-
Notifications
You must be signed in to change notification settings - Fork 59
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
07a79ba
commit 56a86ef
Showing
6 changed files
with
640 additions
and
0 deletions.
There are no files selected for viewing
101 changes: 101 additions & 0 deletions
101
src/Models_Functions/adiabatic_inv/pulses/AI_gauss_pulse.m
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
function [rf_pulse, omega1, A_t, Params] = AI_gauss_pulse( Trf, Params) | ||
|
||
% gauss_pulse Adiabatic Inversion Gaussian RF pulse function. | ||
% pulse = gauss_pulse(Trf, PulseOpt) | ||
% | ||
% B1(t) = A(t) * exp( -1i *integral(omega1(t')) dt' ) | ||
% where A(t) is the envelope, omega1 is the frequency sweep | ||
% | ||
% Phase modulation is found from taking the integral of omega1(t) | ||
% Frequency modulation is time derivative of phi(t) | ||
% | ||
% For the case of a Gauus pulse: | ||
% A(t) = A_0 * exp((-beta^2 * t^2)/2) | ||
% lambda = A0^2/(beta*Q) | ||
% omega1(t) = -lamdba*(erf(beta*t)/erf(beta)) | ||
% | ||
% A0 is the peak amplitude in microTesla | ||
% beta is a frequency modulation parameter in rad/s | ||
% | ||
% The pulse is defined to be 0 outside the pulse window (before | ||
% t = 0 or after t=Trf). (HSn, n = 1-8+) | ||
% | ||
% --args-- | ||
% t: Function handle variable, represents the time. | ||
% Trf: Duration of the RF pulse in seconds. | ||
% | ||
% --optional args-- | ||
% PulseOpt: Struct. Contains optional parameters for pulse shapes. | ||
% PulseOpt.Beta: frequency modulation parameter | ||
% | ||
% Reference: Matt A. Bernstein, Kevin F. Kink and Xiaohong Joe Zhou. | ||
% Handbook of MRI Pulse Sequences, pp. 110, Eq. 4.10, (2004) | ||
% | ||
% Tannús, A., & Garwood, M. (1997). Adiabatic pulses. NMR in | ||
% Biomedicine: An International Journal Devoted to the | ||
% Development and Application of Magnetic Resonance In Vivo, | ||
% 10(8), 423-434. https://doi.org/10.1002/(sici)1099-1492(199712)10:8 | ||
% --> Table 1 contains all modulation functions | ||
% --> A(t), omega1 | ||
% --> Fig 5, Gaussian OIA pulse image | ||
% --> Trf = 10 ms | ||
% | ||
% Kupce, E., & Freeman, R. (1996). Optimized adiabatic pulses | ||
% for wideband spin inversion. Journal of Magnetic Resonance, | ||
% 118(2), 299-303. https://doi.org/https://doi.org/10.1006/jmra.1996.0042 | ||
% --> lambda equation, Eq. 10 (added to omega1 for scaling) | ||
% | ||
% Tannús, A., & Garwood, M. (1996). Improved performance of | ||
% frequency-swept pulses using offset-independent adiabaticity. | ||
% Journal of Magnetic Resonance, 120(1), 133-137. | ||
% https://doi.org/https://doi.org/10.1006/jmra.1996.0110 | ||
% --> Fig 1a and 1b. Show how width of amplitude and | ||
% frequency vary with each pulse | ||
% | ||
% To be used with qMRlab | ||
% Written by Amie Demmans & Christopher Rowley 2024 | ||
|
||
|
||
% Function to fill default values; | ||
if ~isfield(Params, 'PulseOpt') | ||
Params.PulseOpt = struct(); | ||
end | ||
|
||
Params.PulseOpt = AI_defaultGaussParams(Params.PulseOpt); | ||
Trf = Trf/1000; | ||
nSamples = Params.PulseOpt.nSamples; | ||
t = linspace(0, Trf, nSamples); | ||
tau = t-Trf/2; | ||
|
||
% Amplitude | ||
A_t = Params.PulseOpt.A0 .* exp(-1*(Params.PulseOpt.beta.^2 .* tau.^2)./2); | ||
A_t((t < 0 | t>Trf)) = 0; | ||
% disp( ['Average B1 of the pulse is:', num2str(mean(A_t))]) | ||
|
||
% Scaling Factor (lambda) | ||
% --> Setting Q = 0 allows for viewing of RF pulse | ||
if Params.PulseOpt.Q == 0 | ||
lambda = 0; | ||
else | ||
lambda = (Params.PulseOpt.A0)^2 ./ (Params.PulseOpt.beta.*Params.PulseOpt.Q); | ||
end | ||
|
||
% Frequency modulation function | ||
% Carrier frequency modulation function w(t): | ||
omega1 = -lambda*erf(Params.PulseOpt.beta.*tau)./erf(Params.PulseOpt.beta); | ||
|
||
% Phase modulation function phi(t): | ||
phi1num = lambda.*tau.*erf(Params.PulseOpt.beta.*tau); | ||
phi1denom = erf(Params.PulseOpt.beta); | ||
phi1 = phi1num/phi1denom; | ||
phi2num = lambda*exp(-Params.PulseOpt.beta.^2 .* tau.^2); | ||
phi2denom = sqrt(pi)*Params.PulseOpt.beta*erf(Params.PulseOpt.beta); | ||
phi2 = phi2num/phi2denom; | ||
phi = phi1+phi2; | ||
|
||
% Put together complex RF pulse waveform: | ||
rf_pulse = A_t .* exp(1i .* phi); | ||
|
||
|
||
|
||
|
98 changes: 98 additions & 0 deletions
98
src/Models_Functions/adiabatic_inv/pulses/AI_hanning_pulse.m
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
function [rf_pulse, omega1, A_t, Params] = AI_hanning_pulse( Trf, Params) | ||
|
||
% hanning_pulse Adiabatic Inversion Hanning RF pulse function. | ||
% pulse = hanning_pulse(Trf, PulseOpt) | ||
% | ||
% B1(t) = A(t) * exp( -1i *integral(omega1(t')) dt' ) | ||
% where A(t) is the envelope, omega1 is the frequency sweep | ||
% | ||
% Phase modulation is found from taking the integral of omega1(t) | ||
% Frequency modulation is time derivative of phi(t) | ||
% | ||
% For the case of a Hanning pulse: | ||
% A(t) = A_0 * ((1 + cos(beta*pi*t))/2) | ||
% lambda = A0^2/(beta*Q) | ||
% omega1(t) = -lambda ((beta*t)+((4/3)*pi)*sin(beta*pi*t)*(1 +1/4*cos(beta*pi*t))) | ||
% | ||
% A0 is the peak amplitude in microTesla | ||
% beta is a frequency modulation parameter in rad/s | ||
% | ||
% The pulse is defined to be 0 outside the pulse window (before | ||
% t = 0 or after t=Trf). (HSn, n = 1-8+) | ||
% | ||
% --args-- | ||
% t: Function handle variable, represents the time. | ||
% Trf: Duration of the RF pulse in seconds. | ||
% | ||
% --optional args-- | ||
% PulseOpt: Struct. Contains optional parameters for pulse shapes. | ||
% | ||
% Reference: Matt A. Bernstein, Kevin F. Kink and Xiaohong Joe Zhou. | ||
% Handbook of MRI Pulse Sequences, pp. 110, Eq. 4.10, (2004) | ||
% | ||
% Tannús, A., & Garwood, M. (1997). Adiabatic pulses. NMR in | ||
% Biomedicine: An International Journal Devoted to the | ||
% Development and Application of Magnetic Resonance In Vivo, | ||
% 10(8), 423-434. https://doi.org/10.1002/(sici)1099-1492(199712)10:8 | ||
% --> Table 1 contains all modulation functions | ||
% --> A(t), omega1 | ||
% --> Trf = 10ms | ||
% | ||
% Kupce, E., & Freeman, R. (1996). Optimized adiabatic pulses | ||
% for wideband spin inversion. Journal of Magnetic Resonance, | ||
% 118(2), 299-303. https://doi.org/https://doi.org/10.1006/jmra.1996.0042 | ||
% --> lambda equation, Eq. 10 (added to omega1 for scaling) | ||
% --> Added beta for everywhere theres tau to follow | ||
% trends in Table 1 | ||
% | ||
% To be used with qMRlab | ||
% Written by Amie Demmans & Christopher Rowley 2024 | ||
|
||
|
||
% Function to fill default values; | ||
if ~isfield(Params, 'PulseOpt') | ||
Params.PulseOpt = struct(); | ||
end | ||
|
||
Params.PulseOpt = AI_defaultHanningParams(Params.PulseOpt); | ||
Trf = Trf/1000; | ||
nSamples = Params.PulseOpt.nSamples; | ||
t = linspace(0, Trf, nSamples); | ||
tau = t-Trf/2; | ||
|
||
% Amplitude | ||
A_t = Params.PulseOpt.A0*((1+cos(pi.*tau.*Params.PulseOpt.beta))./2); | ||
A_t((t < 0 | t>Trf)) = 0; | ||
% disp( ['Average B1 of the pulse is:', num2str(mean(A_t))]) | ||
|
||
% Scaling Factor (lambda) | ||
% --> Setting Q = 0 allows for viewing of RF pulse | ||
if Params.PulseOpt.Q == 0 | ||
lambda = 0; | ||
else | ||
lambda = (Params.PulseOpt.A0)^2 ./ (Params.PulseOpt.beta.*Params.PulseOpt.Q); | ||
end | ||
|
||
% Frequency modulation function | ||
% Carrier frequency modulation function w(t): | ||
omegaterm1 = Params.PulseOpt.beta.*tau; | ||
omegaterm2 = (4/(3*pi)*sin(pi.*tau.*Params.PulseOpt.beta)); | ||
omegaterm3 = 1+1/4*cos(pi.*tau.*Params.PulseOpt.beta); | ||
omega1 = -lambda.*(omegaterm1+(omegaterm2.*omegaterm3)); | ||
|
||
|
||
% Phase modulation function phi(t): | ||
phiterm1 = (Params.PulseOpt.beta*lambda.*tau.^2)./2; | ||
phiterm2num = lambda*(cos(pi.*tau.*Params.PulseOpt.beta)+4).^2; | ||
phiterm2denom = 6*Params.PulseOpt.beta*pi^2; | ||
phi = phiterm1 - (phiterm2num/phiterm2denom); | ||
|
||
% Put together complex RF pulse waveform: | ||
rf_pulse = A_t .* exp(1i .* phi); | ||
|
||
|
||
|
||
|
||
|
||
|
||
|
126 changes: 126 additions & 0 deletions
126
src/Models_Functions/adiabatic_inv/pulses/AI_hs1_pulse.m
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
function [rf_pulse, omega1, A_t, Params] = AI_hs1_pulse(Trf, Params) | ||
|
||
% hyperbolicSecant_pulse Adiabatic Inversion hyperbolic secant RF pulse function. | ||
% pulse = hyperbolicSecant_pulse(t, Trf, PulseOpt) | ||
% | ||
% B1(t) = A(t) * exp( -1i *integral(omega1(t')) dt' ) | ||
% where A(t) is the envelope, omega1 is the frequency sweep | ||
% | ||
% Phase modulation is found from taking the integral of omega1(t) | ||
% Frequency modulation is time derivative of phi(t) | ||
% | ||
% For the case of a hyperbolic secant pulse: | ||
% A(t) = A0 * sech(Beta*t) | ||
% omega1(t) = -mu*Beta*tanh(Beta*t) | ||
% | ||
% A0 is the peak amplitude in microTesla | ||
% Beta is a frequency modulation parameter in rad/s | ||
% mu is a phase modulation parameter (dimensionless) | ||
% | ||
% The pulse is defined to be 0 outside the pulse window (before | ||
% t = 0 or after t=Trf). (HSn, n = 1-8+) | ||
% | ||
% --args-- | ||
% t: Function handle variable, represents the time. | ||
% Trf: Duration of the RF pulse in seconds. | ||
% | ||
% --optional args-- | ||
% PulseOpt: Struct. Contains optional parameters for pulse shapes. | ||
% PulseOpt.Beta: frequency modulation parameter | ||
% PulseOpt.n: time modulation - Typical 4 for non-selective, 1 for slab | ||
% Reference: Matt A. Bernstein, Kevin F. Kink and Xiaohong Joe Zhou. | ||
% Handbook of MRI Pulse Sequences, pp. 110, Eq. 4.10, (2004) | ||
% | ||
% Tannús, A., & Garwood, M. (1997). Adiabatic pulses. NMR in | ||
% Biomedicine: An International Journal Devoted to the | ||
% Development and Application of Magnetic Resonance In Vivo, | ||
% 10(8), 423-434. https://doi.org/10.1002/(sici)1099-1492(199712)10:8 | ||
% --> Table 1 contains all modulation functions | ||
% | ||
% Garwood, M., & DelaBarre, L. (2001). The return of the frequency | ||
% sweep: designing adiabatic pulses for contemporary NMR. Journal | ||
% of Magnetic Resonance, 153(2), 155-177. | ||
% https://doi.org/10.1006/jmre.2001.2340 | ||
% --> A(t), omega1, mu(phase modulation parameter) | ||
% | ||
% Tannús, A., & Garwood, M. (1996). Improved performance of | ||
% frequency-swept pulses using offset-independent adiabaticity. | ||
% Journal of Magnetic Resonance, 120(1), 133-137. | ||
% https://doi.org/https://doi.org/10.1006/jmra.1996.0110 | ||
% --> Fig 1a and 1b. Show how width of amplitude and | ||
% frequency vary with each pulse | ||
% | ||
% | ||
% To be used with qMRlab | ||
% Written by Christopher Rowley 2023 & Amie Demmans 2024 | ||
|
||
|
||
% Function to fill default values; | ||
if ~isfield(Params, 'PulseOpt') | ||
Params.PulseOpt = struct(); | ||
end | ||
|
||
Params.PulseOpt = AI_defaultHs1Params(Params.PulseOpt); | ||
Trf = Trf/1000; | ||
nSamples = Params.PulseOpt.nSamples; | ||
t = linspace(0, Trf, nSamples); | ||
tau = t-Trf/2; | ||
|
||
% Amplitude | ||
A_t = Params.PulseOpt.A0* sech(Params.PulseOpt.beta* ( (tau)).^Params.PulseOpt.n); | ||
A_t((t < 0 | t>Trf)) = 0; | ||
% disp( ['Average B1 of the pulse is:', num2str(mean(A_t))]) | ||
|
||
% Frequency modulation function | ||
% Carrier frequency modulation function w(t): | ||
% NOTE: Q in Hs1 is NOT the same as in the other pulses, Q = mu | ||
omega1 = -Params.PulseOpt.Q.*Params.PulseOpt.beta .* ... | ||
tanh(Params.PulseOpt.beta .* (tau))./(2*pi); % 2pi to convert from rad/s to Hz | ||
|
||
% Phase modulation function phi(t): | ||
phi = Params.PulseOpt.Q .* log(sech(Params.PulseOpt.beta .* (tau)) ); | ||
|
||
% Put together complex RF pulse waveform: | ||
rf_pulse = A_t .* exp(1i .* phi); | ||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
Oops, something went wrong.