class JLineGenerator2D(JavaIteratorWrapper):
    """
    Create a 2D LineGenerator and wrap the points into java Point objects
    """
    
    def __init__(self, names, units, start, stop, num_points, alternate_direction=False):
        super(JLineGenerator2D, self).__init__()
        
        start = start.tolist()  # Convert from array to list
        stop = stop.tolist()
        
        self.names = names
        self.generator = LineGenerator(names, units, start, stop, num_points, alternate_direction)
        logging.debug(self.generator.to_dict())
    
    def _iterator(self):
        
        for point in self.generator.iterator():
            index = point.indexes[0]
            x_name = self.names[0]
            y_name = self.names[1]
            x_position = point.positions[x_name]
            y_position = point.positions[y_name]
            java_point = Point(x_name, index, x_position, 
                               y_name, index, y_position, False)
            # Set is2D=False
            
            yield java_point
 def test_triple_alternating_linked_gen(self):
     tg = LineGenerator("t", "mm", 1, 5, 5)
     zg = LineGenerator("z", "mm", -1, 3, 5, True)
     yg = LineGenerator("y", "mm", 0, 4, 5, True)
     xg = LineGenerator("x", "mm", 0, 4, 5, True)
     r1 = RectangularROI([-1, -1], 5.5, 3.5)
     r2 = RectangularROI([1, 0], 2.5, 2.5)
     e1 = ROIExcluder([r1], ["z", "y"])
     e2 = ROIExcluder([r2], ["x", "y"])
     g = CompoundGenerator([tg, zg, yg, xg], [e1, e2], [])
     g.prepare()
     zf = True
     yf = True
     xf = True
     expected = []
     for t in range_(1, 6):
         zr = range_(-1, 4) if zf else range_(3, -2, -1)
         zf = not zf
         for z in zr:
             yr = range_(0, 5) if yf else range_(4, -1, -1)
             yf = not yf
             for y in yr:
                 xr = range_(0, 5) if xf else range_(4, -1, -1)
                 xf = not xf
                 for x in xr:
                    if z >= -1 and z < 4.5 and y >= 0 and y < 2.5 \
                         and x >= 1 and x < 3.5:
                         expected.append({"x":float(x), "y":float(y),
                             "z":float(z), "t":float(t)})
     actual = [p.positions for p in g.iterator()]
     self.assertEqual(len(expected), len(actual))
     for e, a in zip(expected, actual):
         self.assertEqual(e, a)
 def test_configure(self):
     xs = LineGenerator("x", "mm", 0.0, 0.5, 3000, alternate=True)
     ys = LineGenerator("y", "mm", 0.0, 0.1, 2000)
     generator = CompoundGenerator([ys, xs], [], [], 0.1)
     generator.prepare()
     completed_steps = 0
     steps_to_do = 2000 * 3000
     # 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.o.configure(self.context,
                      completed_steps,
                      steps_to_do, {},
                      generator=generator)
     assert self.child.handled_requests.mock_calls == [
         call.put('exposure', 0.1),
         call.put('acquirePeriod', 0.1),
         call.put('arrayCallbacks', True),
         call.put('arrayCounter', 0),
         # duration - readout - fudge_factor - crystal offset
         call.put('exposure', pytest.approx(0.1 - 0.005 - 0.0014 - 5e-6)),
         call.put('imageMode', 'Multiple'),
         call.put('numImages', 6000000),
         call.put('acquirePeriod', 0.1 - 5e-6),
         call.post('start')
     ]
    def test_load_more_positions(self):
        task = MagicMock()
        current_index = 1
        # Haven't done point 4 or 5 yet
        self.o.end_index = 4
        self.o.steps_up_to = 6
        xs = LineGenerator("x", "mm", 0.0, 0.5, 3, alternate=True)
        ys = LineGenerator("y", "mm", 0.0, 0.1, 2)
        self.o.generator = CompoundGenerator([ys, xs], [], [])
        self.o.generator.prepare()
        self.o.load_more_positions(current_index, task)
        expected_xml = """<?xml version="1.0" ?>
<pos_layout>
<dimensions>
<dimension name="d0" />
<dimension name="d1" />
<dimension name="FilePluginClose" />
</dimensions>
<positions>
<position FilePluginClose="0" d0="1" d1="1" />
<position FilePluginClose="1" d0="1" d1="0" />
</positions>
</pos_layout>""".replace("\n", "")
        task.put.assert_called_once_with(self.child["xml"], expected_xml)
        self.assertEqual(self.o.end_index, 6)
 def test_validate(self):
     line1 = LineGenerator('y', 'mm', 0, 2, 3)
     line2 = LineGenerator('x', 'mm', 0, 2, 2)
     compound = CompoundGenerator([line1, line2], [], [])
     actual = self.b.validate(generator=compound, axesToMove=['x'])
     self.assertEqual(actual["generator"], compound)
     self.assertEqual(actual["axesToMove"], ('x', ))
    def test_alternating_regions_2(self):
        z = LineGenerator("z", "mm", 1, 5, 5)
        y = LineGenerator("y", "mm", 1, 5, 5, True)
        x = LineGenerator("x", "mm", 1, 5, 5, True)
        r1 = CircularROI([3, 3], 1.5)
        e1 = ROIExcluder([r1], ["x", "y"])
        e2 = ROIExcluder([r1], ["z", "y"])
        g = CompoundGenerator([z, y, x], [e1, e2], [])  #20 points
        g.prepare()
        actual = [p.positions for p in list(g.iterator())]
        expected = []
        yf = True
        xf = True
        for z in range_(1, 6):
            yr = range_(1, 6) if yf else range_(5, 0, -1)
            yf = not yf
            for y in yr:
                xr = range_(1, 6) if xf else range_(5, 0, -1)
                xf = not xf
                for x in xr:
                    expected.append({
                        "x": float(x),
                        "y": float(y),
                        "z": float(z)
                    })

        expected = [
            p for p in expected if (p["x"] - 3)**2 +
            (p["y"] - 3)**2 <= 1.5**2 and (p["z"] - 3)**2 +
            (p["y"] - 3)**2 <= 1.5**2
        ]
        self.assertEqual(expected, actual)
 def test_array_positions_from_line_non_matching_bounds(self):
     genone = LineGenerator("x", "mm", 1.0, 9.0, 5)
     gentwo = LineGenerator("x", "mm", 20, 24, 5)
     g = ConcatGenerator([genone, gentwo])
     g.prepare_positions()
     with self.assertRaises(AssertionError):
         g.prepare_bounds()
    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_alternating_three_axis(self):
     z = LineGenerator("z", "mm", 1, 2, 2)
     y = LineGenerator("y", "mm", 1, 2, 2, True)
     x = LineGenerator("x", "mm", 3, 1, 3, True)
     g = CompoundGenerator([z, y, x], [], [])
     g.prepare()
     expected = []
     expected_idx = []
     expected_lower = []
     expected_upper = []
     y_f = True
     x_f = True
     for z in range_(1, 3):
         y_r = range_(1, 3) if y_f else range_(2, 0, -1)
         y_f = not y_f
         for y in y_r:
             x_r = range_(3, 0, -1) if x_f else range_(1, 4)
             for x in x_r:
                 expected.append({
                     "x": float(x),
                     "y": float(y),
                     "z": float(z)
                 })
                 expected_idx.append([z - 1, y - 1, 3 - x])
                 expected_lower.append(x + (0.5 if x_f else -0.5))
                 expected_upper.append(x + (-0.5 if x_f else 0.5))
             x_f = not x_f
     points = list(g.iterator())
     self.assertEqual(expected, [p.positions for p in points])
     self.assertEqual(expected_idx, [p.indexes for p in points])
     self.assertEqual(expected_lower, [p.lower["x"] for p in points])
     self.assertEqual(expected_upper, [p.upper["x"] for p in points])
 def test_configure_with_breakpoints(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 = 3
     info = ExposureDeadtimeInfo(0.01, 1000, 0.0)
     part_info = dict(anyname=[info])
     self.set_attributes(self.child, triggerMode="Internal")
     self.o.on_configure(
         self.context,
         completed_steps,
         steps_to_do,
         part_info,
         generator,
         fileDir="/tmp",
         breakpoints=[3, 3],
         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", 3),
         call.put("acquirePeriod", 0.1 - 0.0001),
     ]
     assert not self.o.is_hardware_triggered
Exemple #11
0
 def test_validate(self):
     params = MagicMock()
     xs = LineGenerator("x", "mm", 0.0, 0.5, 3, alternate=True)
     ys = LineGenerator("y", "mm", 0.0, 0.1, 2)
     params.generator = CompoundGenerator([ys, xs], [], [], 0.1)
     params.generator.prepare()
     self.o.validate(ANY, ANY, params)
Exemple #12
0
    def test_minimum_profile(self):
        # tests that a turnaround that is >= minturnaround
        # is reduced to a start and end point only
        # this supports keeping the turnaround really short where
        # the motors are fast e.g. j15
        axes_to_scan = ["x", "y"]
        duration = 0.005
        self.set_motor_attributes(
            0.0,
            0.0,
            "mm",
            x_acceleration=100.0,
            x_velocity=2.0,
            y_acceleration=100.0,
            y_velocity=2.0,
        )
        steps_to_do = 1 * len(axes_to_scan)

        xs = LineGenerator("x", "mm", 0, 0.0001, 2)
        ys = LineGenerator("y", "mm", 0, 0, 2)
        generator = CompoundGenerator([ys, xs], [], [],
                                      duration,
                                      continuous=False)
        generator.prepare()

        m = [MinTurnaroundInfo(0.002, 0.002)]
        self.o.on_configure(self.context, 0, steps_to_do, {"part": m},
                            generator, axes_to_scan)

        action, func, args = self.child.handled_requests.mock_calls[-1]
        assert args["a"] == pytest.approx(
            [0, 0, 0, 0.0001, 0.0001, 0.0001, 0.0001])
        assert args["b"] == pytest.approx([0, 0, 0, 0, 0, 0, 0])
        assert args["timeArray"] == pytest.approx(
            [2000, 2500, 2500, 2000, 2500, 2500, 2000])

        # now make the acceleration slower so that the turnaround takes
        # longer than the minimum interval
        self.set_motor_attributes(
            0.0,
            0.0,
            "mm",
            x_acceleration=10.0,
            x_velocity=2.0,
            y_acceleration=100.0,
            y_velocity=2.0,
        )

        self.o.on_configure(self.context, 0, steps_to_do, {"part": m},
                            generator, axes_to_scan)

        # this generates one mid point between the 1st upper and 2nd lower
        # bounds. Note that the point is not exactly central due to time
        # quantization
        action, func, args = self.child.handled_requests.mock_calls[-1]
        assert args["a"] == pytest.approx(
            [0, 0, 0, 5.0e-05, 0.0001, 0.0001, 0.0001, 0.0001])
        assert args["b"] == pytest.approx([0, 0, 0, 0, 0, 0, 0, 0])
        assert args["timeArray"] == pytest.approx(
            [2000, 2500, 2500, 6000, 6000, 2500, 2500, 2000])
    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
Exemple #14
0
    def long_configure(self, row_gate=False):
        # test 4,000,000 points configure - used to check performance
        if row_gate:
            infos = [
                MotionTriggerInfo(MotionTrigger.ROW_GATE),
            ]
        else:
            infos = None
        self.set_motor_attributes(
            0,
            0,
            "mm",
            x_velocity=300,
            y_velocity=300,
            x_acceleration=30,
            y_acceleration=30,
        )
        axes_to_scan = ["x", "y"]
        x_steps, y_steps = 4000, 1000
        steps_to_do = x_steps * y_steps
        xs = LineGenerator("x", "mm", 0.0, 10, x_steps, alternate=True)
        ys = LineGenerator("y", "mm", 0.0, 8, y_steps)
        generator = CompoundGenerator([ys, xs], [], [], 0.0001)
        generator.prepare()

        start = datetime.now()
        self.o.on_configure(self.context, 0, steps_to_do, {"part": infos},
                            generator, axes_to_scan)
        elapsed = datetime.now() - start
        # todo goal was sub 1 second but we achieved sub 3 secs
        assert elapsed.total_seconds() < 3.5
 def test_configure_software_trigger_succeeds(self):
     xs = LineGenerator("x", "mm", 0.0, 0.5, 3, alternate=True)
     ys = LineGenerator("y", "mm", 0.0, 0.1, 2)
     duration = 0.1
     generator = CompoundGenerator([ys, xs], [], [], duration)
     generator.prepare()
     completed_steps = 0
     steps_to_do = 6
     # We wait to be armed, so set this here
     self.set_attributes(self.child,
                         acquiring=True,
                         triggerOffCondition="Always On")
     self.o.on_configure(self.context,
                         completed_steps,
                         steps_to_do, {},
                         generator,
                         fileDir="/tmp")
     # We expect only these calls (no arming in software trigger mode)
     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", 1000),
     ]
 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_configure_continuous(self):
        xs = LineGenerator("x", "mm", 0.0, 0.3, 4, alternate=True)
        ys = LineGenerator("y", "mm", 0.0, 0.1, 2)
        generator = CompoundGenerator([ys, xs], [], [], 1.0)
        self.set_motor_attributes()
        axes_to_move = ["x", "y"]

        seq_rows = self.get_sequencer_rows(generator, axes_to_move)
        # Triggers
        GT = Trigger.POSA_GT
        IT = Trigger.IMMEDIATE
        LT = Trigger.POSA_LT
        # Half a frame
        hf = 62500000
        # Half how long to be blind for
        hb = 22500000
        expected = SequencerRows()
        expected.add_seq_entry(count=1,
                               trigger=LT,
                               position=50,
                               half_duration=hf,
                               live=1,
                               dead=0)
        expected.add_seq_entry(3, IT, 0, hf, 1, 0)
        expected.add_seq_entry(1, IT, 0, hb, 0, 1)
        expected.add_seq_entry(1, GT, -350, hf, 1, 0)
        expected.add_seq_entry(3, IT, 0, hf, 1, 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()
Exemple #18
0
def grid_check():

    x = LineGenerator("x", "mm", 0.0, 4.0, 5, alternate=True)
    y = LineGenerator("y", "mm", 0.0, 3.0, 4)
    gen = CompoundGenerator([y, x], [], [])

    plot_generator(gen)
Exemple #19
0
def grid_fly(flyer, y, ystart, ystop, ynum, x, xstart, xstop, xnum):
    generator = CompoundGenerator(
        generators=[
            LineGenerator(y.name, "mm", ystart, ystop, ynum),
            LineGenerator(x.name, "mm", xstart, xstop, xnum),
        ],
        duration=0.1,
    )
    mapping.configure(dict(generator=generator))
    md = dict(
        hints=dict(
            gridding="rectilinear",
            dimensions=[([y.name], "primary"), ([x.name], "primary")],
        ),
        shape=(ynum, xnum),
        extents=([ystart, ystop], [xstart, xstop]),
    )
    uid = yield from bps.open_run(md)
    yield from bps.kickoff(flyer, wait=True)
    yield from bps.collect(flyer, stream=True)
    yield from bps.checkpoint()
    yield from bps.complete(flyer, group="flyer")
    for _ in range(int(ynum * xnum * 0.1)):
        yield from bps.sleep(1)
        yield from bps.collect(flyer, stream=True)
        yield from bps.checkpoint()
    yield from bps.wait(group="flyer")
    yield from bps.collect(flyer, stream=True)
    yield from bps.close_run()
    return uid
 def test_validate(self):
     line1 = LineGenerator('y', 'mm', 0, 2, 3)
     line2 = LineGenerator('x', 'mm', 0, 2, 2)
     compound = CompoundGenerator([line1, line2], [], [])
     actual = self.b.validate(generator=compound, axesToMove=['x'])
     assert actual["generator"].to_dict() == compound.to_dict()
     assert actual["axesToMove"] == ['x']
    def test_configure(self):
        xs = LineGenerator("x", "mm", 0.0, 0.5, 3000, alternate=True)
        ys = LineGenerator("y", "mm", 0.0, 0.1, 2000)
        generator = CompoundGenerator([ys, xs], [], [], 0.1)
        generator.prepare()
        completed_steps = 0
        steps_to_do = 2000 * 3000
        # We wait to be armed, so set this here
        self.set_attributes(self.child, acquiring=True, fanStateReady=1)
        self.o.on_configure(
            self.context,
            completed_steps,
            steps_to_do,
            {},
            generator=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", 6000000),
            call.put("numImagesPerSeries", 1),
            call.post("start"),
        ]
 def prepare_half_run(self, duration=0.01, exception=0):
     line1 = LineGenerator('y', 'mm', 0, 2, 3)
     line2 = LineGenerator('x', 'mm', 0, 2, 2)
     compound = CompoundGenerator([line1, line2], [], [], duration)
     self.b.configure(generator=compound,
                      axesToMove=['x'],
                      exceptionStep=exception)
    def test_complex_masks(self):
        tg = LineGenerator("t", "mm", 1, 5, 5)
        zg = LineGenerator("z", "mm", 0, 4, 5, alternate=True)
        yg = LineGenerator("y", "mm", 1, 5, 5, alternate=True)
        xg = LineGenerator("x", "mm", 2, 6, 5, alternate=True)
        r1 = CircularROI([4., 4.], 1.5)
        e1 = ROIExcluder([r1], ["y", "x"])
        e2 = ROIExcluder([r1], ["z", "y"])
        g = CompoundGenerator([tg, zg, yg, xg], [e1, e2], [])
        g.prepare()

        t_mask = [True] * 5
        iy = 0
        ix = 0
        xyz_mask = []
        xyz = []
        for z in range_(0, 5):
            for y in (range_(1, 6) if iy % 2 == 0 else range_(5, 0, -1)):
                for x in (range_(2, 7) if ix % 2 == 0 else range_(6, 1, -1)):
                    xyz_mask.append( (x-4)**2 + (y-4)**2 <= 1.5**2 \
                        and (y-4)**2 + (z-4)**2 <= 1.5**2)
                    xyz.append((x, y, z))
                    ix += 1
                iy += 1

        self.assertEqual(t_mask, g.dimensions[0].mask.tolist())
        self.assertEqual(xyz_mask, g.dimensions[1].mask.tolist())
    def test_get_point_large_scan(self):
        s = SpiralGenerator(["x", "y"], "mm", [0, 0], 6, 1) #114 points
        z = LineGenerator("z", "mm", 0, 1, 100)
        w = LineGenerator("w", "mm", 0, 1, 5)
        t = LineGenerator("t", "mm", 0, 1, 5)
        rad1 = 2.8
        r1 = CircularROI([1., 1.], rad1)
        e1 = ROIExcluder([r1], ["x", "y"])
        rad2 = 2
        r2 = CircularROI([0.5, 0.5], rad2)
        e2 = ROIExcluder([r2], ["y", "z"])
        rad3 = 0.5
        r3 = CircularROI([0.5, 0.5], rad3)
        e3 = ROIExcluder([r3], ["w", "t"])
        g = CompoundGenerator([t, w, z, s], [e1, e2, e3], [])
        g.prepare()

        spiral = [(x, y) for (x, y) in zip(s.positions["x"], s.positions["y"])]
        zwt = [(z/99., w/4., t/4.) for t in range_(0, 5)
            for w in range_(0, 5)
            for z in range_(0, 100)]
        expected = [(x, y, z, w, t) for (z, w, t) in zwt for (x, y) in spiral]
        expected = [{"x":x, "y":y, "z":z, "w":w, "t":t}
                for (x,y,z,w,t) in expected if
                (x-1)*(x-1) + (y-1)*(y-1) <= rad1*rad1 and
                (y-0.5)*(y-0.5) + (z-0.5)*(z-0.5) <= rad2*rad2 and
                (w-0.5)*(w-0.5) + (t-0.5)*(t-0.5) <= rad3*rad3]
        points = [g.get_point(n) for n in range_(0, g.size)]
        pos = [p.positions for p in points]
        # assertEqual on a sequence of dicts is *really* slow
        for (e, p) in zip(expected, pos):
            self.assertEquals(e.keys(), p.keys())
            for k in e.keys():
                self.assertAlmostEqual(e[k], p[k])
    def test_inner_alternating(self):
        z = LineGenerator("z", "mm", 1, 5, 5)
        y = LineGenerator("y", "mm", 1, 5, 5, alternate=True)
        x = LineGenerator("x", "mm", 1, 5, 5, alternate=True)
        r1 = CircularROI([3, 3], 1.5)
        e1 = ROIExcluder([r1], ["x", "y"])
        g = CompoundGenerator([z, y, x], [e1], [])
        g.prepare()
        expected = []
        xy_expected = []
        x_f = True
        for y in range_(1, 6):
            for x in (range_(1, 6) if x_f else range(5, 0, -1)):
                if (x - 3)**2 + (y - 3)**2 <= 1.5**2:
                    xy_expected.append((x, y))
            x_f = not x_f
        xy_f = True
        for z in range_(1, 6):
            for (x, y) in (xy_expected if xy_f else xy_expected[::-1]):
                expected.append({"x": float(x), "y": float(y), "z": float(z)})
            xy_f = not xy_f

        expected_idx = []
        xy_f = True
        for z in range_(0, 5):
            xy_idx = range_(len(xy_expected)) if xy_f \
                else range_(len(xy_expected)-1, -1, -1)
            expected_idx += [[z, xy] for xy in xy_idx]
            xy_f = not xy_f

        points = list(g.iterator())
        self.assertEqual(expected, [p.positions for p in points])
        self.assertEqual(expected_idx, [p.indexes for p in points])
    def test_three_dim_middle_alternates(self):
        tg = LineGenerator("t", "mm", 1, 5, 5)
        zg = LineGenerator("z", "mm", -1, 3, 5, True)
        spiral = SpiralGenerator(["s1", "s2"], "mm", [1, 1], 2, 1, True)
        yg = LineGenerator("y", "mm", 0, 4, 5)
        xg = LineGenerator("x", "mm", 0, 4, 5)
        r1 = CircularROI([0, 0], 1)
        e1 = ROIExcluder([r1], ["s1", "z"])
        e2 = ROIExcluder([r1], ["y", "x"])
        g = CompoundGenerator([tg, zg, spiral, yg, xg], [e2, e1], [])
        g.prepare()

        it = 0
        iz = 0
        iy = 0
        ix = 0
        tzs = []
        points = []
        for t in range_(1, 6):
            for z in (range_(-1, 4) if it % 2 == 0 else range_(3, -2, -1)):
                s1p = spiral.positions["s1"] if iz % 2 == 0 else spiral.positions["s1"][::-1]
                s2p = spiral.positions["s2"] if iz % 2 == 0 else spiral.positions["s2"][::-1]
                points += [(x, y, s1, s2, z, t) for (s1, s2) in zip(s1p, s2p)
                        for y in range(0, 5) for x in range(0, 5)
                        if s1*s1 + z*z <= 1 and y*y + x*x <= 1]
                iz += 1
            it += 1
        expected = [{"x":float(x), "y":float(y), "s1":s1, "s2":s2, "z":float(z), "t":float(t)}
            for (x, y, s1, s2, z, t) in points]
        actual = [p.positions for p in list(g.iterator())]
        for e, a in zip(expected, actual):
            self.assertEqual(e, a)
 def test_init(self):
     genone = LineGenerator("x", "mm", 1.0, 9.0, 5)
     gentwo = LineGenerator("x", "mm", 13, 20, 5)
     g = ConcatGenerator([genone, gentwo])
     self.assertEqual(["x"], g.axes)
     self.assertEqual(dict(x="mm"), g.axis_units())
     self.assertEqual(10, g.size)
    def test_configure_and_run_prepare_components(self, buffer_class):
        buffer_instance = buffer_class.return_value
        buffer_instance.run.return_value = []

        xs = LineGenerator("x", "mm", 0.0, 0.3, 4, alternate=True)
        ys = LineGenerator("y", "mm", 0.0, 0.1, 2)
        generator = CompoundGenerator([ys, xs], [], [], 1.0)
        generator.prepare()
        completed_steps = 0
        steps_to_do = generator.size
        self.set_motor_attributes()
        axes_to_move = ["x", "y"]

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

        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

        # Other unit tests check that the sequencer rows used here are correct
        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_pre_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_configure(self):
        task = MagicMock()
        params = MagicMock()
        xs = LineGenerator("x", "mm", 0.0, 0.5, 3, alternate=True)
        ys = LineGenerator("y", "mm", 0.0, 0.1, 2)
        params.generator = CompoundGenerator([ys, xs], [], [])
        params.generator.prepare()
        completed_steps = 2
        steps_to_do = 4
        part_info = ANY
        self.o.configure(task, completed_steps, steps_to_do, part_info, params)
        self.assertEqual(
            task.post_async.call_args_list,
            [call(self.child["delete"]),
             call(self.child["start"])])
        task.put_many_async.assert_called_once_with(
            self.child, dict(enableCallbacks=True, idStart=3))
        expected_xml = """<?xml version="1.0" ?>
<pos_layout>
<dimensions>
<dimension name="d0" />
<dimension name="d1" />
<dimension name="FilePluginClose" />
</dimensions>
<positions>
<position FilePluginClose="0" d0="0" d1="2" />
<position FilePluginClose="0" d0="1" d1="2" />
<position FilePluginClose="0" d0="1" d1="1" />
<position FilePluginClose="1" d0="1" d1="0" />
</positions>
</pos_layout>""".replace("\n", "")
        task.put.assert_called_once_with(self.child["xml"], expected_xml)
 def test_alternating_complex(self):
     tg = LineGenerator("t", "mm", 1, 5, 5)
     zg = LineGenerator("z", "mm", 1, 5, 5, True)
     yg = LineGenerator("y", "mm", 1, 5, 5, True)
     xg = LineGenerator("x", "mm", 1, 5, 5, True)
     r1 = RectangularROI([3., 3.], 2., 2.)
     e1 = ROIExcluder([r1], ["y", "x"])
     e2 = ROIExcluder([r1], ["z", "y"])
     g = CompoundGenerator([tg, zg, yg, xg], [e1, e2], [])
     g.debug = True
     g.prepare()
     points = [p.positions for p in list(g.iterator())]
     expected = []
     zf, yf, xf = True, True, True
     for t in range_(1, 6):
         r_1 = range_(1,6) if zf else range_(5, 0, -1)
         zf = not zf
         for z in r_1:
             r_2 = range_(1,6) if yf else range_(5, 0, -1)
             yf = not yf
             for y in r_2:
                 r_3 = range_(1, 6) if xf else range_(5, 0, -1)
                 xf = not xf
                 for x in r_3:
                     expected.append(
                         {"t":float(t), "z":float(z),
                         "y":float(y), "x":float(x)})
     expected = [p for p in expected if
         (p["y"] >= 3 and p["y"] <= 5 and p["x"] >= 3 and p["x"] <= 5) and
         (p["z"] >= 3 and p["z"] <= 5 and p["y"] >= 3 and p["y"] <= 5)]
     self.assertEqual(expected, points)
    def test_excluder_spread_axes(self):
        sp = SpiralGenerator(["s1", "s2"], ["mm", "mm"], centre=[0, 0], radius=1, scale=0.5, alternate=True)
        y = LineGenerator("y", "mm", 0, 1, 3, True)
        z = LineGenerator("z", "mm", -2, 3, 6, True)
        e = ROIExcluder([CircularROI([0., 0.], 1.0)], ["s1", "z"])
        g = CompoundGenerator([z, y, sp], [e], [])

        g.prepare()

        s1_pos, s2_pos = sp.positions["s1"], sp.positions["s2"]
        s1_pos = np.tile(np.append(s1_pos, s1_pos[::-1]), 9)
        s2_pos = np.tile(np.append(s2_pos, s2_pos[::-1]), 9)
        y_pos = np.tile(np.repeat(np.array([0, 0.5, 1.0, 1.0, 0.5, 0]), sp.size), 3)
        z_pos = np.repeat(np.array([-2, -1, 0, 1, 2, 3]), sp.size * 3)

        mask_func = lambda ps1, pz: ps1**2 + pz**2 <= 1
        mask = mask_func(s1_pos, z_pos)

        expected_s1 = s1_pos[mask]
        expected_s2 = s2_pos[mask]
        expected_y = y_pos[mask]
        expected_z = z_pos[mask]
        expected_positions = [{'s1':ps1, 's2':ps2, 'y':py, 'z':pz}
                for (ps1, ps2, py, pz) in zip(expected_s1, expected_s2, expected_y, expected_z)]
        positions = [point.positions for point in list(g.iterator())]

        self.assertEqual(positions, expected_positions)
 def __init__(self, names, units, start, stop, num_points, alternate_direction=False):
     super(JLineGenerator2D, self).__init__()
     
     start = start.tolist()  # Convert from array to list
     stop = stop.tolist()
     
     self.names = names
     self.generator = LineGenerator(names, units, start, stop, num_points, alternate_direction)
     logging.debug(self.generator.to_dict())
class JLineGenerator1D(JavaIteratorWrapper):
    """
    Create a 1D LineGenerator and wrap the points into java Scalar objects
    """
    
    def __init__(self, name, units, start, stop, num_points, alternate_direction=False):
        super(JLineGenerator1D, self).__init__()
        
        self.name = name
        self.generator = LineGenerator(name, units, start, stop, num_points, alternate_direction)
        logging.debug(self.generator.to_dict())
    
    def _iterator(self):
        
        for point in self.generator.iterator():
            index = point.indexes[0]
            position = point.positions[self.name]
            java_point = Scalar(self.name, index, position)
            
            yield java_point
class LineGeneratorTest(ScanPointGeneratorTest):

    def setUp(self):
        self.g = LineGenerator("x", "mm", 1, 0.1, 5)

    def test_init(self):
        self.assertEqual(self.g.position_units, dict(x="mm"))
        self.assertEqual(self.g.index_dims, [5])
        self.assertEqual(self.g.index_names, ["x"])

    def test_iterator(self):
        positions = [1.0, 1.1, 1.2, 1.3, 1.4]
        lower = [0.95, 1.05, 1.15, 1.25, 1.35]
        upper = [1.05, 1.15, 1.25, 1.35, 1.45]
        indexes = [0, 1, 2, 3, 4]
        for i, p in enumerate(self.g.iterator()):
            self.assertEqual(p.positions, dict(x=positions[i]))
            self.assertEqual(p.lower, dict(x=lower[i]))
            self.assertEqual(p.upper, dict(x=upper[i]))
            self.assertEqual(p.indexes, [indexes[i]])
        self.assertEqual(i, 4)
 def setUp(self):
     self.g = LineGenerator("x", "mm", 1, 0.1, 5)
 def __init__(self, name, units, start, stop, num_points, alternate_direction=False):
     super(JLineGenerator1D, self).__init__()
     
     self.name = name
     self.generator = LineGenerator(name, units, start, stop, num_points, alternate_direction)
     logging.debug(self.generator.to_dict())