class EpicsNotice(ophyd.Device): ''' progress messages posted to a couple stringout PVs ''' msg_a = ophyd.Component(ophyd.EpicsSignal, 'userStringCalc1.AA') msg_b = ophyd.Component(ophyd.EpicsSignal, 'userStringCalc1.BB') def post(self, a=None, b=None): """write text to each/either PV""" if a is not None: self.msg_a.put(str(a)[:39]) if b is not None: self.msg_b.put(str(b)[:39])
def component_from_record_pair(input_record, output_record): rtyp = input_record.record_type string = (rtyp == 'stringin' or (rtyp == 'waveform' and input_record.fields['FTVL'] == 'CHAR') ) if output_record: return ophyd.Component(ophyd.EpicsSignal, input_record.pvname, write_pv=output_record.pvname, kind='normal', string=string, ) return ophyd.Component(ophyd.EpicsSignalRO, input_record.pvname, string=string, kind='normal')
class MyDetector(ophyd.SingleTrigger, ophyd.SimDetector): """customize the sim detector handling""" # NOTE: ophyd.areadetector.ImagePlugin needs testing with AD2.6 no_op = None # image1 = ophyd.Component(ImagePlugin, 'image1:') hdf1 = ophyd.Component(myHDF5Plugin, 'HDF1:')
def to_ophyd_class(self, class_name, *, base_class=ophyd.DetectorBase): class_dict = {} for suffix, info in sorted(self.components.items(), key=lambda item: item[0].lower()): if suffix in self.checked_components: attr = discovery.category_to_identifier(suffix) class_dict[attr] = ophyd.Component(info['class_'], suffix) return ophyd.device.create_device_from_components( name=class_name, docstring='Auto-generated AreaDetector instance from adviewer', base_class=base_class, **class_dict)
def ophyd_device_from_plc(plc_name, plc_project, macros, *, includes=None, excludes=None, flat=False): tmc = pytmc.parser.parse(plc_project.tmc_path) packages, exceptions = process(tmc, allow_errors=True, show_error_context=True) attr_to_pairs = { pvname_to_attribute(input_record.pvname): (input_record, output_record) for input_record, output_record in records_from_packages(packages, macros) if pvname_to_attribute(input_record.pvname) } attr_to_pairs = { attr: (input_record, output_record) for attr, (input_record, output_record) in attr_to_pairs.items() if util.should_filter(includes, excludes, [attr, input_record.pvname]) } motors = {} for motor in tmc.find(pytmc.parser.Symbol_DUT_MotionStage): if motor.is_pointer: continue if not util.should_filter(includes, excludes, ['motor', motor.name]): continue prefix = ''.join( pytmc.bin.stcmd.get_name(motor, {'prefix': plc_name, 'delim': ':'}) ) attr = pvname_to_attribute(prefix) motors[attr] = ophyd.Component(MOTOR_CLASS, prefix) if flat: components = { attr: component_from_record_pair(input_record, output_record) for attr, (input_record, output_record) in attr_to_pairs.items() } device_cls = ophyd.device.create_device_from_components( plc_name.capitalize(), **components, **motors) else: root = Node.build_tree(attr_to_pairs) device_cls = root.create_device_class(threshold=50, components=motors) return device_cls('', name=plc_name)
def ophyd_device_to_caproto_ioc(dev, *, depth=0): import ophyd if isinstance(dev, ophyd.DynamicDeviceComponent): # DynamicDeviceComponent: attr: (sig_cls, prefix, kwargs) # NOTE: cannot inspect types without an instance of the dynamic Device # class attr_components = { attr: ophyd.Component(sig_cls, prefix, **kwargs) for attr, (sig_cls, prefix, kwargs) in dev.defn.items() } dev_name = f'{dev.attr}_group' cls, dev = dev, None else: if inspect.isclass(dev): # we can introspect Device directly, but we cannot connect to PVs # and tell about their data type cls, dev = dev, None else: # if connected, we can reach out to PVs and determine data types cls = dev.__class__ attr_components = cls._sig_attrs dev_name = f'{cls.__name__}_group' dev_name = underscore_to_camel_case(dev_name) indent = ' ' * depth dev_lines = ['', f"{indent}class {dev_name}(PVGroup):"] for attr, component in attr_components.items(): cpt_lines = ophyd_component_to_caproto(attr, component, depth=depth + 1, dev=dev) if isinstance(cpt_lines, dict): # new device/sub-group, for now add it on for lines in cpt_lines.values(): dev_lines.extend(lines) else: dev_lines.extend(cpt_lines) return {dev_name: dev_lines}
def _create_device_class(self, threshold, components): components = dict(components) for prefix, child in sorted(self.children.items(), key=lambda kv: kv[1].prefix[-1]): attr = pvname_to_attribute(child.prefix[-1]) components[attr] = ophyd.Component( child.create_device_class(threshold=threshold, components={}), '', # full PVname, no prefix combining # child.prefix[-1] + ':' ) for input_record, output_record in self.pairs: attr = pvname_to_attribute(input_record.pvname) components[attr] = component_from_record_pair(input_record, output_record) name = (pvname_to_attribute(self.prefix[-1].capitalize()) if self.prefix else 'PLC') self.device_class = ophyd.device.create_device_from_components( name, **components ) return self.device_class
class Detector(ophyd.SimDetector): image1 = ophyd.Component(IP, 'image1:') cam = ophyd.Component(SC, 'cam1:')
class myHDF5Plugin(ophyd.Device): """custom handling of the HDF5 file writing plugin""" # NOTE: ophyd.areadetector.HDF5Plugin needs testing with AD2.6, use Device for now array_callbacks = ophyd.Component(ophyd.EpicsSignalWithRBV, 'ArrayCallbacks') enable_callbacks = ophyd.Component(ophyd.EpicsSignalWithRBV, 'EnableCallbacks') auto_increment = ophyd.Component(ophyd.EpicsSignalWithRBV, 'AutoIncrement') auto_save = ophyd.Component(ophyd.EpicsSignalWithRBV, 'AutoSave') file_path = ophyd.Component(ophyd.EpicsSignalWithRBV, 'FilePath', string=True) file_name = ophyd.Component(ophyd.EpicsSignalWithRBV, 'FileName', string=True) file_number = ophyd.Component(ophyd.EpicsSignalWithRBV, 'FileNumber') file_template = ophyd.Component(ophyd.EpicsSignalWithRBV, 'FileTemplate', string=True) file_write_mode = ophyd.Component(ophyd.EpicsSignalWithRBV, 'FileWriteMode') full_file_name = ophyd.Component(ophyd.EpicsSignalRO, 'FullFileName_RBV', string=True) store_attributes = ophyd.Component(ophyd.EpicsSignalWithRBV, 'StoreAttr', string=True) store_performance_data = ophyd.Component(ophyd.EpicsSignalWithRBV, 'StorePerform', string=True) xml_layout_file = ophyd.Component(ophyd.EpicsSignalWithRBV, 'XMLFileName', string=True)
class FilterBank(ophyd.Device): flt1 = ophyd.Component(EpicsSignal, '1-Cmd', string=True) flt2 = ophyd.Component(EpicsSignal, '2-Cmd', string=True) flt3 = ophyd.Component(EpicsSignal, '3-Cmd', string=True) flt4 = ophyd.Component(EpicsSignal, '4-Cmd', string=True)
class MyDevice(MyDeviceBaseA, MyDeviceBaseB): tab_whitelist = ['c'] c = 3 foobar = 4 tab_component_names = True cpt = ophyd.Component(ophyd.Signal)
def create_detector_class(cams, plugins, default_core_version, *, class_name=None, base_class=ophyd.DetectorBase): ''' Create a Detector class with the base `base_class`, including all cameras and plugins found from `find_cams_over_channel_access` and `find_plugins_over_channel_access`, respectively. Parameters ---------- cams : ConnectStatus Result from `find_cams_over_channel_access` plugins : ConnectStatus Result from `find_plugins_over_channel_access` class_name : str, optional The class name to create base_class : class, optional Defaults to `ophyd.ADBase` ''' prefix = cams.prefix if not cams.connected_count: logger.info('No cams found for prefix %s', prefix) return adcore_version = default_core_version class_dict = {} logger.debug('%s cam-related PVs connected %d', prefix, cams.connected_count) for cam_suffix, info in cams.info.items(): if info: try: cam_cls = get_cam_from_info(**info) except Exception as ex: logger.warning('Failed to get cam class', exc_info=ex) continue if 'adcore_version' in info: adcore_version = version_tuple_from_string( info['adcore_version']) attr = category_to_identifier(cam_suffix) class_dict[attr] = ophyd.Component(cam_cls, cam_suffix) if not class_dict: logger.info('No cams found for prefix %s', prefix) return logger.debug('%s core version: %s', prefix, adcore_version) logger.debug('%s plugin-related PVs connected %d', prefix, plugins.connected_count) for plugin_suffix, info in sorted(plugins.info.items()): if info: try: plugin_cls = get_plugin_from_info( **info, adcore_version=adcore_version) except Exception as ex: logger.warning('Failed to get plugin class', exc_info=ex) else: attr = category_to_identifier(plugin_suffix) class_dict[attr] = ophyd.Component(plugin_cls, plugin_suffix) if class_name is None: class_name = class_name_from_prefix(prefix) return ophyd.device.create_device_from_components( name=class_name, docstring='Auto-generated AreaDetector instance from adviewer', base_class=base_class, **class_dict)
class MyDevice(ophyd.Device): cpt = ophyd.Component(ophyd.Signal) set_metadata(cpt, None) unset_cpt = ophyd.Component(ophyd.Signal)
class Detector(ophyd.SimDetector): image1 = ophyd.Component(ophyd.ImagePlugin, 'image1:')