epyr.baseline.models

Mathematical models for baseline correction.

Pure functions used by epyr.baseline.correction and the automatic model-selection code; no data processing logic lives here. All models are parameterized so that scipy.optimize.curve_fit can call them directly.

Functions

bi_exponential_1d(x, A1, tau1, A2, tau2[, ...])

Sum of two exponential decays.

exponential_1d(x, A, tau[, offset])

Single exponential decay.

get_model_function(model_name[, dimension])

Return the callable for a registered model.

list_available_models()

Return the names of registered baseline models.

polynomial_1d(x, *coeffs)

Evaluate a 1D polynomial.

polynomial_2d(xy, *coeffs)

Evaluate a 2D polynomial surface on flattened coordinates.

stretched_exponential_1d(x, A, tau, beta[, ...])

Stretched-exponential (Kohlrausch-Williams-Watts) decay.

epyr.baseline.models.polynomial_2d(xy, *coeffs)[source]

Evaluate a 2D polynomial surface on flattened coordinates.

The polynomial order is inferred from the number of coefficients: a square layout (order+1)**2 is tried first, falling back to a rectangular (nx+1)*(ny+1) decomposition.

Parameters:
  • xy (tuple of (np.ndarray, np.ndarray)) – Flattened x and y coordinate arrays of identical shape.

  • *coeffs (float) – Polynomial coefficients, ordered as c[i*(order_y+1)+j] for the x**i * y**j term.

Returns:

Flattened surface values, same shape as xy[0].

Return type:

np.ndarray

Raises:

ValueError – If len(coeffs) does not factor as (nx+1)*(ny+1) with nx, ny < 10.

Examples

>>> import numpy as np
>>> from epyr.baseline.models import polynomial_2d
>>> x, y = np.meshgrid(np.linspace(0, 1, 5), np.linspace(0, 1, 5))
>>> z = polynomial_2d((x.ravel(), y.ravel()), 1.0, 2.0, 3.0, 4.0)  # bilinear
>>> z.shape
(25,)
epyr.baseline.models.stretched_exponential_1d(x, A, tau, beta, offset=0.0)[source]

Stretched-exponential (Kohlrausch-Williams-Watts) decay.

\[y(x) = \mathrm{offset} + A \exp\!\left[-(x/\tau)^{\beta}\right]\]

Commonly used for T2 echo decay in disordered systems.

Parameters:
  • x (np.ndarray) – Independent variable (time, often in microseconds).

  • A (float) – Amplitude.

  • tau (float) – Characteristic decay time, same unit as x.

  • beta (float) – Stretching exponent in (0, 5]. beta = 1 recovers a pure exponential; beta < 1 is sub-exponential; beta > 1 super.

  • offset (float, optional) – Constant baseline. Default 0.

Returns:

Decay values, same shape as x.

Return type:

np.ndarray

Examples

>>> import numpy as np
>>> from epyr.baseline.models import stretched_exponential_1d
>>> t = np.linspace(0, 5, 100)  # microseconds
>>> y = stretched_exponential_1d(t, A=1.0, tau=1.5, beta=0.7)
>>> y[0], round(y[-1], 4)
(1.0, 0.098)
epyr.baseline.models.bi_exponential_1d(x, A1, tau1, A2, tau2, offset=0.0)[source]

Sum of two exponential decays.

\[y(x) = \mathrm{offset} + A_1 e^{-x/\tau_1} + A_2 e^{-x/\tau_2}\]

Useful when a system has two well-separated relaxation channels.

Parameters:
  • x (np.ndarray) – Independent variable.

  • A1 (float) – Component amplitudes.

  • A2 (float) – Component amplitudes.

  • tau1 (float) – Component decay times, same unit as x. Order does not matter.

  • tau2 (float) – Component decay times, same unit as x. Order does not matter.

  • offset (float, optional) – Constant baseline. Default 0.

Returns:

Decay values.

Return type:

np.ndarray

Examples

>>> import numpy as np
>>> from epyr.baseline.models import bi_exponential_1d
>>> t = np.linspace(0, 10, 200)
>>> y = bi_exponential_1d(t, A1=0.7, tau1=0.5, A2=0.3, tau2=4.0, offset=0.05)
>>> round(y[0], 3), round(y[-1], 4)
(1.05, 0.0747)
epyr.baseline.models.polynomial_1d(x, *coeffs)[source]

Evaluate a 1D polynomial.

\[y(x) = a_0 + a_1 x + a_2 x^2 + \ldots + a_n x^n\]
Parameters:
  • x (np.ndarray) – Independent variable.

  • *coeffs (float) – Coefficients in ascending order of degree, [a0, a1, ..., an].

Returns:

Polynomial values (float).

Return type:

np.ndarray

Examples

>>> import numpy as np
>>> from epyr.baseline.models import polynomial_1d
>>> x = np.linspace(-1, 1, 5)
>>> polynomial_1d(x, 1.0, 0.0, 2.0)  # 1 + 2*x**2
array([3. , 1.5, 1. , 1.5, 3. ])
epyr.baseline.models.exponential_1d(x, A, tau, offset=0.0)[source]

Single exponential decay.

\[y(x) = \mathrm{offset} + A \exp(-x/\tau)\]
Parameters:
  • x (np.ndarray) – Independent variable.

  • A (float) – Amplitude.

  • tau (float) – Decay time, same unit as x.

  • offset (float, optional) – Constant baseline. Default 0.

Returns:

Decay values.

Return type:

np.ndarray

Examples

>>> import numpy as np
>>> from epyr.baseline.models import exponential_1d
>>> t = np.linspace(0, 5, 50)
>>> y = exponential_1d(t, A=1.0, tau=1.0)
>>> round(y[0], 3), round(y[-1], 4)
(1.0, 0.0067)
epyr.baseline.models.get_model_function(model_name, dimension='1d')[source]

Return the callable for a registered model.

Parameters:
  • model_name (str) – Key from MODEL_INFO ('polynomial', 'stretched_exponential', 'bi_exponential', 'exponential').

  • dimension ({'1d', '2d'}, optional) – Function variant. Most models only provide '1d'; only the polynomial model supports '2d'. Default '1d'.

Returns:

The model function, ready to pass to scipy.optimize.curve_fit.

Return type:

callable

Raises:

ValueError – If model_name is unknown or the requested dimension variant does not exist.

Examples

>>> from epyr.baseline.models import get_model_function
>>> f = get_model_function("stretched_exponential")
>>> f.__name__
'stretched_exponential_1d'
epyr.baseline.models.list_available_models()[source]

Return the names of registered baseline models.

Returns:

Model keys usable with get_model_function() and MODEL_INFO.

Return type:

list of str

Examples

>>> from epyr.baseline.models import list_available_models
>>> sorted(list_available_models())
['bi_exponential', 'exponential', 'polynomial', 'stretched_exponential']