Esempio n. 1
0
def test_one(save_png=False):
    """Perform the first test demonstrating a pi/2 pulse."""
    # create output figure
    fig = plt.figure(figsize=(7, 7))
    ax1 = fig.add_subplot(221)
    ax2 = fig.add_subplot(222, projection='3d')
    ax3 = fig.add_subplot(223)
    ax4 = fig.add_subplot(224, projection='3d')
    # initialize pulse Bloch class
    bloch = pulse(T1=0.001, T2=0.0005, t_sim=0.005)
    # solve
    bloch.solve(m_init=bloch.zunit)
    # create lab-frame plots
    bloch.plot_magnetization(ax1, version='lab')
    bloch.plot_magnetization3d(ax2, version='lab')
    # create rot-frame plots
    bloch.plot_magnetization(ax3, version='rot')
    bloch.plot_magnetization3d(ax4, version='rot')
    # adjust axes position
    low, bot, wid, hei = ax1.get_position().bounds
    ax1.set_position([low, bot * 1.1, wid, hei - 0.05])
    low, bot, wid, hei = ax3.get_position().bounds
    ax3.set_position([low, bot * 1.1, wid, hei - 0.05])
    # adjust titles
    ax1.set_title(r'$^1$H | B0 = {:.1f}$\mu$T'.format(bloch.B0 * 1e6))
    ax2.set_title(r'$\gamma>0$')
    ax3.set_title(r'$^1$H | B1 ~ {:.2f}$\mu$T'.format(bloch.Pulse.factor *
                                                      bloch.B0 * 1e6))
    ax4.set_title(r'$(\pi/2)_{+x}$ - pulse')
    # adjust legends
    ax1.legend(prop={"size": 8}, loc='lower left')
    ax3.legend(prop={"size": 8}, loc='lower right')
    # save figure
    if save_png:
        fig.savefig('example2a.png', dpi=300)
Esempio n. 2
0
def test_four(save_png=False):
    """Perform the fourth test demonstrating different off-resonances.

    here we basically re-plot Fig. 10.28 (p. 255) from
    Levitt, 2008, "spin dynamics" 2nd ed
    positive ratio means the pulse frequency is "higher" as absolute value
    (i.e. instead of -2000 Hz it is -2100 Hz)
    because of the negative Larmor frequency of H-protons the rotation axis
    dips downwards for negative ratios
    """
    # initialize pulse Bloch class
    bloch = pulse(T1=0.001, T2=0.0005, t_sim=0.005)
    # pulse axis
    bloch.Pulse.axis = '+y'
    # df/omega_nut ratio
    ratio = np.arange(-4., 5., 1.)
    # nutation frequency for a pi/2 pulse with 5 ms is 50 Hz
    omega_nut = (np.pi / 2.0) / bloch.Pulse.t_pulse / 2.0 / np.pi  # [Hz]

    # create output figure
    fig = plt.figure(figsize=(7, 7))

    for i in np.arange(len(ratio)):
        # frequency offsets [Hz]
        freq_offset = ratio[i] * omega_nut
        # update frequency offset parameter
        bloch.Pulse.fmod.v_range[1] = freq_offset
        # solve
        bloch.solve(m_init=bloch.zunit)
        # create rot-frame plot
        ax1 = fig.add_subplot(331 + i, projection='3d')
        bloch.plot_magnetization3d(ax1, version='rot')
        ax1.set_title(r'$\Omega_0 / \omega_{{{}}}$ = {}'.format(
            'nut', ratio[i]))

    # save figure
    if save_png:
        fig.savefig('example2d.png', dpi=300)
Esempio n. 3
0
def test_three(save_png=False):
    """Perform the third test demonstrating different pulse axes."""
    # create output figure
    fig = plt.figure(figsize=(7, 7))
    ax1 = fig.add_subplot(221, projection='3d')
    ax2 = fig.add_subplot(222, projection='3d')
    ax3 = fig.add_subplot(223, projection='3d')
    ax4 = fig.add_subplot(224, projection='3d')
    # initialize pulse Bloch class
    bloch = pulse(T1=0.001, T2=0.0005, t_sim=0.005)
    # solve #1
    bloch.solve(m_init=bloch.zunit)
    # create rot-frame plot
    bloch.plot_magnetization3d(ax1, version='rot')
    # solve #2
    bloch.Pulse.axis = '+y'
    bloch.solve(m_init=bloch.zunit)
    # create rot-frame plot
    bloch.plot_magnetization3d(ax2, version='rot')
    # solve #3
    bloch.Pulse.axis = '-x'
    bloch.solve(m_init=bloch.zunit)
    # create rot-frame plot
    bloch.plot_magnetization3d(ax3, version='rot')
    # solve #4
    bloch.Pulse.axis = '-y'
    bloch.solve(m_init=bloch.zunit)
    # create rot-frame plot
    bloch.plot_magnetization3d(ax4, version='rot')

    # adjust titles
    ax1.set_title(r'$(\pi/2)_{+x}$ - pulse')
    ax2.set_title(r'$(\pi/2)_{+y}$ - pulse')
    ax3.set_title(r'$(\pi/2)_{-x}$ - pulse')
    ax4.set_title(r'$(\pi/2)_{-y}$ - pulse')
    # save figure
    if save_png:
        fig.savefig('example2c.png', dpi=300)
Esempio n. 4
0
def test(save_png=False, save_data=False):
    """Perform the lookup table calculation."""
    # LOOKUP TABLE SETTINGS
    # global lookup table settings (change as you like):
    # B1 excitation amplitude [T]
    # in the Grunewald et al., 2016 paper, there are in total 5000 points which
    # would increase the calculation time to more than 10h!
    pulse_num = 1000
    b_pulse = np.logspace(-8, -4, pulse_num)
    # pulse length [s]
    t_pulse = 0.08

    # initialize pulse Bloch class
    bloch = pulse(t_sim=t_pulse)
    # set Larmor freq.
    bloch.larmor_f = -2300

    # pulse type
    bloch.Pulse.pulse_type = 'AHP'
    bloch.Pulse.axis = '+y'
    # frequency modulation
    bloch.Pulse.fmod.mod_type = 'lin'
    bloch.Pulse.fmod.v_range[0] = -200
    bloch.Pulse.fmod.v_range[1] = 0
    # current modulation
    bloch.Pulse.imod.mod_type = 'const'
    bloch.Pulse.imod.qual_fac = 10

    # create output dictionary
    mag_final = np.zeros((pulse_num, 3))
    # loop over all B1 values
    for i_1 in reversed(np.arange(pulse_num)):
        # because the B1 values are given in [T] they need to by divided by
        # B0 because the pulse factor is given in units of [B0]
        bloch.Pulse.factor = b_pulse[i_1] / bloch.B0
        # solve
        bloch.solve(m_init=bloch.zunit, use_numba=True)

        # command line output
        string = '{:d} / {:d}'.format(i_1 + 1, pulse_num)
        print(string)
        # save final magnetization orientation in rotating frame of reference
        mag_final[i_1, :] = bloch.mrot[:, -1]

    # create the output figure
    fig = plt.figure(figsize=(7, 5))
    ax1 = fig.add_subplot(121)
    ax2 = fig.add_subplot(122)

    # plot data
    ax1.plot(mag_final[:, 0], b_pulse * 1e6)
    ax2.plot(mag_final[:, 1], b_pulse * 1e6)
    # adjust axes
    ax1.set_yscale('log')
    ax2.set_yscale('log')
    ax1.set_xlim(-1, 1)
    ax2.set_xlim(-1, 1)
    ax1.set_ylim(b_pulse.min() * 1e6, b_pulse.max() * 1e6)
    ax2.set_ylim(b_pulse.min() * 1e6, b_pulse.max() * 1e6)
    ax1.set_xlabel(r'$M_x/M_0$')
    ax2.set_xlabel(r'$M_y/M_0$')
    ax1.set_ylabel(r'$B_1$ [$\mu T$]')
    ax1.grid(color='lightgray')
    ax2.grid(color='lightgray')

    # save data
    if save_data:
        data = {'B1': b_pulse, 'M': mag_final}
        np.save('example5_lookup-data', data, allow_pickle=True)
    # save figure
    if save_png:
        fig.savefig('example5.png', dpi=300)