def test_zero_zstep(self): self.focus.moveAbsSync({"z": 1300e-6}) zMin = -500e-6 zMax = 500e-6 zrange = [zMin, zMax] zStep = 0e-6 with self.assertRaises(ZeroDivisionError): generate_zlevels(self.focus, zrange, zStep)
def test_zrange_not_in_proper_order(self): self.focus.moveAbsSync({"z": 1300e-6}) zMin = -10e-6 zMax = 10e-6 zrange = [zMax, zMin] zStep = 10e-6 with self.assertRaises(ValueError): generate_zlevels(self.focus, zrange, zStep)
def test_zmax_and_zmin_both_zeros(self): self.focus.moveAbsSync({"z": 1300e-6}) zMin = -0e-6 zMax = 0e-6 zrange = [zMin, zMax] zStep = 10e-6 with self.assertRaises(ValueError): generate_zlevels(self.focus, zrange, zStep)
def test_settings_observer_metadata_with_zstack(self): settings_observer = SettingsObserver(model.getComponents()) vas = {"exposureTime"} s1 = stream.FluoStream("FM", self.ccd, self.ccd.data, self.light, self.light_filter, detvas=vas, focuser=self.fm_focuser) s1.detExposureTime.value = 0.023 # 23 ms zlevels_list = generate_zlevels(self.fm_focuser, [-2e-6, 2e-6], 1e-6) zlevels = {s1: list(zlevels_list)} f = acquireZStack([s1], zlevels, settings_observer) # get the data data, exp = f.result() self.assertIsNone(exp) for d in data: self.assertTrue(model.MD_EXTRA_SETTINGS in d.metadata) # if zstack, so the center has 3 components self.assertEqual(len(d.metadata[model.MD_POS]), 3) # if zstack, so the pixel size has 3 components self.assertEqual(len(d.metadata[model.MD_PIXEL_SIZE]), 3) self.assertEqual( data[0].metadata[model.MD_EXTRA_SETTINGS]["Camera"] ["exposureTime"], [0.023, "s"])
def test_large_number_of_levels(self): self.focus.moveAbsSync({"z": 1000e-6}) zMax = 100e-6 zMin = -100e-6 zrange = [zMin, zMax] zStep = 0.5e-6 output = generate_zlevels(self.focus, zrange, zStep) self.assertEqual(len(output), 401)
def test_zmax_and_zmin_both_zeros(self): self.focus.moveAbsSync({"z": 1300e-6}) zMin = -0e-6 zMax = 0e-6 zrange = [zMin, zMax] zStep = 10e-6 actual = generate_zlevels(self.focus, zrange, zStep) expected = self.focus.position.value self.assertAlmostEqual(expected["z"], actual)
def test_clipping_zmax_on_actuator_upper_limit(self): self.focus.moveAbsSync({"z": 2800e-6}) zMax = 300e-6 zMin = 0e-6 zrange = [zMin, zMax] zStep = 100e-6 expected = numpy.asarray([0e-6, 100e-6, 200e-6]) + \ self.focus.position.value["z"] actual = generate_zlevels(self.focus, zrange, zStep) numpy.testing.assert_array_almost_equal(expected, actual)
def test_normal_zlevels_output_with_rounding_up(self): self.focus.moveAbsSync({"z": 1000e-6}) zMax = 24e-6 zMin = -24e-6 zrange = [zMin, zMax] zStep = 17e-6 expected = numpy.asarray([-24e-6, -8e-6, 8e-6, 24e-6]) + \ self.focus.position.value["z"] actual = generate_zlevels(self.focus, zrange, zStep) numpy.testing.assert_array_almost_equal(expected, actual)
def test_zstep_greater_than_zmax_and_zmin(self): self.focus.moveAbsSync({"z": 1300e-6}) zMin = -10e-6 zMax = 10e-6 zrange = [zMin, zMax] zStep = 70e-6 actual = generate_zlevels(self.focus, zrange, zStep) expected = numpy.asarray([-10e-6, 10e-6 ]) + self.focus.position.value["z"] numpy.testing.assert_array_almost_equal(actual, expected)
def test_normal_zlevels_output_with_positive_zstep(self): self.focus.moveAbsSync({"z": 1000e-6}) zMax = 100e-6 zMin = -250e-6 zrange = [zMin, zMax] zStep = 50e-6 expected = numpy.asarray([ -250e-6, -200e-6, -150e-6, -100e-6, -50e-6, 0e-6, 50e-6, 100e-6 ]) + self.focus.position.value["z"] actual = generate_zlevels(self.focus, zrange, zStep) numpy.testing.assert_array_almost_equal(expected, actual)
def test_normal_zlevels_output_with_negative_zstep(self): self.focus.moveAbsSync({"z": 1000e-6}) zMax = 100e-6 zMin = -250e-6 zrange = [zMin, zMax] zStep = -50e-6 expected = numpy.asarray([ 1.0e-04, 5.0e-05, 0.0, -5.0e-05, -1.0e-04, -1.5e-04, -2.0e-04, -2.5e-04 ]) + self.focus.position.value["z"] actual = generate_zlevels(self.focus, zrange, zStep) numpy.testing.assert_array_almost_equal(expected, actual)
def test_FM_and_SEM_with_zstack(self): s1 = stream.FluoStream("fluo1", self.ccd, self.ccd.data, self.light, self.light_filter, focuser=self.fm_focuser) s1.excitation.value = sorted(s1.excitation.choices)[0] sems = stream.SEMStream("sem", self.sed, self.sed.data, self.ebeam) self.streams = [s1, sems] zlevels_list = generate_zlevels(self.fm_focuser, [-2e-6, 2e-6], 1e-6) zlevels = {} for s in self.streams: if isinstance(s, stream.FluoStream): zlevels[s] = list(zlevels_list) est_time = acqmng.estimateZStackAcquisitionTime(self.streams, zlevels) # about 5 seconds for fm streams, and 1 sec for sem stream, so should be # greater than or equal 5 sec self.assertGreaterEqual(est_time, 4) # start the acquisition f = acqmng.acquireZStack(self.streams, zlevels) f.add_update_callback(self._on_progress_update) data, exp = f.result() self.assertIsNone(exp) for i, d in enumerate(data): self.assertIsInstance(d, model.DataArray) if d.ndim > 2 and d.shape[-3] > 1: # 3D data (FM) # if zstack, so the center has 3 components self.assertEqual(len(d.metadata[model.MD_POS]), 3) # if zstack, so the pixel size has 3 components self.assertEqual(len(d.metadata[model.MD_PIXEL_SIZE]), 3) else: # 2D data (SEM) # even if zstack, it's SEM, so the center has 2 components self.assertEqual(len(d.metadata[model.MD_POS]), 2) # even if zstack, it's SEM, so the pixel size has 2 components self.assertEqual(len(d.metadata[model.MD_PIXEL_SIZE]), 2) # 2 streams, so 2 acquisitions self.assertEqual(len(data), 2) # 2 streams, 2 updates per stream, so >= 2 updates self.assertGreaterEqual(self._nb_updates, 2)
def test_only_FM_streams_with_zstack(self): # create streams s1 = stream.FluoStream("fluo1", self.ccd, self.ccd.data, self.light, self.light_filter, focuser=self.fm_focuser) s1.excitation.value = sorted(s1.excitation.choices)[0] s2 = stream.FluoStream("fluo2", self.ccd, self.ccd.data, self.light, self.light_filter) s2._focuser = self.fm_focuser s2.excitation.value = sorted(s2.excitation.choices)[-1] self.streams = [s1, s2] zlevels_list = generate_zlevels(self.fm_focuser, [-2e-6, 2e-6], 1e-6) zlevels = {} for s in self.streams: zlevels[s] = list(zlevels_list) # there are about 5 zlevels, so should be greater than 2 seconds est_time = acqmng.estimateZStackAcquisitionTime(self.streams, zlevels) self.assertGreaterEqual(est_time, 2) # start the acquisition f = acqmng.acquireZStack(self.streams, zlevels) f.add_update_callback(self._on_progress_update) # get the data data, exp = f.result() self.assertIsNone(exp) for d in data: self.assertIsInstance(d, model.DataArray) # since zstack, the center has 3 components self.assertEqual(len(d.metadata[model.MD_POS]), 3) # since zstack, the pixel size has 3 components self.assertEqual(len(d.metadata[model.MD_PIXEL_SIZE]), 3) # 2 streams, so 2 acquisitions self.assertEqual(len(data), 2) # 2 streams, 2 updates per stream, so 2 updates at least self.assertGreaterEqual(self._nb_updates, 2)