write_2Dt1_mprage.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. from math import pi
  2. import numpy as np
  3. import pypulseq as pp
  4. Nx = 128
  5. Ny = 128
  6. n_slices = 3
  7. system = pp.Opts(
  8. max_grad=32,
  9. grad_unit="mT/m",
  10. max_slew=130,
  11. slew_unit="T/m/s",
  12. grad_raster_time=10e-6,
  13. rf_ringdown_time=10e-6,
  14. rf_dead_time=100e-6,
  15. )
  16. seq = pp.Sequence(system)
  17. fov = 220e-3
  18. slice_thickness = 5e-3
  19. slice_gap = 15e-3
  20. delta_z = n_slices * slice_gap
  21. rf_offset = 0
  22. z = np.linspace((-delta_z / 2), (delta_z / 2), n_slices) + rf_offset
  23. # =========
  24. # RF90, RF180
  25. # =========
  26. flip = 12 * pi / 180
  27. rf, gz, _ = pp.make_sinc_pulse(
  28. flip_angle=flip,
  29. system=system,
  30. duration=2e-3,
  31. slice_thickness=slice_thickness,
  32. apodization=0.5,
  33. time_bw_product=4,
  34. return_gz=True,
  35. )
  36. flip90 = 90 * pi / 180
  37. rf90 = pp.make_block_pulse(
  38. flip_angle=flip90, system=system, duration=500e-6, time_bw_product=4
  39. )
  40. # =========
  41. # Readout
  42. # =========
  43. delta_k = 1 / fov
  44. k_width = Nx * delta_k
  45. readout_time = 6.4e-3
  46. gx = pp.make_trapezoid(
  47. channel="x", system=system, flat_area=k_width, flat_time=readout_time
  48. )
  49. adc = pp.make_adc(num_samples=Nx, duration=gx.flat_time, delay=gx.rise_time)
  50. # =========
  51. # Prephase and Rephase
  52. # =========
  53. phase_areas = (np.arange(Ny) - (Ny / 2)) * delta_k
  54. gy_pre = pp.make_trapezoid(
  55. channel="y", system=system, area=phase_areas[-1], duration=2e-3
  56. )
  57. gx_pre = pp.make_trapezoid(channel="x", system=system, area=-gx.area / 2, duration=2e-3)
  58. gz_reph = pp.make_trapezoid(
  59. channel="z", system=system, area=-gz.area / 2, duration=2e-3
  60. )
  61. # =========
  62. # Spoilers
  63. # =========
  64. pre_time = 8e-4
  65. gx_spoil = pp.make_trapezoid(
  66. channel="x", system=system, area=gz.area * 4, duration=pre_time * 4
  67. )
  68. gy_spoil = pp.make_trapezoid(
  69. channel="y", system=system, area=gz.area * 4, duration=pre_time * 4
  70. )
  71. gz_spoil = pp.make_trapezoid(
  72. channel="z", system=system, area=gz.area * 4, duration=pre_time * 4
  73. )
  74. # =========
  75. # Delays
  76. # =========
  77. TE, TI, TR = 13e-3, 140e-3, 65e-3
  78. delay_TE = (
  79. TE - pp.calc_duration(rf) / 2 - pp.calc_duration(gy_pre) - pp.calc_duration(gx) / 2
  80. )
  81. delay_TE = pp.make_delay(delay_TE)
  82. delay_TI = TI - pp.calc_duration(rf90) / 2 - pp.calc_duration(gx_spoil)
  83. delay_TI = pp.make_delay(delay_TI)
  84. delay_TR = (
  85. TR
  86. - pp.calc_duration(rf) / 2
  87. - pp.calc_duration(gx) / 2
  88. - pp.calc_duration(gy_pre)
  89. - TE
  90. )
  91. delay_TR = pp.make_delay(delay_TR)
  92. for j in range(n_slices):
  93. freq_offset = gz.amplitude * z[j]
  94. rf.freq_offset = freq_offset
  95. for i in range(Ny):
  96. seq.add_block(rf90)
  97. seq.add_block(gx_spoil, gy_spoil, gz_spoil)
  98. seq.add_block(delay_TI)
  99. seq.add_block(rf, gz)
  100. gy_pre = pp.make_trapezoid(
  101. channel="y", system=system, area=phase_areas[i], duration=2e-3
  102. )
  103. seq.add_block(gx_pre, gy_pre, gz_reph)
  104. seq.add_block(delay_TE)
  105. seq.add_block(gx, adc)
  106. gy_pre = pp.make_trapezoid(
  107. channel="y", system=system, area=-phase_areas[i], duration=2e-3
  108. )
  109. seq.add_block(gx_spoil, gy_pre)
  110. seq.add_block(delay_TR)
  111. seq.set_definition(key="Name", value="2D T1 MPRAGE")
  112. seq.write("2d_mprage_pypulseq.seq")