Skip to content

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:

INV.rf_type      = 'HYPSEC_inversion';
INV.tExc         = 10 *1e-3;  % [s]  hypsec pulse duration
INV.beta         = 700;       % [Hz] maximum rf peak amplitude
INV.mu           = 4.9;       % [ ]  determines amplitude of frequency sweep
INV.inv_rec_time = [15 75 150 250] *1e-3;
INV = INV_init(INV, FOV, system);
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.