python - Gaussian Fit on noisy and 'interesting' data set -
i have data (x-ray diffraction) looks this:
i want fit gaussian data set fwhm of 'wider' portion. double peak @ around 7 degrees theta not important information , coming unwanted sources.
to make myself more clear want (which made in paint :) ):
i have tried script in python following code:
import math pylab import * import numpy np import scipy sp import matplotlib.pyplot plt scipy.optimize import curve_fit data2=np.loadtxt('fwhm.spc') x2,y2=data2[:,0],data2[:,7] plt.title('full width half max of 002 peak') plt.plot(x2, y2, color='b') plt.xlabel('$\\theta$', fontsize=10) plt.ylabel('intensity', fontsize=10) plt.xlim([3,11]) plt.xticks(np.arange(3, 12, 1), fontsize=10) plt.yticks(fontsize=10) def func(x, a, x0, sigma): return a*np.exp(-(x-x0)**2/(2*sigma**2)) mean = sum(x2*y2)/sum(y2) sigma2 = sqrt(abs(sum((x2-mean)**2*y2)/sum(y2))) popt, pcov = curve_fit(func, x2, y2, p0 = [1, mean, sigma2]) ym = func(x2, popt[0], popt[1], popt[2]) plt.plot(x2, ym, c='r', label='best fit') fwhm = round(2*np.sqrt(2*np.log(2))*popt[2],4) axvspan(popt[1]-fwhm/2, popt[1]+fwhm/2, facecolor='g', alpha=0.3, label='fwhm = %s'%(fwhm)) plt.legend(fontsize=10) plt.show() and following output:
clearly, way off desired. have tips how can acheive this?
(i have enclosed data here: https://justpaste.it/109qp)
as mentioned in op comments, 1 of ways constrain signal in presence of unwanted data model desired signal. of course, approach valid only when there valid model readily available contaminating data. data provide, 1 can consider composite model sums on following components:
- a linear baseline, because points offset zero.
- two narrow gaussian components model double-peaked feature @ central part of spectrum.
- a narrow gaussian component. 1 you're trying constrain.
all 4 components (double peak counts twice) can fit simultaneusly once pass reasonable starting guess curve_fit:
def composite_spectrum(x, # data a, b, # linear baseline a1, x01, sigma1, # 1st line a2, x02, sigma2, # 2nd line a3, x03, sigma3 ): # 3rd line return (x*a + b + func(x, a1, x01, sigma1) + func(x, a2, x02, sigma2) + func(x, a3, x03, sigma3)) guess = [1, 200, 1000, 7, 0.05, 1000, 6.85, 0.05, 400, 7, 0.6] popt, pcov = curve_fit(composite_spectrum, x2, y2, p0 = guess) plt.plot(x2, composite_spectrum(x2, *popt), 'k', label='total fit') plt.plot(x2, func(x2, *popt[-3:])+x2*popt[0]+popt[1], c='r', label='broad component') fwhm = round(2*np.sqrt(2*np.log(2))*popt[10],4) plt.axvspan(popt[9]-fwhm/2, popt[9]+fwhm/2, facecolor='g', alpha=0.3, label='fwhm = %s'%(fwhm)) plt.legend(fontsize=10) plt.show() in case when unwanted sources can not modeled properly, unwanted discontinuity can masked out suggested mad physicist. simplest case can mask out eveything inside [6.5; 7.4] interval.




Comments
Post a Comment