def setUp(self): syris.init(device_index=0) energies = range(10, 20) * q.keV self.energy = energies[len(energies) / 2] self.material = Material('foo', np.arange(len(energies), dtype=np.complex), energies)
def test_make_fromfile(self): m_0 = Material("PMMA", self.refractive_indices, self.energies) m_0.save() try: make_fromfile('PMMA.mat') finally: os.remove('PMMA.mat')
def test_comparison(self): m_0 = Material("PMMA", self.refractive_indices, self.energies) m_1 = Material("glass", self.refractive_indices, self.energies) m_2 = Material("PMMA", self.refractive_indices, self.energies) self.assertEqual(m_0, m_2) self.assertNotEqual(m_0, m_1) self.assertNotEqual(m_0, None) self.assertNotEqual(m_0, 1)
def setUp(self): default_syris_init() self.energies = np.arange(10, 20) * q.keV self.energy = 15 * q.keV delta = np.linspace(1e-5, 1e-6, len(self.energies)) beta = np.linspace(1e-8, 1e-9, len(self.energies)) self.material = Material("foo", delta + beta * 1j, self.energies) self.thickness = 1 * q.mm self.fltr = MaterialFilter(self.thickness, self.material)
def setUp(self): syris.init(device_index=0) self.energies = np.arange(10, 20) * q.keV self.energy = 15 * q.keV delta = np.linspace(1e-5, 1e-6, len(self.energies)) beta = np.linspace(1e-8, 1e-9, len(self.energies)) self.material = Material('foo', delta + beta * 1j, self.energies) self.thickness = 1 * q.mm self.fltr = MaterialFilter(self.thickness, self.material)
class TestOpticalElement(SyrisTest): def setUp(self): default_syris_init() energies = list(range(10, 20)) * q.keV self.energy = energies[len(energies) // 2] self.material = Material("foo", np.arange(len(energies), dtype=np.complex), energies) def test_2d_conversion(self): elem = DummyOpticalElement() shape, ps = elem.transfer(1, 1 * q.m, 0 * q.keV) self.assertEqual(len(shape), 2) self.assertEqual(len(ps), 2) def test_transfer(self): go = StaticBody(np.arange(4 ** 2).reshape(4, 4) * q.um, 1 * q.um, material=self.material) transferred = go.transfer((4, 4), 1 * q.um, self.energy).get() gt = transfer( go.thickness, self.material.get_refractive_index(self.energy), energy_to_wavelength(self.energy), ).get() np.testing.assert_almost_equal(gt, transferred) def test_transfer_fourier(self): elem = DummyOpticalElement() print(elem.__class__._transfer_fourier == OpticalElement._transfer_fourier) u = elem.transfer_fourier((4, 4), 1 * q.um, 10 * q.keV).get() np.testing.assert_almost_equal(u, 0 + 0j)
def main(): args = parse_args() syris.init() n = 32 ps = 1 * q.um energies = np.arange(5, 30) * q.keV energy = 10 * q.keV lam = energy_to_wavelength(energy) # Delta causes phase shift between two adjacent pixels by 2 Pi delta = (lam / ps).simplified.magnitude ri = np.ones_like(energies.magnitude, dtype=np.complex) * delta + 0j material = Material("dummy", ri, energies) fmt = "Computing with n: {:>4}, pixel size: {}" wedge = np.tile(np.arange(n), [n, 1]) * ps # Non-supersampled object shape causes phase shifts 0, 2Pi, 4Pi, ..., thus the phase is constant # as an extreme result of aliasing print(fmt.format(n, ps)) u = compute_transmission_function(n, ps, 1, energy, material) # Supersampling helps resolve the transmission function print(fmt.format(n * args.supersampling, ps / args.supersampling)) u_s = compute_transmission_function(n, ps, args.supersampling, energy, material) show(wedge.magnitude, title="Projected Object [um]") show(u.real, title="Re[T(x, y)]") show(u_s.real, title="Re[T(x, y)] Supersampled") plt.show()
def test_transfer_many(self): n = 32 shape = (n, n) ps = 1 * q.um energies = np.arange(5, 30) * q.keV energy = 10 * q.keV lam = physics.energy_to_wavelength(energy) # Delta causes phase shift between two adjacent pixels by Pi / 16 delta = (lam / (32 * ps)).simplified.magnitude ri = np.ones_like(energies.magnitude, dtype=np.complex) * delta + 0j material = Material('dummy', ri, energies) wedge = np.tile(np.arange(n), [n, 1]) * ps wedge = StaticBody(wedge, ps, material=material) # Test more objects u_many = physics.transfer_many([wedge, wedge], shape, ps, energy).get() # 2 objects u = wedge.transfer(shape, ps, energy).get()**2 np.testing.assert_almost_equal(u, u_many) # Test exponent u = physics.transfer_many([wedge], shape, ps, energy, exponent=False).get() u_exp = physics.transfer_many([wedge], shape, ps, energy, exponent=True).get() np.testing.assert_almost_equal(u, np.exp(u_exp))
class TestOpticalElement(SyrisTest): def setUp(self): syris.init(device_index=0) energies = range(10, 20) * q.keV self.energy = energies[len(energies) / 2] self.material = Material('foo', np.arange(len(energies), dtype=np.complex), energies) def test_2d_conversion(self): elem = DummyOpticalElement() shape, ps = elem.transfer(1, 1 * q.m, 0 * q.keV) self.assertEqual(len(shape), 2) self.assertEqual(len(ps), 2) @opencl def test_transfer(self): go = StaticBody(np.arange(4 ** 2).reshape(4, 4) * q.um, 1 * q.um, material=self.material) transferred = go.transfer((4, 4), 1 * q.um, self.energy).get() gt = transfer(go.thickness, self.material.get_refractive_index(self.energy), energy_to_wavelength(self.energy)).get() np.testing.assert_almost_equal(gt, transferred) @opencl def test_transfer_fourier(self): elem = DummyOpticalElement() print elem.__class__._transfer_fourier == OpticalElement._transfer_fourier u = elem.transfer_fourier((4, 4), 1 * q.um, 10 * q.keV).get() np.testing.assert_almost_equal(u, 0 + 0j)
class TestOpticalElement(SyrisTest): def setUp(self): syris.init(device_index=0) energies = range(10, 20) * q.keV self.energy = energies[len(energies) / 2] self.material = Material('foo', np.arange(len(energies), dtype=np.complex), energies) def test_2d_conversion(self): elem = DummyOpticalElement() shape, ps = elem.transfer(1, 1 * q.m, 0 * q.keV) self.assertEqual(len(shape), 2) self.assertEqual(len(ps), 2) @opencl def test_transfer(self): go = StaticBody(np.arange(4**2).reshape(4, 4) * q.um, 1 * q.um, material=self.material) transferred = go.transfer((4, 4), 1 * q.um, self.energy).get() gt = transfer(go.thickness, self.material.get_refractive_index(self.energy), energy_to_wavelength(self.energy)).get() np.testing.assert_almost_equal(gt, transferred)
def setUp(self): default_syris_init() energies = list(range(10, 20)) * q.keV self.energy = energies[len(energies) // 2] self.material = Material("foo", np.arange(len(energies), dtype=np.complex), energies)
class TestFilters(SyrisTest): def setUp(self): syris.init(device_index=0) self.energies = np.arange(10, 20) * q.keV self.energy = 15 * q.keV delta = np.linspace(1e-5, 1e-6, len(self.energies)) beta = np.linspace(1e-8, 1e-9, len(self.energies)) self.material = Material('foo', delta + beta * 1j, self.energies) self.thickness = 1 * q.mm self.fltr = MaterialFilter(self.thickness, self.material) def test_transfer(self): thickness = self.thickness.simplified.magnitude lam = energy_to_wavelength(self.energy).simplified.magnitude coeff = -2 * np.pi * thickness / lam ri = self.material.get_refractive_index(self.energy) gt = np.exp(coeff * (ri.imag + ri.real * 1j)) fltr = self.fltr.transfer(None, None, self.energy) self.assertAlmostEqual(gt, fltr) def test_get_attenuation(self): att = self.material.get_attenuation_coefficient(self.energy).simplified.magnitude thickness = self.thickness.simplified.magnitude gt = att * thickness fltr = self.fltr.get_attenuation(self.energy) self.assertAlmostEqual(gt, fltr) def test_exponent(self): transmitted = self.fltr.transfer(None, None, self.energy) exponent = self.fltr.transfer(None, None, self.energy, exponent=True) self.assertAlmostEqual(transmitted, np.exp(exponent), places=5) def test_gaussian(self): energies = np.arange(5, 30, 0.1) * q.keV energy = 15 * q.keV sigma = fwnm_to_sigma(1, n=2) * q.keV energy_10 = energy - sigma_to_fwnm(sigma.magnitude, n=10) / 2 * q.keV fltr = GaussianFilter(energies, energy, sigma, peak_transmission=0.5) u_0 = 10 + 0j u_f = fltr.transfer(None, None, energy) u = u_0 * u_f self.assertAlmostEqual(np.abs(u) ** 2, 50, places=4) u_f = fltr.transfer(None, None, energy_10) u = u_0 * u_f self.assertAlmostEqual(np.abs(u) ** 2, 5, places=4) # Test exponent u_f = fltr.transfer(None, None, energy, exponent=True) u = u_0 * np.exp(u_f) self.assertAlmostEqual(np.abs(u) ** 2, 50, places=4) u_f = fltr.transfer(None, None, energy_10, exponent=True) u = u_0 * np.exp(u_f) self.assertAlmostEqual(np.abs(u) ** 2, 5, places=4) def test_scintillator_conservation(self): """Test if the integral of luminescence is really 1.""" wavelengths = np.linspace(100, 700, 512) * q.nm wavelengths_dense = np.linspace(wavelengths[0].magnitude, wavelengths[-1].magnitude, 4 * len(wavelengths)) * q.nm d_wavelength_dense = wavelengths_dense[1] - wavelengths_dense[0] sigma = 20. * q.nm luminescence = np.exp(-(wavelengths - 400 * q.nm) ** 2 / (2 * sigma ** 2)) / \ (sigma * np.sqrt(2 * np.pi)) sc = Scintillator(1 * q.m, None, np.ones(30) / q.keV, np.arange(30) * q.keV, luminescence, wavelengths, 1) lum_orig = sc.get_luminescence(wavelengths) self.assertAlmostEqual((np.sum(lum_orig) * sc.d_wavelength).simplified.magnitude, 1) lum = sc.get_luminescence(wavelengths_dense) self.assertAlmostEqual((np.sum(lum) * d_wavelength_dense).simplified.magnitude, 1)
def test_interpolation_out_of_bounds(self): mat = Material('foo', self.refractive_indices, self.energies) self.assertRaises(ValueError, mat.get_refractive_index, 1 * q.eV) self.assertRaises(ValueError, mat.get_refractive_index, 1 * q.MeV)
def test_interpolation(self): mat = Material('foo', self.refractive_indices, self.energies) index = mat.get_refractive_index(2400 * q.eV) self.assertAlmostEqual(2.4, index.real, places=5) self.assertAlmostEqual(2.4, index.imag, places=5)
class TestFilters(SyrisTest): def setUp(self): syris.init(device_index=0) self.energies = np.arange(10, 20) * q.keV self.energy = 15 * q.keV delta = np.linspace(1e-5, 1e-6, len(self.energies)) beta = np.linspace(1e-8, 1e-9, len(self.energies)) self.material = Material('foo', delta + beta * 1j, self.energies) self.thickness = 1 * q.mm self.fltr = MaterialFilter(self.thickness, self.material) def test_transfer(self): thickness = self.thickness.simplified.magnitude lam = energy_to_wavelength(self.energy).simplified.magnitude coeff = -2 * np.pi * thickness / lam ri = self.material.get_refractive_index(self.energy) gt = np.exp(coeff * (ri.imag + ri.real * 1j)) fltr = self.fltr.transfer(None, None, self.energy) self.assertAlmostEqual(gt, fltr) def test_get_attenuation(self): att = self.material.get_attenuation_coefficient( self.energy).simplified.magnitude thickness = self.thickness.simplified.magnitude gt = att * thickness fltr = self.fltr.get_attenuation(self.energy) self.assertAlmostEqual(gt, fltr) def test_exponent(self): transmitted = self.fltr.transfer(None, None, self.energy) exponent = self.fltr.transfer(None, None, self.energy, exponent=True) self.assertAlmostEqual(transmitted, np.exp(exponent), places=5) def test_gaussian(self): energies = np.arange(5, 30, 0.1) * q.keV energy = 15 * q.keV sigma = fwnm_to_sigma(1, n=2) * q.keV energy_10 = energy - sigma_to_fwnm(sigma.magnitude, n=10) / 2 * q.keV fltr = GaussianFilter(energies, energy, sigma, peak_transmission=0.5) u_0 = 10 + 0j u_f = fltr.transfer(None, None, energy) u = u_0 * u_f self.assertAlmostEqual(np.abs(u)**2, 50, places=4) u_f = fltr.transfer(None, None, energy_10) u = u_0 * u_f self.assertAlmostEqual(np.abs(u)**2, 5, places=4) # Test exponent u_f = fltr.transfer(None, None, energy, exponent=True) u = u_0 * np.exp(u_f) self.assertAlmostEqual(np.abs(u)**2, 50, places=4) u_f = fltr.transfer(None, None, energy_10, exponent=True) u = u_0 * np.exp(u_f) self.assertAlmostEqual(np.abs(u)**2, 5, places=4) def test_scintillator_conservation(self): """Test if the integral of luminescence is really 1.""" wavelengths = np.linspace(100, 700, 512) * q.nm wavelengths_dense = np.linspace(wavelengths[0].magnitude, wavelengths[-1].magnitude, 4 * len(wavelengths)) * q.nm d_wavelength_dense = wavelengths_dense[1] - wavelengths_dense[0] sigma = 20. * q.nm luminescence = np.exp(-(wavelengths - 400 * q.nm) ** 2 / (2 * sigma ** 2)) / \ (sigma * np.sqrt(2 * np.pi)) sc = Scintillator(1 * q.m, None, np.ones(30) / q.keV, np.arange(30) * q.keV, luminescence, wavelengths, 1) lum_orig = sc.get_luminescence(wavelengths) self.assertAlmostEqual( (np.sum(lum_orig) * sc.d_wavelength).simplified.magnitude, 1) lum = sc.get_luminescence(wavelengths_dense) self.assertAlmostEqual( (np.sum(lum) * d_wavelength_dense).simplified.magnitude, 1)
def test_transmission_sampling(self): def compute_transmission_function(n, ps, energy, material): wedge = np.tile(np.arange(n), [n, 1]) * ps wedge = StaticBody(wedge, ps, material=material) return wedge.transfer((n, n), ps, energy, exponent=True) def compute_distance(n, ps, lam, ps_per_lam): ca = (lam / (ps_per_lam * ps)).simplified.magnitude alpha = np.arccos(ca) theta = np.pi / 2 - alpha return (n * ps / (2 * np.tan(theta))).simplified n = 32 ps = 1 * q.um energies = np.arange(5, 30) * q.keV energy = 10 * q.keV lam = physics.energy_to_wavelength(energy) # Delta causes phase shift between two adjacent pixels by 2 Pi delta = (lam / ps).simplified.magnitude ri = np.ones_like(energies.magnitude, dtype=np.complex) * delta + 0j material = Material('dummy', ri, energies) # Single object u = compute_transmission_function(n, ps, energy, material) self.assertFalse(physics.is_wavefield_sampling_ok(u)) # 4x supersampling => phase shift Pi/2 u = compute_transmission_function(4 * n, ps / 4, energy, material) self.assertTrue(physics.is_wavefield_sampling_ok(u)) # 4x supersampling with 2 objects => phase shift Pi n *= 4 ps /= 4 wedge = np.tile(np.arange(n), [n, 1]) * ps wedge = StaticBody(wedge, ps, material=material) u = physics.transfer_many([wedge, wedge], (n, n), ps, energy, exponent=True) self.assertFalse(physics.is_wavefield_sampling_ok(u)) # X-ray source with a parabolic phase profile n = 128 ps = 1 * q.um trajectory = Trajectory([(n / 2, n / 2, 0)] * ps) # 1 pixel per wavelength => insufficient sampling d = compute_distance(n, ps, lam, 1) source = BendingMagnet(2.5 * q.GeV, 150 * q.mA, 1.5 * q.T, d, 1, np.array([0.2, 0.8]) * q.mm, ps, trajectory, phase_profile='parabola') u = source.transfer((n, n), ps, energy, exponent=True) self.assertFalse(physics.is_wavefield_sampling_ok(u)) # 4 pixel per wavelength => good sampling d = compute_distance(n, ps, lam, 4) source = BendingMagnet(2.5 * q.GeV, 150 * q.mA, 1.5 * q.T, d, 1, np.array([0.2, 0.8]) * q.mm, ps, trajectory, phase_profile='parabola') u = source.transfer((n, n), ps, energy, exponent=True) self.assertTrue(physics.is_wavefield_sampling_ok(u))
def test_hashing(self): m_0 = Material("PMMA", self.refractive_indices, self.energies) m_1 = Material("glass", self.refractive_indices, self.energies) m_2 = Material("PMMA", self.refractive_indices, self.energies) self.assertEqual(len(set([m_1, m_0, m_1, m_2])), 2)