def test_to_dict(self):
        g = StaticPointGenerator(7)
        expected_dict = {
            "typeid": "scanpointgenerator:generator/StaticPointGenerator:1.0",
            "size": 7,
        }

        self.assertEqual(expected_dict, g.to_dict())
    def test_to_dict_with_axis(self):
        g = StaticPointGenerator(7, 'repeats')
        expected_dict = {
            "typeid": "scanpointgenerator:generator/StaticPointGenerator:1.0",
            "size": 7,
            "axes": ['repeats'],
        }

        self.assertEqual(expected_dict, g.to_dict())
Esempio n. 3
0
    def test_breakpoints_repeat_rocking_tomo(self):
        line1 = LineGenerator("x", "mm", -10, -10, 5)
        line2 = LineGenerator("x", "mm", 0, 180, 10)
        line3 = LineGenerator("x", "mm", 190, 190, 2)
        line4 = LineGenerator("x", "mm", 180, 0, 10)
        concat = ConcatGenerator([line1, line2, line3, line4])

        staticGen = StaticPointGenerator(2)

        duration = 0.01
        breakpoints = [2, 3, 10, 2, 10, 2, 3, 10, 2, 10]
        self.b.configure(
            generator=CompoundGenerator([staticGen, concat], [], [], duration),
            axesToMove=["x"],
            breakpoints=breakpoints,
        )

        assert self.c.configure_params.generator.size == 54

        self.checkState(self.ss.ARMED)
        self.checkSteps(2, 0, 54)

        self.b.run()
        self.checkSteps(5, 2, 54)
        self.checkState(self.ss.ARMED)

        self.b.run()
        self.checkSteps(15, 5, 54)
        self.checkState(self.ss.ARMED)

        self.b.run()
        self.checkSteps(17, 15, 54)
        self.checkState(self.ss.ARMED)

        self.b.run()
        self.checkSteps(27, 17, 54)
        self.checkState(self.ss.ARMED)

        self.b.run()
        self.checkSteps(29, 27, 54)
        self.checkState(self.ss.ARMED)

        self.b.run()
        self.checkSteps(32, 29, 54)
        self.checkState(self.ss.ARMED)

        self.b.run()
        self.checkSteps(42, 32, 54)
        self.checkState(self.ss.ARMED)

        self.b.run()
        self.checkSteps(44, 42, 54)
        self.checkState(self.ss.ARMED)

        self.b.run()
        self.checkSteps(54, 44, 54)
        self.checkState(self.ss.ARMED)

        self.b.run()
        self.checkState(self.ss.FINISHED)
    def test_invalid_parameters(self):
        self.part_under_test = BeamSelectorPart(
            name="beamSelector2",
            mri="PMAC",
            selectorAxis="x",
            tomoAngle="invalid",
            diffAngle=0.5,
            moveTime=0.5,
        )

        self.context.set_notify_dispatch_request(
            self.part_under_test.notify_dispatch_request)

        self.set_motor_attributes()
        nCycles = 1
        generator = CompoundGenerator([StaticPointGenerator(nCycles)], [], [],
                                      duration=0.5)
        generator.prepare()

        self.part_under_test.on_configure(self.context, 0, nCycles, {},
                                          generator, [])

        assert self.part_under_test.tomoAngle == 0.0
        assert self.part_under_test.diffAngle == 0.0
        assert self.part_under_test.move_time == 0.5
    def test_alternating_line_with_staticpointgen(self):
        x = LineGenerator("x", "mm", 0, 1, 3, True)
        m = StaticPointGenerator(5)
        g = CompoundGenerator([m, x], [], [])
        g.prepare()
        expected_positions = [
                {'x':0.0}, {'x':0.5}, {'x':1.0},
                {'x':1.0}, {'x':0.5}, {'x':0.0},
                {'x':0.0}, {'x':0.5}, {'x':1.0},
                {'x':1.0}, {'x':0.5}, {'x':0.0},
                {'x':0.0}, {'x':0.5}, {'x':1.0}]

        positions = [point.positions for point in g.iterator()]
        self.assertEqual(expected_positions, positions)

        self.assertEqual(15, g.size)
        self.assertEqual((5, 3), g.shape)
        self.assertEqual(["x"], g.axes)
        self.assertEqual({"x":"mm"}, g.units)

        expected_dimensions = [{"axes":[], "size":5, "alternate":False, "upper":[], "lower":[]},
                {"axes":["x"], "size":3, "alternate":True, "upper":[1.0], "lower":[0.0]}]
        dimensions = [{"axes":d.axes, "size":d.size, "alternate":d.alternate, "upper":d.upper, "lower":d.lower}
                for d in g.dimensions]
        self.assertEqual(expected_dimensions, dimensions)
    def test_staticpointgen_in_alternating(self):
        x = LineGenerator("x", "mm", 0, 1, 3, True)
        y = LineGenerator("y", "cm", 2, 3, 4, False)
        m = StaticPointGenerator(5)
        r = CircularROI((0.5, 2.5), 0.4)
        e = ROIExcluder([r], ["x", "y"])
        g = CompoundGenerator([y, m, x], [e], [])
        g.prepare()

        expected_positions = []
        x_positions = [0.0, 0.5, 1.0]
        direction = 1
        for yp in [2.0, 2 + 1. / 3, 2 + 2. / 3, 3.0]:
            for mp in range_(5):
                for xp in x_positions[::direction]:
                    if (xp - 0.5)**2 + (yp - 2.5)**2 <= 0.4**2:
                        expected_positions.append({"y": yp, "x": xp})
                direction *= -1

        positions = [point.positions for point in g.iterator()]

        self.assertEqual(expected_positions, positions)
        self.assertEqual(len(expected_positions), g.size)
        self.assertEqual((len(expected_positions), ), g.shape)
        self.assertEqual(["y", "x"], g.axes)
        self.assertEqual({"y": "cm", "x": "mm"}, g.units)
        self.assertEqual(1, len(g.dimensions))
    def test_validate_raises_ValueError_for_detector_with_zero_exposure(self):
        nCycles = 1
        generator = CompoundGenerator([StaticPointGenerator(nCycles)], [], [],
                                      duration=0.0)
        imaging_exposure_time = 0.1
        diffraction_exposure_time = 0.3
        detectors_with_zero_exposure_for_imaging = self._get_detector_table(
            0.0, diffraction_exposure_time)
        detectors_with_zero_exposure_for_diffraction = self._get_detector_table(
            imaging_exposure_time, 0.0)

        self.assertRaises(
            ValueError,
            self.o.on_validate,
            generator,
            {},
            detectors_with_zero_exposure_for_imaging,
        )
        self.assertRaises(
            ValueError,
            self.o.on_validate,
            generator,
            {},
            detectors_with_zero_exposure_for_diffraction,
        )
    def test_configure_and_run_prepare_no_axes(self, buffer_class):
        buffer_instance = buffer_class.return_value
        buffer_instance.run.return_value = []

        generator = CompoundGenerator([StaticPointGenerator(size=1)], [], [],
                                      1.0)
        generator.prepare()

        completed_steps = 0
        steps_to_do = generator.size

        self.o.on_configure(self.context, completed_steps, steps_to_do, {},
                            generator, "")

        assert self.o.generator is generator
        assert self.o.loaded_up_to == completed_steps
        assert self.o.scan_up_to == completed_steps + steps_to_do

        buffer_instance.configure.assert_called_once()

        self.gate_part.enable_set.assert_not_called()
        buffer_instance.run.assert_not_called()

        # The SRGate should only be enabled by on_run() here.
        self.o.on_pre_run(self.context)
        self.o.on_run(self.context)
        self.gate_part.enable_set.assert_called_once()
        buffer_instance.run.assert_called_once()
    def test_validate_raises_ValueError_for_detector_with_invalid_frames_per_step(
            self):
        nCycles = 1
        generator = CompoundGenerator([StaticPointGenerator(nCycles)], [], [],
                                      duration=0.0)
        imaging_exposure_time = 0.1
        diffraction_exposure_time = 0.3
        bad_imaging_frames_per_step = DetectorTable(
            [True, True, True],
            ["imagingDetector", "diffDetector", "PandA"],
            ["ML-IMAGING-01", "ML-DIFF-01", "ML-PANDA-01"],
            [imaging_exposure_time, diffraction_exposure_time, 0.0],
            [3, 1, 2],
        )

        bad_diffraction_frames_per_step = DetectorTable(
            [True, True, True],
            ["imagingDetector", "diffDetector", "PandA"],
            ["ML-IMAGING-01", "ML-DIFF-01", "ML-PANDA-01"],
            [imaging_exposure_time, diffraction_exposure_time, 0.0],
            [1, 10, 2],
        )

        self.assertRaises(ValueError, self.o.on_validate, generator, {},
                          bad_imaging_frames_per_step)
        self.assertRaises(
            ValueError,
            self.o.on_validate,
            generator,
            {},
            bad_diffraction_frames_per_step,
        )
Esempio n. 10
0
 def test_report_configuration(self):
     p = DSGather("DS")
     self.o.add_part(p)
     b = self.process.block_view("P")
     pos_table = DatasetPositionsTable(
         name=["INENC1.VAL", "INENC2.VAL", "INENC3.VAL", "INENC4.VAL"],
         value=[0] * 4,
         offset=[0] * 4,
         scale=[0] * 4,
         units=[""] * 4,
         capture=["Diff", "No", "Min Max Mean", "Diff"],
         datasetName=["", "x1", "x2", "x3"],
         datasetType=["monitor", "monitor", "position", "monitor"],
     )
     b.positions.put_value(pos_table)
     b.configure(generator=CompoundGenerator([StaticPointGenerator(1)], [], []))
     dataset_infos = p.part_info["busses"]
     assert len(dataset_infos) == 4
     assert dataset_infos[0].name == "x2.min"
     assert dataset_infos[0].type == DatasetType.POSITION_MIN
     assert dataset_infos[0].attr == "INENC3.VAL.Min"
     assert dataset_infos[1].name == "x2.max"
     assert dataset_infos[1].type == DatasetType.POSITION_MAX
     assert dataset_infos[1].attr == "INENC3.VAL.Max"
     assert dataset_infos[2].name == "x2.value"
     assert dataset_infos[2].type == DatasetType.POSITION_VALUE
     assert dataset_infos[2].attr == "INENC3.VAL.Mean"
     assert dataset_infos[3].name == "x3.data"
     assert dataset_infos[3].type == DatasetType.MONITOR
     assert dataset_infos[3].attr == "INENC4.VAL.Diff"
 def test_acquire_scan(self):
     generator = CompoundGenerator([StaticPointGenerator(size=5)], [], [],
                                   1.0)
     generator.prepare()
     completed_steps = 0
     steps_to_do = 5
     self.o.on_configure(self.context, completed_steps, steps_to_do, {},
                         generator, [])
     assert self.o.generator is generator
     assert self.o.loaded_up_to == completed_steps
     assert self.o.scan_up_to == completed_steps + steps_to_do
     # Triggers
     IT = Trigger.IMMEDIATE
     # Half a frame
     hf = 62500000
     self.seq_parts[1].table_set.assert_called_once()
     table = self.seq_parts[1].table_set.call_args[0][0]
     assert table.repeats == [5, 1]
     assert table.trigger == [IT, IT]
     assert table.position == [0, 0]
     assert table.time1 == [hf, 125000000]
     assert table.outa1 == [1, 0]  # Live
     assert table.outb1 == [0, 1]  # Dead
     assert table.outc1 == table.outd1 == table.oute1 == table.outf1 == [
         0, 0
     ]
     assert table.time2 == [hf, 125000000]
     assert (table.outa2 == table.outb2 == table.outc2 == table.outd2 ==
             table.oute2 == table.outf2 == [0, 0])
     # Check we didn't press the gate part
     self.gate_part.enable_set.assert_not_called()
Esempio n. 12
0
 def test_validate(self):
     generator = CompoundGenerator([StaticPointGenerator(2)], [], [],
                                   0.0102)
     axesToMove = ["x"]
     # servoFrequency() return value
     self.child.handled_requests.post.return_value = 4919.300698316487
     ret = self.o.on_validate(self.context, generator, axesToMove, {})
     expected = 0.010166
     assert ret.value.duration == expected
 def test_30_thousand_time_constraint_with_inner(self):
     a = StaticPointGenerator(1)
     z = LineGenerator("z", "mm", 0, 1, 300, True)
     w = LineGenerator("w", "mm", 0, 1, 300, True)
     g = CompoundGenerator([z, w, a], [], [])
     g.prepare()  # 9e4 points
     start_time = time.time()
     C = g.get_points(0, 30000)
     end_time = time.time()
     self.assertLess(end_time - start_time, TIMELIMIT * 3)
Esempio n. 14
0
 def test_configure_no_axes(self):
     self.set_motor_attributes()
     generator = CompoundGenerator([StaticPointGenerator(6)], [], [],
                                   duration=0.1)
     generator.prepare()
     self.o.on_configure(self.context, 0, 6, {}, generator, [])
     assert self.child.handled_requests.mock_calls == [
         call.post("writeProfile",
                   csPort="CS1",
                   timeArray=[0.002],
                   userPrograms=[8]),
         call.post("executeProfile"),
         # pytest.approx to allow sensible compare with numpy arrays
         call.post(
             "writeProfile",
             csPort="CS1",
             timeArray=pytest.approx([
                 2000,
                 50000,
                 50000,
                 50000,
                 50000,
                 50000,
                 50000,
                 50000,
                 50000,
                 50000,
                 50000,
                 50000,
                 50000,
                 2000,
             ]),
             userPrograms=pytest.approx(
                 [1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 2, 8]),
             velocityMode=pytest.approx(
                 [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3]),
         ),
     ]
     assert self.o.completed_steps_lookup == [
         0,
         0,
         1,
         1,
         2,
         2,
         3,
         3,
         4,
         4,
         5,
         5,
         6,
         6,
     ]
Esempio n. 15
0
 def _configure_args(
     self,
     generator: AGenerator,
     file_dir: AFileDir,
     detectors: ADetectorTable = None,
     axes_to_move: AAxesToMove = None,
     breakpoints: ABreakpoints = None,
     file_template: AFileTemplate = "%s.h5",
 ) -> Tuple[bool, int, Dict[str, Any]]:
     # Check the detector table to see what we need to do
     assert detectors, "No detectors"
     for enable, name, mri, exposure, frames in detectors.rows():
         if name == self.name and enable:
             # Found a row saying to take part
             assert mri == self.mri, "%s has mri %s, passed %s" % (
                 name,
                 self.mri,
                 mri,
             )
             break
     else:
         # Didn't find a row or no frames, don't take part
         return False, 0, {}
     # If we had more than one frame per point, multiply out
     if frames > 1:
         axis_name = name + "_frames_per_step"
         axes_to_move = list(cast(Iterable, axes_to_move)) + [axis_name]
         # We need to multiply up the last dimension by frames
         serialized = dict(generator.to_dict())
         serialized["generators"] = list(serialized["generators"]) + [
             StaticPointGenerator(frames, axes=[axis_name])
         ]
         # Squash it down with the axes of the fastest generator
         squash_axes = list(generator.generators[-1].axes) + [axis_name]
         serialized["excluders"] = list(serialized["excluders"]) + [
             SquashingExcluder(axes=squash_axes)
         ]
         # Divide it down
         serialized["duration"] = float(serialized["duration"]) / frames
         generator = CompoundGenerator.from_dict(serialized)
     kwargs = dict(
         generator=generator,
         axesToMove=axes_to_move,
         breakpoints=breakpoints,
         fileDir=file_dir,
         # formatName is the unique part of the HDF filename, so use the part
         # name for this
         formatName=self.name,
         fileTemplate=file_template,
     )
     if exposure > 0.0:
         kwargs["exposure"] = exposure
     return enable, frames, kwargs
Esempio n. 16
0
    def test_on_validate_tweaks_zero_duration(self):
        points = StaticPointGenerator(10)
        generator = CompoundGenerator([points], [], [], 0.0)
        generator.prepare()
        # Disable the detector
        detectors = DetectorTable.from_rows([[False, "det", "DET", 0.0, 5]])
        # Expected duration is 2 clock cycles
        expected_duration = 2 * 8.0e-9

        b = self.scan.block_view()
        params = b.validate(generator, self.tmpdir, detectors=detectors)

        self.assertEqual(expected_duration, params["generator"]["duration"])
Esempio n. 17
0
    def test_breakpoints_repeat_with_static(self):
        line1 = LineGenerator("x", "mm", -10, -10, 5)
        line2 = LineGenerator("x", "mm", 0, 180, 10)
        line3 = LineGenerator("x", "mm", 190, 190, 2)
        duration = 0.01
        concat = ConcatGenerator([line1, line2, line3])

        staticGen = StaticPointGenerator(2)
        breakpoints = [2, 3, 10, 2, 2, 3, 10, 2]

        self.b.configure(
            generator=CompoundGenerator([staticGen, concat], [], [], duration),
            axesToMove=["x"],
            breakpoints=breakpoints,
        )

        assert self.c.configure_params.generator.size == 34

        self.checkState(self.ss.ARMED)
        self.checkSteps(2, 0, 34)

        self.b.run()
        self.checkSteps(5, 2, 34)
        self.checkState(self.ss.ARMED)

        self.b.run()
        self.checkSteps(15, 5, 34)
        self.checkState(self.ss.ARMED)

        self.b.run()
        self.checkSteps(17, 15, 34)
        self.checkState(self.ss.ARMED)

        self.b.run()
        self.checkSteps(19, 17, 34)
        self.checkState(self.ss.ARMED)

        self.b.run()
        self.checkSteps(22, 19, 34)
        self.checkState(self.ss.ARMED)

        self.b.run()
        self.checkSteps(32, 22, 34)
        self.checkState(self.ss.ARMED)

        self.b.run()
        self.checkSteps(34, 32, 34)
        self.checkState(self.ss.ARMED)

        self.b.run()
        self.checkState(self.ss.FINISHED)
    def test_array_positions(self):
        g = StaticPointGenerator(5)

        g.prepare_positions()
        g.prepare_bounds()

        self.assertEqual({}, g.positions)
        self.assertEqual({}, g.bounds)
    def test_array_positions_with_axis(self):
        g = StaticPointGenerator(5, 'repeats')
        positions = [1, 2, 3, 4, 5]
        bounds = [1, 2, 3, 4, 5, 6]

        g.prepare_positions()
        g.prepare_bounds()

        self.assertEqual(positions, g.positions['repeats'].tolist())
        self.assertEqual(bounds, g.bounds['repeats'].tolist())
Esempio n. 20
0
    def test_configure_cycle(self):
        self.set_motor_attributes()
        nCycles = 1
        generator = CompoundGenerator([StaticPointGenerator(nCycles)], [], [],
                                      duration=4.0)
        generator.prepare()
        self.o.on_configure(self.context, 0, nCycles, {}, generator, [])

        assert generator.duration == 1.5

        assert self.child.handled_requests.mock_calls == [
            call.post("writeProfile",
                      csPort="CS1",
                      timeArray=[0.002],
                      userPrograms=[8]),
            call.post("executeProfile"),
            call.post("moveCS1",
                      a=-0.125,
                      moveTime=pytest.approx(0.790, abs=1e-3)),
            # pytest.approx to allow sensible compare with numpy arrays
            call.post(
                "writeProfile",
                a=pytest.approx([
                    0.0, 0.25, 0.5, 0.625, 0.625, 0.5, 0.25, 0.0, -0.125,
                    -0.125, 0.0
                ]),
                csPort="CS1",
                timeArray=pytest.approx([
                    250000,
                    250000,
                    250000,
                    250000,
                    1000000,
                    250000,
                    250000,
                    250000,
                    250000,
                    1000000,
                    250000,
                ]),
                userPrograms=pytest.approx([1, 4, 2, 8, 8, 1, 4, 2, 8, 8, 1]),
                velocityMode=pytest.approx([1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 3]),
            ),
        ]
        assert self.o.completed_steps_lookup == [
            0, 0, 1, 1, 1, 1, 1, 2, 3, 3, 3
        ]
Esempio n. 21
0
 def test_configure_multiple_no_exposure(self):
     xs = LineGenerator("x", "mm", 0.0, 0.3, 4)
     ys = LineGenerator("y", "mm", 0.0, 0.1, 2)
     generator = CompoundGenerator([ys, xs], [], [], 1.0)
     generator.prepare()
     detectors = DetectorTable.from_rows([[True, "det", "DET", 0.0, 5]])
     self.o.on_configure(self.context, generator, detectors)
     assert self.o.generator_duration == 1.0
     assert self.o.frames_per_step == 5
     # Detector would normally be configured by DetectorChildPart
     detector = self.process.block_view("DET")
     spg = StaticPointGenerator(5, axes=["det_frames_per_step"])
     ex = SquashingExcluder(axes=["det_frames_per_step", "x"])
     generatormultiplied = CompoundGenerator([ys, xs, spg], [ex], [], 0.2)
     detector.configure(generatormultiplied, self.tmpdir)
     self.o.on_post_configure()
     self.check_pulse_mocks(0.19899, 0.2, 0.000505, 5)
 def test_configure_raises_ValueError_with_invalid_frames_per_step(self):
     self.set_motor_attributes()
     nCycles = 1
     generator = CompoundGenerator([StaticPointGenerator(nCycles)], [], [],
                                   duration=0.0)
     generator.prepare()
     imaging_exposure_time = 0.01
     diffraction_exposure_time = 1.0
     detectors_with_bad_imaging_frames_per_step = DetectorTable(
         [True, True, True],
         ["imagingDetector", "diffDetector", "PandA"],
         ["ML-IMAGING-01", "ML-DIFF-01", "ML-PANDA-01"],
         [imaging_exposure_time, diffraction_exposure_time, 0.0],
         [3, 1, 2],
     )
     detectors_with_bad_diffraction_frames_per_step = DetectorTable(
         [True, True, True],
         ["imagingDetector", "diffDetector", "PandA"],
         ["ML-IMAGING-01", "ML-DIFF-01", "ML-PANDA-01"],
         [imaging_exposure_time, diffraction_exposure_time, 0.0],
         [1, 10, 2],
     )
     self.assertRaises(
         ValueError,
         self.o.on_configure,
         self.context,
         0,
         nCycles,
         {},
         generator,
         detectors_with_bad_imaging_frames_per_step,
         [],
     )
     self.assertRaises(
         ValueError,
         self.o.on_configure,
         self.context,
         0,
         nCycles,
         {},
         generator,
         detectors_with_bad_diffraction_frames_per_step,
         [],
     )
    def test_configure_raises_ValueError_when_exposure_is_zero(self):
        nCycles = 1
        generator = CompoundGenerator([StaticPointGenerator(nCycles)], [], [],
                                      duration=0.0)
        imaging_exposure_time = 0.1
        diffraction_exposure_time = 0.3
        detectors_with_imaging_zero_exposure = DetectorTable(
            [False, True, True],
            ["imagingDetector", "diffDetector", "PandA"],
            ["ML-IMAGING-01", "ML-DIFF-01", "ML-PANDA-01"],
            [imaging_exposure_time, 0.0, 0.0],
            [1, 1, 2],
        )

        detectors_with_diffraction_zero_exposure = DetectorTable(
            [True, False, True],
            ["imagingDetector", "diffDetector", "PandA"],
            ["ML-IMAGING-01", "ML-DIFF-01", "ML-PANDA-01"],
            [0.0, diffraction_exposure_time, 0.0],
            [1, 1, 2],
        )

        self.assertRaises(
            ValueError,
            self.o.on_configure,
            self.context,
            0,
            nCycles,
            {},
            generator,
            detectors_with_imaging_zero_exposure,
            [],
        )
        self.assertRaises(
            ValueError,
            self.o.on_configure,
            self.context,
            0,
            nCycles,
            {},
            generator,
            detectors_with_diffraction_zero_exposure,
            [],
        )
    def test_configure_raises_ValueError_with_missing_detector(self):
        self.set_motor_attributes()
        nCycles = 1
        generator = CompoundGenerator([StaticPointGenerator(nCycles)], [], [],
                                      duration=0.0)
        generator.prepare()
        exposure_time = 0.01
        detectors_without_diffraction = DetectorTable(
            [True, True],
            ["imagingDetector", "PandA"],
            ["ML-IMAGING-01", "ML-PANDA-01"],
            [exposure_time, 0.0],
            [1, 2],
        )
        detectors_without_imaging = DetectorTable(
            [True, True],
            ["diffDetector", "PandA"],
            ["ML-DIFF-01", "ML-PANDA-01"],
            [exposure_time, 0.0],
            [1, 2],
        )

        self.assertRaises(
            ValueError,
            self.o.on_configure,
            self.context,
            0,
            nCycles,
            {},
            generator,
            detectors_without_diffraction,
            [],
        )
        self.assertRaises(
            ValueError,
            self.o.on_configure,
            self.context,
            0,
            nCycles,
            {},
            generator,
            detectors_without_imaging,
            [],
        )
    def test_staticpointgen(self):
        m = StaticPointGenerator(3)
        g = CompoundGenerator([m], [], [])
        g.prepare()

        expected_positions = [{}] * 3
        positions = [point.positions for point in g.iterator()]
        self.assertEqual(expected_positions, positions)

        self.assertEqual([], g.axes)
        self.assertEqual({}, g.units)
        self.assertEqual(3, g.size)
        self.assertEqual((3, ), g.shape)

        self.assertEqual(1, len(g.dimensions))
        self.assertEqual([], g.dimensions[0].upper)
        self.assertEqual([], g.dimensions[0].lower)
        self.assertEqual([], g.dimensions[0].axes)
        self.assertEqual(3, g.dimensions[0].size)
    def test_validate_returns_tweaked_generator_duration(self):
        nCycles = 1
        generator = CompoundGenerator([StaticPointGenerator(nCycles)], [], [],
                                      duration=0.0)
        imaging_exposure_time = 0.1
        diffraction_exposure_time = 0.3
        detectors = self._get_detector_table(imaging_exposure_time,
                                             diffraction_exposure_time)

        # First pass we should tweak
        infos = self.o.on_validate(generator, {}, detectors)

        self.assertEqual(infos.parameter, "generator")
        assert infos.value.duration == pytest.approx(self.move_time * 2 +
                                                     imaging_exposure_time +
                                                     diffraction_exposure_time)

        # Now re-run with our tweaked generator
        infos = self.o.on_validate(infos.value, {}, detectors)
        assert infos is None, "We shouldn't need to tweak again"
    def test_acquire_scan(self):
        generator = CompoundGenerator([StaticPointGenerator(size=5)], [], [],
                                      1.0)
        generator.prepare()

        seq_rows = self.get_sequencer_rows(generator, [])
        # Triggers
        IT = Trigger.IMMEDIATE
        # Half a frame
        hf = 62500000
        expected = SequencerRows()
        expected.add_seq_entry(count=5,
                               trigger=IT,
                               position=0,
                               half_duration=hf,
                               live=1,
                               dead=0)
        expected.add_seq_entry(1, IT, 0, MIN_PULSE, 0, 1)
        expected.add_seq_entry(0, IT, 0, MIN_PULSE, 0, 0)

        assert seq_rows.as_tuples() == expected.as_tuples()
    def test_intermediate_staticpointgen(self):
        x = LineGenerator("x", "mm", 0, 1, 3, False)
        y = LineGenerator("y", "cm", 2, 3, 4, False)
        m = StaticPointGenerator(5)
        g = CompoundGenerator([y, m, x], [], [])
        g.prepare()

        expected_positions = []
        for yp in [2.0, 2 + 1. / 3, 2 + 2. / 3, 3.0]:
            for mp in range_(5):
                for xp in [0.0, 0.5, 1.0]:
                    expected_positions.append({"y": yp, "x": xp})

        positions = [point.positions for point in g.iterator()]
        self.assertEqual(expected_positions, positions)

        self.assertEqual(60, g.size)
        self.assertEqual((4, 5, 3), g.shape)
        self.assertEqual(["y", "x"], g.axes)
        self.assertEqual({"y": "cm", "x": "mm"}, g.units)
        self.assertEqual(3, len(g.dimensions))
    def test_validate_raises_ValueError_when_detector_not_enabled(self):
        nCycles = 1
        generator = CompoundGenerator([StaticPointGenerator(nCycles)], [], [],
                                      duration=0.0)
        imaging_exposure_time = 0.1
        diffraction_exposure_time = 0.3
        detectors_with_imaging_disabled = DetectorTable(
            [False, True, True],
            ["imagingDetector", "diffDetector", "PandA"],
            ["ML-IMAGING-01", "ML-DIFF-01", "ML-PANDA-01"],
            [imaging_exposure_time, diffraction_exposure_time, 0.0],
            [1, 1, 2],
        )

        detectors_with_diffraction_disabled = DetectorTable(
            [True, False, True],
            ["imagingDetector", "diffDetector", "PandA"],
            ["ML-IMAGING-01", "ML-DIFF-01", "ML-PANDA-01"],
            [imaging_exposure_time, diffraction_exposure_time, 0.0],
            [1, 1, 2],
        )

        self.assertRaises(
            ValueError,
            self.o.on_validate,
            generator,
            {},
            detectors_with_imaging_disabled,
        )
        self.assertRaises(
            ValueError,
            self.o.on_validate,
            generator,
            {},
            detectors_with_diffraction_disabled,
        )
    def test_validate_raises_ValueError_for_missing_detector(self):
        nCycles = 1
        generator = CompoundGenerator([StaticPointGenerator(nCycles)], [], [],
                                      duration=0.0)
        imaging_exposure_time = 0.1
        diffraction_exposure_time = 0.3
        table_without_imaging_detector = DetectorTable(
            [True, True],
            ["diffDetector", "PandA"],
            ["ML-DIFF-01", "ML-PANDA-01"],
            [diffraction_exposure_time, 0.0],
            [1, 2],
        )

        table_without_diffraction_detector = DetectorTable(
            [True, True],
            ["imagingDetector", "PandA"],
            ["ML-IMAGING-01", "ML-PANDA-01"],
            [imaging_exposure_time, 0.0],
            [1, 2],
        )

        self.assertRaises(
            ValueError,
            self.o.on_validate,
            generator,
            {},
            table_without_imaging_detector,
        )
        self.assertRaises(
            ValueError,
            self.o.on_validate,
            generator,
            {},
            table_without_diffraction_detector,
        )