Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add j120k flowswitch, insert flow switch in appropriate classes. #1189

Merged
merged 9 commits into from
Dec 16, 2023
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions docs/source/upcoming_release_notes/1189-flow-switch.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
1189 flow-switch
#################

API Breaks
----------
- N/A

Features
--------
- pcdsdevices now has a `digital_signals` module for simple digital io.

Device Updates
--------------
- added `J120K` to `SxrTestAbsorber`, `XPIM`, `IM2K0`, `PowerSlits`

New Devices
-----------
- `PPMCoolSwitch` ppms with cooling switch not a meter.
- `WaveFrontSensorTargetCool` WaveFrontSensors with a cooling switch.
- `J120K` a device class for a cooling switch.

Bugfixes
--------
- N/A

Maintenance
-----------
- N/A

Contributors
------------
- nrwslac
20 changes: 20 additions & 0 deletions pcdsdevices/digital_signals.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
from ophyd import Component as Cpt
from ophyd import Device

from .interface import BaseInterface
from .signal import PytmcSignal


class J120K(BaseInterface, Device):
"""
A class representing the J120K 24V dry contact cooling flow switch.
"""
flow_ok = Cpt(PytmcSignal, ':FSW:FLOW_OK', io='i',
kind='normal', doc='flow rate nominal')

@property
def get_flow_ok(self):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few more thoughts, though I'm totally splitting hairs at this point:

  • Why does this property exist? Is flow_ok.get() insufficient as an API? (I do see that it returns an int and not a bool)
  • If there's a reason for it to exist, why is it a property and not a method?
  • If there's a good reason for it to be a property, why is it named like a function? I think people in an interactive session will very likely do a get_flow_ok() call which will give an annoying "type bool is not callable" sort of error.

Copy link
Contributor Author

@nrwslac nrwslac Dec 16, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is actually totally true, I did this myself. I'll delete it. I thought people would want a designated function, but in this case it should drop the property tag. I also did not think about the fact that you can just call get on the signal.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, sounds good- I would have been fine with any outcome here, just trying to make sure we consider these small details

"""
returns True if flow rate is nominal
"""
return bool(self.flow_ok.get())
13 changes: 13 additions & 0 deletions pcdsdevices/pim.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
PCDSAreaDetectorTyphosTrigger)
from .device import GroupDevice
from .device import UpdateComponent as UpCpt
from .digital_signals import J120K
from .epics_motor import IMS, BeckhoffAxisNoOffset
from .inout import InOutRecordPositioner
from .interface import BaseInterface, LightpathInOutCptMixin
Expand Down Expand Up @@ -541,6 +542,8 @@ class XPIM(LCLS2ImagerBase):
filter_wheel = Cpt(XPIMFilterWheel, ':MFW', kind='config',
doc='Optical filter wheel in front of the camera '
'to prevent saturation.')
flow_switch = Cpt(J120K, '', kind='normal',
doc='Device that indicates nominal PCW Flow Rate.')

set_metadata(zoom_lock, dict(variety='command-enum'))
set_metadata(focus_lock, dict(variety='command-enum'))
Expand All @@ -557,6 +560,8 @@ class IM2K0(LCLS2ImagerBase):
# XPIM illuminator
led = Cpt(XPIMLED, ':CIL', kind='config',
doc='LED for viewing the reticle.')
flow_switch = Cpt(J120K, '', kind='normal',
doc='Device that indicates nominal PCW Flow Rate.')
# Nothing else! No power meter, no zoom/focus, no filter wheel...


Expand All @@ -580,3 +585,11 @@ class PPMCOOL(PPM):
"""
flow_meter = Cpt(FDQ, '', kind='normal',
doc='Device that measures PCW Flow Rate.')


class PPMCoolSwitch(PPM):
"""
L2SI's Power and Profile Monitor design with cooling switch.
"""
flow_switch = Cpt(J120K, '', kind='normal',
doc='Device that indicates nominal PCW Flow Rate.')
6 changes: 4 additions & 2 deletions pcdsdevices/slits.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,13 @@
from .areadetector.detectors import PCDSAreaDetectorTyphosTrigger
from .device import GroupDevice
from .device import UpdateComponent as UpCpt
from .digital_signals import J120K
from .epics_motor import BeckhoffAxis, BeckhoffAxisNoOffset, PCDSMotorBase
from .interface import (BaseInterface, FltMvInterface, LightpathInOutCptMixin,
LightpathMixin, MvInterface)
from .pmps import TwinCATStatePMPS
from .sensors import RTD, TwinCATTempSensor
from .signal import NotImplementedSignal, PytmcSignal
from .signal import PytmcSignal
from .sim import FastMotor
from .utils import get_status_float, get_status_value, schedule_task
from .variety import set_metadata
Expand Down Expand Up @@ -622,7 +623,8 @@ class PowerSlits(BeckhoffSlits):
"""

rtds = DDCpt(_rtd_fields(RTD, 'rtd', range(1, 9)))
fsw = Cpt(NotImplementedSignal, ':FSW', kind='normal')
flow_switch = Cpt(J120K, '', kind='normal',
doc='Device that indicates nominal PCW Flow Rate.')


class ExitSlitTarget(TwinCATStatePMPS):
Expand Down
3 changes: 3 additions & 0 deletions pcdsdevices/sxr_test_absorber.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

from ophyd.device import Component as Cpt

from .digital_signals import J120K
from .epics_motor import BeckhoffAxisNoOffset
from .inout import TwinCATInOutPositioner
from .interface import BaseInterface, LightpathInOutCptMixin
Expand Down Expand Up @@ -59,5 +60,7 @@ class SxrTestAbsorber(BaseInterface, LightpathInOutCptMixin):

state = Cpt(SxrTestAbsorberStates, ':MMS:STATE', kind='hinted')
absorber_vert = Cpt(BeckhoffAxisNoOffset, ':MMS:01', kind='normal')
flow_switch = Cpt(J120K, '', kind='normal',
doc='Device that indicates nominal PCW Flow Rate.')

lightpath_cpts = ['state']
11 changes: 11 additions & 0 deletions pcdsdevices/wfs.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from .device import GroupDevice
from .device import UpdateComponent as UpCpt
from .digital_signals import J120K
from .epics_motor import BeckhoffAxisNoOffset
from .interface import BaseInterface, LightpathInOutCptMixin
from .pmps import TwinCATStatePMPS
Expand Down Expand Up @@ -43,3 +44,13 @@ class WaveFrontSensorTarget(BaseInterface, GroupDevice,
doc='First thermocouple.')
thermocouple2 = Cpt(TwinCATTempSensor, ':STC:02', kind='normal',
doc='Second thermocouple.')


class WaveFrontSensorTargetCool(WaveFrontSensorTarget):
"""
An array of targets used to determine the beam's wavefront.

This array has a cooling indication switch.
"""
flow_switch = Cpt(J120K, '', kind='normal',
doc='Device that indicates nominal PCW Flow Rate.')