예제 #1
0
    def test_get_pos_first_tile(self):
        """Test that the position of the first tile is calculated correctly for a varying number of fields."""
        res_x, res_y = self.multibeam.resolution.value  # single field size
        px_size_x, px_size_y = self.multibeam.pixelSize.value

        # Loop over different ROA sizes by varying the number of fields in x and y.
        for x_fields, y_fields in zip((1, 2, 40, 34, 5), (1, 22, 43, 104, 25)):
            # The coordinates of the ROA in meters.
            xmin, ymin, xmax, ymax = (0, 0, res_x * px_size_x * x_fields, res_y * px_size_y * y_fields)
            coordinates = (xmin, ymin, xmax, ymax)  # in m

            # Create an ROA with the coordinates of the field.
            roa_name = time.strftime("test_megafield_id-%Y-%m-%d-%H-%M-%S")
            roa = fastem.FastEMROA(roa_name, coordinates, None, None,
                                   self.asm, self.multibeam, self.descanner,
                                   self.mppc)

            task = fastem.AcquisitionTask(self.scanner, self.multibeam, self.descanner,
                                          self.mppc, self.stage, self.ccd,
                                          self.beamshift, self.lens,
                                          roa, path=None, pre_calibrations=None, future=None)

            pos_first_tile_actual = task.get_pos_first_tile()

            # The position of the first tile is expected to be to the center position of the top left corner tile
            # of the ROA.
            pos_first_tile_expected = (xmin + res_x / 2 * px_size_x,
                                       ymax - res_y / 2 * px_size_y)
            self.assertEqual(pos_first_tile_actual, pos_first_tile_expected)
예제 #2
0
    def test_pre_calibrate(self):
        """
        Test the ASM settings are unchanged after running the pre-calibrations, except the descanner scan offset.
        """
        try:
            import fastem_calibrations
        except ImportError as err:
            raise unittest.SkipTest(f"Skipping 'test_pre_calibrate', correct libraries to perform this test are not available.\n"
                                    f"Got the error: {err}")
        res_x, res_y = self.multibeam.resolution.value  # single field size
        px_size_x, px_size_y = self.multibeam.pixelSize.value

        x_fields = 5
        y_fields = 8

        # The coordinates of the ROA in meters.
        xmin, ymin, xmax, ymax = (0, 0, res_x * px_size_x * x_fields, res_y * px_size_y * y_fields)
        coordinates = (xmin, ymin, xmax, ymax)  # in m

        # Create an ROA with the coordinates of the field.
        roa_name = time.strftime("test_megafield_id-%Y-%m-%d-%H-%M-%S")
        roa = fastem.FastEMROA(roa_name, coordinates, None, None,
                               self.asm, self.multibeam, self.descanner,
                               self.mppc)

        task = fastem.AcquisitionTask(self.scanner, self.multibeam, self.descanner,
                                      self.mppc, self.stage, self.ccd,
                                      self.beamshift, self.lens,
                                      roa, path=None, pre_calibrations=None, future=None)

        self.descanner.updateMetadata({model.MD_SCAN_GAIN: (5000, 5000)})

        # Set the _pos_first_tile, which would normally be set in the run function.
        task._pos_first_tile = task.get_pos_first_tile()
        
        asm_config_orig = configure_hw.get_config_asm(self.multibeam, self.descanner, self.mppc)
        pre_calibrations = [Calibrations.OPTICAL_AUTOFOCUS, Calibrations.IMAGE_TRANSLATION_PREALIGN]
        task.pre_calibrate(pre_calibrations=pre_calibrations)
        asm_config_current = configure_hw.get_config_asm(self.multibeam, self.descanner, self.mppc)

        # Verify that all settings, except the descanner scan offset, stay the same after running the pre-calibrations.
        for component, settings in asm_config_current.items():
            for va, value in settings.items():
                if va == 'scanOffset' and component == 'descanner':
                    # image translation pre-alignment changes the descanner offset, therefore it has changed.
                    continue
                self.assertEqual(asm_config_orig[component][va], value)
예제 #3
0
    def test_stage_pos_outside_roa(self):
        """
        The pre-calibrations need to run outside the ROA. Test that get_abs_stage_movement returns the correct value
        for a field index of (-1, -1) and that that value is outside the ROA.
        """
        res_x, res_y = self.multibeam.resolution.value  # single field size
        px_size_x, px_size_y = self.multibeam.pixelSize.value
        x_fields, y_fields = (3, 4)
        field_size_x = res_x * px_size_x
        field_size_y = res_y * px_size_y
        # The coordinates of the ROA in meters.
        xmin, ymin = (0, 0)
        xmax, ymax = (field_size_x * x_fields,
                      field_size_y * y_fields)
        coordinates = (xmin, ymin, xmax, ymax)  # in m

        # Create an ROA with the coordinates of the field.
        roa_name = time.strftime("test_megafield_id-%Y-%m-%d-%H-%M-%S")
        roa = fastem.FastEMROA(roa_name, coordinates, None, None,
                               self.asm, self.multibeam, self.descanner,
                               self.mppc)

        task = fastem.AcquisitionTask(self.scanner, self.multibeam, self.descanner,
                                      self.mppc, self.stage, self.ccd,
                                      self.beamshift, self.lens,
                                      roa, path=None, pre_calibrations=None, future=None)
        # Set the _pos_first_tile, which would normally be set in the run function.
        task._pos_first_tile = task.get_pos_first_tile()

        # Verify that for pre-calibrations compared to the top left corner of the ROA, the stage
        # position is located half a field to the top left (outside the ROA).
        task.field_idx = (-1, -1)  # (-1, -1) is the index where the pre-calibrations are performed

        # In the role='stage' coordinate system the x-axis points to the right and y-axis to the top.
        expected_position = (xmin - res_x / 2 * px_size_x,
                             ymax + res_x / 2 * px_size_y)  # [m]
        actual_position = task.get_abs_stage_movement()  # [m]
        numpy.testing.assert_allclose(actual_position, expected_position)
        # Verify that the position where the pre-calibration is performed, does not lie inside the ROA coordinates.
        self.assertFalse(is_point_in_rect(actual_position, coordinates))
예제 #4
0
    def test_get_abs_stage_movement_overlap(self):
        """
        Test the correct stage positions are returned for the corner fields of
        ROAs when there is an overlap in between fields.
        """
        res_x, res_y = self.multibeam.resolution.value  # single field size
        px_size_x, px_size_y = self.multibeam.pixelSize.value
        x_fields, y_fields = (3, 4)
        field_size_x = res_x * px_size_x
        field_size_y = res_y * px_size_y

        for overlap in (0, 0.0625, 0.2, 0.5, 0.7):
            # The coordinates of the ROA in meters.
            xmin, ymin = (0, 0)
            # The max field size is the number of fields multiplied with the field size including overlap, plus
            # the extra overlap added to the end.
            xmax, ymax = (field_size_x * x_fields * (1 - overlap) + field_size_x * overlap,
                          field_size_y * y_fields * (1 - overlap) + field_size_y * overlap)
            coordinates = (xmin, ymin, xmax, ymax)  # in m

            # Create an ROA with the coordinates of the field.
            roa_name = time.strftime("test_megafield_id-%Y-%m-%d-%H-%M-%S")
            roa = fastem.FastEMROA(roa_name, coordinates, None, None,
                                   self.asm, self.multibeam, self.descanner,
                                   self.mppc, overlap)

            task = fastem.AcquisitionTask(self.scanner, self.multibeam, self.descanner,
                                          self.mppc, self.stage, self.ccd,
                                          self.beamshift, self.lens,
                                          roa, path=None, pre_calibrations=None, future=None)

            # Set the _pos_first_tile, which would normally be set in the run function.
            task._pos_first_tile = task.get_pos_first_tile()

            # Verify that compared to the top left corner of the ROA, the stage
            # position is located half a field to the bottom right.
            task.field_idx = (0, 0)  # (0, 0) is the index of the first field

            # In the role='stage' coordinate system the x-axis points to the right and y-axis to the top.
            expected_position = (xmin + res_x / 2 * px_size_x,
                                 ymax - res_x / 2 * px_size_y)  # [m]
            actual_position = task.get_abs_stage_movement()  # [m]
            numpy.testing.assert_allclose(actual_position, expected_position)

            # Verify that compared to the bottom right corner of the ROA, the stage
            # position is located half a field to the top left.
            task.field_idx = (x_fields - 1, y_fields - 1)  # index of the last field

            # In the role='stage' coordinate system the x-axis points to the right and y-axis to the top.
            expected_position = (xmax - res_x / 2 * px_size_x,
                                 ymin + res_x / 2 * px_size_y)  # [m]
            actual_position = task.get_abs_stage_movement()  # [m]
            numpy.testing.assert_allclose(actual_position, expected_position)

            # Verify that compared to the top right corner of the ROA, the stage
            # position is located half a field to the bottom left.
            task.field_idx = (x_fields - 1, 0)  # index of the last field in x and first field in y
            expected_position = (xmax - res_x / 2 * px_size_x,
                                 ymax - res_x / 2 * px_size_y)  # [m]
            actual_position = task.get_abs_stage_movement()  # [m]
            numpy.testing.assert_allclose(actual_position, expected_position)

            # Verify that compared to the bottom left corner of the ROA, the stage
            # position is located half a field to the top right.
            task.field_idx = (0, y_fields - 1)  # index of the first field in x and the last field in y

            # In the role='stage' coordinate system the x-axis points to the right and y-axis to the top.
            expected_position = (xmin + res_x / 2 * px_size_x,
                                 ymin + res_x / 2 * px_size_y)  # [m]
            actual_position = task.get_abs_stage_movement()  # [m]
            numpy.testing.assert_allclose(actual_position, expected_position)
예제 #5
0
    def test_get_abs_stage_movement(self):
        """
        Test the correct stage positions are returned for the corner fields of
        ROAs consisting of a varying number of single fields.
        """
        res_x, res_y = self.multibeam.resolution.value  # single field size
        px_size_x, px_size_y = self.multibeam.pixelSize.value

        # Loop over different ROA sizes by varying the number of fields in x and y.
        for x_fields, y_fields in zip((1, 2, 40, 34, 5), (1, 22, 43, 104, 25)):
            # The coordinates of the ROA in meters.
            xmin, ymin, xmax, ymax = (0, 0, res_x * px_size_x * x_fields, res_y * px_size_y * y_fields)
            coordinates = (xmin, ymin, xmax, ymax)  # in m

            # Create an ROA with the coordinates of the field.
            roa_name = time.strftime("test_megafield_id-%Y-%m-%d-%H-%M-%S")
            roa = fastem.FastEMROA(roa_name, coordinates, None, None,
                                   self.asm, self.multibeam, self.descanner,
                                   self.mppc)

            task = fastem.AcquisitionTask(self.scanner, self.multibeam, self.descanner,
                                          self.mppc, self.stage, self.ccd,
                                          self.beamshift, self.lens,
                                          roa, path=None, pre_calibrations=None, future=None)

            # Set the _pos_first_tile, which would normally be set in the run function.
            task._pos_first_tile = task.get_pos_first_tile()

            # Verify that compared to the top left corner of the ROA, the stage
            # position is located half a field to the bottom right.
            task.field_idx = (0, 0)  # (0, 0) is the index of the first field

            # In the role='stage' coordinate system the x-axis points to the right and y-axis to the top.
            expected_position = (xmin + res_x / 2 * px_size_x,
                                 ymax - res_x / 2 * px_size_y)  # [m]
            actual_position = task.get_abs_stage_movement()  # [m]
            actual_position_first_tile = task.get_pos_first_tile()  # [m]
            numpy.testing.assert_allclose(actual_position, expected_position)
            numpy.testing.assert_allclose(actual_position, actual_position_first_tile)

            # Verify that compared to the bottom right corner of the ROA, the stage
            # position is located half a field to the top left.
            task.field_idx = (x_fields - 1, y_fields - 1)  # index of the last field

            # In the role='stage' coordinate system the x-axis points to the right and y-axis to the top.
            expected_position = (xmax - res_x / 2 * px_size_x,
                                 ymin + res_x / 2 * px_size_y)  # [m]
            actual_position = task.get_abs_stage_movement()  # [m]
            numpy.testing.assert_allclose(actual_position, expected_position)

            # Verify that compared to the top right corner of the ROA, the stage
            # position is located half a field to the bottom left.
            task.field_idx = (x_fields - 1, 0)  # index of the last field in x and first field in y
            expected_position = (xmax - res_x / 2 * px_size_x,
                                 ymax - res_x / 2 * px_size_y)  # [m]
            actual_position = task.get_abs_stage_movement()  # [m]
            numpy.testing.assert_allclose(actual_position, expected_position)

            # Verify that compared to the bottom left corner of the ROA, the stage
            # position is located half a field to the top right.
            task.field_idx = (0, y_fields - 1)  # index of the first field in x and the last field in y

            # In the role='stage' coordinate system the x-axis points to the right and y-axis to the top.
            expected_position = (xmin + res_x / 2 * px_size_x,
                                 ymin + res_x / 2 * px_size_y)  # [m]
            actual_position = task.get_abs_stage_movement()  # [m]
            numpy.testing.assert_allclose(actual_position, expected_position)