def decon_known(df,center): """ This method uses multiple make_lor to do a multiple-peak deconvolutoin using multiple Lorentzians and one arc tangent step function Notice: parameters are NOT automatically deleted if they are not used in the deconvolution of data with fewer peaks than the last time Parameters ---------- df : pandas dataframe df is a column-wise dataframe that records the data you want to deconvolve. center : array the array recording the centers of all peaks. Returns ------- out : lmfit.Model the composit multiple-peak model for the deconvolution. """ arctan_mod=StepModel(form='atan',prefix='arctan_') paras.update(arctan_mod.make_params()) paras['arctan_center'].set(value=inflection(norm.Energy,df),vary=False,min=0.0) paras['arctan_amplitude'].set(value=1.0,vary=False) paras['arctan_sigma'].set(value=1.0,min=0.01) mod=arctan_mod for i in range(len(center)): this=make_lor(df,i,center,2.0)['model'] mod=mod+this paras.update(make_lor(df,i,center,2.0)['paras']) out=mod.fit(df,params=paras,x=norm.Energy,weights=df) return {'out':out}
Returns ------- float returns the energy where the point of inflection of df happens. """ energy_diff=np.diff(energy) df_diff=np.diff(df) slope=(df_diff/energy_diff) slope_min=np.amin(-1*slope) index=np.where(-slope_min-slope==0)[0] return energy[index].item() #make parameters for the deconvolution of known arctan_mod=StepModel(form='atan',prefix='arctan_') paras=arctan_mod.make_params() #construct the model with 5 arctangents and 5 Lorentzians atan2=StepModel(form='atan',prefix='atan2_') atan3=StepModel(form='atan',prefix='atan3_') atan4=StepModel(form='atan',prefix='atan4_') atan5=StepModel(form='atan',prefix='atan5_') atan6=StepModel(form='atan',prefix='atan6_') lor2=LorentzianModel(prefix='l2_') lor3=LorentzianModel(prefix='l3_') lor4=LorentzianModel(prefix='l4_') lor5=LorentzianModel(prefix='l5_') lor6=LorentzianModel(prefix='l6_') model=atan2+atan3+atan4+atan5+atan6+lor2+lor3+lor4+lor5+lor6 model.set_param_hint('l2_amplitude', min=0.0) model.set_param_hint('l3_amplitude', min=0.0) model.set_param_hint('l4_amplitude', min=0.0)
b.append(i + 1) for j in b: if j not in b_new: b_new.append(j) funccenter = funccenter[b_new] ## First fitting attempt gaussnum = len(funccenter) funcnum = gaussnum # initial guess x0F, lower bound lb, upper bound up x0f = np.zeros((funcnum, 4)) lb = np.zeros((funcnum, 4)) ub = np.zeros((funcnum, 4)) # initial guess for error function step1 = StepModel(form='arctan', prefix='step1_') # pars.update(step2.guess(y,x=x)) pars = step1.make_params() pars['step1_center'].set(e0 + 6, min=e0 + 3, max=e0 + 8) pars['step1_amplitude'].set(0.5, min=0.1, max=1) pars['step1_sigma'].set(0.5, min=0.3, max=0.8) mod = step1 # initial guess for gaussian x0f[:funcnum, 2] = funccenter[:] for n0 in range(0, funcnum): x0f[n0, 0:2] = [0.5, 0.5] lb[n0, :] = [0.2, 0.2, x0f[n0, 2] - 1, 0] ub[n0, :] = [3, 0.7, x0f[n0, 2] + 1, 0.1] gauss = GaussianModel(prefix='g%s_' % int(n0 + 1)) pars.update(gauss.make_params()) pars['g%s_amplitude' % int(n0 + 1)].set(x0f[n0][0], min=lb[n0][0], max=ub[n0][0])