Source code for carspy.convol_fcn

"""Functions used in the convolution of CARS spectrum.

- Laser lineshape
- Impulse spectral response function (ISRF) for the spectrometer slit
"""
import numpy as np


[docs]def gaussian_line(w, w0, sigma): """Generate a normalized Gaussian lineshape (integral equals to 1). Parameters ---------- w : sorted 1d array of floats Spectral positions in wavenumber cm^(-1). w0 : float Center of the Gaussian lineshape in wavenumber cm^(-1). sigma : float FWHM of the Gaussian lineshape wavenumber cm^(-1). Returns ------- 1d array of floats Intensities of the normalized Gaussian lineshape over w. """ return 2/sigma*(np.log(2)/np.pi)**0.5*np.exp( -4*np.log(2)*((w-w0)/sigma)**2)
[docs]def lorentz_line(w, w0, sigma): """Generate a normalized Lorentzian lineshape (integral equals to 1). Parameters ---------- w : sorted 1d array of floats Spectral positions in wavenumber cm^(-1). w0 : float Center of the Lorentzian lineshape in wavenumber cm^(-1). sigma : float FWHM of the Lorentzian lineshape wavenumber cm^(-1). Returns ------- 1d array of floats Intensities of the normalized Lorentzian lineshape over w. """ return 1/np.pi*(sigma/2)/((w-w0)**2+sigma**2/4)
[docs]def voigt_line(w, w0, sigma_V, sigma_L): """Generate an approximated Voigt lineshape following :cite:`Whiting:68`. Parameters ---------- w : 1d array of floats Spectral positions in wavenumber cm^(-1). w0 : float Center of the Lorentzian lineshape in wavenumber cm^(-1). sigma_V : float FWHM of the Voigt lineshape wavenumber cm^(-1). sigma_L : float FWHM of the Lorentzian lineshape wavenumber cm^(-1). Returns ------- 1d array Intensities of the Voigt lineshape over w. """ # Preparations _ratio = sigma_L/sigma_V I_g = 1/(sigma_V*(1.065 + 0.447*_ratio + 0.058*_ratio**2)) _w = abs(w-w0)/sigma_V # Building up the function _term_1 = I_g*(1-_ratio)*np.exp(-2.772*_w**2) + _ratio/(1 + 4*_w**2) _term_2 = 0.016*(1-_ratio)*_ratio*(np.exp(-0.4*_w**2.25) - 10/(10 + _w**2.25)) return _term_1 + _term_2
[docs]def asym_Gaussian(w, w0, sigma, k, a_sigma, a_k, offset, power_factor=1.): """Asymmetric super-Gaussian following :cite:`Beirle:17`. Parameters ---------- w : sorted 1d array of floats Spectral positions in wavenumber cm^(-1). w0 : float Center of the asymmetric Gaussian function in wavenumber cm^(-1). sigma : float FWHM of the Gaussian function in wavenumber cm^(-1). k : float Controls the skewing of the asymmetry. a_sigma, a_k : float Tuning factors for sigma and k. offset : float Background offset (from experimental spectrum). power_factor : float Power factor on the output (e.g. can be used during slit fitting). Returns ------- 1d array of floats Intensities of the peak-normalized asymmetric super-Gaussian over w. """ response_low = np.exp(-abs((w[w <= w0]-w0)/(sigma-a_sigma))**(k-a_k)) response_high = np.exp(-abs((w[w > w0]-w0)/(sigma+a_sigma))**(k+a_k)) response = (np.append(response_low, response_high) + offset)**power_factor return np.nan_to_num(response/response.max())
[docs]def asym_Voigt(w, w0, sigma, k, a_sigma, a_k, sigma_L_l, sigma_L_h, offset, power_factor=1.): """Asymmetric super-Voigt. .. note:: This is based on the super-Gaussian from :cite:`Beirle:17`, with additional convolution with two Lorentzian profiles to better capture slow-decaying wings in some experimental slit function Parameters ---------- w : sorted 1d array of floats Spectral positions in wavenumber cm^(-1). w0 : float Center of the asymmetric Gaussian function in wavenumber cm^(-1). sigma : float FWHM of the Gaussian function in wavenumber cm^(-1). k : float Controls the skewing of the asymmetry. a_sigma, a_k : float Tuning factors for sigma and k. sigma_L_l : float FWHM of the Lorentzian function in wavenumber cm^(-1) for the lower half. sigma_L_h : float FWHM of the Lorentzian function in wavenumber cm^(-1) for the higher half. offset : float Background offset. power_factor : float Power factor on the output (e.g. can be used during slit fitting). Returns ------- 1d array of floats Intensities of the peak-normalized asymmetric super-Gaussian over w. """ response_low = np.exp(-abs((w-w0)/(sigma-a_sigma))**(k-a_k)) response_high = np.exp(-abs((w-w0)/(sigma+a_sigma))**(k+a_k)) response_low = np.convolve(response_low, lorentz_line(w, (w[0]+w[-1])/2, sigma_L_l), 'same') response_high = np.convolve(response_high, lorentz_line(w, (w[0]+w[-1])/2, sigma_L_h), 'same') response_low = response_low/response_low.max() response_high = response_high/response_high.max() response = (np.append(response_low[np.where(w <= w0)], response_high[np.where(w > w0)]) + offset)**power_factor return np.nan_to_num(response/response.max())
[docs]def asym_Voigt_deprecated(w, w0, sigma_V_l, sigma_V_h, sigma_L_l, sigma_L_h, offset): """Asymmetric Voigt profile following NRC. .. admonition:: Deprecated :class: attention This profile cannot capture certain slit functions with broadened Gaussian profile. Parameters ---------- w : sorted 1d array of floats Spectral positions in wavenumber cm^(-1). w0 : float Center of the asymmetric Gaussian function in wavenumber cm^(-1). sigma_V_l : float FWHM of the Voigt function in wavenumber cm^(-1) for the lower half. sigma_V_h : float FWHM of the Voigt function in wavenumber cm^(-1) for the higher half. sigma_L_l : float FWHM of the Lorentzian function in wavenumber cm^(-1) for the lower half. sigma_L_h : float FWHM of the Lorentzian function in wavenumber cm^(-1) for the higher half. offset : float Background offset. Returns ------- 1d array of floats Intensities of the peak-normalized asymmetric super-Gaussian over w. """ response_low = voigt_line(w[w <= w0], w0, sigma_V_l, sigma_L_l) response_high = voigt_line(w[w > w0], w0, sigma_V_h, sigma_L_h) response = (np.append(response_low/response_low.max(), response_high/response_high.max()) + offset) return response/response.max()
[docs]def slit_ISRF(w, w0, param_1, param_2, param_3, param_4, param_5, param_6, offset, mode='sGaussian'): """Impulse spectral response function (ISRF) as the slit function. Parameters ---------- w : sorted 1d array of floats Spectral positions in wavenumber cm^(-1). w0 : float Center of the asymmetric Gaussian function in wavenumber cm^(-1). param_1, param_2, param_3, param_4 : float Parameters needed for the asymmetric ISRF depending on the mode. - 'sGaussian': sigma : float FWHM of the Gaussian function in wavenumber cm^(-1). k : float Controls the skewing of the asymmetry. a_sigma, a_k : float Tuning factors for sigma and k. - 'Voigt': sigma_V_l : float FWHM of the Voigt function in wavenumber cm^(-1) for the lower half. sigma_L_l : float FWHM of the Lorentzian function in wavenumber cm^(-1) for the lower half. sigma_V_h : float FWHM of the Voigt function in wavenumber cm^(-1) for the higher half. sigma_L_h : float FWHM of the Lorentzian function in wavenumber cm^(-1) for the higher half. offset : float Background offset. mode : 'sGaussian', str, optional Two options for the ISRF: - Asymmetric super Gaussian: 'sGaussian'. - Asymmetric Voigt: 'Voigt'. Returns ------- 1d array of floats Intensities of the peak-normalized asymmetric ISRF. """ slit_fc = [] if mode == 'sGaussian': slit_fc = asym_Gaussian(w, w0, param_1, param_2, param_3, param_4, offset) elif mode == 'Voigt': slit_fc = asym_Voigt(w, w0, param_1, param_2, param_3, param_4, param_5, param_6, offset) return slit_fc