Skip to content

Commit 8305e2a

Browse files
committed
Voigt model now functional, height and fwhm added
1 parent 5fc3bdb commit 8305e2a

4 files changed

Lines changed: 89 additions & 8 deletions

File tree

src/ramanchada2/fitting_functions/models.py

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
from ramanchada2.fitting_functions.voigtareaparametrizationnu import (
88
VoigtAreaParametrizationNu,
99
)
10-
import numpy as np
1110

1211

1312
class PearsonIVParametrizationHPWModel(Model):
@@ -113,14 +112,55 @@ def __init__(self, independent_vars=["x"], prefix="", nan_policy="raise", **kwar
113112
self._set_paramhints_prefix()
114113

115114
def _set_paramhints_prefix(self):
116-
self.set_param_hint("sigma", min=np.tiny)
117-
self.set_param_hint("nu", min=0, max=1)
118-
119-
fexpr = "2.0*{pre:s}sigma"
120-
self.set_param_hint("fwhm", expr=fexpr.format(pre=self.prefix))
115+
self.set_param_hint("sigma", min=1E-100)
116+
self.set_param_hint("nu", min=0.0, max=1.0)
121117

122118
def guess(self, data, x, negative=False, **kwargs):
123119
"""Estimate initial model parameter values from data."""
124120
pars = guess_from_peak(self, data, x, negative)
125121
pars[f"{self.prefix}nu"].set(value=1.0)
126122
return update_param_vals(pars, self.prefix, **kwargs)
123+
124+
def fit(
125+
self,
126+
data,
127+
params=None,
128+
weights=None,
129+
method="leastsq",
130+
iter_cb=None,
131+
scale_covar=True,
132+
verbose=False,
133+
fit_kws=None,
134+
nan_policy=None,
135+
calc_covar=True,
136+
max_nfev=None,
137+
**kwargs,
138+
):
139+
"""overwrite fit in order to amend area and fwhm to the parameters"""
140+
result = super().fit(
141+
data,
142+
params=params,
143+
weights=weights,
144+
method=method,
145+
iter_cb=iter_cb,
146+
scale_covar=scale_covar,
147+
verbose=verbose,
148+
fit_kws=fit_kws,
149+
nan_policy=nan_policy,
150+
calc_covar=calc_covar,
151+
max_nfev=max_nfev,
152+
**kwargs,
153+
)
154+
pahf = VoigtAreaParametrizationNu.GetPositionAreaHeightFWHMFromPeakParameters(
155+
result.params[f"{self.prefix}amplitude"],
156+
result.params[f"{self.prefix}center"],
157+
result.params[f"{self.prefix}sigma"],
158+
result.params[f"{self.prefix}nu"],
159+
result.covar
160+
)
161+
p1 = Parameter(f"{self.prefix}height", value=pahf.Height)
162+
p1.stderr = pahf.HeightStdDev
163+
p2 = Parameter(f"{self.prefix}fwhm", value=pahf.FWHM)
164+
p2.stderr = pahf.FWHMStdDev
165+
result.params.add_many(p1, p2)
166+
return result

src/ramanchada2/fitting_functions/voigtareaparametrizationnu.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -388,14 +388,32 @@ def GetPositionAreaHeightFWHMFromSinglePeakParameters(
388388
pos = parameters[f"pos{indexOfPeak}"]
389389
w = parameters[f"w{indexOfPeak}"]
390390
nu = parameters[f"nu{indexOfPeak}"]
391-
sigma = w * np.sqrt(nu) * OneBySqrtLog4
392-
gamma = w * (1 - nu)
393391

394392
if cv is not None:
395393
cv = cv[
396394
indexOfPeak * 4: (indexOfPeak + 1) * 4,
397395
indexOfPeak * 4: (indexOfPeak + 1) * 4,
398396
]
397+
return VoigtAreaParametrizationNu.GetPositionAreaHeightFWHMFromPeakParameters(area, pos, w, nu, cv)
398+
399+
def GetPositionAreaHeightFWHMFromPeakParameters(
400+
area, pos, w, nu, cv=None
401+
):
402+
"""
403+
Get position, area, height, and FWHM of one peak from the peak parameters.
404+
If the covariance matrix is given, the corresponding errors are calculated.
405+
406+
Parameters
407+
----------
408+
parameters: Parameters
409+
Existing instance of Parameters, which contains the result of the fit.
410+
indexOfPeak: int
411+
The index of the peak into consideration.
412+
cv: np.array
413+
Covariance matrix of the fit.
414+
"""
415+
sigma = w * np.sqrt(nu) * OneBySqrtLog4
416+
gamma = w * (1 - nu)
399417

400418
if cv is not None:
401419
areaStdDev = SafeSqrt(cv[0, 0])

tests/fitting_functions/test_pearsonivamplitudeparametrizationhpw.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,3 +475,5 @@ def test_fit_with_model_oneterm():
475475
np.testing.assert_almost_equal(result.params["sigma"], w, 7)
476476
np.testing.assert_almost_equal(result.params["expon"], m, 7)
477477
np.testing.assert_almost_equal(result.params["skew"], v, 7)
478+
np.testing.assert_almost_equal(result.params["amplitude"], 92.774482626349894596, 7)
479+
np.testing.assert_almost_equal(result.params["fwhm"], 10.02952431724565395, 7)

tests/fitting_functions/test_voigtareaparametrizationnu.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from ramanchada2.fitting_functions import voigtareaparametrizationnu
2+
from ramanchada2.fitting_functions.models import VoigtAreaParametrizationNuModel
23
from ramanchada2.fitting_functions.voigtareaparametrizationnu import (
34
VoigtAreaParametrizationNu,
45
)
@@ -794,3 +795,23 @@ def test_parameter_boundaries():
794795
c.add(d)
795796
assert c["foo"] == 34
796797
assert c["foo"].max == 77
798+
799+
800+
def test_fit_with_model_oneterm():
801+
x = np.linspace(0, 99, 100)
802+
a = 7
803+
pos = 50
804+
w = 5
805+
nu = 6 / 11.0
806+
sigma = w * np.sqrt(nu) * voigtareaparametrizationnu.OneBySqrtLog4
807+
gamma = w * (1 - nu)
808+
data = a * voigt_profile(x - pos, sigma, gamma)
809+
model = VoigtAreaParametrizationNuModel(x=x)
810+
params = model.guess(data, x)
811+
result = model.fit(data, x=x, params=params)
812+
np.testing.assert_almost_equal(result.params["amplitude"], a, 3)
813+
np.testing.assert_almost_equal(result.params["center"], pos, 3)
814+
np.testing.assert_almost_equal(result.params["sigma"], w, 3)
815+
np.testing.assert_almost_equal(result.params["nu"], nu, 3)
816+
np.testing.assert_almost_equal(result.params["height"], 0.542599801404569082663570, 3)
817+
np.testing.assert_almost_equal(result.params["fwhm"], 10.111072472153491175127, 3)

0 commit comments

Comments
 (0)