def test_metadata(self): """ Check if extra metadata are saved """ settings_obs = SettingsObserver(model.getComponents()) detvas = {"binning", "exposureTime"} sems = stream.SEMStream("test sem", self.sed, self.sed.data, self.ebeam) specs = stream.SpectrumSettingsStream("test spec", self.spec, self.spec.data, self.ebeam, detvas=detvas) sps = stream.SEMSpectrumMDStream("test sem-spec", [sems, specs]) specs.roi.value = (0, 0, 1, 1) specs.repetition.value = (2, 3) specs.detBinning.value = (2, specs.detBinning.value[1]) specs.detExposureTime.value = 0.1 specs2 = stream.SpectrumSettingsStream("test spec2", self.spec, self.spec.data, self.ebeam, detvas=detvas) sps2 = stream.SEMSpectrumMDStream("test sem-spec2", [sems, specs2]) specs2.roi.value = (0, 0, 1, 1) specs2.repetition.value = (2, 3) specs2.detBinning.value = (4, specs2.detBinning.value[1]) specs2.detExposureTime.value = 0.05 f = acqmng.acquire([sps, sps2], settings_obs) data = f.result() spec1_data = data[0][1] spec2_data = data[0][3] self.assertEqual( spec1_data.metadata[model.MD_EXTRA_SETTINGS][self.spec.name] ['binning'], [(2, specs.detBinning.value[1]), 'px']) self.assertEqual( spec2_data.metadata[model.MD_EXTRA_SETTINGS][self.spec.name] ['binning'], [(4, specs2.detBinning.value[1]), 'px']) self.assertEqual( spec1_data.metadata[model.MD_EXTRA_SETTINGS][self.spec.name] ['exposureTime'], [0.1, 's']) self.assertEqual( spec2_data.metadata[model.MD_EXTRA_SETTINGS][self.spec.name] ['exposureTime'], [0.05, 's'])
def test_guess_mode(self): # test guess mode for ar sems = stream.SEMStream("test sem", self.sed, self.sed.data, self.ebeam) ars = stream.ARSettingsStream("test ar", self.ccd, self.ccd.data, self.ebeam) sas = stream.SEMARMDStream("test sem-ar", sems, ars) guess = self.optmngr.guessMode(ars) self.assertEqual(guess, "ar") guess = self.optmngr.guessMode(sas) self.assertEqual(guess, "ar") # test guess mode for spectral-dedicated sems = stream.SEMStream("test sem", self.sed, self.sed.data, self.ebeam) specs = stream.SpectrumSettingsStream("test spec", self.spec, self.spec.data, self.ebeam) sps = stream.SEMSpectrumMDStream("test sem-spec", sems, specs) guess = self.optmngr.guessMode(specs) self.assertIn(guess, ("spectral", "spectral-dedicated")) guess = self.optmngr.guessMode(sps) self.assertIn(guess, ("spectral", "spectral-dedicated"))
def test_guess_mode(self): # test guess mode for ar sems = stream.SEMStream("test sem", self.sed, self.sed.data, self.ebeam) ars = stream.ARSettingsStream("test ar", self.ccd, self.ccd.data, self.ebeam) sas = stream.SEMARMDStream("test sem-ar", sems, ars) guess = self.optmngr.guessMode(ars) self.assertEqual(guess, "ar") guess = self.optmngr.guessMode(sas) self.assertEqual(guess, "ar") # test guess mode for spectral sems = stream.SEMStream("test sem", self.sed, self.sed.data, self.ebeam) specs = stream.SpectrumSettingsStream("test spec", self.spec, self.spec.data, self.ebeam) sps = stream.SEMSpectrumMDStream("test sem-spec", sems, specs) guess = self.optmngr.guessMode(specs) self.assertEqual(guess, "spectral") guess = self.optmngr.guessMode(sps) self.assertEqual(guess, "spectral") # test guess mode for cli sems = stream.SEMStream("test sem", self.sed, self.sed.data, self.ebeam) cls = stream.SpectrumSettingsStream("test cl", self.cld, self.cld.data, self.ebeam) sls = stream.SEMSpectrumMDStream("test sem-cl", sems, cls) guess = self.optmngr.guessMode(cls) self.assertEqual(guess, "cli") guess = self.optmngr.guessMode(sls) self.assertEqual(guess, "cli")
def test_guess_mode(self): # test guess mode for spectral sems = stream.SEMStream("test sem", self.sed, self.sed.data, self.ebeam) specs = stream.SpectrumSettingsStream("test spec", self.spec, self.spec.data, self.ebeam) sps = stream.SEMSpectrumMDStream("test sem-spec", sems, specs) guess = self.optmngr.guessMode(specs) self.assertEqual(guess, "spectral") guess = self.optmngr.guessMode(sps) self.assertEqual(guess, "spectral") with self.assertRaises(LookupError): guess = self.optmngr.guessMode(sems)
def test_set_path_stream(self): # test guess mode for ar sems = stream.SEMStream("test sem", self.sed, self.sed.data, self.ebeam) ars = stream.ARSettingsStream("test ar", self.ccd, self.ccd.data, self.ebeam) sas = stream.SEMARMDStream("test sem-ar", sems, ars) self.optmngr.setPath(ars).result() # Assert that actuator was moved according to mode given self.assert_pos_as_in_mode(self.lenswitch, "ar") self.assert_pos_as_in_mode(self.slit, "ar") self.assert_pos_as_in_mode(self.specgraph, "ar") self.assertEqual(self.spec_det_sel.position.value, {'rx': 0}) self.assertAlmostEqual(self.spec_sel.position.value["x"], 0.022) # Change positions back self.optmngr.setPath("mirror-align").result() self.optmngr.setPath(sas).result() # Assert that actuator was moved according to mode given self.assert_pos_as_in_mode(self.lenswitch, "ar") self.assert_pos_as_in_mode(self.slit, "ar") self.assert_pos_as_in_mode(self.specgraph, "ar") self.assertEqual(self.spec_det_sel.position.value, {'rx': 0}) self.assertAlmostEqual(self.spec_sel.position.value["x"], 0.022) # test guess mode for spectral-dedicated sems = stream.SEMStream("test sem", self.sed, self.sed.data, self.ebeam) specs = stream.SpectrumSettingsStream("test spec", self.spec, self.spec.data, self.ebeam) sps = stream.SEMSpectrumMDStream("test sem-spec", sems, specs) self.optmngr.setPath(specs).result() # Assert that actuator was moved according to mode given self.assert_pos_as_in_mode(self.lenswitch, "spectral") # No slit/spectrograph as they are not affecting the detector self.assertAlmostEqual(self.spec_sel.position.value["x"], 0.026112848) # Change positions back self.optmngr.setPath("chamber-view").result() self.optmngr.setPath(sps).result() # Assert that actuator was moved according to mode given self.assert_pos_as_in_mode(self.lenswitch, "spectral") self.assertAlmostEqual(self.spec_sel.position.value["x"], 0.026112848)
def test_sync_path_guess(self): """ try synchronized acquisition using the Optical Path Manager """ # Create the streams and streamTree opmngr = path.OpticalPathManager(self.microscope) semsur = stream.SEMStream("test sem", self.sed, self.sed.data, self.ebeam) sems = stream.SEMStream("test sem cl", self.sed, self.sed.data, self.ebeam) ars = stream.ARSettingsStream("test ar", self.ccd, self.ccd.data, self.ebeam, opm=opmngr) semars = stream.SEMARMDStream("test SEM/AR", [sems, ars]) specs = stream.SpectrumSettingsStream("test spec", self.spec, self.spec.data, self.ebeam, opm=opmngr) sps = stream.SEMSpectrumMDStream("test sem-spec", [sems, specs]) st = stream.StreamTree(streams=[semsur, semars, sps]) # SEM survey settings are via the current hardware settings self.ebeam.dwellTime.value = self.ebeam.dwellTime.range[0] # SEM/AR/SPEC settings are via the AR stream ars.roi.value = (0.1, 0.1, 0.8, 0.8) specs.roi.value = (0.2, 0.2, 0.7, 0.7) mx_brng = self.ccd.binning.range[1] binning = tuple(min(4, mx) for mx in mx_brng) # try binning 4x4 self.ccd.binning.value = binning self.ccd.exposureTime.value = 1 # s ars.repetition.value = (2, 3) specs.repetition.value = (3, 2) num_ar = numpy.prod(ars.repetition.value) est_time = acq.estimateTime(st.getProjections()) # prepare callbacks self.start = None self.end = None self.updates = 0 self.done = 0 # Run acquisition start = time.time() f = acq.acquire(st.getProjections()) f.add_update_callback(self.on_progress_update) f.add_done_callback(self.on_done) data, e = f.result() dur = time.time() - start self.assertGreaterEqual(dur, est_time / 2) # Estimated time shouldn't be too small self.assertIsInstance(data[0], model.DataArray) self.assertIsNone(e) self.assertEqual(len(data), num_ar + 4) thumb = acq.computeThumbnail(st, f) self.assertIsInstance(thumb, model.DataArray) self.assertGreaterEqual(self.updates, 1) # at least one update at end self.assertLessEqual(self.end, time.time()) self.assertTrue(not f.cancelled()) # assert optical path configuration exp_pos = path.SPARC_MODES["spectral"][1] self.assertEqual(self.lenswitch.position.value, exp_pos["lens-switch"]) self.assertEqual(self.spec_det_sel.position.value, exp_pos["spec-det-selector"]) self.assertEqual(self.ar_spec_sel.position.value, exp_pos["ar-spec-selector"]) time.sleep(0.1) self.assertEqual(self.done, 1)
def test_roi_rep_pxs_links(self): """ Test the connections between .roi, .pixelSize and .repetition of a SpectrumStream. """ ebeam = FakeEBeam("ebeam") ss = stream.SpectrumSettingsStream("test spec", None, None, ebeam) # if roi is UNDEFINED, everything is left unchanged ss.roi.value = stream.UNDEFINED_ROI ss.pixelSize.value = 1e-8 self.assertEqual(ss.pixelSize.value, 1e-8) ss.repetition.value = (100, 100) self.assertEqual(ss.repetition.value, (100, 100)) self.assertEqual(ss.roi.value, stream.UNDEFINED_ROI) # in any cases, a pixel is always square self._check_square_pixel(ss) # for any value set in ROI, the new ROI value respects: # ROI = pixelSize * repetition / phy_size # ROI < (0,0,1,1) rois = [(0, 0, 1, 1), (0.1, 0.1, 0.8, 0.8), (0.00001, 0.1, 1, 0.2)] epxs = ebeam.pixelSize.value eshape = ebeam.shape phy_size = [epxs[0] * eshape[0], epxs[1] * eshape[1]] # max physical ROI for roi in rois: ss.roi.value = roi new_roi = ss.roi.value rep = ss.repetition.value pxs = ss.pixelSize.value exp_roi_size = [ rep[0] * pxs / phy_size[0], rep[1] * pxs / phy_size[1] ] roi_size = [new_roi[2] - new_roi[0], new_roi[3] - new_roi[1]] self.assertTupleAlmostEqual(roi_size, exp_roi_size, msg="with roi = %s => %s" % (roi, new_roi)) self.assertTrue( new_roi[0] >= 0 and new_roi[1] >= 0 and new_roi[2] <= 1 and new_roi[3] <= 1, "with roi = %s => %s" % (roi, new_roi)) self._check_square_pixel(ss) ss.pixelSize.value = ss.pixelSize.range[ 0] # needed to get the finest grain ss.roi.value = (0.3, 0.65, 0.5, 0.9) # changing one repetition dimension is always respected. rep = list(ss.repetition.value) rep[0] //= 2 ss.repetition.value = rep self.assertEqual(ss.repetition.value[0], rep[0]) self._check_square_pixel(ss) rep = list(ss.repetition.value) rep[1] //= 2 ss.repetition.value = rep self.assertEqual(ss.repetition.value[1], rep[1]) self._check_square_pixel(ss) # Changing 2 repetition dimensions at once respects at least one rep = [rep[0] * 2, int(round(rep[1] * 1.4))] ss.repetition.value = rep new_rep = list(ss.repetition.value) self.assertTrue(rep[0] == new_rep[0] or rep[1] == new_rep[1]) self._check_square_pixel(ss) # 1x1 repetition leads to a square ROI ss.repetition.value = (1, 1) new_roi = ss.roi.value roi_size = [new_roi[2] - new_roi[0], new_roi[3] - new_roi[1]] self.assertAlmostEqual(roi_size[0], roi_size[1]) self._check_square_pixel(ss) ss.pixelSize.value = ss.pixelSize.range[0] ss.roi.value = (0, 0, 1, 1) # Changing pixel size to the minimum leads to the smallest pixel size ss.pixelSize.value = ss.pixelSize.range[0] self.assertAlmostEqual(ss.pixelSize.value, max(ebeam.pixelSize.value)) self.assertEqual(tuple(ss.repetition.value), ebeam.shape) self._check_square_pixel(ss) # TODO: changing pixel size to a huge number leads to a 1x1 repetition # When changing both repetition dims, they are both respected ss.pixelSize.value = ss.pixelSize.range[0] ss.roi.value = (0.3, 0.65, 0.5, 0.6) ss.repetition.value = (3, 5) new_rep = (5, 6) ss.repetition.value = new_rep self.assertAlmostEqual(new_rep, ss.repetition.value) self._check_square_pixel(ss) # Changing the SEM magnification updates the pixel size (iff the # magnification cannot be automatically linked to the actual SEM # magnification). old_rep = ss.repetition.value old_roi = ss.roi.value old_pxs = ss.pixelSize.value old_mag = ebeam.magnification.value ebeam.magnification.value = old_mag * 2 new_pxs = ss.pixelSize.value new_mag = ebeam.magnification.value mag_ratio = new_mag / old_mag pxs_ratio = new_pxs / old_pxs self.assertAlmostEqual(mag_ratio, 1 / pxs_ratio) self.assertEqual(old_rep, ss.repetition.value) self.assertEqual(old_roi, ss.roi.value) self._check_square_pixel(ss)
def test_set_path_stream(self): sems = stream.SEMStream("test sem", self.sed, self.sed.data, self.ebeam) ars = stream.ARSettingsStream("test ar", self.ccd, self.ccd.data, self.ebeam) sas = stream.SEMARMDStream("test sem-ar", sems, ars) self.optmngr.setPath(ars).result() # Assert that actuator was moved according to mode given self.assert_pos_as_in_mode(self.lenswitch, "ar") self.assert_pos_as_in_mode(self.slit, "ar") self.assert_pos_as_in_mode(self.specgraph, "ar") self.assertEqual(self.spec_det_sel.position.value, {'rx': 0}) # Change positions back self.optmngr.setPath("mirror-align").result() self.optmngr.setPath(sas).result() # Assert that actuator was moved according to mode given self.assert_pos_as_in_mode(self.lenswitch, "ar") self.assert_pos_as_in_mode(self.slit, "ar") self.assert_pos_as_in_mode(self.specgraph, "ar") self.assertEqual(self.spec_det_sel.position.value, {'rx': 0}) sems = stream.SEMStream("test sem", self.sed, self.sed.data, self.ebeam) specs = stream.SpectrumSettingsStream("test spec", self.spec, self.spec.data, self.ebeam) sps = stream.SEMSpectrumMDStream("test sem-spec", sems, specs) self.optmngr.setPath(specs).result() # Assert that actuator was moved according to mode given self.assertEqual(self.spec_det_sel.position.value, {'rx': 1.5707963267948966}) self.assertEqual(self.cl_det_sel.position.value, {'x': 0.01}) # Change positions back self.optmngr.setPath("chamber-view").result() self.optmngr.setPath(sps).result() # Assert that actuator was moved according to mode given self.assert_pos_as_in_mode(self.lenswitch, "spectral") self.assert_pos_as_in_mode(self.slit, "spectral") self.assert_pos_as_in_mode(self.specgraph, "spectral") self.assertEqual(self.spec_det_sel.position.value, {'rx': 1.5707963267948966}) self.assertEqual(self.cl_det_sel.position.value, {'x': 0.01}) sems = stream.SEMStream("test sem", self.sed, self.sed.data, self.ebeam) specs = stream.SpectrumSettingsStream("test spec", self.spec_integrated, self.spec_integrated.data, self.ebeam) sps = stream.SEMSpectrumMDStream("test sem-spec", sems, specs) # Change positions back self.optmngr.setPath("chamber-view").result() self.optmngr.setPath(specs).result() # Assert that actuator was moved according to mode given self.assert_pos_as_in_mode(self.lenswitch, "spectral-integrated") self.assert_pos_as_in_mode(self.slit, "spectral-integrated") self.assert_pos_as_in_mode(self.specgraph, "spectral-integrated") self.assertEqual(self.spec_det_sel.position.value, {'rx': 0}) self.assertEqual(self.cl_det_sel.position.value, {'x': 0.01}) # Check the focus is remembered before going to chamber-view orig_focus = self.focus.position.value # Change positions back self.optmngr.setPath("chamber-view").result() self.focus.moveRel({"z": 1e-3}).result() self.optmngr.setPath(sps).result() # Assert that actuator was moved according to mode given self.assert_pos_as_in_mode(self.lenswitch, "spectral") self.assert_pos_as_in_mode(self.slit, "spectral") self.assert_pos_as_in_mode(self.specgraph, "spectral") self.assertEqual(self.spec_det_sel.position.value, {'rx': 0}) self.assertEqual(self.cl_det_sel.position.value, {'x': 0.01}) self.assertEqual(self.focus.position.value, orig_focus)