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)
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
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