使用lmfit的python 2峰值洛伦兹拟合问题

时间:2016-05-19 15:27:21

标签: python curve-fitting lmfit

import numpy as np
import os
import matplotlib.pyplot as plt
from lmfit.models import GaussianModel, ExponentialModel, LorentzianModel, VoigtModel
import scipy
from scipy.optimize import leastsq
###############################################################################
###############################################################################

os.chdir('D:/reference')

def readfio(filename):
"""
READ *.fio file into dictionary of arrays
"""
    cols = []
# Open file
    f = open(filename +'.fio')
    counter = 0
    for n, line in enumerate(f):
        if line.strip().startswith('Col'):
            linestoskip = n +  1
            cols.append(line.split()[2]) #To have only the column headers in a list
            counter = counter + 1 #gives the number of columns, in principle it is not necessary
    f.close() # close the file 
    # Read numerical data without header
    #print (cols)
    data = np.genfromtxt(filename+'.fio',skip_header=linestoskip, skip_footer =1)
    return data, cols
###############################################################################
###############################################################################
def fitting():
    data, cols = readfio(filename)
    x = (2*np.pi/wavelength(energy))*(np.sin(np.radians(data[:,cols.index('om')]))+
    np.sin(np.radians(data[:,cols.index('tt')])-np.radians(data[:,cols.index('om')])))  
    y = data[:,cols.index('signalcounter_atten')]/data[:,cols.index('petra_beamcurrent')]

    exp_mod = ExponentialModel(prefix='exp_')
    pars = exp_mod.guess(y, x=x)

    gauss1  = LorentzianModel(prefix='g1_')
    pars.update( gauss1.make_params())

    pars['g1_center'].set(3.33, min=3.2, max=3.45)
    pars['g1_sigma'].set(0.02, min=0.01)
    pars['g1_amplitude'].set(2000, min=1)

    gauss2  = LorentzianModel(prefix='g2_')

    pars.update(gauss2.make_params())

    pars['g2_center'].set(3.59, min=3.45, max=3.7)
    pars['g2_sigma'].set(0.01, min=0.001)
    pars['g2_amplitude'].set(10000, min=1)

    mod = gauss1 + gauss2 + exp_mod


    init = mod.eval(pars, x=x)
    plt.semilogy(x, y)
    plt.semilogy(x, init, 'k--')

    out = mod.fit(y, pars, x=x)

    print(out.fit_report(min_correl=0.01))

    plt.semilogy(x, out.best_fit, 'r-')
    plt.show()
###############################################################################    ###############################################################################

def wavelength(energy):
    h = 6.626e-34  #joules
    c = 2.998e8    #m/sec
    eV = 1.602e-19 #Joules
    wavelength = h*c/(energy*1000*eV)*1e10       
    return wavelength

##############################################################################    
energy = 10.000 # in KeV    
filename = 'alignment_00241'
fitting()

我有这个程序使用洛伦兹函数拟合两个峰值。但是,我没有得到最合适的。谁能帮我这个。这是我用来拟合的文件。 The data file can be downloaded from this link

1 个答案:

答案 0 :(得分:1)

我相信你的y数据中有NaNs,阻止了它的适应性。您可能会看到NaNs的参数值。如果是这样,做一些像::

for ix in np.where(np.isnan(y)):
    y[ix]  = (y[ix-1] + y[ix+1]) / 2.0

在做之前可能有所帮助。