实际上,只需添加一个二次背景并提升质心的边界就可以得到一个不错的拟合。
使用您的数据,我稍微修改了您的示例::
#!/usr/bin/env python
import matplotlib.pyplot as plt
import numpy as np
from lmfit.models import LorentzianModel, QuadraticModel
test = np.loadtxt('spectra.txt')
xdat = test[0, :]
ydat = test[1, :]
def add_peak(prefix, center, amplitude=0.005, sigma=0.05):
peak = LorentzianModel(prefix=prefix)
pars = peak.make_params()
pars[prefix + 'center'].set(center)
pars[prefix + 'amplitude'].set(amplitude)
pars[prefix + 'sigma'].set(sigma, min=0)
return peak, pars
model = QuadraticModel(prefix='bkg_')
params = model.make_params(a=0, b=0, c=0)
rough_peak_positions = (0.61, 0.76, 0.85, 0.99, 1.10, 1.40, 1.54, 1.7)
for i, cen in enumerate(rough_peak_positions):
peak, pars = add_peak('lz%d_' % (i+1), cen)
model = model + peak
params.update(pars)
init = model.eval(params, x=xdat)
result = model.fit(ydat, params, x=xdat)
comps = result.eval_components()
print(result.fit_report(min_correl=0.5))
plt.plot(xdat, ydat, label='data')
plt.plot(xdat, result.best_fit, label='best fit')
for name, comp in comps.items():
plt.plot(xdat, comp, '--', label=name)
plt.legend(loc='upper right')
plt.show()
打印报告
[[Model]]
((((((((Model(parabolic, prefix='bkg_') + Model(lorentzian, prefix='lz1_')) + Model(lorentzian, prefix='lz2_')) + Model(lorentzian, prefix='lz3_')) + Model(lorentzian, prefix='lz4_')) + Model(lorentzian, prefix='lz5_')) + Model(lorentzian, prefix='lz6_')) + Model(lorentzian, prefix='lz7_')) + Model(lorentzian, prefix='lz8_'))
[[Fit Statistics]]
# fitting method = leastsq
# function evals = 1101
# data points = 800
# variables = 27
chi-square = 7.3824e-04
reduced chi-square = 9.5504e-07
Akaike info crit = -11062.6801
Bayesian info crit = -10936.1956
[[Variables]]
bkg_c: 0.03630504 +/- 9.4269e-04 (2.60%) (init = 0)
bkg_b: -0.05150031 +/- 0.00272084 (5.28%) (init = 0)
bkg_a: 0.02285577 +/- 0.00109543 (4.79%) (init = 0)
lz1_sigma: 0.03853490 +/- 0.00224206 (5.82%) (init = 0.05)
lz1_center: 0.60596282 +/- 0.00101699 (0.17%) (init = 0.61)
lz1_amplitude: 0.00121362 +/- 8.0862e-05 (6.66%) (init = 0.005)
lz1_fwhm: 0.07706979 +/- 0.00448412 (5.82%) == '2.0000000*lz1_sigma'
lz1_height: 0.01002487 +/- 3.1221e-04 (3.11%) == '0.3183099*lz1_amplitude/max(2.220446049250313e-16, lz1_sigma)'
lz2_sigma: 0.03534226 +/- 3.5893e-04 (1.02%) (init = 0.05)
lz2_center: 0.76784323 +/- 1.9002e-04 (0.02%) (init = 0.76)
lz2_amplitude: 0.00738785 +/- 8.9378e-05 (1.21%) (init = 0.005)
lz2_fwhm: 0.07068452 +/- 7.1786e-04 (1.02%) == '2.0000000*lz2_sigma'
lz2_height: 0.06653864 +/- 3.6663e-04 (0.55%) == '0.3183099*lz2_amplitude/max(2.220446049250313e-16, lz2_sigma)'
lz3_sigma: 0.03948780 +/- 0.00111507 (2.82%) (init = 0.05)
lz3_center: 0.85427526 +/- 5.4206e-04 (0.06%) (init = 0.85)
lz3_amplitude: 0.00317016 +/- 1.1244e-04 (3.55%) (init = 0.005)
lz3_fwhm: 0.07897560 +/- 0.00223015 (2.82%) == '2.0000000*lz3_sigma'
lz3_height: 0.02555459 +/- 3.9771e-04 (1.56%) == '0.3183099*lz3_amplitude/max(2.220446049250313e-16, lz3_sigma)'
lz4_sigma: 0.02983045 +/- 0.00283845 (9.52%) (init = 0.05)
lz4_center: 0.99544342 +/- 0.00142552 (0.14%) (init = 0.99)
lz4_amplitude: 6.9114e-04 +/- 7.6016e-05 (11.00%) (init = 0.005)
lz4_fwhm: 0.05966089 +/- 0.00567690 (9.52%) == '2.0000000*lz4_sigma'
lz4_height: 0.00737492 +/- 3.6918e-04 (5.01%) == '0.3183099*lz4_amplitude/max(2.220446049250313e-16, lz4_sigma)'
lz5_sigma: 0.06666333 +/- 0.00196152 (2.94%) (init = 0.05)
lz5_center: 1.10162076 +/- 7.8293e-04 (0.07%) (init = 1.1)
lz5_amplitude: 0.00522275 +/- 2.2587e-04 (4.32%) (init = 0.005)
lz5_fwhm: 0.13332666 +/- 0.00392304 (2.94%) == '2.0000000*lz5_sigma'
lz5_height: 0.02493807 +/- 4.7491e-04 (1.90%) == '0.3183099*lz5_amplitude/max(2.220446049250313e-16, lz5_sigma)'
lz6_sigma: 0.11712113 +/- 0.00307555 (2.63%) (init = 0.05)
lz6_center: 1.43220451 +/- 0.00102240 (0.07%) (init = 1.4)
lz6_amplitude: 0.01215451 +/- 5.1928e-04 (4.27%) (init = 0.005)
lz6_fwhm: 0.23424227 +/- 0.00615109 (2.63%) == '2.0000000*lz6_sigma'
lz6_height: 0.03303334 +/- 6.2184e-04 (1.88%) == '0.3183099*lz6_amplitude/max(2.220446049250313e-16, lz6_sigma)'
lz7_sigma: 0.02603963 +/- 0.00335175 (12.87%) (init = 0.05)
lz7_center: 1.55545329 +/- 0.00152567 (0.10%) (init = 1.54)
lz7_amplitude: 4.6978e-04 +/- 7.1036e-05 (15.12%) (init = 0.005)
lz7_fwhm: 0.05207926 +/- 0.00670351 (12.87%) == '2.0000000*lz7_sigma'
lz7_height: 0.00574266 +/- 3.8805e-04 (6.76%) == '0.3183099*lz7_amplitude/max(2.220446049250313e-16, lz7_sigma)'
lz8_sigma: 0.11332337 +/- 0.00336106 (2.97%) (init = 0.05)
lz8_center: 1.79132485 +/- 0.00117968 (0.07%) (init = 1.7)
lz8_amplitude: 0.00700579 +/- 3.2606e-04 (4.65%) (init = 0.005)
lz8_fwhm: 0.22664674 +/- 0.00672212 (2.97%) == '2.0000000*lz8_sigma'
lz8_height: 0.01967830 +/- 4.2422e-04 (2.16%) == '0.3183099*lz8_amplitude/max(2.220446049250313e-16, lz8_sigma)'
[[Correlations]] (unreported correlations are < 0.500)
C(bkg_b, bkg_a) = -0.993
C(bkg_c, bkg_b) = -0.981
C(bkg_c, bkg_a) = 0.966
C(lz6_sigma, lz6_amplitude) = 0.963
C(lz8_sigma, lz8_amplitude) = 0.935
C(lz5_sigma, lz5_amplitude) = 0.933
C(bkg_b, lz6_amplitude) = -0.907
C(lz3_sigma, lz3_amplitude) = 0.905
<snip>
并显示了一个情节
这可能并不完美,但应该会给你一个很好的开始。