简体   繁体   中英

How do I perform a gaussian curve fit in the presence of a linear background with scipy?

I have the given data set:

在此输入图像描述

Of which I would like to fit a Gaussian curve at the point where the red arrow is directed towards. I have attempted to do so by restricting the data points to a range of channels close to the peak, using scipy.optimize.curve_fit and a gaussian function to obtain the fit as shown below.

在此输入图像描述

This method, however, does not take into account the slope of the background noise of the data points. Thus affecting the accuracy of the position of the peak of the fitted curve by the above-mentioned method.

I would like to take into account this background slope. How do I go about doing so in python?

You have to somehow model the background and the Gaussian peak, and perhaps any other peaks in the spectrum. Your background looks to be roughly 1/x (or some other power of x ), but it might also be exponential. You may know this, or you may find that plotting on a semi-log plot can help decide which of these forms is better.

To fit the background and Gaussian with curve_fit , you would have to write a model function that modeled both. Allow me to recommend using lmfit ( http://lmfit.github.io/lmfit-py/ ) as it has several built-in models and can help you compose a model of several different line shapes. An example that might be helpful for your problem is at ( http://lmfit.github.io/lmfit-py/builtin_models.html#example-3-fitting-multiple-peaks-and-using-prefixes ).

A script to fit your data might look like

import numpy as np
from lmfit.models import PowerLawModel, ExponentialModel, GaussianModel

# make models for individual components
mod_expon = ExponentialModel(prefix='exp_')
mod_gauss = GaussianModel(prefix='g1_')

# sum components to make a composite model (add more if needed)
model  = mod_expon + mod_gauss

# create fitting parameters by name, give initial values
params = model.make_params(g1_amplitude=5, g1_center=55, g1_sigma=5, 
                           exp_amplitude=5, exp_decay=10)

# do fit
result = model.fit(ydata, params, x=xdata)

# print out fitting statistics, best-fit parameters, uncertainties,....
print(result.fit_report())

There are many more examples in the docs, including showing how to extract and plot the individual components, and so on.

How I would do this is to use a fit that fits to both the signal and the background. That is, fit not just a Gaussian, but a fit that is a Guassian plus a function that fits the background. The first approximation to your background is a linear slope, so you could use a form like a*exp(-(x-x0)**2/w**2) + m*x + c .

This gives you more fitting parameters, all of which are interdependent, but if you can give them reasonable initial values then the fit normally converges well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM