Search code examples
pythontypeerrorlmfit

lmfit RectangleModel or StepModel


I am trying to fit the model with peak + background, my code is as below:

import numpy as np
import scipy.stats as stats
import lmfit
import matplotlib.pyplot as plt

# Generate random data 
np.random.seed(1234)
y_data = np.random.normal(loc =5, scale = 4, size=100000) + np.random.exponential(scale = 5, size=100000)
# Histogram the data for fitting
y, x = np.histogram(y_data, bins=100, density=False)
# # # calculate bin centers
x=(x[1:]+x[:-1])/2
# plt.plot(x,y)
plt.errorbar(x,y,yerr=stats.sem(y), fmt='.', zorder=1, label='data points')

peak1 = lmfit.models.SkewedVoigtModel(prefix="peak_")
pars = peak1.make_params()
# Set some parameters
pars['peak_center'].set(value=5, vary =True)
pars['peak_sigma'].set(value=4,vary=True)
# Set the background
#background1 = lmfit.models.PolynomialModel(3,prefix="back_",)
background1 = lmfit.models.RectangleModel(prefix="back_", format='arctan')
pars.update(background1.guess(y, x=x)) 
# Make full model to fit
model = peak1 + background1
# Fit our full model
out = model.fit(y, pars, x=x)
# Make a more fine set of x's to plot with
xs= np.linspace(min(x), max(x), 100)
 # Plot our output model withe the new parameter and finer x's
plt.plot(xs, out.eval(params=out.params, x=xs), label='Total Fit')
plt.legend()
plt.show()

This code produce error: TypeError: lmfit.parameter.Parameter.set() argument after ** must be a mapping, not numpy.int64

This is indicating this line is responsible for the error: pars.update(background1.guess(y, x=x) It will not produce eror if I use PlynomialModel or other type models. StepModel and RectangleModel has this issue. My numpy version is 1.2.0 which has RectagleModel included. Any suggestions, how to resolve the issue?

I tried changing the models it worked (see pic attached) but not working with rectanglemodel. enter image description here


Solution

  • Thanks for updating the code and sorry for the trouble. I believe this reveals a bug in lmfit that should be raised as an Issue on Github and fixed. The issue seems to be that values of type np.Int64 are not currently recognized (in lmfit 1.2.0, due to changes introduced for that version, by me;)) correctly. I think a fix in the code is simple.

    For a quick workaround, I believe that doing

    pars.update(background1.guess(y*1.0, x=x*1.0)) 
    

    in your script should work correctly. To be clear, that should not be necessary, but it will avoid this current bug.