Beispiel #1
0
    def test_progress(self):
        """Check if some progress is reported during the optical autofocus calibration."""

        self.updates = 0  # updated in callback on_progress_update

        calibrations = [
            Calibrations.OPTICAL_AUTOFOCUS,
            Calibrations.IMAGE_TRANSLATION_PREALIGN
        ]
        f = fastem.align(self.scanner, self.multibeam, self.descanner,
                         self.mppc, self.stage, self.ccd, self.beamshift,
                         self.det_rotator, calibrations)

        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)

        config = f.result()

        self.assertIsNotNone(
            config)  # check configuration dictionary is returned
        self.assertTrue(self.done)
        # at least one update per calibration plus once at start of calibration, plus once at end of calibration
        self.assertGreaterEqual(self.updates, 4)
Beispiel #2
0
    def test_image_dark_gain(self):
        """Run the dark offset and digital gain calibration. Can also be tested with simulator.
        It calibrates the dark offset and digital gain per mppc detector cell."""

        calibrations = [Calibrations.DARK_OFFSET, Calibrations.DIGITAL_GAIN]

        # set current cell dark offset and cell digital gain
        # (also for simulator the calibration will find values different from 0 and 1)
        self.mppc.cellDarkOffset.value = \
            tuple(tuple(0 for _ in range(0, self.mppc.shape[0])) for i in range(0, self.mppc.shape[1]))
        self.mppc.cellDigitalGain.value = \
            tuple(tuple(1 for _ in range(0, self.mppc.shape[0])) for i in range(0, self.mppc.shape[1]))

        dark_offset_cur = self.mppc.cellDarkOffset.value
        digital_gain_cur = self.mppc.cellDigitalGain.value

        # Run the calibrations
        f = fastem.align(self.scanner, self.multibeam, self.descanner,
                         self.mppc, self.stage, self.ccd, self.beamshift,
                         self.det_rotator, calibrations)

        config = f.result(timeout=900)

        self.assertIsNotNone(
            config)  # check configuration dictionary is returned

        # get the calibrated dark offset and digital gain from the configuration
        dark_offset_calib = config["mppc"]["cellDarkOffset"]
        digital_gain_calib = config["mppc"]["cellDigitalGain"]

        # check the calibrated values are different from the previous values
        self.assertNotEqual(dark_offset_cur, dark_offset_calib)
        self.assertNotEqual(digital_gain_cur, digital_gain_calib)
Beispiel #3
0
    def test_cancel(self):
        """Test if it is possible to cancel the optical autofocus calibration."""

        # FIXME no subfuture available yet, which are cancelable
        #  when subfutures are implemented, add a check in this test case that the subfuture was also cancelled

        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

        calibrations = [
            Calibrations.OPTICAL_AUTOFOCUS,
            Calibrations.IMAGE_TRANSLATION_PREALIGN
        ]
        f = fastem.align(self.scanner, self.multibeam, self.descanner,
                         self.mppc, self.stage, self.ccd, self.beamshift,
                         self.det_rotator, calibrations)

        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()

        with self.assertRaises(CancelledError):
            f.result(
                timeout=5
            )  # add timeout = 5s in case cancellation error was not raised
        self.assertGreaterEqual(self.updates,
                                2)  # at least one update at cancellation
        self.assertLessEqual(self.end, time.time())
        self.assertTrue(self.done)
        self.assertTrue(f.cancelled())
Beispiel #4
0
    def test_optical_autofocus(self):
        """Run the optical autofocus calibration. Can also be tested with simulator."""

        calibrations = [Calibrations.OPTICAL_AUTOFOCUS]

        # move the stage so that the image is out of focus
        center_position = -30e-6
        self.stage.moveAbs({"z": center_position}).result()

        # Run auto focus
        f = fastem.align(self.scanner, self.multibeam, self.descanner,
                         self.mppc, self.stage, self.ccd, self.beamshift,
                         self.det_rotator, calibrations)

        config = f.result(timeout=900)

        self.assertIsNotNone(
            config)  # check configuration dictionary is returned
        # check that z stage position is close to good position
        # Note: This accuracy is dependent on the value chosen for the magnification on the lens.
        numpy.testing.assert_allclose(self.stage.position.value["z"],
                                      self.good_focus,
                                      atol=2e-6)
Beispiel #5
0
    def pre_calibrate(self, pre_calibrations):
        """
        Run optical multiprobe autofocus and image translation pre-alignment before the ROA acquisition.
        The image translation pre-alignment adjusts the descanner.scanOffset VA such that the image of the
        multiprobe is roughly centered on the mppc detector. This function reads in the ASM configuration
        and makes sure all values, except the descanner offset, are set back after the calibrations are run.
        The calibration is run at the stage position as indicated on the .field_indices attribute.

        NOTE: Canceling is currently not supported.

        :param pre_calibrations: (list[Calibrations]) List of calibrations that should be run before the ROA
                                 acquisition.
        """
        if not fastem_calibrations:
            raise ModuleNotFoundError(
                "Need fastem_calibrations repository to run pre-calibrations.")

        logging.debug("Start pre-calibration.")

        stage_pos = self.get_abs_stage_movement()

        f = align(
            self._scanner,
            self._multibeam,
            self._descanner,
            self._detector,
            self._stage,
            self._ccd,
            self._beamshift,
            None,  # no need for the detector rotator
            calibrations=pre_calibrations,
            stage_pos=stage_pos)

        f.result()  # wait for the calibrations to be finished

        logging.debug("Finish pre-calibration.")
Beispiel #6
0
    def test_image_translation_prealign(self):
        """Run the image translation prealing calibration. Can also be tested with simulator.
        It calibrates the descanner offset."""

        calibrations = [Calibrations.IMAGE_TRANSLATION_PREALIGN]

        # get current descanner offset
        descan_offset_cur = self.descanner.scanOffset.value

        # Run image translation pre-align
        f = fastem.align(self.scanner, self.multibeam, self.descanner,
                         self.mppc, self.stage, self.ccd, self.beamshift,
                         self.det_rotator, calibrations)

        config = f.result(timeout=900)

        self.assertIsNotNone(
            config)  # check configuration dictionary is returned

        # get the calibrated descanner offset
        descan_offset_calib = self.descanner.scanOffset.value

        # check the calibrated descan offset is different from the previous offset
        self.assertNotEqual(descan_offset_cur, descan_offset_calib)