Esempio n. 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)
Esempio n. 2
0
    def test_progress_ROA(self):
        """Check if some progress is reported between the field images acquired for the ROA (megafield)."""
        x_fields = 2
        y_fields = 3
        res_x, res_y = self.multibeam.resolution.value  # single field size
        px_size_x, px_size_y = self.multibeam.pixelSize.value
        coordinates = (0, 0, res_x * px_size_x * x_fields, res_y * px_size_y * y_fields)  # in m
        roc_2 = fastem.FastEMROC("roc_2", coordinates)
        roc_3 = fastem.FastEMROC("roc_3", coordinates)
        roa_name = time.strftime("test_megafield_id-%Y-%m-%d-%H-%M-%S")
        roa = fastem.FastEMROA(roa_name,
                               coordinates,
                               roc_2,
                               roc_3,
                               self.asm,
                               self.multibeam,
                               self.descanner,
                               self.mppc)

        path_storage = os.path.join(datetime.today().strftime('%Y-%m-%d'), "test_project_progress")

        self.updates = 0  # updated in callback on_progress_update

        f = fastem.acquire(roa, path_storage, self.scanner, self.multibeam, self.descanner, self.mppc, self.stage,
                           self.ccd, self.beamshift, self.lens)
        f.add_update_callback(self.on_progress_update)  # callback executed every time f.set_progress is called
        f.add_done_callback(self.on_done)  # callback executed when f.set_result is called (via bindFuture)

        data, e = f.result()

        self.assertIsNone(e)  # check no exceptions were returned
        self.assertIsInstance(data[(0, 0)], model.DataArray)
        self.assertTrue(self.done)
        self.assertGreaterEqual(self.updates, 6)  # at least one update per field
Esempio n. 3
0
    def test_calculate_field_indices_overlap_small_roa(self):
        """Check that the correct number of field indices are calculated for ROA's that are smaller than the overlap."""
        res_x, res_y = self.multibeam.resolution.value  # single field size
        px_size_x, px_size_y = self.multibeam.pixelSize.value
        overlap = 0.2

        roa_name = time.strftime("test_megafield_id-%Y-%m-%d-%H-%M-%S")

        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)
        # Create xmax and ymax such that they are smaller than the field_size * overlap.
        xmax, ymax = (0.8 * field_size_x * overlap,
                      0.8 * field_size_y * overlap)
        coordinates = (xmin, ymin, xmax, ymax)  # in m
        roa = fastem.FastEMROA(roa_name,
                               coordinates,
                               None,
                               None,
                               self.asm,
                               self.multibeam,
                               self.descanner,
                               self.mppc,
                               overlap)

        # For very small ROA's we expect at least a single field.
        expected_indices = [(0, 0)]  # (col, row)
        field_indices = roa._calculate_field_indices()
        self.assertListEqual(field_indices, expected_indices)
Esempio n. 4
0
    def test_coverage_ROA(self):
        """Acquire a megafield (ROA), which does not match an integer multiple of fields.
        Check that the acquired ROA exceeds the requested ROA."""
        x_fields = 3
        y_fields = 4
        self.multibeam.resolution.value = (6400, 6400)  # don't change
        res_x, res_y = self.multibeam.resolution.value  # single field size
        px_size_x, px_size_y = self.multibeam.pixelSize.value
        # some extra pixels (< 1 field) to be added to the ROA
        x_margin, y_margin = (res_x / 10, res_y / 20)
        coordinates = (0, 0,
                       res_x * px_size_x * x_fields + x_margin * px_size_x,
                       res_y * px_size_y * y_fields + y_margin * px_size_y)  # in m
        roc_2 = fastem.FastEMROC("roc_2", coordinates)
        roc_3 = fastem.FastEMROC("roc_3", coordinates)
        roa_name = time.strftime("test_megafield_id-%Y-%m-%d-%H-%M-%S")
        roa = fastem.FastEMROA(roa_name,
                               coordinates,
                               roc_2,
                               roc_3,
                               self.asm,
                               self.multibeam,
                               self.descanner,
                               self.mppc)

        path_storage = os.path.join(datetime.today().strftime('%Y-%m-%d'), "test_project_field_indices")
        f = fastem.acquire(roa, path_storage, self.scanner, self.multibeam, self.descanner, self.mppc, self.stage,
                           self.ccd, self.beamshift, self.lens)
        data, e = f.result()

        self.assertIsNone(e)  # check no exceptions were returned
        # check data returned contains the correct number of field images
        # expect plus 1 field in x and y respectively
        self.assertEqual(len(data), (x_fields + 1) * (y_fields + 1))
        self.assertIsInstance(data[(0, 0)], model.DataArray)
Esempio n. 5
0
    def test_calculate_field_indices(self):
        """Check that the correct number and order of field indices is returned and that row and column are in the
        correct order."""
        x_fields = 3
        y_fields = 2
        self.multibeam.resolution.value = (6400, 6400)  # don't change
        res_x, res_y = self.multibeam.resolution.value  # single field size
        px_size_x, px_size_y = self.multibeam.pixelSize.value
        coordinates = (0, 0, res_x * px_size_x * x_fields, res_y * px_size_y * y_fields)  # in m, don't change
        roc_2 = fastem.FastEMROC("roc_2", coordinates)
        roc_3 = fastem.FastEMROC("roc_3", coordinates)
        roa_name = time.strftime("test_megafield_id-%Y-%m-%d-%H-%M-%S")
        roa = fastem.FastEMROA(roa_name,
                               coordinates,
                               roc_2,
                               roc_3,
                               self.asm,
                               self.multibeam,
                               self.descanner,
                               self.mppc)

        expected_indices = [(0, 0), (1, 0), (2, 0), (0, 1), (1, 1), (2, 1)]  # (col, row)

        field_indices = roa._calculate_field_indices()

        self.assertListEqual(expected_indices, field_indices)
Esempio n. 6
0
    def test_acquire_ROA(self):
        """Acquire a small mega field image with ROA matching integer multiple of single field size."""
        x_fields = 2
        y_fields = 3
        self.multibeam.resolution.value = (6400, 6400)  # don't change
        res_x, res_y = self.multibeam.resolution.value  # single field size
        px_size_x, px_size_y = self.multibeam.pixelSize.value
        # Note: Do not change those values; _calculate_field_indices handles floating point errors the same way
        # as an ROA that does not match an integer number of field indices by just adding an additional row or column
        # of field images.
        top = -0.002  # top corner coordinate of ROA in stage coordinates in meter
        left = +0.001  # left corner coordinate of ROA in stage coordinates in meter
        coordinates = (top, left, top + res_x * px_size_x * x_fields,
                       left + res_y * px_size_y * y_fields)  # in m
        roc = fastem.FastEMROC("roc_name", coordinates)
        roa_name = time.strftime("test_megafield_id-%Y-%m-%d-%H-%M-%S")
        roa = fastem.FastEMROA(roa_name, coordinates, roc, self.asm,
                               self.multibeam, self.descanner, self.mppc)
        path_storage = os.path.join(datetime.today().strftime('%Y-%m-%d'),
                                    "test_project_megafield")
        f = fastem.acquire(roa, path_storage, self.scanner, self.multibeam,
                           self.descanner, self.mppc, self.stage, self.ccd,
                           self.beamshift, self.lens)
        data, e = f.result()

        self.assertIsNone(e)  # check no exceptions were returned
        # check data returned contains the correct number of field images
        self.assertEqual(len(data), x_fields * y_fields)
        self.assertIsInstance(data[(0, 0)], model.DataArray)
Esempio n. 7
0
    def test_estimate_acquisition_time(self):
        """Check that the estimated time for one ROA (megafield) is calculated correctly."""
        # Use float for number of fields, in order to not end up with additional fields scanned and thus an
        # incorrectly estimated roa acquisition time.
        x_fields = 2.9
        y_fields = 3.2
        res_x, res_y = self.multibeam.resolution.value  # single field size
        px_size_x, px_size_y = self.multibeam.pixelSize.value
        coordinates = (0, 0, res_x * px_size_x * x_fields,
                       res_y * px_size_y * y_fields)  # in m
        roc = fastem.FastEMROC("roc_name", coordinates)
        roa_name = time.strftime("test_megafield_id-%Y-%m-%d-%H-%M-%S")
        roa = fastem.FastEMROA(roa_name, coordinates, roc, self.asm,
                               self.multibeam, self.descanner, self.mppc)
        cell_res = self.mppc.cellCompleteResolution.value
        dwell_time = self.multibeam.dwellTime.value
        flyback = self.descanner.physicalFlybackTime.value  # extra time per line scan

        # calculate expected roa (megafield) acquisition time
        # (number of pixels per line * dwell time + flyback time) * number of lines * number of cells in x and y
        estimated_roa_acq_time = (cell_res[0] * dwell_time + flyback) * cell_res[1] \
                                 * math.ceil(x_fields) * math.ceil(y_fields)
        # get roa acquisition time
        roa_acq_time = roa.estimate_acquisition_time()

        self.assertAlmostEqual(estimated_roa_acq_time, roa_acq_time)
Esempio n. 8
0
    def test_stage_movement(self):
        """Test that the stage move corresponds to one field image (excluding over-scanned pixels)."""
        x_fields = 2
        y_fields = 3
        res_x, res_y = self.multibeam.resolution.value  # single field size
        px_size_x, px_size_y = self.multibeam.pixelSize.value

        # FIXME: This test does not consider yet, that ROA coordinates need to be transformed into the
        #  correct coordinate system. Replace role='stage' with role='stage-scan' when function available.
        # Note: Do not change those values; _calculate_field_indices handles floating point errors the same way
        # as an ROA that does not match an integer number of field indices by just adding an additional row or column
        # of field images.
        xmin = -0.002  # top corner coordinate of ROA in stage coordinates in meter
        ymin = +0.001  # left corner coordinate of ROA in stage coordinates in meter
        xmax = xmin + res_x * px_size_x * x_fields
        ymax = ymin + res_y * px_size_y * y_fields
        coordinates = (xmin, ymin, xmax, ymax)  # in m
        roc_2 = fastem.FastEMROC("roc_2", coordinates)
        roc_3 = fastem.FastEMROC("roc_3", coordinates)
        roa_name = time.strftime("test_megafield_id-%Y-%m-%d-%H-%M-%S")
        roa = fastem.FastEMROA(roa_name,
                               coordinates,
                               roc_2,
                               roc_3,
                               self.asm,
                               self.multibeam,
                               self.descanner,
                               self.mppc)

        path_storage = os.path.join(datetime.today().strftime('%Y-%m-%d'), "test_project_stage_move")

        f = fastem.acquire(roa, path_storage, self.scanner, self.multibeam, self.descanner, self.mppc, self.stage,
                           self.ccd, self.beamshift, self.lens)
        data, e = f.result()

        self.assertIsNone(e)  # check no exceptions were returned

        # total expected stage movement in x and y during the acquisition
        # half a field to start at center of first field image
        exp_move_x = res_x / 2. * px_size_x + res_x * px_size_x * (x_fields - 1)
        exp_move_y = res_y / 2. * px_size_y + res_y * px_size_y * (y_fields - 1)

        # FIXME Needs to be updated when role="stage" is replaced with role="stage-scan"
        # In role="stage" coordinate system:
        # Move in the positive x direction, because the second field should be right of the first.
        # Move in the negative y direction, because the second field should be below the first.
        exp_position = (xmin + exp_move_x, ymax - exp_move_y)
        # get the last stage position (it is the center of the last field)
        cur_position = (self.stage.position.value['x'], self.stage.position.value['y'])

        # check stage position is matching expected position (Note: stage accuracy is ~ TODO fix decimal accordingly)
        numpy.testing.assert_almost_equal(exp_position, cur_position, decimal=6)
Esempio n. 9
0
    def test_stage_movement(self):
        """Test that the stage move corresponds to one field image (excluding over-scanned pixels)."""
        x_fields = 2
        y_fields = 3
        res_x, res_y = self.multibeam.resolution.value  # single field size
        px_size_x, px_size_y = self.multibeam.pixelSize.value

        # FIXME: It is not clear in which coordinate system the coordinates of the ROA are!!!
        # Note: the coordinates are in the stage coordinate system with role='stage' and not role='stage-scan'.
        # However, for fast em acquisitions we use stage-scan, which scans along the multiprobe axes.
        # FIXME: This test does not consider yet, that ROA coordinates need to be transformed into the
        #  correct coordinate system. Replace role='stage' with role='stage-scan' when function available.
        # Note: Do not change those values; _calculate_field_indices handles floating point errors the same way
        # as an ROA that does not match an integer number of field indices by just adding an additional row or column
        # of field images.
        top = -0.002  # top corner coordinate of ROA in stage coordinates in meter
        left = +0.001  # left corner coordinate of ROA in stage coordinates in meter
        coordinates = (top, left, top + res_x * px_size_x * x_fields,
                       left + res_y * px_size_y * y_fields)  # in m
        roc = fastem.FastEMROC("roc_name", coordinates)
        roa_name = time.strftime("test_megafield_id-%Y-%m-%d-%H-%M-%S")
        roa = fastem.FastEMROA(roa_name, coordinates, roc, self.asm,
                               self.multibeam, self.descanner, self.mppc)
        path_storage = os.path.join(datetime.today().strftime('%Y-%m-%d'),
                                    "test_project_stage_move")

        f = fastem.acquire(roa, path_storage, self.multibeam, self.descanner,
                           self.mppc, self.stage)
        data, e = f.result()

        self.assertIsNone(e)  # check no exceptions were returned

        # total expected stage movement in x and y during the acquisition
        # half a field to start at center of first field image
        exp_move_x = res_x / 2. * px_size_x + res_x * px_size_x * (x_fields -
                                                                   1)
        exp_move_y = res_y / 2. * px_size_y + res_y * px_size_y * (y_fields -
                                                                   1)

        # TODO these comments are true, when stage is replaced with stage-scan
        # Move in the negative x direction, because the second field should be right of the first.
        # Move in positive y direction, because the second field should be bottom of the first.
        exp_position = (top - exp_move_x, left + exp_move_y)
        # get the last stage position (it is the center of the last field)
        cur_position = (self.stage.position.value['x'],
                        self.stage.position.value['y'])

        # check stage position is matching expected position (Note: stage accuracy is ~ TODO fix decimal accordingly)
        numpy.testing.assert_almost_equal(exp_position,
                                          cur_position,
                                          decimal=6)
Esempio n. 10
0
    def test_estimate_acquisition_time(self):
        """Check that the estimated time for one ROA (megafield) is calculated correctly."""
        # Use float for number of fields, in order to not end up with additional fields scanned and thus an
        # incorrectly estimated roa acquisition time.
        x_fields = 2.9
        y_fields = 3.2
        n_fields = math.ceil(x_fields) * math.ceil(y_fields)
        res_x, res_y = self.multibeam.resolution.value  # single field size
        px_size_x, px_size_y = self.multibeam.pixelSize.value
        coordinates = (0, 0, res_x * px_size_x * x_fields, res_y * px_size_y * y_fields)  # in m
        roc_2 = fastem.FastEMROC("roc_2", coordinates)
        roc_3 = fastem.FastEMROC("roc_3", coordinates)
        roa_name = time.strftime("test_megafield_id-%Y-%m-%d-%H-%M-%S")

        for dwell_time in [400e-9, 1e-6, 10e-6]:
            self.multibeam.dwellTime.value = dwell_time
            roa = fastem.FastEMROA(roa_name,
                                   coordinates,
                                   roc_2,
                                   roc_3,
                                   self.asm,
                                   self.multibeam,
                                   self.descanner,
                                   self.mppc)

            cell_res = self.mppc.cellCompleteResolution.value
            flyback = self.descanner.physicalFlybackTime.value  # extra time per line scan

            # calculate expected roa (megafield) acquisition time
            # (number of pixels per line * dwell time + flyback time) * number of lines * number of cells in x and y
            estimated_line_time = cell_res[0] * dwell_time
            # Remainder of the line scan time, part which is not a whole multiple of the descan periods.
            remainder_scanning_time = estimated_line_time % self.descanner.clockPeriod.value
            if remainder_scanning_time is not 0:
                # Adjusted the flyback time if there is a remainder of scanning time by adding one setpoint to ensure
                # the line scan time is equal to a whole multiple of the descanner clock period
                flyback = flyback + (self.descanner.clockPeriod.value - remainder_scanning_time)

            # Round to prevent floating point errors
            estimated_line_time = numpy.round(estimated_line_time + flyback, 9)

            # The estimated ROA time is the line time multiplied with the cell resolution and the number of fields.
            # Additionally, 1.5s overhead per field image and the first field image is acquired twice.
            estimated_roa_acq_time = (estimated_line_time * cell_res[1] + 1.5) * (n_fields + 1)

            # get roa acquisition time
            roa_acq_time = estimate_acquisition_time(roa)

            self.assertAlmostEqual(estimated_roa_acq_time, roa_acq_time)
Esempio n. 11
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)
Esempio n. 12
0
    def test_calculate_field_indices_overlap(self):
        """Check that the correct number of field indices are calculated when there is overlap between the fields."""
        x_fields = 3
        y_fields = 2
        self.multibeam.resolution.value = (6400, 6400)  # don't change
        res_x, res_y = self.multibeam.resolution.value  # single field size
        px_size_x, px_size_y = self.multibeam.pixelSize.value

        roa_name = time.strftime("test_megafield_id-%Y-%m-%d-%H-%M-%S")

        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)
            # Calculate the ROA size for a well specified number of fields taking the specified overlap between fields
            # into account. As the fields of the last row and column do not have any neighbor to their right and bottom,
            # do take their full size into account.
            # An ROA with overlap can be visualized as follows:
            # |------|--⁞----|--⁞----|--⁞
            # where the left border of each field is drawn with a '|' and the right border of each field with a '⁞'.
            # There are 3 fields of 8 '-' and the overlap is 2, therefore the total size is 3 * (8-2) + 2
            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
            roa = fastem.FastEMROA(roa_name,
                                   coordinates,
                                   None,
                                   None,
                                   self.asm,
                                   self.multibeam,
                                   self.descanner,
                                   self.mppc,
                                   overlap)

            expected_indices = [(0, 0), (1, 0), (2, 0), (0, 1), (1, 1), (2, 1)]  # (col, row)
            field_indices = roa._calculate_field_indices()

            # Floating point errors can result in an extra field, which is fine.
            # Check that maximum 1 extra field index in x and 1 in y is calculated and that there are not fewer fields
            # calculated than expected.
            self.assertLessEqual(max(field_indices)[0] - max(expected_indices)[0], 1)
            self.assertGreaterEqual(max(field_indices)[0] - max(expected_indices)[0], 0)
            self.assertLessEqual(max(field_indices)[1] - max(expected_indices)[1], 1)
            self.assertGreaterEqual(max(field_indices)[1] - max(expected_indices)[1], 0)
Esempio n. 13
0
    def test_cancel_ROA(self):
        """Test if it is possible to cancel between field images acquired for one ROA."""
        x_fields = 2
        y_fields = 3
        res_x, res_y = self.multibeam.resolution.value  # single field size
        px_size_x, px_size_y = self.multibeam.pixelSize.value
        coordinates = (0, 0, res_x * px_size_x * x_fields,
                       res_y * px_size_y * y_fields)  # in m
        roc = fastem.FastEMROC("roc_name", coordinates)
        roa_name = time.strftime("test_megafield_id-%Y-%m-%d-%H-%M-%S")
        roa = fastem.FastEMROA(roa_name, coordinates, roc, self.asm,
                               self.multibeam, self.descanner, self.mppc)
        path_storage = os.path.join(datetime.today().strftime('%Y-%m-%d'),
                                    "test_project_cancel")

        self.end = None  # updated in callback on_progress_update
        self.updates = 0  # updated in callback on_progress_update
        self.done = False  # updated in callback on_done

        f = fastem.acquire(roa, path_storage, self.scanner, self.multibeam,
                           self.descanner, self.mppc, self.stage, self.ccd,
                           self.beamshift, self.lens)
        f.add_update_callback(
            self.on_progress_update
        )  # callback executed every time f.set_progress is called
        f.add_done_callback(
            self.on_done
        )  # callback executed when f.set_result is called (via bindFuture)

        time.sleep(1)  # make sure it's started
        self.assertTrue(f.running())
        f.cancel()

        self.assertRaises(
            CancelledError, f.result,
            1)  # add timeout = 1s in case cancellation error was not raised
        self.assertGreaterEqual(self.updates,
                                3)  # at least one update at cancellation
        self.assertLessEqual(self.end, time.time())
        self.assertTrue(self.done)
        self.assertTrue(f.cancelled())
Esempio n. 14
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))
Esempio n. 15
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)
Esempio n. 16
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)