Reputation: 35
I have three sets of data (x,y) that define unique lineshapes. Using linear combination fitting I want to fit these three lineshapes to a fourth. I can set up the simple code below:
#read in data (three components)
header_list=['Energy','Intensity']
component_1 = pd.read_csv('Lineshape_average.txt', delimiter="\t", skiprows=1,names=header_list)
component_2=pd.read_csv('Morb_11.txt', delimiter="\t",skiprows=1,names=header_list)
component_3=pd.read_csv('PM224.txt', delimiter="\t", skiprows=1,names=header_list)
c1=component_1['Intensity']
c2=component_2['Intensity']
c3=component_3['Intensity']
#read in data to be fit
df1 = pd.read_csv(file_name, delimiter="\t", skiprows=1,names=header_list)
df1['unc']=0.1
#set up model
def equation(params, obvs_intensity, uncertainty):
a = params['a']
b = params['b']
c = params['c']
calc_intensity=a*c1+b*c2+c*c3
return (obvs_intensity-calc_intensity)/uncertainty
params = Parameters()
params.add('a', value = 0.33,min=0, max=1)
params.add('b',value =0.33,min=0, max=1)
params.add('c', value = 0.33, min=0, max=1)
#run model
result = minimize(equation, params, args =(df1['Intensity'],df1['unc']), nan_policy='omit')
Is there a way to allow the three components to shift in x (energy) so that I can get a better fit?
Upvotes: 0
Views: 32
Reputation: 189
You could try to fit your data using linear interpolation. You can for instance use scipy.interpolate.interp1d.
from scipy.interpolate import interp1d
f_intensity_1 = interp1d(component_1["Energy"], component_1["Intensity"])
f_intensity_2 = interp1d(component_2["Energy"], component_2["Intensity"])
f_intensity_3 = interp1d(component_3["Energy"], component_3["Intensity"])
f_intensity_df = interp1d(df["Energy"], df["Intensity"])
f_uncertainty_df = interp1d(df["Energy"], df["unc"]) # this probably will be constant in your case
Then you can add the energy as a parameter:
params = Parameters()
params.add('a', value = 0.33,min=0, max=1)
params.add('b',value =0.33,min=0, max=1)
params.add('c', value = 0.33, min=0, max=1)
# You can improve that using your knowledge of the system
params.add('e', value=component_1["Energy"].mean(), min=component_1["Energy"].min(), max=component_1["Energy"].max())
And update your equation as
def equation(params):
a = params['a']
b = params['b']
c = params['c']
e = params['e']
c1 = f_intensity_1(e)
c2 = f_intensity_2(e)
c3 = f_intensity_3(e)
obs_intensity = f_intensity_df(e)
uncertainty = f_uncertainty_df(e)
calc_intensity=a*c1+b*c2+c*c3
return (obvs_intensity-calc_intensity)/uncertainty
Would something like that work for you?
Upvotes: 0