예제 #1
0
 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)
예제 #2
0
 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')
예제 #3
0
    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)
예제 #4
0
 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)
예제 #5
0
 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)
예제 #6
0
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)
예제 #7
0
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()
예제 #8
0
    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))
예제 #9
0
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)
예제 #10
0
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)
예제 #11
0
 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)
예제 #12
0
 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)
예제 #13
0
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)
예제 #14
0
 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)
예제 #15
0
 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)
예제 #16
0
 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)
예제 #17
0
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)
예제 #18
0
 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)
예제 #19
0
    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))
예제 #20
0
    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)