Source code for qef.operators.convolve

import numpy as np
from lmfit import CompositeModel


[docs]def convolve(model, resolution): r"""Convolution of resolution with model data. It is assumed that the resolution FWHM is energy independent. We multiply by spacing :math:`dx` of independent variable :math:`x`. .. math:: (model \otimes resolution)[n] = dx * \sum_m model[m] * resolution[m-n] Parameters ---------- model : numpy.ndarray model data resolution : numpy.ndarray resolution data Returns ------- numpy.ndarray """ # noqa: E501 c = np.convolve(model, resolution, mode='valid') if len(model) % len(resolution) == 0: c = c[:-1] return c
[docs]class Convolve(CompositeModel): r"""Convolution between model and resolution. It is assumed that the resolution FWHM is energy independent. Non-symmetric energy ranges are allowed (when the range of negative values is different than that of positive values). The convolution requires multiplication by the X-spacing to preserve normalization """ def __init__(self, resolution, model, **kws): super(Convolve, self).__init__(resolution, model, convolve, **kws) self.resolution = resolution self.model = model
[docs] def eval(self, params=None, **kwargs): res_data = self.resolution.eval(params=params, **kwargs) # evaluate model on an extended energy range to avoid boundary effects independent_var = self.resolution.independent_vars[0] e = kwargs[independent_var] # energy values neg_e = min(e) - np.flip(e[np.where(e > 0)], axis=0) pos_e = max(e) - np.flip(e[np.where(e < 0)], axis=0) e = np.concatenate((neg_e, e, pos_e)) kwargs.update({independent_var: e}) model_data = self.model.eval(params=params, **kwargs) # Multiply by the X-spacing to preserve normalization de = (e[-1] - e[0])/(len(e) - 1) # energy spacing return de * convolve(model_data, res_data)