standart_RF.py 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. # -*- coding: utf-8 -*-
  2. """
  3. A subroutine functions to create different excitation and refocusing
  4. pulses accompanied by combined SS and spoil gradients.
  5. Requires the params structure as input.
  6. @author: petrm
  7. """
  8. # import
  9. from MRI_sequences.pypulseq.make_sinc_pulse import make_sinc_pulse
  10. from MRI_sequences.pypulseq.make_trapezoid import make_trapezoid
  11. from MRI_sequences.pypulseq.make_extended_trapezoid import make_extended_trapezoid
  12. import numpy as np
  13. # def tse_excitation_grad(params, scanner_parameters, area_gz_spoil, flip180):
  14. #
  15. # return
  16. def refocusing_grad(params, scanner_parameters, gz90_area, flip180, rf180_phase, t_refwd, spoil_duration, united: bool):
  17. # Create 180 degree SS refocusing pulse with SS and spoiled gradients
  18. rf180, gz_ref, _ = make_sinc_pulse(
  19. flip_angle=flip180,
  20. system=scanner_parameters,
  21. duration=params['t_ref'],
  22. slice_thickness=params['sl_thkn'],
  23. apodization=0.5,
  24. time_bw_product=round(params['t_BW_product_ref'], 8),
  25. phase_offset=rf180_phase,
  26. use="refocusing",
  27. return_gz=True,
  28. )
  29. gz180 = make_trapezoid(channel="z", system=scanner_parameters, amplitude=gz_ref.amplitude,
  30. flat_time=t_refwd, rise_time=params['dG'])
  31. # spoil gradient around 180 RF pulse - G_crs
  32. # t_gz_spoil = (np.ceil(params['t_ref'] / 2 / scanner_parameters.grad_raster_time)
  33. # * scanner_parameters.grad_raster_time)
  34. if spoil_duration == 'min':
  35. gz_spoil1 = make_trapezoid(channel='z', system=scanner_parameters, area= gz90_area,
  36. rise_time=params['dG'], flat_time=params['dG'])
  37. gz_spoil2 = make_trapezoid(channel='z', system=scanner_parameters, area= gz90_area,
  38. rise_time=params['dG'], flat_time=params['dG'])
  39. else:
  40. spoil_duration = float(spoil_duration)
  41. spoil_duration = np.ceil(spoil_duration / scanner_parameters.grad_raster_time) * scanner_parameters.grad_raster_time
  42. gz_spoil1 = make_trapezoid(channel='z', system=scanner_parameters, area= gz90_area,
  43. duration=spoil_duration, rise_time=params['dG'])
  44. gz_spoil2 = make_trapezoid(channel='z', system=scanner_parameters, area= gz90_area,
  45. duration=spoil_duration, rise_time=params['dG'])
  46. # SS refocusing gradient with spoilers
  47. gz_sp1_times = np.array(
  48. [
  49. 0,
  50. gz_spoil1.rise_time,
  51. gz_spoil1.rise_time + gz_spoil1.flat_time,
  52. gz_spoil1.rise_time + gz_spoil1.flat_time + gz_spoil1.fall_time
  53. ]
  54. )
  55. gz_sp1_amp = np.array(
  56. [
  57. 0,
  58. gz_spoil1.amplitude,
  59. gz_spoil1.amplitude,
  60. gz180.amplitude
  61. ]
  62. )
  63. gz_sp1 = make_extended_trapezoid(channel='z', system=scanner_parameters, times=gz_sp1_times, amplitudes=gz_sp1_amp)
  64. gz_sp2_times = np.array(
  65. [
  66. 0,
  67. gz180.flat_time
  68. ]
  69. )
  70. gz_sp2_amp = np.array(
  71. [
  72. gz180.amplitude,
  73. gz180.amplitude
  74. ]
  75. )
  76. gz_sp2 = make_extended_trapezoid(channel='z', system=scanner_parameters, times=gz_sp2_times, amplitudes=gz_sp2_amp)
  77. gz_sp3_times = np.array(
  78. [
  79. 0,
  80. gz_spoil2.rise_time,
  81. gz_spoil2.rise_time + gz_spoil2.flat_time,
  82. gz_spoil2.rise_time + gz_spoil2.flat_time + gz_spoil2.fall_time
  83. ]
  84. )
  85. gz_sp3_amp = np.array(
  86. [
  87. gz180.amplitude,
  88. gz_spoil2.amplitude,
  89. gz_spoil2.amplitude,
  90. 0
  91. ]
  92. )
  93. gz_sp3 = make_extended_trapezoid(channel='z', system=scanner_parameters, times=gz_sp3_times, amplitudes=gz_sp3_amp)
  94. if united:
  95. return rf180, gz_sp1, gz_sp2, gz_sp3
  96. else:
  97. return rf180, gz_spoil1, gz180, gz_spoil2
  98. def readout_grad(params, scanner_parameters, spoil_duration, united: bool):
  99. # Create readout gradient
  100. readout_time = round(1 / params['BW_pixel'], 8)
  101. k_read = np.double(params['Nf']) / np.double(params['FoV_f'])
  102. t_gx = np.ceil(readout_time / scanner_parameters.grad_raster_time) * scanner_parameters.grad_raster_time
  103. gx = make_trapezoid(channel='x', system=scanner_parameters, flat_area=k_read,
  104. flat_time=t_gx + 2 * scanner_parameters.adc_dead_time, rise_time=params['dG'])
  105. # generate gx spoiler gradient - G_crr
  106. if spoil_duration == 'min':
  107. gx_spoil = make_trapezoid(channel='x', system=scanner_parameters, area=gx.area,
  108. flat_time=params['dG'], rise_time=params['dG'])
  109. else:
  110. spoil_duration = float(spoil_duration)
  111. spoil_duration = (np.ceil(spoil_duration / scanner_parameters.grad_raster_time)
  112. * scanner_parameters.grad_raster_time)
  113. gx_spoil = make_trapezoid(channel='x', system=scanner_parameters, area=gx.area,
  114. duration=spoil_duration, rise_time=params['dG'])
  115. # readout gradient with spoilers
  116. gx_sp1_times = np.array(
  117. [
  118. 0,
  119. scanner_parameters.grad_raster_time * np.round(
  120. (gx_spoil.rise_time) / scanner_parameters.grad_raster_time),
  121. scanner_parameters.grad_raster_time * np.round(
  122. (gx_spoil.rise_time + gx_spoil.flat_time) / scanner_parameters.grad_raster_time),
  123. scanner_parameters.grad_raster_time * np.round(
  124. (gx_spoil.rise_time + gx_spoil.flat_time + gx_spoil.fall_time) / scanner_parameters.grad_raster_time)
  125. ]
  126. )
  127. gx_sp1_amp = np.array(
  128. [
  129. 0,
  130. gx_spoil.amplitude,
  131. gx_spoil.amplitude,
  132. gx.amplitude
  133. ]
  134. )
  135. gx_sp1 = make_extended_trapezoid(channel='x', system=scanner_parameters, times=gx_sp1_times, amplitudes=gx_sp1_amp)
  136. gx_sp2_times = np.array(
  137. [
  138. 0,
  139. scanner_parameters.grad_raster_time * np.round(
  140. (gx.flat_time) / scanner_parameters.grad_raster_time)
  141. ]
  142. )
  143. gx_sp2_amp = np.array(
  144. [
  145. gx.amplitude,
  146. gx.amplitude
  147. ]
  148. )
  149. gx_sp2 = make_extended_trapezoid(channel='x', system=scanner_parameters, times=gx_sp2_times, amplitudes=gx_sp2_amp)
  150. gx_sp3_times = np.array(
  151. [
  152. 0,
  153. scanner_parameters.grad_raster_time * np.round(
  154. (gx_spoil.rise_time) / scanner_parameters.grad_raster_time),
  155. scanner_parameters.grad_raster_time * np.round(
  156. (gx_spoil.rise_time + gx_spoil.flat_time) / scanner_parameters.grad_raster_time),
  157. scanner_parameters.grad_raster_time * np.round(
  158. (gx_spoil.rise_time + gx_spoil.flat_time + gx_spoil.fall_time) / scanner_parameters.grad_raster_time)
  159. ]
  160. )
  161. gx_sp3_amp = np.array(
  162. [
  163. gx.amplitude,
  164. gx_spoil.amplitude,
  165. gx_spoil.amplitude,
  166. 0
  167. ]
  168. )
  169. gx_sp3 = make_extended_trapezoid(channel='x', system=scanner_parameters, times=gx_sp3_times, amplitudes=gx_sp3_amp)
  170. if united:
  171. return gx_sp1, gx_sp2, gx_sp3, t_gx, gx.area
  172. else:
  173. return gx_spoil, gx, gx_spoil, t_gx, gx.area