2

I am sorry for a fairly basic question, but I am having trouble understanding the syntax with lmfit and can't come up with why this error comes up. The error is specifically:

"KeyError: 'flux'"

I understand that it wants some type of dictionary object, but still don't see the disagreement with my code and the lmfit documentation.

I have created a function to be the model of a certain distribution. I want to use this model to fit to an actual data distribution. This distribution is binned data hence the part I get the midpoints of the bins to use as the x-axis data points.

def flemming(flux,alpha,fhalf):

    a = alpha*np.log10(flux/fhalf)
    b = np.sqrt(1+a**2)
    return (1/2)*(1+(a/b))

def f20func(flux,alpha,fhalf):

    return flemming(flux,alpha,fhalf) - 0.2

def modified(flux,alpha,fhalf):

    flem = flemming(flux,alpha,fhalf)
    f20 = fsolve(f20func,fhalf/2,args=(alpha,fhalf))
    tau = 1 - np.exp(-flux/f20)

    return flem**(1/tau)


def powerlaw(flux,beta,c):

    return c*flux**(-beta)


def distribution(flux,alpha,fhalf,beta,c):
    return powerlaw(flux,beta,c)*modified(flux,alpha,fhalf)

n_bins = 40
    
    
y_data, bin_edges, patches = plt.hist(flux,bins=n_bins,ec='black')
    
i = 0
  
midpoints = []
   
while i < len(bin_edges)-1:
    midpoints.append((bin_edges[i+1]+bin_edges[i])/2)
        
    i+=1
    
    
model = Model(distribution)
    
    
    
aegis_params = model.make_params()
aegis_params['alpha'].set(value=3.4,min=3.0,max=3.8)
aegis_params['fhalf'].set(value=3.9,min=3.5,max=4.4)
aegis_params['beta'].set(value=3.5,min=3.2,max=3.8)
aegis_params['c'].set(value=45000.0,min=0.0)
    
    
best_fit = model.fit(y_data,params=aegis_params,x=midpoints)

Vickel
  • 7,879
  • 6
  • 35
  • 56
astroguy
  • 45
  • 4

1 Answers1

0

I think that the problem you are seeing is because you used:

   best_fit = model.fit(y_data,params=aegis_params,x=midpoints)

but your model function (your distribution()) does not have an x defined and instead will have an independent variable named flux. I would guess that you want

   best_fit = model.fit(y_data, params=aegis_params, flux=midpoints)

By default, the first argument to the model function will be considered the independent variable, and all the other positional arguments and those keyword arguments with numeric defaults will be turned into parameters.

To be clear, you can have multiple independent variables and they can be in positions other than the first argument, and the name x is not at all special. Also: the independent variables are passed through to your model function without any coercion or checks on data type, and so can be complex objects or data structures.

M Newville
  • 7,486
  • 2
  • 16
  • 29