Source code for glotaran.builtin.models.kinetic_image.irf

"""This package contains irf items."""

from typing import List

import numpy as np

from glotaran.model import model_attribute
from glotaran.model import model_attribute_typed
from glotaran.parameter import Parameter


[docs]@model_attribute(has_type=True) class IrfMeasured: """A measured IRF. The data must be supplied by the dataset."""
[docs]@model_attribute( properties={ "center": List[Parameter], "width": List[Parameter], "scale": {"type": List[Parameter], "allow_none": True}, "normalize": {"type": bool, "default": False}, "backsweep": {"type": bool, "default": False}, "backsweep_period": {"type": Parameter, "allow_none": True}, }, has_type=True, ) class IrfMultiGaussian: """ Represents a gaussian IRF. One width and one center is a single gauss. One center and multiple widths is a multiple gaussian. Multiple center and multiple widths is Double-, Triple- , etc. Gaussian. Parameters ---------- label: label of the irf center: one or more center of the irf as parameter indices width: one or more widths of the gaussian as parameter index center_dispersion: polynomial coefficients for the dispersion of the center as list of parameter indices. None for no dispersion. width_dispersion: polynomial coefficients for the dispersion of the width as parameter indices. None for no dispersion. """
[docs] def parameter(self, index): centers = self.center if isinstance(self.center, list) else [self.center] centers = np.asarray([c.value for c in centers]) widths = self.width if isinstance(self.width, list) else [self.width] widths = np.asarray([w.value for w in widths]) len_centers = len(centers) len_widths = len(widths) if len_centers != len_widths: if min(len_centers, len_widths) != 1: raise ValueError( f"len(centers) ({len_centers}) not equal " f"len(widths) ({len_widths}) none of is 1." ) if len_centers == 1: centers = [centers[0] for _ in range(len_widths)] len_centers = len_widths else: widths = [widths[0] for _ in range(len_centers)] len_widths = len_centers scale = self.scale if self.scale is not None else [1.0 for _ in centers] scale = scale if isinstance(scale, list) else [scale] scale = np.asarray(scale) backsweep = self.backsweep backsweep_period = self.backsweep_period.value if self.backsweep else 0 return centers, widths, scale, backsweep, backsweep_period
[docs] def calculate(self, index, axis): center, width, scale, _, _ = self.parameter(index) irf = scale[0] * np.exp(-1 * (axis - center[0]) ** 2 / (2 * width[0] ** 2)) if len(center) > 1: for i in range(1, len(center)): irf += scale[i] * np.exp(-1 * (axis - center[i]) ** 2 / (2 * width[i] ** 2)) return irf
[docs]@model_attribute( properties={ "center": Parameter, "width": Parameter, }, has_type=True, ) class IrfGaussian(IrfMultiGaussian): pass
[docs]@model_attribute_typed( types={ "gaussian": IrfGaussian, "multi-gaussian": IrfMultiGaussian, "measured": IrfMeasured, } ) class Irf: """Represents an IRF."""