拟合后如何得到lmfit参数?

Den*_*kir 3 python windows parameters lmfit

我编写了一个程序来拟合一些拉曼光谱峰值。\n我需要返回拟合的参数(位置、幅度、HWHM)。

\n\n

我使用 modul lmfit 创建一个带有约束的洛伦兹峰。

\n\n

根据我的图形,拟合峰值和原始数据之间有很好的一致性。\n但是当拟合提取参数时,我遇到了一个问题,程序仅返回初始值。

\n\n

我绑定了“report_fit 模块”并更改了初始参数,但没有成功。参数值不会变化。

\n\n

令我困扰的是,这个程序在我同事的电脑上运行,但在我的电脑上运行不了。\n所以问题可能出在我的 python 版本上。

\n\n

我正在使用spyder 2.3.9,并在Windows 10下使用anaconda安装了python 3.4。\nlmfit模块0.9.3似乎可以部分工作,因为我可以获得一个很好的拟合协议(从图plt.plot中)。\n但是拟合后无法返回参数值。

\n\n
\n\n

这是我的代码:

\n\n
#!/usr/bin/python3\n# -*- coding:utf-8 -*-\n\nimport os\nimport numpy as np\nimport matplotlib.pyplot as plt\nfrom math import factorial\nfrom scipy.interpolate import interp1d\nfrom lmfit import minimize, Parameters  #,report_fit\n\n##############################################################################\n# Fit of Raman peaks\n\ndef fmin150(pars,x,y):  \n    amp= pars[\'Amp_150\'].value\n    cent=pars[\'Cent_150\'].value\n    hwhm=pars[\'Wid_150\'].value\n    a=pars[\'a_150\'].value\n    b=pars[\'b_150\'].value\n    peak = (amp*hwhm)/(((x-cent)**2)+(hwhm**2)) + ((a*x)+b)\n    return peak - y    \n\ndef fmin220(pars,x,y):  \n    amp= pars[\'Amp_220\'].value\n    cent=pars[\'Cent_220\'].value\n    hwhm=pars[\'Wid_220\'].value\n    a=pars[\'a_220\'].value\n    b=pars[\'b_220\'].value\n    peak = (amp*hwhm)/(((x-cent)**2)+(hwhm**2)) + ((a*x)+b)\n    return peak - y   \n\ndef fmin2d(pars,x,y):  \n    amp= pars[\'Amp_2D\'].value\n    cent=pars[\'Cent_2D\'].value\n    hwhm=pars[\'Wid_2D\'].value\n    a=pars[\'a_2D\'].value\n    b=pars[\'b_2D\'].value\n    peak = (amp*hwhm)/(((x-cent)**2)+(hwhm**2))  + ((a*x)+b)\n    return peak - y \n\n##############################################################################\ndef fit(filename):\n    """\n    Fit Raman spectrum file\n    Return filename, for each peak  (*f*whm, position, height) \n    PL (Position, Intensity, Area)\n    """\n    print ("----------------------------")\n    print("Treating file : ")\n    print(filename)\n    try:\n        data = np.loadtxt(filename)\n    except:\n        print("Unable to load file")\n\n    xx=data[:,0]\n    yy=data[:,1]\n #### Define fitting interval  ##### \n    # Cu oxides (unit\xc3\xa9s en cm-1)\n    xminim150 = 120\n    xmaxim150 = 170\n    xminim220 = 175\n    xmaxim220 = 275\n    xminim300 = 280\n    xmaxim300 = 340\n    xminim640 = 345\n    xmaxim640 = 800\n    # Graphene\n    xminimG = 1540\n    xmaximG = 1680\n    xminim2D = 2600\n    xmaxim2D = 2820\n\n    # Definition Baground = place without the fitted peaks\n    zone1 = (xx > min(xx)) & (xx < xminim150)\n    zone2 = (xx > xmaxim150) & (xx < xminim220)\n    zone3 = (xx > xmaxim220) & (xx < xminim300)\n    zone4 = (xx > xmaxim300) & (xx < xminim640)\n    zone5 = (xx > xmaxim640) & (xx < xminimG)\n    zone6 = (xx > xmaximG) & (xx < xminim2D)\n    zone7 = (xx > xmaxim2D) & (xx < max(xx))\n\n    x_BG = np.concatenate((xx[zone1],xx[zone2],xx[zone3],xx[zone4],xx[zone5],xx[zone6],xx[zone7]))\n    y_BG = np.concatenate((yy[zone1],yy[zone2],yy[zone3],yy[zone4],yy[zone5],yy[zone6],yy[zone7]))\n\n\n    #Creation de l\'interpolation lineaire\n    f1 = interp1d(x_BG, y_BG, kind=\'linear\')\n    xinterpmin= x_BG[0]   # valeur de x_BG min\n    xinterpmax= x_BG[len(x_BG)-1]  # valeur de x_BG max\n    nbxinterp = len(xx) * 4 #(nb de point en x)* 4 pour une interpolation correcte\n\n    xnew = np.linspace(xinterpmin, xinterpmax, num=nbxinterp, endpoint=True)\n    ynew= f1(xnew)\n##########################  Fit 2D peaks  ############################### \n    # create a set of Parameters\n    pars150 = Parameters()\n    pars220 = Parameters()\n    pars300 = Parameters()\n    pars640 = Parameters()\n    parsg = Parameters()  \n    pars2d = Parameters()\n\n            #####   Cu2O pic 150 cm-1     #####\n    pars150.add(\'Amp_150\', value=10, min=0.0001, max=100000)  # Amplitude ~intensity\n    pars150.add(\'Cent_150\', value=150, min=140, max=160)      # Center  ~position\n    pars150.add(\'Wid_150\', value=5, min=4, max=15 )           # Width is the HWHM\n    pars150.add(\'a_150\', value=1, min=-100000, max=100000) \n    pars150.add(\'b_150\', value=10, min=-100000, max=100000)\n            #####   Cu2O pic 220 cm-1     #####\n    pars220.add(\'Amp_220\', value=10, min=0.0001, max=100000)\n    pars220.add(\'Cent_220\', value=220, min=200, max=230)\n    pars220.add(\'Wid_220\', value=5, min=4, max=15 )\n    pars220.add(\'a_220\', value=1, min=-100000, max=100000) \n    pars220.add(\'b_220\', value=10, min=-100000, max=100000)\n        #####    Graphene 2D     #####\n    pars2d.add(\'Amp_2D\', value=15, min=0.0001, max=100000)\n    pars2d.add(\'Cent_2D\', value=2711, min=2670, max=2730)\n    pars2d.add(\'Wid_2D\', value=15, min=4, max=25 )\n    pars2d.add(\'a_2D\', value=1, min=-100000, max=100000) \n    pars2d.add(\'b_2D\', value=10, min=-100000, max=100000)\n\n    # define x for each peaks\n    interv_150 = (xx > xminim150) & (xx < xmaxim150)\n    x_150 = xx[interv_150]\n    y_150 = yy[interv_150]\n    interv_220 = (xx > xminim220) & (xx < xmaxim220)\n    x_220 = xx[interv_220]\n    y_220 = yy[interv_220]\n\n    interv_2D = (xx > xminim2D) & (xx < xmaxim2D)\n    x_2D = xx[interv_2D]\n    y_2D = yy[interv_2D]\n    ###########################################################\n    # Performe FIT with leastsq model  ###########\n    result_150 = minimize(fmin150, pars150, args=(x_150, y_150))\n    result_220 = minimize(fmin220, pars220, args=(x_220, y_220))\n    result_2D = minimize(fmin2d, pars2d, args=(x_2D, y_2D))\n\n    # calculate final result\n    final_150 = y_150 + result_150.residual\n    final_220 = y_220 + result_220.residual\n    final_2D = y_2D + result_2D.residual\n\n    ###########################################################\n    # Parameter after fit #\n    amp_150= pars150[\'Amp_150\'].value\n    cent_150=pars150[\'Cent_150\'].value\n    fwhm_150=2*pars150[\'Wid_150\'].value\n\n    amp_220= pars220[\'Amp_220\'].value\n    cent_220=pars220[\'Cent_220\'].value\n    fwhm_220=2*pars220[\'Wid_220\'].value\n\n    amp_2D= pars2d[\'Amp_2D\'].value\n    cent_2D=pars2d[\'Cent_2D\'].value\n    fwhm_2D=2*pars2d[\'Wid_2D\'].value\n\n    ###########\n    #Plot data#\n    plt.plot(xx, yy, \'k+\' ,x_150, final_150, \'r\', x_220, final_220,\'r\', x_2D, final_2D,\'b\')\n    plt.xlabel(r\'Raman shift (cm$^{-1}$)\', fontsize=14)\n    plt.ylabel(\'Intensity (a.u.)\', fontsize=14)\n    plt.xlim(0,3000)\n    plt.title(filename, fontsize=16)\n    savename=filename[:-4]+".png"\n    print(savename)\n    plt.savefig(savename)\n    plt.clf()\n\n    return filename, amp_150, cent_150, fwhm_150, amp_220, cent_220, fwhm_220,  amp_2D, cent_2D, fwhm_2D\n\n\ndef main():\n    """main program loop"""\n    print("----------------------------")\n    liste = []\n    for filename in os.listdir(os.getcwd()):\n      if filename.endswith(".txt"):\n        liste.append(filename)\n\n    f1 = open("TestFit_all.dat","w")\n    header = "Filename\\tI_150\\tCentre_150\\tFWHM_150\\tI_220\\tCentre_220\\tFWHM_220\\tI_300\\tCentre_300\\tFWHM_300\\tI_640\\tCentre_640\\tFWHM_640\\tI_G\\tCentre_G\\tFWHM_G\\tI_2D\\tCentre_2D\\tFWHM_2D\\tI_PL\\tI_PL_err\\tCent_PL\\tCent_PL_err\\tArea1000_PL\\n"\n    f1.write(header)\n    for i in liste:\n        txt=fit(i)\n        print(txt)\n        #text = str(txt[0])+"\\t"+str(txt[1])+"\\t"+str(txt[2])+"\\t"+str(txt[3])+"\\t"+str(txt[4])+"\\t"+"\\n"\n        text = str(txt[0])+"\\t"+str(txt[1])+"\\t"+str(txt[2])+"\\t"+str(txt[3])+"\\t"+str(txt[4])+"\\t"+str(txt[5])+"\\t"+str(txt[6])+"\\t"+str(txt[7])+"\\t"+str(txt[8])+"\\t"+str(txt[9])+"\\t"+"\\t"+"\\n"\n        f1.write(text)\n\n    f1.close()\n\n    print("----------------------------")\n    print("Done")\n###################################################################\n# start\n\nif __name__ == "__main__":\n  main()  \n
Run Code Online (Sandbox Code Playgroud)\n\n

谢谢你的帮助 :)

\n\n

工作适合的示例

\n\n

请将您的回复发送至deniz.cakir@etu.umontpellier.fr

\n

M N*_*lle 5

您的脚本可以短得多来说明问题。但是,最终的参数被保留result_150.params等等。传入的参数minimize()在拟合中不会改变。

嗯,对于 lmfit 0.9.0 及更高版本来说也是如此。也许您的同事在 lmfit 上有旧版本。