1% step
2% 0 ... Basic sequence
3% 1 ... Add spoiler in read, phase and slice (vary spoiler - line 49)
4% 2 ... Refocus in phase
5% 3 ... Vary RF phase quasi-randomly
6% 4 ... Make receiver phase follow transmitter phase
7% 5 ... Add dummy scans
8step = 0;
10% Define FOV and resolution
11fov = 256e-3;
12sliceThickness = 5e-3;
13Nx = 128;
14Ny = Nx;
16% Define sequence parameters
17TE = 8e-3;
18TR = 16e-3;
19alpha=30;
21% set system limits
22sys = mr.opts('MaxGrad',20,'GradUnit','mT/m',...
23 'MaxSlew',120,'SlewUnit','T/m/s',...
24 'rfRingdownTime', 20e-6, 'rfDeadtime', 100e-6);
26% Create a new sequence object
27seq=mr.Sequence(sys);
29% Create slice selective alpha-pulse and corresponding gradients
30[rf, gz, gzReph] = mr.makeSincPulse(alpha*pi/180, 'Duration', 4e-3,...
31 'SliceThickness', sliceThickness, 'apodization', 0.5,'timeBwProduct', 4, ...
32 'system' ,sys,...
33 'use', 'excitation');
35% Define other gradients and ADC events
36deltak = 1/fov; % Pulseq toolbox defaults to k-space units of m^-1
37gx = mr.makeTrapezoid('x', 'FlatArea', Nx*deltak, 'FlatTime', 6.4e-3);
38adc = mr.makeAdc(Nx, 'Duration', gx.flatTime, 'Delay', gx.riseTime);
39gxPre = mr.makeTrapezoid('x', 'Area', -gx.area/2, 'Duration', 2e-3);
40phaseAreas = ((0:Ny-1)-Ny/2)*deltak;
43% Calculate timing
44delayTE = round((TE - mr.calcDuration(gxPre) - mr.calcDuration(gz)/2 ...
45 - mr.calcDuration(gx)/2)/seq.gradRasterTime)*seq.gradRasterTime;
46delayTR = round((TR - mr.calcDuration(gxPre) - mr.calcDuration(gz) ...
47 - mr.calcDuration(gx) - delayTE)/seq.gradRasterTime)*seq.gradRasterTime;
49if step > 0
50 spoilArea=4*gx.area(); % 4 "looks" good
51 % Add spoilers in read, refocus in phase and spoiler in slice
52 gxPost = mr.makeTrapezoid('x', 'Area', spoilArea, 'system', sys); % we pass 'system' here to calculate shortest time gradient
53 gyPost = mr.makeTrapezoid('y', 'Area', spoilArea, 'system', sys);
54 gzPost = mr.makeTrapezoid('z', 'Area', spoilArea, 'system', sys);
55end
57if step > 1
58 gyPost = mr.makeTrapezoid('y', 'Area', -max(phaseAreas(:)), 'Duration', 2e-3);
59end
61if step > 0
62 delayTR = delayTR - mr.calcDuration(gxPost, gyPost, gzPost);
63end
65if step > 4
66 start = -30; % dummy scans
67else
68 start = 1;
69end
70% Loop over phase encodes and define sequence blocks
71for i=start:Ny
72 if step > 2
73 % Vary RF phase quasi-randomly
74 % RF spoiling phase increment = 84° for smoother transient decay, https://doi.org/10.1002/mrm.1910350216, 169° for diffusion independent rf spoiling in steady-state https://doi.org/10.1371/journal.pone.0324455
75 rand_phase = mod(84*(i^2 + i + 2), 360)*pi/180;
76 [rf, gz] = mr.makeSincPulse(alpha*pi/180, 'Duration', 4e-3,...
77 'SliceThickness', 5e-3, ...
78 'apodization', 0.5, ...
79 'timeBwProduct', 4, ...
80 'system', sys, ...
81 'phaseOffset', rand_phase);
82 end
83 seq.addBlock(rf, gz);
84 if (i>0) % negative or zero index -- dummy scans
85 gyPre = mr.makeTrapezoid('y', 'Area', phaseAreas(i), 'Duration', 2e-3);
86 else
87 gyPre = mr.makeTrapezoid('y', 'Area', 0, 'Duration', 2e-3);
88 end
89 seq.addBlock(gxPre, gyPre, gzReph);
90 seq.addBlock(mr.makeDelay(delayTE));
91 if step > 3
92 % Make receiver phase follow transmitter phase
93 adc = mr.makeAdc(Nx, 'Duration', gx.flatTime,...
94 'Delay', gx.riseTime,...
95 'phaseOffset', rand_phase);
96 end
97 if (i>0) % negative index -- dummy scans
98 seq.addBlock(gx, adc);
99 else
100 seq.addBlock(gx);
101 end
102 if step > 1
103 gyPost = mr.makeTrapezoid('y', 'Area', -gyPre.area, 'Duration', 2e-3);
104 end
105 if step > 0
106 % Add spoilers in read and slice and may be in phase
107 seq.addBlock(gxPost, gyPost, gzPost);
108 end
109 seq.addBlock(mr.makeDelay(delayTR));
110end
112% check whether the timing of the sequence is correct
113[ok, error_report]=seq.checkTiming;
115if (ok)
116 fprintf('Timing check passed successfully\n');
117else
118 fprintf('Timing check failed! Error listing follows:\n');
119 fprintf([error_report{:}]);
120 fprintf('\n');
121end
123% export definitions
124seq.setDefinition('FOV', [fov fov sliceThickness]);
125seq.setDefinition('Name', ['DEMO_gre' num2str(step)]);
127seq.write(['DEMO_gre' num2str(step) '.seq']) % Write to pulseq file