Skip to content

Commit

Permalink
Squashed 'RF_pulses/spectral_spatial/' changes from ee102d3..a21f1ba
Browse files Browse the repository at this point in the history
a21f1ba merging changes for fixing GE pulse duration bug
ec2303c fixed kPL error plots, and potential bug with spectral-spatial waveforms for odd number of points on GE systems
bb69713 Merge pull request #2 from LarsonLab/HEAD
cabf492 Fix to spectral correction for flyback spectral-spatial pulses
48db96a Fix to spectral correction for flyback spectral-spatial pulses
bbfd759 Update README.md
7f4b9a3 Merge pull request #1 from LarsonLab/HP_toolbox_edits
fc7819e Minor edits
51a48a0 Minor edits
3eb1b7e Minor edit
434c9e6 Minor edit
ea4129b New kinetic model fitting function
d0bbfb6 New kinetic model fitting function
66cdbfb Updated cplot function
8cb1bac Merge commit 'd608131b1f2f6f4aa6d21cf277dc842fa47730a4' as 'RF_pulses/spectral_spatial'
ded562d Update README.md
88984ee Removing Spectral Spatial from toolbox (moved into its own repo)
b95dc02 renamed mex directory
d94d5bf Added gradient scaling compensation function and rf_tools
4c803a2 bug fixes, added some exploration of optimization
797d490 updates to documentation and new optimization code
c0c903a Added optimal signal VFA code
2fdf290 IDEAL cleanup
ba1be84 Update README.md
609451c Update README.md
74114d5 Create README.md
9867a0d Merge branch 'master' of https://git01.codeplex.com/hyperpolarizedmritoolbox Merging with spectral-spatial RF pulse additions
6140547 IDEAL cleanup
be8f2eb Added Spectral-Spatial RF Pulse MATLAB Toolbox
658031a Added function to calculate NSA
48cad95 Initial file upload, including EPSI and variable flip angles

git-subtree-dir: RF_pulses/spectral_spatial
git-subtree-split: a21f1ba
  • Loading branch information
agentmess committed Aug 28, 2018
1 parent d608131 commit 857c3c9
Show file tree
Hide file tree
Showing 11 changed files with 362 additions and 52 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ All Rights Reserved.

This package includes Matlab functions to design spectral-spatial RF pulses (also known as spatial-spectral RF pulses) for application to magnetic resonance spectroscopy and imaging. See the "examples/" folder for sample code and pulse designs.

Examples include excitation and refocusing pulses, as well as pulses for hyperpolarized carbon-13 MRI.

Requirements:
- Signal Processing Toolbox (MathWorks)
- Optimization Toolbox (MathWorks)
Expand Down
12 changes: 8 additions & 4 deletions create_freq_specs.m
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
function [fspec, a_angs, d] = create_freq_specs(mets)
function [fspec, a_angs, d] = create_freq_specs(mets, fmid)
% CREATE_FREQ_SPECS - Helper function for creating spectral-spatial
% frequency specifications
%
% [fspec, a_angs, d] = create_freq_specs(mets);
% [fspec, a_angs, d] = create_freq_specs(mets, fmid);
%
% INPUT
% mets - structure containing:
% mets(i).f - center frequency of bands (Hz)
% mets(i).df - bandwidth of bands (Hz)
% mets(i).ang - flip angle of bands (degress)
% mets(i).d - ripple of bands (Mxy, default = .01)
% fmid [optional] - center frequency spec around fmid
%
% OUTPUT
% spec, a_angs, d - inputs for ss_design()
Expand Down Expand Up @@ -41,6 +42,9 @@
end
end

% by default, center frequency specification
fmid = (mets(1).f+mets(end).f)/2;
if nargin < 2 || isempty(fmid)
% by default, center frequency specification
fmid = (min(fspec)+max(fspec))/2;
end

fspec = fspec - fmid;
46 changes: 46 additions & 0 deletions examples/demo_C13_singleband.m
Original file line number Diff line number Diff line change
Expand Up @@ -105,3 +105,49 @@
ss_design(z_thk, z_tb, [z_d1 z_d2], fspec, a_angs, d, ptype, ...
z_ftype, s_ftype, ss_type, fctr);
set(gcf,'Name', '[1-13C]lac only for 14T animal system');

fprintf(1,'Hit any key to continue:\n');
pause;


%% lactate-only pulse
fprintf(1, '\nFor studies including copolarized 13C-urea or a 13C-urea phantom\n');
fprintf(1, 'Here''s a C13 single-band excitation pulse to excite only [1-13C]lactate\n');
fprintf(1, 'while not exciting pyruvate, alanine and pyruvate-hydrate AND urea, for a 3T clinical system\n\n');

clear all; ss_opt([]); ss_globals; % Reset all options

% GENERAL PULSE PARAMETERS
ss_type = 'EP Whole';
ptype = 'ex'; % excitation pulse
opt = ss_opt({'Nucleus', 'Carbon', ...
'Max Duration', 25e-3, ...
'Spect Correct', 1});

% SPECTRAL PULSE PARAMETERS - large pass/stop bands chosen for wide
% supression regions
B0 = 3e4; % G
df = 0.5e-6 * B0 * SS_GAMMA; % 0.5 ppm = gamma_C13 * B0 * 0.5e-6
% metabolite frequency (Hz) freq bandwidth (Hz) flip angle (deg)
mets(1).name = 'urea'; mets(1).f = -470; mets(1).df = 2*df; mets(1).ang = 0;
mets(2).name = 'pyr'; mets(2).f = -230; mets(2).df = 2*df; mets(2).ang = 0;
mets(3).name = 'ala'; mets(3).f = -45; mets(3).df = 3*df; mets(3).ang = 0;
mets(4).name = 'pyrh'; mets(4).f = 40; mets(4).df = 2*df; mets(4).ang = 0;
mets(5).name = 'lac'; mets(5).f = 165; mets(5).df = 2*df; mets(5).ang = 90;

% create vectors of angles, ripples, and band edges for input to pulse design
[fspec, a_angs, d] = create_freq_specs(mets);
fctr = 0; % force pulse design to optimize for center of frequency specification
s_ftype = 'min'; % minimum-phase spectral filter

% SPATIAL PULSE PARAMETERS
z_thk = 1; % thickness (cm)
z_tb = 4; % time-bandwidth, proportional to profile sharpness
z_ftype='ls'; % least-squares filter design
z_d1 = 0.01; z_d2 = 0.01; % slice profile pass and stop-band ripples, respectively

% DESIGN THE PULSE!
[g,rf,fs,z,f,mxy] = ...
ss_design(z_thk, z_tb, [z_d1 z_d2], fspec, a_angs, d, ptype, ...
z_ftype, s_ftype, ss_type, fctr);
set(gcf,'Name', '[1-13C]lac only for 3T clinical system, avoiding urea');
21 changes: 14 additions & 7 deletions rf_tools/cplot.m
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
%
% cplot(x) - plot complex function;
% cplot([x,] y) - plot complex function; optional specification of x-axis
%

% written by John Pauly, 1989
% modified by Peder Larson, 2006
% (c) Board of Trustees, Leland Stanford Junior University

function cplot(x)

l = length(x);
t = [1:l]/(l+1);
plot(t,real(x),t,imag(x));

function cplot(x,y,s)

if nargin == 1
y = x;
l = length(x);
x = [1:l]/(l+1);
end

if nargin < 3
plot(x,real(y),x,imag(y));
elseif nargin == 3
plot(x,real(y),s,x,imag(y),s);
end


32 changes: 16 additions & 16 deletions signa.m
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
function signa(wav,fn,s)
function signa(waveform,filename,scale)

%
% signa(waveform, filename [,scale]);
Expand All @@ -24,40 +24,40 @@ function signa(wav,fn,s)

% if no scale is specified, use as much dynamic range as possible
if nargin == 2,
s = 1/max(max(abs(real(wav)),abs(imag(wav))));
scale = 1/max(max(abs(real(waveform)),abs(imag(waveform))));
end;

% scale up to fit in a short integer
wav = wav*s*wmax;
waveform = waveform*scale*wmax;

% mask off low bit, since it would be an EOS otherwise
wav = 2*round(wav/2);
waveform = 2*round(waveform/2);

% if the imaginary component is zero, supress it
if sum(abs(imag(wav))) == 0,
wav = real(wav);
if sum(abs(imag(waveform))) == 0,
waveform = real(waveform);
end;

if isreal(wav),
fip = fopen(fn,'wb','b');
if isreal(waveform),
fip = fopen(filename,'wb','b');
if fip == -1,
disp(sprintf('Error opening %s for write',fn));
disp(sprintf('Error opening %s for write',filename));
return;
end;
fwrite(fip,wav,'short');
fwrite(fip,waveform,'short');
else
fip = fopen([fn,'.r'],'wb','b');
fip = fopen([filename,'.r'],'wb','b');
if fip == -1,
disp(sprintf('Error opening %s for write',[fn,'.r']));
disp(sprintf('Error opening %s for write',[filename,'.r']));
return;
end;
fwrite(fip,real(wav),'short');
fwrite(fip,real(waveform),'short');
fclose(fip);
fip = fopen([fn,'.i'],'wb','b');
fip = fopen([filename,'.i'],'wb','b');
if fip == -1,
disp(sprintf('Error opening %s for write',[fn,'.i']));
disp(sprintf('Error opening %s for write',[filename,'.i']));
return;
end;
fwrite(fip,imag(wav),'short');
fwrite(fip,imag(waveform),'short');
fclose(fip);
end;
4 changes: 1 addition & 3 deletions ss_flyback.m
Original file line number Diff line number Diff line change
Expand Up @@ -339,9 +339,7 @@
if (dbg)
fprintf(1,'No SLR.. spectral correction...\n');
end;
% s_rfm = ss_spect_correct(s_b, bsf, Nper, Noff, (f-f_off)/(fs/2), ...
% ptype, 'Flyback', SS_SLR_FLAG, SS_SPECT_CORRECT_REGULARIZATION, dbg);
s_rfm = ss_spect_correct(s_b, bsf, Nper, Noff, f, ...
s_rfm = ss_spect_correct(s_b, bsf, Nper, Noff, (f-f_off)/(fs/2), ...
ptype, 'Flyback', SS_SLR_FLAG, SS_SPECT_CORRECT_REGULARIZATION, dbg);
else
s_rfm = ang * conj(s_b(:)) * ones(1,ng2); % Intentional conjugation
Expand Down
2 changes: 1 addition & 1 deletion ss_plot.m
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@
subplot(4,nplot,3*nplot + idx);
m_f = calc_mag(rf_rot,gz_rot+i*gf_rot, z, fplot(idx),ptype);
plot_mag(z,m_f,ptype);
title(sprintf('Spatial Profile - Freq = %5.1f', fplot(idx)));
title(sprintf('%5.1f', fplot(idx)));
xlabel('Position [cm]');
end;

Expand Down
17 changes: 13 additions & 4 deletions ss_save.m
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,23 @@ function ss_save(g,rf,ang,thk, isodelay, format, fspec, a_angs)

if (nargin < 6) || isempty(format)
format = 'GE';
else
end

switch format,
case {'GE', 'Varian'}
case 'GE'
% force even number of samples due to some GE sequences having
% issues loading odd number of samples
if rem(length(rf))
rf = [rf(:), 0];
g = [g(:), 0];
end

case 'Varian'

otherwise
error(sprintf(['Format save type of: %s not' ...
' recognized'], format));
end;
end

maxg = max(abs(g));
if maxg ~= 0,
Expand Down Expand Up @@ -233,4 +242,4 @@ function ss_save(g,rf,ang,thk, isodelay, format, fspec, a_angs)





19 changes: 14 additions & 5 deletions ss_save_dyn.m
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,23 @@ function ss_save_dyn(g,rf,ang,thk, isodelay, format, fspec, a_angs, root_fname,

if (nargin < 6) || isempty(format)
format = 'GE';
else
switch format,
case {'GE', 'Varian'}
end

switch format,
case 'GE'
% force even number of samples due to some GE sequences having
% issues loading odd number of samples
if rem(length(rf))
rf = [rf(:), 0];
g = [g(:), 0];
end

case 'Varian'

otherwise
error(sprintf(['Format save type of: %s not' ...
' recognized'], format));
end;
end

maxg = max(abs(g));
if maxg ~= 0,
Expand Down Expand Up @@ -229,4 +238,4 @@ function ss_save_dyn(g,rf,ang,thk, isodelay, format, fspec, a_angs, root_fname,





Loading

0 comments on commit 857c3c9

Please sign in to comment.