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