3D RF spoiled gradient echo imaging
Image matrix = 256 x 256 x 32, TR = 18 ms, TE = 10 ms, flip angle = 30 degree, subvoxel = s x 1 x 1 (s = 1 – 16), calculation time = 771.94 s for sv = 16, number of subvoxels = 54,577,152 for sv = 16.
Amplitude of artifact vs number of subvoxels. Artifact has local minima for s = power of 2.
Python sequence code:
from psdk import * import numpy as np gamma = 42.57747892 # [MHz/T] TR = 18.0e+3 # [us] TE = 10.0e+3 # [us] NR = 256 # Number of readout points NPE1 = 256 # Number of 1st phase encoding NPE2 = 32 # Number of 2nd phase encoding fov = [256.0, 256.0, 256.0] # [mm] dwell_time = 10.0 # [us] gx_value = 1e+6 / (dwell_time * gamma * fov[0]) # [mT/m] gy_value = 2e+6 / (dwell_time * gamma * fov[1]) * NPE1 / NR # [mT/m] gz_value = 2e+6 / (dwell_time * gamma * fov[2]) * NPE2 / NR # [mT/m] gx_rise_time = 300.0 # [us] gy_rise_time = 300.0 # [us] gz_rise_time = 300.0 # [us] excitation_pulse_width = 100.0 # [us] excitation_pulse_flip_angle = 30.0 # [degree] excitation_pulse_value = excitation_pulse_flip_angle / (360.0e-6 * gamma * excitation_pulse_width) # [uT] def phase_shift_angle(i): phi = i * (i + 1) / 2 * 117 / 360 phi -= round(phi) return 2.0 * np.pi * phi with Sequence('3D SPGR'): with Block('Excitation', excitation_pulse_width): RF(0.0, [excitation_pulse_value] * 10, excitation_pulse_width / 10, phase=([phase_shift_angle(i) for i in range(NPE1 * NPE2)], ['PE2', 'PE1'])) with Block('PhaseEncoding', NR // 2 * dwell_time + gx_rise_time * 2.5): GX(0.0, -gx_value, gx_rise_time) GY(0.0, ([gy_value * (i - NPE1 // 2) / NPE1 for i in range(NPE1)], ['PE1']), gy_rise_time) GZ(0.0, ([gz_value * (i - NPE2 // 2) / NPE2 for i in range(NPE2)], ['PE2']), gy_rise_time) GY(NR // 2 * dwell_time, 0.0, gy_rise_time) GZ(NR // 2 * dwell_time, 0.0, gz_rise_time) GX(NR // 2 * dwell_time + gx_rise_time * 0.5, gx_value, gx_rise_time * 2.0) with Block('Readout', NR * dwell_time): AD(0.0, NR, dwell_time, phase=([phase_shift_angle(i) for i in range(NPE1 * NPE2)], ['PE2', 'PE1'])) with Block('Rewinding', NR // 2 * dwell_time + gx_rise_time * 2.5): GY(gx_rise_time * 2.5 - gy_rise_time, ([gy_value * (NPE1 // 2 - i) / NPE1 for i in range(NPE1)], ['PE1']), gy_rise_time) GZ(gx_rise_time * 2.5 - gz_rise_time, ([gz_value * (NPE2 // 2 - i) / NPE2 for i in range(NPE2)], ['PE2']), gz_rise_time) GX(NR // 2 * dwell_time + gx_rise_time * 2.5 - gx_rise_time, 0.0, gx_rise_time) GY(NR // 2 * dwell_time + gx_rise_time * 2.5 - gy_rise_time, 0.0, gy_rise_time) GZ(NR // 2 * dwell_time + gx_rise_time * 2.5 - gz_rise_time, 0.0, gz_rise_time) with Main(): with Loop('PE2', NPE2): with Loop('PE1', NPE1): BlockRef('Excitation') WaitUntil(TE - NR // 2 * 2 * dwell_time - gx_rise_time * 2.5 + excitation_pulse_width * 0.5) BlockRef('PhaseEncoding') BlockRef('Readout') BlockRef('Rewinding') WaitUntil(TR)