lmfit模型中拟合参数的不同约束 [英] Different constraints for fit parameter in lmfit model

查看:99
本文介绍了lmfit模型中拟合参数的不同约束的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用lmfit创建多重voigt/Gaussian/Lorentizan-peak拟合函数. 因此,我编写了以下函数:

I am trying to create a multible voigt/Gaussian/Lorentizan-peak fit function with lmfit. Therefore, I wrote the following Function:

def apply_fit_mix_multy(data,modelPeak,peakPos,amplitud,**kwargs):
peakPos=np.array(peakPos)
Start=kwargs.get('Start',data[0,0])
length_data=len(data)-1
End=kwargs.get('End',data[length_data,0])
StartPeak=kwargs.get('StartPeak',data[0,0])
EndPeak=kwargs.get('EndPeak',data[length_data,0])
BackFunc=kwargs.get('BackFunc',False)
BackCut=kwargs.get('BackCut',False)
dataN=data_intervall(data,Start,End)
y=dataN[:, 1]
x=dataN[:, 0]
amplitud=amplitud
center=peakPos

mod = None
for i in range(len(peakPos)):
    this_mod = make_model(i,amplitud,center,modelPeak)
    if mod is None:
        mod = this_mod
    else:
        mod = mod + this_mod

bgy=[list() for f in range(len(x))]
if(BackFunc==True):
    bg,bgx=BackFunc
    for i in range(len(x)):
        bgy[i]=bg.best_values.get('c')        

elif(BackCut!=False):
    slope,intercept=back_ground_cut(data,BackCut[0],BackCut[1])  
    for i in range(len(x)):
        bgy[i]=slope*x[i]+intercept       

if(BackCut!=False):
    print('Background substraction model is used! (Sign=Sign-backgr(linear between two points))')
    y=y-bgy
    out = mod.fit(y, x=x)
else:  
    print('Combination model is used! (offset+Gauss/Lor/Voig)')
    offset=ConstantModel()
    mod=mod+offset

out = mod.fit(y, x=x)#out is the fitted function

area=[list() for f in range(len(peakPos))]
comps=out.eval_components(x=x)
if(BackCut!=False):
    for i in range(len(peakPos)):
        area[i]=simps(comps['peak'+str(i)+'_'],x=x,even='avg')-simps(bgy,x=x,even='avg')
    fit_dict={'signal':y, 'convol':out.best_fit,'x':x,'peak_area':area,'backgr':bgy,'comps':comps}
else:
    for i in range(len(peakPos)):
        area[i]=simps(comps['peak'+str(i)+'_'],x=x,even='avg')
    fit_dict={'convol':out.best_fit,'x':x,'peak_area':area,'comps':comps} #comps is inf. of  sperate peaks

return fit_dict

该函数读取数据集modelPeak(例如GaussianModel)对峰值位置和振幅(peakPos,振幅)的初始猜测.

The function reads in a data set, the modelPeak (e.g. GaussianModel) an initial guess of peak positions and amplitudes (peakPos, amplitude) .

在第一部分中,初始化峰的模型(有多少个峰...)

In the first Part I initializing the model of the peaks (how many peaks...)

    for i in range(len(peakPos)):
    this_mod = make_model(i,amplitud,center,modelPeak)
    if mod is None:
        mod = this_mod
    else:
        mod = mod + this_mod

具有make_model功能:

With the make_model funktion:

def make_model(num,amplitud,center,mod):
pref = "peak{0}_".format(num)
model = mod(prefix = pref)
model.set_param_hint(pref+'amplitud', value=amplitud[num], min=0, max=5*amplitud[num])
model.set_param_hint(pref+'center', value=center[num], min=center[num]-0.5, max=center[num]+0.5)
if(num==0):
    model.set_param_hint(pref+'sigma', value=0.3, min=0.01, max=1)
else:
    model.set_param_hint(pref+'sigma', value=0.3, min=0.01, max=1)
#print('Jetzt',center[num],amplitud[num])
return model

这是我的问题:我想适应例如我想要3个山峰,例如在拟合过程中,第一个峰的sigma会有所不同,而其他峰的sigma则取决于第一个峰的sigma! 任何的想法? 谢谢 数学

here is now my Problem: I I whant to fit e.g. 3 Peaks I whant that e.g. the sigma of the first peak is varies during the fit while the sigmas of the other peaks depend on the sigma of the first peak! any idea? thx maths

仅供参考,适合度如下所示: 在此处输入图片描述

FYI this is how a fit looks like: enter image description here

推荐答案

如果我理解您的冗长问题(删除多余的内容会很有帮助-并且有很多问题),您想创建一个Model具有多个峰,从而允许第一个峰的sigma自由变化,并限制sigma以便其他峰依赖于此.

If I understand your long question (it would be helpful to remove the extraneous stuff - and there is quite a lot of it), you want to create a Model with multiple peaks, allowing sigma from the 1st peak to vary freely, and constraining sigma for the other peaks to depend on this.

为此,您可以使用参数提示(如在make_model()函数中使用的那样),也可以在创建Parameters对象之后为参数设置表达式.对于第一种方法,类似这样的

To do that, you can either use parameter hints (as you use in your make_model() function) or set expressions for the parameters after the Parameters object is created. For the first approach, something like this

def make_model(num,amplitud,center,mod):
    pref = "peak{0}_".format(num)
    model = mod(prefix = pref)
    model.set_param_hint(pref+'amplitud', value=amplitud[num], min=0, max=5*amplitud[num])
    model.set_param_hint(pref+'center', value=center[num], min=center[num]-0.5, max=center[num]+0.5)
    if(num==0):
        model.set_param_hint(pref+'sigma', value=0.3, min=0.01, max=1)
    else:
        ## instead of 
        # model.set_param_hint(pref+'sigma', value=0.3, min=0.01, max=1)
        ## set peakN_sigma == peak0_sigma
        model.set_param_hint(pref+'sigma', expr='peak0_sigma') 
        ## or maybe set peakN_sigma == N * peak0_sigma 
        model.set_param_hint(pref+'sigma', expr='%d*peak0_sigma' % num)
    return model

您还可以制作完整的模型(从代码中进行了简化,但思路相同):

You could also make the full model (simplified somewhat from your code, but the same idea):

model = (VoigtModel(prefix='peak0_') + VoigtModel(prefix='peak1_') +
         VoigtModel(prefix='peak2_') + LinearModel(prefix='const_'))

# create parameters with default values
params = model.make_params(peak0_amplitude=10, peak0_sigma=2, ....)

# set constraints for `sigma` params:
params['peak1_sigma'].expr = 'peak0_sigma'
params['peak2_sigma'].expr = 'peak0_sigma'

# similarly, set bounds as needed:
params['peak1_sigma'].min = 0
params['peak1_amplitude'].min = 0

希望有帮助...

这篇关于lmfit模型中拟合参数的不同约束的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆