python - Gaussian Fit on noisy and 'interesting' data set -


i have data (x-ray diffraction) looks this:

enter image description here

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 :) ):

enter image description here

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:

enter image description here

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:

  1. a linear baseline, because points offset zero.
  2. two narrow gaussian components model double-peaked feature @ central part of spectrum.
  3. 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() 

enter image description here

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

Popular posts from this blog

sql server - Cannot query correctly (MSSQL - PHP - JSON) -

php - trouble displaying mysqli database results in correct order -

C++ Linked List -