def test_run(self):
     self.o.registrar = MagicMock()
     # This would have been done by configure
     self.o.is_hardware_triggered = False
     self.o.on_run(self.context)
     assert self.child.handled_requests.mock_calls == [
         call.post("start"),
         call.when_value_matches("acquiring", True, None),
         call.when_value_matches("arrayCounterReadback", 0, None),
     ]
     assert self.o.registrar.report.call_count == 2
     assert self.o.registrar.report.call_args[0][0].steps == 0
    def test_configure_from_armed_but_not_continuous_state(self):
        # Set the attributes to appear already armed in wrong image mode
        self.set_attributes(self.child, acquiring=True, imageMode="Single")

        self._do_configure()

        assert self.child.handled_requests.mock_calls == [
            call.post("stop"),
            call.when_value_matches("acquiring", False, None),
            call.put("imageMode", "Continuous"),
            call.post("start"),
            call.when_value_matches("acquiring", True, None),
        ]
Esempio n. 3
0
 def test_move(self):
     self.mock_when_value_matches(self.child)
     # Move time is converted into milliseconds
     move_time = 2.3
     expected_move_time = move_time * 1000.0
     self.b.moveCS1(a=32, c=19.1, moveTime=move_time)
     assert self.child.handled_requests.mock_calls == [
         call.put("deferMoves", True),
         call.put("csMoveTime", expected_move_time),
         call.put("demandA", 32),
         call.put("demandC", 19.1),
         call.when_value_matches("demandA", 32, None),
         call.when_value_matches("demandC", 19.1, None),
         call.put("deferMoves", False),
     ]
 def test_configure_with_hardware_trigger_and_breakpoints(self):
     xs = LineGenerator("x", "mm", 0.0, 0.5, 20, alternate=True)
     ys = LineGenerator("y", "mm", 0.0, 0.1, 3)
     generator = CompoundGenerator([ys, xs], [], [], 0.1)
     generator.prepare()
     completed_steps = 0
     steps_to_do = 15
     info = ExposureDeadtimeInfo(0.01, 1000, 0.0)
     part_info = dict(anyname=[info])
     self.set_attributes(self.child, triggerMode="Hardware")
     self.o.on_configure(
         self.context,
         completed_steps,
         steps_to_do,
         part_info,
         generator,
         fileDir="/tmp",
         breakpoints=[15, 35, 10],
         exposure=info.calculate_exposure(generator.duration),
     )
     assert self.child.handled_requests.mock_calls == [
         call.put("arrayCallbacks", True),
         call.put("arrayCounter", 0),
         call.put("exposure", 0.1 - 0.01 - 0.0001),
         call.put("imageMode", "Multiple"),
         call.put("numImages", 15),
         call.put("acquirePeriod", 0.1 - 0.0001),
         call.post("start"),
         call.when_value_matches("acquiring", True, None),
     ]
     assert self.o.is_hardware_triggered
    def test_configure(self):
        tmp_dir = mkdtemp() + os.path.sep
        vds_file = "odin2"

        start_time = datetime.now()
        self.o.on_configure(
            self.context,
            self.completed_steps,
            self.steps_to_do,
            generator=self.generator,
            fileDir=tmp_dir,
            formatName=vds_file,
        )
        assert self.child.handled_requests.mock_calls == [
            call.put("fileName", "odin2_raw_data"),
            call.put("filePath", tmp_dir),
            call.put("numCapture", self.steps_to_do),
            call.post("start"),
            call.when_value_matches("numCaptured", greater_than_zero, None),
        ]
        print(self.child.handled_requests.mock_calls)
        print("OdinWriter configure {} points took {} secs".format(
            self.steps_to_do,
            datetime.now() - start_time))
        rmtree(tmp_dir)
 def test_configure_with_hardware_start_trigger_succeeds(self):
     xs = LineGenerator("x", "mm", 0.0, 0.5, 3, alternate=True)
     ys = LineGenerator("y", "mm", 0.0, 0.1, 2)
     generator = CompoundGenerator([ys, xs], [], [], 0.1)
     generator.prepare()
     completed_steps = 0
     steps_to_do = 6
     # We are not gated
     self.o.gated_trigger = False
     # We want to be armed and in a hardware trigger mode
     self.set_attributes(self.child,
                         acquiring=True,
                         triggerMode="Rising Edge")
     self.o.on_configure(self.context,
                         completed_steps,
                         steps_to_do, {},
                         generator,
                         fileDir="/tmp")
     assert self.child.handled_requests.mock_calls == [
         call.put("arrayCallbacks", True),
         call.put("arrayCounter", 0),
         call.put("imageMode", "Multiple"),
         call.put("numImages", 6),
         call.put("postCount", 999),
         call.post("start"),
         call.when_value_matches("acquiring", True, None),
     ]
 def test_execute_profile(self):
     self.mock_when_value_matches(self.child)
     self.b.executeProfile()
     assert self.child.handled_requests.mock_calls == [
         call.post("executeProfile"),
         call.when_value_matches("pointsScanned", 0, None),
     ]
    def test_post_run_armed_with_hardware_trigger_and_breakpoints(self):
        xs = LineGenerator("x", "mm", 0.0, 0.5, 100, alternate=True)
        ys = LineGenerator("y", "mm", 0.0, 0.1, 5)
        generator = CompoundGenerator([ys, xs], [], [], 0.1)
        generator.prepare()
        info = ExposureDeadtimeInfo(0.01, 1000, 0.0)
        part_info = dict(anyname=[info])
        breakpoints = [100, 400]

        # This would have been done by initial configure
        self.o.is_hardware_triggered = True
        self.o.done_when_reaches = 100

        self.o.on_post_run_armed(self.context, 100, 400, part_info, generator,
                                 breakpoints)
        assert self.child.handled_requests.mock_calls == [
            call.put("arrayCallbacks", True),
            call.put("arrayCounter", 100),
            call.put("imageMode", "Multiple"),
            call.put("numImages", 400),
            call.put("acquirePeriod", 0.1 - 0.0001),
            call.post("start"),
            call.when_value_matches("acquiring", True, None),
        ]
        assert self.o.done_when_reaches == 500
    def test_configure_from_disarmed_state(self):
        self._do_configure()

        assert self.child.handled_requests.mock_calls == [
            call.put("imageMode", "Continuous"),
            call.post("start"),
            call.when_value_matches("acquiring", True, None),
        ]
Esempio n. 10
0
    def test_configure(self):
        completed_steps = 0
        steps_to_do = 456
        part_info = {"sth": [FilePathTranslatorInfo("Z", "/tmp", "")]}
        self.o.post_configure = MagicMock()
        # We wait to be armed, so set this here
        self.set_attributes(self.child, acquiring=True)

        extra_attributes = ExtraAttributesTable(
            name=["test1", "test2", "test3"],
            sourceId=["PV1", "PV2", "PARAM1"],
            sourceType=[SourceType.PV, SourceType.PV, SourceType.PARAM],
            description=[
                "a test pv", "another test PV", "a param, for testing"
            ],
            dataType=[DataType.INT, DataType.STRING, DataType.STRING],
            datasetType=[
                AttributeDatasetType.MONITOR,
                AttributeDatasetType.DETECTOR,
                AttributeDatasetType.POSITION,
            ],
        )
        self.o.extra_attributes.set_value(extra_attributes)
        self.o.on_configure(
            self.context,
            completed_steps,
            steps_to_do,
            part_info,
            generator=MagicMock(duration=1.0),
            fileDir="/tmp",
        )
        assert self.child.handled_requests.mock_calls == [
            call.put("arrayCallbacks", True),
            call.put("arrayCounter", completed_steps),
            call.put("autoPixelsPerBuffer", "Manual"),
            call.put("binsInSpectrum", 2048),
            call.put("collectMode", "MCA mapping"),
            call.put("ignoreGate", "No"),
            call.put("inputLogicPolarity", "Normal"),
            call.put("pixelAdvanceMode", "Gate"),
            call.put("pixelsPerBuffer", 1),
            call.put("pixelsPerRun", steps_to_do),
            call.put("presetMode", "No preset"),
            call.post("start"),
            call.when_value_matches("acquiring", True, None),
            call.put("attributesFile", "Z:\\mri-attributes.xml"),
        ]
        with open("/tmp/mri-attributes.xml") as f:
            actual_xml = f.read().replace(">", ">\n")

        actual_tree = ElementTree.XML(actual_xml)
        expected_tree = ElementTree.XML(expected_xml)
        assert ElementTree.dump(actual_tree) == ElementTree.dump(expected_tree)
 def test_nested_hardware_triggered_configure(self):
     self.set_attributes(self.child, triggerMode="External")
     self.configure()
     # When hardware triggered we set numImages to the total frames and call start
     assert self.child.handled_requests.mock_calls == [
         call.put("arrayCallbacks", True),
         call.put("arrayCounter", 0),
         call.put("exposure", 0.1 - 0.01 - 0.0001),
         call.put("imageMode", "Multiple"),
         call.put("numImages", 50),
         call.put("acquirePeriod", 0.1 - 0.0001),
         call.post("start"),
         call.when_value_matches("acquiring", True, None),
     ]
Esempio n. 12
0
 def test_seek(self):
     self.mock_when_value_matches(self.child)
     self.o = HDFWriterPart(name="m", mri="BLOCK:HDF5")
     self.context.set_notify_dispatch_request(
         self.o.notify_dispatch_request)
     self.o.done_when_reaches = 10
     completed_steps = 4
     steps_to_do = 3
     self.o.on_seek(self.context, completed_steps, steps_to_do)
     assert self.child.handled_requests.mock_calls == [
         call.put("arrayCounter", 0),
         call.when_value_matches("arrayCounterReadback", greater_than_zero,
                                 None),
     ]
     assert self.o.done_when_reaches == 13
Esempio n. 13
0
 def test_run(self):
     self.o = HDFWriterPart(name="m", mri="BLOCK:HDF5")
     self.context.set_notify_dispatch_request(
         self.o.notify_dispatch_request)
     self.o.done_when_reaches = 38
     self.o.completed_offset = 0
     # Say that we're getting the first frame
     self.o.array_future = Future(None)
     self.o.array_future.set_result(None)
     self.o.registrar = MagicMock()
     # run waits for this value, so say we have finished immediately
     self.set_attributes(self.child, uniqueId=self.o.done_when_reaches)
     self.mock_when_value_matches(self.child)
     self.o.on_run(self.context)
     assert self.child.handled_requests.mock_calls == [
         call.when_value_matches("uniqueId", 38, None)
     ]
     assert self.o.registrar.report.called_once
     assert self.o.registrar.report.call_args_list[0][0][0].steps == 38
Esempio n. 14
0
    def test_run(self):
        self.o = HDFWriterPart(name="m", mri="BLOCK:HDF5")
        self.context.set_notify_dispatch_request(
            self.o.notify_dispatch_request)
        self.o.done_when_captured = 38
        # Need a registrar object or we get AssertionError
        self.o.registrar = MagicMock()
        # Run waits for this value, so say we have finished immediately
        self.set_attributes(self.child,
                            numCapturedReadback=self.o.done_when_captured)
        self.mock_when_value_matches(self.child)

        # Run
        self.o.on_run(self.context)

        # Check calls
        assert self.child.handled_requests.mock_calls == [
            call.when_value_matches("numCapturedReadback", 38, None)
        ]
        assert self.o.registrar.report.called_once
        assert self.o.registrar.report.call_args_list[0][0][0].steps == 38
    def test_seek_with_hardware_trigger_and_breakpoints(self):
        self.o.is_hardware_triggered = True
        # Calling seek after 10 completed steps with 10 left until a breakpoint
        self.o.done_when_reaches = 10

        # Build our seek parameters
        xs = LineGenerator("x", "mm", 0.0, 0.5, 20, alternate=True)
        ys = LineGenerator("y", "mm", 0.0, 0.1, 3)
        generator = CompoundGenerator([ys, xs], [], [], 0.1)
        generator.prepare()
        completed_steps = 10
        steps_to_do = 10
        info = ExposureDeadtimeInfo(0.01, 1000, 0.0)
        part_info = dict(anyname=[info])
        breakpoints = [20, 20, 20]

        self.o.on_seek(
            self.context,
            completed_steps,
            steps_to_do,
            part_info,
            generator,
            fileDir="/tmp",
            breakpoints=breakpoints,
            exposure=info.calculate_exposure(generator.duration),
        )

        # Check we got the right calls to setup the driver
        assert self.child.handled_requests.mock_calls == [
            call.put("arrayCallbacks", True),
            call.put("arrayCounter", 10),
            call.put("exposure", 0.1 - 0.01 - 0.0001),
            call.put("imageMode", "Multiple"),
            call.put("numImages", 10),
            call.put("acquirePeriod", 0.1 - 0.0001),
            call.post("start"),
            call.when_value_matches("acquiring", True, None),
        ]
        assert self.o.done_when_reaches == 20
        assert len(self.context._subscriptions) == 0
Esempio n. 16
0
 def test_configure_frame_transfer(self):
     accumulate_period = 0.08
     # We wait to be armed, so set this here
     self.set_attributes(self.child, acquiring=True)
     # Set what we need to simulate frame transfer mode
     self.set_attributes(
         self.child,
         andorFrameTransferMode=True,
         andorAccumulatePeriod=accumulate_period,
     )
     self.do_configure()
     assert self.child.handled_requests.mock_calls == [
         call.put("exposure", 0.0),
         call.put("acquirePeriod", 0.0),
         call.put("arrayCallbacks", True),
         call.put("arrayCounter", 0),
         call.put("exposure", 0.0),
         call.put("imageMode", "Multiple"),
         call.put("numImages", 6000000),
         call.put("acquirePeriod", accumulate_period),
         call.post("start"),
         call.when_value_matches("acquiring", True, None),
     ]
Esempio n. 17
0
 def test_configure(self):
     # We wait to be armed, so set this here
     self.set_attributes(self.child, acquiring=True)
     # This is what the detector does when exposure and acquirePeriod are
     # both set to 0.1
     self.set_attributes(self.child, exposure=0.1, acquirePeriod=0.105)
     self.do_configure()
     # duration - readout - fudge_factor - crystal offset
     expected_exposure = pytest.approx(0.1 - 0.005 - 0.0014 - 5e-6)
     assert self.child.handled_requests.mock_calls == [
         # Checking for readout time
         call.put("exposure", 0.1),
         call.put("acquirePeriod", 0.1),
         # Setup of detector
         call.put("arrayCallbacks", True),
         call.put("arrayCounter", 0),
         call.put("exposure", expected_exposure),
         call.put("imageMode", "Multiple"),
         call.put("numImages", 6000000),
         call.put("acquirePeriod", 0.1 - 5e-6),
         call.post("start"),
         call.when_value_matches("acquiring", True, None),
     ]
     assert self.andor_driver_part.exposure.value == expected_exposure
Esempio n. 18
0
 def test_run(self):
     tmp_dir = mkdtemp() + os.path.sep
     self.o.on_configure(
         self.context,
         self.completed_steps,
         self.steps_to_do,
         generator=self.generator,
         fileDir=tmp_dir,
         formatName="odin2",
         fileTemplate="a_unique_name_%s_from_gda.h5",
     )
     self.child.handled_requests.reset_mock()
     self.o.registrar = MagicMock()
     # run waits for this value
     self.child.field_registry.get_field("numCaptured").set_value(
         self.o.done_when_reaches)
     self.o.on_run(self.context)
     assert self.child.handled_requests.mock_calls == [
         call.when_value_matches("numCaptured", self.steps_to_do, None)
     ]
     assert self.o.registrar.report.called_once
     assert self.o.registrar.report.call_args_list[0][0][
         0].steps == self.steps_to_do
     rmtree(tmp_dir)
 def test_abort(self):
     self.o.on_abort(self.context)
     assert self.child.handled_requests.mock_calls == [
         call.post("stop"),
         call.when_value_matches("acquiring", False, None),
     ]
Esempio n. 20
0
    def configure_and_check_output(self, on_windows=False):
        energy = LineGenerator("energy", "kEv", 13.0, 15.2, 2)
        spiral = SpiralGenerator(["x", "y"], ["mm", "mm"], [0.0, 0.0],
                                 5.0,
                                 scale=2.0)
        generator = CompoundGenerator([energy, spiral], [], [], 0.1)
        generator.prepare()
        fileDir = "/tmp"
        formatName = "xspress3"
        fileTemplate = "thing-%s.h5"
        completed_steps = 0
        steps_to_do = 38
        part_info = {
            "DET": [NDArrayDatasetInfo(2)],
            "PANDA": [
                NDAttributeDatasetInfo.from_attribute_type(
                    "I0", AttributeDatasetType.DETECTOR, "COUNTER1.COUNTER"),
                NDAttributeDatasetInfo.from_attribute_type(
                    "It", AttributeDatasetType.MONITOR, "COUNTER2.COUNTER"),
                NDAttributeDatasetInfo.from_attribute_type(
                    "t1x", AttributeDatasetType.POSITION, "INENC1.VAL"),
            ],
            "STAT": [CalculatedNDAttributeDatasetInfo("sum", "StatsTotal")],
        }
        if on_windows:
            part_info["WINPATH"] = [FilePathTranslatorInfo("Y", "/tmp", "")]
        infos = self.o.on_configure(
            self.context,
            completed_steps,
            steps_to_do,
            part_info,
            generator,
            fileDir,
            formatName,
            fileTemplate,
        )
        assert len(infos) == 8
        assert infos[0].name == "xspress3.data"
        assert infos[0].filename == "thing-xspress3.h5"
        assert infos[0].type == DatasetType.PRIMARY
        assert infos[0].rank == 4
        assert infos[0].path == "/entry/detector/detector"
        assert infos[0].uniqueid == "/entry/NDAttributes/NDArrayUniqueId"

        assert infos[1].name == "xspress3.sum"
        assert infos[1].filename == "thing-xspress3.h5"
        assert infos[1].type == DatasetType.SECONDARY
        assert infos[1].rank == 2
        assert infos[1].path == "/entry/sum/sum"
        assert infos[1].uniqueid == "/entry/NDAttributes/NDArrayUniqueId"

        assert infos[2].name == "I0.data"
        assert infos[2].filename == "thing-xspress3.h5"
        assert infos[2].type == DatasetType.PRIMARY
        assert infos[2].rank == 2
        assert infos[2].path == "/entry/I0.data/I0.data"
        assert infos[2].uniqueid == "/entry/NDAttributes/NDArrayUniqueId"

        assert infos[3].name == "It.data"
        assert infos[3].filename == "thing-xspress3.h5"
        assert infos[3].type == DatasetType.MONITOR
        assert infos[3].rank == 2
        assert infos[3].path == "/entry/It.data/It.data"
        assert infos[3].uniqueid == "/entry/NDAttributes/NDArrayUniqueId"

        assert infos[4].name == "t1x.value"
        assert infos[4].filename == "thing-xspress3.h5"
        assert infos[4].type == DatasetType.POSITION_VALUE
        assert infos[4].rank == 2
        assert infos[4].path == "/entry/t1x.value/t1x.value"
        assert infos[4].uniqueid == "/entry/NDAttributes/NDArrayUniqueId"

        assert infos[5].name == "energy.value_set"
        assert infos[5].filename == "thing-xspress3.h5"
        assert infos[5].type == DatasetType.POSITION_SET
        assert infos[5].rank == 1
        assert infos[5].path == "/entry/detector/energy_set"
        assert infos[5].uniqueid == ""

        assert infos[6].name == "x.value_set"
        assert infos[6].filename == "thing-xspress3.h5"
        assert infos[6].type == DatasetType.POSITION_SET
        assert infos[6].rank == 1
        assert infos[6].path == "/entry/detector/x_set"
        assert infos[6].uniqueid == ""

        assert infos[7].name == "y.value_set"
        assert infos[7].filename == "thing-xspress3.h5"
        assert infos[7].type == DatasetType.POSITION_SET
        assert infos[7].rank == 1
        assert infos[7].path == "/entry/detector/y_set"
        assert infos[7].uniqueid == ""

        expected_xml_filename_local = "/tmp/BLOCK_HDF5-layout.xml"
        if on_windows:
            expected_xml_filename_remote = "Y:\\BLOCK_HDF5-layout.xml"
            expected_filepath = "Y:" + os.sep
        else:
            expected_xml_filename_remote = expected_xml_filename_local
            expected_filepath = "/tmp" + os.sep
        # Wait for the start_future so the post gets through to our child
        # even on non-cothread systems
        self.o.start_future.result(timeout=1)
        assert self.child.handled_requests.mock_calls == [
            call.put("positionMode", True),
            call.put("arrayCounter", 0),
            call.put("dimAttDatasets", True),
            call.put("enableCallbacks", True),
            call.put("fileName", "xspress3"),
            call.put("filePath", expected_filepath),
            call.put("fileTemplate", "%sthing-%s.h5"),
            call.put("fileWriteMode", "Stream"),
            call.put("lazyOpen", True),
            call.put("storeAttr", True),
            call.put("swmrMode", True),
            call.put("extraDimSize3", 1),
            call.put("extraDimSize4", 1),
            call.put("extraDimSize5", 1),
            call.put("extraDimSize6", 1),
            call.put("extraDimSize7", 1),
            call.put("extraDimSize8", 1),
            call.put("extraDimSize9", 1),
            call.put("extraDimSizeN", 20),
            call.put("extraDimSizeX", 2),
            call.put("extraDimSizeY", 1),
            call.put("numExtraDims", 1),
            call.put("posNameDim3", ""),
            call.put("posNameDim4", ""),
            call.put("posNameDim5", ""),
            call.put("posNameDim6", ""),
            call.put("posNameDim7", ""),
            call.put("posNameDim8", ""),
            call.put("posNameDim9", ""),
            call.put("posNameDimN", "d1"),
            call.put("posNameDimX", "d0"),
            call.put("posNameDimY", ""),
            call.put("flushAttrPerNFrames", 0),
            call.put("flushDataPerNFrames", 38),
            call.put("xmlLayout", expected_xml_filename_remote),
            call.put("numCapture", 0),
            call.post("start"),
            call.when_value_matches("arrayCounterReadback", greater_than_zero,
                                    None),
        ]
        with open(expected_xml_filename_local) as f:
            actual_xml = f.read().replace(">", ">\n")
        # Check the layout filename Malcolm uses for file creation
        assert self.o.layout_filename == expected_xml_filename_local
        return actual_xml