adding peak_voigt model#743
Conversation
|
Purpose of this PR is to add pseudo Voigt peak shape model. If someone could help with the RUFF issue, I would be grateful ! |
|
@marimperorclerc - I've applied the ruff fixes. If you would like to not have this type of issue in the future, please follow the instructions at https://github.com/orgs/SasView/discussions/3171#discussioncomment-17148772 to get ruff and pre-commit set up. |
| sigma = hwhm / cste | ||
| intensity = (wf * (1 / (1 + ((q - q0)**2.0 / hwhm**2.0)))) + \ | ||
| ((1.0 - wf) * np.exp((-0.5 * (q - q0)**2.0) / (sigma**2.0))) | ||
| return intensity |
There was a problem hiding this comment.
You can use Voigt rather than pseudo-Voigt:
def voigt(x, sigma, gamma):
"""
Return the voigt function, which is the convolution of a Lorentz
function with a Gaussian.
:Parameters:
gamma : real
The half-width half-maximum of the Lorentzian
sigma : real
The 1-sigma width of the Gaussian, which is one standard deviation.
Ref: W.I.F. David, J. Appl. Cryst. (1986). 19, 63-64
Note: adjusted to use stddev and HWHM rather than FWHM parameters
"""
# wofz function = w(z) = Fad[d][e][y]eva function = exp(-z**2)erfc(-iz)
from scipy.special import wofz
# TODO: if sigma == 0: return Lorentzian
z = (x + 1j * gamma) / (sigma * np.sqrt(2))
V = wofz(z) / (np.sqrt(2 * pi) * sigma)
return V.real
For a 1000 point function on my mac this takes 47.5 μs vs 12.5 μs for the pseudo-Voigt function.
| # cste = 1.17741 | ||
| sigma = hwhm / cste | ||
| intensity = (wf * (1 / (1 + ((q - q0)**2.0 / hwhm**2.0)))) + \ | ||
| ((1.0 - wf) * np.exp((-0.5 * (q - q0)**2.0) / (sigma**2.0))) |
There was a problem hiding this comment.
Rather than the "\" line extender use parentheses around the entire expression so it can break across multiple lines without the backslash.
Move the "+" operator to the beginning of the second line.
| half-maximum) for the Lorentzian and sigma = HWHM / 1.17741 for the | ||
| Gaussian, where sigma is the standard deviation of the Gaussian. In | ||
| other words, the widths of the Lorentzian and the Gaussian have been | ||
| coupled for convenience of parameterisation. |
There was a problem hiding this comment.
Convenient for whom? The width of the Gaussian and Lorentzian are easier to interpret physically. I don't think the optimizer will care which pair it is fitting. The only advantage seems to be that it is easier to guess the initial value of HWHM from the graph.
| This pseudo-Voigt peak function is a weighted linear summation of | ||
| Lorentzian (L) and Gaussian (G) peak shapes. | ||
| It is a popular function for modelling peak shape. | ||
| It can be tailored to any specific peak shape and it can also produce a peak shape with asymmetry. |
There was a problem hiding this comment.
Both the gaussian and the lorentzian are symmetric about peak_pos, and so is the linear combination. It make look asymmetric due to log q scale, or because the resolution function Δq is increasing with q.
Mention that the voigt function is a convolution
Add a note that the instrument resolution function contributes to the convolution. That is, if the resolution is a gaussian of approximately constant width Δq then peak_hwhm parameter value.
No description provided.