Exemplo n.º 1
0
    def test_D_scalar(self):
        D_scalar = 1 * um * um / ms
        D_tensor = [
            1 * um * um / ms, 0 * um * um / ms, 0 * um * um / ms,
            0 * um * um / ms, 1 * um * um / ms, 0 * um * um / ms,
            0 * um * um / ms, 0 * um * um / ms, 1 * um * um / ms
        ]

        species = sycomore.Species(1 * ms, 100 * ms, D_scalar)
        self.assertSequenceEqual(species.D, D_tensor)

        species = sycomore.Species(1 * ms, 100 * ms)
        species.D = D_scalar
        self.assertSequenceEqual(species.D, D_tensor)
Exemplo n.º 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)
Exemplo n.º 3
0
 def test_gradient_multiple(self):
     species = sycomore.Species(1000*ms, 100*ms, 3*um**2/ms)
     model = sycomore.epg.Regular(species, unit_gradient_area=1*mT/m*ms)
     model.apply_pulse(47*deg, 23*deg)
     
     model.shift(1*ms, 1*mT/m)
     self._test_model(
         model,  
         [
             [0, 0, 0.6819983600624985],
             [0.2857626571584661-0.6732146319308543j, 0, 0]])
     
     model.shift(2*ms, 1*mT/m)
     self._test_model(
         model,  
         [
             [0, 0, 0.6819983600624985],
             [0, 0, 0],
             [0, 0, 0],
             [0.2857626571584661-0.6732146319308543j, 0, 0]])
     
     model.shift(1*ms, -1*mT/m)
     self._test_model(
         model,  
         [
             [0, 0, 0.6819983600624985],
             [0, 0, 0],
             [0.2857626571584661-0.6732146319308543j, 0, 0]])
     
     with self.assertRaises(Exception):
         model.shift(1.5*ms, 1*mT/m)
Exemplo n.º 4
0
    def test_gradient_default(self):
        species = sycomore.Species(1000 * ms, 100 * ms, 3 * um**2 / ms)
        model = sycomore.epg.Regular(species)
        model.apply_pulse(47 * deg, 23 * deg)
        model.shift()

        self._test_model(model,
                         [[0, 0, 0.6819983600624985],
                          [0.2857626571584661 - 0.6732146319308543j, 0, 0]])
Exemplo n.º 5
0
    def test_relaxation(self):
        species = sycomore.Species(1000 * ms, 100 * ms, 3 * um**2 / ms)
        model = sycomore.epg.Regular(species)
        model.apply_pulse(47 * deg, 23 * deg)
        model.shift()
        model.relaxation(10 * ms)

        self._test_model(model,
                         [[0, 0, 0.6851625292479138],
                          [0.2585687448743616 - 0.6091497893403431j, 0, 0]])
Exemplo n.º 6
0
    def test_apply_time_interval_field_off_resonance(self):
        species = sycomore.Species(1000 * ms, 100 * ms, 3 * um**2 / ms)
        model = sycomore.epg.Regular(species,
                                     unit_gradient_area=10 * mT / m * ms)
        model.delta_omega = 10 * Hz
        model.apply_pulse(47 * deg, 23 * deg)
        model.apply_time_interval(10 * ms, 2 * mT / m)

        self._test_model(model,
                         [[0, 0, 0.6851625292479138], [0, 0, 0],
                          [0.56707341067384409 - 0.34073208057155585j, 0, 0]])
Exemplo n.º 7
0
    def test_off_resonance(self):
        species = sycomore.Species(1000 * ms, 100 * ms, 3 * um**2 / ms)
        model = sycomore.epg.Regular(species)
        model.delta_omega = 10 * Hz
        model.apply_pulse(47 * deg, 23 * deg)
        model.shift()
        model.off_resonance(10 * ms)

        self._test_model(model,
                         [[0, 0, 0.6819983600624985],
                          [0.6268924782754024 - 0.37667500256027975j, 0, 0]])
Exemplo n.º 8
0
 def test_quantity_constructor_partial(self):
     species = sycomore.Species(1 * ms, 0.01 * kHz, R2_prime=1. / (15 * ds))
     self.assertEqual(species.R1, 1. * kHz)
     self.assertEqual(species.T1, 1. * ms)
     self.assertEqual(species.R2, 10. * Hz)
     self.assertEqual(species.T2, 0.1 * s)
     self.assertEqual(species.D[0], 0 * m * m / s)
     self.assertEqual(species.R2_prime, (1 / 1.5) * Hz)
     self.assertEqual(species.T2_prime, 1.5 * s)
     self.assertEqual(species.delta_omega, 0 * rad / s)
     self.assertEqual(species.w, 1)
Exemplo n.º 9
0
 def test_quantity_constructor_full(self):
     species = sycomore.Species(1 * ms, 0.01 * kHz, 3 * um * um / ms,
                                1. / (15 * ds), 0.9 * rad / s, 1.1)
     self.assertEqual(species.R1, 1. * kHz)
     self.assertEqual(species.T1, 1. * ms)
     self.assertEqual(species.R2, 10. * Hz)
     self.assertEqual(species.T2, 0.1 * s)
     self.assertEqual(species.D[0], 3e-9 * m * m / s)
     self.assertEqual(species.R2_prime, (1 / 1.5) * Hz)
     self.assertEqual(species.T2_prime, 1.5 * s)
     self.assertEqual(species.delta_omega, 0.9 * rad / s)
     self.assertEqual(species.w, 1.1)
Exemplo n.º 10
0
    def test_D_tensor(self):

        D = [
            1 * um * um / ms, 4 * um * um / ms, 7 * um * um / ms,
            2 * um * um / ms, 5 * um * um / ms, 8 * um * um / ms,
            3 * um * um / ms, 6 * um * um / ms, 9 * um * um / ms
        ]

        species = sycomore.Species(1 * ms, 100 * ms,
                                   sycomore.Array[sycomore.Quantity](D))
        self.assertSequenceEqual(species.D, D)

        species = sycomore.Species(1 * ms, 100 * ms, D)
        self.assertSequenceEqual(species.D, D)

        species = sycomore.Species(1 * ms, 100 * ms)
        species.D = sycomore.Array[sycomore.Quantity](D)
        self.assertSequenceEqual(species.D, D)

        species.D = D
        self.assertSequenceEqual(species.D, D)
Exemplo n.º 11
0
    def test_apply_time_interval_species_off_resonance(self):
        model = sycomore.epg.Discrete(
            sycomore.Species(self.species.R1,
                             self.species.R2,
                             self.species.D,
                             delta_omega=10 * Hz))
        model.apply_pulse(47 * deg, 23 * deg)
        model.apply_time_interval(10 * ms, 2 * mT / m)

        self._test_model(model, [0 * rad / m, 5350 * rad / m],
                         [[0, 0, 0.6851625292479138],
                          [0.56707341067384409 - 0.34073208057155585j, 0, 0]])
Exemplo n.º 12
0
    def test_diffusion(self):
        species = sycomore.Species(1000 * ms, 100 * ms, 3 * um**2 / ms)
        model = sycomore.epg.Regular(species,
                                     unit_gradient_area=20 * mT / m * ms)
        model.apply_pulse(47 * deg, 23 * deg)
        model.shift()
        model.relaxation(10 * ms)
        model.diffusion(10 * ms, 2 * mT / m)

        self._test_model(model,
                         [[0, 0, 0.6851625292479138],
                          [0.25805111586158685 - 0.60793033180597855j, 0, 0]])
Exemplo n.º 13
0
 def test_apply_time_interval_species_off_resonance(self):
     species = sycomore.Species(1000*ms, 100*ms, 3*um**2/ms, delta_omega=10*Hz)
     model = sycomore.epg.Regular(species, unit_gradient_area=10*mT/m*ms)
     model.delta_omega = -10*Hz
     model.apply_pulse(47*deg, 23*deg)
     model.apply_time_interval(10*ms, 2*mT/m)
     
     self._test_model(
         model, 
         [
             [0, 0, 0.6851625292479138], 
             [0, 0, 0],
             [0.2584947343504123-0.6089754314724013j, 0, 0]])
Exemplo n.º 14
0
    def test_apply_time_interval_both_off_resonance(self):
        model = sycomore.epg.Discrete(
            sycomore.Species(self.species.R1,
                             self.species.R2,
                             self.species.D,
                             delta_omega=10 * Hz))
        model.delta_omega = -10 * Hz
        model.apply_pulse(47 * deg, 23 * deg)
        model.apply_time_interval(10 * ms, 2 * mT / m)

        self._test_model(model, [0 * rad / m, 5350 * rad / m],
                         [[0, 0, 0.6851625292479138],
                          [0.2584947343504123 - 0.6089754314724013j, 0, 0]])
Exemplo n.º 15
0
    def setUp(self):
        self.species = sycomore.Species(1000*ms, 100*ms, 0.89*um*um/ms)
        self.m0 = sycomore.Magnetization(0, 0, 1)

        self.flip_angle = 40*deg
        self.pulse_duration = 1*ms
        self.pulse_support_size = 101
        self.zero_crossings = 2

        self.TR = 500*ms
        self.slice_thickness = 1*mm

        self.TR_count = 10
Exemplo n.º 16
0
    def test_time_interval(self):
        species = sycomore.Species(1000 * ms, 100 * ms, 3 * um**2 / ms)
        model = sycomore.epg.Regular(species,
                                     unit_gradient_area=10 * mT / m * ms)
        model.apply_pulse(47 * deg, 23 * deg)
        model.apply_time_interval(10 * ms, 2 * mT / m)

        self._test_model(model,
                         [[0, 0, 0.6851625292479138], [0, 0, 0],
                          [0.2584947343504123 - 0.6089754314724013j, 0, 0]])

        model.apply_time_interval(10 * ms, -2 * mT / m)
        self._test_model(model, [[
            0.23382875968307784 - 0.5508660366970124j,
            0.23382875968307784 + 0.5508660366970124j, 0.6882952144238884
        ]])
Exemplo n.º 17
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])
Exemplo n.º 18
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)
Exemplo n.º 19
0
def update():
    start = time.time()

    slice_thickness = 1 * mm

    document = bokeh.plotting.curdoc()

    T1 = document.get_model_by_id("T1").value * ms
    T2 = document.get_model_by_id("T2").value * ms

    flip_angle = document.get_model_by_id("flip_angle").value * deg
    TE = document.get_model_by_id("TE").value * ms
    TR = document.get_model_by_id("TR").value * ms

    species = sycomore.Species(T1, T2)
    repetitions = int(4 * species.T1 / TR)

    phase_steps = sycomore.linspace(0 * deg, 180 * deg, 100)

    steady_states = [
        rf_spoiling(sycomore.epg.Regular(species), flip_angle, TE, TR,
                    slice_thickness, phase_step, repetitions)[-1]
        for phase_step in phase_steps
    ]

    magnitude_data = document.get_model_by_id("magnitude_data")
    magnitude_data.data = {
        "x": [x.convert_to(deg) for x in phase_steps],
        "y": [numpy.abs(x) for x in steady_states]
    }

    ideal_spoiling = compute_ideal_spoiling(species, flip_angle, TR)
    ideal_spoiling_data = document.get_model_by_id("ideal_spoiling_data")
    ideal_spoiling_data.data = {
        "x": (phase_steps[0].convert_to(deg), phase_steps[-1].convert_to(deg)),
        "y": (ideal_spoiling, ideal_spoiling)
    }

    stop = time.time()
    document.get_model_by_id("runtime").text = "Runtime: {}".format(
        utils.to_eng_string(stop - start, "s", 3))
Exemplo n.º 20
0
 def test_time_interval(self):
     species = sycomore.Species(1000*ms, 100*ms, 3*um**2/ms)
     model = sycomore.epg.Regular(species, unit_gradient_area=10*mT/m*ms)
     model.apply_pulse(47*deg, 23*deg)
     model.apply_time_interval(10*ms, 2*mT/m)
     
     self._test_model(
         model,  
         [
             [0, 0, 0.6851625292479138],
             [0, 0, 0],
             [0.2584947343504123-0.6089754314724013j, 0, 0]])
     
     model.apply_time_interval(10*ms, -2*mT/m)
     self._test_model(
         model, 
         [
             [
                 0.23262696138115807-0.5480347773241918j, 
                 0.23262696138115807+0.5480347773241918j,
                 0.6882952144238884]])
Exemplo n.º 21
0
def update():
    start = time.time()
    
    slice_thickness = 1*mm
    
    document = bokeh.plotting.curdoc()
    
    T1 = document.get_model_by_id("T1").value*ms
    T2 = document.get_model_by_id("T2").value*ms
    
    flip_angle = document.get_model_by_id("flip_angle").value*deg
    TE = document.get_model_by_id("TE").value*ms
    TR = document.get_model_by_id("TR").value*ms
    phase_step = document.get_model_by_id("phase_step").value*deg
    
    species = sycomore.Species(T1, T2)
    model = sycomore.epg.Regular(species)
    
    repetitions = int(4*species.T1/TR)
    
    echoes = rf_spoiling(
        model, flip_angle, TE, TR, slice_thickness, phase_step, repetitions)
    
    magnitude_data = document.get_model_by_id("magnitude_data")
    magnitude_data.data = {
        "x": range(repetitions), 
        "y": numpy.abs(echoes) }
    
    ideal_spoiling = compute_ideal_spoiling(species, flip_angle, TR)
    ideal_spoiling_data = document.get_model_by_id("ideal_spoiling_data")
    ideal_spoiling_data.data = {
        "x": (0, repetitions), 
        "y": (ideal_spoiling, ideal_spoiling) }
    
    stop = time.time()
    document.get_model_by_id("runtime").text = "Runtime: {}".format(
        utils.to_eng_string(stop-start, "s", 1))
Exemplo n.º 22
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])
Exemplo n.º 23
0
 def test_empty(self):
     species = sycomore.Species(1000*ms, 100*ms)
     model = sycomore.epg.Regular(species)
     
     self._test_model(model, [[0,0,1]])
Exemplo n.º 24
0
def update():
    start = time.time()

    document = bokeh.plotting.curdoc()

    T1 = document.get_model_by_id("T1").value * ms
    T2 = document.get_model_by_id("T2").value * ms

    excitation = document.get_model_by_id("excitation").value * deg
    TE = document.get_model_by_id("TE").value * ms
    refocalization = document.get_model_by_id("refocalization").value * deg
    train_length = document.get_model_by_id("train_length").value
    TR = document.get_model_by_id("TR").value * ms
    repetitions = document.get_model_by_id("repetitions").value

    species = sycomore.Species(T1, T2)

    m0 = [0., 0., 1., 1.]

    voxel_size = 1 * mm
    positions_count = 192

    steps = 1 + int(repetitions * TR / time_step)
    times = sycomore.linspace(0 * s, repetitions * TR, steps)

    excitation = sycomore.bloch.pulse(excitation, 90 * deg)
    refocalization = sycomore.bloch.pulse(refocalization, 0 * rad)

    positions = sycomore.linspace(voxel_size, positions_count)
    gradient = (
        2 * numpy.pi * rad / sycomore.gamma  # T*s
        / voxel_size  # T*s/m
        / (TE / 2))

    time_intervals = numpy.asarray([
        sycomore.bloch.time_interval(species,
                                     time_step,
                                     gradient_amplitude=gradient,
                                     position=position)
        for position in positions
    ])

    magnetizations = numpy.full((positions_count, steps, 4), m0)
    # WARNING: floating-point modulo arithmetic is not reliable (pulses are
    # missed). Switch to integer arithmetic in ms; this assumes that
    # time_step >= 2*ms.
    TE_ms = int(numpy.round(TE.convert_to(ms)))
    TR_ms = int(numpy.round(TR.convert_to(ms)))
    for step, t in enumerate(times[:-1]):

        t_in_TR = int(numpy.round(t.convert_to(ms))) % TR_ms
        t_in_TE = t_in_TR % TE_ms

        if t_in_TR == 0 and step != len(times) - 1:
            pulse = excitation
        elif t_in_TE == TE_ms // 2:
            echo = (t_in_TR - TE_ms // 2) // TE_ms
            if echo < train_length:
                pulse = refocalization
            else:
                pulse = numpy.identity(4)
        else:
            pulse = numpy.identity(4)
        magnetizations[:, step + 1] = numpy.einsum("ij,oj->oi", pulse,
                                                   magnetizations[:, step])
        magnetizations[:,
                       step + 1] = numpy.einsum("oij,oj->oi", time_intervals,
                                                magnetizations[:, step + 1])

    signals = [m[:, 0] + 1j * m[:, 1] for m in magnetizations]
    phases = numpy.angle(signals)

    times_ms = [x.convert_to(ms) for x in times]

    magnitude_data = document.get_model_by_id("magnitude_data")
    magnitude_data.data = {
        "x": times_ms,
        "y": numpy.abs(numpy.mean(signals, axis=0))
    }

    phase_data = document.get_model_by_id("phase_data")
    phase_data.data = {
        "x": times_ms,
        "y_min": numpy.min(phases, axis=0),
        "y_max": numpy.max(phases, axis=0)
    }

    stop = time.time()
    document.get_model_by_id("runtime").text = "Runtime: {}".format(
        utils.to_eng_string(stop - start, "s", 1))
Exemplo n.º 25
0
def update():
    start = time.time()

    slice_thickness = 1 * mm

    document = bokeh.plotting.curdoc()

    pulse_support_size = 101

    T1 = document.get_model_by_id("T1").value * ms
    T2 = document.get_model_by_id("T2").value * ms

    flip_angle = document.get_model_by_id("flip_angle").value * deg
    duration = document.get_model_by_id("duration").value * ms
    zero_crossings = document.get_model_by_id("zero_crossings").value

    t0 = duration / (2 * zero_crossings)

    support = sycomore.linspace(duration, pulse_support_size)
    envelope = sycomore.sinc_envelope(t0)
    bandwidth = 1 / t0

    sinc_pulse = sycomore.HardPulseApproximation(
        sycomore.Pulse(flip_angle, 0 * deg), support, envelope, bandwidth,
        slice_thickness, "")
    gradient_duration = sinc_pulse.get_time_interval().duration
    gradient_amplitude = (sinc_pulse.get_time_interval().gradient_moment[2] /
                          (2 * numpy.pi * sycomore.gamma) /
                          sinc_pulse.get_time_interval().duration)

    species = sycomore.Species(T1, T2)

    model = sycomore.epg.Discrete3D(species)
    for index, hard_pulse in enumerate(sinc_pulse.get_pulses()):
        model.apply_pulse(hard_pulse.angle, hard_pulse.phase)
        model.apply_time_interval(gradient_duration,
                                  [0 * T / m, 0 * T / m, gradient_amplitude])

    # Unfold the F and the Z states: create an array for all orders, including
    # empty ones.
    max_order = numpy.max(model.orders, axis=0)[2]
    max_bin = int(max_order / model.bin_width)
    F = numpy.zeros(2 * max_bin + 1, model.states.dtype)
    Z = numpy.zeros(2 * max_bin + 1, model.states.dtype)
    for order, state in zip(model.orders, model.states):
        bin = int(order[2] / model.bin_width)
        # WARNING: since we de-bin the orders, we need to scale the population
        F[bin] = F.shape[0] * state[0]
        Z[bin] = F.shape[0] * state[2]

        if order != 0:
            F[-bin] = F.shape[0] * state[1].conj()
            Z[-bin] = F.shape[0] * state[2]

    # Perform iFFT, and shift it since the spatial axis must be centered on zero.
    M_transversal = numpy.fft.fftshift(numpy.fft.ifft(F))
    M_longitudinal = numpy.fft.fftshift(numpy.fft.ifft(Z))

    # Frequency ranges from -max_order to +max_order: the spatial step size
    # is then given by the following expression.
    step = (1 / (2 * max_order)).convert_to(mm)

    x_axis = step * numpy.arange(len(M_transversal))
    x_axis -= 0.5 * (x_axis[0] + x_axis[-1])

    # Crop between [-slice_thickness, +slice_thickness]
    slice_ = (
        numpy.searchsorted(x_axis, -slice_thickness.convert_to(mm), "left"),
        numpy.searchsorted(x_axis, +slice_thickness.convert_to(mm), "right"),
    )
    x_axis = x_axis[slice_[0]:slice_[1]]
    M_transversal = M_transversal[slice_[0]:slice_[1]]
    M_longitudinal = M_longitudinal[slice_[0]:slice_[1]]

    transversal_data = document.get_model_by_id("transversal_data")
    transversal_data.data = {"x": x_axis, "y": numpy.abs(M_transversal)}

    longitudinal_data = document.get_model_by_id("longitudinal_data")
    longitudinal_data.data = {"x": x_axis, "y": numpy.abs(M_longitudinal)}

    stop = time.time()
    document.get_model_by_id("runtime").text = "Runtime: {}".format(
        utils.to_eng_string(stop - start, "s", 3))
Exemplo n.º 26
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))
Exemplo n.º 27
0
 def setUp(self):
     self.species = sycomore.Species(1000 * ms, 100 * ms, 3 * um**2 / ms)