Source code for aim2dat.fct.smearing

"""Module to implement different smearing methods."""

# Third party library imports
import numpy as np
from scipy.ndimage import filters


def _gaussian(x: np.array, sigma: float) -> np.array:
    """Gaussian function.

    Parameters
    ----------
    x : np.array
        x-values.
    sigma : float
        Scale parameter corresponding to the standard deviation.

    Returns
    -------
    np.array
        Gaussian function values.

    """
    return 1 / np.sqrt(2 * np.pi * sigma**2) * np.exp(-(x**2) / (2 * sigma**2))


def _lorentzian(x: np.array, sigma: float) -> np.array:
    """Lorentzian function.

    Parameters
    ----------
    x : np.array
        x-values.
    sigma : float
        Scale parameter corresponding to the full-width at half-maximum (FWHM).

    Returns
    -------
    np.array
        Lorentzian function values.

    """
    return 1 / np.pi * 0.5 * sigma / (x**2 + (0.5 * sigma) ** 2)


AVAILABLE_SMEARING_METHODS = {"gaussian": _gaussian, "lorentzian": _lorentzian}


[docs] def apply_smearing( y: np.array, sampling_width: float = 1.0, sigma: float = 0.5, radius: int = None, method: str = "gaussian", ) -> np.array: """Apply smearing to a dataset. Different smearing methods can be specified. Parameters ---------- y : np.array y-values of dataset. sampling_width : float Sampling width of the x-axis, i.e. distance between adjacent x-values. Defaults to 1.0. sigma : float Scale parameter. Defaults to 0.5. radius : int Radius of the kernel. method : str String to specify smearing method, see AVAILABLE_SMEARING_METHODS. Defaults to 'gaussian'. Returns ------- np.array Smeared y-values. """ smearing_method = AVAILABLE_SMEARING_METHODS[method] if radius is None: radius = int(4 * sigma + 0.5) weights = smearing_method(np.arange(-radius, radius + sampling_width, sampling_width), sigma) weights = weights / weights.sum() y_smeared = np.convolve(y, weights, mode="same") return y_smeared
# Class implementation of the above functions class _BaseSmearing: _allowed_methods = ["gaussian", "lorentzian"] def __init__(self, method="gaussian"): self.method = method @property def method(self): """Smearing method.""" return self._method @method.setter def method(self, value): if value not in self._allowed_methods: raise ValueError(f"Smearing method {value} is not supported.") self._method = value @staticmethod def _gaussian(x, sigma): """Gaussian function.""" return _gaussian(x, sigma) @staticmethod def _lorentzian(x, sigma): """Lorentzian function.""" return _lorentzian(x, sigma) def apply_smearing(self, x, y): """Apply smearing.""" smearing_method = getattr(self, self.method) weights = smearing_method(x, self.sigma) weights = weights / weights.sum() y_total = np.sum(y) y_smeared = filters.convolve1d(y, weights) y_smeared = y_total / y_smeared.sum() * y_smeared return y_smeared