Example #1
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
Example #2
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)
Example #3
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)
Example #4
0
    def on_acquisition(self, evt):
        """
        Start the acquisition (really)
        """
        self._main_data_model.is_acquiring.value = True
        self.btn_acquire.Enable(False)
        self.btn_cancel.Enable(True)
        self.btn_cancel.Show()
        self.gauge_acq.Show()
        self._show_status_icons(None)

        self.gauge_acq.Range = self.roa_count
        self.gauge_acq.Value = 0

        # Acquire ROAs for all projects
        fs = {}
        for p in self._tab_data_model.projects.value:
            ppath = os.path.join(self.path, p.name.value)  # <acquisition date>/<project name>
            for roa in p.roas.value:
                f = fastem.acquire(roa, ppath, self._main_data_model.ebeam, self._main_data_model.multibeam,
                                   self._main_data_model.descanner, self._main_data_model.mppc,
                                   self._main_data_model.stage, self._main_data_model.ccd,
                                   self._main_data_model.beamshift, self._main_data_model.lens)
                t = roa.estimate_acquisition_time()
                fs[f] = t

        self.acq_future = model.ProgressiveBatchFuture(fs)
        self._fs_connector = ProgressiveFutureConnector(self.acq_future, self.gauge_acq, self.lbl_acqestimate)
        self.acq_future.add_done_callback(self.on_acquisition_done)
Example #5
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)
Example #6
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)
Example #7
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())