GENsim - Matrix Method Diffusion MRI Simulator
Introduction
GENsim is a Matlab toolkit designed to simulate diffusion MRI signal for a large variety of pulse sequences in diffusion substrates which include restriction. It provides the means to understand the diffusion patterns in synthetic tissue models (white matter, cancer, etc) for various diffusion sequences.
This tutorial describes the use of GENsim Matlab toolkit for simulating diffusion MRI data in various substrates.
The novelty of GENSim is that it allows the user to create a flexible diffusion gradient waveform. It assumes a basic understanding of diffusion MRI pulse sequences, including more advanced sequences such as square and trapezoidal oscillating gradients. The diffusion signal is calculated using the matrix formalism detailed in Drobnjak et al. 2010 and Drobnjak et al. 2011 . The existing parametrizations for square and trapezoidal oscillating gradients follow the description in Ianus et al. 2012 . The diffusion substrates available in GENSim are the basic compartments presented in Panagiotaki et al. 2011, as well as some two- and three-compartment models of white matter.
Terms and Conditions
GENSim is distributed under the Artistic License 2.0. The full text of the license can be found here . The Owner draws your attention to the fact that the Software has been developed for and is intended for use in a research environment only. No endorsement can be given for other use including, but not limited to, use in a clinical environment.
If you are using GENSim in your research, please cite Drobnjak et al. 2010 , Drobnjak et al. 2011 and Ianus et al. 2012
Download
Coming soon
Step-by-step getting started tutorial
- Include GENSim toolbox in the Matlab search path: (:toggle init=hide hide="Hide the detail" show="Show the detail" div=matlab_path button=1 :)
/usr/local/GENSim
, then run
addpath(genpath('/usr/local/GENSim'))
- Take a minute to understand the format of the gradient waveform necessary for the simulation: (:toggle init=hide hide="Hide the detail" show="Show the detail" div=GEN_sequence button=1 :)
protocol.pulseseq = 'GEN'
- the name of the sequence, protocol.G
- the gradient waveform, protocol.tau
- time interval between two points on the gradient waveform and optionally protocol.smalldel
and protocol.delta
which are the pulse duration and time interval between the onset of the first and second pulse. It is not mandatory to specify the last two parameters, but they save computation time if the diffusion sequence has two gradient intervals. Additionally the user can specify if the second gradient is repeated protocol.mirror = 0
- default value or reflected protocol.mirror = 1
.
protocol.G
is a M x 3K matrix which stores the values of the diffusion gradient at each time point. Each row represents one measurement and contains the values of the gradients in x, y and z direction. M is the total number of measurements and K is the number of gradient points in each direction for one measurement:
protocol.G
includes the complete diffusion gradient and the user should take into account any realistic situations such as the duration of the rf pulses, crusher gradients, etc.
protocol.G
should satisfy the echo condition, that the integral of the gradient over time should be 0.
- Take a minute to understand the diffusion substrates available in the simulation: (:toggle init=hide hide="Hide the detail" show="Show the detail" div=model button=1 :)
All the information related to the diffusion substrate is stored in a Matlab structure, which we call “model” in the examples. For the purpose of signal generation, “model” has only two fields: model.name
– the name of the model (listed above) and model.params
- the values of the model parameters in S.I. (m, s, etc.) of each model. See documentation for details.
- Create an example gradient waveform for square oscillating gradients (:toggle init=hide hide="Hide the detail" show="Show the detail" div=example_SWOGSE button=1 :)
wave_form
function. The available sequences are: pulse gradient spin echo sequence PGSE, square oscillating gradient - SWOGSE, trapezoidal oscillating gradients - TWOGSE, square oscillating gradients with different parameters in x,y and z directions - SWOGSE_3D. See documentation for details.
% add some combinations of parameters: delta = 0.015:0.005:0.04; % duration in s smalldel = delta - 0.005; % duration in s Nosc = 1:5; % number of lobes in the oscillating gradient. A full period has 2 lobes G = 0.08; % gradient strength in T/m; tau = 1E-4; % time interval for waveform discretization it = 0; protocol_init.pulseseq = 'SWOGSE'; for i = 1:length(delta) for j = 1:length(Nosc) it = it+1; protocol_init.smalldel(it) = smalldel(i); protocol_init.delta(it) = delta(i); protocol_init.omega(it) = Nosc(j).*pi./smalldel(i); protocol_init.G(it) = G; protocol_init.grad_dirs(it,:) = [1 0 0]; % gradient in x direction end end protocol_init.tau = tau;
protocolGEN.pulseseq = 'GEN'; protocolGEN.G = wave_form(protocol_init); protocolGEN.tau = tau; % include smalldel and delta as they make computation slightly faster protocolGEN.delta = protocol_init.delta; protocolGEN.smalldel = protocol_init.smalldel;
- View the example waveform for square oscillating gradients (:toggle init=hide hide="Hide the detail" show="Show the detail" div=view_SWOGSE button=1 :)
figure(); Gx = protocolGEN.G(1,1:3:end); plot((0:tau:(length(Gx)-1)*tau)*1E3,Gx*1000,'LineWidth',2) xlim([0,(protocolGEN.smalldel(1)+protocolGEN.delta(1)+10*tau)*1E3]) ylim([min(Gx)*1200 max(Gx)*1200]) xlabel('time (ms)'); ylabel('Gx (mT/m)');
- Synthesize the diffusion signal for the previous example (:toggle init=hide hide="Hide the detail" show="Show the detail" div=run_SWOGSE button=1 :)
model.name = 'ZeppelinCylinder'; di = 1.7E-9; % intrinsic diffusivity dh = 1.2E-9; % hindered diffusivity rad = 4E-6; % cylinder radius % angles in spherical coordinates describing the cylinder orientation; theta = 0; % angle from z axis phi = 0; % azimuthal angle ficvf = 0.7; % intracellular volume fraction model.params = [ficvf di dh rad theta phi];
protocolGEN = MMConstants(model,protocolGEN);
signal = SynthMeas(model,protocolGEN);
- Plot the synthesized diffusion signal (:toggle init=hide hide="Hide the detail" show="Show the detail" div=plot_signal button=1 :)
signal_matrix = reshape(signal,length(Nosc),length(delta)); figure(); colors = jet(length(Nosc)); hold on; for i = 1:length(Nosc) legend_name{i} = ['Nosc = ' num2str(Nosc(i))]; plot(delta*1000,signal_matrix(i,:),'LineWidth',2,'Color',colors(i,:)); end xlabel('\Delta (ms)','FontSize',16); ylabel('Diffusion Signal','FontSize',16); set(gca,'FontSize',16); title('Diffusion signal as a function of \Delta for various number of oscillations, G = 80mT/m') legend(legend_name,'FontSize',16)
- A true advantage of GENSim is that it can compute the diffusion signal for any sequence, not only parametrized ones. An example with random values (:toggle init=hide hide="Hide the detail" show="Show the detail" div=rand_protocol button=1 :)
grad_dirs
, similarly to the parametrized versions.
wave_form
with a protocol which has pulseseq = 'GEN'
and a field GENGx
which is the vector with the gradient values. To understand the resulting waveform, think of a PGSE where the constant gradient was replaced by GENGx
.
smalldel = delta - 0.005; % duration in s G = 0.08; % maximum gradient strength in T/m; protocol_rand.pulseseq = 'GEN'; protocol_rand.grad_dirs = [1/sqrt(2) 1/sqrt(2) 0 ]; % gradient along x and y protocol_rand.smalldel = smalldel; protocol_rand.delta = delta; % protocol_rand consists of a random waveform with 40 points which will be repeated after the 180 pulse protocol_rand.GENGx = rand(1,40)*G; protocol_rand.tau = protocol_rand.smalldel(1)./length(protocol_rand.GENGx);% calculate the time interval based on the number of points
protocolGEN.pulseseq = 'GEN'; protocolGEN.G = wave_form(protocol_rand); protocolGEN.tau = tau; % include smalldel and delta as they make computation slightly faster protocolGEN.delta = protocol_rand.delta; protocolGEN.smalldel = protocol_rand.smalldel;
figure(); plot(protocol_rand.GENGx) figure(); Gx = protocolGEN.G(1,1:3:end); plot((0:protocolGEN.tau:(length(Gx)-1)*protocolGEN.tau)*1E3,Gx*1000,'LineWidth',2) xlabel('time (ms)'); ylabel('Gx (mT/m)'); xlim([0,(protocolGEN.smalldel(1)+protocolGEN.delta(1)+2*protocolGEN.tau)*1E3])
model.name = 'ZeppelinCylinder'; di = 1.7E-9; % intrinsic diffusivity dh = 1.2E-9; % hindered diffusivity rad = 4E-6; % cylinder radius % angles in spherical coordinates describing the cylinder orientation; theta = 0; % angle from z axis phi = 0; % azimuthal angle ficvf = 0.7; % intracellular volume fraction model.params = [ficvf di dh rad theta phi];
protocolGEN = MMConstants(model,protocolGEN);
signal = SynthMeas(model,protocolGEN);
- Create your own diffusion protocol.
- To help you start, the same commands are in GENSim/example/RunGEN.m