Dynamic Fitting

The dynamic fitting module fsl_mrs.dynamic and command-line tool fsl_dynmrs can simultaneously fit multiple spectra which are linked by an arbitrary model.

“Dynamic” MRS is defined as spectra acquired under changing experimental and/or acquisition conditions. For example functional (fMRS), diffusion weighted MRS (dwMRS), or edited MRS. The FSL-MRS dynamic fitting tools are suitable for fitting all of these types of data.

Requirements

Three things are needed to use the dynamic fitting tools:

  1. A 2D (or higher) dataset - This contains a spectral dimension and at least one other dimension across which spectra change.

  2. A model configuration file - This specifies how each spectrum is related to the others by describing a dynamic model.

  3. A description of the modulating input variables - For example, a file or files with time values or b-values / gradient directions.

  4. One or more sets of basis spectra - Used to perform the linear combination fitting. Different spectra can be fitted using different basis sets.

To run the fitting use the fsl_dynmrs interface. An example using the packaged dwMRS data (found in example_usage/example_data/example_dwmrs) is:

fsl_dynmrs\
--data metab.nii.gz\
--basis basis\
--dyn_config config.py\
--time_variables bvals\
--output dyn_results

The same fit, but run using the interactive python interface is demonstrated in the packaged Example Dynamic Fitting.ipynb

Dataset

The dynamic data should be formatted as NIfTI-MRS with a single ‘higher dimension’ in use. I.e. the fifth dimension should contain the dynamically varying spectra (with the first three dimensions encoding spatial extent and the fourth, the spectral time domain.)

Requisite pre-processing (e.g. coil combination, phase & frequency alignment, etc.) should already have been carried out.

Shaping of the NIfTI-MRS file can be carried out using the mrs_tools command-line tool.

Configuration file

Purpose

The configuration file is a python-formatted (.py) file that describes how the parameters of the dynamic model, known here as free parameters, correspond to the parameters of spectral fitting (e.g., concentrations, lineshapes, phases etc.), known as mapped parameters.

The file contains the explicit mappings, any bounds on the free parameters, and finally a functional description of the dynamic model.

Sections

The file come in three parts:

Parameters variable - dict:

For each spectral fitting parameter type (e.g. concentration, or line-shift eps) this dict parameter defines whether that parameter:

  • Takes a different (unconstrained) value for each b value - variable

  • Has a fixed value across all b values - fixed

  • Or is described by a function of the varying acquisition (time, b-value, etc.) - dynamic

Bounds variable - dict:

This dictionary provides lower and upper bounds for free parameters.

Dynamic models and gradients - function definitions:

If a mapped parameter has been identified as dynamic then a functional relationship between the mapped parameter and the time variable and free parameters must be given.

These relationships are described using python functions. Each function listed in the Parameters dict must be defined. In addition a function providing the gradient of that function must be defined with a name suffix _grad. Custom initialisation functions can be defined for each dynamic function. These must return estimates of the free parameters and named with a suffix _init.

Example Syntax

Example Parameters dict
Parameters = {
 'conc'     : {'dynamic': 'model_exp', 'params':['c_amp','c_adc']},
 'gamma'    : 'fixed',
 'eps'      : 'fixed',
 'Phi_0'    : 'variable',
 'Phi_1'    : 'fixed'
 }

Here we see a simple example of a Parameters dict. It defines a (exponentially decaying) dynamic model for metabolite concentration mapped parameters. In doing so it requires a function model_exp, and defines two free parameters c_amp, c_adc. Zero-order phase Phi_0 is free to vary across all spectra, whilst all other parameters are fixed (including the not listed baseline, which defaults to fixed.)

The above listing of model_exp requires a definition and a definition of the gradient function.

Example function definitions
from numpy import exp, asarray

def model_exp(p, t):
    # p = [amp,adc]
    return p[0] * exp(-p[1] * t)

def model_exp_grad(p, t):
    e1 = exp(-p[1] * t)
    g0 = e1
    g1 = -t * p[0] * e1
    return asarray([g0, g1], dtype=object)

We may also wish to place bounds on the new free parameters. Below we limit the metabolite amplitudes, decay time constants and the line broadening to positive (but otherwise unbounded) values.

Example free parameter bounds
Bounds = {
'c_amp'       : (0, None),
'c_adc'       : (0, None),
'gamma'       : (0,None)
}

More complex models can be defined, with different dynamic models defined per-metabolite (for concentrations) or per-metabolite-group for line widths (sigma, gamma) and shifts (eps).

Example multi-model Parameters dict
 Parameters = {
 'conc' : {'other': {'dynamic': 'model_exp', 'params': ['c_amp', 'c_adc']},
           'Mac':   {'dynamic': 'model_lin', 'params': ['c_amp', 'c_slope']}
           'H2O':   'variable'}}

In the above we provide a nested dict entry for the metabolite concentrations conc entry. This defines that all metabolites except water (H2O) and the macromolecules (Mac) should follow the above exponential decay model. Macromolecules follow a linear decay, and water is free to vary unconstrained by a particular model. Note the names of water and macromolecules would be linked to the specific basis spectra set. Additional function definitions for model_lin and model_lin_grad would be needed. All other parameters would take the default fixed profile.

Other requirements

Two further items are needed:

A set of basis spectra:

In the standard FSL-MRS format (directory of .json files). A different set of basis spectra can be used for each dynamically linked spectra, though all metabolites must appear in each set.

A file (or files) defining the dynamically changing variable(s):

Each file contains a list of one dynamically varying acquisition parameters, one value per spectrum. These values are passed to the functions defined in the configuration file.

Command line Interface Options

Below are detailed explanations of some of the optional arguments in the wrapper script. Type fsl_dynmrs --help to get the full set of available options.

--ppmlim LOW HIGH

Only calculate the loss function within this ppm range.

--baseline_order

Polynomial baseline order. Set to -1 to remove the baseline altogether.

--metab_groups

Group metabolites into sub-groups that get their own lineshape parameters (shift and broadening). This can either be a list of integers (one per metabolite) from 0 to the max number of groups minus one. Or it could be a list of metabolites to be grouped. E.g. using the flag --metab_groups Mac NAA+NAAG+Cr then the Mac spectrum will have its own group, the NAA, NAAG, and Cr will be in a different group, and all other metabolites in a 3rd group. Other possibilities are combine_all and separate_all, where metabs are combined into a single group or separated into distinct groups respectively.

--lorentzian

By default the lineshape is a Voigt (lorentizian+gaussian). Use this flag to set to Lorentzian.

--report

Generate an HTML report of the fitting.

--no_rescale

Do not rescale the input data before fitting. By default all spectra are rescaled using a single scaling factor.