Modules
OpenMRF is a modular framework. All magnetization preparation and readout modules are implemented as Matlab structs and follow a similar structure.
Module vs. instance
The Matlab structure defines the module. If your sequence features a specific module more than once, you do not need to initialize them individually. See code examples below.
Overview of module names
Magnetization preparations
The source code for the following modules can be found in include_pulseq_toolbox/src_preparations.
| Module Name | Long Name | Notes |
|---|---|---|
| ADIASL | Adiabatic Spin Lock | Defines an adiabatic spin lock module for T1\(\rho\) preparation |
| CEST | Chemical Exchange Saturation Transfer | |
| CRUSH | Crusher | |
| FAT | Fat suppression | |
| INV | Inversion | |
| MLEV | Malcolm Levitt | Defines a T2\(\rho\) preparation featuring Malcolm Levitt phase cycling. |
| SAT | Saturation | |
| SL | Spin Lock | Defines a continuous wave spin lock module for T1\(\rho\) preparation. |
| T2 | T2 preparation |
Readouts
The source code for the following modules can be found in include_pulseq_toolbox/src_readouts.
| Module Name | Long Name | Notes |
|---|---|---|
| EPI | Echo Planar Imaging | |
| PRESS | Point Resolved Spectroscopy | |
| RAD | Radial | |
| SPI | Spiral | Used for spiral and custom non-Cartesian trajectories. |
| SPITSE | Spiral Turbo Spin Echo | |
| TSE | Turbo Spin Echo | |
| UTE | Ultra short TE |
Other
The source code for the following modules can be found in include_pulseq_toolbox/src_misc.
| Module Name | Long Name | Notes |
|---|---|---|
| FOV | Field of view | Defines the field of view geometry. |
| TRAJ | Trajectory | Used for trajectory calibration. |
| WASABI | Waserstein based anatomical brain Index | Used for simultaneous B0 and B1 mapping. |
The ..._init() function
Before they can be added to a sequence, all magnetization preparations and readouts have to be initialized.
The first step is to create the structure. Second, the respective ..._init() function is called, with the respective structure as the first input argument. You don't have to define all parameters of the module yourself - optional parameters have a default value that will be assigned by the ..._init() function unless specified explicitly. When in doubt, just look at the source code of the module in question.
Multiple instances of the same preparation module
If you are planning to add multiple instances of the same magnetization preparation module with different preparation times (as often done in cardiac & abdominal MRF), you can initialize them all at once by making the respective field an array instead of a single value. See examples below.
The following two examples show how advanced magnetization preparations can be easily initialized in OpenMRF:
T2.exc_mode = 'adiabatic_BIR4';
T2.rfc_dur = 2 *1e-3; % [s] duration of composite refocusing pulses
T2.bir4_tau = 10 *1e-3; % [s] bir4 pulse duration
T2.bir4_f1 = 640; % [Hz] maximum rf peak amplitude
T2.bir4_beta = 10; % [ ] am waveform parameter
T2.bir4_kappa = atan(10); % [ ] fm waveform parameter
T2.bir4_dw0 = 30000; % [rad/s] fm waveform scaling
T2.prep_times = [40 80] * 1e-3; % [s] inversion times
T2 = T2_init(T2, FOV, system);
This example shows how to define and initialize a spiral readout with golden angle interleaves for MRF:
% import params from MRF struct
SPI.nr = MRF.nr; % [ ] number of readouts per heart beat
SPI.NR = MRF.NR; % [ ] number of repetitions
SPI.mrf_import.TRs = MRF.TRs; % [s] repetition times
SPI.mrf_import.FAs = MRF.FAs; % [rad] flip angles
% slice excitation
SPI.exc_mode = 'sinc'; % 'sinc' or 'sigpy_SLR'
SPI.exc_time = 0.8 *1e-3; % [s] excitation time
SPI.exc_tbw = 2; % [ ] time bandwidth product
SPI.exc_fa_mode = 'import'; % 'equal', 'ramped', 'import'
SPI.lim_gz_slew = 0.9; % [ ] reduce stimulation during slice excitation
SPI.lim_reph_slew = 0.9; % [ ] reduce stimulation during slice rephaser
% gradient spoiling
SPI.spoil_nTwist = 4; % [ ] number of 2pi twists in z-direction, 0 for balanced
SPI.spoil_duration = 0.8 *1e-3; % [s] time for spoiler and rewinder gradients
SPI.lim_spoil_slew = 0.9; % [ ] reduce stimulation during gradient spoiling
% rf spoiling
SPI.spoil_rf_mode = 'lin'; % rf spoiling mode: 'lin' or 'quad'
SPI.spoil_rf_inc = 0 *pi/180; % rf spoiling increment [rad]
% spiral geometry mode
SPI.geo.interleave_mode = 'RoundGoldenAngle';
SPI.geo.traj_mode = 'vds';
% vds parameters
SPI.Nunique = 48; % number of unique projection angles
SPI.deltak = 1/FOV.fov_xy; % [1/m] kspace sampling
SPI.kmax = SPI.deltak * FOV.Nxy/2;
SPI.geo.Nvds = 24; % number of vds-spirals for sampling the kspce center
SPI.geo.BW = 500 *1e3; % [Hz] bandwidth of spiral acquisition
SPI.geo.Fcoeff = [1 -0.5]; % [1 0] for archimedean (equal density), [1 -0.5] for logarithmic (variable density)
SPI.geo.grad_lim = 1/sqrt(3); % limit of gradient field strength
SPI.geo.slew_lim = 1/sqrt(3); % limit of slew rate
SPI.geo.kmax = SPI.kmax; % determines resolution
SPI.geo.t_dwell = 1/SPI.geo.BW; % [s] dwell time for spiral acquisition
[SPI, ktraj_adc, ktraj_full, ktraj_reco] = SPI_init(SPI, FOV, system, 1);
The ..._add() function
When building a sequence, instances of a module can be added using the respective ..._add() function. If your sequence features multiple instances of the same magnetization preparation module, a counter is increased automatically to ensure that each instance is added with the correct preparation time.
Tip
Take a closer look at main_sequences/fingerprinting/pulseq_mrf.m and main_sequences/fingerprinting/pulseq_cmrf.m to understand the use of magnetization preparation and readout modules.