t_refwd = t_ref + system.rf_ringdown_time + system.rf_dead_time t_sp = 0.5 * (TE - readout_time - t_refwd) t_spex = 0.5 * (TE - t_exwd - t_refwd) fsp_r = 1 fsp_s = 0.5 rf_ex_phase = np.pi / 2 rf_ref_phase = 0 # ====== # CREATE EVENTS # ====== flip_ex = 90 * np.pi / 180 rf_ex, gz, _ = pp.make_sinc_pulse(flip_angle=flip_ex, system=system, duration=t_ex, slice_thickness=slice_thickness, apodization=0.5, time_bw_product=4, phase_offset=rf_ex_phase, return_gz=True) gs_ex = pp.make_trapezoid(channel='z', system=system, amplitude=gz.amplitude, flat_time=t_exwd, rise_time=dG) flip_ref = rf_flip[0] * np.pi / 180 rf_ref, gz, _ = pp.make_sinc_pulse(flip_angle=flip_ref, system=system, duration=t_ref, slice_thickness=slice_thickness, apodization=0.5, time_bw_product=4, phase_offset=rf_ref_phase, use='refocusing', return_gz=True) gs_ref = pp.make_trapezoid(channel='z', system=system, amplitude=gs_ex.amplitude, flat_time=t_refwd, rise_time=dG) ags_ex = gs_ex.area / 2 gs_spr = pp.make_trapezoid(channel='z', system=system, area=ags_ex * (1 + fsp_s), duration=t_sp, rise_time=dG) gs_spex = pp.make_trapezoid(channel='z', system=system, area=ags_ex * fsp_s, duration=t_spex, rise_time=dG) delta_k = 1 / fov k_width = Nx * delta_k gr_acq = pp.make_trapezoid(channel='x', system=system, flat_area=k_width, flat_time=readout_time, rise_time=dG)
# Set system limits system = pp.Opts(max_grad=32, grad_unit='mT/m', max_slew=130, slew_unit='T/m/s', rf_ringdown_time=30e-6, rf_dead_time=100e-6, adc_dead_time=20e-6) # ====== # CREATE EVENTS # ====== # Create 90 degree slice selection pulse and gradient rf, gz, _ = pp.make_sinc_pulse(flip_angle=np.pi / 2, system=system, duration=3e-3, slice_thickness=3e-3, apodization=0.5, time_bw_product=4, return_gz=True) # Define other gradients and ADC events delta_k = 1 / fov k_width = Nx * delta_k readout_time = 3.2e-4 gx = pp.make_trapezoid(channel='x', system=system, flat_area=k_width, flat_time=readout_time) adc = pp.make_adc(num_samples=Nx, system=system, duration=gx.flat_time, delay=gx.rise_time) # Pre-phasing gradients pre_time = 8e-4 gz_reph = pp.make_trapezoid(channel='z', system=system, area=-gz.area / 2, duration=pre_time) # Do not need minus for in-plane prephasers because of the spin-echo (position reflection in k-space) gx_pre = pp.make_trapezoid(channel='x', system=system, area=gx.area / 2 - delta_k / 2, duration=pre_time) gy_pre = pp.make_trapezoid(channel='y', system=system, area=Ny / 2 * delta_k, duration=pre_time) # Phase blip in shortest possible time dur = math.ceil(2 * math.sqrt(delta_k / system.max_slew) / 10e-6) * 10e-6 gy = pp.make_trapezoid(channel='y', system=system, area=delta_k, duration=dur) # Refocusing pulse with spoiling gradients rf180 = pp.make_block_pulse(flip_angle=np.pi, system=system, duration=500e-6, use='refocusing')
slice_thickness=slice_thickness, apodization=0.5, time_bw_product=2, center_pos=1, system=system, return_gz=True) # Align RO asymmetry to ADC samples Nxo = np.round(ro_os * Nx) ro_asymmetry = np.round(ro_asymmetry * Nxo / 2) / Nxo * 2 # Define other gradients and ADC events delta_k = 1 / fov / (1 + ro_asymmetry) ro_area = Nx * delta_k gx = pp.make_trapezoid(channel='x', flat_area=ro_area, flat_time=ro_duration, system=system) adc = pp.make_adc(num_samples=Nxo, duration=gx.flat_time, delay=gx.rise_time, system=system) adc.delay = adc.delay - 0.5 * adc.dwell # compensate for the 0.5 samples shift gx_pre = pp.make_trapezoid(channel='x', area=-(gx.area - ro_area) / 2 - ro_area / 2 * (1 - ro_asymmetry), system=system) # Gradient spoiling gx_spoil = pp.make_trapezoid(channel='x', area=0.2 * Nx * delta_k, system=system)
return_gz=True, time_bw_product=tb, rf_freq=0) else: rf, gz, gzr = pp.make_sinc_pulse(flip_angle=alpha * math.pi / 180, duration=duration, slice_thickness=slice_thickness, apodization=0.5, time_bw_product=tb, system=system, return_gz=True) # Define other gradients and ADC events delta_k = 1 / fov gx = pp.make_trapezoid(channel='x', flat_area=Nx * delta_k, flat_time=3.2e-3, system=system) adc = pp.make_adc(num_samples=Nx, duration=gx.flat_time, delay=gx.rise_time, system=system) gx_pre = pp.make_trapezoid(channel='x', area=-gx.area / 2, duration=1e-3, system=system) gz_reph = pp.make_trapezoid(channel='z', area=-gz.area / 2, duration=1e-3, system=system) phase_areas = (np.arange(Ny) - Ny / 2) * delta_k
spoil_factor = 1.5 # Spoiling gradient around the pi-pulse (rf180) # Set system limits system = pp.Opts(max_grad=32, grad_unit='mT/m', max_slew=130, slew_unit='T/m/s', rf_ringdown_time=30e-6, rf_dead_time=100e-6) # ====== # CREATE EVENTS # ====== # Create fat-sat pulse B0 = 2.89 sat_ppm = -3.45 sat_freq = sat_ppm * 1e-6 * B0 * system.gamma rf_fs = pp.make_gauss_pulse(flip_angle=110 * np.pi / 180, system=system, duration=8e-3, bandwidth=abs(sat_freq), freq_offset=sat_freq) gz_fs = pp.make_trapezoid(channel='z', system=system, delay=pp.calc_duration(rf_fs), area=1 / 1e-4) # Create 90 degree slice selection pulse and gradient rf, gz, gz_reph = pp.make_sinc_pulse(flip_angle=np.pi / 2, system=system, duration=t_RF_ex, slice_thickness=slice_thickness, apodization=0.5, time_bw_product=4, return_gz=True) # Create 90 degree slice refocusing pulse and gradients rf180, gz180, _ = pp.make_sinc_pulse(flip_angle=np.pi, system=system, duration=t_RF_ref, slice_thickness=slice_thickness, apodization=0.5, time_bw_product=4, phase_offset=np.pi / 2, use='refocusing', return_gz=True) _, gzr1_t, gzr1_a = pp.make_extended_trapezoid_area(channel='z', Gs=0, Ge=gz180.amplitude, A=spoil_factor * gz.area, system=system) _, gzr2_t, gzr2_a = pp.make_extended_trapezoid_area(channel='z', Gs=gz180.amplitude, Ge=0, A=-gz_reph.area + spoil_factor * gz.area, system=system) if gz180.delay > (gzr1_t[3] - gz180.rise_time):