Skip to content

Commit ee102d3

Browse files
committed
Finished updates to examples
Finished current round of updates to the example scripts for clarity. Added dynamic variable flip example as well
1 parent 9168267 commit ee102d3

File tree

3 files changed

+114
-22
lines changed

3 files changed

+114
-22
lines changed

examples/demo_C13_multiband.m

Lines changed: 99 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,10 @@
2525
clc
2626

2727
%% multiband pulse
28-
fprintf(1, '\nHere''s a C13 multiband excitation pulse example, for [1-13C]pyr+13C-urea\n');
29-
fprintf(1, 'dynamic MR spectroscopic or chemical shift imaging on a 3T clinical system\n\n');
28+
fprintf(1, '************************************************************\n')
29+
fprintf(1, 'Here''s a C13 multiband excitation pulse example, for [1-13C]pyr+13C-urea\n');
30+
fprintf(1, 'dynamic MR spectroscopic or chemical shift imaging on a 3T clinical system\n');
31+
fprintf(1, '************************************************************\n')
3032
fprintf(1,'Hit any key to continue:\n');
3133
pause;
3234

@@ -70,10 +72,12 @@
7072
pause;
7173

7274
%% multiband pulse - minimum phase
73-
fprintf(1, '\nThis pulse is shortened by using a Minimum-phase spectral filter\n');
75+
fprintf(1, '************************************************************\n')
76+
fprintf(1, 'This pulse is shortened by using a Minimum-phase spectral filter\n');
7477
fprintf(1, 'This may add some phase offset between metabolites and may slightly distort lineshapes\n');
7578
fprintf(1, 'but under most circumstances won''t reduce SNR and allows for shorter TEs\n\n');
76-
fprintf(1, 'Here is the resulting pulse with a linear-phase (which is longer and may have higher peak power)\n\n');
79+
fprintf(1, 'Here is the resulting pulse with a linear-phase (which is longer and may have higher peak power)\n');
80+
fprintf(1, '************************************************************\n')
7781
fprintf(1,'Hit any key to continue:\n');
7882
pause;
7983

@@ -91,12 +95,14 @@
9195
s_ftype = 'min';
9296

9397
%% minimum phase - spectral correction
94-
fprintf(1, '\nThis pulse also is corrected for chemical-shift slice misregistration\n');
98+
fprintf(1, '************************************************************\n')
99+
fprintf(1, 'This pulse also is corrected for chemical-shift slice misregistration\n');
95100
fprintf(1, 'by using the ''Spect Correct'' option.\n');
96101
fprintf(1, 'If the frequency specification bandwidth is too large and/or not sparse, \n');
97102
fprintf(1, 'the spectral correction can fail and/or result in high RF pulse powers.\n\n');
98103
fprintf(1, 'Here is the resulting pulse without spectral correction\n');
99-
fprintf(1, '(the slices for different frequencies are slightly shifted and distorted).\n\n');
104+
fprintf(1, '(the slices for different frequencies are slightly shifted and distorted).\n');
105+
fprintf(1, '************************************************************\n')
100106
fprintf(1,'Hit any key to continue:\n');
101107
pause;
102108

@@ -113,8 +119,10 @@
113119

114120
opt = ss_opt({'Spect Correct', 1});
115121
%% multiband pulse - thicker slice
116-
fprintf(1, '\nIncreasing slice thickness from 5mm to 1cm will allow for a higher\n');
117-
fprintf(1, 'spatial time-bandwidth and a sharper slice profile\n\n');
122+
fprintf(1, '************************************************************\n')
123+
fprintf(1, 'Increasing slice thickness from 5mm to 1cm will allow for a higher\n');
124+
fprintf(1, 'spatial time-bandwidth and a sharper slice profile\n');
125+
fprintf(1, '************************************************************\n')
118126
fprintf(1,'Hit any key to continue:\n');
119127
pause;
120128

@@ -132,9 +140,11 @@
132140

133141
%% short duration pyruvate-lactate pulse
134142

135-
fprintf(1, '\nHere''s a short C13 multiband excitation pulse, for [1-13C]pyr/lac imaging on a 3T clinical system\n');
143+
fprintf(1, '************************************************************\n')
144+
fprintf(1, 'Here''s a short C13 multiband excitation pulse, for [1-13C]pyr/lac imaging on a 3T clinical system\n');
136145
fprintf(1, 'with unspecified flip angles for other metabolites for cancer imaging applications.\n');
137-
fprintf(1, 'This type of design is used in UCSF clinical MRSI studies.\n\n');
146+
fprintf(1, 'This type of design is used in UCSF clinical MRSI studies.\n');
147+
fprintf(1, '************************************************************\n')
138148
fprintf(1,'Hit any key to continue:\n');
139149
pause;
140150

@@ -158,7 +168,7 @@
158168
% create vectors of angles, ripples, and band edges for input to pulse design
159169
[fspec, a_angs, d] = create_freq_specs(mets);
160170
fctr = 0; % force pulse design to optimize for center of frequency specification
161-
s_ftype = 'lin'; % linear-phase spectral filter
171+
s_ftype = 'min'; % linear-phase spectral filter
162172

163173
% SPATIAL PULSE PARAMETERS
164174
z_thk = .5; % thickness (cm)
@@ -171,3 +181,81 @@
171181
ss_design(z_thk, z_tb, [z_d1 z_d2], fspec, a_angs, d, ptype, ...
172182
z_ftype, s_ftype, ss_type, fctr);
173183
set(gcf,'Name', '[1-13C]pyr+lac Simple Multiband');
184+
185+
186+
%% short duration pyruvate-lactate pulse with variable flip angles
187+
188+
fprintf(1, '************************************************************\n')
189+
fprintf(1, 'To improve the SNR for dynamic imaging, the flip angle should be varied over time.\n');
190+
fprintf(1, 'Here is an example to design a set of RF pulses, with identical gradients.\n\n');
191+
fprintf(1, 'and different variable flip angles for pyruvate and lactate.\n');
192+
fprintf(1, '************************************************************\n')
193+
fprintf(1,'Hit any key to continue: (design is slower since a set of pulses)\n');
194+
pause;
195+
196+
clear all; ss_opt([]); ss_globals; % Reset all options
197+
198+
% GENERAL PULSE PARAMETERS
199+
ss_type = 'EP Whole';
200+
ptype = 'ex'; % excitation pulse
201+
opt = ss_opt({'Nucleus', 'Carbon', ...
202+
'Max Duration', 8e-3, ...
203+
'Max B1', 0.5, ...
204+
'Spect Correct', 1});
205+
206+
% SPECTRAL PULSE PARAMETERS
207+
B0 = 3e4; % G
208+
df = 0.5e-6 * B0 * SS_GAMMA; % 0.5 ppm = gamma_C13 * B0 * 0.5e-6
209+
% metabolite frequency (Hz) freq bandwidth (Hz)
210+
mets(1).name = 'pyr'; mets(1).f = -230; mets(1).df = 2*df;
211+
mets(2).name = 'lac'; mets(2).f = 165; mets(2).df = 2*df;
212+
213+
% define variable flip angles
214+
% (see hyperpolarized-mri-toolbox for more info and code on schemes)
215+
TR = 3; N = 16;
216+
kPLest = .05; R1est = [1/35 1/30]; % [T1pyr, T1lac], 1/s
217+
218+
flips = zeros(2,N);
219+
% pyruvate flips for constant signal
220+
% vfa_const_amp(N, pi/2, exp(-TR * (R1(1)+kPL)))
221+
E1 = exp(-TR * (R1est(1)+kPLest));
222+
flips(1,N) = pi/2;
223+
for n = N-1:-1:1
224+
flips(1,n) = atan(E1*sin(flips(1,n+1)));
225+
end
226+
227+
% lactate flips for maximum total SNR
228+
% vfa_opt_signal(N, exp(-TR * R1(2)));
229+
E1 = exp(-TR * R1est(2));
230+
flips(2,:) = acos( sqrt((E1^2-E1.^(2.*(N-[1:N]+1))) ./ (1-E1.^(2*(N-[1:N]+1)))) );
231+
232+
233+
dr = .02; % here ripple is a fraction of the flip angle
234+
235+
for n = 1:length(mets)
236+
fspec(2*n-1) = mets(n).f - mets(n).df;
237+
fspec(2*n) = mets(n).f + mets(n).df;
238+
end
239+
fmid = (mets(1).f+mets(end).f)/2;
240+
fspec = fspec - fmid;
241+
242+
fctr = 0; % force pulse design to optimize for center of frequency specification
243+
s_ftype = 'min'; % linear-phase spectral filter
244+
245+
% SPATIAL PULSE PARAMETERS
246+
z_thk = .5; % thickness (cm)
247+
z_tb = 3; % time-bandwidth, proportional to profile sharpness
248+
z_ftype='ls'; % least-squares filter design
249+
z_d1 = 0.01; z_d2 = 0.01; % slice profile pass and stop-band ripples, respectively
250+
251+
% DESIGN THE PULSE!
252+
[g,rf,fs,z,f,mxy] = ...
253+
ss_design_dyn(z_thk, z_tb, [z_d1 z_d2], fspec, flips, dr, ptype, ...
254+
z_ftype, s_ftype, ss_type, fctr);
255+
256+
% % for saving dynamic pulses:
257+
% for t = 1:N
258+
% ss_save_dyn(g(:,t),rf(:,t),max(flips(:,t)),z_thk, [], 'GE', fspec, flips(:,t), root_fname, t);
259+
% end
260+
261+

examples/demo_general.m

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@
8383
fprintf(1, '\n************************************************************\n')
8484
fprintf(1, 'Here''s an example of a water/fat spectral spatial pulse for 1.5T\n\n');
8585
fprintf(1, 'The pulse is a ''Flyback Half'' type, meaning that it\n');
86-
fprintf(1, 'uses a flyback trajectory, and has a asymmetric frequency\n');
86+
fprintf(1, 'uses a flyback trajectory, and has a symmetric frequency\n');
8787
fprintf(1, 'response.\n');
8888
fprintf(1, 'The frequency spec includes a passband at [%3f,%3f]\n',fspec(3),fspec(4));
8989
fprintf(1, 'and stopbands at [%3f,%3f]\n',fspec(1),fspec(2));
@@ -226,7 +226,8 @@
226226
fprintf(1,'Hit any key to continue:\n');
227227
pause;
228228

229-
opt = ss_opt({'B1 Verse', 0});
229+
opt = ss_opt({'B1 Verse', 0, ...
230+
'Max B1', 0.2});
230231

231232
%%
232233

@@ -252,17 +253,17 @@
252253
fprintf(1, 'The package also allows for echo-planar (''EP'') trajectory designs\n');
253254
fprintf(1, 'which can reduce the pulse duration and allow for thinner slices\n');
254255
fprintf(1, 'but are more sensitive to eddy currents and timing errors.\n');
255-
fprintf(1, 'Here is an example of the original design using a EP trajectory\n');
256-
fprintf(1, 'There is some more ripple in the stopband, but it still meets the spec\n');
256+
fprintf(1, 'Here is an example of a fat-water EP trajectory design\n');
257+
fprintf(1, 'The slice is thinner with less stopband ripple, which the EP trajectory can achieve.\n');
258+
fprintf(1, 'However, with this initial design the ripple specification is not met in the stopband...\n');
257259
fprintf(1, '************************************************************\n');
258260

259261
ss_opt(default_opt);
260-
%opt = ss_opt({'Max B1', 0.4});
261262
ss_type = 'EP Whole';
262263
f_ctr = [];
263-
z_thk = .5;
264264

265-
%d = [0.01 0.005];
265+
z_thk = .5;
266+
d = [0.005 0.005];
266267

267268
[g_ew,rf_ew,fs,z,f,mxy] = ...
268269
ss_design(z_thk, z_tb, [z_d1 z_d2], fspec, a*ang, d, ptype, ...
@@ -298,17 +299,19 @@
298299
fprintf(1, '\n************************************************************\n');
299300
fprintf(1, 'There is a more sophisticated solution....\n');
300301
fprintf(1, 'The ripple arises from the nonuniform sampling in time\n');
301-
fprintf(1, 'that occurs for EP trajectories\n');
302+
fprintf(1, 'that occurs for EP trajectories.\n');
303+
fprintf(1, 'This can be corrected for by using the ''Spect Correct'' option.\n');
302304
fprintf(1, '************************************************************\n');
303305

304306
ss_type = 'EP Whole';
305307
f_ctr = [];
306-
ss_opt({'Spect Correct', 1});
308+
ss_opt({'Spect Correct', 1, ...
309+
'Spect Correct Reg', 0.001}); % small amount of regularization added to better condition spectral correction inversion
310+
307311
[g_fw,rf_fw,fs,z,f,mxy] = ...
308312
ss_design(z_thk, z_tb, [z_d1 z_d2], fspec, a*ang, d, ptype, ...
309313
z_ftype, s_ftype, ss_type, f_ctr, dbg);
310314
set(gcf,'Name', 'Water/Fat EP Whole - Spect Correct');
311315

312-
fprintf(1,'Hit any key to continue:\n');
313-
pause;
316+
314317

ss_design_dyn.m

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,7 @@
543543
for t = [1, round(Nt/2) Nt]
544544
[f_plot,z_plot,m_plot] = ss_plot(g(:,t),rf(:,t),SS_TS, ptype,z_thk*2,bw,...
545545
SS_GAMMA, fmid);
546+
set(gcf, 'Name', ['Pulse #' int2str(t)])
546547
end
547548
end
548549

0 commit comments

Comments
 (0)