示例#1
0
    def test_writeable_function_value(self):
        def nop():
            return 0

        def write(position):
            positions.append(position)

        positions = []

        # Get 10 images.
        readables = [nop]
        expected_positions = [1, 2, 3, 4, 5]
        positioner = VectorPositioner(expected_positions)
        writables = write

        scan(positioner, readables=readables, writables=writables)
        self.assertEqual(positions, expected_positions,
                         "Expected positions not equal.")

        def write2(position):
            positions2.append(position)

        positions2 = []

        positions.clear()
        expected_positions = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
        writables = ["something1", write, "something2", write2]
        positioner = VectorPositioner(expected_positions)

        scan(positioner, readables=readables, writables=writables)

        self.assertEqual(positions, [x[1] for x in expected_positions],
                         "Values not as expected.")
        self.assertEqual(positions2, [x[3] for x in expected_positions],
                         "Values not as expected")
示例#2
0
    def test_VectorPositioner(self):
        expected_result = [[-2., -2], [-1., -1], [0., 0], [1., 1], [2., 2]]

        # # Test 1 pass.
        self.verify_result(VectorPositioner(expected_result), expected_result)

        # Test 3 passes.
        self.verify_result(VectorPositioner(expected_result, passes=3),
                           expected_result * 3)

        expected_result = [[0.0, -1], [1.0, 0], [2.0, 1], [3.0, 2], [4.0, 3]]

        # Test offset.
        self.verify_result(VectorPositioner(expected_result, offsets=[2, 1]),
                           expected_result)
示例#3
0
    def test_actions(self):
        positions = [[1, 1], [2, 2]]
        positioner = VectorPositioner(positions)

        writables = [
            epics_pv("PYSCAN:TEST:MOTOR1:SET", "PYSCAN:TEST:MOTOR1:GET"),
            epics_pv("PYSCAN:TEST:MOTOR2:SET", "PYSCAN:TEST:MOTOR2:GET")
        ]

        readables = [epics_pv("PYSCAN:TEST:OBS1")]

        # MOTOR1 initial values should be -11, MOTOR2 -22.
        cached_initial_values["PYSCAN:TEST:MOTOR1:SET"] = -11
        cached_initial_values["PYSCAN:TEST:MOTOR2:SET"] = -22
        initialization = [action_set_epics_pv("PYSCAN:TEST:OBS1", -33)]
        finalization = [action_restore(writables)]

        result = scan(positioner=positioner,
                      readables=readables,
                      writables=writables,
                      initialization=initialization,
                      finalization=finalization,
                      settings=scan_settings(measurement_interval=0.25,
                                             n_measurements=1))

        self.assertEqual(pv_cache["PYSCAN:TEST:MOTOR1:SET"][0].value, -11,
                         "Finalization did not restore original value.")
        self.assertEqual(pv_cache["PYSCAN:TEST:MOTOR2:SET"][0].value, -22,
                         "Finalization did not restore original value.")

        self.assertEqual(result[0][0], -33,
                         "Initialization action did not work.")
示例#4
0
    def test_progress_monitor(self):

        current_index = []
        total_positions = 0
        current_percentage = []

        def progress(current_position, max_position):
            current_index.append(current_position)
            current_percentage.append(100 * (current_position / max_position))

            nonlocal total_positions
            total_positions = max_position

        positions = [1, 2, 3, 4, 5]
        positioner = VectorPositioner(positions)
        writables = epics_pv("PYSCAN:TEST:MOTOR1:SET",
                             "PYSCAN:TEST:MOTOR1:GET")
        readables = epics_pv("PYSCAN:TEST:OBS1")
        settings = scan_settings(progress_callback=progress)

        scan(positioner, readables, writables, settings=settings)

        self.assertEqual(
            len(positions) + 1, len(current_index),
            "The number of reported positions is wrong.")
        self.assertEqual(total_positions, 5,
                         "The number of total positions is wrong.")
        self.assertEqual(current_index, [0, 1, 2, 3, 4, 5],
                         "The reported percentage is wrong.")
        self.assertEqual(current_percentage, [0, 20, 40, 60, 80, 100],
                         "The reported percentage is wrong.")
示例#5
0
    def test_after_measurement_executor(self):

        counter = -1

        def void_read():
            nonlocal counter
            counter += 1
            return counter

        def void_write(position):
            positions.append(position)

        positions = []

        def after_read_0():
            self.assertTrue(len(positions) > 0)

        def after_read_1(position):
            self.assertEqual(position, positions[-1])

        def after_read_2(position, position_data):
            self.assertEqual(position, positions[-1])
            # Data value is equal to the position index.
            self.assertEqual(position_data[0], positions[-1])

        positioner = VectorPositioner([0, 1, 2, 3, 4, 5])

        after_read = [after_read_0, after_read_1, after_read_2]

        scan(readables=void_read,
             writables=void_write,
             positioner=positioner,
             after_read=after_read)
示例#6
0
    def test_mixed_sources(self):
        config.bs_connection_mode = "pull"
        config.bs_default_host = "localhost"
        config.bs_default_port = 9999

        positions = [[1, 1], [2, 2], [3, 3], [4, 4]]
        positioner = VectorPositioner(positions)

        writables = [
            epics_pv("PYSCAN:TEST:MOTOR1:SET", "PYSCAN:TEST:MOTOR1:GET"),
            epics_pv("PYSCAN:TEST:MOTOR2:SET", "PYSCAN:TEST:MOTOR2:GET")
        ]

        readables = [
            bs_property("CAMERA1:X"),
            bs_property("CAMERA1:Y"),
            epics_pv("PYSCAN:TEST:OBS1")
        ]

        conditions = [
            epics_condition("PYSCAN:TEST:VALID1", 10),
            bs_condition("CAMERA1:VALID", 10)
        ]

        initialization = [
            action_set_epics_pv("PYSCAN:TEST:PRE1:SET", 1,
                                "PYSCAN:TEST:PRE1:GET")
        ]

        finalization = [
            action_set_epics_pv("PYSCAN:TEST:PRE1:SET", 0,
                                "PYSCAN:TEST:PRE1:GET"),
            action_restore(writables)
        ]

        result = scan(positioner=positioner,
                      readables=readables,
                      writables=writables,
                      conditions=conditions,
                      initialization=initialization,
                      finalization=finalization,
                      settings=scan_settings(measurement_interval=0.25,
                                             n_measurements=1))

        self.assertEqual(len(result), len(positions),
                         "Not the expected number of results.")

        # The first 2 attributes are from bs_read, they should be equal to the pulse ID processed.
        self.assertTrue(all(x[0] == x[1] and x[2] == 1 for x in result),
                        "The result is wrong.")
示例#7
0
    def get_positioner(self):
        """
        Generate a positioner for the provided dimensions.
        :return: Positioner object.
        """
        # Read all the initial positions - in case we need to do an additive scan.
        initial_positions = self.epics_dal.get_group(READ_GROUP).read()

        positioners = []
        knob_readback_offset = 0
        for dimension in self.dimensions:
            is_additive = bool(dimension.get("Additive", 0))
            is_series = bool(dimension.get("Series", 0))
            n_knob_readbacks = len(dimension["KnobReadback"])

            # This dimension uses relative positions, read the PVs initial state.
            # We also need initial positions for the series scan.
            if is_additive or is_series:
                offsets = convert_to_list(initial_positions[
                    knob_readback_offset:knob_readback_offset +
                    n_knob_readbacks])
            else:
                offsets = None

            # Series scan in this dimension, use StepByStepVectorPositioner.
            if is_series:
                # In the StepByStep positioner, the initial values need to be added to the steps.
                positions = convert_to_list(dimension["ScanValues"])
                positioners.append(
                    SerialPositioner(positions,
                                     initial_positions=offsets,
                                     offsets=offsets if is_additive else None))
            # Line scan in this dimension, use VectorPositioner.
            else:
                positions = convert_to_position_list(
                    convert_to_list(dimension["KnobExpanded"]))
                positioners.append(VectorPositioner(positions,
                                                    offsets=offsets))

            # Increase the knob readback offset.
            knob_readback_offset += n_knob_readbacks

        # Assemble all individual positioners together.
        positioner = CompoundPositioner(positioners)
        return positioner
示例#8
0
    def test_convert_readables(self):
        config.bs_connection_mode = "pull"
        config.bs_default_host = "localhost"
        config.bs_default_port = 9999

        positions = [[0, 10], [1, 11], [2, 12], [2, 13]]
        positioner = VectorPositioner(positions)

        readables = [
            bs_property("CAMERA1:X"), "bs://CAMERA1:X", "BS://CAMERA1:X",
            epics_pv("PYSCAN:TEST:OBS1"), "PYSCAN:TEST:OBS1",
            "ca://PYSCAN:TEST:OBS1", "CA://PYSCAN:TEST:OBS1"
        ]

        writables = ["ca://PYSCAN:TEST:MOTOR1:SET", "PYSCAN:TEST:MOTOR2:SET"]

        def collect_positions():
            actual_positions.append([
                pv_cache["PYSCAN:TEST:MOTOR1:SET"][0].value,
                pv_cache["PYSCAN:TEST:MOTOR2:SET"][0].value
            ])

        actual_positions = []

        result = scan(positioner=positioner,
                      readables=readables,
                      writables=writables,
                      after_read=collect_positions)
        for index in range(len(positions)):
            self.assertTrue(
                result[index][0] == result[index][1] == result[index][2],
                "Not all acquisitions are equal.")
            self.assertTrue(
                result[index][3] == result[index][4] == result[index][5],
                "Not all acquisitions are equal.")

        self.assertEqual(positions, actual_positions,
                         "Does not work for writables.")
示例#9
0
    def test_before_after_move_executor(self):
        def void_read():
            return 1

        def void_write(position):
            positions.append(position)

        positions = []

        def before_move(position):
            self.assertTrue(position not in positions,
                            "Positions already visited.")

        def after_move(position):
            self.assertTrue(position in positions, "Position not yet visited.")

        positioner = VectorPositioner([1, 2, 3, 4, 5, 6])

        scan(readables=void_read,
             writables=void_write,
             positioner=positioner,
             before_move=before_move,
             after_move=after_move)
示例#10
0
    def test_CompoundPositioner(self):
        expected_result = [[0], [1], [2], [3]]
        # The compound positioner should not modify the behaviour if only 1 positioner was supplied.
        self.verify_result(
            CompoundPositioner([SerialPositioner([0, 1, 2, 3], [-1])]),
            expected_result)

        expected_result = [[0.0, 0.0], [0.0, 3.0], [3.0, 3.0], [3.0, 0.0]]
        # Test with other positioners as well.
        self.verify_result(
            CompoundPositioner([ZigZagAreaPositioner([0, 0], [3, 3], [1, 1])]),
            expected_result)

        self.verify_result(
            CompoundPositioner([VectorPositioner(expected_result, passes=3)]),
            expected_result * 3)

        # Perform tests for PyScan.
        first_input = [[-3, -2, -1, 0], [-3, -2, -1, 0]]
        second_input = [[0, 1, 2], [0, 1, 2]]
        # Transform the list to be position by position, not axis by axis.
        first_input = convert_to_position_list(first_input)
        second_input = convert_to_position_list(second_input)

        # 2 ScanLine axes.
        expected_result = [[-3, -3, 0, 0], [-3, -3, 1, 1], [-3, -3, 2, 2],
                           [-2, -2, 0, 0], [-2, -2, 1, 1], [-2, -2, 2, 2],
                           [-1, -1, 0, 0], [-1, -1, 1, 1], [-1, -1, 2, 2],
                           [-0, -0, 0, 0], [-0, -0, 1, 1], [-0, -0, 2, 2]]

        self.verify_result(
            CompoundPositioner([
                VectorPositioner(first_input),
                VectorPositioner(second_input)
            ]), expected_result)

        # 2 ScanSeries axes.
        expected_result = [[-3, -12, 0, -22], [-3, -12, 1, -22],
                           [-3, -12, 2, -22], [-3, -12, -21, 0],
                           [-3, -12, -21, 1], [-3, -12, -21, 2],
                           [-2, -12, 0, -22], [-2, -12, 1, -22],
                           [-2, -12, 2, -22], [-2, -12, -21, 0],
                           [-2, -12, -21, 1], [-2, -12, -21, 2],
                           [-1, -12, 0, -22], [-1, -12, 1, -22],
                           [-1, -12, 2, -22], [-1, -12, -21, 0],
                           [-1, -12, -21, 1], [-1, -12, -21, 2],
                           [-0, -12, 0, -22], [-0, -12, 1, -22],
                           [-0, -12, 2, -22], [-0, -12, -21, 0],
                           [-0, -12, -21, 1], [-0, -12, -21, 2],
                           [-11, -3, 0, -22], [-11, -3, 1, -22],
                           [-11, -3, 2, -22], [-11, -3, -21, 0],
                           [-11, -3, -21, 1], [-11, -3, -21, 2],
                           [-11, -2, 0, -22], [-11, -2, 1, -22],
                           [-11, -2, 2, -22], [-11, -2, -21, 0],
                           [-11, -2, -21, 1], [-11, -2, -21, 2],
                           [-11, -1, 0, -22], [-11, -1, 1, -22],
                           [-11, -1, 2, -22], [-11, -1, -21, 0],
                           [-11, -1, -21, 1], [-11, -1, -21, 2],
                           [-11, -0, 0, -22], [-11, -0, 1, -22],
                           [-11, -0, 2, -22], [-11, -0, -21, 0],
                           [-11, -0, -21, 1], [-11, -0, -21, 2]]

        # Initial positions to be used.
        first_input = [[-3, -2, -1, 0], [-3, -2, -1, 0]]
        second_input = [[0, 1, 2], [0, 1, 2]]
        first_initial = [-11, -12]
        second_initial = [-21, -22]

        self.verify_result(
            CompoundPositioner([
                SerialPositioner(first_input, first_initial),
                SerialPositioner(second_input, second_initial)
            ]), expected_result)

        # First dimension LineScan, second dimension first change one, than another.
        expected_result = [[-3, -3, 0, -22], [-3, -3, 1,
                                              -22], [-3, -3, 2, -22],
                           [-3, -3, -21, 0], [-3, -3, -21,
                                              1], [-3, -3, -21, 2],
                           [-2, -2, 0, -22], [-2, -2, 1,
                                              -22], [-2, -2, 2, -22],
                           [-2, -2, -21, 0], [-2, -2, -21,
                                              1], [-2, -2, -21, 2],
                           [-1, -1, 0, -22], [-1, -1, 1,
                                              -22], [-1, -1, 2, -22],
                           [-1, -1, -21, 0], [-1, -1, -21,
                                              1], [-1, -1, -21, 2],
                           [-0, -0, 0, -22], [-0, -0, 1,
                                              -22], [-0, -0, 2, -22],
                           [-0, -0, -21, 0], [-0, -0, -21, 1],
                           [-0, -0, -21, 2]]

        first_input = convert_to_position_list([[-3, -2, -1, 0],
                                                [-3, -2, -1, 0]])

        self.verify_result(
            CompoundPositioner([
                VectorPositioner(first_input),
                SerialPositioner(second_input, second_initial)
            ]), expected_result)