class DodgyEpicsScaler(Device): '''SynApps Scaler Record interface''' # tigger + trigger mode count = C(DodgyEpicsSignal, '.CNT', trigger_value=1) count_mode = C(DodgyEpicsSignal, '.CONT', string=True) # delay from triggering to starting counting delay = C(DodgyEpicsSignal, '.DLY') auto_count_delay = C(DodgyEpicsSignal, '.DLY1') # the data channels = DDC(_scaler_fields(DodgyEpicsSignal, 'chan', '.S', range(1, 33))) names = DDC(_scaler_fields(DodgyEpicsSignal, 'name', '.NM', range(1, 33))) time = C(DodgyEpicsSignal, '.T') freq = C(DodgyEpicsSignal, '.FREQ') preset_time = C(DodgyEpicsSignal, '.TP') auto_count_time = C(DodgyEpicsSignal, '.TP1') presets = DDC( _scaler_fields(DodgyEpicsSignal, 'preset', '.PR', range(1, 33))) gates = DDC(_scaler_fields(DodgyEpicsSignal, 'gate', '.G', range(1, 33))) update_rate = C(DodgyEpicsSignal, '.RATE') auto_count_update_rate = C(DodgyEpicsSignal, '.RAT1') egu = C(DodgyEpicsSignal, '.EGU') def __init__(self, prefix, *, read_attrs=None, configuration_attrs=None, name=None, parent=None, **kwargs): if read_attrs is None: read_attrs = ['channels', 'time'] if configuration_attrs is None: configuration_attrs = [ 'preset_time', 'presets', 'gates', 'names', 'freq', 'auto_count_time', 'count_mode', 'delay', 'auto_count_delay', 'egu' ] super().__init__(prefix, read_attrs=read_attrs, configuration_attrs=configuration_attrs, name=name, parent=parent, **kwargs) self.stage_sigs.update([('count_mode', 0)]) for channel in ['channels.chan2', 'channels.chan3', 'channels.chan4']: getattr(self, channel).kind = 'hinted'
class EpicsSwaitRecord(Device): """synApps swait record: used as $(P):userCalc$(N)""" desc = Cpt(EpicsSignal, '.DESC') scan = Cpt(EpicsSignal, '.SCAN') calc = Cpt(EpicsSignal, '.CALC') val = Cpt(EpicsSignalRO, '.VAL') prec = Cpt(EpicsSignal, '.PREC') oevt = Cpt(EpicsSignal, '.OEVT') outn = Cpt(EpicsSignal, '.OUTN') odly = Cpt(EpicsSignal, '.ODLY') doln = Cpt(EpicsSignal, '.DOLN') dold = Cpt(EpicsSignal, '.DOLD') dopt = Cpt(EpicsSignal, '.DOPT') oopt = Cpt(EpicsSignal, '.OOPT') flnk = Cpt(EpicsSignal, '.FLNK') channels = DDC(_swait_channels("A B C D E F G H I J K L".split())) def reset(self): """set all fields to default values""" self.desc.put(self.desc.pvname.split(".")[0]) self.scan.put("Passive") self.calc.put("0") self.prec.put("5") self.dold.put(0) self.doln.put("") self.dopt.put("Use VAL") self.flnk.put("0") self.odly.put(0) self.oopt.put("Every Time") self.outn.put("") for letter in self.channels.read_attrs: channel = self.channels.__getattr__(letter) channel.reset()
class ScalerMCA(Device): _default_read_attrs = ('channels', 'current_channel') _default_configuration_attrs = ('nuse', 'prescale') channels = DDC( {f'mca{k:02d}': (EpicsSignal, f"mca{k}", {}) for k in range(1, 33)}) startall = C(EpicsSignal, 'StartAll', string=True) stopall = C(EpicsSignal, 'StopAll', string=True) eraseall = C(EpicsSignal, 'EraseAll', string=True) erasestart = C(EpicsSignal, 'EraseStart', string=True) current_channel = C(EpicsSignal, 'CurrentChannel') nuse = C(EpicsSignal, 'NuseAll') prescale = C(EpicsSignal, 'Prescale') # high is acquiring status = C(EpicsSignal, 'Acquiring', string=True) def stage(self): super().stage() self.eraseall.put('Erase') def stop(self): self.stopall.put('Stop') def trigger(self): self.erasestart.put('Erase') return StatusBase()
class SwaitRecord(EpicsRecordDeviceCommonAll): """ synApps swait record: used as $(P):userCalc$(N) .. autosummary:: ~reset """ precision = Cpt(EpicsSignal, ".PREC") high_operating_range = Cpt(EpicsSignal, ".HOPR") low_operating_range = Cpt(EpicsSignal, ".LOPR") calculated_value = Cpt(EpicsSignal, ".VAL") calculation = Cpt(EpicsSignal, ".CALC") output_link_pv = Cpt(EpicsSignal, '.OUTN') output_location_name = Cpt(EpicsSignal, '.DOLN') output_location_data = Cpt(EpicsSignal, '.DOLD') output_data_option = Cpt(EpicsSignal, ".DOPT") output_execute_option = Cpt(EpicsSignal, ".OOPT") output_execution_delay = Cpt(EpicsSignal, ".ODLY") event_to_issue = Cpt(EpicsSignal, ".OEVT") read_attrs = APS_utils.itemizer("channels.%s", CHANNEL_LETTERS_LIST) hints = {'fields': read_attrs} channels = DDC(_swait_channels(CHANNEL_LETTERS_LIST)) @property def value(self): return self.calculated_value.value def reset(self): """set all fields to default values""" pvname = self.description.pvname.split(".")[0] self.description.put(pvname) self.scanning_rate.put("Passive") self.calculation.put("0") self.precision.put("5") self.output_location_data.put(0) self.output_location_name.put("") self.output_data_option.put("Use VAL") self.forward_link.put("0") self.output_execution_delay.put(0) self.output_execute_option.put("Every Time") self.output_link_pv.put("") for letter in self.channels.read_attrs: channel = getattr(self.channels, letter) if isinstance(channel, SwaitRecordChannel): channel.reset() self.read_attrs = ["channels.%s" % c for c in CHANNEL_LETTERS_LIST] self.hints = {'fields': self.read_attrs} self.read_attrs.append('calculated_value')
class swaitRecord(Device): """ synApps swait record: used as $(P):userCalc$(N) .. autosummary:: ~reset """ desc = Cpt(EpicsSignal, '.DESC') scan = Cpt(EpicsSignal, '.SCAN') calc = Cpt(EpicsSignal, '.CALC') val = Cpt(EpicsSignalRO, '.VAL') prec = Cpt(EpicsSignal, '.PREC') process = Cpt(EpicsSignal, '.PROC') oevt = Cpt(EpicsSignal, '.OEVT') outn = Cpt(EpicsSignal, '.OUTN') odly = Cpt(EpicsSignal, '.ODLY') doln = Cpt(EpicsSignal, '.DOLN') dold = Cpt(EpicsSignal, '.DOLD') dopt = Cpt(EpicsSignal, '.DOPT') oopt = Cpt(EpicsSignal, '.OOPT') flnk = Cpt(EpicsSignal, '.FLNK') hints = { 'fields': ["channels.%s" % c for c in "A B C D E F G H I J K L".split()] } read_attrs = ["channels.%s" % c for c in "A B C D E F G H I J K L".split()] channels = DDC(_swait_channels("A B C D E F G H I J K L".split())) def reset(self): """set all fields to default values""" self.desc.put(self.desc.pvname.split(".")[0]) self.scan.put("Passive") self.calc.put("0") self.prec.put("5") self.dold.put(0) self.doln.put("") self.dopt.put("Use VAL") self.flnk.put("0") self.odly.put(0) self.oopt.put("Every Time") self.outn.put("") for letter in self.channels.read_attrs: channel = getattr(self.channels, letter) if isinstance(channel, swaitRecordChannel): channel.reset() self.hints = { 'fields': ["channels.%s" % c for c in "A B C D E F G H I J K L".split()] } self.read_attrs = [ "channels.%s" % c for c in "A B C D E F G H I J K L".split() ] self.read_attrs.append('val')
class AttenuatorCalculator_AT2L0(AttenuatorCalculatorBase): """ Solid attenuator variant from the LCLS-II XTES project. Parameters ---------- prefix : str Full Solid Attenuator base PV. name : str Alias for the Solid Attenuator. """ tab_component_names = True first_filter = 2 num_filters = 18 # "filters" DDC holds all the individual components: _filter_parent = 'filters' _filter_index_to_attr = { idx: f'filter_{idx:02d}' for idx in range(first_filter, num_filters + first_filter) } # Creates filters from 2 to num_filters, with attributes filter_02 and so # on. filters = DDC( {attr: (AttenuatorCalculatorFilter, f':FILTER:{idx:02d}:', {'index': idx}) for idx, attr in _filter_index_to_attr.items() } ) def format_status_info(self, status_info): """ Override status info handler to render the attenuator. """ table = utils.format_status_table( status_info.get('filters', {}), row_to_key=self._filter_index_to_attr, column_to_key={ 'Active': 'active', 'Material': 'material', 'Thickness [um]': 'thickness', 'Stuck': 'is_stuck', 'Transmission': 'transmission', 'Transmission 3 Omega': 'transmission_3omega', }, row_identifier='Filter', ) return str(table)
class EpicsScaler(Device): '''SynApps Scaler Record interface''' _default_configuration_attrs = ('preset_time', 'presets', 'gates', 'names', 'freq', 'auto_count_time', 'count_mode', 'delay', 'auto_count_delay', 'egu') _default_read_attrs = ('channels', 'time') # tigger + trigger mode count = C(EpicsSignal, '.CNT', trigger_value=1) count_mode = C(EpicsSignal, '.CONT', string=True) # delay from triggering to starting counting delay = C(EpicsSignal, '.DLY') auto_count_delay = C(EpicsSignal, '.DLY1') # the data channels = DDC(_scaler_fields(EpicsSignalRO, 'chan', '.S', range(1, 33))) names = DDC(_scaler_fields(EpicsSignal, 'name', '.NM', range(1, 33))) time = C(EpicsSignal, '.T') freq = C(EpicsSignal, '.FREQ') preset_time = C(EpicsSignal, '.TP') auto_count_time = C(EpicsSignal, '.TP1') presets = DDC(_scaler_fields(EpicsSignal, 'preset', '.PR', range(1, 33))) gates = DDC(_scaler_fields(EpicsSignal, 'gate', '.G', range(1, 33))) update_rate = C(EpicsSignal, '.RATE') auto_count_update_rate = C(EpicsSignal, '.RAT1') egu = C(EpicsSignal, '.EGU') def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.stage_sigs.update([('count_mode', 0)])
class SRXScaler(EpicsScaler): acquire_mode = Cpt(EpicsSignal, 'AcquireMode') acquiring = Cpt(EpicsSignal, 'Acquiring') asyn = Cpt(EpicsSignal, 'Asyn') channel1_source = Cpt(EpicsSignal, 'Channel1Source') channel_advance = Cpt(EpicsSignal, 'ChannelAdvance', string=True) channels = DDC(_scaler_fields('chan', '.S', range(1, 33))) client_wait = Cpt(EpicsSignal, 'ClientWait') count_on_start = Cpt(EpicsSignal, 'CountOnStart') current_channel = Cpt(EpicsSignal, 'CurrentChannel') disable_auto_count = Cpt(EpicsSignal, 'DisableAutoCount') do_read_all = Cpt(EpicsSignal, 'DoReadAll') dwell = Cpt(EpicsSignal, 'Dwell') elapsed_real = Cpt(EpicsSignal, 'ElapsedReal') enable_client_wait = Cpt(EpicsSignal, 'EnableClientWait') erase_all = Cpt(EpicsSignal, 'EraseAll') erase_start = Cpt(EpicsSignal, 'EraseStart') firmware = Cpt(EpicsSignal, 'Firmware') hardware_acquiring = Cpt(EpicsSignal, 'HardwareAcquiring') input_mode = Cpt(EpicsSignal, 'InputMode') max_channels = Cpt(EpicsSignal, 'MaxChannels') model = Cpt(EpicsSignal, 'Model') mux_output = Cpt(EpicsSignal, 'MUXOutput') nuse_all = Cpt(EpicsSignal, 'NuseAll') output_mode = Cpt(EpicsSignal, 'OutputMode') output_polarity = Cpt(EpicsSignal, 'OutputPolarity') prescale = Cpt(EpicsSignal, 'Prescale') preset_real = Cpt(EpicsSignal, 'PresetReal') read_all = Cpt(EpicsSignal, 'ReadAll') read_all_once = Cpt(EpicsSignal, 'ReadAllOnce') set_acquiring = Cpt(EpicsSignal, 'SetAcquiring') set_client_wait = Cpt(EpicsSignal, 'SetClientWait') snl_connected = Cpt(EpicsSignal, 'SNL_Connected') software_channel_advance = Cpt(EpicsSignal, 'SoftwareChannelAdvance') count_mode = Cpt(EpicsSignal, '.CONT') start_all = Cpt(EpicsSignal, 'StartAll') stop_all = Cpt(EpicsSignal, 'StopAll') user_led = Cpt(EpicsSignal, 'UserLED') wfrm = Cpt(EpicsSignal, 'Wfrm') mca1 = Cpt(EpicsSignalRO, 'mca1') mca2 = Cpt(EpicsSignalRO, 'mca2') mca3 = Cpt(EpicsSignalRO, 'mca3') mca4 = Cpt(EpicsSignalRO, 'mca4') def __init__(self, prefix, **kwargs): super().__init__(prefix, **kwargs) self.stage_sigs[self.count_mode] = 'OneShot'
class SRXScaler(EpicsScaler): acquire_mode = Cpt(EpicsSignal, "AcquireMode") acquiring = Cpt(EpicsSignal, "Acquiring") asyn = Cpt(EpicsSignal, "Asyn") channel1_source = Cpt(EpicsSignal, "Channel1Source") channel_advance = Cpt(EpicsSignal, "ChannelAdvance", string=True) channels = DDC(_scaler_fields("chan", ".S", range(1, 33))) client_wait = Cpt(EpicsSignal, "ClientWait") count_on_start = Cpt(EpicsSignal, "CountOnStart") current_channel = Cpt(EpicsSignal, "CurrentChannel") disable_auto_count = Cpt(EpicsSignal, "DisableAutoCount") do_read_all = Cpt(EpicsSignal, "DoReadAll") dwell = Cpt(EpicsSignal, "Dwell") elapsed_real = Cpt(EpicsSignal, "ElapsedReal") enable_client_wait = Cpt(EpicsSignal, "EnableClientWait") erase_all = Cpt(EpicsSignal, "EraseAll") erase_start = Cpt(EpicsSignal, "EraseStart") firmware = Cpt(EpicsSignal, "Firmware") hardware_acquiring = Cpt(EpicsSignal, "HardwareAcquiring") input_mode = Cpt(EpicsSignal, "InputMode") max_channels = Cpt(EpicsSignal, "MaxChannels") model = Cpt(EpicsSignal, "Model") mux_output = Cpt(EpicsSignal, "MUXOutput") nuse_all = Cpt(EpicsSignal, "NuseAll") output_mode = Cpt(EpicsSignal, "OutputMode") output_polarity = Cpt(EpicsSignal, "OutputPolarity") prescale = Cpt(EpicsSignal, "Prescale") preset_real = Cpt(EpicsSignal, "PresetReal") read_all = Cpt(EpicsSignal, "ReadAll") read_all_once = Cpt(EpicsSignal, "ReadAllOnce") set_acquiring = Cpt(EpicsSignal, "SetAcquiring") set_client_wait = Cpt(EpicsSignal, "SetClientWait") snl_connected = Cpt(EpicsSignal, "SNL_Connected") software_channel_advance = Cpt(EpicsSignal, "SoftwareChannelAdvance") count_mode = Cpt(EpicsSignal, ".CONT") start_all = Cpt(EpicsSignal, "StartAll") stop_all = Cpt(EpicsSignal, "StopAll") user_led = Cpt(EpicsSignal, "UserLED") wfrm = Cpt(EpicsSignal, "Wfrm") mca1 = Cpt(EpicsSignalRO, "mca1") mca2 = Cpt(EpicsSignalRO, "mca2") mca3 = Cpt(EpicsSignalRO, "mca3") mca4 = Cpt(EpicsSignalRO, "mca4") def __init__(self, prefix, **kwargs): super().__init__(prefix, **kwargs) self.stage_sigs[self.count_mode] = "OneShot"
class TransformRecord(EpicsRecordDeviceCommonAll): """ EPICS transform record support in ophyd .. autosummary:: ~reset :see: https://htmlpreview.github.io/?https://raw.githubusercontent.com/epics-modules/calc/R3-6-1/documentation/TransformRecord.html#Fields """ units = Cpt(EpicsSignal, ".EGU") precision = Cpt(EpicsSignal, ".PREC") version = Cpt(EpicsSignalRO, ".VERS") calc_option = Cpt(EpicsSignal, ".COPT") invalid_link_action = Cpt(EpicsSignalRO, ".IVLA") input_bitmap = Cpt(EpicsSignalRO, ".MAP") read_attrs = APS_utils.itemizer("channels.%s", CHANNEL_LETTERS_LIST) hints = {'fields': read_attrs} channels = DDC(_channels(CHANNEL_LETTERS_LIST)) def reset(self): """set all fields to default values""" self.scanning_rate.put("Passive") self.description.put(self.description.pvname.split(".")[0]) self.units.put("") self.calc_option.put(0) self.precision.put("3") self.forward_link.put("") for letter in self.channels.read_attrs: channel = getattr(self.channels, letter) if isinstance(channel, transformRecordChannel): channel.reset() self.hints = { 'fields': ["channels.%s" % c for c in CHANNEL_LETTERS_LIST] } self.read_attrs = ["channels.%s" % c for c in CHANNEL_LETTERS_LIST]
class ScalerMCA(Device): _default_read_attrs = ('channels', 'current_channel') _default_configuration_attrs = ('nuse', 'prescale') # things to be read as data channels = DDC({f'mca{k:02d}': (EpicsSignal, f"mca{k}", {}) for k in range(1, 21)}) current_channel = C(EpicsSignal, 'CurrentChannel') # configuration details nuse = C(EpicsSignal, 'NuseAll', kind='config') prescale = C(EpicsSignal, 'Prescale', kind='config') channel_advance = C(EpicsSignal, 'ChannelAdvance') # control PVs # high is acquiring with kind_context('omitted') as Co: status = Co(EpicsSignal, 'Acquiring', string=True,) startall = Co(EpicsSignal, 'StartAll', string=True) stopall = Co(EpicsSignal, 'StopAll', string=True) eraseall = Co(EpicsSignal, 'EraseAll', string=True) erasestart = Co(EpicsSignal, 'EraseStart', string=True) def stage(self): super().stage() self.eraseall.put('Erase') def stop(self): self.stopall.put('Stop') def trigger(self): self.erasestart.put('Erase') return StatusBase(done=True, success=True) def read(self): # TODO handle file writing and document generation return super().read()
class ScalerMCA(Device): _default_read_attrs = ("channels", "current_channel") _default_configuration_attrs = ("nuse", "prescale") # things to be read as data channels = DDC({f"mca{k:02d}": (EpicsSignal, f"mca{k}", {}) for k in range(1, 21)}) current_channel = C(EpicsSignal, "CurrentChannel") # configuration details nuse = C(EpicsSignal, "NuseAll", kind="config") prescale = C(EpicsSignal, "Prescale", kind="config") channel_advance = C(EpicsSignal, "ChannelAdvance") # control PVs # high is acquiring with kind_context("omitted") as Co: status = Co(EpicsSignal, "Acquiring", string=True) startall = Co(EpicsSignal, "StartAll", string=True) stopall = Co(EpicsSignal, "StopAll", string=True) eraseall = Co(EpicsSignal, "EraseAll", string=True) erasestart = Co(EpicsSignal, "EraseStart", string=True) def stage(self): staged_cmpts = super().stage() self.eraseall.put("Erase") return staged_cmpts def stop(self): self.stopall.put("Stop") def trigger(self): self.erasestart.put("Erase") return StatusBase(done=True, success=True) def read(self): # TODO handle file writing and document generation return super().read()
class swaitRecord(Device): """synApps swait record: used as $(P):userCalc$(N)""" desc = Cpt(EpicsSignal, '.DESC') scan = Cpt(EpicsSignal, '.SCAN') calc = Cpt(EpicsSignal, '.CALC') val = Cpt(EpicsSignalRO, '.VAL') prec = Cpt(EpicsSignal, '.PREC') oevt = Cpt(EpicsSignal, '.OEVT') outn = Cpt(EpicsSignal, '.OUTN') odly = Cpt(EpicsSignal, '.ODLY') doln = Cpt(EpicsSignal, '.DOLN') dold = Cpt(EpicsSignal, '.DOLD') dopt = Cpt(EpicsSignal, '.DOPT') oopt = Cpt(EpicsSignal, '.OOPT') flnk = Cpt(EpicsSignal, '.FLNK') _channel_letters = "A B C D E F G H I J K L".split() # TODO: eliminate the ".channels" # Note that the scaler support has this also. channels = DDC(_swait_channels('chan', _channel_letters)) def reset(self): """set all fields to default values""" self.scan.put("Passive") self.calc.put("0") self.prec.put("5") self.dold.put(0) self.doln.put("") self.dopt.put("Use VAL") self.flnk.put("0") self.odly.put(0) self.oopt.put("Every Time") self.outn.put("") for letter in self.channels.read_attrs: channel = self.channels.__getattr__(letter) channel.value.put(0) channel.input_pv.put("") channel.input_trigger.put("Yes")
class StatsPluginCSX(PluginBase): """This supports changes to time series PV names in AD 3-3 Due to https://github.com/areaDetector/ADCore/pull/333 """ _default_suffix = 'Stats1:' _suffix_re = 'Stats\d:' _html_docs = ['NDPluginStats.html'] _plugin_type = 'NDPluginStats' _default_configuration_attrs = ( PluginBase._default_configuration_attrs + ('centroid_threshold', 'compute_centroid', 'compute_histogram', 'compute_profiles', 'compute_statistics', 'bgd_width', 'hist_size', 'hist_min', 'hist_max', 'profile_size', 'profile_cursor')) bgd_width = ADCpt(SignalWithRBV, 'BgdWidth') centroid_threshold = ADCpt(SignalWithRBV, 'CentroidThreshold') centroid = DDC(ad_group(EpicsSignalRO, (('x', 'CentroidX_RBV'), ('y', 'CentroidY_RBV'))), doc='The centroid XY', default_read_attrs=('x', 'y')) compute_centroid = ADCpt(SignalWithRBV, 'ComputeCentroid', string=True) compute_histogram = ADCpt(SignalWithRBV, 'ComputeHistogram', string=True) compute_profiles = ADCpt(SignalWithRBV, 'ComputeProfiles', string=True) compute_statistics = ADCpt(SignalWithRBV, 'ComputeStatistics', string=True) cursor = DDC(ad_group(SignalWithRBV, (('x', 'CursorX'), ('y', 'CursorY'))), doc='The cursor XY', default_read_attrs=('x', 'y')) hist_entropy = ADCpt(EpicsSignalRO, 'HistEntropy_RBV') hist_max = ADCpt(SignalWithRBV, 'HistMax') hist_min = ADCpt(SignalWithRBV, 'HistMin') hist_size = ADCpt(SignalWithRBV, 'HistSize') histogram = ADCpt(EpicsSignalRO, 'Histogram_RBV') max_size = DDC(ad_group(EpicsSignal, (('x', 'MaxSizeX'), ('y', 'MaxSizeY'))), doc='The maximum size in XY', default_read_attrs=('x', 'y')) max_value = ADCpt(EpicsSignalRO, 'MaxValue_RBV') max_xy = DDC(ad_group(EpicsSignalRO, (('x', 'MaxX_RBV'), ('y', 'MaxY_RBV'))), doc='Maximum in XY', default_read_attrs=('x', 'y')) mean_value = ADCpt(EpicsSignalRO, 'MeanValue_RBV') min_value = ADCpt(EpicsSignalRO, 'MinValue_RBV') min_xy = DDC(ad_group(EpicsSignalRO, (('x', 'MinX_RBV'), ('y', 'MinY_RBV'))), doc='Minimum in XY', default_read_attrs=('x', 'y')) net = ADCpt(EpicsSignalRO, 'Net_RBV') profile_average = DDC(ad_group(EpicsSignalRO, (('x', 'ProfileAverageX_RBV'), ('y', 'ProfileAverageY_RBV'))), doc='Profile average in XY', default_read_attrs=('x', 'y')) profile_centroid = DDC(ad_group(EpicsSignalRO, (('x', 'ProfileCentroidX_RBV'), ('y', 'ProfileCentroidY_RBV'))), doc='Profile centroid in XY', default_read_attrs=('x', 'y')) profile_cursor = DDC(ad_group(EpicsSignalRO, (('x', 'ProfileCursorX_RBV'), ('y', 'ProfileCursorY_RBV'))), doc='Profile cursor in XY', default_read_attrs=('x', 'y')) profile_size = DDC(ad_group(EpicsSignalRO, (('x', 'ProfileSizeX_RBV'), ('y', 'ProfileSizeY_RBV'))), doc='Profile size in XY', default_read_attrs=('x', 'y')) profile_threshold = DDC(ad_group(EpicsSignalRO, (('x', 'ProfileThresholdX_RBV'), ('y', 'ProfileThresholdY_RBV'))), doc='Profile threshold in XY', default_read_attrs=('x', 'y')) set_xhopr = ADCpt(EpicsSignal, 'SetXHOPR') set_yhopr = ADCpt(EpicsSignal, 'SetYHOPR') sigma_xy = ADCpt(EpicsSignalRO, 'SigmaXY_RBV') sigma_x = ADCpt(EpicsSignalRO, 'SigmaX_RBV') sigma_y = ADCpt(EpicsSignalRO, 'SigmaY_RBV') sigma = ADCpt(EpicsSignalRO, 'Sigma_RBV') # ts_acquiring = ADCpt(EpicsSignal, 'TS:TSAcquiring') ts_centroid = DDC(ad_group(EpicsSignal, (('x', 'TS:TSCentroidX'), ('y', 'TS:TSCentroidY'))), doc='Time series centroid in XY', default_read_attrs=('x', 'y')) # ts_control = ADCpt(EpicsSignal, 'TS:TSControl', string=True) # ts_current_point = ADCpt(EpicsSignal, 'TS:TSCurrentPoint') ts_max_value = ADCpt(EpicsSignal, 'TS:TSMaxValue') ts_max = DDC(ad_group(EpicsSignal, (('x', 'TS:TSMaxX'), ('y', 'TS:TSMaxY'))), doc='Time series maximum in XY', default_read_attrs=('x', 'y')) ts_mean_value = ADCpt(EpicsSignal, 'TS:TSMeanValue') ts_min_value = ADCpt(EpicsSignal, 'TS:TSMinValue') ts_min = DDC(ad_group(EpicsSignal, (('x', 'TS:TSMinX'), ('y', 'TS:TSMinY'))), doc='Time series minimum in XY', default_read_attrs=('x', 'y')) ts_net = ADCpt(EpicsSignal, 'TS:TSNet') # ts_num_points = ADCpt(EpicsSignal, 'TS:TSNumPoints') ts_read = ADCpt(EpicsSignal, 'TS:TSRead') ts_sigma = ADCpt(EpicsSignal, 'TS:TSSigma') ts_sigma_x = ADCpt(EpicsSignal, 'TS:TSSigmaX') ts_sigma_xy = ADCpt(EpicsSignal, 'TS:TSSigmaXY') ts_sigma_y = ADCpt(EpicsSignal, 'TS:TSSigmaY') ts_total = ADCpt(EpicsSignal, 'TS:TSTotal') total = ADCpt(EpicsSignalRO, 'Total_RBV')
class Bimorph(Device): '''Bimorph HV Power Source''' bank_no = C(EpicsSignal, ':BANK_NO_32.VAL') step_size = C(EpicsSignal, ':U_STEP.VAL') inc_bank = C(EpicsSignal, ':INCR_U_BANK_CMD.PROC') dec_bank = C(EpicsSignal, ':DECR_U_BANK_CMD.PROC') stop_ramp = C(EpicsSignal, ':STOP_RAMPS_BANK.PROC') start_ramp = C(EpicsSignal, ':START_RAMPS_CMD.PROC') format_number = C(EpicsSignal, ':FORMAT_NO_SP.VAL') load_format = C(EpicsSignal, ':FORMAT_ACTIVE_SP.PROC') all_target_voltages = C(EpicsSignalRO, ':U_ALL_TARGET_MON.VAL') all_current_voltages = C(EpicsSignalRO, ':U_ALL_CURRENT_MON.VAL') unit_status = C(EpicsSignalRO, ':UNIT_STATUS_MON.A') channels = DDC(add_channels(range(0, 32))) def step(self, bank, size, direction, start=False, wait=False): self.bank_no.put(bank) self.step_size.put(size) if (direction == "inc"): self.inc_bank.put(1) else: self.dec_bank.put(1) if (start): self.start() if (wait): self.wait() def increment_bank(self, bank, size, start=False, wait=False): ''' Increments the target voltage in `size` Volts in the specified `bank` Parameters: ----------- bank : int The number of the bank to be incremented size : float The amount of Volts to increment from the bank target value start : bool Determines if the ramp must start right after the increment. Defaults to False. wait : bool Determines if the code must wait until the ramp process finishes. Defaults to False. ''' self.step(bank, size, "inc", start) def decrement_bank(self, bank, size, start=False, wait=False): ''' Decrements the target voltage in `size` Volts in the specified `bank` Parameters: ----------- bank : int The number of the bank to be decremented size : float The amount of Volts to decrement from the bank target value start : bool Determines if the ramp must start right after the decrement. Defaults to False. wait : bool Determines if the code must wait until the ramp process finishes. Defaults to False. ''' self.step(bank, size, "dec", start) def start(self): ''' Start the Ramping process on all channels ''' self.start_ramp.put(1) def stop(self): ''' Stops the Ramping process on all channels ''' self.stop_ramp.put(1) def is_ramping(self): ''' Returns wether the power supply is ramping or not ''' return (int(self.unit_status.get()) >> 30) == 1 def is_interlock_ok(self): ''' Returns the interlock state ''' st = int(self.unit_status.get()) return (st & 1) & ((st >> 1) & 1) == 1 def is_on(self): ''' Returns wether the Channels are ON or OFF ''' return (int(self.unit_status.get()) >> 29) == 1 def wait(self): while self.is_ramping(): sleep(0.1)
class ScalerCH(Device): _default_configuration_attrs = ('preset_time', 'freq', 'auto_count_time', 'count_mode', 'delay', 'auto_count_delay', 'egu', 'channels') _default_read_attrs = ('time', 'channels') # The data channels = DDC(_sc_chans('chan', range(1, 33))) # tigger + trigger mode count = C(EpicsSignal, '.CNT', trigger_value=1) count_mode = C(EpicsSignal, '.CONT', string=True) # delay from triggering to starting counting delay = C(EpicsSignal, '.DLY') auto_count_delay = C(EpicsSignal, '.DLY1') time = C(EpicsSignal, '.T') freq = C(EpicsSignal, '.FREQ') preset_time = C(EpicsSignal, '.TP') auto_count_time = C(EpicsSignal, '.TP1') update_rate = C(EpicsSignal, '.RATE') auto_count_update_rate = C(EpicsSignal, '.RAT1') egu = C(EpicsSignal, '.EGU') def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.channels.read_attrs = ['chan01'] self.channels.configuration_attrs = ['chan01'] def match_names(self): for s in self.channels.component_names: getattr(self.channels, s).match_name() def select_channels(self, chan_names): '''Select channels based on the EPICS name PV Parameters ---------- chan_names : Iterable[str] The names (as reported by the channel.chname signal) of the channels to select. ''' self.match_names() name_map = { getattr(self.channels, s).name.get(): s for s in self.channels.component_names } read_attrs = ['chan01'] # always include time for ch in chan_names: try: read_attrs.append(name_map[ch]) except KeyError: raise RuntimeError("The channel {} is not configured " "on the scaler. The named channels are " "{}".format(ch, tuple(name_map))) self.channels.read_attrs = list(read_attrs) self.channels.configuration_attrs = list(read_attrs) self.hints = { 'fields': [getattr(self.channels, ch).s.name for ch in read_attrs[1:]] }
class SscanRecord(Device): """ EPICS synApps sscan record: used as $(P):scan(N) .. autosummary:: ~defined_in_EPICS ~reset ~select_channels """ desc = Cpt(EpicsSignal, '.DESC', kind=Kind.config) scan_phase = Cpt(EpicsSignalRO, '.FAZE') data_state = Cpt(EpicsSignalRO, '.DSTATE') data_ready = Cpt(EpicsSignalRO, '.DATA') scan_busy = Cpt(EpicsSignalRO, '.BUSY') alert_flag = Cpt(EpicsSignalRO, '.ALRT') alert_message = Cpt(EpicsSignalRO, '.SMSG') number_points = Cpt(EpicsSignal, '.NPTS', kind=Kind.config) maximum_number_points = Cpt(EpicsSignal, '.MPTS', kind=Kind.config) current_point = Cpt(EpicsSignalRO, '.CPT') pasm = Cpt(EpicsSignal, '.PASM') execute_scan = Cpt(EpicsSignal, '.EXSC') bspv = Cpt(EpicsSignal, '.BSPV', kind=Kind.config) bscd = Cpt(EpicsSignal, '.BSCD') bswait = Cpt(EpicsSignal, '.BSWAIT') cmnd = Cpt(EpicsSignal, '.CMND') detector_delay = Cpt(EpicsSignal, '.DDLY') positioner_delay = Cpt(EpicsSignal, '.PDLY') reference_detector = Cpt(EpicsSignal, '.REFD', kind=Kind.config) wait = Cpt(EpicsSignal, '.WAIT') wcnt = Cpt(EpicsSignalRO, '.WCNT') awct = Cpt(EpicsSignal, '.AWCT') acqt = Cpt(EpicsSignal, '.ACQT') acqm = Cpt(EpicsSignal, '.ACQM') atime = Cpt(EpicsSignal, '.ATIME') copyto = Cpt(EpicsSignal, '.COPYTO') a1pv = Cpt(EpicsSignal, '.A1PV', kind=Kind.config) a1nv = Cpt(EpicsSignal, '.A1NV', kind=Kind.config) a1cd = Cpt(EpicsSignal, '.A1CD') aspv = Cpt(EpicsSignal, '.ASPV', kind=Kind.config) ascd = Cpt(EpicsSignal, '.ASCD') positioners = DDC(_sscan_positioners("1 2 3 4".split())) detectors = DDC(_sscan_detectors(APS_utils.itemizer("%02d", range(1, 71)))) triggers = DDC(_sscan_triggers("1 2 3 4".split())) def set(self, value, **kwargs): """interface to use bps.mv()""" if value != 1: return working_status = DeviceStatus(self) started = False def execute_scan_cb(value, timestamp, **kwargs): value = int(value) if started and value == 0: working_status._finished() self.execute_scan.subscribe(execute_scan_cb) self.execute_scan.set(1) started = True return working_status def reset(self): """set all fields to default values""" self.desc.put(self.desc.pvname.split(".")[0]) self.number_points.put(1000) for part in (self.positioners, self.detectors, self.triggers): for ch_name in part.component_names: channel = getattr(part, ch_name) channel.reset() self.a1pv.put("") self.acqm.put("NORMAL") if self.name.find("scanH") > 0: self.acqt.put("1D ARRAY") else: self.acqt.put("SCALAR") self.aspv.put("") self.bspv.put("") self.pasm.put("STAY") self.bswait.put("Wait") self.a1cd.put(1) self.ascd.put(1) self.bscd.put(1) self.reference_detector.put(1) self.atime.put(0) self.awct.put(0) self.copyto.put(0) self.detector_delay.put(0) self.positioner_delay.put(0) while self.wcnt.get() > 0: self.wait.put(0) def select_channels(self): """ Select channels that are configured in EPICS """ for part in (self.positioners, self.detectors, self.triggers): channel_names = [] # part.get_configured_channels() channel_names = [ ch for ch in part.component_names if getattr(part, ch).defined_in_EPICS ] part.configuration_attrs = channel_names part.read_attrs = channel_names part.kind = Kind.normal @property def defined_in_EPICS(self): """True if will be used in EPICS""" self.select_channels() channels = len(self.positioners.read_attrs) channels += len(self.detectors.read_attrs) #channels += len(self.triggers.read_attrs) return channels > 0
class CalcoutRecord(EpicsRecordFloatFields, EpicsRecordDeviceCommonAll): """ EPICS calcout record support in ophyd .. autosummary:: ~reset :see: https://wiki-ext.aps.anl.gov/epics/index.php/RRM_3-14_Calcout """ units = Cpt(EpicsSignal, ".EGU") precision = Cpt(EpicsSignal, ".PREC") calculated_value = Cpt(EpicsSignal, ".VAL") calculation = Cpt(EpicsSignal, ".CALC") output_pv = Cpt(EpicsSignal, ".OUT") output_execute_option = Cpt(EpicsSignal, ".OOPT") output_execution_delay = Cpt(EpicsSignal, ".ODLY") output_data_option = Cpt(EpicsSignal, ".DOPT") output_calculation = Cpt(EpicsSignal, ".OCAL") output_value = Cpt(EpicsSignal, ".OVAL") invalid_output_action = Cpt(EpicsSignal, ".IVOA") invalid_output_value = Cpt(EpicsSignal, ".IVOV") event_to_issue = Cpt(EpicsSignal, ".OEVT") output_pv_status = Cpt(EpicsSignal, ".OUTV") calculation_valid = Cpt(EpicsSignal, ".CLCV") output_calculation_valid = Cpt(EpicsSignal, ".OCLV") output_delay_active = Cpt(EpicsSignal, ".DLYA") channels = DDC(_channels(CHANNEL_LETTERS_LIST)) read_attrs = APS_utils.itemizer("channels.%s", CHANNEL_LETTERS_LIST) hints = {'fields': read_attrs} @property def value(self): return self.calculated_value.value def reset(self): """set all fields to default values""" pvname = self.description.pvname.split(".")[0] self.scanning_rate.put("Passive") self.description.put(pvname) self.units.put("") self.precision.put("5") self.calculation.put("") self.calculated_value.put(0) self.output_calculation.put("") self.output_value.put(0) self.forward_link.put("") self.output_pv.put("") self.invalid_output_action.put(0) self.invalid_output_value.put(0) self.output_execution_delay.put(0) self.output_execute_option.put(0) self.output_data_option.put(0) for letter in self.channels.read_attrs: channel = getattr(self.channels, letter) if isinstance(channel, CalcoutRecordChannel): channel.reset() self.hints = { 'fields': ["channels.%s" % c for c in CHANNEL_LETTERS_LIST] } self.read_attrs = ["channels.%s" % c for c in CHANNEL_LETTERS_LIST]
class SscanRecord(RecordBase): detectors = DDC(_make_detectors(1, 71)) positioners = DDC(_make_positioners(1, 5)) readbacks = DDC(_make_readbacks(1, 5)) triggers = DDC(_make_triggers(1, 5)) a1_pv_status = Cpt(EpicsSignalRO, '.A1NV') abort_right_now = Cpt(EpicsSignalRO, '.KILL') after_scan_pv_status = Cpt(EpicsSignalRO, '.ASNV') alarm_status = Cpt(EpicsSignalRO, '.STAT') auto_wait_count = Cpt(EpicsSignal, '.AWCT') beforescan_pv_status = Cpt(EpicsSignalRO, '.BSNV') buffered_current_point = Cpt(EpicsSignalRO, '.BCPT') code_version = Cpt(EpicsSignalRO, '.VERS') command_field = Cpt(EpicsSignal, '.CMND') current_point = Cpt(EpicsSignalRO, '.CPT') desired_point = Cpt(EpicsSignal, '.DPT') execute_scan = Cpt(EpicsSignal, '.EXSC') go_pause_control = Cpt(EpicsSignal, '.PAUS') internal_execscan = Cpt(EpicsSignalRO, '.XSC') last_value_of_go_pause = Cpt(EpicsSignalRO, '.LPAU') operator_alert = Cpt(EpicsSignalRO, '.ALRT') point_oflast_posting = Cpt(EpicsSignalRO, '.PCPT') previous_xscan = Cpt(EpicsSignalRO, '.PXSC') record_state_msg = Cpt(EpicsSignal, '.SMSG$', string=True) reference_detector = Cpt(EpicsSignal, '.REFD') scan_data_ready = Cpt(EpicsSignalRO, '.DATA') scan_in_progress = Cpt(EpicsSignalRO, '.BUSY') scan_phase = Cpt(EpicsSignalRO, '.FAZE') wait_count = Cpt(EpicsSignalRO, '.WCNT') wait_for_client_s = Cpt(EpicsSignal, '.WAIT') waiting_for_client_s = Cpt(EpicsSignalRO, '.WTNG') waiting_for_data_storage_client = Cpt(EpicsSignal, '.AWAIT') # - calc after_scan_pv_name = Cpt(EpicsSignal, '.ASPV$', string=True) array_read_trigger_1_pv_name = Cpt(EpicsSignal, '.A1PV$', string=True) before_scan_pv_name = Cpt(EpicsSignal, '.BSPV$', string=True) # - common acquisition_mode = Cpt(EpicsSignal, '.ACQM') acquisition_type = Cpt(EpicsSignal, '.ACQT') copy_last_pt_thru = Cpt(EpicsSignal, '.COPYTO') data_state = Cpt(EpicsSignalRO, '.DSTATE') # - inputs a1_command = Cpt(EpicsSignal, '.A1CD') after_scan_command = Cpt(EpicsSignal, '.ASCD') array_post_time_period = Cpt(EpicsSignal, '.ATIME') autowait_for_data_storage_client = Cpt(EpicsSignal, '.AAWAIT') before_scan_command = Cpt(EpicsSignal, '.BSCD') detector_settling_delay = Cpt(EpicsSignal, '.DDLY') pause_resume_delay = Cpt(EpicsSignal, '.RDLY') positioner_settling_delay = Cpt(EpicsSignal, '.PDLY') wait_for_completion = Cpt(EpicsSignal, '.ASWAIT') wait_for_completion_bswait = Cpt(EpicsSignal, '.BSWAIT') # - links max_of_points = Cpt(EpicsSignalRO, '.MPTS') number_of_points = Cpt(EpicsSignal, '.NPTS') # - output after_scan_mode = Cpt(EpicsSignal, '.PASM') freeze_flag_override = Cpt(EpicsSignal, '.FFO') freeze_num_of_points = Cpt(EpicsSignal, '.FPTS')
class EpicsSscanRecord(Device): """EPICS synApps sscan record: used as $(P):userCalc$(N)""" desc = Cpt(EpicsSignal, '.DESC') faze = Cpt(EpicsSignalRO, '.FAZE') data_state = Cpt(EpicsSignalRO, '.DSTATE') npts = Cpt(EpicsSignal, '.NPTS') cpt = Cpt(EpicsSignalRO, '.CPT') pasm = Cpt(EpicsSignal, '.PASM') exsc = Cpt(EpicsSignal, '.EXSC') bspv = Cpt(EpicsSignal, '.BSPV') bscd = Cpt(EpicsSignal, '.BSCD') bswait = Cpt(EpicsSignal, '.BSWAIT') cmnd = Cpt(EpicsSignal, '.CMND') ddly = Cpt(EpicsSignal, '.DDLY') pdly = Cpt(EpicsSignal, '.PDLY') refd = Cpt(EpicsSignal, '.REFD') wait = Cpt(EpicsSignal, '.WAIT') wcnt = Cpt(EpicsSignalRO, '.WCNT') awct = Cpt(EpicsSignal, '.AWCT') acqt = Cpt(EpicsSignal, '.ACQT') acqm = Cpt(EpicsSignal, '.ACQM') atime = Cpt(EpicsSignal, '.ATIME') copyto = Cpt(EpicsSignal, '.COPYTO') a1pv = Cpt(EpicsSignal, '.A1PV') a1cd = Cpt(EpicsSignal, '.A1CD') aspv = Cpt(EpicsSignal, '.ASPV') ascd = Cpt(EpicsSignal, '.ASCD') positioners = DDC(_sscan_positioners("1 2 3 4".split())) detectors = DDC(_sscan_detectors(["%02d" % k for k in range(1, 71)])) triggers = DDC(_sscan_triggers("1 2 3 4".split())) def reset(self): """set all fields to default values""" self.desc.put(self.desc.pvname.split(".")[0]) self.npts.put(1000) for part in (self.positioners, self.detectors, self.triggers): for ch_name in part.read_attrs: channel = part.__getattr__(ch_name) channel.reset() self.a1pv.put("") self.acqm.put("NORMAL") if self.name.find("scanH") > 0: self.acqt.put("1D ARRAY") else: self.acqt.put("SCALAR") self.aspv.put("") self.bspv.put("") self.pasm.put("STAY") self.bswait.put("Wait") self.a1cd.put(1) self.ascd.put(1) self.bscd.put(1) self.refd.put(1) self.atime.put(0) self.awct.put(0) self.copyto.put(0) self.ddly.put(0) self.pdly.put(0) while self.wcnt.get() > 0: self.wait.put(0)