Ejemplo n.º 1
0
 def test_set_elements(self):
     tm = self.tm
     elements = OrderedDict()
     elements["col1"] = StringArrayMeta()
     elements["col2"] = StringArrayMeta()
     tm.set_elements(elements)
     assert elements == tm.elements
Ejemplo n.º 2
0
class TestTableMetaSerialization(unittest.TestCase):
    def setUp(self):
        self.sam = StringArrayMeta()
        self.serialized = OrderedDict()
        self.serialized["typeid"] = "malcolm:core/TableMeta:1.0"
        self.serialized["elements"] = dict(c1=self.sam.to_dict())
        self.serialized["description"] = "desc"
        self.serialized["tags"] = ()
        self.serialized["writeable"] = True
        self.serialized["label"] = "Name"

    def test_to_dict(self):
        tm = TableMeta("desc")
        tm.set_label("Name")
        tm.set_elements(dict(c1=self.sam))
        tm.set_writeable(True)
        assert tm.to_dict() == self.serialized

    def test_from_dict(self):
        tm = TableMeta.from_dict(self.serialized)
        assert tm.description == "desc"
        assert len(tm.elements) == 1
        assert tm.elements["c1"].to_dict() == self.sam.to_dict()
        assert tm.tags == ()
        assert tm.writeable == True
        assert tm.label == "Name"
Ejemplo n.º 3
0
class TestSerialization(unittest.TestCase):

    def setUp(self):
        self.sam = StringArrayMeta()
        self.serialized = OrderedDict()
        self.serialized["typeid"] = "malcolm:core/MapMeta:1.0"
        self.serialized["elements"] = dict(c1=self.sam.to_dict())
        self.serialized["elements"]["c1"]["label"] = "C1"
        self.serialized["description"] = "desc"
        self.serialized["tags"] = ()
        self.serialized["writeable"] = False
        self.serialized["label"] = ""
        self.serialized["required"] = ("c1",)

    def test_to_dict(self):
        tm = MapMeta("desc")
        tm.set_elements(dict(c1=self.sam))
        tm.set_required(["c1"])
        assert tm.to_dict() == self.serialized

    def test_from_dict(self):
        tm = MapMeta.from_dict(self.serialized)
        assert tm.description == "desc"
        assert len(tm.elements) == 1
        expected = self.sam.to_dict()
        expected["label"] = "C1"
        assert tm.elements["c1"].to_dict() == expected
        assert tm.tags == ()
        assert tm.required == ("c1",)
Ejemplo n.º 4
0
 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
Ejemplo n.º 5
0
 def test_set_elements_from_serialized(self):
     tm = self.tm
     elements = OrderedDict()
     elements["col1"] = StringArrayMeta().to_dict()
     elements["col2"] = StringArrayMeta().to_dict()
     tm.set_elements(elements)
     assert isinstance(tm.elements["col1"], StringArrayMeta)
     assert tm.elements["col1"].to_dict() == elements["col1"]
Ejemplo n.º 6
0
 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
Ejemplo n.º 7
0
 def setUp(self):
     self.sam = StringArrayMeta()
     self.serialized = OrderedDict()
     self.serialized["typeid"] = "malcolm:core/TableMeta:1.0"
     self.serialized["elements"] = dict(c1=self.sam.to_dict())
     self.serialized["description"] = "desc"
     self.serialized["tags"] = ()
     self.serialized["writeable"] = True
     self.serialized["label"] = "Name"
Ejemplo n.º 8
0
 def setUp(self):
     self.sam = StringArrayMeta()
     self.serialized = OrderedDict()
     self.serialized["typeid"] = "malcolm:core/MapMeta:1.0"
     self.serialized["elements"] = dict(c1=self.sam.to_dict())
     self.serialized["elements"]["c1"]["label"] = "C1"
     self.serialized["description"] = "desc"
     self.serialized["tags"] = ()
     self.serialized["writeable"] = False
     self.serialized["label"] = ""
     self.serialized["required"] = ("c1",)
Ejemplo n.º 9
0
 def test_init_with_dict(self):
     meta = Mock()
     meta.elements = {
         "e1": NumberArrayMeta("int32"),
         "e2": StringArrayMeta(),
         "e3": StringArrayMeta()
     }
     d = {"e1": [0, 1], "e3": ["value"]}
     t = Table(meta, d)
     assert [0, 1] == list(t.e1)
     assert () == t.e2
     assert ("value", ) == t.e3
     assert "malcolm:core/Table:1.0" == t.typeid
Ejemplo n.º 10
0
 def setUp(self):
     meta = Mock()
     meta.elements = OrderedDict()
     meta.elements["e1"] = StringArrayMeta()
     meta.elements["e2"] = NumberArrayMeta("int32")
     meta.elements["e3"] = NumberArrayMeta("int32")
     self.meta = meta
Ejemplo n.º 11
0
class ScanTickerPart(ChildPart):
    """Provides control of a `counter_block` within a `RunnableController`"""
    # Generator instance
    generator = None
    # Where to start
    completed_steps = None
    # How many steps to do
    steps_to_do = None
    # When to blow up
    exception_step = None

    @RunnableController.Configure
    @RunnableController.PostRunArmed
    @RunnableController.Seek
    @method_takes(
        "generator", PointGeneratorMeta("Generator instance"), REQUIRED,
        "axesToMove",
        StringArrayMeta(
            "List of axes in inner dimension of generator that should be moved"
        ), REQUIRED, "exceptionStep",
        NumberMeta("int32",
                   "If >0, raise an exception at the end of this step"), 0)
    def configure(self, context, completed_steps, steps_to_do, part_info,
                  params):
        # If we are being asked to move
        if self.name in params.axesToMove:
            # Just store the generator and place we need to start
            self.generator = params.generator
            self.completed_steps = completed_steps
            self.steps_to_do = steps_to_do
            self.exception_step = params.exceptionStep
        else:
            # Flag nothing to do
            self.generator = None

    @RunnableController.Run
    @RunnableController.Resume
    def run(self, context, update_completed_steps):
        # Start time so everything is relative
        point_time = time.time()
        if self.generator:
            child = context.block_view(self.params.mri)
            for i in range(self.completed_steps,
                           self.completed_steps + self.steps_to_do):
                self.log.debug("Starting point %s", i)
                # Get the point we are meant to be scanning
                point = self.generator.get_point(i)
                # Update the child counter_block to be the demand position
                position = point.positions[self.name]
                child.counter.put_value(position)
                # Wait until the next point is due
                point_time += point.duration
                wait_time = point_time - time.time()
                self.log.debug("%s Sleeping %s", self.name, wait_time)
                context.sleep(wait_time)
                # Update the point as being complete
                update_completed_steps(i + 1, self)
                # If this is the exception step then blow up
                assert i + 1 != self.exception_step, \
                    "Raising exception at step %s" % self.exception_step
Ejemplo n.º 12
0
 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
Ejemplo n.º 13
0
class TestStringArrayMeta(unittest.TestCase):

    def setUp(self):
        self.meta = StringArrayMeta("test description")

    def test_init(self):
        assert "test description" == self.meta.description
        assert self.meta.label == ""
        assert self.meta.typeid == "malcolm:core/StringArrayMeta:1.0"

    def test_validate_none(self):
        assert self.meta.validate(None) == ()

    def test_validate_array(self):
        array = ["test_string", 123, 123.456]
        with self.assertRaises(ValueError):
            self.meta.validate(array)

    def test_not_iterable_raises(self):
        value = 12346
        with self.assertRaises(TypeError):
            self.meta.validate(value)

    def test_null_element_raises(self):
        array = ["test", None]
        with self.assertRaises(ValueError):
            self.meta.validate(array)
Ejemplo n.º 14
0
 def test_init(self):
     meta = Mock()
     s = StringArrayMeta()
     meta.elements = {"e1": s, "e2": s, "e3": s}
     t = Table(meta)
     assert () == t.e1
     assert () == t.e2
     assert () == t.e3
     assert "malcolm:core/Table:1.0" == t.typeid
    snake_to_camel
from malcolm.modules.ADCore.includes import adbase_parts
from malcolm.modules.ADCore.infos import attribute_dataset_types
from malcolm.modules.ADPandABlocks.parts import PandABlocksDriverPart, \
    PandABlocksChildPart
from malcolm.modules.builtin.controllers import StatefulController
from malcolm.modules.builtin.parts import StringPart, ChoicePart
from malcolm.modules.builtin.vmetas import StringMeta, StringArrayMeta
from malcolm.modules.pandablocks.controllers import PandABlocksManagerController
from malcolm.modules.scanning.controllers import RunnableController


@method_also_takes("areaDetectorPrefix",
                   StringMeta("Prefix for areaDetector records"), REQUIRED,
                   "axesToMove",
                   StringArrayMeta("Default value for configure() axesToMove"),
                   [])
class PandABlocksRunnableController(PandABlocksManagerController,
                                    RunnableController):
    def _make_child_controller(self, parts, mri):
        # Add some extra parts to determine the dataset name and type for
        # any CAPTURE field part
        new_parts = []
        for existing_part in parts:
            new_parts.append(existing_part)
            if existing_part.name.endswith(".CAPTURE"):
                # Add capture dataset name and type
                part_name = existing_part.name.replace(".CAPTURE",
                                                       ".DATASET_NAME")
                attr_name = snake_to_camel(part_name.replace(".", "_"))
                new_parts.append(
Ejemplo n.º 16
0
 def setUp(self):
     self.meta = StringArrayMeta("test description")
Ejemplo n.º 17
0
            self.READY, self.CONFIGURING, self.ARMED, self.RUNNING,
            self.POSTRUN, self.PAUSED, self.SEEKING]
        for state in normal_states:
            self.set_allowed(state, self.ABORTING)

        # Set transitions for aborted states
        self.set_allowed(self.ABORTING, self.ABORTED)
        self.set_allowed(self.ABORTED, self.RESETTING)


ss = RunnableStates


configure_args = (
    "generator", PointGeneratorMeta("Generator instance"), REQUIRED,
    "axesToMove", StringArrayMeta(
        "List of axes in inner dimension of generator that should be moved"),
    []
)
validate_args = configure_args[:-1] + (REQUIRED,)


@method_also_takes(
    "axesToMove", StringArrayMeta("Default value for configure() axesToMove"),
    []
)
class RunnableController(ManagerController):
    """RunnableDevice implementer that also exposes GUI for child parts"""
    # The stateSet that this controller implements
    stateSet = ss()

    Validate = Hook()
Ejemplo n.º 18
0
from malcolm.core import method_also_takes, REQUIRED
from malcolm.modules.builtin.vmetas import ChoiceMeta, StringMeta, StringArrayMeta
from .attributepart import AttributePart


@method_also_takes(
    "choices", StringArrayMeta("Possible choices for this attribute"), REQUIRED,
    "initialValue", StringMeta("Initial value of attribute"), REQUIRED,
)
class ChoicePart(AttributePart):
    def get_initial_value(self):
        return self.params.initialValue

    def create_meta(self, description, tags):
        return ChoiceMeta(
            choices=self.params.choices, description=description, tags=tags)
Ejemplo n.º 19
0
 def test_set_elements(self):
     els = dict(sam=StringArrayMeta())
     self.mm.set_elements(els)
     assert self.mm.elements == els
Ejemplo n.º 20
0
 def setUp(self):
     self.tm = TableMeta("desc")
     self.tm.set_elements(dict(c1=StringArrayMeta()))
Ejemplo n.º 21
0
 def test_init_with_none(self):
     meta = Mock()
     meta.elements = {"e1": StringArrayMeta()}
     t = Table(meta, None)
     assert () == t.e1
     assert "malcolm:core/Table:1.0" == t.typeid
Ejemplo n.º 22
0
from malcolm.compat import OrderedDict
from malcolm.core import Part, Table, method_takes, REQUIRED
from malcolm.modules.ADCore.infos import DatasetProducedInfo, dataset_types
from malcolm.modules.builtin.vmetas import StringArrayMeta, ChoiceArrayMeta, \
    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)
Ejemplo n.º 23
0
TRIG_CAPTURE = 4  # Capture 1, Frame 0, Detector 0
TRIG_DEAD_FRAME = 2  # Capture 0, Frame 1, Detector 0
TRIG_LIVE_FRAME = 3  # Capture 0, Frame 1, Detector 1
TRIG_ZERO = 8  # Capture 0, Frame 0, Detector 0

# How many profile points to write each time
PROFILE_POINTS = 10000

# All possible PMAC CS axis assignment
cs_axis_names = list("ABCUVWXYZ")

# Args for configure and validate
configure_args = (
    "generator", PointGeneratorMeta("Generator instance"), REQUIRED,
    "axesToMove",
    StringArrayMeta(
        "List of axes in inner dimension of generator that should be moved"),
    [])


@method_also_takes("minTurnaround",
                   NumberMeta("float64",
                              "Min time for any gaps between frames"), 0.0)
class PmacTrajectoryPart(StatefulChildPart):
    # Axis information stored from validate
    # {scannable_name: MotorInfo}
    axis_mapping = None
    # Lookup of the completed_step value for each point
    completed_steps_lookup = []
    # If we are currently loading then block loading more points
    loading = False
    # Where we have generated into profile