Models

The models implemented in this package build on the general two-compartment IVIM model

\[S = S_0 ((1-f)F_D + fe^{-bD_b}F_P)\]

where S and S0 are the signal with and without diffusion weighting, respectively, f is the signal fraction of the perfusion compartment, FD describes the signal decay due to diffusion weighting in the diffusion (extravascular) compartment, b is the b-value, Db is the diffusion coefficient of blood, and FP describes the signal decay due to diffusion weighting in the perfusion (vascular) compartment.[1],[2]

By default is it assumed that sufficiently small b-values are used such that FD can be decribed by a monoexponential (API)

\[F_D = e^{-bD}\]

although there is support for the kurtosis expression (API) if higher b-values are of interest

\[F_D = e^{-bD+b^2D^2K/6}\]

where D is the extravascular diffusion coefficient, and K is the kurtosis koefficient.[3]

The expression for FP depends on the what temporal regime is assumed and choice of pulse sequence. Currently, the code supports models in the ballistic (short encoding time), diffusive (long encoding time), and intermediate (short to long encoding time) regimes. The specific expression for FP in the ballistic regime (API) is

\[F_P = e^{-c^2v^2/6}\]

where c describes the velocity encoding and v is the root-mean-squared velocity of blood.[4] The expression for FP in the diffusive regime (API) is

\[F_P = e^{-bD^*}\]

where D* is the pseudo-diffusion coefficient.[1] The expression in the intermediate regime (API) is

\[F_P = \exp{-\gamma^2G^2v^2\frac{\tau}{3}p[\tau^3(\Psi+\Omega) - 2\delta\tau^2 + \delta^2(\Delta-\frac{\delta}{3})]}\]
\[\Psi = e^{-(\Delta+\delta)/\tau}[e^{\delta/\tau}-1][2e^{\Delta/\tau}+e^{\delta/\tau}-1]\]
\[\begin{split}\Omega = \begin{cases} 0 & \text{Monopolar} \\ \frac{k}{p}[e^{\Delta/\tau}-1]^2[e^{\delta/\tau}-1]^2e^{-T/\tau} & \text{Bipolar} \end{cases}\end{split}\]

where \(\gamma\) is the gyromagnetic ratio, G is the gradient strength, tau is the correlation time of the motion of blood, p takes values 1 for a monopolar pulse sequence and 2 for a bipolar pulse sequence, k takes values -1 and 1 for flow-compensated and non-flow-compensated diffusion encoding, and T is the total encoding time (start of first diffusion encoding gradient to end of last one).[5]

Additionally, if b-values are either zero or sufficiently large such that FP is approximately zero, a simplified expression can be used (API)

\[\begin{split}F_P = \begin{cases} 1 & b = 0 \\ 0 & b \geq b_{thr} \end{cases}\end{split}\]

where bthr is the threshold b-value where \(F_P \approx 0\).[1]

Analytical jacobian matrices are available for all models (API).

References:

API

ivim.models

This module provides functions to generate MR signal and corresponding Jacobians based on IVIM parameters.

ivim.models.sIVIM(b: ndarray[Any, dtype[float64]], D: ndarray[Any, dtype[float64]], f: ndarray[Any, dtype[float64]], S0: ndarray[Any, dtype[float64]] = 1, K: ndarray[Any, dtype[float64]] = 0) ndarray[Any, dtype[float64]]

Return MR signal based on the simplified IVIM (sIVIM) model.

Parameters:
  • b – vector of b-values [s/mm2]

  • D – ND array of diffusion coefficients [mm2/s]

  • f – ND array of perfusion fractions (same shape as D or scalar)

  • S0 – (optional) ND array of signal values at b == 0 (same shape as D or scalar)

  • K – (optional) ND array of kurtosis coefficients (same shape as D or scalar)

Output:

S: (N+1)D array of signal values

ivim.models.diffusive(b: ndarray[Any, dtype[float64]], D: ndarray[Any, dtype[float64]], f: ndarray[Any, dtype[float64]], Dstar: ndarray[Any, dtype[float64]], S0: ndarray[Any, dtype[float64]] = 1, K: ndarray[Any, dtype[float64]] = 0) ndarray[Any, dtype[float64]]

Return MR signal based on the diffusive IVIM model with \(F_P = e^{-bD^*}\).

Parameters:
  • b – vector of b-values [s/mm2]

  • D – ND array of diffusion coefficients [mm2/s]

  • f – ND array of perfusion fractions (same shape as D or scalar)

  • Dstar – ND array of pseudo-diffusion coefficients [mm2/s] (same shape as D or scalar)

  • S0 – (optional) ND array of signal values at b == 0 (same shape as D or scalar)

  • K – (optional) ND array of kurtosis coefficients (same shape as D or scalar)

Output:

S: (N+1)D array of signal values

ivim.models.ballistic(b: ndarray[Any, dtype[float64]], c: ndarray[Any, dtype[float64]], D: ndarray[Any, dtype[float64]], f: ndarray[Any, dtype[float64]], v: ndarray[Any, dtype[float64]], S0: ndarray[Any, dtype[float64]] = 1, K: ndarray[Any, dtype[float64]] = 0) ndarray[Any, dtype[float64]]

Return MR signal based on the ballistic IVIM model with \(F_P = e^{-c^2v^2/6}\).

Parameters:
  • b – vector of b-values [s/mm2]

  • c – vector of c-values [s/mm]

  • D – ND array of diffusion coefficients [mm2/s]

  • f – ND array of perfusion fractions (same shape as D or scalar)

  • v – ND array of velocities [mm/s] (same shape as D or scalar)

  • S0 – (optional) ND array of signal values at b == 0 (same shape as D or scalar)

  • K – (optional) ND array of kurtosis coefficients (same shape as D or scalar)

Output:

S: (N+1)D array of signal values

ivim.models.intermediate(b: ndarray[Any, dtype[float64]], delta: ndarray[Any, dtype[float64]], Delta: ndarray[Any, dtype[float64]], D: ndarray[Any, dtype[float64]], f: ndarray[Any, dtype[float64]], v: ndarray[Any, dtype[float64]], tau: ndarray[Any, dtype[float64]], S0: ndarray[Any, dtype[float64]] = 1, K: ndarray[Any, dtype[float64]] = 0, seq='monopolar', T: ndarray[Any, dtype[float64]] | None = None, k: ndarray[Any, dtype[float64]] | None = None) ndarray[Any, dtype[float64]]

Return MR signal based on the intermediate IVIM model.

Parameters:
  • b – vector of b-values [s/mm2]

  • delta – vector of gradient durations [s]

  • Delta – vector of gradient separations [s]

  • D – ND array of diffusion coefficients [mm2/s]

  • f – ND array of perfusion fractions (same shape as D or scalar)

  • v – ND array of velocities [mm/s] (same shape as D or scalar)

  • tau – ND array of correlation times [s] (same shape as D or scalar)

  • S0 – (optional) ND array of signal values at b == 0 (same shape as D or scalar)

  • K – (optional) ND array of kurtosis coefficients (same shape as D or scalar)

  • seq – (optional) pulse sequence used (monopolar or bipolar)

  • T – (optional) vector of encoding times [s]

  • k – (optional) vector indicating if bipolar pulse sequence is flow compensated or not [-1/1]

Output:

S: (N+1)D array of signal values

ivim.models.monoexp(b: ndarray[Any, dtype[float64]], D: ndarray[Any, dtype[float64]]) ndarray[Any, dtype[float64]]

Return the monoexponential \(e^{-bD}\).

Parameters:
  • b – vector of b-values [s/mm2]

  • D – ND array of diffusion coefficients [mm2/s]

Output:

S: (N+1)D array of signal values

ivim.models.kurtosis(b: ndarray[Any, dtype[float64]], D: ndarray[Any, dtype[float64]], K: ndarray[Any, dtype[float64]]) ndarray[Any, dtype[float64]]

Return the kurtosis signal representation \(e^{-bD+b^2D^2K/6}\).

Parameters:
  • b – vector of b-values [s/mm2]

  • D – ND array of diffusion coefficients [mm2/s]

  • K – ND array of kurtosis coefficients (same shape as D or scalar)

Output:

S: (N+1)D array of signal values

ivim.models.monoexp_jacobian(b: ndarray[Any, dtype[float64]], D: ndarray[Any, dtype[float64]]) ndarray[Any, dtype[float64]]

Return the Jacobian matrix for the monoexponential expression.

Parameters:
  • b – vector of b-values [s/mm2]

  • D – ND array of diffusion coefficients [mm2/s]

Output:

J: Jacobian matrix

ivim.models.kurtosis_jacobian(b: ndarray[Any, dtype[float64]], D: ndarray[Any, dtype[float64]], K: ndarray[Any, dtype[float64]]) ndarray[Any, dtype[float64]]

Return the Jacobian matrix for the monoexponential expression.

Parameters:
  • b – vector of b-values [s/mm2]

  • D – ND array of diffusion coefficients [mm2/s]

  • K – ND array of kurtosis coefficients (same shape as D or scalar)

Output:

J: Jacobian matrix

ivim.models.sIVIM_jacobian(b: ndarray[Any, dtype[float64]], D: ndarray[Any, dtype[float64]], f: ndarray[Any, dtype[float64]], S0: ndarray[Any, dtype[float64]] | None = None, K: ndarray[Any, dtype[float64]] | None = None) ndarray[Any, dtype[float64]]

Return the Jacobian matrix for the simplified IVIM (sIVIM) model.

Parameters:
  • b – vector of b-values [s/mm2]

  • D – ND array of diffusion coefficients [mm2/s]

  • f – ND array of perfusion fractions (same shape as D or scalar)

  • S0 – (optional) ND array of signal values at b == 0 (same shape as D or scalar)

  • K – (optional) ND array of kurtosis coefficients (same shape as D or scalar)

Output:

J: Jacobian matrix

ivim.models.diffusive_jacobian(b: ndarray[Any, dtype[float64]], D: ndarray[Any, dtype[float64]], f: ndarray[Any, dtype[float64]], Dstar: ndarray[Any, dtype[float64]], S0: ndarray[Any, dtype[float64]] | None = None, K: ndarray[Any, dtype[float64]] | None = None) ndarray[Any, dtype[float64]]

Return the Jacobian matrix for the diffusive IVIM model.

Parameters:
  • b – vector of b-values [s/mm2]

  • D – ND array of diffusion coefficients [mm2/s]

  • f – ND array of perfusion fractions (same shape as D or scalar)

  • Dstar – ND array of perfusion fractions (same shape as D or scalar)

  • S0 – (optional) ND array of signal values at b == 0 (same shape as D or scalar)

  • K – (optional) ND array of kurtosis coefficients (same shape as D or scalar)

Output:

J: Jacobian matrix

ivim.models.ballistic_jacobian(b: ndarray[Any, dtype[float64]], c: ndarray[Any, dtype[float64]], D: ndarray[Any, dtype[float64]], f: ndarray[Any, dtype[float64]], v: ndarray[Any, dtype[float64]], S0: ndarray[Any, dtype[float64]] | None = None, K: ndarray[Any, dtype[float64]] | None = None) ndarray[Any, dtype[float64]]

Return the Jacobian matrix for the ballistic IVIM model.

Parameters:
  • b – vector of b-values [s/mm2]

  • c – vector of c-values [s/mm]

  • D – ND array of diffusion coefficients [mm2/s]

  • f – ND array of perfusion fractions (same shape as D or scalar)

  • v – ND array of velocities [mm/s] (same shape as D or scalar)

  • S0 – (optional) ND array of signal values at b == 0 (same shape as D or scalar)

  • K – (optional) ND array of kurtosis coefficients (same shape as D or scalar)

Output:

J: Jacobian matrix

ivim.models.intermediate_jacobian(b: ndarray[Any, dtype[float64]], delta: ndarray[Any, dtype[float64]], Delta: ndarray[Any, dtype[float64]], D: ndarray[Any, dtype[float64]], f: ndarray[Any, dtype[float64]], v: ndarray[Any, dtype[float64]], tau: ndarray[Any, dtype[float64]], S0: ndarray[Any, dtype[float64]] | None = None, K: ndarray[Any, dtype[float64]] | None = None, seq: str = 'monopolar', T: ndarray[Any, dtype[float64]] | None = None, k: ndarray[Any, dtype[float64]] | None = None) ndarray[Any, dtype[float64]]

Return the Jacobian matrix for the ballistic IVIM model.

Parameters:
  • b – vector of b-values [s/mm2]

  • delta – vector of deltas [s]

  • Delta – vector of deltas [s]

  • D – ND array of diffusion coefficients [mm2/s]

  • f – ND array of perfusion fractions (same shape as D or scalar)

  • v – ND array of velocity [mm/s] (same shape as D or scalar)

  • tau – ND array of correlation times [s] (same shape as D or scalar)

  • S0 – (optional) ND array of signal values at b == 0 (same shape as D or scalar)

  • K – (optional) ND array of kurtosis coefficients (same shape as D or scalar)

  • seq – (optional) pulse sequence used (monopolar or bipolar)

  • T – (optional) vector of encoding times [s]

  • k – (optional) vector indicating if bipolar pulse sequence is flow compensated or not [-1/1]

Output:

J: Jacobian matrix