def check_mt_sequence():
    """
    Test for the MT sequence.
    """
    w_c = GAMMA['1H'] * B0

    spin_model = SpinModel(s0=100,
                           mc=(1.0, 0.152),
                           w0=((w_c, ) * 2),
                           r1=(1.8, 1.0),
                           r2=(32.2581, 8.4746e4),
                           k=(0.3456, ),
                           approx=(None, 'superlorentz_approx'))

    num_repetitions = 300

    mt_flash_kernel = PulseSequence([
        Delay(10.0e-3),
        Spoiler(1.0),
        Pulse.shaped(40.0e-3, 220.0, 4000, 'gauss', None, w_c + 50.0, 'poly',
                     {'fit_order': 5}),
        Delay(20.0e-3),
        Spoiler(1.0),
        Pulse.shaped(10.0e-6, 90.0, 1, 'rect', None),
        Delay(30.0e-3)
    ],
                                    b0=3.0)
    mt_flash = PulseSequenceRepeated(mt_flash_kernel, num_repetitions)

    signal = mt_flash.signal(spin_model)

    print(mt_flash)
    print(mt_flash.propagator(spin_model))
    print(signal)
Ejemplo n.º 2
0
Archivo: qmt.py Proyecto: norok2/pymrt
 def signal(self, spin_model, *_args, **_kws):
     base_p_ops = self.propagators(spin_model, *_args, **_kws)
     te_p_ops = [
         Delay(t_d).propagator(spin_model, *_args, **_kws)
         for t_d in self._pre_post_delays(self.te, self._t_ro, self._t_pexc)
     ]
     mt_pulse = self.pulses[self._idx['MagnetizationPreparation']]
     f_c = mt_pulse.carrier_freq
     mt_p_ops = [
         mt_pulse.set_carrier_freq(f_c + df).set_flip_angle(fa).propagator(
             spin_model, *_args, **_kws) for df, fa in self.preps
     ]
     central_p_ops_list = [
         self._p_ops_reorder(
             self._p_ops_subst(base_p_ops,
                               self._idx['MagnetizationPreparation'],
                               mt_p_op), self._idx['ReadOut'])
         for mt_p_op in mt_p_ops
     ]
     s_arr = np.array([
         self._signal(
             spin_model,
             self._propagator([te_p_ops[0]] + central_p_ops + [te_p_ops[1]],
                              self.n_r))
         for central_p_ops in central_p_ops_list
     ])
     return s_arr
Ejemplo n.º 3
0
Archivo: qmt.py Proyecto: norok2/pymrt
    def signal(self, spin_model, *_args, **_kws):
        """

        Args:
            spin_model ():
            *_args ():
            **_kws ():

        Returns:

        """
        base_p_ops = self.propagators(spin_model, *_args, **_kws)
        unique_pre_post_delays = set(
            fc.flatten([
                self._pre_post_delays(te, self._get_t_ro(self.duration, tr),
                                      self._t_pexc)
                for df, mfa, fa, tr, tes in self.preps for te in tes
            ]))
        unique_pre_post_p_ops = {
            t_d: Delay(t_d).propagator(spin_model, *_args, **_kws)
            for t_d in unique_pre_post_delays
        }
        mt_pulse = self.pulses[self._idx['MagnetizationPreparation']]
        f_c = mt_pulse.carrier_freq
        unique_mt = set([(df, mfa) for df, mfa, fa, tr, tes in self.preps])
        unique_mt_p_ops = {
            (df, mfa):
            mt_pulse.set_carrier_freq(f_c + df).set_flip_angle(mfa).propagator(
                spin_model, *_args, **_kws)
            for df, mfa in unique_mt
        }
        pexc_pulse = self.pulses[self._idx['PulseExc']]
        unique_pexc = set([fa for df, mfa, fa, tr, tes in self.preps])
        unique_pexc_p_ops = {
            fa:
            pexc_pulse.set_flip_angle(fa).propagator(spin_model, *_args,
                                                     **_kws)
            for fa in unique_pexc
        }
        s_arr = np.array([
            self._signal(
                spin_model,
                self._propagator(
                    [unique_pre_post_p_ops[self._t_pre(te, tr)]] +
                    self._p_ops_reorder(
                        self._p_ops_substs(base_p_ops, (
                            (self._idx['MagnetizationPreparation'],
                             unique_mt_p_ops[(df, mfa)]),
                            (self._idx['PulseExc'], unique_pexc_p_ops[fa]),
                        )), self._idx['ReadOut']) +
                    [unique_pre_post_p_ops[self._t_post(te, tr)]], self.n_r))
            for df, mfa, fa, tr, tes in self.preps for te in tes
        ])
        return spin_model.s0 * s_arr
def check_fit_spin_model(snr_level=20, plot_data=True):
    """
    Test calculation of z-spectra

    Args:
        snr_level (float):
        plot_data (bool):

    Returns:
        None
    """
    w_c = GAMMA['1H'] * B0

    # mt_flash = MtFlash(
    #     PulseList([
    #         Delay(16610.0e-6),
    #         Spoiler(0.0),
    #         Delay(160.0e-6),
    #         PulseExc.shaped(10000.0e-6, 90.0, 0, '_from_GAUSS5120', {},
    #                         0.0, 'poly', {'fit_order': 3}),
    #         Delay(160.0e-6 + 970.0e-6),
    #         Spoiler(1.0),
    #         Delay(160.0e-6),
    #         PulseExc.shaped(100e-6, 11.0, 1, 'rect', {}),
    #         Delay(4900.0e-6)],
    #         w_c=w_c),
    #     300)

    t_e = 1.7e-3
    t_r = 70.0e-3
    w_c = 297220696
    mt_flash = MultiMtSteadyState2(PulseSequence([
        Delay(t_r - (t_e + 3 * 160.0e-6 + 20000.0e-6 + 970.0e-6 + 100e-6)),
        Spoiler(0.0),
        Delay(160.0e-6),
        Pulse.shaped(20000.0e-6, 90.0, 0, '_from_GAUSS5120', {}, 0.0, 'linear',
                     {'num_samples': 15}),
        Delay(160.0e-6 + 970.0e-6),
        Spoiler(1.0),
        Delay(160.0e-6),
        Pulse.shaped(100e-6, 30.0, 1, 'rect', {}),
        Delay(t_e)
    ],
                                                 w_c=w_c),
                                   num_repetitions=100 * 100)

    def mt_signal(x_arr, s0, mc_a, r1a, r2a, r2b, k_ab):
        spin_model = SpinModel(
            s0=s0,
            mc=(mc_a, 1.0 - mc_a),
            w0=(w_c, w_c * (1 - 3.5e-6)),
            # w0=((w_c,) * 2),
            r1=(r1a, 1.0),
            r2=(r2a, r2b),
            k=(k_ab, ),
            approx=(None, 'superlorentz_approx'))
        y_arr = np.zeros_like(x_arr[:, 0])
        i = 0
        for freq, flip_angle in x_arr:
            mt_flash.set_flip_angle(flip_angle)
            mt_flash.set_freq(freq)
            y_arr[i] = mt_flash.signal(spin_model)
            i += 1
        return y_arr

    # simulate a measurement
    freqs = np.geomspace(100.0, 300.0e3, 32)
    flip_angles = np.linspace(1.0, 1100.0, 32)

    x_data = np.array(tuple(itertools.product(freqs, flip_angles)))

    # see: mt_signal
    p_e = 100, 0.8681, 2.0, 32.2581, 8.4746e4, 0.3456
    exact = mt_signal(x_data, *p_e).reshape((len(freqs), len(flip_angles)))
    # num = len(freqs) * len(flip_angles)
    # noise = (np.random.rand(*exact.shape) - 0.5) * np.max(exact) / snr_level
    # measured = exact + noise
    #
    # p0 = 100, 0.5, 5.0, 20.0, 5e4, 0.5
    # bounds = [[50, 1000], [0, 1], [0.1, 10], [10, 50], [1e4, 1e5], [0, 1]]
    # y_data = measured.ravel()
    #
    # def sum_of_squares(params, x_data, m_data):
    #     e_data = mt_signal(x_data, *params)
    #     return np.sum((m_data - e_data) ** 2.0)
    #
    # res = scipy.optimize.minimize(
    #     sum_of_squares, p0, args=(x_data, y_data), method='L-BFGS-B',
    #     bounds=bounds, options={'gtol': 1e-05, 'ftol': 2e-09})
    # print(res.x, res.success, res.message)
    #
    # fitted = mt_signal(x_data, *res.x).reshape(measured.shape)

    # # faked fitted
    # fitted = mt_signal(x_data, *p0).reshape(measured.shape)

    if plot_data:
        X, Y = np.meshgrid(flip_angles, fc.sgnlog(freqs, 10.0))
        fig = plt.figure()
        ax = fig.add_subplot(111, projection='3d')
        ax.set_xlabel('Pulse Amplitude (flip angle) / deg')
        ax.set_ylabel('Frequency offset / Hz (log10 scale)')
        ax.set_zlabel('Signal Intensity / arb. units')
        ax.plot_surface(X,
                        Y,
                        exact,
                        cmap=plt.cm.hot,
                        rstride=1,
                        cstride=1,
                        linewidth=0.005,
                        antialiased=False)
def check_z_spectrum_sparse(spin_model=SpinModel(s0=1e8,
                                                 mc=(0.8681, 0.1319),
                                                 w0=((GAMMA['1H'] * 7.0, ) *
                                                     2),
                                                 r1=(1.8, 1.0),
                                                 r2=(32.2581, 8.4746e4),
                                                 k=(0.3456, ),
                                                 approx=(
                                                     None,
                                                     'superlorentz_approx')),
                            frequencies=np.round(np.geomspace(50, 10000, 32)),
                            amplitudes=np.round(np.linspace(1, 5000, 24)),
                            plot_data=True,
                            save_file=None):
    """
    Test calculation of z-spectra

    Args:

        spin_model (SpinModel):
        frequencies (ndarray[float]):
        amplitudes (ndarray[float]):
        plot_data (bool):
        save_file (string):

    Returns:
        freq

    """
    print('Checking Z-spectrum (sparse)')
    w_c = spin_model.w0[0]

    flip_angles = amplitudes * 11.799 / 50.0

    my_seq = MultiMtVarMGESS(pulses=[
        MagnetizationPreparation.shaped(10.0e-3, 90.0, 4000, 'gauss', {}, w_c,
                                        'poly', {'fit_order': 3}),
        Delay(1.0e-3),
        Spoiler(1.0),
        PulseExc.shaped(2.1e-3, 15.0, 1, 'rect', {}),
        ReadOut(),
        Spoiler(1.0),
    ],
                             tes=5.0e-3,
                             tr=70.0e-3,
                             n_r=300,
                             w_c=w_c,
                             preps=[(
                                 df,
                                 mfa,
                             ) for df in frequencies for mfa in flip_angles])
    data = my_seq.signal(spin_model).reshape(
        (len(frequencies), len(flip_angles)))

    # plot results
    if plot_data:
        sns.set_style('whitegrid')
        X, Y = np.meshgrid(flip_angles, np.log10(frequencies))
        fig = plt.figure()
        ax = fig.add_subplot(111, projection='3d')
        ax.set_xlabel('Pulse Amplitude (flip angle) / deg')
        ax.set_ylabel('Frequency offset / Hz (log10 scale)')
        ax.set_zlabel('Signal Intensity / arb. units')
        ax.plot_surface(X,
                        Y,
                        data,
                        cmap=mpl.cm.plasma,
                        rstride=1,
                        cstride=1,
                        linewidth=0.01,
                        antialiased=False)
    if save_file:
        np.savez(save_file, frequencies, amplitudes, data)
    return data, frequencies, flip_angles