| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155 |
- from math import pi
- import numpy as np
- import pypulseq as pp
- Nx = 256
- Ny = 256
- Nz = 32
- system = pp.Opts(
- max_grad=32,
- grad_unit="mT/m",
- max_slew=130,
- slew_unit="T/m/s",
- grad_raster_time=10e-6,
- rf_ringdown_time=10e-6,
- rf_dead_time=100e-6,
- )
- seq = pp.Sequence(system)
- fov = 256e-3
- fov_z = 256e-3
- slice_thickness = 1e-3
- section_thickness = 5e-3
- # =========
- # RF preparatory, excitation
- # =========
- flip_exc = 12 * pi / 180
- rf = pp.make_block_pulse(
- flip_angle=flip_exc, system=system, duration=250e-6, time_bw_product=4
- )
- flip_prep = 90 * pi / 180
- rf_prep = pp.make_block_pulse(
- flip_angle=flip_prep, system=system, duration=500e-6, time_bw_product=4
- )
- # =========
- # Readout
- # =========
- delta_k = 1 / fov
- k_width = Nx * delta_k
- readout_time = 3.5e-3
- gx = pp.make_trapezoid(
- channel="x", system=system, flat_area=k_width, flat_time=readout_time
- )
- adc = pp.make_adc(num_samples=Nx, duration=gx.flat_time, delay=gx.rise_time)
- # =========
- # Prephase and Rephase
- # =========
- delta_kz = 1 / fov_z
- phase_areas = (np.arange(Ny) - (Ny / 2)) * delta_k
- slice_areas = (np.arange(Nz) - (Nz / 2)) * delta_kz
- gx_pre = pp.make_trapezoid(channel="x", system=system, area=-gx.area / 2, duration=2e-3)
- gy_pre = pp.make_trapezoid(
- channel="y", system=system, area=phase_areas[-1], duration=2e-3
- )
- # =========
- # Spoilers
- # =========
- pre_time = 6.4e-4
- gx_spoil = pp.make_trapezoid(
- channel="x",
- system=system,
- area=(4 * np.pi) / (42.576e6 * delta_k * 1e-3) * 42.576e6,
- duration=pre_time * 6,
- )
- gy_spoil = pp.make_trapezoid(
- channel="y",
- system=system,
- area=(4 * np.pi) / (42.576e6 * delta_k * 1e-3) * 42.576e6,
- duration=pre_time * 6,
- )
- gz_spoil = pp.make_trapezoid(
- channel="z",
- system=system,
- area=(4 * np.pi) / (42.576e6 * delta_kz * 1e-3) * 42.576e6,
- duration=pre_time * 6,
- )
- # =========
- # Extended trapezoids: gx, gx_spoil
- # =========
- t_gx_extended = np.array(
- [0, gx.rise_time, gx.flat_time, (gx.rise_time * 2) + gx.flat_time + gx.fall_time]
- )
- amp_gx_extended = np.array([0, gx.amplitude, gx.amplitude, gx_spoil.amplitude])
- t_gx_spoil_extended = np.array(
- [
- 0,
- gx_spoil.rise_time + gx_spoil.flat_time,
- gx_spoil.rise_time + gx_spoil.flat_time + gx_spoil.fall_time,
- ]
- )
- amp_gx_spoil_extended = np.array([gx_spoil.amplitude, gx_spoil.amplitude, 0])
- gx_extended = pp.make_extended_trapezoid(
- channel="x", times=t_gx_extended, amplitudes=amp_gx_extended
- )
- gx_spoil_extended = pp.make_extended_trapezoid(
- channel="x", times=t_gx_spoil_extended, amplitudes=amp_gx_spoil_extended
- )
- # =========
- # Delays
- # =========
- TE, TI, TR, T_recovery = 4e-3, 140e-3, 10e-3, 1e-3
- delay_TE = (
- TE - pp.calc_duration(rf) / 2 - pp.calc_duration(gx_pre) - pp.calc_duration(gx) / 2
- )
- delay_TI = TI - pp.calc_duration(rf_prep) / 2 - pp.calc_duration(gx_spoil)
- delay_TR = (
- TR
- - pp.calc_duration(rf)
- - pp.calc_duration(gx_pre)
- - pp.calc_duration(gx)
- - pp.calc_duration(gx_spoil)
- )
- for i in range(Ny):
- gy_pre = pp.make_trapezoid(
- channel="y", system=system, area=phase_areas[i], duration=2e-3
- )
- seq.add_block(rf_prep)
- seq.add_block(gx_spoil, gy_spoil, gz_spoil)
- seq.add_block(pp.make_delay(delay_TI))
- for j in range(Nz):
- gz_pre = pp.make_trapezoid(
- channel="z", system=system, area=slice_areas[j], duration=2e-3
- )
- gz_reph = pp.make_trapezoid(
- channel="z", system=system, area=-slice_areas[j], duration=2e-3
- )
- seq.add_block(rf)
- seq.add_block(gx_pre, gy_pre, gz_pre)
- # Skip TE: readout_time = 3.5e3 --> TE = -2.168404344971009e-19
- # seq.add_block(pp.make_delay(delay_TE))
- seq.add_block(gx_extended, adc)
- seq.add_block(gx_spoil_extended, gz_reph)
- seq.add_block(pp.make_delay(delay_TR))
- seq.add_block(pp.make_delay(T_recovery))
- seq.set_definition(key="Name", value="3D T1 MPRAGE")
- seq.write("256_3d_t1_mprage_pypulseq.seq")
- # seq.plot(time_range=(0, TI + TR + 2e-3))
|