This Julia package provides functionality
for simulating arbitrary MRI pulse sequences.
It includes support for (traditional) single-compartment Bloch simulations
(using Spin
objects) as well as multi-compartment Bloch-McConnell simulations
(using SpinMC
objects).
This package is registered in the
General registry, so you can
install it at the REPL with ] add BlochSim
.
The main functionality is provided by the functions
freeprecess
, excite
, and spoil
(and their mutating variants freeprecess!
, excite!
, and spoil!
).
These functions can be used to simulate a wide variety of MRI sequences.
In addition, this package provides implementations for
a multi-echo spin echo (MESE) scan (MESEBlochSim
)
and a spoiled gradient-recalled echo (SPGR) scan (SPGRBlochSim
).
See the examples given in the documentation strings for how to use the provided
functions. To access the documentation for, e.g., freeprecess
, simply type
?freeprecess
at the Julia REPL after loading the package.
For examples of how to simulate full MRI sequences, see src/mese.jl and src/spgr.jl in this repo, and STFR.jl.
Below are some concrete examples of how to use this package.
julia> using BlochSim
julia> spin = Spin(1, 1000, 100, 3.75)
Spin{Float64}:
M = Magnetization(0.0, 0.0, 1.0)
M0 = 1.0
T1 = 1000.0 ms
T2 = 100.0 ms
Δf = 3.75 Hz
pos = Position(0.0, 0.0, 0.0) cm
julia> excite!(spin, InstantaneousRF(π/2)) # 90° excitation
julia> spin.M # Mz is not quite 0 due to numerical roundoff
Magnetization vector with eltype Float64:
Mx = 1.0
My = 0.0
Mz = 6.123233995736766e-17
julia> freeprecess!(spin, 100) # Free-precess for 100 ms
julia> spin.M
Magnetization vector with eltype Float64:
Mx = -0.2601300475114444
My = -0.2601300475114445
Mz = 0.09516258196404054
julia> spgr! = SPGRBlochSim(5, 2.5, deg2rad(20)) # Create an object to simulate an SPGR scan
Spoiled Gradient-Recalled Echo (SPGR) Bloch Simulation:
TR = 5.0 ms
TE = 2.5 ms
rf (excitation pulse) = Instantaneous RF pulse with eltype Float64:
α = 0.3490658503988659 rad
θ = 0.0 rad
spoiling = IdealSpoiling()
steady-state
julia> spgr!(spin) # Simulate a steady-state SPGR scan applied to the given spin
julia> spin.M # Steady-state magnetization
Magnetization vector with eltype Float64:
Mx = 0.025553542433162182
My = -0.0015069712547712193
Mz = 0.07442699373678281
julia> spinmc = SpinMC(1, (0.2, 0.8), (400, 1000), (20, 80), (15, 0), (100, 25))
SpinMC{Float64,2}:
M = MagnetizationMC((0.0, 0.0, 0.2), (0.0, 0.0, 0.8))
M0 = 1.0
frac = (0.2, 0.8)
T1 = (400.0, 1000.0) ms
T2 = (20.0, 80.0) ms
Δf = (15.0, 0.0) Hz
r = ((0.0, 0.01), (0.04, 0.0)) 1/ms
pos = Position(0.0, 0.0, 0.0) cm
julia> spgr!(spinmc) # The same SPGR scan can be used on multi-compartment spins
julia> spinmc.M # Steady-state magnetization
2-compartment Magnetization vector with eltype Float64:
Compartment 1:
Mx = -0.09359002635156467
My = 0.02433674787041617
Mz = -0.36973998540693054
Compartment 2:
Mx = 0.1541252837882581
My = 0.00031515000730316224
Mz = 0.5077167235922019
julia> signal(spin) # Grab the observed signal from the spin
0.025553542433162182 - 0.0015069712547712193im
julia> signal(spinmc)
0.060535257436693427 + 0.02465189787771933im
- MRIgeneralizedBloch.jl focuses on magnetization transfer
This package was developed based on
Brian Hargreaves' Bloch simulation tutorial.
All tests for this package of the form testX0x
(like testA5b
or testF3d
)
are based on the corresponding section in the tutorial (see
test/matlab.jl).