def create_attribute_models(self): for data in super(RunnableController, self).create_attribute_models(): yield data # Create sometimes writeable attribute for the current completed scan # step completed_steps_meta = NumberMeta( "int32", "Readback of number of scan steps", tags=[widget("textinput")]) completed_steps_meta.set_writeable_in(ss.PAUSED, ss.ARMED) self.completed_steps = completed_steps_meta.create_attribute_model(0) yield "completedSteps", self.completed_steps, self.set_completed_steps # Create read-only attribute for the number of configured scan steps configured_steps_meta = NumberMeta( "int32", "Number of steps currently configured", tags=[widget("textupdate")]) self.configured_steps = configured_steps_meta.create_attribute_model(0) yield "configuredSteps", self.configured_steps, None # Create read-only attribute for the total number scan steps total_steps_meta = NumberMeta( "int32", "Readback of number of scan steps", tags=[widget("textupdate")]) self.total_steps = total_steps_meta.create_attribute_model(0) yield "totalSteps", self.total_steps, None # Create sometimes writeable attribute for the default axis names axes_to_move_meta = StringArrayMeta( "Default axis names to scan for configure()", tags=[widget("table"), config()]) axes_to_move_meta.set_writeable_in(ss.READY) self.axes_to_move = axes_to_move_meta.create_attribute_model( self.params.axesToMove) yield "axesToMove", self.axes_to_move, self.set_axes_to_move
def __init__(self, process, control, meta, block_name, field_name, writeable): super(PandABoxTablePart, self).__init__( process, control, meta, block_name, field_name, writeable) # Fill in the meta object with the correct headers columns = OrderedDict() self.fields = OrderedDict() fields = control.get_table_fields(block_name, field_name) for field_name, (bits_hi, bits_lo) in fields.items(): nbits = bits_hi - bits_lo + 1 if nbits < 1: raise ValueError("Bad bits %s:%s" % (bits_hi, bits_lo)) if nbits == 1: column_meta = BooleanArrayMeta(field_name) widget_tag = widget("checkbox") else: if nbits <= 8: dtype = "uint8" elif nbits <= 16: dtype = "uint16" elif nbits <= 32: dtype = "uint32" elif nbits <= 64: dtype = "uint64" else: raise ValueError("Bad bits %s:%s" % (bits_hi, bits_lo)) column_meta = NumberArrayMeta(dtype, field_name) widget_tag = widget("textinput") label, column_name = make_label_attr_name(field_name) column_meta.set_label(label) column_meta.set_tags([widget_tag]) columns[column_name] = column_meta self.fields[column_name] = (bits_hi, bits_lo) meta.set_elements(TableElementMap(columns))
def make_meta(subtyp, description, tags, writeable=True, labels=None): if subtyp == "enum": if writeable: widget_type = "combo" else: widget_type = "textupdate" tags.append(widget(widget_type)) meta = ChoiceMeta(description, labels, tags) elif subtyp == "bit": if writeable: widget_type = "checkbox" else: widget_type = "led" tags.append(widget(widget_type)) meta = BooleanMeta(description, tags) else: if writeable: widget_type = "textinput" else: widget_type = "textupdate" tags.append(widget(widget_type)) if subtyp == "uint": meta = NumberMeta("uint32", description, tags) elif subtyp == "int": meta = NumberMeta("int32", description, tags) elif subtyp == "scalar": meta = NumberMeta("float64", description, tags) elif subtyp == "lut": meta = StringMeta(description, tags) elif subtyp in ("pos", "relative_pos"): meta = NumberMeta("float64", description, tags) else: raise ValueError("Unknown subtype %r" % subtyp) return meta
def _make_scale_offset(self, field_name): group_tag = self._make_group("outputs") meta = StringMeta("Units for position fields on this block", tags=[group_tag, widget("textinput")]) self._make_field_part(field_name + ".UNITS", meta, writeable=True) meta = NumberMeta("float64", "Scale for block position fields", tags=[group_tag, widget("textinput")]) self._make_field_part(field_name + ".SCALE", meta, writeable=True) meta = NumberMeta("float64", "Offset for block position fields", tags=[group_tag, widget("textinput")]) self._make_field_part(field_name + ".OFFSET", meta, writeable=True)
def _make_time_parts(self, field_name, field_data, writeable): description = field_data.description if writeable: widget_tag = widget("textupdate") group_tag = self._make_group("parameters") else: widget_tag = widget("textinput") group_tag = self._make_group("readbacks") meta = NumberMeta("float64", description, [group_tag, widget_tag]) self._make_field_part(field_name, meta, writeable) meta = ChoiceMeta(description + " time units", ["s", "ms", "us"], tags=[group_tag, widget("combo")]) self._make_field_part(field_name + ".UNITS", meta, writeable=True)
def create_attributes(self): tags = [widget("group")] meta = ChoiceMeta("All %s attributes" % self.attr_name, choices=["expanded", "collapsed"], tags=tags, label=self.attr_name.title()) self.attr = meta.make_attribute("expanded") yield self.attr_name, self.attr, self.attr.set_value
def _make_table(self, field_name, field_data): widget_tag = widget("table") group_tag = self._make_group("parameters") meta = TableMeta(field_data.description, [widget_tag, group_tag]) part = PandABoxTablePart(self.process, self.control, meta, self.block_name, field_name, writeable=True) self._add_part(field_name, part)
def create_tags(self, params): tags = [] if params.widget: tags.append(widget(params.widget)) if params.inport: tags.append(inport(params.inport, "")) return tags
def create_tags(self): tags = [] if self.params.widget: tags.append(widget(self.params.widget)) if self.params.config: tags.append(config()) return tags
def create_attribute_models(self): for y in super(WebsocketClientComms, self).create_attribute_models(): yield y # Create read-only attribute for the remotely reachable blocks meta = StringArrayMeta("Remotely reachable blocks", tags=[widget("table")]) self.remote_blocks = meta.create_attribute_model() yield "remoteBlocks", self.remote_blocks, None
def create_attribute_models(self): for data in super(ManagerController, self).create_attribute_models(): yield data assert os.path.isdir(self.params.configDir), \ "%s is not a directory" % self.params.configDir if not os.path.isdir(os.path.join(self.params.configDir, ".git")): # Try and make it a git repo, don't care if it fails self._run_git_cmd("init") self._run_git_cmd("commit", "--allow-empty", "-m", "Created repo") # Create writeable attribute table for the layout info we need elements = OrderedDict() elements["name"] = StringArrayMeta("Name of layout part") elements["mri"] = StringArrayMeta("Malcolm full name of child block") elements["x"] = NumberArrayMeta( "float64", "X Coordinate of child block") elements["y"] = NumberArrayMeta( "float64", "Y Coordinate of child block") elements["visible"] = BooleanArrayMeta("Whether child block is visible") layout_table_meta = TableMeta( "Layout of child blocks", elements=elements, tags=[widget("flowgraph")]) layout_table_meta.set_writeable_in(ss.READY) self.layout = layout_table_meta.create_attribute_model() yield "layout", self.layout, self.set_layout # Create writeable attribute for loading an existing layout design_meta = ChoiceMeta( "Design name to load", tags=[config(), widget("combo")]) design_meta.set_writeable_in(ss.READY) self.design = design_meta.create_attribute_model() yield "design", self.design, self.set_design # Create writeable attribute table for the exported fields elements = OrderedDict() elements["name"] = ChoiceArrayMeta("Name of exported block.field") elements["exportName"] = StringArrayMeta( "Name of the field within current block") exports_table_meta = TableMeta( "Exported fields of child blocks", tags=[widget("table")], elements=elements) exports_table_meta.set_writeable_in(ss.READY) self.exports = exports_table_meta.create_attribute_model() yield "exports", self.exports, self.set_exports # Create read-only indicator for when things are modified modified_meta = BooleanMeta( "Whether the design is modified", tags=[widget("led")]) self.modified = modified_meta.create_attribute_model() yield "modified", self.modified, None
def __init__(self, process, attr_name): params = Part.MethodMeta.prepare_input_map(name=attr_name) super(PandABoxGroupPart, self).__init__(process, params) self.attr_name = attr_name tags = [widget("group"), config()] self.meta = ChoiceMeta("All %s attributes" % self.attr_name, choices=["expanded", "collapsed"], tags=tags, label=self.attr_name.title())
def _make_out_capture(self, field_name, field_data): group_tag = self._make_group("outputs") meta = ChoiceMeta("Capture %s in PCAP?" % field_name, field_data.labels, tags=[group_tag, widget("combo")]) self._make_field_part(field_name + ".CAPTURE", meta, writeable=True) meta = NumberMeta( "uint8", "How many FPGA ticks to delay data capture", tags=[group_tag, widget("textinput")]) self._make_field_part(field_name + ".DATA_DELAY", meta, writeable=True) if self.area_detector: # Make a string part to hold the name of the dataset field_name += ".DATASET_NAME" label, attr_name = make_label_attr_name(field_name) params = StringPart.MethodMeta.prepare_input_map( name=attr_name, widget="textinput", description="Name of the captured dataset in HDF file", writeable=True) part = StringPart(self.process, params) self._add_part(field_name, part)
def _make_table(self, field_name, field_data): group_tag = self._make_group("parameters") tags = [widget("table"), group_tag, config()] meta = TableMeta(field_data.description, tags) part = PandABlocksTablePart(self.client, meta, self.block_name, field_name, writeable=True) self._add_part(field_name, part)
def create_tags(self): tags = [] if self.params.widget: tags.append(widget(self.params.widget)) if self.params.config and self.is_writeable(): # If we have a writeable func we can be a config param tags.append(config()) if self.params.group: # If we have a group then add the tag tags.append(group(self.params.group)) return tags
def _make_mux(self, field_name, field_data, typ): group_tag = self._make_group("inputs") if typ == "bit": inport_type = "bool" else: inport_type = "int32" meta = ChoiceMeta(field_data.description, field_data.labels, tags=[ group_tag, inport(inport_type, "ZERO"), widget("combo")]) self._make_field_part(field_name, meta, writeable=True) meta = make_meta(typ, "%s current value" % field_name, tags=[group_tag], writeable=False) self._make_field_part(field_name + ".VAL", meta, writeable=False)
def _make_action_part(self, field_name, field_data): group_tag = self._make_group("actions") if field_data.field_subtype == "action": # Nothing to send arg_meta = None else: arg_meta = make_meta( field_data.field_subtype, field_data.description, tags=[group_tag], writeable=True, labels=field_data.labels) part = PandABoxActionPart( self.process, self.control, self.block_name, field_name, field_data.description, [widget("action"), group_tag], arg_meta) self._add_part(field_name, part)
def create_attribute_models(self): for data in super(PmacTrajectoryPart, self).create_attribute_models(): yield data # Create writeable attribute for the minimum time to leave when there # is a gap between frames meta = NumberMeta("float64", "Min time for any gaps between frames", tags=[widget("textinput"), config()]) self.min_turnaround = meta.create_attribute_model( self.params.minTurnaround) yield "minTurnaround", self.min_turnaround, \ self.min_turnaround.set_value
def create_attribute_models(self): for data in super(ExposureDetectorDriverPart, self).create_attribute_models(): yield data # Create writeable attribute for how long we should allow for detector # read out meta = NumberMeta("float64", "Time taken to readout detector", tags=[widget("textinput"), config()]) self.readout_time = meta.create_attribute_model( self.params.readoutTime) yield "readoutTime", self.readout_time, self.readout_time.set_value
def _make_action_part(self, field_name, field_data): group_tag = self._make_group("actions") if field_data.field_subtype == "action": # Nothing to send arg_meta = None else: arg_meta = make_meta(field_data.field_subtype, field_data.description, tags=[group_tag], writeable=True, labels=field_data.labels) part = PandABoxActionPart(self.process, self.control, self.block_name, field_name, field_data.description, [widget("action"), group_tag], arg_meta) self._add_part(field_name, part)
def _make_mux(self, field_name, field_data, typ): group_tag = self._make_group("inputs") if typ == "bit": inport_type = "bool" else: inport_type = "int32" meta = ChoiceMeta( field_data.description, field_data.labels, tags=[group_tag, inport(inport_type, "ZERO"), widget("combo")]) self._make_field_part(field_name, meta, writeable=True) meta = make_meta(typ, "%s current value" % field_name, tags=[group_tag], writeable=False) self._make_field_part(field_name + ".VAL", meta, writeable=False)
def _make_out_capture(self, field_name, field_data): group_tag = self._make_group("outputs") meta = ChoiceMeta("Capture %s in PCAP?" % field_name, field_data.labels, tags=[group_tag, widget("combo")]) self._make_field_part(field_name + ".CAPTURE", meta, writeable=True) if self.area_detector: from malcolm.parts.ADCore.hdfwriterpart import \ attribute_dataset_types # Make a string part to hold the name of the dataset part_name = field_name + ".DATASET_NAME" label, attr_name = make_label_attr_name(part_name) params = StringPart.MethodMeta.prepare_input_map( name=attr_name, widget="textinput", description="Name of the captured dataset in HDF file", writeable=True, config=True) part = StringPart(self.process, params) self._add_part(part_name, part) # Make a choice part to hold the type of the dataset part_name = field_name + ".DATASET_TYPE" label, attr_name = make_label_attr_name(part_name) if "INENC" in self.block_name: initial = "position" else: initial = "monitor" params = ChoicePart.MethodMeta.prepare_input_map( name=attr_name, widget="textinput", description="Type of the captured dataset in HDF file", writeable=True, choices=attribute_dataset_types, initialValue=initial) part = StringPart(self.process, params) self._add_part(part_name, part)
TableMeta, NumberArrayMeta, StringMeta from malcolm.modules.scanning.controllers import RunnableController from malcolm.tags import widget # Make a table for the dataset info we produce columns = OrderedDict() columns["name"] = StringArrayMeta("Dataset name") columns["filename"] = StringArrayMeta( "Filename of HDF file relative to fileDir") columns["type"] = ChoiceArrayMeta("Type of dataset", dataset_types) columns["rank"] = NumberArrayMeta("int32", "Rank (number of dimensions)") columns["path"] = StringArrayMeta("Dataset path within HDF file") columns["uniqueid"] = StringArrayMeta("UniqueID array path within HDF file") dataset_table_meta = TableMeta("Datsets produced in HDF file", elements=columns, tags=[widget("table")]) @method_takes("name", StringMeta("Name of the Part within the controller"), REQUIRED) class DatasetTablePart(Part): """Exposes an Attribute that reports the datasets that will be written during a scan""" def __init__(self, params): # Created attributes self.datasets = None super(DatasetTablePart, self).__init__(params.name) def create_attribute_models(self): # Create read-only attribute showing the datasets we are creating self.datasets = dataset_table_meta.create_attribute_model()
def _make_icon(self): meta = StringMeta("URL for ICON", tags=[widget("icon")]) self._make_field_part("icon", meta, writeable=False)
def create_tags(self, params): tags = [widget("textupdate")] return tags
def _make_mux_delay(self, field_name): group_tag = self._make_group("inputs") meta = NumberMeta("uint8", "How many FPGA ticks to delay input", tags=[group_tag, widget("textinput")]) self._make_field_part(field_name + ".DELAY", meta, writeable=True)
def create_tags(self): tags = [] if self.params.widget: tags.append(widget(self.params.widget)) return tags
def _make_out_capture(self, field_name, field_data): group_tag = self._make_group("outputs") meta = ChoiceMeta("Capture %s in PCAP?" % field_name, field_data.labels, tags=[group_tag, widget("combo")]) self._make_field_part(field_name + ".CAPTURE", meta, writeable=True)
def create_tags(self): tags = super(AsynOutportPart, self).create_tags() tags.append(widget("textupdate")) return tags
def _make_mux_delay(self, field_name): group_tag = self._make_group("inputs") meta = NumberMeta( "uint8", "How many FPGA ticks to delay input", tags=[group_tag, widget("textinput")]) self._make_field_part(field_name + ".DELAY", meta, writeable=True)