class AutosavedSimpleIOC(PVGroup): """ An IOC with three uncoupled read/writable PVs Scalar PVs ---------- A (int) B (float) Vectors PVs ----------- C (vector of int) """ autosave_helper = SubGroup(AutosaveHelper) A = autosaved(pvproperty(value=1, record='ao')) B = pvproperty(value=2.0) C = autosaved(pvproperty(value=[1, 2, 3])) subgroup = SubGroup(AutosavedSubgroup)
class CCM(PVGroup): """ A simulated CCM IOC. May require some customization when using a custom prefix. :: pcdsdevices.ccm.CCMCalc.energy_request.suffix = 'sim:{hutch}' ccm = pcdsdevices.ccm.CCM(**{ 'in_pos': 3.3, 'out_pos': 13.18, 'theta0': 0.2311318654103, 'name': 'xcs_ccm', 'alio_prefix': 'sim:XCS:MON:MPZ:01', 'chi2_prefix': 'sim:XCS:MON:PIC:06', 'theta2coarse_prefix': 'sim:XCS:MON:PIC:05', 'theta2fine_prefix': 'sim:XCS:MON:MPZ:02', 'x_down_prefix': 'sim:XCS:MON:MMS:24', 'x_up_prefix': 'sim:XCS:MON:MMS:25', 'y_down_prefix': 'sim:XCS:MON:MMS:26', 'y_up_north_prefix': 'sim:XCS:MON:MMS:27', 'y_up_south_prefix': 'sim:XCS:MON:MMS:28', }) """ calc = SubGroup(CCMCalcGroup, prefix='') theta2fine = SubGroup(CCMMotorGroup, prefix='{{theta2fine_prefix}}') theta2coarse = SubGroup(Motor, prefix='{{theta2coarse_prefix}}') chi2 = SubGroup(Motor, prefix='{{chi2_prefix}}') x = SubGroup(CCMXGroup, prefix='') y = SubGroup(CCMYGroup, prefix='')
class TwinCATStateConfigAll(PVGroup): state01 = SubGroup(TwinCATStateConfigOne, prefix='01:') state02 = SubGroup(TwinCATStateConfigOne, prefix='02:') state03 = SubGroup(TwinCATStateConfigOne, prefix='03:') state04 = SubGroup(TwinCATStateConfigOne, prefix='04:') state05 = SubGroup(TwinCATStateConfigOne, prefix='05:') state06 = SubGroup(TwinCATStateConfigOne, prefix='06:')
class JitterRead(PVGroup): """ When a PV is read add some noise. """ N_per_I_per_s = 200 current = pvproperty(value=[500], dtype=float, read_only=True) @current.startup async def current(self, instance, async_lib): f = (2 * np.pi) / 4 while True: t = time.monotonic() await instance.write(value=[500 + 25 * np.sin(t * f)]) await async_lib.library.sleep(.1) ph = SubGroup(PinHole) edge = SubGroup(Edge) slit = SubGroup(Slit) dot = SubGroup(MovingDot)
class BeamParametersGroup(PVGroup): undulator_info = SubGroup(UndulatorInfoGroup, prefix='') rate = pvproperty(value=10, doc='Repetition rate', units='Hz') charge = pvproperty(value=10, mock_record='longin', units='pC', doc='Bunch charge') async def _recalculate(self, instance, value): await self.k.write(self.undulator_info.calculate_k(self.gap.value)) await self.photon_energy.write( calculate_photon_energy(electron_energy=self.electron_energy.value, period=self.undulator_info.period.value, k=self.k.value)) gap = pvproperty( value=10., doc='Undulator gap', mock_record='ai', units='mm', put=_recalculate, ) k = pvproperty( value=0., doc='Undulator strength (K)', mock_record='ai', units='n/a', ) electron_energy = pvproperty( value=0.0, doc='Electron energy', units='GeV', precision=4, put=_recalculate, ) photon_energy = pvproperty( value=0.0, doc='Photon energy', read_only=True, precision=4, ) @gap.startup async def gap(self, instance, async_lib): # Ensure k/photon energy is calculated on startup await instance.write(instance.value)
class MiniBeamline(PVGroup): """ A collection of detectors coupled to motors and an oscillating beam current. An IOC that provides a simulated pinhole, edge and slit with coupled with a shared global current that oscillates in time. """ N_per_I_per_s = 200 current = pvproperty(value=500, dtype=float, read_only=True) @current.scan(period=0.1) async def current(self, instance, async_lib): current = 500 + 25 * np.sin(time.monotonic() * (2 * np.pi) / 4) await instance.write(value=current) ph = SubGroup(PinHole, doc="Simulated pinhole") edge = SubGroup(Edge, doc="Simulated edge") slit = SubGroup(Slit, doc="Simulated slit") dot = SubGroup(MovingDot, doc="The simulated detector")
class MyPVGroup(PVGroup): 'Example group of PVs, a mix of pvproperties and subgroups' # Create two subgroups: group1 = SubGroup(MySubGroup, prefix="group1:", max_value=5) group2 = SubGroup(MySubGroup, prefix='group2:', max_value=20) # And a third one, using the decorator pattern: @SubGroup(prefix='group3:') class group3(PVGroup): nested_rand = pvproperty( value=1, name="random", doc="A random value between 1 and self.max_value.", ) @nested_rand.scan(period=2.0, stop_on_error=False, use_scan_field=False) async def nested_rand(self, instance, async_lib): max_value = 10 print(f'{instance.pvname} random value from 1 to {max_value}') await instance.write(value=random.randint(1, max_value))
class MyPVGroup(PVGroup): 'Example group of PVs, a mix of pvproperties and subgroups' # PV: {prefix}random @pvproperty async def random(self, instance): logger.debug('read random from %s', type(self).__name__) return random.randint(1, 100) # PVs: {prefix}RECORD_LIKE1.RTYP, .VAL, and .DESC recordlike1 = SubGroup(RecordLike, prefix='RECORD_LIKE1') # PVs: {prefix}recordlike2.RTYP, .VAL, and .DESC recordlike2 = SubGroup(RecordLike) # PV: {prefix}group1:random group1 = SubGroup(MySubGroup) # PV: {prefix}group2-random group2 = SubGroup(MySubGroup, prefix='group2-') # PV: {prefix}group3_prefix:random @SubGroup(prefix='group3_prefix:') class group3(PVGroup): @pvproperty async def random(self, instance): logger.debug('read random from %s', type(self).__name__) return random.randint(1, 100) # PV: {prefix}group4:subgroup4:random # (TODO BUG) {prefix}subgroup4:random @SubGroup class group4(PVGroup): @SubGroup class subgroup4(PVGroup): @pvproperty async def random(self, instance): logger.debug('read random from %s', type(self).__name__) return random.randint(1, 100)
class FakeTwinCATStatePositioner(PVGroup): _delay = 0.2 state_enum_strings = [ 'UNKNOWN', 'OUT', 'Filter 1', 'Filter 2', 'Filter 3', 'Filter 4', 'Filter 5', 'Filter 6', 'Filter 7', 'Filter 8' ] state_get = pvproperty( value=0, name='GET_RBV', record='bo', enum_strings=state_enum_strings, doc='State information enum', dtype=ca.ChannelType.ENUM, ) state_set = pvproperty( value=0, name='SET', enum_strings=state_enum_strings, dtype=ca.ChannelType.ENUM, ) error = pvproperty(value=0.0, name='ERR_RBV') error_id = pvproperty(value=0, name='ERRID_RBV') error_message = pvproperty(dtype=str, name='ERRMSG_RBV') busy = pvproperty(value=0, name='BUSY_RBV') done = pvproperty(value=0, name='DONE_RBV') reset_cmd = pvproperty_with_rbv(dtype=int, name='RESET') config = SubGroup(FakeTwinCATStateConfigAll, prefix='') @state_set.startup async def state_set(self, instance, async_lib): self.async_lib = async_lib # Start as "out" and not unknown await self.state_get.write(1) @state_set.putter async def state_set(self, instance, value): await self.busy.write(1) await self.state_get.write(0) await self.async_lib.library.sleep(self._delay) await self.state_get.write(value) await self.busy.write(0) await self.done.write(1)
class MotorIOC(PVGroup): """ A fake motor IOC, with 3 fake motors. PVs --- mtr1 (motor) mtr2 (motor) mtr3 (motor) """ motor1 = SubGroup(Motor, velocity=1., precision=3, prefix='mtr1') motor2 = SubGroup(Motor, velocity=2., precision=2, prefix='mtr2') motor3 = SubGroup(Motor, velocity=3., precision=2, prefix='mtr3') xps_motor1 = SubGroup(XpsMotor, velocity=3., precision=2, prefix='xps:mtr1') xps_motor2 = SubGroup(XpsMotor, velocity=3., precision=2, prefix='xps:mtr2') xps_motor3 = SubGroup(XpsMotor, velocity=3., precision=2, prefix='xps:mtr3') aero_motor1 = SubGroup(AerotechMotor, velocity=3., precision=2, prefix='aero:mtr1') aero_motor2 = SubGroup(AerotechMotor, velocity=3., precision=2, prefix='aero:mtr2') aero_motor3 = SubGroup(AerotechMotor, velocity=3., precision=2, prefix='aero:mtr3')
class DatabaseBackedJSONRequestGroup(JSONRequestGroup): """ Extends the JSON request-backed PVGroup by storing the gathered information in an external database instance. """ handlers = { 'elastic': ManualElasticHandler, } init_document: Optional[dict] = None db_helper = SubGroup(DatabaseBackedHelper) def __init__(self, *args, index: Optional[str] = None, index_suffix: Optional[str] = None, backend: str, url: str, **kwargs): super().__init__(*args, **kwargs) self.init_document = None # Init here handler_class: Type[DatabaseHandler] = self.handlers[backend] self.db_helper.handler = handler_class( self, url, index=index, index_suffix=index_suffix ) async def __ainit__(self): """ A special async init handler. """ await super().__ainit__() try: self.init_document = await self.db_helper.handler.get_last_document() except Exception: logger.warning( 'Unable to get last database document; are we starting from ' 'scratch or is there a misconfiguration?' ) self.init_document = None
class FakeBeckhoffAxis(PVGroup): plc = SubGroup(FakeBeckhoffAxisPLC, prefix=':PLC:') state = SubGroup(FakeTwinCATStatePositioner, prefix=':STATE:') motor = SubGroup(FakeMotor, velocity=2, prefix='')
class IOCMain(PVGroup): """AT2L0 motion simulator IOC.""" # beam = SubGroup(EVGroup, prefix='LCLS:HXR:BEAM:') # pmps = SubGroup(PMPSGroup, prefix='PMPS:AT2L0:') attenuator = SubGroup(BladeGroup, prefix='AT2L0:XTES:')
class RoisGroup(PVGroup): roi0 = SubGroup(MCAROIGroup, prefix='.R0') roi1 = SubGroup(MCAROIGroup, prefix='.R1') roi2 = SubGroup(MCAROIGroup, prefix='.R2') roi3 = SubGroup(MCAROIGroup, prefix='.R3') roi4 = SubGroup(MCAROIGroup, prefix='.R4') roi5 = SubGroup(MCAROIGroup, prefix='.R5') roi6 = SubGroup(MCAROIGroup, prefix='.R6') roi7 = SubGroup(MCAROIGroup, prefix='.R7') roi8 = SubGroup(MCAROIGroup, prefix='.R8') roi9 = SubGroup(MCAROIGroup, prefix='.R9') roi10 = SubGroup(MCAROIGroup, prefix='.R10') roi11 = SubGroup(MCAROIGroup, prefix='.R11') roi12 = SubGroup(MCAROIGroup, prefix='.R12') roi13 = SubGroup(MCAROIGroup, prefix='.R13') roi14 = SubGroup(MCAROIGroup, prefix='.R14') roi15 = SubGroup(MCAROIGroup, prefix='.R15') roi16 = SubGroup(MCAROIGroup, prefix='.R16') roi17 = SubGroup(MCAROIGroup, prefix='.R17') roi18 = SubGroup(MCAROIGroup, prefix='.R18') roi19 = SubGroup(MCAROIGroup, prefix='.R19') roi20 = SubGroup(MCAROIGroup, prefix='.R20') roi21 = SubGroup(MCAROIGroup, prefix='.R21') roi22 = SubGroup(MCAROIGroup, prefix='.R22') roi23 = SubGroup(MCAROIGroup, prefix='.R23') roi24 = SubGroup(MCAROIGroup, prefix='.R24') roi25 = SubGroup(MCAROIGroup, prefix='.R25') roi26 = SubGroup(MCAROIGroup, prefix='.R26') roi27 = SubGroup(MCAROIGroup, prefix='.R27') roi28 = SubGroup(MCAROIGroup, prefix='.R28') roi29 = SubGroup(MCAROIGroup, prefix='.R29') roi30 = SubGroup(MCAROIGroup, prefix='.R30') roi31 = SubGroup(MCAROIGroup, prefix='.R31')
class McaDxpIOC(PVGroup): mca = SubGroup(EpicsMCAGroup, prefix='mca') dxp = SubGroup(EpicsDXPGroup, prefix='dxp:')
class BtpsPrototypeSimulator(PVGroup): """ A simulator for key BTPS PVs in the control system. Listed PVs do not include the default "SIM:" prefix. PVs --- Motor - Linear LAS:BTS:MCS2:01:m1 (ioc-las-bts-mcs1) LAS:BTS:MCS2:01:m4 (ioc-las-bts-mcs1) LAS:BTS:MCS2:01:m7 (ioc-las-bts-mcs1) Motor - Rotary LAS:BTS:MCS2:01:m2 (ioc-las-bts-mcs1) LAS:BTS:MCS2:01:m6 (ioc-las-bts-mcs1) LAS:BTS:MCS2:01:m8 (ioc-las-bts-mcs1) Motor - Goniometer LAS:BTS:MCS2:01:m3 (ioc-las-bts-mcs1) LAS:BTS:MCS2:01:m5 (ioc-las-bts-mcs1) LAS:BTS:MCS2:01:m9 (ioc-las-bts-mcs1) NF Camera LAS:LHN:BAY1:CAM:01 (ioc-lhn-bay1-nf-01) LAS:LHN:BAY3:CAM:01 (?, assumed) LAS:LHN:BAY4:CAM:01 (ioc-lhn-bay4-nf-01) FF Camera LAS:LHN:BAY1:CAM:02 (ioc-lhn-bay1-ff-01) LAS:LHN:BAY3:CAM:02 (?, assumed) LAS:LHN:BAY4:CAM:02 (ioc-lhn-bay4-ff-01) The following are sourced from plc-las-bts: Source Gate Valve LTLHN:LS1:VGC:01 (ioc-las-bts) LTLHN:LS5:VGC:01 (ioc-las-bts) LTLHN:LS8:VGC:01 (ioc-las-bts) Destination Gate Valve PV LTLHN:LD8:VGC:01 (ioc-las-bts) - TMO - IP1 LTLHN:LD10:VGC:01 (ioc-las-bts) - TMO - IP2 LTLHN:LD2:VGC:01 (ioc-las-bts) - TMO - IP3 LTLHN:LD6:VGC:01 (ioc-las-bts) - RIX - qRIXS LTLHN:LD4:VGC:01 (ioc-las-bts) - RIX - ChemRIXS LTLHN:LD14:VGC:01 (ioc-las-bts) - XPP LTLHN:LD9:VGC:01 (ioc-las-bts) - Laser Lab The following *will be* sourced from plc-las-bts: LSS Shutter Request LTLHN:LS1:LST:REQ (ioc-las-lhn-bhc-05 -> ioc-las-bts) LTLHN:LS5:LST:REQ (ioc-las-lhn-bhc-05 -> ioc-las-bts) LTLHN:LS8:LST:REQ (ioc-las-lhn-bhc-05 -> ioc-las-bts) LSS Shutter State - Open LTLHN:LS1:LST:OPN (ioc-las-lhn-bhc-05 -> ioc-las-bts) LTLHN:LS5:LST:OPN (ioc-las-lhn-bhc-05 -> ioc-las-bts) LTLHN:LS8:LST:OPN (ioc-las-lhn-bhc-05 -> ioc-las-bts) LSS Shutter State - Closed LTLHN:LS1:LST:CLS (ioc-las-lhn-bhc-05 -> ioc-las-bts) LTLHN:LS5:LST:CLS (ioc-las-lhn-bhc-05 -> ioc-las-bts) LTLHN:LS8:LST:CLS (ioc-las-lhn-bhc-05 -> ioc-las-bts) """ # Linear motors (ioc-las-bts-mcs1) m1 = SubGroup(Motor, prefix="LAS:BTS:MCS2:01:m1", user_limits=(0, 0)) m4 = SubGroup(Motor, prefix="LAS:BTS:MCS2:01:m4", user_limits=(0, 2000)) m7 = SubGroup(Motor, prefix="LAS:BTS:MCS2:01:m7", position=405.0, user_limits=(400, 1446.53)) # Rotary motors m2 = SubGroup(Motor, prefix="LAS:BTS:MCS2:01:m2", user_limits=(0, 0)) m6 = SubGroup(Motor, prefix="LAS:BTS:MCS2:01:m6", user_limits=(-95, 95)) m8 = SubGroup(Motor, prefix="LAS:BTS:MCS2:01:m8", user_limits=(-300, 300)) # Goniometers m3 = SubGroup(Motor, prefix="LAS:BTS:MCS2:01:m3", user_limits=(0, 0)) m5 = SubGroup(Motor, prefix="LAS:BTS:MCS2:01:m5", user_limits=(0, 0)) m9 = SubGroup(Motor, prefix="LAS:BTS:MCS2:01:m9", user_limits=(0, 0)) nf_cam_bay1 = SubGroup(StatsPlugin, prefix="LAS:LHN:BAY1:CAM:01:Stats1:") nf_cam_bay3 = SubGroup(StatsPlugin, prefix="LAS:LHN:BAY3:CAM:01:Stats1:") nf_cam_bay4 = SubGroup(StatsPlugin, prefix="LAS:LHN:BAY4:CAM:01:Stats1:") ff_cam_bay1 = SubGroup(StatsPlugin, prefix="LAS:LHN:BAY1:CAM:02:Stats1:") ff_cam_bay3 = SubGroup(StatsPlugin, prefix="LAS:LHN:BAY3:CAM:02:Stats1:") ff_cam_bay4 = SubGroup(StatsPlugin, prefix="LAS:LHN:BAY4:CAM:02:Stats1:")
class SimDetectorCamGroup(PVGroup): # configuration_names = pvproperty(name=None, dtype=str) array_counter = pvproperty_with_rbv(name='ArrayCounter', dtype=int) array_rate = pvproperty(name='ArrayRate_RBV', dtype=float, read_only=True) asyn_io = pvproperty(name='AsynIO', dtype=int) nd_attributes_file = pvproperty(name='NDAttributesFile', dtype=str, max_length=256) pool_alloc_buffers = pvproperty(name='PoolAllocBuffers', dtype=int, read_only=True) pool_free_buffers = pvproperty(name='PoolFreeBuffers', dtype=int, read_only=True) pool_max_buffers = pvproperty(name='PoolMaxBuffers', dtype=int, read_only=True) pool_max_mem = pvproperty(name='PoolMaxMem', dtype=float, read_only=True) pool_used_buffers = pvproperty(name='PoolUsedBuffers', dtype=float, read_only=True) pool_used_mem = pvproperty(name='PoolUsedMem', dtype=float, read_only=True) port_name = pvproperty(name='PortName_RBV', dtype=str, read_only=True) acquire = pvproperty_with_rbv(name='Acquire', dtype=int) acquire_period = pvproperty_with_rbv(name='AcquirePeriod', dtype=float) acquire_time = pvproperty_with_rbv(name='AcquireTime', dtype=float) array_callbacks = pvproperty_with_rbv(name='ArrayCallbacks', dtype=int) class SimDetectorCamArraySizeGroup(PVGroup): array_size_x = pvproperty(name='ArraySizeX_RBV', dtype=int, read_only=True) array_size_y = pvproperty(name='ArraySizeY_RBV', dtype=int, read_only=True) array_size_z = pvproperty(name='ArraySizeZ_RBV', dtype=int, read_only=True) array_size = SubGroup(SimDetectorCamArraySizeGroup, prefix='') array_size_bytes = pvproperty(name='ArraySize_RBV', dtype=int, read_only=True) bin_x = pvproperty_with_rbv(name='BinX', dtype=int) bin_y = pvproperty_with_rbv(name='BinY', dtype=int) color_mode = pvproperty_with_rbv(name='ColorMode', dtype=int) data_type = pvproperty_with_rbv(name='DataType', dtype=int) detector_state = pvproperty(name='DetectorState_RBV', dtype=int, read_only=True) frame_type = pvproperty_with_rbv(name='FrameType', dtype=int) gain = pvproperty_with_rbv(name='Gain', dtype=float) image_mode = pvproperty_with_rbv(name='ImageMode', dtype=int) manufacturer = pvproperty(name='Manufacturer_RBV', dtype=str, read_only=True) class SimDetectorCamMaxSizeGroup(PVGroup): max_size_x = pvproperty(name='MaxSizeX_RBV', dtype=int, read_only=True) max_size_y = pvproperty(name='MaxSizeY_RBV', dtype=int, read_only=True) max_size = SubGroup(SimDetectorCamMaxSizeGroup, prefix='') min_x = pvproperty_with_rbv(name='MinX', dtype=int) min_y = pvproperty_with_rbv(name='MinY', dtype=int) model = pvproperty(name='Model_RBV', dtype=str, read_only=True) num_exposures = pvproperty_with_rbv(name='NumExposures', dtype=int) num_exposures_counter = pvproperty(name='NumExposuresCounter_RBV', dtype=int, read_only=True) num_images = pvproperty_with_rbv(name='NumImages', dtype=int) num_images_counter = pvproperty(name='NumImagesCounter_RBV', dtype=int, read_only=True) read_status = pvproperty(name='ReadStatus', dtype=int) class SimDetectorCamReverseGroup(PVGroup): reverse_x = pvproperty_with_rbv(name='ReverseX', dtype=int) reverse_y = pvproperty_with_rbv(name='ReverseY', dtype=int) reverse = SubGroup(SimDetectorCamReverseGroup, prefix='') shutter_close_delay = pvproperty_with_rbv(name='ShutterCloseDelay', dtype=float) shutter_close_epics = pvproperty(name='ShutterCloseEPICS', dtype=float) shutter_control = pvproperty_with_rbv(name='ShutterControl', dtype=int) shutter_control_epics = pvproperty(name='ShutterControlEPICS', dtype=int) shutter_fanout = pvproperty(name='ShutterFanout', dtype=int) shutter_mode = pvproperty_with_rbv(name='ShutterMode', dtype=int) shutter_open_delay = pvproperty_with_rbv(name='ShutterOpenDelay', dtype=float) shutter_open_epics = pvproperty(name='ShutterOpenEPICS', dtype=float) shutter_status_epics = pvproperty(name='ShutterStatusEPICS_RBV', dtype=int, read_only=True) shutter_status = pvproperty(name='ShutterStatus_RBV', dtype=int, read_only=True) class SimDetectorCamSizeGroup(PVGroup): size_x = pvproperty_with_rbv(name='SizeX', dtype=int) size_y = pvproperty_with_rbv(name='SizeY', dtype=int) size = SubGroup(SimDetectorCamSizeGroup, prefix='') status_message = pvproperty(name='StatusMessage_RBV', dtype=str, max_length=256, read_only=True) string_from_server = pvproperty(name='StringFromServer_RBV', dtype=str, max_length=256, read_only=True) string_to_server = pvproperty(name='StringToServer_RBV', dtype=str, max_length=256, read_only=True) temperature = pvproperty_with_rbv(name='Temperature', dtype=float) temperature_actual = pvproperty(name='TemperatureActual', dtype=float) time_remaining = pvproperty(name='TimeRemaining_RBV', dtype=float, read_only=True) trigger_mode = pvproperty_with_rbv(name='TriggerMode', dtype=int) class SimDetectorCamGainRgbGroup(PVGroup): gain_red = pvproperty_with_rbv(name='GainRed', dtype=float) gain_green = pvproperty_with_rbv(name='GainGreen', dtype=float) gain_blue = pvproperty_with_rbv(name='GainBlue', dtype=float) gain_rgb = SubGroup(SimDetectorCamGainRgbGroup, prefix='') class SimDetectorCamGainXyGroup(PVGroup): gain_x = pvproperty_with_rbv(name='GainX', dtype=float) gain_y = pvproperty_with_rbv(name='GainY', dtype=float) gain_xy = SubGroup(SimDetectorCamGainXyGroup, prefix='') noise = pvproperty_with_rbv(name='Noise', dtype=int) class SimDetectorCamPeakNumGroup(PVGroup): peak_num_x = pvproperty_with_rbv(name='PeakNumX', dtype=int) peak_num_y = pvproperty_with_rbv(name='PeakNumY', dtype=int) peak_num = SubGroup(SimDetectorCamPeakNumGroup, prefix='') class SimDetectorCamPeakStartGroup(PVGroup): peak_start_x = pvproperty_with_rbv(name='PeakStartX', dtype=int) peak_start_y = pvproperty_with_rbv(name='PeakStartY', dtype=int) peak_start = SubGroup(SimDetectorCamPeakStartGroup, prefix='') class SimDetectorCamPeakStepGroup(PVGroup): peak_step_x = pvproperty_with_rbv(name='PeakStepX', dtype=int) peak_step_y = pvproperty_with_rbv(name='PeakStepY', dtype=int) peak_step = SubGroup(SimDetectorCamPeakStepGroup, prefix='') peak_variation = pvproperty_with_rbv(name='PeakVariation', dtype=int) class SimDetectorCamPeakWidthGroup(PVGroup): peak_width_x = pvproperty_with_rbv(name='PeakWidthX', dtype=int) peak_width_y = pvproperty_with_rbv(name='PeakWidthY', dtype=int) peak_width = SubGroup(SimDetectorCamPeakWidthGroup, prefix='') reset = pvproperty_with_rbv(name='Reset', dtype=int) sim_mode = pvproperty_with_rbv(name='SimMode', dtype=int)
class ServerExample(PVGroup): io_put_queue = None io_get_queue = None device = None io_get_queue = None io_put_queue = None # Creates the SubGroup for this IO with 'seq.' as subgroup name. The PV banes become: TEST:SERVER.seq.CMD (and ACK, values). seq = SubGroup(Server, prefix='seq.') # Define PVs for this specific server example_pv = pvproperty(value=0.0) VAL = pvproperty(value=0.0) # run this function when examnple_pv is initilized @example_pv.startup async def example_pv(self, instance, async_lib): debug('* request method called at server startup @example_pv.startup') self.io_get_queue = async_lib.ThreadsafeQueue() self.io_put_queue = async_lib.ThreadsafeQueue() while True: print(self.io_put_queue) if self.io_put_queue is not None: value = await self.io_put_queue.async_get() print(f'Got put request from the system main: {value}') if 'example_pv' in list(value.keys()): await self.example_pv.write(value['example_pv']) if 'VAL' in list(value.keys()): await self.VAL.write(value['VAL']) else: await async_lib.library.sleep(1) # run this function when someone writes in example_pv. @example_pv.putter async def example_pv(self, instance, value): print(f"PV: {'example_pv'} Got 'put' request from outside: new value is {value}") # run this function when someone reads from example_pv. @example_pv.getter async def example_pv(self, instance): print(f"PV: {'example_pv'} Got 'get' request from outside") @VAL.putter #A Putter for the PV with name CMD async def VAL(self, instance, value): print('VAL putter received update for the {}, sending new value {}'.format('VAL',value)) print(f'self.system = {self.system}') await self.system_io_execute(pv_name = 'VAL', value = value) return value async def system_io_execute(self, pv_name, value): """ wrapper used to submit commands to the system code for execution Parameters ---------- pv_name: (string) string name of the PV value: new value for the PV specified in the pv_name field Returns ------- Examples -------- >>> self.system_io_execute(pv_name = 'CMD', value = '[0]') """ from ubcs_auxiliary.threading import new_thread print("@system_io_execute: The {} putter was called with value {}. The system connected is {}".format(pv_name,value,self.system)) if self.system is not None: new_thread(self.system.io_execute,pv_name, value)
class CCMXGroup(PVGroup): # pseudo = SubGroup(PseudoSingleInterfaceGroup, prefix='None') down = SubGroup(ImsMotor, prefix='{{x_down_prefix}}', velocity=10) up = SubGroup(ImsMotor, prefix='{{x_up_prefix}}', velocity=10)
class AcceleratorGroup(PVGroup): """Accelerator IOC simulator for PMPS.""" hxu = SubGroup(HxuBeamlineGroup) sxu = SubGroup(SxuBeamlineGroup)
class EightFilterGroup(FilterGroup): """ PVGroup for a single blade with 8 spots for filters. This inherits and overrides methods from :class:`FilterGroup`. If a filter is selected, values such as transmission and material will reflect those of the selected filter. .. note:: As this is the standard holder for AT1K4 and similar attenuators, a dynamic "NFilterGroup" is currently unnecessary. Parameters ---------- prefix : str PV prefix. index : int Index of the blade in the system. """ N_FILTERS = 8 def __init__(self, prefix, *, index, **kwargs): self.table = None super().__init__(prefix, index=index, **kwargs) self._last_photon_energy = 0.0 self.filters = { idx: getattr(self, f'filter{idx:02d}') for idx in range(1, self.N_FILTERS + 1) } # TODO: caproto pvproperty doesn't really work this way, sadly: # self.material.read_only = True # self.thickness.read_only = True filter01 = SubGroup(FilterGroup, prefix='FILTER:01:', index=1) filter02 = SubGroup(FilterGroup, prefix='FILTER:02:', index=2) filter03 = SubGroup(FilterGroup, prefix='FILTER:03:', index=3) filter04 = SubGroup(FilterGroup, prefix='FILTER:04:', index=4) filter05 = SubGroup(FilterGroup, prefix='FILTER:05:', index=5) filter06 = SubGroup(FilterGroup, prefix='FILTER:06:', index=6) filter07 = SubGroup(FilterGroup, prefix='FILTER:07:', index=7) filter08 = SubGroup(FilterGroup, prefix='FILTER:08:', index=8) inserted_filter_index = pvproperty( name='InsertedFilter_RBV', value=0, read_only=True, ) def load_data(self, formula): # Stub load_data, as `self.table` is not used here, instead relying # on the inserted filter's information. ... @property def inserted_filter_state(self) -> State: """The current filter state, according to inserted_filter_index.""" if self.is_stuck.value != 'Not stuck': return self.get_stuck_state() return State(self.inserted_filter_index.value) @property def inserted_filter(self) -> Optional[FilterGroup]: """The currently inserted filter.""" return self.filters.get(self.inserted_filter_state.filter_index, None) def get_transmission(self, photon_energy_ev): """ Get the transmission for the given photon energy based on the material and thickness configured. Parameters ---------- energy_ev : float The photon energy [eV]. Returns ------- transmission : float Normalized transmission value. """ flt = self.inserted_filter if flt is None: return 1.0 return flt.get_transmission(photon_energy_ev) async def set_inserted_filter_state(self, state: State): await self.inserted_filter_index.write(int(state)) await self._update() async def _update(self): """Proxy the inserted filter's information to transmission, etc.""" flt = self.inserted_filter if flt is None: transmission = 1.0 transmission_3omega = 1.0 closest_index = 0 closest_energy = 0.0 thickness = 0.0 material = 'None' else: transmission = flt.transmission.value transmission_3omega = flt.transmission_3omega.value closest_index = flt.closest_index.value closest_energy = flt.closest_energy.value thickness = flt.thickness.value material = flt.material.value await self.transmission.write(transmission, verify_value=False) await self.transmission_3omega.write(transmission_3omega, verify_value=False) await self.closest_index.write(closest_index, verify_value=False) await self.closest_energy.write(closest_energy, verify_value=False) await self.thickness.write(thickness, verify_value=False) await self.material.write(material, verify_value=False) async def set_photon_energy(self, energy_ev: float): """ Set the current photon energy to determine transmission. Parameters ---------- energy_ev : float The photon energy [eV]. """ self._last_photon_energy = energy_ev for flt in self.filters.values(): await flt.set_photon_energy(energy_ev) await self._update() @property def active_filters(self) -> Dict[int, FilterGroup]: """A dictionary of all filters that are in active, working order.""" return { idx: filt for idx, filt in self.filters.items() if filt.active.value == "True" }
class EpicsScalerGroup(PVGroup): count = pvproperty(name='.CNT', dtype=int) count_mode = pvproperty(value='OneShot', name='.CONT', dtype=ChannelType.ENUM, enum_strings=['OneShot', 'AutoCount']) delay = pvproperty(name='.DLY', dtype=float) auto_count_delay = pvproperty(name='.DLY1', dtype=float) class ChannelsGroup(PVGroup): chan1 = pvproperty(value=0, name='.S1', dtype=int, read_only=True) chan2 = pvproperty(value=0, name='.S2', dtype=int, read_only=True) chan3 = pvproperty(value=0, name='.S3', dtype=int, read_only=True) chan4 = pvproperty(value=0, name='.S4', dtype=int, read_only=True) chan5 = pvproperty(value=0, name='.S5', dtype=int, read_only=True) chan6 = pvproperty(value=0, name='.S6', dtype=int, read_only=True) chan7 = pvproperty(value=0, name='.S7', dtype=int, read_only=True) chan8 = pvproperty(value=0, name='.S8', dtype=int, read_only=True) chan9 = pvproperty(value=0, name='.S9', dtype=int, read_only=True) chan10 = pvproperty(value=0, name='.S10', dtype=int, read_only=True) chan11 = pvproperty(value=0, name='.S11', dtype=int, read_only=True) chan12 = pvproperty(value=0, name='.S12', dtype=int, read_only=True) chan13 = pvproperty(value=0, name='.S13', dtype=int, read_only=True) chan14 = pvproperty(value=0, name='.S14', dtype=int, read_only=True) chan15 = pvproperty(value=0, name='.S15', dtype=int, read_only=True) chan16 = pvproperty(value=0, name='.S16', dtype=int, read_only=True) chan17 = pvproperty(value=0, name='.S17', dtype=int, read_only=True) chan18 = pvproperty(value=0, name='.S18', dtype=int, read_only=True) chan19 = pvproperty(value=0, name='.S19', dtype=int, read_only=True) chan20 = pvproperty(value=0, name='.S20', dtype=int, read_only=True) chan21 = pvproperty(value=0, name='.S21', dtype=int, read_only=True) chan22 = pvproperty(value=0, name='.S22', dtype=int, read_only=True) chan23 = pvproperty(value=0, name='.S23', dtype=int, read_only=True) chan24 = pvproperty(value=0, name='.S24', dtype=int, read_only=True) chan25 = pvproperty(value=0, name='.S25', dtype=int, read_only=True) chan26 = pvproperty(value=0, name='.S26', dtype=int, read_only=True) chan27 = pvproperty(value=0, name='.S27', dtype=int, read_only=True) chan28 = pvproperty(value=0, name='.S28', dtype=int, read_only=True) chan29 = pvproperty(value=0, name='.S29', dtype=int, read_only=True) chan30 = pvproperty(value=0, name='.S30', dtype=int, read_only=True) chan31 = pvproperty(value=0, name='.S31', dtype=int, read_only=True) chan32 = pvproperty(value=0, name='.S32', dtype=int, read_only=True) channels = SubGroup(ChannelsGroup, prefix='') class NamesGroup(PVGroup): name1 = pvproperty(value='name', name='.NM1', dtype=ChannelType.STRING) name2 = pvproperty(value='name', name='.NM2', dtype=ChannelType.STRING) name3 = pvproperty(value='name', name='.NM3', dtype=ChannelType.STRING) name4 = pvproperty(value='name', name='.NM4', dtype=ChannelType.STRING) name5 = pvproperty(value='name', name='.NM5', dtype=ChannelType.STRING) name6 = pvproperty(value='name', name='.NM6', dtype=ChannelType.STRING) name7 = pvproperty(value='name', name='.NM7', dtype=ChannelType.STRING) name8 = pvproperty(value='name', name='.NM8', dtype=ChannelType.STRING) name9 = pvproperty(value='name', name='.NM9', dtype=ChannelType.STRING) name10 = pvproperty(value='name', name='.NM10', dtype=ChannelType.STRING) name11 = pvproperty(value='name', name='.NM11', dtype=ChannelType.STRING) name12 = pvproperty(value='name', name='.NM12', dtype=ChannelType.STRING) name13 = pvproperty(value='name', name='.NM13', dtype=ChannelType.STRING) name14 = pvproperty(value='name', name='.NM14', dtype=ChannelType.STRING) name15 = pvproperty(value='name', name='.NM15', dtype=ChannelType.STRING) name16 = pvproperty(value='name', name='.NM16', dtype=ChannelType.STRING) name17 = pvproperty(value='name', name='.NM17', dtype=ChannelType.STRING) name18 = pvproperty(value='name', name='.NM18', dtype=ChannelType.STRING) name19 = pvproperty(value='name', name='.NM19', dtype=ChannelType.STRING) name20 = pvproperty(value='name', name='.NM20', dtype=ChannelType.STRING) name21 = pvproperty(value='name', name='.NM21', dtype=ChannelType.STRING) name22 = pvproperty(value='name', name='.NM22', dtype=ChannelType.STRING) name23 = pvproperty(value='name', name='.NM23', dtype=ChannelType.STRING) name24 = pvproperty(value='name', name='.NM24', dtype=ChannelType.STRING) name25 = pvproperty(value='name', name='.NM25', dtype=ChannelType.STRING) name26 = pvproperty(value='name', name='.NM26', dtype=ChannelType.STRING) name27 = pvproperty(value='name', name='.NM27', dtype=ChannelType.STRING) name28 = pvproperty(value='name', name='.NM28', dtype=ChannelType.STRING) name29 = pvproperty(value='name', name='.NM29', dtype=ChannelType.STRING) name30 = pvproperty(value='name', name='.NM30', dtype=ChannelType.STRING) name31 = pvproperty(value='name', name='.NM31', dtype=ChannelType.STRING) name32 = pvproperty(value='name', name='.NM32', dtype=ChannelType.STRING) names = SubGroup(NamesGroup, prefix='') time = pvproperty(name='.T', dtype=float) freq = pvproperty(name='.FREQ', dtype=float) preset_time = pvproperty(name='.TP', dtype=float) auto_count_time = pvproperty(name='.TP1', dtype=float) class PresetsGroup(PVGroup): preset1 = pvproperty(name='.PR1', dtype=int) preset2 = pvproperty(name='.PR2', dtype=int) preset3 = pvproperty(name='.PR3', dtype=int) preset4 = pvproperty(name='.PR4', dtype=int) preset5 = pvproperty(name='.PR5', dtype=int) preset6 = pvproperty(name='.PR6', dtype=int) preset7 = pvproperty(name='.PR7', dtype=int) preset8 = pvproperty(name='.PR8', dtype=int) preset9 = pvproperty(name='.PR9', dtype=int) preset10 = pvproperty(name='.PR10', dtype=int) preset11 = pvproperty(name='.PR11', dtype=int) preset12 = pvproperty(name='.PR12', dtype=int) preset13 = pvproperty(name='.PR13', dtype=int) preset14 = pvproperty(name='.PR14', dtype=int) preset15 = pvproperty(name='.PR15', dtype=int) preset16 = pvproperty(name='.PR16', dtype=int) preset17 = pvproperty(name='.PR17', dtype=int) preset18 = pvproperty(name='.PR18', dtype=int) preset19 = pvproperty(name='.PR19', dtype=int) preset20 = pvproperty(name='.PR20', dtype=int) preset21 = pvproperty(name='.PR21', dtype=int) preset22 = pvproperty(name='.PR22', dtype=int) preset23 = pvproperty(name='.PR23', dtype=int) preset24 = pvproperty(name='.PR24', dtype=int) preset25 = pvproperty(name='.PR25', dtype=int) preset26 = pvproperty(name='.PR26', dtype=int) preset27 = pvproperty(name='.PR27', dtype=int) preset28 = pvproperty(name='.PR28', dtype=int) preset29 = pvproperty(name='.PR29', dtype=int) preset30 = pvproperty(name='.PR30', dtype=int) preset31 = pvproperty(name='.PR31', dtype=int) preset32 = pvproperty(name='.PR32', dtype=int) presets = SubGroup(PresetsGroup, prefix='') class GatesGroup(PVGroup): gate1 = pvproperty(name='.G1', dtype=int) gate2 = pvproperty(name='.G2', dtype=int) gate3 = pvproperty(name='.G3', dtype=int) gate4 = pvproperty(name='.G4', dtype=int) gate5 = pvproperty(name='.G5', dtype=int) gate6 = pvproperty(name='.G6', dtype=int) gate7 = pvproperty(name='.G7', dtype=int) gate8 = pvproperty(name='.G8', dtype=int) gate9 = pvproperty(name='.G9', dtype=int) gate10 = pvproperty(name='.G10', dtype=int) gate11 = pvproperty(name='.G11', dtype=int) gate12 = pvproperty(name='.G12', dtype=int) gate13 = pvproperty(name='.G13', dtype=int) gate14 = pvproperty(name='.G14', dtype=int) gate15 = pvproperty(name='.G15', dtype=int) gate16 = pvproperty(name='.G16', dtype=int) gate17 = pvproperty(name='.G17', dtype=int) gate18 = pvproperty(name='.G18', dtype=int) gate19 = pvproperty(name='.G19', dtype=int) gate20 = pvproperty(name='.G20', dtype=int) gate21 = pvproperty(name='.G21', dtype=int) gate22 = pvproperty(name='.G22', dtype=int) gate23 = pvproperty(name='.G23', dtype=int) gate24 = pvproperty(name='.G24', dtype=int) gate25 = pvproperty(name='.G25', dtype=int) gate26 = pvproperty(name='.G26', dtype=int) gate27 = pvproperty(name='.G27', dtype=int) gate28 = pvproperty(name='.G28', dtype=int) gate29 = pvproperty(name='.G29', dtype=int) gate30 = pvproperty(name='.G30', dtype=int) gate31 = pvproperty(name='.G31', dtype=int) gate32 = pvproperty(name='.G32', dtype=int) gates = SubGroup(GatesGroup, prefix='') update_rate = pvproperty(name='.RATE', dtype=int) auto_count_update_rate = pvproperty(name='.RAT1', dtype=int) egu = pvproperty(value='EGU', name='.EGU', dtype=ChannelType.STRING)
class ImagePluginGroup(PVGroup): # configuration_names = pvproperty(name=None, dtype=str) array_counter = pvproperty_with_rbv(name='ArrayCounter', dtype=int) array_rate = pvproperty(name='ArrayRate_RBV', dtype=float, read_only=True) asyn_io = pvproperty(name='AsynIO', dtype=int) nd_attributes_file = pvproperty(name='NDAttributesFile', dtype=str, max_length=256) pool_alloc_buffers = pvproperty(name='PoolAllocBuffers', dtype=int, read_only=True) pool_free_buffers = pvproperty(name='PoolFreeBuffers', dtype=int, read_only=True) pool_max_buffers = pvproperty(name='PoolMaxBuffers', dtype=int, read_only=True) pool_max_mem = pvproperty(name='PoolMaxMem', dtype=float, read_only=True) pool_used_buffers = pvproperty(name='PoolUsedBuffers', dtype=float, read_only=True) pool_used_mem = pvproperty(name='PoolUsedMem', dtype=float, read_only=True) port_name = pvproperty(name='PortName_RBV', dtype=str, read_only=True) # asyn_pipeline_config = pvproperty(name=None, dtype=str) # width = pvproperty(name='ArraySize0_RBV', dtype=int, read_only=True) # height = pvproperty(name='ArraySize1_RBV', dtype=int, read_only=True) # depth = pvproperty(name='ArraySize2_RBV', dtype=int, read_only=True) class ImagePluginArraySizeGroup(PVGroup): height = pvproperty(name='ArraySize1_RBV', dtype=int, read_only=True) width = pvproperty(name='ArraySize0_RBV', dtype=int, read_only=True) depth = pvproperty(name='ArraySize2_RBV', dtype=int, read_only=True) array_size = SubGroup(ImagePluginArraySizeGroup, prefix='') bayer_pattern = pvproperty(name='BayerPattern_RBV', dtype=int, read_only=True) blocking_callbacks = pvproperty_with_rbv(name='BlockingCallbacks', dtype=str) color_mode = pvproperty(name='ColorMode_RBV', dtype=int, read_only=True) data_type = pvproperty(name='DataType_RBV', dtype=str, read_only=True) # dim0_sa = pvproperty(name='Dim0SA', dtype=int, max_length=10) # dim1_sa = pvproperty(name='Dim1SA', dtype=int, max_length=10) # dim2_sa = pvproperty(name='Dim2SA', dtype=int, max_length=10) class ImagePluginDimSaGroup(PVGroup): dim0 = pvproperty(name='Dim0SA', dtype=int, max_length=10) dim1 = pvproperty(name='Dim1SA', dtype=int, max_length=10) dim2 = pvproperty(name='Dim2SA', dtype=int, max_length=10) dim_sa = SubGroup(ImagePluginDimSaGroup, prefix='') dimensions = pvproperty(name='Dimensions_RBV', dtype=int, max_length=10, read_only=True) dropped_arrays = pvproperty_with_rbv(name='DroppedArrays', dtype=int) enable = pvproperty_with_rbv(name='EnableCallbacks', dtype=str) min_callback_time = pvproperty_with_rbv(name='MinCallbackTime', dtype=float) nd_array_address = pvproperty_with_rbv(name='NDArrayAddress', dtype=int) nd_array_port = pvproperty_with_rbv(name='NDArrayPort', dtype=str) ndimensions = pvproperty(name='NDimensions_RBV', dtype=int, read_only=True) plugin_type = pvproperty(name='PluginType_RBV', dtype=str, read_only=True) queue_free = pvproperty(name='QueueFree', dtype=int) queue_free_low = pvproperty(name='QueueFreeLow', dtype=float) queue_size = pvproperty(name='QueueSize', dtype=int) queue_use = pvproperty(name='QueueUse', dtype=float) queue_use_high = pvproperty(name='QueueUseHIGH', dtype=float) queue_use_hihi = pvproperty(name='QueueUseHIHI', dtype=float) time_stamp = pvproperty(name='TimeStamp_RBV', dtype=float, read_only=True) unique_id = pvproperty(name='UniqueId_RBV', dtype=int, read_only=True) array_data = pvproperty(name='ArrayData', dtype=int, max_length=300000) # NOTE: this portion written by hand: @array_data.startup async def array_data(self, instance, async_lib): await self.plugin_type.write('NDPluginStdArrays') w, h = 256, 256 await self.array_size.width.write(w) await self.array_size.height.write(h) await self.array_size.depth.write(0) await self.ndimensions.write(2) await self.dimensions.write([w, h, 0]) async for image in get_images(w, h): await self.array_data.write(image.flatten()) await async_lib.library.sleep(1.0)
class Fluke985Main(Fluke985Base): autosave_helper = SubGroup(AutosaveHelper, file_manager=RotatingFileManager(autosave)) autosave_helper.filename = autosave
class DetectorGroup(PVGroup): # configuration_names = pvproperty(name=None, dtype=str) class SimDetectorCamGroup(PVGroup): # configuration_names = pvproperty(name=None, dtype=str) array_counter = pvproperty_with_rbv(name='ArrayCounter', dtype=int) array_rate = pvproperty(name='ArrayRate_RBV', dtype=float, read_only=True) asyn_io = pvproperty(name='AsynIO', dtype=int) nd_attributes_file = pvproperty(name='NDAttributesFile', dtype=str, max_length=256) pool_alloc_buffers = pvproperty(name='PoolAllocBuffers', dtype=int, read_only=True) pool_free_buffers = pvproperty(name='PoolFreeBuffers', dtype=int, read_only=True) pool_max_buffers = pvproperty(name='PoolMaxBuffers', dtype=int, read_only=True) pool_max_mem = pvproperty(name='PoolMaxMem', dtype=float, read_only=True) pool_used_buffers = pvproperty(name='PoolUsedBuffers', dtype=float, read_only=True) pool_used_mem = pvproperty(name='PoolUsedMem', dtype=float, read_only=True) port_name = pvproperty(name='PortName_RBV', dtype=str, read_only=True) acquire = pvproperty_with_rbv(name='Acquire', dtype=int) acquire_period = pvproperty_with_rbv(name='AcquirePeriod', dtype=float) acquire_time = pvproperty_with_rbv(name='AcquireTime', dtype=float) array_callbacks = pvproperty_with_rbv(name='ArrayCallbacks', dtype=int) class SimDetectorCamArraySizeGroup(PVGroup): array_size_x = pvproperty(name='ArraySizeX_RBV', dtype=int, read_only=True) array_size_y = pvproperty(name='ArraySizeY_RBV', dtype=int, read_only=True) array_size_z = pvproperty(name='ArraySizeZ_RBV', dtype=int, read_only=True) array_size = SubGroup(SimDetectorCamArraySizeGroup, prefix='') array_size_bytes = pvproperty(name='ArraySize_RBV', dtype=int, read_only=True) bin_x = pvproperty_with_rbv(name='BinX', dtype=int) bin_y = pvproperty_with_rbv(name='BinY', dtype=int) color_mode = pvproperty_with_rbv(name='ColorMode', dtype=int) data_type = pvproperty_with_rbv(name='DataType', dtype=int) detector_state = pvproperty(name='DetectorState_RBV', dtype=int, read_only=True) frame_type = pvproperty_with_rbv(name='FrameType', dtype=int) gain = pvproperty_with_rbv(name='Gain', dtype=float) image_mode = pvproperty_with_rbv(name='ImageMode', dtype=int) manufacturer = pvproperty(name='Manufacturer_RBV', dtype=str, read_only=True) class SimDetectorCamMaxSizeGroup(PVGroup): max_size_x = pvproperty(name='MaxSizeX_RBV', dtype=int, read_only=True) max_size_y = pvproperty(name='MaxSizeY_RBV', dtype=int, read_only=True) max_size = SubGroup(SimDetectorCamMaxSizeGroup, prefix='') min_x = pvproperty_with_rbv(name='MinX', dtype=int) min_y = pvproperty_with_rbv(name='MinY', dtype=int) model = pvproperty(name='Model_RBV', dtype=str, read_only=True) num_exposures = pvproperty_with_rbv(name='NumExposures', dtype=int) num_exposures_counter = pvproperty(name='NumExposuresCounter_RBV', dtype=int, read_only=True) num_images = pvproperty_with_rbv(name='NumImages', dtype=int) num_images_counter = pvproperty(name='NumImagesCounter_RBV', dtype=int, read_only=True) read_status = pvproperty(name='ReadStatus', dtype=int) class SimDetectorCamReverseGroup(PVGroup): reverse_x = pvproperty_with_rbv(name='ReverseX', dtype=int) reverse_y = pvproperty_with_rbv(name='ReverseY', dtype=int) reverse = SubGroup(SimDetectorCamReverseGroup, prefix='') shutter_close_delay = pvproperty_with_rbv(name='ShutterCloseDelay', dtype=float) shutter_close_epics = pvproperty(name='ShutterCloseEPICS', dtype=float) shutter_control = pvproperty_with_rbv(name='ShutterControl', dtype=int) shutter_control_epics = pvproperty(name='ShutterControlEPICS', dtype=int) shutter_fanout = pvproperty(name='ShutterFanout', dtype=int) shutter_mode = pvproperty_with_rbv(name='ShutterMode', dtype=int) shutter_open_delay = pvproperty_with_rbv(name='ShutterOpenDelay', dtype=float) shutter_open_epics = pvproperty(name='ShutterOpenEPICS', dtype=float) shutter_status_epics = pvproperty(name='ShutterStatusEPICS_RBV', dtype=int, read_only=True) shutter_status = pvproperty(name='ShutterStatus_RBV', dtype=int, read_only=True) class SimDetectorCamSizeGroup(PVGroup): size_x = pvproperty_with_rbv(name='SizeX', dtype=int) size_y = pvproperty_with_rbv(name='SizeY', dtype=int) size = SubGroup(SimDetectorCamSizeGroup, prefix='') status_message = pvproperty(name='StatusMessage_RBV', dtype=str, max_length=256, read_only=True) string_from_server = pvproperty(name='StringFromServer_RBV', dtype=str, max_length=256, read_only=True) string_to_server = pvproperty(name='StringToServer_RBV', dtype=str, max_length=256, read_only=True) temperature = pvproperty_with_rbv(name='Temperature', dtype=float) temperature_actual = pvproperty(name='TemperatureActual', dtype=float) time_remaining = pvproperty(name='TimeRemaining_RBV', dtype=float, read_only=True) trigger_mode = pvproperty_with_rbv(name='TriggerMode', dtype=int) class SimDetectorCamGainRgbGroup(PVGroup): gain_red = pvproperty_with_rbv(name='GainRed', dtype=float) gain_green = pvproperty_with_rbv(name='GainGreen', dtype=float) gain_blue = pvproperty_with_rbv(name='GainBlue', dtype=float) gain_rgb = SubGroup(SimDetectorCamGainRgbGroup, prefix='') class SimDetectorCamGainXyGroup(PVGroup): gain_x = pvproperty_with_rbv(name='GainX', dtype=float) gain_y = pvproperty_with_rbv(name='GainY', dtype=float) gain_xy = SubGroup(SimDetectorCamGainXyGroup, prefix='') noise = pvproperty_with_rbv(name='Noise', dtype=int) class SimDetectorCamPeakNumGroup(PVGroup): peak_num_x = pvproperty_with_rbv(name='PeakNumX', dtype=int) peak_num_y = pvproperty_with_rbv(name='PeakNumY', dtype=int) peak_num = SubGroup(SimDetectorCamPeakNumGroup, prefix='') class SimDetectorCamPeakStartGroup(PVGroup): peak_start_x = pvproperty_with_rbv(name='PeakStartX', dtype=int) peak_start_y = pvproperty_with_rbv(name='PeakStartY', dtype=int) peak_start = SubGroup(SimDetectorCamPeakStartGroup, prefix='') class SimDetectorCamPeakStepGroup(PVGroup): peak_step_x = pvproperty_with_rbv(name='PeakStepX', dtype=int) peak_step_y = pvproperty_with_rbv(name='PeakStepY', dtype=int) peak_step = SubGroup(SimDetectorCamPeakStepGroup, prefix='') peak_variation = pvproperty_with_rbv(name='PeakVariation', dtype=int) class SimDetectorCamPeakWidthGroup(PVGroup): peak_width_x = pvproperty_with_rbv(name='PeakWidthX', dtype=int) peak_width_y = pvproperty_with_rbv(name='PeakWidthY', dtype=int) peak_width = SubGroup(SimDetectorCamPeakWidthGroup, prefix='') reset = pvproperty_with_rbv(name='Reset', dtype=int) sim_mode = pvproperty_with_rbv(name='SimMode', dtype=int) cam = SubGroup(SimDetectorCamGroup, prefix='cam1:') class ImagePluginGroup(PVGroup): # configuration_names = pvproperty(name=None, dtype=str) array_counter = pvproperty_with_rbv(name='ArrayCounter', dtype=int) array_rate = pvproperty(name='ArrayRate_RBV', dtype=float, read_only=True) asyn_io = pvproperty(name='AsynIO', dtype=int) nd_attributes_file = pvproperty(name='NDAttributesFile', dtype=str, max_length=256) pool_alloc_buffers = pvproperty(name='PoolAllocBuffers', dtype=int, read_only=True) pool_free_buffers = pvproperty(name='PoolFreeBuffers', dtype=int, read_only=True) pool_max_buffers = pvproperty(name='PoolMaxBuffers', dtype=int, read_only=True) pool_max_mem = pvproperty(name='PoolMaxMem', dtype=float, read_only=True) pool_used_buffers = pvproperty(name='PoolUsedBuffers', dtype=float, read_only=True) pool_used_mem = pvproperty(name='PoolUsedMem', dtype=float, read_only=True) port_name = pvproperty(name='PortName_RBV', dtype=str, read_only=True) # asyn_pipeline_config = pvproperty(name=None, dtype=str) # width = pvproperty(name='ArraySize0_RBV', dtype=int, read_only=True) # height = pvproperty(name='ArraySize1_RBV', dtype=int, read_only=True) # depth = pvproperty(name='ArraySize2_RBV', dtype=int, read_only=True) class ImagePluginArraySizeGroup(PVGroup): height = pvproperty(name='ArraySize1_RBV', dtype=int, read_only=True) width = pvproperty(name='ArraySize0_RBV', dtype=int, read_only=True) depth = pvproperty(name='ArraySize2_RBV', dtype=int, read_only=True) array_size = SubGroup(ImagePluginArraySizeGroup, prefix='') bayer_pattern = pvproperty(name='BayerPattern_RBV', dtype=int, read_only=True) blocking_callbacks = pvproperty_with_rbv(name='BlockingCallbacks', dtype=str) color_mode = pvproperty(name='ColorMode_RBV', dtype=int, read_only=True) data_type = pvproperty(name='DataType_RBV', dtype=str, read_only=True) # dim0_sa = pvproperty(name='Dim0SA', dtype=int, max_length=10) # dim1_sa = pvproperty(name='Dim1SA', dtype=int, max_length=10) # dim2_sa = pvproperty(name='Dim2SA', dtype=int, max_length=10) class ImagePluginDimSaGroup(PVGroup): dim0 = pvproperty(name='Dim0SA', dtype=int, max_length=10) dim1 = pvproperty(name='Dim1SA', dtype=int, max_length=10) dim2 = pvproperty(name='Dim2SA', dtype=int, max_length=10) dim_sa = SubGroup(ImagePluginDimSaGroup, prefix='') dimensions = pvproperty(name='Dimensions_RBV', dtype=int, max_length=10, read_only=True) dropped_arrays = pvproperty_with_rbv(name='DroppedArrays', dtype=int) enable = pvproperty_with_rbv(name='EnableCallbacks', dtype=str) min_callback_time = pvproperty_with_rbv(name='MinCallbackTime', dtype=float) nd_array_address = pvproperty_with_rbv(name='NDArrayAddress', dtype=int) nd_array_port = pvproperty_with_rbv(name='NDArrayPort', dtype=str) ndimensions = pvproperty(name='NDimensions_RBV', dtype=int, read_only=True) plugin_type = pvproperty(name='PluginType_RBV', dtype=str, read_only=True) queue_free = pvproperty(name='QueueFree', dtype=int) queue_free_low = pvproperty(name='QueueFreeLow', dtype=float) queue_size = pvproperty(name='QueueSize', dtype=int) queue_use = pvproperty(name='QueueUse', dtype=float) queue_use_high = pvproperty(name='QueueUseHIGH', dtype=float) queue_use_hihi = pvproperty(name='QueueUseHIHI', dtype=float) time_stamp = pvproperty(name='TimeStamp_RBV', dtype=float, read_only=True) unique_id = pvproperty(name='UniqueId_RBV', dtype=int, read_only=True) array_data = pvproperty(name='ArrayData', dtype=int, max_length=300000) # NOTE: this portion written by hand: @array_data.startup async def array_data(self, instance, async_lib): await self.plugin_type.write('NDPluginStdArrays') w, h = 256, 256 await self.array_size.width.write(w) await self.array_size.height.write(h) await self.array_size.depth.write(0) await self.ndimensions.write(2) await self.dimensions.write([w, h, 0]) async for image in get_images(w, h): await self.array_data.write(image.flatten()) await async_lib.library.sleep(1.0) # END hand-written portion image1 = SubGroup(ImagePluginGroup, prefix='image1:')
class CCMYGroup(PVGroup): # pseudo = SubGroup(PseudoSingleInterfaceGroup, prefix='None') down = SubGroup(ImsMotor, prefix='{{y_down_prefix}}') up_north = SubGroup(ImsMotor, prefix='{{y_up_north_prefix}}') up_south = SubGroup(ImsMotor, prefix='{{y_up_south_prefix}}')
class AcceleratorGroup(PVGroup): hxu = SubGroup(HxuBeamlineGroup) sxu = SubGroup(SxuBeamlineGroup)
for i in range(1,5): u = User(i, f'user_{i}') users[u.id] = u for i in range(1,3): m = Machine(i, f'machine_{i}') machines[m.id] = m external_pvprops = {} for k,v in users.items(): v.exportPvs(external_pvprops) for k,v in machines.items(): v.exportPvs(external_pvprops) more_props = {} for i in range(1,6): more_props[f'g{i}'] = SubGroup(Group, prefix=f'group{i}:') external_pvprops.update(more_props) FullIOC = type('FullIOC', (SimpleIOC,), external_pvprops) ioc = FullIOC(**ioc_options) dispatcher_thread = Thread(target = run_dispatcher) dispatcher_thread.start() run(ioc.pvdb, **run_options)
class IOCBase(PVGroup): """ Base for attenuator IOCs. This is extended dynamically with SubGroups in `at2l0.create_ioc` or `sxr.create_ioc`. """ filters: Dict[int, PVGroup] prefix: str # Set by subclass in `create_ioc_class`: motors: Dict[str, List[str]] monitor_pvnames: Dict[str, str] first_filter: int num_filters: int def __init__(self, prefix, **kwargs): self.num_filters = len(self.filter_index_to_attribute) self.first_filter = min(self.filter_index_to_attribute) super().__init__(prefix, **kwargs) self.prefix = prefix self.filters = { idx: getattr(self, attr) for idx, attr in self.filter_index_to_attribute.items() } self.monitor_pvnames = dict( ev=expand_macros(self.macros['ev_pv'], self.macros), pmps_run=expand_macros(self.macros['pmps_run_pv'], self.macros), pmps_tdes=expand_macros(self.macros['pmps_tdes_pv'], self.macros), motors=self.motors, ) autosave_helper = SubGroup(AutosaveHelper) stats_helper = SubGroup(StatusHelper, prefix=':STATS:') @classmethod def create_ioc_class( cls, filters: Dict[int, str], subgroups: Dict[str, SubGroup], motor_prefixes: Dict[int, str], ) -> Type[PVGroup]: """ Helper that creates a new, complete IOC PVGroup class from the base. Parameters ---------- filters : dict Dictionary of filter index to attribute name. Mirrored in ``filter_index_to_attribute`` on the returned class. subgroups : dict Dictionary of subgroups to add, which should include one per filter and also a system subgroup. motor_prefixes : dict Dictionary of motor index to PV prefix. Used to generate the list of get, set, and error PVs for each motor. """ assert 'sys' in subgroups, 'Missing system subgroup' class IOCMain(IOCBase): filter_index_to_attribute = dict(filters) motors = { 'get': [f'{pv}:GET_RBV' for pv in motor_prefixes.values()], 'set': [f'{pv}:SET' for pv in motor_prefixes.values()], 'error': [f'{pv}:ERR_RBV' for pv in motor_prefixes.values()], } locals().update(**subgroups) return IOCMain
class SplitAndDelayIOC(PVGroup): """ A stand-in split and delay IOC, including: * Aerotech stages * The rest is TODO """ default_velo = 3. default_prec = 2 t1_tth = SubGroup(AerotechMotor, velocity=default_velo, precision=default_prec, prefix=':T1:TTH') t1_th1 = SubGroup(AerotechMotor, velocity=default_velo, precision=default_prec, prefix=':T1:TH1') t1_th2 = SubGroup(AerotechMotor, velocity=default_velo, precision=default_prec, prefix=':T1:TH2') t1_x = SubGroup(AerotechMotor, velocity=default_velo, precision=default_prec, prefix=':T1:X') t1_l = SubGroup(AerotechMotor, velocity=default_velo, precision=default_prec, prefix=':T1:L') t4_tth = SubGroup(AerotechMotor, velocity=default_velo, precision=default_prec, prefix=':T4:TTH') t4_th1 = SubGroup(AerotechMotor, velocity=default_velo, precision=default_prec, prefix=':T4:TH1') t4_th2 = SubGroup(AerotechMotor, velocity=default_velo, precision=default_prec, prefix=':T4:TH2') t4_x = SubGroup(AerotechMotor, velocity=default_velo, precision=default_prec, prefix=':T4:X') t4_l = SubGroup(AerotechMotor, velocity=default_velo, precision=default_prec, prefix=':T4:L') t2_th = SubGroup(AerotechMotor, velocity=default_velo, precision=default_prec, prefix=':T2:TH') t2_x = SubGroup(AerotechMotor, velocity=default_velo, precision=default_prec, prefix=':T2:X') t3_th = SubGroup(AerotechMotor, velocity=default_velo, precision=default_prec, prefix=':T3:TH') t3_x = SubGroup(AerotechMotor, velocity=default_velo, precision=default_prec, prefix=':T3:X') dia_di_x = SubGroup(AerotechMotor, velocity=default_velo, precision=default_prec, prefix=':DIA:DI:X') dia_dd_x = SubGroup(AerotechMotor, velocity=default_velo, precision=default_prec, prefix=':DIA:DD:X') dia_dd_y = SubGroup(AerotechMotor, velocity=default_velo, precision=default_prec, prefix=':DIA:DD:Y') dia_do_x = SubGroup(AerotechMotor, velocity=default_velo, precision=default_prec, prefix=':DIA:DO:X') dia_dci_x = SubGroup(AerotechMotor, velocity=default_velo, precision=default_prec, prefix=':DIA:DCI:X') dia_dcc_x = SubGroup(AerotechMotor, velocity=default_velo, precision=default_prec, prefix=':DIA:DCC:X') dia_dcc_y = SubGroup(AerotechMotor, velocity=default_velo, precision=default_prec, prefix=':DIA:DCC:Y') dia_dco_x = SubGroup(AerotechMotor, velocity=default_velo, precision=default_prec, prefix=':DIA:DCO:X') t1_y1 = SubGroup(AttocubeMotor, prefix=':T1:Y1') t1_y2 = SubGroup(AttocubeMotor, prefix=':T1:Y2') t1_chi1 = SubGroup(AttocubeMotor, prefix=':T1:CHI1') t1_chi2 = SubGroup(AttocubeMotor, prefix=':T1:CHI2') t1_dh = SubGroup(AttocubeMotor, prefix=':T1:DH') t4_y1 = SubGroup(AttocubeMotor, prefix=':T4:Y1') t4_y2 = SubGroup(AttocubeMotor, prefix=':T4:Y2') t4_chi1 = SubGroup(AttocubeMotor, prefix=':T4:CHI1') t4_chi2 = SubGroup(AttocubeMotor, prefix=':T4:CHI2') t4_dh = SubGroup(AttocubeMotor, prefix=':T4:DH') n2_t1_gps = pvproperty(name=':N2:T1:GPS', value=1.0) n2_t1_vgp = pvproperty(name=':N2:T1:VGP', value=1.0) n2_t4_gps = pvproperty(name=':N2:T4:GPS', value=1.0) n2_t4_vgp = pvproperty(name=':N2:T4:VGP', value=1.0) t1_n2_t1_gps = pvproperty(name=':T1:N2:T1:GPS', value=1.0) t4_n2_t4_gps = pvproperty(name=':T4:N2:T4:GPS', value=1.0) vac_gps = pvproperty(name=':VAC:GPS', value=1.0) vac_vgp = pvproperty(name=':VAC:VGP', value=1.0)