Skip to content

models#

Ready-made model functions to fit, grouped by shape.

Pass any of these straight to fitting.fit(data, models.<name>). They cover the common decay/recovery curves (exponential, Gaussian, Lorentzian, stretched), general-purpose shapes (power law, sigmoid), and NMR relaxation dispersion models (CPMG two-/three-site exchange). See each function for its formula and parameters.

bi_exponential #

bi_exponential(
    x: ndarray,
    a1: float,
    tau1: float,
    a2: float,
    tau2: float,
    offset: float,
) -> ndarray

Two-component (bi-exponential) decay.

A sum of two single decays — the go-to model when a sample has two distinct pools relaxing at different rates (e.g. bound vs. free liquid), giving a fast initial drop followed by a slower tail.

\[y = A_1\,e^{-x/\tau_1} + A_2\,e^{-x/\tau_2} + c\]

Parameters:

Name Type Description Default
x ndarray

Independent variable, usually time.

required
a1 float

Amplitude of the first (typically faster) component, \(A_1\).

required
tau1 float

Time constant of the first component, \(\tau_1\).

required
a2 float

Amplitude of the second (typically slower) component, \(A_2\).

required
tau2 float

Time constant of the second component, \(\tau_2\).

required
offset float

Baseline the curve decays towards, \(c\).

required

Returns:

Type Description
ndarray

Predicted \(y\) values, one per element of x.

cpmg_sdr #

cpmg_sdr(
    nu_cpmg: ndarray, r2_0: float, gamma_g2_tau_d: float
) -> ndarray

Static Dephasing Regime (SDR) model for magnetic-particle solutions.

Applies when particles are large enough that the strong local field gradients around them are not averaged out by molecular diffusion. In this regime the relaxation rate no longer depends on the CPMG frequency, so the model returns a flat (frequency-independent) line — a useful null reference when checking whether a sample shows true dispersion.

\[R_2^{\text{eff}} = R_2^{0} + \tfrac{2}{3}\,\gamma^{2} G^{2} \tau_D\]

Parameters:

Name Type Description Default
nu_cpmg ndarray

CPMG frequency. Only its shape is used (the result is constant across it).

required
r2_0 float

Intrinsic relaxation rate, \(R_2^{0}\).

required
gamma_g2_tau_d float

The combined dephasing term \(\gamma^{2} G^{2} \tau_D\) (gyromagnetic ratio, local gradient, and correlation time rolled into one fitted constant).

required

Returns:

Type Description
ndarray

Effective \(R_2\) values (a constant array matching nu_cpmg).

cpmg_three_site #

cpmg_three_site(
    nu_cpmg: ndarray,
    r2_0: float,
    d_omega_ab: float,
    d_omega_ac: float,
    d_omega_bc: float,
    k_eff: float,
    p_a: float,
    p_b: float,
) -> ndarray

Three-site exchange CPMG relaxation dispersion.

Extends the two-site picture to a nucleus exchanging between three environments — for systems with an intermediate state, where each pair of sites contributes its own shift difference and population product.

\[R_2^{\text{eff}} = R_2^{0} + \frac{\Delta\omega_{AB}^{2}\,p_A p_B + \Delta\omega_{AC}^{2}\,p_A p_C + \Delta\omega_{BC}^{2}\,p_B p_C} {k_{\text{eff}} + \nu_{\text{CPMG}}^{2}/k_{\text{eff}}}, \qquad p_C = 1 - p_A - p_B\]

Parameters:

Name Type Description Default
nu_cpmg ndarray

CPMG refocusing frequency \(\nu_{\text{CPMG}}\) (the swept variable).

required
r2_0 float

Intrinsic relaxation rate with no exchange, \(R_2^{0}\).

required
d_omega_ab float

Shift difference between sites A and B, \(\Delta\omega_{AB}\).

required
d_omega_ac float

Shift difference between sites A and C, \(\Delta\omega_{AC}\).

required
d_omega_bc float

Shift difference between sites B and C, \(\Delta\omega_{BC}\).

required
k_eff float

Effective overall exchange rate, \(k_{\text{eff}}\).

required
p_a float

Fractional population of site A, \(p_A\).

required
p_b float

Fractional population of site B, \(p_B\) (site C is \(1 - p_A - p_B\)).

required

Returns:

Type Description
ndarray

Effective \(R_2\) values, one per element of nu_cpmg.

cpmg_tollinger #

cpmg_tollinger(
    nu_cpmg: ndarray,
    r2_0: float,
    delta_omega: float,
    k_ex: float,
    k_ba: float,
) -> ndarray

Two-site exchange dispersion for the slow-exchange limit (Tollinger).

An alternative to r2_effective_carver_richards that is accurate when exchange is slow compared with the shift difference. Use it for CPMG dispersion data where the populations are skewed and the simple fast-exchange form breaks down.

\[R_2^{\text{eff}} = R_2^{0} + k_{AB}\left(1 - \frac{\sin(\Delta\omega\,\tau_{cp})}{\Delta\omega\,\tau_{cp}}\right), \qquad \tau_{cp} = \frac{1}{2\,\nu_{\text{CPMG}}}, \quad k_{AB} = k_{\text{ex}} - k_{BA}\]

Reference: Tollinger et al., J. Am. Chem. Soc. 2001, 123, 11341.

Parameters:

Name Type Description Default
nu_cpmg ndarray

CPMG refocusing frequency \(\nu_{\text{CPMG}}\) (the swept variable).

required
r2_0 float

Intrinsic relaxation rate with no exchange, \(R_2^{0}\).

required
delta_omega float

Chemical-shift difference between the two sites, \(\Delta\omega\) (rad/s).

required
k_ex float

Total exchange rate, \(k_{\text{ex}}\).

required
k_ba float

Reverse (B→A) exchange rate, \(k_{BA}\); the forward rate is \(k_{AB} = k_{\text{ex}} - k_{BA}\).

required

Returns:

Type Description
ndarray

Effective \(R_2\) values, one per element of nu_cpmg.

cpmg_two_site #

cpmg_two_site(
    nu_cpmg: ndarray,
    r2_0: float,
    delta_omega: float,
    k_ex: float,
    p_a: float,
) -> ndarray

Two-site exchange CPMG relaxation dispersion (Carver–Richards form).

Fits how the effective transverse relaxation rate \(R_2^{\text{eff}}\) changes with the CPMG pulsing frequency when a nucleus hops between two environments (e.g. a protein switching between two conformations). The rate is highest when slow pulsing lets exchange dephase the signal and drops as fast pulsing refocuses it — the classic dispersion curve used to extract exchange rates and populations.

\[R_2^{\text{eff}}(\nu_{\text{CPMG}}) = R_2^{0} + \frac{\Delta\omega^{2}}{2}\, \frac{k_{\text{ex}}\,p_A\,p_B}{k_{\text{ex}}^{2} + \nu_{\text{CPMG}}^{2}}, \qquad p_B = 1 - p_A\]

Parameters:

Name Type Description Default
nu_cpmg ndarray

CPMG refocusing frequency \(\nu_{\text{CPMG}}\) (the swept variable).

required
r2_0 float

Intrinsic relaxation rate with no exchange, \(R_2^{0}\).

required
delta_omega float

Chemical-shift difference between the two sites, \(\Delta\omega\) (rad/s).

required
k_ex float

Total exchange rate between the sites, \(k_{\text{ex}}\).

required
p_a float

Fractional population of site A, \(p_A\) (site B is \(1 - p_A\)).

required

Returns:

Type Description
ndarray

Effective \(R_2\) values, one per element of nu_cpmg.

double_sigmoid #

double_sigmoid(
    x: ndarray,
    a1: float,
    c1: float,
    w1: float,
    a2: float,
    c2: float,
    w2: float,
    offset: float,
) -> ndarray

Two stacked sigmoids for a two-step transition.

Sums two S-shaped curves, so it can fit data that switches levels twice — e.g. a system with two sequential transitions or two unfolding events.

\[y = \frac{A_1}{1 + e^{-(x - c_1)/w_1}} + \frac{A_2}{1 + e^{-(x - c_2)/w_2}} + c\]

Parameters:

Name Type Description Default
x ndarray

Independent variable.

required
a1 float

Height of the first step, \(A_1\).

required
c1 float

Midpoint of the first step, \(c_1\).

required
w1 float

Steepness of the first step, \(w_1\).

required
a2 float

Height of the second step, \(A_2\).

required
c2 float

Midpoint of the second step, \(c_2\).

required
w2 float

Steepness of the second step, \(w_2\).

required
offset float

Lower plateau the curve rises from, \(c\).

required

Returns:

Type Description
ndarray

Predicted \(y\) values, one per element of x.

exponential_decay #

exponential_decay(
    x: ndarray,
    amplitude: float,
    time_constant: float,
    offset: float,
) -> ndarray

Single-rate exponential decay.

The workhorse for anything that falls from a starting level to a flat baseline at one characteristic rate: transverse (\(T_2\)) relaxation, a free-induction-decay envelope, or a generic intensity that dies away.

\[y = A\,e^{-x/\tau} + c\]

Parameters:

Name Type Description Default
x ndarray

Independent variable, usually time.

required
amplitude float

Starting height above the baseline, \(A\).

required
time_constant float

Decay constant \(\tau\) (the value of \(x\) at which the signal falls to \(1/e \approx 37\%\) of \(A\)).

required
offset float

Baseline the curve decays towards, \(c\).

required

Returns:

Type Description
ndarray

Predicted \(y\) values, one per element of x.

exponential_plateau #

exponential_plateau(
    x: ndarray,
    amplitude: float,
    time_constant: float,
    offset: float,
) -> ndarray

Exponential build-up to a plateau (saturation-recovery \(T_1\)).

Mirror image of a decay: the signal grows from the baseline and levels off at \(A + c\). This is the saturation-recovery longitudinal-relaxation curve, where magnetisation rebuilds along the field after being saturated.

\[y = A\left(1 - e^{-x/\tau}\right) + c\]

Parameters:

Name Type Description Default
x ndarray

Independent variable, usually the recovery delay.

required
amplitude float

Total rise from baseline to plateau, \(A\).

required
time_constant float

Recovery constant \(\tau\) (\(T_1\)); the signal reaches \(\approx 63\%\) of its final rise at \(x = \tau\).

required
offset float

Baseline the curve starts from, \(c\).

required

Returns:

Type Description
ndarray

Predicted \(y\) values, one per element of x.

gaussian_decay #

gaussian_decay(
    x: ndarray,
    amplitude: float,
    time_constant: float,
    offset: float,
) -> ndarray

Gaussian (bell-shaped) decay.

Falls off faster than an exponential at first and then more gently — the shape produced by a spread of frequencies rather than a single rate. Typical of strongly-coupled solids and inhomogeneously broadened signals, where it gives a Gaussian line in the spectrum.

\[y = A\,e^{-(x/\tau)^{2}} + c\]

Parameters:

Name Type Description Default
x ndarray

Independent variable, usually time.

required
amplitude float

Starting height above the baseline, \(A\).

required
time_constant float

Decay constant \(\tau\) (sets the width of the bell).

required
offset float

Baseline the curve decays towards, \(c\).

required

Returns:

Type Description
ndarray

Predicted \(y\) values, one per element of x.

gaussian_lorentzian #

gaussian_lorentzian(
    x: ndarray,
    a_gauss: float,
    tau_gauss: float,
    a_lorentz: float,
    tau_lorentz: float,
    offset: float,
) -> ndarray

Combined Gaussian + Lorentzian decay (Voigt-like).

Adds a Gaussian and an exponential (Lorentzian) decay together, so it can capture signals that are partly inhomogeneously broadened (Gaussian) and partly homogeneously broadened (Lorentzian) — the time-domain analogue of a Voigt lineshape. Useful when neither pure shape fits the data alone.

\[y = A_g\,e^{-(x/\tau_g)^{2}} + A_l\,e^{-x/\tau_l} + c\]

Parameters:

Name Type Description Default
x ndarray

Independent variable, usually time.

required
a_gauss float

Amplitude of the Gaussian part, \(A_g\).

required
tau_gauss float

Time constant of the Gaussian part, \(\tau_g\).

required
a_lorentz float

Amplitude of the Lorentzian (exponential) part, \(A_l\).

required
tau_lorentz float

Time constant of the Lorentzian part, \(\tau_l\).

required
offset float

Baseline the curve decays towards, \(c\).

required

Returns:

Type Description
ndarray

Predicted \(y\) values, one per element of x.

lorentzian_decay #

lorentzian_decay(
    x: ndarray,
    amplitude: float,
    time_constant: float,
    offset: float,
) -> ndarray

Lorentzian decay (exponential in time, Lorentzian in the spectrum).

A plain exponential decay in the time domain Fourier-transforms into a Lorentzian line in the spectrum, so this is the model for homogeneously broadened signals with a single \(T_2\). It is identical in form to ExponentialModels.exponential_decay; the name reflects the lineshape it produces, not a different equation.

\[y = A\,e^{-x/\tau} + c\]

Parameters:

Name Type Description Default
x ndarray

Independent variable, usually time.

required
amplitude float

Starting height above the baseline, \(A\).

required
time_constant float

Decay constant \(\tau\) (\(T_2\)); sets the linewidth of the resulting Lorentzian.

required
offset float

Baseline the curve decays towards, \(c\).

required

Returns:

Type Description
ndarray

Predicted \(y\) values, one per element of x.

power_law #

power_law(
    x: ndarray,
    amplitude: float,
    exponent: float,
    offset: float,
) -> ndarray

Power-law relationship.

For quantities that scale as a power of \(x\) rather than rising or decaying exponentially — e.g. signal attenuation versus gradient strength, or any process that looks like a straight line on a log–log plot.

\[y = A\,x^{p} + c\]

Parameters:

Name Type Description Default
x ndarray

Independent variable.

required
amplitude float

Overall scale factor, \(A\).

required
exponent float

Power \(p\) (negative for a falling curve, positive for a rising one).

required
offset float

Vertical offset, \(c\).

required

Returns:

Type Description
ndarray

Predicted \(y\) values, one per element of x.

sigmoid #

sigmoid(
    x: ndarray,
    amplitude: float,
    center: float,
    width: float,
    offset: float,
) -> ndarray

Sigmoid (S-shaped) transition.

Describes a smooth step from one level to another: titration and dose–response curves, melting/transition profiles, or any quantity that switches between two plateaus around a threshold.

\[y = \frac{A}{1 + e^{-(x - x_0)/w}} + c\]

Parameters:

Name Type Description Default
x ndarray

Independent variable.

required
amplitude float

Total height of the step, \(A\).

required
center float

Midpoint \(x_0\) where the curve is halfway through the transition.

required
width float

Steepness \(w\); smaller is a sharper step, larger is more gradual.

required
offset float

Lower plateau the curve rises from, \(c\).

required

Returns:

Type Description
ndarray

Predicted \(y\) values, one per element of x.

stretched_exponential #

stretched_exponential(
    x: ndarray,
    amplitude: float,
    time_constant: float,
    beta: float,
    offset: float,
) -> ndarray

Stretched exponential (Kohlrausch–Williams–Watts).

A decay that is not governed by a single rate but by a distribution of rates — typical of disordered, glassy, or porous systems where many environments relax at slightly different speeds. The stretch exponent \(\beta\) controls how broad that distribution is (\(\beta = 1\) recovers an ordinary single exponential).

\[y = A\,e^{-(x/\tau)^{\beta}} + c\]

Parameters:

Name Type Description Default
x ndarray

Independent variable, usually time.

required
amplitude float

Starting height above the baseline, \(A\).

required
time_constant float

Characteristic time \(\tau\).

required
beta float

Stretch exponent, \(0 < \beta \le 1\); smaller means a wider spread of underlying rates.

required
offset float

Baseline the curve decays towards, \(c\).

required

Returns:

Type Description
ndarray

Predicted \(y\) values, one per element of x.