def test_aligned_stream(self): """ Test the AlignedSEMStream """ # Use fake ccd in order to have just one spot ccd = mock.FakeCCD(self.fake_img) # first try using the metadata correction st = stream.AlignedSEMStream("sem-md", self.sed, self.sed.data, self.ebeam, ccd, self.stage, self.focus, shiftebeam=stream.MTD_MD_UPD) # we don't really care about the SEM image, so the faster the better self.ebeam.dwellTime.value = self.ebeam.dwellTime.range[0] # start one image acquisition (so it should do the calibration) f = acq.acquire([st]) received, _ = f.result() self.assertTrue(received, "No image received after 30 s") # Check the correction metadata is there md = self.sed.getMetadata() self.assertIn(model.MD_POS_COR, md) # Check the position of the image is correct pos_cor = md[model.MD_POS_COR] pos_dict = self.stage.position.value pos = (pos_dict["x"], pos_dict["y"]) exp_pos = tuple(p - c for p, c in zip(pos, pos_cor)) imd = received[0].metadata self.assertEqual(exp_pos, imd[model.MD_POS]) # Check the calibration doesn't happen again on a second acquisition bad_cor = (-1, -1) # stupid impossible value self.sed.updateMetadata({model.MD_POS_COR: bad_cor}) f = acq.acquire([st]) received, _ = f.result() self.assertTrue(received, "No image received after 10 s") # if calibration has happened (=bad), it has changed the metadata md = self.sed.getMetadata() self.assertEqual(bad_cor, md[model.MD_POS_COR], "metadata has been updated while it shouldn't have") # Check calibration happens again after a stage move f = self.stage.moveRel({"x": 100e-6}) f.result() # make sure the move is over time.sleep(0.1) # make sure the stream had time to detect position has changed f = acq.acquire([st]) received, _ = f.result() self.assertTrue(received, "No image received after 30 s") # if calibration has happened (=good), it has changed the metadata md = self.sed.getMetadata() self.assertNotEqual(bad_cor, md[model.MD_POS_COR], "metadata hasn't been updated while it should have") ccd.terminate()
def addSEMBSD(self, **kwargs): """ Creates a new backscattered electron stream and panel in the stream bar returns (StreamPanel): the panel created """ if self._main_data_model.role == "delphi": # For the Delphi, the SEM stream needs to be more "clever" because # it needs to run a simple spot alignment every time the stage has # moved before starting to acquire. s = acqstream.AlignedSEMStream("Backscattered electrons", self._main_data_model.bsd, self._main_data_model.bsd.data, self._main_data_model.ebeam, self._main_data_model.ccd, self._main_data_model.stage, shiftebeam="Ebeam shift") # Select between "Metadata update" and "Stage move" # TODO: use shiftebeam once the phenom driver supports it else: s = acqstream.SEMStream("Backscattered electrons", self._main_data_model.bsd, self._main_data_model.bsd.data, self._main_data_model.ebeam) return self._addStream(s, **kwargs)
def test_aligned_stream(self): """ Test the AlignedSEMStream """ # Use fake ccd in order to have just one spot ccd = self.FakeCCD(self, self.align) # first try using the metadata correction st = stream.AlignedSEMStream("sem-md", self.sed, self.sed.data, self.ebeam, ccd, self.stage, shiftebeam=False) # we don't really care about the SEM image, so the faster the better self.ebeam.dwellTime.value = self.ebeam.dwellTime.range[0] # start one image acquisition (so it should do the calibration) self.image_received = threading.Event() st.image.subscribe(self.on_image) st.should_update.value = True st.is_active.value = True # wait until the image is acquired, which can be a bit long if the # calibration is difficult => 30s received = self.image_received.wait(30) st.is_active.value = False st.image.unsubscribe(self.on_image) self.assertTrue(received, "No image received after 30 s") # Check the correction metadata is there md = self.sed.getMetadata() self.assertIn(model.MD_POS_COR, md) md = st.raw[0].metadata self.assertIn(model.MD_POS_COR, md) # Check the position of the image is correct pos_cor = md[model.MD_POS_COR] pos_dict = self.stage.position.value pos = (pos_dict["x"], pos_dict["y"]) exp_pos = tuple(p - c for p, c in zip(pos, pos_cor)) imd = st.image.value.metadata self.assertEqual(exp_pos, imd[model.MD_POS]) # Check the calibration doesn't happen again on a second acquisition bad_cor = (-1, -1) # stupid impossible value self.sed.updateMetadata({model.MD_POS_COR: bad_cor}) self.image_received.clear() st.image.subscribe(self.on_image) st.is_active.value = True # wait until the image is acquired received = self.image_received.wait(10) st.is_active.value = False st.image.unsubscribe(self.on_image) self.assertTrue(received, "No image received after 10 s") # if calibration has happened (=bad), it has changed the metadata md = self.sed.getMetadata() self.assertEqual(bad_cor, md[model.MD_POS_COR], "metadata has been updated while it shouldn't have") # Check calibration happens again after a stage move f = self.stage.moveRel({"x": 100e-6}) f.result() # make sure the move is over self.image_received.clear() st.image.subscribe(self.on_image) st.is_active.value = True # wait until the image is acquired received = self.image_received.wait(30) st.is_active.value = False st.image.unsubscribe(self.on_image) self.assertTrue(received, "No image received after 30 s") # if calibration has happened (=good), it has changed the metadata md = self.sed.getMetadata() self.assertNotEqual(bad_cor, md[model.MD_POS_COR], "metadata hasn't been updated while it should have")