Source code for pyspeckit.spectrum.models.inherited_voigtfitter

"""
====================
Voigt Profile Fitter
====================

Module API
^^^^^^^^^^
"""
from . import model
import numpy as np
from ...spectrum.moments import moments
import types
try:
    import scipy.special
    scipyOK = True
except ImportError:
    scipyOK = False


[docs]def voigt(xarr, amp, xcen, sigma, gamma, normalized=False): """ Normalized Voigt profile z = (x+i*gam)/(sig*sqrt(2)) V(x,sig,gam) = Re(w(z))/(sig*sqrt(2*pi)) The area of V in this definition is 1. If normalized=False, then you can divide the integral of V by sigma*sqrt(2*pi) to get the area. Original implementation converted from http://mail.scipy.org/pipermail/scipy-user/2011-January/028327.html (had an incorrect normalization and strange treatment of the input parameters) Modified implementation taken from wikipedia, using the definition. http://en.wikipedia.org/wiki/Voigt_profile Parameters ---------- xarr : np.ndarray The X values over which to compute the Voigt profile amp : float Amplitude of the voigt profile if normalized = True, amp is the AREA xcen : float The X-offset of the profile sigma : float The width / sigma parameter of the Gaussian distribution gamma : float The width / shape parameter of the Lorentzian distribution normalized : bool Determines whether "amp" refers to the area or the peak of the voigt profile """ if scipyOK: z = ((xarr.value-xcen) + 1j*gamma) / (sigma * np.sqrt(2)) V = amp * np.real(scipy.special.wofz(z)) if normalized: return V / (sigma*np.sqrt(2*np.pi)) else: return V else: raise ImportError("Couldn't import scipy, therefore cannot do " "voigt profile stuff")
[docs]def voigt_fwhm(sigma, gamma): """ Approximation to the Voigt FWHM from wikipedia http://en.wikipedia.org/wiki/Voigt_profile Parameters ---------- sigma : float The width / sigma parameter of the Gaussian distribution gamma : float The width / shape parameter of the Lorentzian distribution """ return 0.5346 * 2 * gamma + np.sqrt(0.2166*(2*gamma)**2 + sigma**2*8*np.log(2))
[docs]def voigt_moments(self, *args, **kwargs): """ Get the spectral moments from the moments package. Use the gaussian width for the lorentzian width (not a great guess!) """ m = moments(*args,**kwargs) return list(m) + [m[-1]]
[docs]def voigt_fitter(): """ Generator for voigt fitter class """ myclass = model.SpectralModel(voigt, 4, parnames=['amplitude', 'shift', 'gwidth', 'lwidth'], parlimited=[(False, False), (False, False), (True, False), (True, False)], parlimits=[(0, 0), (0, 0), (0, 0), (0, 0)], shortvarnames=('A', r'\Delta x', r'\sigma_G', r'\sigma_L'), centroid_par='shift', fwhm_func=voigt_fwhm, fwhm_pars=['gwidth','lwidth'], guess_types=['amplitude', 'center', 'width', 'width'], ) myclass.__name__ = "voigt" try: myclass.moments = types.MethodType(voigt_moments, myclass, myclass.__class__) except TypeError: # indicates py3 is being used # http://stackoverflow.com/questions/10729909/convert-builtin-function-type-to-method-type-in-python-3?lq=1 myclass.moments = voigt_moments.__get__(myclass) return myclass