class CounterPart(Part): """Defines a counter `Attribute` with zero and increment `Method` objects""" def __init__(self, name): # type: (APartName) -> None super(CounterPart, self).__init__(name) # TODO: why doesn't this show up in the docs for CounterPart? self.counter = NumberMeta("float64", "The current value of the counter", tags=[config_tag(), Widget.TEXTINPUT.tag() ]).create_attribute_model() """Attribute holding the current counter value""" def setup(self, registrar): # type: (PartRegistrar) -> None # Add some Attribute and Methods to the Block registrar.add_attribute_model("counter", self.counter, self.counter.set_value) registrar.add_method_model(self.zero) registrar.add_method_model(self.increment) def zero(self): """Zero the counter attribute""" self.counter.set_value(0) def increment(self): """Add one to the counter attribute""" self.counter.set_value(self.counter.value + 1)
def setup(self, registrar: PartRegistrar) -> None: attr = TableMeta.from_table( SequencerTable, "Sequencer Table", writeable=list( SequencerTable.call_types)).create_attribute_model() self.table_set = MagicMock(side_effect=attr.set_value) registrar.add_attribute_model("table", attr, self.table_set) for suff, val in (("a", "INENC1.VAL"), ("b", "INENC2.VAL"), ("c", "ZERO")): attr = StringMeta("Input").create_attribute_model(val) registrar.add_attribute_model(f"pos{suff}", attr) attr = StringMeta("Input").create_attribute_model("ZERO") registrar.add_attribute_model("bita", attr) attr = BooleanMeta("Active", (), True).create_attribute_model(False) registrar.add_attribute_model("active", attr, attr.set_value) attr = NumberMeta("int16", "repeats", writeable=True).create_attribute_model(1) registrar.add_attribute_model("repeats", attr, writeable_func=attr.set_value) attr = NumberMeta("int16", "prescale", writeable=True).create_attribute_model(0) registrar.add_attribute_model("prescale", attr, writeable_func=attr.set_value)
def __init__(self, name, wait=0.0): # type: (APartName, AWait) -> None super(WaitingPart, self).__init__(name) meta = NumberMeta("float64", "How long to wait") set_tags(meta, writeable=True) self.attr = meta.create_attribute_model(wait) self.register_hooked(RunHook, self.run)
def exposure_attribute(min_exposure: float) -> AttributeModel: meta = NumberMeta( "float64", "The calculated exposure for this run", tags=[Widget.TEXTUPDATE.tag()], display=Display(precision=6, units="s", limitLow=min_exposure), ) return meta.create_attribute_model()
def __init__(self, name): # type: (APartName) -> None super(CounterPart, self).__init__(name) # TODO: why doesn't this show up in the docs for CounterPart? self.counter = NumberMeta("float64", "The current value of the counter", tags=[config_tag(), Widget.TEXTINPUT.tag() ]).create_attribute_model() """Attribute holding the current counter value"""
def __init__( self, mri: AMri, config_dir: AConfigDir, hostname: AHostname = "localhost", port: APort = 8888, doc_url_base: ADocUrlBase = DOC_URL_BASE, poll_period: APollPeriod = 0.1, template_designs: ATemplateDesigns = "", initial_design: AInitialDesign = "", use_git: AUseGit = True, description: ADescription = "", ) -> None: super().__init__( mri=mri, config_dir=config_dir, template_designs=template_designs, initial_design=initial_design, use_git=use_git, description=description, ) self._poll_period = poll_period self._doc_url_base = doc_url_base # All the bit_out fields and their values # {block_name.field_name: value} self._bit_outs: Dict[str, bool] = {} # The bit_out field values that need toggling since the last handle # {block_name.field_name: value} self._bit_out_changes: Dict[str, bool] = {} # The fields that busses needs to know about # {block_name.field_name[.subfield_name]} self._bus_fields: Set[str] = set() # The child controllers we have created self._child_controllers: Dict[str, PandABlockController] = {} # The PandABlock client that does the comms self._client = PandABlocksClient(hostname, port, Queue) # Filled in on reset self._stop_queue = None self._poll_spawned = None # Poll period reporting self.last_poll_period = NumberMeta( "float64", "The time between the last 2 polls of the hardware", tags=[Widget.TEXTUPDATE.tag()], display=Display(units="s", precision=3), ).create_attribute_model(poll_period) self.field_registry.add_attribute_model("lastPollPeriod", self.last_poll_period) # Bus tables self.busses: PandABussesPart = self._make_busses() self.add_part(self.busses)
def setup(self, registrar: PartRegistrar) -> None: super().setup(registrar) # Hooks registrar.hook(scanning.hooks.ReportStatusHook, self.on_report_status) registrar.hook(scanning.hooks.ValidateHook, self.on_validate) registrar.hook( scanning.hooks.ConfigureHook, self.on_configure, self.configure_args_with_exposure, ) registrar.hook( scanning.hooks.SeekHook, self.on_seek, self.configure_args_with_exposure, ) registrar.hook(scanning.hooks.RunHook, self.on_run) registrar.hook(scanning.hooks.PostRunArmedHook, self.on_post_run_armed) registrar.hook((scanning.hooks.PauseHook, scanning.hooks.AbortHook), self.on_abort) # Attributes registrar.add_attribute_model("attributesToCapture", self.extra_attributes, self.set_extra_attributes) # Tell the controller to pass "exposure" and "frames_per_step" to configure info = scanning.infos.ConfigureParamsInfo( metas=dict(frames_per_step=NumberMeta.from_annotype( ADetectorFramesPerStep, writeable=False), ), required=[], defaults=dict(frames_per_step=1), ) registrar.report(info)
def __init__(self, pv_prefix: APvPrefix, group: ca.util.AGroup = None) -> None: super().__init__("sinkPorts") self.pvs = [pv_prefix + ":CsPort", pv_prefix + ":CsAxis"] self.rbvs = [ pv_prefix + ":CsPort_RBV", pv_prefix + ":CsAxis_RBV", pv_prefix + ".OUT", ] meta = ChoiceMeta("CS Axis") builtin.util.set_tags(meta, writeable=True, group=group, sink_port=Port.MOTOR) self.cs_attr = meta.create_attribute_model() meta = StringMeta("Parent PMAC Port name") builtin.util.set_tags(meta, group=group, sink_port=Port.MOTOR) self.pmac_attr = meta.create_attribute_model() meta = NumberMeta("int32", "Parent PMAC Axis number") builtin.util.set_tags(meta, group=group) self.axis_num_attr = meta.create_attribute_model() # Subscriptions self.monitors: List = [] self.port = None self.axis = None self.port_choices: List = []
def __init__( self, name: util.APartName, description: util.AMetaDescription, pv: util.APv = "", rbv: util.ARbv = "", rbv_suffix: util.ARbvSuffix = "", min_delta: util.AMinDelta = 0.05, timeout: util.ATimeout = DEFAULT_TIMEOUT, sink_port: util.ASinkPort = None, widget: util.AWidget = None, group: util.AGroup = None, config: util.AConfig = True, display_from_pv: util.AGetLimits = True, throw: util.AThrow = True, ) -> None: super().__init__(name) self.display_from_pv = display_from_pv self.caa = util.CAAttribute( NumberMeta("float64", description), util.catools.DBR_DOUBLE, pv, rbv, rbv_suffix, min_delta, timeout, sink_port, widget, group, config, on_connect=self._update_display, throw=throw, )
def __init__( self, name, # type: APartName description, # type: AMetaDescription writeable=False, # type: AWriteable config=1, # type: AConfig group=None, # type: AGroup widget=None, # type: AWidget value=0.0, # type: Value ): # type: (...) -> None super(Float64Part, self).__init__(name) meta = NumberMeta("float64", description) set_tags(meta, writeable, config, group, widget) self.attr = meta.create_attribute_model(value) self.writeable_func = self.attr.set_value if writeable else None
def __init__( self, name: util.APartName, description: util.AMetaDescription, pv: util.APv = "", rbv: util.ARbv = "", rbv_suffix: util.ARbvSuffix = "", min_delta: util.AMinDelta = 0.05, timeout: util.ATimeout = DEFAULT_TIMEOUT, sink_port: util.ASinkPort = None, widget: util.AWidget = None, group: util.AGroup = None, config: util.AConfig = True, throw: util.AThrow = True, ) -> None: super().__init__(name) self.caa = util.CAAttribute( NumberMeta("int32", description), util.catools.DBR_LONG, pv, rbv, rbv_suffix, min_delta, timeout, sink_port, widget, group, config, throw=throw, )
def _make_mux_delay(self, field_name: str) -> None: group = self._make_group("inputs") meta = NumberMeta( "uint8", "How many FPGA ticks to delay input", tags=[group, Widget.TEXTINPUT.tag()], ) self._make_field_part(field_name + ".DELAY", meta, writeable=True)
def __init__(self, name: APartName, mri: AMri) -> None: super().__init__(name, mri) self.targetSamplesPerFrame = NumberMeta( "uint32", "Target samples that each frame contains, " "0 for maximum, -1 for not controlling it.", tags=[Widget.TEXTINPUT.tag()], ).create_attribute_model()
def _make_scale_offset(self, field_name): group = self._make_group("outputs") meta = StringMeta("Units for position fields on this block", tags=[group, Widget.TEXTINPUT.tag()]) self._make_field_part(field_name + ".UNITS", meta, writeable=True) meta = NumberMeta("float64", "Scale for block position fields", tags=[group, Widget.TEXTINPUT.tag()]) self._make_field_part(field_name + ".SCALE", meta, writeable=True) meta = NumberMeta("float64", "Offset for block position fields", tags=[group, Widget.TEXTINPUT.tag()]) self._make_field_part(field_name + ".OFFSET", meta, writeable=True) meta = NumberMeta("float64", "Current scaled value of position field", tags=[group, Widget.TEXTUPDATE.tag()]) self._make_field_part(field_name + ".SCALED", meta, writeable=False)
def test_from_dict(self): nm = NumberMeta.from_dict(self.serialized) assert type(nm) == NumberMeta assert nm.description == "desc" assert nm.dtype == "float64" assert nm.tags == [] assert not nm.writeable assert nm.label == "name"
def setup(self, registrar: PartRegistrar) -> None: super().setup(registrar) # Validate hook for exposure time registrar.hook(scanning.hooks.ValidateHook, self.on_validate) # Attributes registrar.add_attribute_model("exposure", self.exposure) # Tell the controller to pass "exposure" and "frames_per_step" to configure info = scanning.infos.ConfigureParamsInfo( metas=dict( exposure=NumberMeta.from_annotype(scanning.hooks.AExposure, writeable=True), frames_per_step=NumberMeta.from_annotype(AFramesPerStep, writeable=False), ), required=[], defaults=dict(exposure=0.0, frames_per_step=1), ) registrar.report(info)
def make_meta(subtyp, description, tags, writeable=True, labels=None): if subtyp == "enum": meta = ChoiceMeta(description, labels) elif subtyp == "bit": meta = BooleanMeta(description) elif subtyp in ("uint", ""): meta = NumberMeta("uint32", description) elif subtyp in ("int", "pos"): meta = NumberMeta("int32", description) elif subtyp == "scalar": meta = NumberMeta("float64", description) elif subtyp == "lut": meta = StringMeta(description) else: raise ValueError("Unknown subtype %r" % subtyp) meta.set_writeable(writeable) tags.append(meta.default_widget().tag()) meta.set_tags(tags) return meta
def __init__( self, name: APartName = "minTurnaround", gap: AMinTurnaround = None, interval: ATurnaroundInterval = None, ) -> None: super().__init__(name) self.gap = NumberMeta( "float64", "Minimum time for any gaps between non-joined points", tags=[Widget.TEXTINPUT.tag(), config_tag()], display=Display(precision=6, units="s"), ).create_attribute_model(gap) self.interval = NumberMeta( "float64", "Minimum interval between turnaround points", tags=[Widget.TEXTINPUT.tag(), config_tag()], display=Display(precision=6, units="s"), ).create_attribute_model(interval)
def __init__( self, name: APartName, mri: AMri, ) -> None: super().__init__(name, mri, initial_visibility=True) # The total number of points we have written self.total_points = 0 self.points_scanned = NumberMeta( "int32", "The number of points scanned", tags=[Widget.METER.tag()] ).create_attribute_model(0)
def setup(self, registrar: PartRegistrar) -> None: super().setup(registrar) # Attributes registrar.add_attribute_model("exposure", self.exposure) # Tell the controller to pass "exposure" to configure info = scanning.infos.ConfigureParamsInfo( metas=dict(exposure=NumberMeta.from_annotype( scanning.hooks.AExposure, writeable=True)), required=[], defaults=dict(exposure=0.0), ) registrar.report(info)
def setup(self, registrar: PartRegistrar) -> None: super().setup(registrar) # Add some Attribute and Methods to the Block self.counter = NumberMeta( "float64", "The current value of the counter", tags=[config_tag(), Widget.TEXTINPUT.tag()], ).create_attribute_model() registrar.add_attribute_model("counter", self.counter, self.counter.set_value) self.delta = NumberMeta( "float64", "The amount to increment() by", tags=[config_tag(), Widget.TEXTINPUT.tag()], ).create_attribute_model(initial_value=1) registrar.add_attribute_model("delta", self.delta, self.delta.set_value) registrar.add_method_model(self.zero) registrar.add_method_model(self.increment)
def __init__( self, name: APartName, initial_readout_time: AInitialReadoutTime = 0.0, initial_frequency_accuracy: AInitialAccuracy = 50.0, min_exposure: AMinExposure = 0.0, ) -> None: super().__init__(name) self.readout_time = NumberMeta( "float64", readout_desc, tags=[Widget.TEXTINPUT.tag(), config_tag()], display=Display(precision=6, units="s"), ).create_attribute_model(initial_readout_time) self.frequency_accuracy = NumberMeta( "float64", frequency_accuracy_desc, tags=[Widget.TEXTINPUT.tag(), config_tag()], display=Display(precision=3, units="ppm"), ).create_attribute_model(initial_frequency_accuracy) self.min_exposure = min_exposure self.exposure = exposure_attribute(min_exposure)
def __init__( self, name: APartName, description: AMetaDescription, writeable: AWriteable = False, config: AConfig = 1, group: AGroup = None, widget: AWidget = None, value: AValue = 0.0, limit_low: ULimitLow = 0, limit_high: ULimitHigh = 0, precision: UPrecision = 8, units: AUnits = "", ) -> None: super().__init__(name) display = Display( limitLow=limit_low, limitHigh=limit_high, precision=precision, units=units ) meta = NumberMeta("float64", description, display=display) set_tags(meta, writeable, config, group, widget) self.attr = meta.create_attribute_model(value) self.writeable_func = self.attr.set_value if writeable else None
def __init__( self, name, # type: APartName initial_readout_time=0.0, # type: AInitialReadoutTime initial_frequency_accuracy=50.0 # type: AInitialAccuracy ): # type: (...) -> None super(ExposureDeadtimePart, self).__init__(name) self.readout_time = NumberMeta( "float64", readout_desc, tags=[Widget.TEXTINPUT.tag(), config_tag()]).create_attribute_model(initial_readout_time) self.frequency_accuracy = NumberMeta( "float64", frequency_accuracy_desc, tags=[Widget.TEXTINPUT.tag(), config_tag() ]).create_attribute_model(initial_frequency_accuracy) # Hooks self.register_hooked(scanning.hooks.ReportStatusHook, self.report_status) self.register_hooked(scanning.hooks.ValidateHook, self.validate)
def setup(self, registrar: PartRegistrar) -> None: self.mocks = {} self.units = {} for suffix in ["step", "delay", "width", "pulses"]: # Add an attribute that will be set attr = NumberMeta("float64").create_attribute_model() mock = MagicMock(side_effect=attr.set_value) registrar.add_attribute_model(suffix, attr, mock) self.mocks[suffix] = mock if suffix != "pulses": # Add a units attribute that will be read units_attr = StringMeta().create_attribute_model("s") registrar.add_attribute_model(suffix + "Units", units_attr) self.units[suffix] = units_attr
class CounterPart(Part): """Defines a counter `Attribute` with zero and increment `Method` objects""" #: Writeable Attribute holding the current counter value counter: Optional[AttributeModel] = None #: Writeable Attribute holding the amount to increment() by delta: Optional[AttributeModel] = None def setup(self, registrar: PartRegistrar) -> None: super().setup(registrar) # Add some Attribute and Methods to the Block self.counter = NumberMeta( "float64", "The current value of the counter", tags=[config_tag(), Widget.TEXTINPUT.tag()], ).create_attribute_model() registrar.add_attribute_model("counter", self.counter, self.counter.set_value) self.delta = NumberMeta( "float64", "The amount to increment() by", tags=[config_tag(), Widget.TEXTINPUT.tag()], ).create_attribute_model(initial_value=1) registrar.add_attribute_model("delta", self.delta, self.delta.set_value) registrar.add_method_model(self.zero) registrar.add_method_model(self.increment) def zero(self): """Zero the counter attribute""" self.counter.set_value(0) def increment(self): """Add delta to the counter attribute""" self.counter.set_value(self.counter.value + self.delta.value)
def _make_time_parts(self, field_name, field_data, writeable): description = field_data.description if writeable: widget = Widget.TEXTINPUT group = self._make_group("parameters") else: widget = Widget.TEXTUPDATE group = self._make_group("readbacks") meta = NumberMeta("float64", description, [group, widget.tag()]) # We must change time units before value, so restore value in 2nd # iteration self._make_field_part(field_name, meta, writeable, iteration=2) meta = ChoiceMeta(description + " time units", ["s", "ms", "us"], tags=[group, Widget.COMBO.tag()]) self._make_field_part(field_name + ".UNITS", meta, writeable=True)
def __init__(self, name, # type: util.APartName description, # type: util.AMetaDescription pv="", # type: util.APv rbv="", # type: util.ARbv rbv_suffix="", # type: util.ARbvSuffix min_delta=0.05, # type: util.AMinDelta timeout=DEFAULT_TIMEOUT, # type: util.ATimeout sink_port=None, # type: util.ASinkPort widget=None, # type: util.AWidget group=None, # type: util.AGroup config=True, # type: util.AConfig ): # type: (...) -> None super(CADoublePart, self).__init__(name) self.caa = util.CAAttribute( NumberMeta("float64", description), util.catools.DBR_DOUBLE, pv, rbv, rbv_suffix, min_delta, timeout, sink_port, widget, group, config)
def __init__(self, name: APartName, mri: AMri) -> None: super().__init__(name, mri, stateful=False, initial_visibility=True) self.runner_config = None self.context: Optional[AContext] = None self.scan_sets: Dict[str, Scan] = {} self.runner_state = StringMeta( "Runner state", tags=Widget.TEXTUPDATE.tag()).create_attribute_model("Idle") self.runner_status_message = StringMeta( "Runner status message", tags=Widget.TEXTUPDATE.tag()).create_attribute_model("Idle") self.scan_file = StringMeta( "Path to input scan file", tags=[config_tag(), Widget.TEXTINPUT.tag()]).create_attribute_model() self.scans_configured = NumberMeta( "int64", "Number of configured scans", tags=Widget.TEXTUPDATE.tag()).create_attribute_model() self.current_scan_set = StringMeta( "Current scan set", tags=Widget.TEXTUPDATE.tag()).create_attribute_model() self.scans_completed = NumberMeta( "int64", "Number of scans completed", tags=Widget.TEXTUPDATE.tag()).create_attribute_model() self.scan_successes = NumberMeta("int64", "Successful scans", tags=[Widget.TEXTUPDATE.tag() ]).create_attribute_model() self.scan_failures = NumberMeta("int64", "Failed scans", tags=[Widget.TEXTUPDATE.tag() ]).create_attribute_model() self.output_directory = StringMeta( "Root output directory (will create a sub-directory inside)", tags=[config_tag(), Widget.TEXTINPUT.tag()], ).create_attribute_model()
def __init__( self, name, # type: builtin.parts.APartName mri, # type: builtin.parts.AMri initial_min_turnaround=0.0 # type: AMinTurnaround ): # type: (...) -> None super(PmacTrajectoryPart, self).__init__(name, mri, initial_visibility=True) # Axis information stored from validate self.axis_mapping = None # type: Dict[str, MotorInfo] # Lookup of the completed_step value for each point self.completed_steps_lookup = [] # type: List[int] # If we are currently loading then block loading more points self.loading = False # Where we have generated into profile self.end_index = 0 # Where we should stop loading points self.steps_up_to = 0 # Profile points that haven't been sent yet # {time_array/velocity_mode/trajectory/user_programs: [elements]} self.profile = {} # Stored generator for positions self.generator = None # type: CompoundGenerator # Attribute info self.min_turnaround = NumberMeta( "float64", "Min time for any gaps between frames", tags=[Widget.TEXTINPUT.tag(), config_tag()]).create_attribute_model(initial_min_turnaround) # Hooks self.register_hooked(scanning.hooks.ValidateHook, self.validate) self.register_hooked( (scanning.hooks.ConfigureHook, scanning.hooks.PostRunArmedHook, scanning.hooks.SeekHook), self.configure) self.register_hooked( (scanning.hooks.RunHook, scanning.hooks.ResumeHook), self.run) self.register_hooked( (scanning.hooks.AbortHook, scanning.hooks.PauseHook), self.abort)