class Wave8Channel(Device): """ Class for a single channel read out by a wave8 Parameters ---------- prefix : ``str`` Wave8 base PV name : ``str`` Alias for the wave8 channnel_index : ``int`` Index for gauge (0-15) """ amplitude = FCpt(EpicsSignal, '{self.prefix}:AMPL_{self.channel_index}', kind='hinted') tpos = FCpt(EpicsSignal, '{self.prefix}:TPOS_{self.channel_index}', kind='normal') number_of_samples = FCpt( EpicsSignal, '{self.prefix}:NumberOfSamples{self.channel_index}_RBV', write_pv='{self.prefix}:NumberOfSamples{self.channel_index}', kind='config') delay = FCpt(EpicsSignal, '{self.prefix}:Delay{self.channel_index}', kind='config', write_pv='{self.prefix}:Delay{self.channel_index}_RBV') def __init__(self, prefix, *, name, channel_index, **kwargs): self.channel_index = channel_index super().__init__(prefix, name=name, **kwargs)
class ScalerChannel(Device): # TODO set up monitor on this to automatically change the name chname = FCpt(EpicsSignal, '{self.prefix}.NM{self._ch_num}', kind=Kind.config) s = FCpt(EpicsSignalRO, '{self.prefix}.S{self._ch_num}', kind=Kind.hinted, auto_monitor=False) preset = FCpt(EpicsSignal, '{self.prefix}.PR{self._ch_num}', kind=Kind.config) gate = FCpt(EpicsSignal, '{self.prefix}.G{self._ch_num}', string=True, kind=Kind.config) def __init__(self, prefix, ch_num, **kwargs): self._ch_num = ch_num super().__init__(prefix, **kwargs) self.match_name() def match_name(self): self.s.name = self.chname.get()
class Wave8Channel(BaseInterface, Device): """ Class for a single channel read out by a wave8. Parameters ---------- prefix : str Wave8 base PV. name : str Alias for the wave8. channnel_index : int Index for gauge (0-15). """ tab_component_names = True amplitude = FCpt(EpicsSignalRO, '{self.prefix}:AMPL_{self.channel_index}', kind='hinted') tpos = FCpt(EpicsSignalRO, '{self.prefix}:TPOS_{self.channel_index}', kind='normal') number_of_samples = FCpt( EpicsSignal, '{self.prefix}:NumberOfSamples{self.channel_index}_RBV', write_pv='{self.prefix}:NumberOfSamples{self.channel_index}', kind='config') delay = FCpt( EpicsSignal, '{self.prefix}:Delay{self.channel_index}_RBV', write_pv='{self.prefix}:Delay{self.channel_index}', kind='config') def __init__(self, prefix, *, name, channel_index, **kwargs): self.channel_index = channel_index super().__init__(prefix, name=name, **kwargs)
class VonHamosFE(BaseInterface, Device): """ von Hamos spectrometer with Focus and Energy motors. These motors should be run as user stages and have their PVs passed into this object as keyword arguments, as labeled. Parameters ---------- prefix : str, optional von Hamos base PV. name : str A name to refer to the device. prefix_focus : str The EPICS base PV of the motor controlling the spectrometer's focus. prefix_energy : str The EPICS base PV of the motor controlling the spectrometer energy. """ tab_component_names = True # Update PVs in IOC and change here to reflect f = FCpt(BeckhoffAxis, '{self._prefix_focus}', kind='normal') e = FCpt(BeckhoffAxis, '{self._prefix_energy}', kind='normal') def __init__(self, *args, name, prefix_focus, prefix_energy, **kwargs): self._prefix_focus = prefix_focus self._prefix_energy = prefix_energy if args: super().__init__(args[0], name=name, **kwargs) else: super().__init__('', name=name, **kwargs)
class IPIMBChannel(BaseInterface, Device): """ Class for a single channel read out by an IPIMB box. Parameters ---------- prefix : str IPIMB base PV. name : str Alias for the IPIMB box. channnel_index : int Index for gauge (0-3). """ tab_component_names = True amplitude = FCpt(EpicsSignalRO, '{self.prefix}:CH{self.channel_index}', kind='hinted') gain = FCpt(EpicsSignal, '{self.prefix}:ChargeAmpRangeCH{self.channel_index}', kind='config', string=True) base = FCpt(EpicsSignal, '{self.prefix}:CH{self.channel_index}_BASE', kind='config') scale = FCpt(EpicsSignal, '{self.prefix}:CH{self.channel_index}_SCALE', kind='config') def __init__(self, prefix, *, name, channel_index, **kwargs): self.channel_index = channel_index super().__init__(prefix, name=name, **kwargs)
class IPIMBChannel(Device): """ Class for a single channel read out by an ipimb box Parameters ---------- prefix : ``str`` Ipimb base PV name : ``str`` Alias for the ipimb box channnel_index : ``int`` Index for gauge (0-3) """ amplitude = FCpt(EpicsSignal, '{self.prefix}:CH{self.channel_index}', kind='hinted') gain = FCpt(EpicsSignal, '{self.prefix}:ChargeAmpRangeCH{self.channel_index}', kind='config', string=True) base = FCpt(EpicsSignal, '{self.prefix}:CH{self.channel_index}_BASE', kind='config') scale = FCpt(EpicsSignal, '{self.prefix}:CH{self.channel_index}_SCALE', kind='config') def __init__(self, prefix, *, name, channel_index, **kwargs): self.channel_index = channel_index super().__init__(prefix, name=name, **kwargs)
class OffsetIMSWithPreset(OffsetMotorBase): """ Offset IMS with an additiona Offset _SET PV. This motor puts to an additional PV (_SET) during `set_current_postion`. """ motor = FCpt(IMS, '{self._motor_prefix}') offset_set_pv = FCpt(EpicsSignal, '{self._prefix}_SET', kind='normal') # override the set_current_position def set_current_position(self, position): ''' Override this method defined in OffsetMotorBase to allow setting the new current position to the _SET pv as well. Calculate and configure the user_offset value, indicating the provided ``position`` as the new current position. Parameters ---------- position : number The new current position. ''' self.user_offset.put(0.0) new_offset = position - self.position[0] self.offset_set_pv.put(new_offset) self.user_offset.put(new_offset)
class SmarActTipTilt(Device): """ Class for bundling two SmarActOpenLoop axes arranged in a tip-tilt mirro positioning configuration into a single device. Parameters: ----------- prefix : str <optional, default=''> The base PV of the stages. Can be omitted, but then tip_pv and tilt_pv must specify the full stage PV. tip_pv : str The PV suffix of the "tip" axis to add to the device prefix. Any PV separator (e.g. ':') must be included. tilt_pv : str The PV suffix of the "tilt" axis to add to the device prefix. Any PV separator (e.g. ':') must be included. Examples -------- # Tip Tilt stage with same base PV tt = SmarActTipTilt(prefix='LAS:MCS2:01', tip_pv=':M1', tilt_pv=':M2') # Tip Tilt stage with different base PV (separate controller, etc.) tt2 = SmarActTipTilt(tip_pv='LAS:MCS2:01:M1', tilt_pv='LAS:MCS2:02:M1') """ tip = FCpt(SmarActOpenLoop, '{prefix}{self._tip_pv}', kind='normal') tilt = FCpt(SmarActOpenLoop, '{prefix}{self._tilt_pv}', kind='normal') def __init__(self, prefix='', *, tip_pv, tilt_pv, **kwargs): self._tip_pv = tip_pv self._tilt_pv = tilt_pv super().__init__(prefix, **kwargs)
class CCM(InOutPositioner): """ The full CCM assembly. This requires a huge number of motor pv prefixes to be passed in, and they are all labelled accordingly. """ calc = FCpt(CCMCalc, '{self.alio_prefix}', kind='hinted') theta2fine = FCpt(CCMMotor, '{self.theta2fine_prefix}') x = FCpt(CCMX, down_prefix='{self.x_down_prefix}', up_prefix='{self.x_up_prefix}', add_prefix=('down_prefix', 'up_prefix'), kind='omitted') y = FCpt(CCMY, down_prefix='{self.y_down_prefix}', up_north_prefix='{self.y_up_north_prefix}', up_south_prefix='{self.y_up_south_prefix}', add_prefix=('down_prefix', 'up_north_prefix', 'up_south_prefix'), kind='omitted') state = Cpt(AttributeSignal, attr='_state', kind='omitted') # Placeholder value. This represents "not full transmission". _transmission = {'IN': 0.9} tab_component_names = True def __init__(self, alio_prefix, theta2fine_prefix, x_down_prefix, x_up_prefix, y_down_prefix, y_up_north_prefix, y_up_south_prefix, in_pos, out_pos, *args, **kwargs): self.alio_prefix = alio_prefix self.theta2fine_prefix = theta2fine_prefix self.x_down_prefix = x_down_prefix self.x_up_prefix = x_up_prefix self.y_down_prefix = y_down_prefix self.y_up_north_prefix = y_up_north_prefix self.y_up_south_prefix = y_up_south_prefix self._in_pos = in_pos self._out_pos = out_pos super().__init__(alio_prefix, *args, **kwargs) @property def _state(self): if np.isclose(self.x.position, self._in_pos): return 1 elif np.isclose(self.x.position, self._out_pos): return 2 else: return 0 @_state.setter def _state(self, value): if value == 1: self.x.move(self._in_pos, wait=False) elif value == 2: self.x.move(self._out_pos, wait=False)
class LensStack(Device): x = FCpt(IMS, '{self.x_prefix}') y = FCpt(IMS, '{self.y_prefix}') z = FCpt(IMS, '{self.z_prefix}') def __init__(self, x_prefix, y_prefix, z_prefix, *args, **kwargs): self.x_prefix = x_prefix self.y_prefix = y_prefix self.z_prefix = z_prefix super().__init__(x_prefix, *args, **kwargs)
class FeeAtt(AttBase): """ Old attenuator IOC in the FEE. """ # Positioner Signals setpoint = Cpt(EpicsSignal, ':RDES', kind='normal') readback = Cpt(EpicsSignal, ':RACT', kind='hinted') actuate = Cpt(EpicsSignal, ':GO', kind='omitted') done = None # Attenuator Signals energy = Cpt(EpicsSignalRO, ':ETOA.E', kind='normal') trans_ceil = Cpt(EpicsSignalRO, ':R_CEIL', kind='omitted') trans_floor = Cpt(EpicsSignalRO, ':R_FLOOR', kind='omitted') user_energy = Cpt(EpicsSignal, ':EDES', kind='omitted') eget_cmd = Cpt(EpicsSignal, ':EACT.SCAN', kind='omitted') # status = None calcpend = Cpt(Signal, value=0) # Hardcode filters for FEE, because there is only one. filter1 = FCpt(FeeFilter, '{self._filter_prefix}1') filter2 = FCpt(FeeFilter, '{self._filter_prefix}2') filter3 = FCpt(FeeFilter, '{self._filter_prefix}3') filter4 = FCpt(FeeFilter, '{self._filter_prefix}4') filter5 = FCpt(FeeFilter, '{self._filter_prefix}5') filter6 = FCpt(FeeFilter, '{self._filter_prefix}6') filter7 = FCpt(FeeFilter, '{self._filter_prefix}7') filter8 = FCpt(FeeFilter, '{self._filter_prefix}8') filter9 = FCpt(FeeFilter, '{self._filter_prefix}9') num_att = 9 def __init__(self, prefix='SATT:FEE1:320', *, name='FeeAtt', **kwargs): self._filter_prefix = prefix[:-1] super().__init__(prefix, name=name, **kwargs)
class PressureController(Device, _TableMixin): '''An Pressure Controller for the sample delivery system Parameters ---------- pvs : str dict A dictionary containing the PVs of all the pressure controller components name : str The device name Attributes ---------- status : EpicsSignal Connection status of pressure controller pressure1 : EpicsSignal Pressure of 1 enabled1 : EpicsSignal Is 1 enabled limit1 : EpicsSignal High pressure limit of 1 SP1 : EpicsSignal Pressure set point of 1 pressure2 : EpicsSignal Pressure of 2 enabled2 : EpicsSignal Is 2 enabled limit2 : EpicsSignal High pressure limit of 2 SP2 : EpicsSignal Pressure set point of 2 ''' status = FCpt(EpicsSignal, '{self._status}') pressure1 = FCpt(EpicsSignal, '{self._pressure1}') enabled1 = FCpt(EpicsSignal, '{self._enabled1}') limit1 = FCpt(EpicsSignal, '{self._limit1}') SP1 = FCpt(EpicsSignal, '{self._SP1}') pressure2 = FCpt(EpicsSignal, '{self._pressure2}') enabled2 = FCpt(EpicsSignal, '{self._enabled2}') limit2 = FCpt(EpicsSignal, '{self._limit2}') SP2 = FCpt(EpicsSignal, '{self._SP2}') def __init__(self, name, status, pressure1, enabled1, limit1, SP1, pressure2, enabled2, limit2, SP2, **kwargs): self._status = status self._pressure1 = pressure1 self._enabled1 = enabled1 self._limit1 = limit1 self._SP1 = SP1 self._pressure2 = pressure2 self._enabled2 = enabled2 self._limit2 = limit2 self._SP2 = SP2 super().__init__(name=name, **kwargs)
class CoolerShaker(Device, _TableMixin): '''A Cooler/Shaker for the sample delivery system Parameters ---------- pvs : str dict A dictionary containing the PVs of all the cooler/shaker components name : str The device name Attributes ---------- temperature1 : EpicsSignal Temperature of 1 SP1 : EpicsSignal Set point of 1 set_SP1 : EpicsSignal Set the set point for 1 current1 : EpicsSignal Current for 1 temperature2 : EpicsSignal Temperature of 2 SP2 : EpicsSignal Set point of 2 set_SP2 : EpicsSignal Set the set point of 2 current2 : EpicsSignal Current of 2 reboot : EpicsSignal Reboot the cooler/shaker ''' temperature1 = FCpt(EpicsSignal, '{self._temperature1}') SP1 = FCpt(EpicsSignal, '{self._SP1}') set_SP1 = FCpt(EpicsSignal, '{self._set_SP1}') current1 = FCpt(EpicsSignal, '{self._current1}') temperature2 = FCpt(EpicsSignal, '{self._temperature2}') SP2 = FCpt(EpicsSignal, '{self._SP2}') set_SP2 = FCpt(EpicsSignal, '{self._set_SP2}') current2 = FCpt(EpicsSignal, '{self._current2}') reboot = FCpt(EpicsSignal, '{self._reboot}') def __init__(self, name, temperature1, SP1, set_SP1, current1, temperature2, SP2, set_SP2, current2, reboot, **kwargs): self._temperature1 = temperature1 self._SP1 = SP1 self._set_SP1 = set_SP1 self._current1 = current1 self._temperature2 = temperature2 self._SP2 = SP2 self._set_SP2 = set_SP2 self._current2 = current2 self._reboot = reboot super().__init__(name=name, **kwargs)
class CCMX(SyncAxesBase): """Combined motion of the CCM X motors.""" down = FCpt(IMS, '{self.down_prefix}') up = FCpt(IMS, '{self.up_prefix}') tab_component_names = True def __init__(self, down_prefix, up_prefix, *args, **kwargs): self.down_prefix = down_prefix self.up_prefix = up_prefix super().__init__(down_prefix, *args, **kwargs)
class CCMX(SyncAxis): """Combined motion of the CCM X motors.""" down = FCpt(IMS, '{self.down_prefix}') up = FCpt(IMS, '{self.up_prefix}') offset_mode = SyncAxisOffsetMode.AUTO_FIXED tab_component_names = True def __init__(self, down_prefix, up_prefix, *args, **kwargs): self.down_prefix = down_prefix self.up_prefix = up_prefix super().__init__(down_prefix, *args, **kwargs)
class CCMY(SyncAxesBase): """ Combined motion of the CCM Y motors """ down = FCpt(IMS, '{self.down_prefix}') up_north = FCpt(IMS, '{self.up_north_prefix}') up_south = FCpt(IMS, '{self.up_south_prefix}') def __init__(self, down_prefix, up_north_prefix, up_south_prefix, *args, **kwargs): self.down_prefix = down_prefix self.up_north_prefix = up_north_prefix self.up_south_prefix = up_south_prefix super().__init__(down_prefix, *args, **kwargs)
class Sample(Device): egg = Cpt(SampleNested, ':EGG') butter = Cpt(EpicsSignal, ':BUTTER') flour = Cpt(EpicsSignalRO, ':FLOUR') baster = FCpt(EpicsSignal, '{self.drawer}:BASTER') sink = FCpt(EpicsSignal, '{self.sink_location}:SINK') fridge = DDCpt({'milk': (EpicsSignal, ':MILK', {}), 'cheese': (EpicsSignalRO, ':CHEESE', {})}) nothing = Cpt(Signal) def __init__(self, prefix, *, drawer='UNDER_THE_SINK', sink_location='COUNTER', **kwargs): self.drawer = drawer self.sink_location = sink_location super().__init__(prefix, **kwargs)
class PIM(PIMMotor): """ Profile intensity monitor, fully motorized and with a detector. Parameters ---------- prefix : str The EPICS base of the motor name : str A name to refer to the device prefix_det : str, optional The EPICS base PV of the detector. If None, it will be inferred from the motor prefix """ detector = FCpt(PCDSAreaDetector, "{self._prefix_det}", kind='normal') tab_whitelist = ["detector"] def __init__(self, prefix, *, name, prefix_det=None, **kwargs): # Infer the detector PV from the motor PV if not prefix_det: self._section = prefix.split(":")[0] self._imager = prefix.split(":")[1] self._prefix_det = "{0}:{1}:CVV:01".format( self._section, self._imager) else: self._prefix_det = prefix_det super().__init__(prefix, name=name, **kwargs)
class IPM_Wave8(IPMMotion, IPM_Det): """ %s has a `wave8` component which represents the Wave8 used for readout. """ __doc__ = __doc__ % (IPM_base) + basic_positioner_init wave8 = FCpt(Wave8, '{self.prefix_wave8}', prefix_ioc='{self.prefix_ioc}') # Wave8's have sixteen channels _num_channels = 16 _det = 'wave8' def __init__(self, prefix, *, name, prefix_wave8, prefix_ioc=None, **kwargs): self.prefix_wave8 = prefix_wave8 self.prefix_ioc = prefix_ioc super().__init__(prefix, name=name, **kwargs) self.det = self.wave8 def configure(self): raise NotImplementedError
class One(Device): cpt = Cpt(PrefixSignal, 'CPT', kind='normal') fcpt = FCpt(PrefixSignal, '{_fcpt}', kind='normal') def __init__(self, prefix, fcpt, **kwargs): self._fcpt = fcpt super().__init__(prefix, **kwargs)
class IPM_IPIMB(IPMMotion, IPM_Det): """ %s has a `ipimb` component which represents the IPIMB box used for readout. """ __doc__ = __doc__ % (IPM_base) + basic_positioner_init ipimb = FCpt(IPIMB, '{self.prefix_ipimb}', prefix_ioc='{self.prefix_ioc}') # IPIMB's have four channels _num_channels = 4 _det = 'ipimb' def __init__(self, prefix, *, name, prefix_ipimb, prefix_ioc=None, **kwargs): self.prefix_ipimb = prefix_ipimb self.prefix_ioc = prefix_ioc super().__init__(prefix, name=name, **kwargs)
class ProductionCamTriggered(ProductionCamStandard): dg1 = FCpt(DelayGenerator, '{self._dg1_prefix}') # TODO: populate dg1_prefix using happi rather than hard coded value def __init__(self, *args, dg1_prefix=None, **kwargs): self._dg1_prefix = "ES7011:ShutterDelayGenerator:" super().__init__(*args, **kwargs)
class VonHamosFER(VonHamosFE): """ von Hamos spectrometer with Focus, Energy, and Rotation motors. These motors should be run as user stages and have their PVs passed into this object as keyword arguments, as labeled. Parameters ---------- prefix : str, optional von Hamos base PV. name : str A name to refer to the device. prefix_focus : str The EPICS base PV of the motor controlling the spectrometer's focus. prefix_energy : str The EPICS base PV of the motor controlling the spectrometer energy. prefix_rot : str The EPICS base PV of the common rotation motor. """ rot = FCpt(BeckhoffAxis, '{self._prefix_rot}', kind='normal') def __init__(self, *args, name, prefix_rot, **kwargs): self._prefix_rot = prefix_rot if args: super().__init__(args[0], name=name, **kwargs) else: super().__init__('', name=name, **kwargs)
class PulsePickerInOut(PulsePicker, GroupDevice): """ `PulsePicker` paired with a states record to control the Y position. This allows us to insert and remove the entire device from the beam. The inout states record lives in a separate IOC from the main pulsepicker due to versioning issues. The parent IOC is called 'device_states'. We're expecting the resulting states record to have states 'Unknown', 'OUT', and 'IN', in that order. The naming convention for the states is to take the first two segments of the pulsepicker prefix and add 'PP:Y' to the end. So therefore, if the picker is 'TST:DG1:MMS:03', the inout states should be 'TST:DG1:PP:Y'. """ __doc__ += basic_positioner_init inout = FCpt(InOutRecordPositioner, '{self._inout}', kind='normal') states_list = ['OUT', 'OPEN', 'CLOSED'] out_states = ['OUT', 'OPEN'] _state_logic = { 'inout.state': { 1: 'defer', 2: 'OUT', 'IN': 'defer', 'OUT': 'OUT' }, 'blade': { 0: 'OPEN', 1: 'CLOSED', 2: 'CLOSED' } } _state_logic_mode = 'FIRST' # When we move PulsePickerInOut, it moves inout stage_group = [inout] def __init__(self, prefix, **kwargs): # inout follows naming convention parts = prefix.split(':') self._inout = ':'.join(parts[:2] + ['PP', 'Y']) super().__init__(prefix, **kwargs) def _do_move(self, state): """ Handles movement to state 'OUT'. Handles moving the state motor OUT when commands like ``pulsepicker.move('OUT')`` are called, and inserting on other move commands. """ if state.name == 'OUT': self.inout.remove() else: self.inout.insert() super()._do_move(state)
class FakeScalerChannel(Device): # TODO set up monitor on this to automatically change the name chname = FCpt(FakeEpicsSignal, '', kind=Kind.config) s = FCpt(FakeEpicsSignalRO, '', kind=Kind.hinted) preset = FCpt(FakeEpicsSignal, '', kind=Kind.config) gate = FCpt(FakeEpicsSignal, '', string=True, kind=Kind.config) def __init__(self, prefix, ch_num, **kwargs): self._ch_num = ch_num super().__init__(prefix, **kwargs) self.match_name() def match_name(self): #self.s.name = self.chname.get() self.s.name = '{}{:02d}'.format('chan', self._ch_num) self.chname.put('{}{:02d}'.format('chan', self._ch_num))
class Sample(Device): egg = Cpt(SampleNested, ':EGG') butter = Cpt(EpicsSignal, ':BUTTER') flour = Cpt(EpicsSignalRO, ':FLOUR') sink = FCpt(EpicsSignal, '{self.sink_location}:SINK') fridge = DDCpt({'milk': (EpicsSignal, ':MILK', {}), 'cheese': (EpicsSignalRO, ':CHEESE', {})}) nothing = Cpt(Signal) sink_location = 'COUNTER'
class FCCDCam(AreaDetectorCam): sdk_version = Cpt(EpicsSignalRO, 'SDKVersion_RBV') firmware_version = Cpt(EpicsSignalRO, 'FirmwareVersion_RBV') overscan_cols = Cpt(EpicsSignalWithRBV, 'OverscanCols') fcric_gain = Cpt(EpicsSignalWithRBV, 'FCRICGain') fcric_clamp = Cpt(EpicsSignalWithRBV, 'FCRICClamp') temp = FCpt(EpicsSignal, '{self._temp_pv}') def __init__(self, *args, temp_pv=None, **kwargs): self._temp_pv = temp_pv super().__init__(*args, **kwargs)
class Questar(PCDSDetector): ''' Area detector for Inline Questar Camera in CXI Parameters ---------- port_names : str dict A dictionary containing the access port names for the plugins prefix : str Prefix for the PV name of the camera name : str Name of the camera Attributes ---------- ROI : ROIPlugin ROI on original rate image ROI_stats : StatsPlugin Stats on ROI of original rate image ''' ROI = FCpt(ROIPlugin, '{self._ROI_port}') ROI_stats = FCpt(StatsPlugin, '{self._ROI_stats_port}') ROI_image = FCpt(ImagePlugin, '{self._ROI_image_port}') def __init__(self, ROI_port, ROI_stats_port, ROI_image_port, prefix, *args, **kwargs): self._ROI_port = f'{prefix}:{ROI_port}:' self._ROI_stats_port = f'{prefix}:{ROI_stats_port}:' self._ROI_image_port = f'{prefix}:{ROI_image_port}:' super().__init__(prefix, *args, **kwargs) self.ROI_stats.nd_array_port.put(ROI_port) self.ROI_image.nd_array_port.put(ROI_port) self.ROI.enable.put('Enabled') self.ROI_stats.enable.put('Enabled') self.ROI_image.enable.put('Enabled')
class JetCamera(PCDSAreaDetector): """ Area detector for inline and offaxis cameras in CXI. Parameters ---------- prefix : str The base PV for the camera. name : str Name of the camera. ROI_port : str Port for the :class:`~ophyd.areadetector.plugins.ROIPlugin`, which gives an ROI on the original rate image. ROI_stats_port : str Port for the :class:`~ophyd.areadetector.plugins.StatsPlugin`, which gives stats on an ROI of the original rate image. ROI_image_port : str Port for the :class:`~ophyd.areadetector.plugins.ImagePlugin`. """ ROI = FCpt(ROIPlugin, '{prefix}:{_ROI_port}') ROI_stats = FCpt(StatsPlugin, '{prefix}:{_ROI_stats_port}') ROI_image = FCpt(ImagePlugin, '{prefix}:{_ROI_image_port}') def __init__(self, prefix, *, name, ROI_port, ROI_stats_port, ROI_image_port, **kwargs): self._ROI_port = ROI_port self._ROI_stats_port = ROI_stats_port self._ROI_image_port = ROI_image_port super().__init__(prefix, name=name, **kwargs) self.ROI_stats.nd_array_port.put(ROI_port) self.ROI_image.nd_array_port.put(ROI_port) self.ROI.enable.put('Enabled') self.ROI_stats.enable.put('Enabled') self.ROI_image.enable.put('Enabled')
class ProductionCamTriggered(ProductionCamStandard): dg2 = FCpt(DelayGenerator, '{self._dg2_prefix}') dg1 = FCpt(DelayGenerator, '{self._dg1_prefix}') mcs = FCpt(StruckSIS3820MCS, '{self._mcs_prefix}') exposure = Cpt(TriggeredCamExposure, '') def __init__(self, *args, dg1_prefix=None, dg2_prefix=None, mcs_prefix=None, **kwargs): self._dg1_prefix = dg1_prefix self._dg2_prefix = dg2_prefix self._mcs_prefix = mcs_prefix super().__init__(*args, **kwargs) def trigger(self): self.mcs.trigger() return super().trigger() def read(self): self.mcs.read() return super().read()