Example #1
0
    def test_ideal(self):
        model = sycomore.como.Model(
            self.species, self.m0,
            [["half_echo", sycomore.TimeInterval(self.TR/2.)]])

        magnetization = []
        for i in range(self.TR_count):
            model.apply_pulse(
                sycomore.Pulse(self.flip_angle, (math.pi/3+(i%2)*math.pi)*rad))
            model.apply_time_interval("half_echo")
            magnetization.append(model.isochromat())
            model.apply_time_interval("half_echo")

        root = os.environ["SYCOMORE_TEST_DATA"]
        with open(os.path.join(root, "baseline", "GRE_ideal.dat"), "rb") as fd:
            contents = fd.read()
            baseline = struct.unpack((int(len(contents)/8))*"d", contents)

        self.assertEqual(len(baseline), 3*self.TR_count)
        for i in range(self.TR_count):
            m_test = magnetization[i]
            m_baseline = baseline[3*i:3*(i+1)]

            self.assertAlmostEqual(m_test[0], m_baseline[0])
            self.assertAlmostEqual(m_test[1], m_baseline[1])
            self.assertAlmostEqual(m_test[2], m_baseline[2])
Example #2
0
    def test_diffusion(self):
        model = sycomore.como.Model(
            sycomore.Species(0 * Hz, 0 * Hz, 1 * um * um / ms),
            sycomore.Magnetization(0, 0, 1),
            [["foo", sycomore.TimeInterval(500 * ms, 0.1 * rad / um)]])

        model.apply_pulse(sycomore.Pulse(40 * deg, 0 * deg))
        model.apply_time_interval("foo")

        grid = model.magnetization()
        for index, _ in sycomore.GridScanner(grid.origin(), grid.shape()):
            if index == sycomore.Index(-1):
                self.assertEqual(grid[index].p, 0)
                self.assertEqual(grid[index].z, 0)
                self.assertAlmostEqual(grid[index].m, 0 + 0.003062528150606j)
            elif index == sycomore.Index(0):
                self.assertEqual(grid[index].p, 0)
                self.assertAlmostEqual(grid[index].z, 0.766044443118978)
                self.assertEqual(grid[index].m, 0)
            elif index == sycomore.Index(1):
                self.assertAlmostEqual(grid[index].p, 0 - 0.003062528150606j)
                self.assertEqual(grid[index].z, 0)
                self.assertEqual(grid[index].m, 0)
            else:
                self.assertEqual(grid[index].p, 0)
                self.assertAlmostEqual(grid[index].z, 0)
                self.assertAlmostEqual(grid[index].m, 0)
Example #3
0
 def test_duration_constructor(self):
     interval = sycomore.TimeInterval(1 * ms)
     self.assertEqual(interval.duration, 1 * ms)
     self._test_quantity_array(interval.gradient_amplitude,
                               3 * [0. * T / m])
     self._test_quantity_array(interval.gradient_area, 3 * [0. * T / m * s])
     self._test_quantity_array(interval.gradient_dephasing,
                               3 * [0. * rad / m])
     self._test_quantity_array(interval.gradient_moment, 3 * [0. * rad / m])
Example #4
0
    def test_comparison(self):
        interval_1 = sycomore.TimeInterval(1. * ms, 2 * T / m)
        interval_2 = sycomore.TimeInterval(1. * ms, 2 * T / m)
        interval_3 = sycomore.TimeInterval(1. * ms,
                                           [2 * T / m, 2 * T / m, 2 * T / m])

        self.assertTrue(interval_1 == interval_2)
        self.assertTrue(interval_1 == interval_3)
        self.assertFalse(interval_1 != interval_2)
        self.assertFalse(interval_1 != interval_3)

        interval_4 = sycomore.TimeInterval(4. * ms, 2 * T / m)
        self.assertFalse(interval_1 == interval_4)
        self.assertTrue(interval_1 != interval_4)

        interval_5 = sycomore.TimeInterval(1. * ms, 4 * T / m)
        self.assertFalse(interval_1 == interval_5)
        self.assertTrue(interval_1 != interval_5)
Example #5
0
 def test_amplitude_scalar_constructor(self):
     interval = sycomore.TimeInterval(1. * ms, 2. * mT / dm)
     self.assertEqual(interval.duration, 1e-3 * s)
     self._test_quantity_array(interval.gradient_amplitude,
                               3 * [20 * mT / m])
     self._test_quantity_array(interval.gradient_area,
                               3 * [20 * mT / m * ms])
     self._test_quantity_array(interval.gradient_dephasing,
                               3 * [5350.4437993378515 * rad / m])
     self._test_quantity_array(interval.gradient_moment,
                               3 * [5350.4437993378515 * rad / m])
Example #6
0
 def test_dephasing_scalar_constructor(self):
     interval = sycomore.TimeInterval(1. * ms, 2. * rad / dm)
     self.assertEqual(interval.duration, 1e-3 * s)
     self._test_quantity_array(interval.gradient_amplitude,
                               3 * [74.76015355016015 * uT / m])
     self._test_quantity_array(interval.gradient_area,
                               3 * [74.76015355016015 * uT / m * ms])
     self._test_quantity_array(interval.gradient_dephasing,
                               3 * [20. * rad / m])
     self._test_quantity_array(interval.gradient_moment,
                               3 * [20. * rad / m])
Example #7
0
 def test_dephasing_vector_constructor(self):
     interval = sycomore.TimeInterval(
         1. * ms, [2 * rad / dm, 4 * rad / m, 8 * rad / dam])
     self.assertEqual(interval.duration, 1e-3 * s)
     self._test_quantity_array(interval.gradient_amplitude, [
         74.76015355016015 * uT / m, 14.95203071003203 * uT / m,
         2.9904061420064063 * uT / m
     ])
     self._test_quantity_array(interval.gradient_area, [
         74.76015355016015 * uT / m * ms, 14.95203071003203 * uT / m * ms,
         2.9904061420064063 * uT / m * ms
     ])
     self._test_quantity_array(interval.gradient_dephasing,
                               [20 * rad / m, 4 * rad / m, 0.8 * rad / m])
     self._test_quantity_array(interval.gradient_moment,
                               [20 * rad / m, 4 * rad / m, 0.8 * rad / m])
Example #8
0
 def test_amplitude_vector_constructor(self):
     interval = sycomore.TimeInterval(
         1. * ms, [2. * mT / dm, 4. * mT / m, 8. * mT / dam])
     self.assertEqual(interval.duration, 1e-3 * s)
     self._test_quantity_array(interval.gradient_amplitude,
                               [20. * mT / m, 4. * mT / m, 0.8 * mT / m])
     self._test_quantity_array(
         interval.gradient_area,
         [20. * mT / m * ms, 4. * mT / m * ms, 0.8 * mT / m * ms])
     self._test_quantity_array(interval.gradient_dephasing, [
         5350.4437993378515 * rad / m, 1070.0887598675702 * rad / m,
         214.01775197351404 * rad / m
     ])
     self._test_quantity_array(interval.gradient_moment, [
         5350.4437993378515 * rad / m, 1070.0887598675702 * rad / m,
         214.01775197351404 * rad / m
     ])
Example #9
0
    def test_off_resonance(self):
        species = sycomore.Species(0 * Hz, 0 * Hz, 0 * um * um / ms)
        m0 = sycomore.Magnetization(0, 0, 1)

        pulse = sycomore.Pulse(90 * deg, math.pi * rad)
        pulse_duration = 1 * ms
        pulse_support_size = 101
        zero_crossings = 2

        # NOTE: in the absence of relaxation and diffusion, the TR is meaningless
        TR = 500 * ms
        slice_thickness = 1 * mm

        t0 = pulse_duration / (2 * zero_crossings)
        sinc_pulse = sycomore.HardPulseApproximation(
            pulse, sycomore.linspace(pulse_duration, pulse_support_size),
            sycomore.sinc_envelope(t0), 1 / t0, slice_thickness, "rf")

        refocalization = sycomore.TimeInterval(
            (TR - pulse_duration) / 2., -sinc_pulse.get_gradient_moment() / 2)

        model = sycomore.como.Model(
            species, m0, [["rf", sinc_pulse.get_time_interval()],
                          ["refocalization", refocalization]])

        model.apply_pulse(sinc_pulse)
        model.apply_time_interval("refocalization")

        frequencies = sycomore.linspace(60. * rad / ms, 201)
        magnetization = [
            model.isochromat(set(), sycomore.Point(), f) for f in frequencies
        ]

        root = os.environ["SYCOMORE_TEST_DATA"]
        with open(os.path.join(root, "baseline", "off_resonance.dat"),
                  "rb") as fd:
            contents = fd.read()
            baseline = struct.unpack((int(len(contents) / 8)) * "d", contents)

        self.assertEqual(len(baseline), 2 * len(magnetization))
        for i in range(len(magnetization)):
            self.assertAlmostEqual(sycomore.transversal(magnetization[i]),
                                   baseline[2 * i])
            self.assertAlmostEqual(magnetization[i][2], baseline[2 * i + 1])
Example #10
0
    def test_gradient_properties(self):
        amplitude = [20 * mT / m, 40 * mT / m, 80 * mT / m]
        area = [20 * mT / m * ms, 40 * mT / m * ms, 80 * mT / m * ms]
        dephasing = [
            5350.4437993378515 * rad / m, 10700.887598675701 * rad / m,
            21401.775197351402 * rad / m
        ]
        moment = dephasing

        for property in ["amplitude", "area", "dephasing", "moment"]:
            interval = sycomore.TimeInterval(1. * ms)

            setattr(interval, "gradient_{}".format(property),
                    locals()[property][0])
            self._test_quantity_array(interval.gradient_amplitude,
                                      3 * [amplitude[0]])
            self._test_quantity_array(interval.gradient_area, 3 * [area[0]])
            self._test_quantity_array(interval.gradient_dephasing,
                                      3 * [dephasing[0]])
            self._test_quantity_array(interval.gradient_moment,
                                      3 * [moment[0]])

            setattr(interval, "gradient_{}".format(property),
                    locals()[property])
            self._test_quantity_array(interval.gradient_amplitude, amplitude)
            self._test_quantity_array(interval.gradient_area, area)
            self._test_quantity_array(interval.gradient_dephasing, dephasing)
            self._test_quantity_array(interval.gradient_moment, moment)

            interval.set_gradient(locals()[property][1])
            self._test_quantity_array(interval.gradient_amplitude,
                                      3 * [amplitude[1]])
            self._test_quantity_array(interval.gradient_area, 3 * [area[1]])
            self._test_quantity_array(interval.gradient_dephasing,
                                      3 * [dephasing[1]])
            self._test_quantity_array(interval.gradient_moment,
                                      3 * [moment[1]])

            interval.set_gradient(locals()[property])
            self._test_quantity_array(interval.gradient_amplitude, amplitude)
            self._test_quantity_array(interval.gradient_area, area)
            self._test_quantity_array(interval.gradient_dephasing, dephasing)
            self._test_quantity_array(interval.gradient_moment, moment)
Example #11
0
    def test_pulse(self):
        model = sycomore.como.Model(
            sycomore.Species(1 * s, 0.1 * s), sycomore.Magnetization(0, 0, 1),
            [["dummy", sycomore.TimeInterval(0 * s)]])

        model.apply_pulse(sycomore.Pulse(41 * deg, 27 * deg))

        grid = model.magnetization()
        for index, _ in sycomore.GridScanner(grid.origin(), grid.shape()):
            if index == sycomore.Index(0):
                self.assertAlmostEqual(grid[index].p,
                                       0.210607912662250 - 0.413341301933443j)
                self.assertAlmostEqual(grid[index].z, 0.754709580222772)
                self.assertAlmostEqual(grid[index].m,
                                       0.210607912662250 + 0.413341301933443j)
            else:
                self.assertEqual(grid[index].p, 0)
                self.assertAlmostEqual(grid[index].z, 0)
                self.assertAlmostEqual(grid[index].m, 0)
Example #12
0
    def test_real(self):
        t0 = self.pulse_duration/(2*self.zero_crossings)
        sinc_pulse = sycomore.HardPulseApproximation(
            sycomore.Pulse(self.flip_angle, 0*rad),
            sycomore.linspace(self.pulse_duration, self.pulse_support_size),
            sycomore.sinc_envelope(t0), 1/t0, self.slice_thickness, "rf")

        half_echo = sycomore.TimeInterval(
            (self.TR-self.pulse_duration)/2.,
            -sinc_pulse.get_gradient_moment()/2)

        model = sycomore.como.Model(
            self.species, self.m0, [
                ["rf", sinc_pulse.get_time_interval()],
                ["half_echo", half_echo]])

        magnetization = []
        for i in range(self.TR_count):
            sinc_pulse.set_phase((math.pi/3+(i%2)*math.pi)*rad)
            model.apply_pulse(sinc_pulse)
            model.apply_time_interval("half_echo")
            magnetization.append(model.isochromat())
            model.apply_time_interval("half_echo")

        root = os.environ["SYCOMORE_TEST_DATA"]
        with open(os.path.join(root, "baseline", "GRE_real.dat"), "rb") as fd:
            contents = fd.read()
            baseline = struct.unpack((int(len(contents)/8))*"d", contents)

        self.assertEqual(len(baseline), 3*self.TR_count)
        for i in range(self.TR_count):
            m_test = magnetization[i]
            m_baseline = baseline[3*i:3*(i+1)]

            self.assertAlmostEqual(m_test[0], m_baseline[0])
            self.assertAlmostEqual(m_test[1], m_baseline[1])
            self.assertAlmostEqual(m_test[2], m_baseline[2])
Example #13
0
    def test_time_interval(self):
        model = sycomore.como.Model(
            sycomore.Species(math.log(2) * Hz,
                             math.log(2) * Hz),
            sycomore.Magnetization(0, 0, 1),
            [["foo", sycomore.TimeInterval(1 * s)],
             ["bar", sycomore.TimeInterval(1 * s)]])

        model.apply_pulse(sycomore.Pulse(45 * deg, 90 * deg))

        model.apply_time_interval("foo")

        grid = model.magnetization()
        for index, _ in sycomore.GridScanner(grid.origin(), grid.shape()):
            if index == sycomore.Index(-1, 0):
                self.assertEqual(grid[index].p, 0)
                self.assertEqual(grid[index].z, 0)
                self.assertAlmostEqual(grid[index].m, 0.25)
            elif index == sycomore.Index(0, 0):
                self.assertEqual(grid[index].p, 0)
                self.assertEqual(grid[index].z, 0.5 * (1 + math.sqrt(2) / 2))
                self.assertEqual(grid[index].m, 0)
            elif index == sycomore.Index(1, 0):
                self.assertAlmostEqual(grid[index].p, 0.25)
                self.assertEqual(grid[index].z, 0)
                self.assertEqual(grid[index].m, 0)
            else:
                self.assertEqual(grid[index].p, 0)
                self.assertAlmostEqual(grid[index].z, 0)
                self.assertAlmostEqual(grid[index].m, 0)

        model.apply_time_interval("bar")

        grid = model.magnetization()
        for index, _ in sycomore.GridScanner(grid.origin(), grid.shape()):
            if index == sycomore.Index(-1, -1):
                self.assertEqual(grid[index].p, 0)
                self.assertEqual(grid[index].z, 0)
                self.assertAlmostEqual(grid[index].m, 0.125)
            elif index == sycomore.Index(0, 0):
                self.assertEqual(grid[index].p, 0)
                self.assertEqual(grid[index].z,
                                 0.5 + 0.25 * (1 + math.sqrt(2) / 2))
                self.assertEqual(grid[index].m, 0)
            elif index == sycomore.Index(1, 1):
                self.assertAlmostEqual(grid[index].p, 0.125)
                self.assertEqual(grid[index].z, 0)
                self.assertEqual(grid[index].m, 0)
            else:
                self.assertEqual(grid[index].p, 0)
                self.assertAlmostEqual(grid[index].z, 0)
                self.assertAlmostEqual(grid[index].m, 0)

        isochromat = model.isochromat()
        self.assertAlmostEqual(isochromat[0], 0.125 * math.sqrt(2))
        self.assertAlmostEqual(isochromat[1], 0)
        self.assertAlmostEqual(isochromat[2],
                               0.5 + 0.25 * (1 + math.sqrt(2) / 2))

        isochromat = model.isochromat(
            {sycomore.Index(0, 0),
             sycomore.Index(-1, -1)})
        self.assertAlmostEqual(isochromat[0], 0.125 * math.sqrt(2) / 2)
        self.assertAlmostEqual(isochromat[1], 0)
        self.assertAlmostEqual(isochromat[2],
                               0.5 + 0.25 * (1 + math.sqrt(2) / 2))
Example #14
0
    def test_pulse_profile(self):
        species = sycomore.Species(0*Hz, 0*Hz, 0*um*um/ms)
        m0 = sycomore.Magnetization(0, 0, 1)

        pulse = sycomore.Pulse(90*deg, math.pi*rad)
        pulse_duration = 1*ms
        pulse_support_size = 101
        zero_crossings = 2

        # NOTE: in the absence of relaxation and diffusion, the TR is meaningless
        TR = 500*ms;
        slice_thickness = 1*mm;

        sampling_support_size = 501

        t0 = pulse_duration/(2*zero_crossings)
        sinc_pulse = sycomore.HardPulseApproximation(
            pulse,
            sycomore.linspace(pulse_duration, pulse_support_size),
            sycomore.sinc_envelope(t0), 1/t0, slice_thickness, "rf")

        refocalization = sycomore.TimeInterval(
            (TR-pulse_duration)/2., -sinc_pulse.get_gradient_moment()/2)

        sampling_locations = sycomore.linspace(
            sycomore.Point(0*m, 0*m, 2*slice_thickness), sampling_support_size)

        model = sycomore.como.Model(
            species, m0, [
                ["rf", sinc_pulse.get_time_interval()],
                ["refocalization", refocalization]])

        model.apply_pulse(sinc_pulse)

        before_refocalization = [
            model.isochromat(set(), p) for p in sampling_locations]

        model.apply_time_interval("refocalization")

        after_refocalization = [
            model.isochromat(set(), p) for p in sampling_locations]

        root = os.environ["SYCOMORE_TEST_DATA"]
        with open(os.path.join(root, "baseline", "pulse_profile.dat"), "rb") as fd:
            contents = fd.read()
            baseline = struct.unpack((int(len(contents)/8))*"d", contents)

        self.assertEqual(len(baseline), 2*3*len(sampling_locations))
        for i in range(len(sampling_locations)):
            m_test = before_refocalization[i]
            m_baseline = baseline[3*i:3*(i+1)]

            self.assertAlmostEqual(m_test[0], m_baseline[0])
            self.assertAlmostEqual(m_test[1], m_baseline[1])
            self.assertAlmostEqual(m_test[2], m_baseline[2])
        for i in range(len(sampling_locations)):
            m_test = after_refocalization[i]
            m_baseline = baseline[
                3*(i+len(sampling_locations)):3*(i+len(sampling_locations)+1)]

            self.assertAlmostEqual(m_test[0], m_baseline[0])
            self.assertAlmostEqual(m_test[1], m_baseline[1])
            self.assertAlmostEqual(m_test[2], m_baseline[2])