DEcomposition and Component Analysis of Exponential Signals (DECAES) - a Julia implementation of the UBC Myelin Water Imaging (MWI) toolbox for computing voxelwise T2-distributions of multi spin-echo MRI images.
Author jondeuce
7 Stars
Updated Last
1 Year Ago
Started In
January 2020

DEcomposition and Component Analysis of Exponential Signals (DECAES)

Dev Build Status Build Status Codecov Coveralls Build Status

DECAES is a fast Julia implementation of the MATLAB toolbox from the UBC MRI Research Centre for computing voxelwise T2-distributions from multi spin-echo MRI images using the extended phase graph algorithm with stimulated echo corrections. Post-processing of these T2-distributions allows for the computation of measures such as the myelin water fraction (MWF) or the luminal water fraction (LWF).

DECAES is written in the open-source Julia programming language. Julia and command line interfaces are available through this package. The examples repository additionally provides a MATLAB interface via the MATLAB function decaes.m. If you use DECAES in your research, please cite our work.


In Julia v1.3 or later you can install DECAES from the Pkg REPL:

pkg> add DECAES

Command Line Interface

This toolbox provides a command line interface (CLI) for processing from the terminal. The CLI takes image files as inputs and performs one or both of T2-distribution computation and T2-parts analysis, the latter of which performs post-processing of the T2-distribution to calculate parameters such as the MWF or LWF. The input image must be one of the following file types:

  1. NIfTI file with extension .nii, or gzip compressed NIfTI file with extension .nii.gz
  2. MATLAB file with extension .mat
  3. Philips PAR/REC file pair with extensions .par and .rec (or .PAR and .REC)
  4. Philips XML/REC file pair with extensions .xml and .rec (or .XML and .REC)

All output files are saved as .mat files in format v7.3.

Basic usage

There are two equivalent ways to use the CLI, assuming DECAES is already installed:

1. Helper script: Create a script called e.g. decaes.jl with the following contents:

using DECAES # load the package
main() # call CLI entrypoint function

This script can then be invoked from the command line as follows:

$ export JULIA_NUM_THREADS=4 # set JULIA_NUM_THREADS > 1 to enable parallel processing
$ julia decaes.jl <COMMAND LINE ARGS>

2. Julia -e flag: The contents of the above script can be written directly at the command line using the -e (for "evaluate") flag:

$ julia -e 'using DECAES; main()' -- <COMMAND LINE ARGS>



Find package documentation at the above link, which includes:

  • The command line interface API, available command line arguments, and examples
  • API reference detailing how to use DECAES.jl from within Julia
  • Other internals and algorithmic details

Examples repository

See the examples repository for a walk-through guide for using the CLI, including example CPMG data for performing MWI, as well as a script for calling the CLI from MATLAB.

Citing this work

Z Med Phys

If you use DECAES in your research, please cite the following:

  title = {{{DECAES}} - {{DEcomposition}} and {{Component Analysis}} of {{Exponential Signals}}},
  author = {Doucette, Jonathan and Kames, Christian and Rauscher, Alexander},
  year = {2020},
  month = may,
  issn = {1876-4436},
  doi = {10.1016/j.zemedi.2020.04.001},
  journal = {Zeitschrift Fur Medizinische Physik},
  keywords = {Brain,Luminal Water Imaging,MRI,Myelin Water Imaging,Prostate},
  language = {eng},
  pmid = {32451148}


Comparison of processing time on various data sets. The MATLAB implementation uses the scripts contained within the MWI_NNLS_toolbox_0319 folder in the ubcmwf github repository. The Julia implementation uses DECAES.jl.

Processor: 3.60GHz Intel Core i7-7700 with 4 CPU cores/8 threads:

Toolbox Parallelism Image Size T2-Distribution Speedup Total Time Speedup
MWI_NNLS_toolbox_0319 4 workers + parfor 240x240x48x48 + mask 01h:29m:35s - 01h:30m:37s -
DECAES 4 threads 240x240x48x48 + mask 00h:01m:35s 57X 00h:02m:34s 35X
DECAES 8 threads 240x240x48x48 + mask 00h:01m:24s 64X 00h:02m:14s 41X
MWI_NNLS_toolbox_0319 4 workers + parfor 240x240x113x56 + mask 02h:25m:19s - 02h:27m:52s -
DECAES 4 threads 240x240x113x56 + mask 00h:02m:34s 57X 00h:04m:00s 37X
DECAES 8 threads 240x240x113x56 + mask 00h:02m:20s 62X 00h:03m:38s 41X
MWI_NNLS_toolbox_0319 4 workers + parfor 240x240x48x48 02h:53m:13s - 02h:54m:24s -
DECAES 8 threads 240x240x48x48 00h:03m:35s 48X 00h:04m:11s 42X
MWI_NNLS_toolbox_0319 4 workers + parfor 240x240x113x56 09h:35m:17s - 09h:39m:33s -
DECAES 8 threads 240x240x113x56 00h:11m:49s 49X 00h:12m:36s 46X

Processor: 2.10GHz Intel Xeon Gold 6130 with 16 CPU cores/32 threads:

Toolbox Parallelism Image Size T2-Distribution Total Time
DECAES 4 threads 240x240x48x48 + mask 04m:01s 04m:14s
DECAES 8 threads 240x240x48x48 + mask 02m:13s 02m:28s
DECAES 16 threads 240x240x48x48 + mask 01m:11s 01m:24s
DECAES 32 threads 240x240x48x48 + mask 00m:57s 01m:09s
DECAES 4 threads 240x240x113x56 + mask 05m:56s 06m:25s
DECAES 8 threads 240x240x113x56 + mask 03m:45s 04m:21s
DECAES 16 threads 240x240x113x56 + mask 02m:09s 02m:37s
DECAES 32 threads 240x240x113x56 + mask 01m:40s 02m:09s

Note: images sizes which include "+ mask" used brain masks generated with the BET tool (done automatically using the --bet flag for DECAES, and manually for MATLAB) and only processed voxels within the brain mask.

The T2-Distribution column shows the time taken to complete the most costly step of the analysis pipeline, calling the function T2mapSEcorr. This function performs the voxelwise nonnegative least-squares (NNLS) analysis to compute T2-distributions. The Total Time column includes image loading and saving time, Julia startup and compilation time, BET brain mask generation, and the post-processing step of calling the T2partSEcorr. Note that MATLAB startup time is not included in the Total Time.

Notes regarding parallelism:

  • MATLAB parallelism is implemented via parfor loops, executing the independent voxelwise T2-distribution computations in parallel. MATLAB parfor loops are rather restrictive, as each loop iteration is executed on separate MATLAB processes. Each loop iteration must be completed independent from each other, which among other restrictions, means memory cannot be shared between loop iterations.
  • Julia parallelism is implemented via the more flexible task-based multi-threading model of parallelism. Communication between threads is possible, and memory can be easily shared and reused among threads. This allows one to perform memory allocation up front: thread-local memory buffers, containing e.g. pre-allocated matrices for intermediate calculations, can be created outside of the parallel loop and efficiently re-used.
  • Julia multithreading makes use of hyperthreads by default. It is possible to configure MATLAB to use hyperthreads in parfor loops, though it is not generally beneficial and indeed we found a ~20% slowdown.