class SRXHFVLMCam(SingleTrigger, AreaDetector): cam = C(AreaDetectorCam, '') image_plugin = C(ImagePlugin, 'image1:') stats1 = C(StatsPlugin, 'Stats1:') stats2 = C(StatsPlugin, 'Stats2:') stats3 = C(StatsPlugin, 'Stats3:') stats4 = C(StatsPlugin, 'Stats4:') roi1 = C(ROIPlugin, 'ROI1:') roi2 = C(ROIPlugin, 'ROI2:') roi3 = C(ROIPlugin, 'ROI3:') roi4 = C(ROIPlugin, 'ROI4:') over1 = C(OverlayPlugin, 'Over1:') trans1 = C(TransformPlugin, 'Trans1:') tiff = C( SRXTIFFPlugin, 'TIFF1:', #write_path_template='/epicsdata/hfvlm/%Y/%m/%d/', #root='/epicsdata', write_path_template='/nsls2/xf05id1/data/hfvlm/%Y/%m/%d/', root='/nsls2/xf05id1')
class SrxXspress3Detector2(SRXXspressTrigger, Xspress3Detector): # TODO: garth, the ioc is missing some PVs? # det_settings.erase_array_counters # (XF:05IDD-ES{Xsp:1}:ERASE_ArrayCounters) # det_settings.erase_attr_reset (XF:05IDD-ES{Xsp:1}:ERASE_AttrReset) # det_settings.erase_proc_reset_filter # (XF:05IDD-ES{Xsp:1}:ERASE_PROC_ResetFilter) # det_settings.update_attr (XF:05IDD-ES{Xsp:1}:UPDATE_AttrUpdate) # det_settings.update (XF:05IDD-ES{Xsp:1}:UPDATE) roi_data = Cpt(PluginBase, 'ROIDATA:') # Currently only using three channels. Uncomment these to enable more channel1 = C(Xspress3Channel, 'C1_', channel_num=1, read_attrs=['rois']) # channel2 = C(Xspress3Channel, 'C2_', channel_num=2, read_attrs=['rois']) # channel3 = C(Xspress3Channel, 'C3_', channel_num=3, read_attrs=['rois']) # channels: # channel4 = C(Xspress3Channel, 'C4_', channel_num=4) # channel5 = C(Xspress3Channel, 'C5_', channel_num=5) # channel6 = C(Xspress3Channel, 'C6_', channel_num=6) # channel7 = C(Xspress3Channel, 'C7_', channel_num=7) # channel8 = C(Xspress3Channel, 'C8_', channel_num=8) create_dir = Cpt(EpicsSignal, 'HDF5:FileCreateDir') hdf5 = Cpt( Xspress3FileStoreFlyable, 'HDF5:', read_path_template='/nsls2/xf05id1/data/2019-1/XS3MINI', # read_path_template='/XF05IDD/XSPRESS3-2/2018-1/', # write_path_template='/epics/data/2017-3/', # write_path_template='/nsls2/xf05id1/data/2018-1/XS3MINI', write_path_template='/home/xspress3/data/SRX/2019-1', #write_path_template='/nsls2/xf05id1/XF05ID1/XSPRESS3/2018-1', #write_path_template='/nsls2/xf05id1/data/xspress3/%Y/%M/', # root='/data', # root='/', root='/nsls2/xf05id1') # this is used as a latch to put the xspress3 into 'bulk' mode # for fly scanning. Do this is a signal (rather than as a local variable # or as a method so we can modify this as part of a plan fly_next = Cpt(Signal, value=False) def __init__(self, prefix, *, configuration_attrs=None, read_attrs=None, **kwargs): if configuration_attrs is None: configuration_attrs = [ 'external_trig', 'total_points', 'spectra_per_point', 'settings', 'rewindable' ] if read_attrs is None: read_attrs = ['channel1', 'hdf5'] super().__init__(prefix, configuration_attrs=configuration_attrs, read_attrs=read_attrs, **kwargs) # this is possiblely one too many places to store this # in the parent class it looks at if the extrenal_trig signal is high self._mode = SRXMode.step # self.create_dir.put(-3) def stop(self, *, success=False): ret = super().stop() # todo move this into the stop method of the settings object? self.settings.acquire.put(0) self.hdf5.stop(success=success) return ret def stage(self): # do the latching if self.fly_next.get(): self.fly_next.put(False) self._mode = SRXMode.fly return super().stage() def unstage(self): try: ret = super().unstage() finally: self._mode = SRXMode.step return ret
class SRXPCOEDGECam(SingleTrigger, AreaDetector): cam = C(AreaDetectorCam, 'cam1:') image_plugin = C(ImagePlugin, 'image1:') stats1 = C(StatsPlugin, 'Stats1:') stats2 = C(StatsPlugin, 'Stats2:') stats3 = C(StatsPlugin, 'Stats3:') stats4 = C(StatsPlugin, 'Stats4:') stats5 = C(StatsPlugin, 'Stats5:') roi1 = C(ROIPlugin, 'ROI1:') roi2 = C(ROIPlugin, 'ROI2:') roi3 = C(ROIPlugin, 'ROI3:') roi4 = C(ROIPlugin, 'ROI4:') tiff = C(SRXTIFFPlugin, 'TIFF1:', read_path_template='/data/PCOEDGE/%Y/%m/%d/', write_path_template='C:/epicsdata/pcoedge/%Y/%m/%d/', root='/data')
class DG645(Device): """Barebones class for managing DG645 for MEC Uniblitz deployment.""" # EPICS Signals ch_AB_pol = C(EpicsSignal, ':abOutputPolarityBO.VAL') ch_CD_pol = C(EpicsSignal, ':cdOutputPolarityBO.VAL')
class Turbo(Device): """ Base turbo class for CXI turbo pumps. Parameters ---------- prefix: str The EPICS base pv to use. Expected format: {hutch}:{stand}:{device_abbrv}:{number} name: str The name of the turbo pump """ turboStart = C(EpicsSignal, ':START_SW') turboRun = C(EpicsSignal, ':RUN_SW') def selectMode(self, *argv): """ Shortcut to allow user to change the status of the Turbo device. Accepted arguments: 0,1 selectMode(0) will turn off the turbo device. selectMode(1) will turn the turbo device on. """ for arg in argv: if arg == 0: try: self.turboStart.put(value=0) except TimeoutError: try: self.turboRun.put(value=0) except TimeoutError: print("Error with Device - check prefix") elif arg == 1: try: self.turboStart.put(value=1) except TimeoutError: try: self.turboRun.put(value=1) except TimeoutError: print("Error with device - check prefix") else: print("Only valid arguments are 0(off) & 1(on)") def turnOff(self): """ Shortcut to quickly turn off the selected turbo device """ try: self.turboStart.put(value=0) except TimeoutError: try: self.turboRun.put(value=0) except TimeoutError: print("Error with Device - check prefix") def turnOn(self): """ Shortcut to quickly turn on the selected turbo device" """ try: self.turboStart.put(value=1) except TimeoutError: try: self.turboRun.put(value=1) except TimeoutError: print("Error with Device - check prefix")
class SynWithConfig(Device): a = C(sim.Signal, value=0) b = C(sim.Signal, value=2) d = C(sim.Signal, value=1)
class MyPositioner(PVPositionerPC): '''Setpoint only''' setpoint = C(EpicsSignal, '.VAL')
class XPDPerkinElmer(PerkinElmerDetector): image = C(ImagePlugin, 'image1:') _default_configuration_attrs = ( PerkinElmerDetector._default_configuration_attrs + ('images_per_set', 'number_of_sets')) tiff = C( XPDTIFFPlugin, 'TIFF1:', write_path_template='/a/b/c/', read_path_template='/a/b/c', cam_name='cam', # used to configure "tiff squashing" proc_name='proc', # ditto read_attrs=[], root='/nsls2/xf28id2/') # hdf5 = C(XPDHDF5Plugin, 'HDF1:', # write_path_template='G:/pe1_data/%Y/%m/%d/', # read_path_template='/direct/XF28ID2/pe1_data/%Y/%m/%d/', # root='/direct/XF28ID2/') proc = C(ProcessPlugin, 'Proc1:') # These attributes together replace `num_images`. They control # summing images before they are stored by the detector (a.k.a. "tiff # squashing"). images_per_set = C(Signal, value=1, add_prefix=()) number_of_sets = C(Signal, value=1, add_prefix=()) stats1 = C(StatsPlugin, 'Stats1:') stats2 = C(StatsPlugin, 'Stats2:') stats3 = C(StatsPlugin, 'Stats3:') stats4 = C(StatsPlugin, 'Stats4:') stats5 = C(StatsPlugin, 'Stats5:') roi1 = C(ROIPlugin, 'ROI1:') roi2 = C(ROIPlugin, 'ROI2:') roi3 = C(ROIPlugin, 'ROI3:') roi4 = C(ROIPlugin, 'ROI4:') # dark_image = C(SavedImageSignal, None) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.stage_sigs.update([(self.cam.trigger_mode, 'Internal')])
class MyPositioner(PVPositionerPC): '''Setpoint, readback, put completion. No done pv.''' setpoint = C(EpicsSignal, '.VAL') readback = C(EpicsSignalRO, '.RBV')
class MyPositioner(PVPositioner): setpoint = C(EpicsSignal, '.VAL')
class MyPositioner(PVPositionerPC): '''Setpoint, readback, done, stop. Put completion''' setpoint = C(EpicsSignal, '.VAL') readback = C(EpicsSignalRO, '.RBV') done = C(EpicsSignalRO, '.MOVN') done_value = 0
class Bundle(MotorBundle): a = C(EpicsMotor, ':mtr1') b = C(EpicsMotor, ':mtr2') c = C(EpicsMotor, ':mtr3')
class PluginBase(ophyd.plugins.PluginBase, ADBase): """ Overridden PluginBase to make it work when the root device is not a CamBase class. """ enable = C(EpicsSignal, 'EnableCallbacks_RBV.RVAL', write_pv="EnableCallbacks", string=False) @property def source_plugin(self): # The PluginBase object that is the asyn source for this plugin. source_port = self.nd_array_port.get() if source_port == 'CAM' or not hasattr(self.root, 'get_plugin_by_asyn_port'): return None source_plugin = self.root.get_plugin_by_asyn_port(source_port) return source_plugin @property def _asyn_pipeline_configuration_names(self): # This broke any instantiated plugin b/c _asyn_pipeline is a list that # can have None. return [ _.configuration_names.name for _ in self._asyn_pipeline if hasattr(_, 'configuration_names') ] @property def _asyn_pipeline(self): parent = None # Add a check to make sure root has this attr, otherwise return None if hasattr(self.root, 'get_plugin_by_asyn_port') and self.root != self: parent = self.root.get_plugin_by_asyn_port( self.nd_array_port.get()) if hasattr(parent, '_asyn_pipeline'): return parent._asyn_pipeline + (self, ) return (parent, self) def describe_configuration(self): # Use the overridden describe_configuration defined above ret = ADBase.describe_configuration(self) source_plugin = self.source_plugin if source_plugin is not None and source_plugin is not self: ret.update(source_plugin.describe_configuration()) return ret def read_configuration(self): ret = ADBase.read_configuration(self) if self.source_plugin is not self: ret.update(self.source_plugin.read_configuration()) return ret def stage(self): # Ensure the plugin is enabled. We do not disable it on unstage if self.enable not in self.stage_sigs and 'enable' not in self.stage_sigs: if not self.enable.connected: self.enable.get() set_and_wait(self.enable, 1, atol=0) ADBase.stage(self) @property def array_pixels(self): """The total number of pixels, calculated from array_size.""" array_size = list(self.array_size.get()) dimensions = int(self.ndimensions.get()) if dimensions == 0: return 0 pixels = array_size[0] for dim in array_size[1:dimensions]: if dim: pixels *= dim return int(pixels)
class SRXPixirad(SingleTrigger, AreaDetector): det = C(PixiradDetectorCam, 'cam1:') image = C(ImagePlugin, 'image1:') roi1 = C(ROIPlugin, 'ROI1:') roi2 = C(ROIPlugin, 'ROI2:') roi3 = C(ROIPlugin, 'ROI3:') roi4 = C(ROIPlugin, 'ROI4:') stats1 = C(StatsPlugin, 'Stats1:') stats2 = C(StatsPlugin, 'Stats2:') stats3 = C(StatsPlugin, 'Stats3:') stats4 = C(StatsPlugin, 'Stats4:') tiff = C( SRXTIFFPlugin, 'TIFF1:', #write_path_template='/epicsdata/pixirad/%Y/%m/%d/', #root='/epicsdata') write_path_template='/nsls2/xf05id1/data/pixirad/%Y/%m/%d/', root='/nsls2/xf05id1')
class AreaDetector(Device): images_per_set = C(Signal, value=1, add_prefix=()) number_of_sets = C(Signal, value=1, add_prefix=()) cam = C(Cam, '', add_prefix=())
class FaultyPseudo1x3(Pseudo1x3): real1 = C(FaultyStopperEpicsMotor, motor_recs[0])
class Cam(Device): acquire_time = C(Signal, value=1, add_prefix=())
class PerkinElmerMulti(MultiTrigger, XPDPerkinElmer): shutter = C(EpicsSignal, 'XF:28IDC-ES:1{Sh:Exp}Cmd-Cmd')
class Slits(Device, MvInterface): """ Beam slits with combined motion for center and width. Parameters ---------- prefix : ``str`` The EPICS base of the motor name : ``str``, optional The name of the offset mirror nominal_aperture : ``float``, optional Nominal slit size that will encompass the beam without blocking Notes ----- The slits represent a unique device when forming the lightpath as whether the beam is being blocked or not depends on the pointing. In order to create an estimate that will warn operators of narrowly closed slits while still allowing slits to be closed along the beampath. The simplest solution was to use a :attr:`.nominal_aperture` that stores the slit width and height that the slits should use for general operation. Using this the :attr:`.transmission` is calculated based on how the current aperture compares to the nominal, always using the minimum of the width or height. This means that if you have a nominal aperture of 2 mm, but your slits are set to 0.5 mm, the total estimated transmission will be 25%. Obviously this is greatly oversimplified, but it allows the lightpath to make a rough back of the hand calculation without being over aggressive about changing slit widths during alignment """ xcenter = C(SlitPositioner, '', slit_type="XCENTER") xwidth = C(SlitPositioner, '', slit_type="XWIDTH") ycenter = C(SlitPositioner, '', slit_type="YCENTER") ywidth = C(SlitPositioner, '', slit_type="YWIDTH") blocked = C(EpicsSignalRO, ":BLOCKED") open_cmd = C(EpicsSignal, ":OPEN") close_cmd = C(EpicsSignal, ":CLOSE") block_cmd = C(EpicsSignal, ":BLOCK") # Subscription information SUB_STATE = 'sub_state_changed' _default_sub = SUB_STATE # Default Attributes _default_read_attrs = ['xwidth', 'ywidth'] _default_configuration_attrs = ['xcenter.readback', 'ycenter.readback'] def __init__(self, *args, nominal_aperture=(5.0, 5.0), **kwargs): self._has_subscribed = False self.nominal_aperture = nominal_aperture super().__init__(*args, **kwargs) def move(self, size, wait=False, moved_cb=None, timeout=None): """ Set the dimensions of the width/height of the gap to width paramater. Parameters --------- size : ``float``, tuple Target size for slits in both x and y axis. Either specify as a tuple for a rectangular aperture (width, height) or set both with single floating point value to use set a square width wait : ``bool`` If true, block until move is completed timeout: ``float``, optional Maximum time for the motion. If None is given, the default value of `xwidth` and `ywidth` positioners is used. moved_cb: ``callable``, optional Function to be run when the operation finishes. This callback should not expect any arguments or keywords Returns ------- status : ``AndStatus`` Logical combination of the request to both horizontal and vertical motors """ # Check for rectangular setpoint if isinstance(size, tuple): (width, height) = size else: width, height = size, size # Instruct both width and height then combine the output status x_stat = self.xwidth.move(width, wait=False, timeout=timeout) y_stat = self.ywidth.move(height, wait=False, timeout=timeout) status = x_stat & y_stat # Add our callback if one was given if moved_cb is not None: status.add_callback(moved_cb) # Wait if instructed to do so. Stop the motors if interrupted if wait: try: status_wait(status) except KeyboardInterrupt: self.xwidth.stop() self.ywidth.stop() raise return status @property def inserted(self): """ Whether the slits are inserted into the beampath """ return all([ self.nominal_aperture[idx] > self.current_aperture[idx] for idx in range(0, 2) ]) @property def removed(self): """ Whether the slits are entirely removed from the beampath """ return not self.inserted @property def transmission(self): """ Estimated transmission of the slits based on :attr:`.nominal_aperture` """ # Find most restrictive side of slit aperture min_dim = np.argmin(self.current_aperture) # Don't allow transmissions over 1.0 return min([ self.current_aperture[min_dim] / self.nominal_aperture[min_dim], 1.0 ]) @property def current_aperture(self): """ Current size of the aperture (width, height) """ return (self.xwidth.position, self.ywidth.position) @property def position(self): return self.current_aperture def remove(self, size=None, wait=False, timeout=None, **kwargs): """ Open the slits to unblock the beam Parameters ---------- size : ``float``, optional Open the slits to a specific size otherwise `:attr:`.nominal_aperture is used wait : ``bool``, optional Wait for the status object to complete the move before returning timeout : ``float``, optional Maximum time to wait for the motion. If None, the default timeout for this positioner is used Returns ------- MoveStatus: ``Status`` object based on move completion See Also -------- :meth:`Slits.move` """ # Use nominal_aperture by default size = size or self.nominal_aperture return self.move(size, wait=wait, timeout=timeout, **kwargs) def set(self, size): """ Alias for the move method, here for bluesky compatibilty """ return self.move(size, wait=False) @property def hints(self): """Device hints""" return { 'fields': [self.xwidth.readback.name, self.ywidth.readback.name] } def open(self): """ Uses the built-in ``OPEN`` record to move open the aperture """ self.open_cmd.put(1) def close(self): """ Close the slits to have an aperture of 0mm on each side """ self.close_cmd.put(1) def block(self): """ Overlap the slits to block the beam """ self.block_cmd.put(1) def stage(self): """ Store the initial values of the aperture position before scanning """ self._original_vals[self.xwidth.setpoint] = self.xwidth.readback.value self._original_vals[self.ywidth.setpoint] = self.ywidth.readback.value return super().stage() def subscribe(self, cb, event_type=None, run=True): """ Subscribe to changes of the slits Parameters ---------- cb : ``callable`` Callback to be run event_type : ``str``, optional Type of event to run callback on run : ``bool``, optional Run the callback immediatelly """ # Avoid making child subscriptions unless a client cares if not self._has_subscribed: # Subscribe to changes in aperture self.xwidth.readback.subscribe(self._aperture_changed, run=False) self.ywidth.readback.subscribe(self._aperture_changed, run=False) self._has_subscribed = True return super().subscribe(cb, event_type=event_type, run=run) def _aperture_changed(self, *args, **kwargs): """ Callback run when slit size is adjusted """ # Avoid duplicate keywords kwargs.pop('sub_type', None) kwargs.pop('obj', None) # Run subscriptions self._run_subs(sub_type=self.SUB_STATE, obj=self, **kwargs)
class SRXPCOEDGE(SingleTrigger, AreaDetector): cam = C(PCOEdgeCamV33, 'cam1:') image_plugin = C(ImagePlugin, 'image1:') stats1 = C(StatsPluginV33, 'Stats1:') stats2 = C(StatsPluginV33, 'Stats2:') stats3 = C(StatsPluginV33, 'Stats3:') stats4 = C(StatsPluginV33, 'Stats4:') stats5 = C(StatsPluginV33, 'Stats5:') roi1 = C(ROIPlugin, 'ROI1:') roi2 = C(ROIPlugin, 'ROI2:') roi3 = C(ROIPlugin, 'ROI3:') roi4 = C(ROIPlugin, 'ROI4:') hdf = C(HDF5PluginWithFileStore, 'HDF1:', read_path_template=r'/nsls2/xf05id1/XF05ID1/PCO/%Y/%m/%d/', write_path_template=r'Z:\%Y\%m\%d\\', root='/nsls2/xf05id1/XF05ID1/')
class PU610K_Channel(Device): """Class for the MEC PU610K PFN charging system channels.""" _enabled = C(EpicsSignalRO, ':ENABLE_RBV') _enable = C(EpicsSignal, ':ENABLE') _desc = C(EpicsSignalRO, ':NAME') _vset = C(EpicsSignal, ':VOLTAGE') _vget = C(EpicsSignalRO, ':VOLTAGE_MEASURED') _inh = C(EpicsSignal, ':CHARGE_INHIBIT') _inh_RBV = C(EpicsSignalRO, ':CHARGE_INHIBIT_RBV') _cntdown = C(EpicsSignal, ':CI_COUNTDOWN') _state = C(EpicsSignalRO, ':CHARGE_STATE') _status = C(EpicsSignalRO, ':ERRORMSG') @property def enabled(self): rbv = self._enabled.get() if rbv == 'Enabled': return True else: return False def enable(self): self._enable.put(1) def disable(self): self._enable.put(0) @property def chan_name(self): return self._desc.get() @property def voltage(self): return self._vget.get() @voltage.setter def voltage(self, value): self._vset.put(value) @property def charge_inhibit(self): return self._inh_RBV.get() @charge_inhibit.setter def charge_inhibit(self, value): self._inh.put(value) @property def countdown(self): return self._cntdown.get() @countdown.setter def countdown(self, value): self._countdown.put(value) @property def state(self): state_dict = {0: 'Not Charging', 1: 'Charging', 2: 'Charged'} return state_dict[self._state.get()] @property def status(self): return self._status.get()
class SynWithConfig(Device): x = C(sim.Signal, value=0) y = C(sim.Signal, value=2) z = C(sim.Signal, value=3)
class PU610K(Device): """Class for the MEC PFN charging racks.""" _charge = C(EpicsSignal, ':START_CHARGE') _mode = C(EpicsSignal, ':MODE') _mode_rbv = C(EpicsSignalRO, ':MODE_RBV') _mode_ok = C(EpicsSignalRO, ':MODE_OK') _fault = C(EpicsSignal, ':FAULT') _charge_ok = C(EpicsSignalRO, ':CHARGE_OK') _wp_ab = wp_ab _wp_ef = wp_ef _wp_gh = wp_gh _wp_ij = wp_ij __chancd = C(PU610K_Channel, ':CH0') __chana = C(PU610K_Channel, ':CH1') __chanb = C(PU610K_Channel, ':CH2') __chane = C(PU610K_Channel, ':CH3') __chanf = C(PU610K_Channel, ':CH4') __chang = C(PU610K_Channel, ':CH5') __chanh = C(PU610K_Channel, ':CH6') __chani = C(PU610K_Channel, ':CH7') __chanj = C(PU610K_Channel, ':CH8') @property def charged(self): c = self._charge_ok.get() if c == 0: return False elif c == 1: return True else: raise Exception("Unknown PFN charge state: {}".format(c)) @property def faulted(self): f = self._fault.get() if c == 1: return True else: return False @property def ready(self): mode_rbv = self._mode_rbv.get() mode_ok = self._mode_ok.get() if (mode_rbv == 2) and (mode_ok == 0): return True else: return False @property def stand_by(self): mode_rbv = self._mode_rbv.get() mode_ok = self._mode_ok.get() if (mode_rbv == 1) and (mode_ok == 0): return True else: return False @property def stopped(self): mode_rbv = self._mode_rbv.get() mode_ok = self._mode_ok.get() if (mode_rbv == 0) and (mode_ok == 0): return True else: return False def charge(self): """Charge the PFN racks based on current settings.""" self._mode.put(0) # First go to stop to clear any errors while not self.stopped: time.sleep(0.1) self._mode.put(1) # Now go to standby to start cooling while not self.standby: time.sleep(0.1) self._mode.put(2) # now go to "ready" and wait. Requires at least # a 5 second delay (HW 'feature'). while not self.ready: time.sleep(0.1) self._charge.put(1) print("Charging, please wait ...") while not self.charged: time.sleep(1) print("Charging complete!") def discharge(self): """Discharge the PFN racks.""" self.mode.put(0) def ALL(self): self.__chancd.enable() self.__chang.enable() self.__chanh.enable() self.__chani.enable() self.__chanj.enable() self.__chana.enable() self.__chanb.enable() self.__chane.enable() self.__chanf.enable() self._wp_ab.mv_on() self._wp_ef.mv_on() self._wp_gh.mv_on() self._wp_ij.mv_on() def ALL_OFF(self): self.__chancd.disable() self.__chang.disable() self.__chanh.disable() self.__chani.disable() self.__chanj.disable() self.__chana.disable() self.__chanb.disable() self.__chane.disable() self.__chanf.disable() self._wp_ab.mv_off() self._wp_ef.mv_off() self._wp_gh.mv_off() self._wp_ij.mv_off() def GHIJ(self): """Enable the GHIJ arms, disable ABEF arms.""" self.__chancd.enable() self.__chang.enable() self.__chanh.enable() self.__chani.enable() self.__chanj.enable() self.__chana.disable() self.__chanb.disable() self.__chane.disable() self.__chanf.disable() self._wp_ab.mv_off() self._wp_ef.mv_off() self._wp_gh.mv_on() self._wp_ij.mv_on() def ABEF(self): """Enable the ABEF arms, disable GHIJ arms.""" self.__chancd.enable() self.__chana.enable() self.__chanb.enable() self.__chane.enable() self.__chanf.enable() self.__chang.disable() self.__chanh.disable() self.__chani.disable() self.__chanj.disable() self._wp_ab.mv_on() self._wp_ef.mv_on() self._wp_gh.mv_off() self._wp_ij.mv_off()
class BPMCam(SingleTrigger, AreaDetector): cam = C(AreaDetectorCam, '') image_plugin = C(ImagePlugin, 'image1:') tiff = C( SRXTIFFPlugin, 'TIFF1:', #write_path_template='/epicsdata/bpm1-cam1/2016/2/24/') #write_path_template='/epicsdata/bpm1-cam1/%Y/%m/%d/', #root='/epicsdata', reg=db.reg) write_path_template='/nsls2/xf05id1/data/bpm1-cam1/%Y/%m/%d/', root='/nsls2/xf05id1') roi1 = C(ROIPlugin, 'ROI1:') roi2 = C(ROIPlugin, 'ROI2:') roi3 = C(ROIPlugin, 'ROI3:') roi4 = C(ROIPlugin, 'ROI4:') stats1 = C(StatsPlugin, 'Stats1:') stats2 = C(StatsPlugin, 'Stats2:') stats3 = C(StatsPlugin, 'Stats3:') stats4 = C(StatsPlugin, 'Stats4:') # this is flakey? # stats5 = C(StatsPlugin, 'Stats5:') pass
class UniblitzEVRCH(Device): """Barebones class for managing EVR channels for MEC Uniblitz deployment.""" # EPICS Signals ch_enable = C(EpicsSignal, ':TCTL') ch_eventc = C(EpicsSignal, ':TEC')