Search code examples
pythonarrayscurve-fittinggaussiandata-fitting

one component Gaussian fit with python is not working


i have the orange peak that I want to do a Gaussian fit on with the aim of obtaining an estimate of the FWHM and the maximum temperature: enter image description here

The function is given by:

def Gauss(velo_peak, a, mu0, sigma):
          res = a * np.exp(-(velo_peak - mu0)**2 / (2 * sigma**2))
          return res

And my code is:

i1,i2 = 0,len(y)
n = len(x[i1:i2])
mu0 = sum(x[i1:i2] * y[i1:i2])/n
sigma = sum(y[i1:i2]*(x[i1:i2] - mu0)**2)/n
peak = max(y)
p0 = [peak, mu0, sigma]   # a = max(spec_peak)
popt,pcov = curve_fit(Gauss, x, y, p0, maxfev=100000)

but the fit is not working, I have tried playing around with the guess values but I cant find any reason why it is not working. any help would be much apreciated. The x-axis is given by this data:

109.774
109.774
109.774
109.774
109.774
109.774
109.774
109.774
109.774
109.774
109.774
109.774
109.775
109.775
109.775
109.775
109.775
109.775
109.775
109.775
109.775
109.775
109.775
109.775
109.775
109.776
109.776
109.776
109.776
109.776
109.776
109.776
109.776
109.776
109.776
109.776
109.776
109.776
109.777
109.777
109.777
109.777
109.777
109.777
109.777
109.777
109.777
109.777
109.777
109.777
109.777
109.778
109.778
109.778
109.778
109.778
109.778
109.778
109.778
109.778
109.778
109.778
109.778
109.778
109.779
109.779
109.779
109.779
109.779
109.779
109.779
109.779
109.779
109.779
109.779
109.779
109.779
109.78
109.78
109.78
109.78
109.78
109.78
109.78
109.78
109.78
109.78
109.78
109.78
109.78
109.781
109.781
109.781
109.781
109.781
109.781
109.781
109.781
109.781
109.781
109.781
109.781
109.781
109.782
109.782
109.782
109.782
109.782
109.782
109.782
109.782
109.782
109.782
109.782
109.782
109.782
109.783
109.783
109.783
109.783
109.783
109.783
109.783
109.783
109.783
109.783
109.783
109.783
109.783
109.783
109.784
109.784
109.784
109.784
109.784
109.784
109.784
109.784
109.784
109.784
109.784
109.784
109.784
109.785
109.785
109.785
109.785
109.785
109.785
109.785
109.785
109.785
109.785
109.785
109.785
109.785
109.786
109.786
109.786
109.786
109.786
109.786
109.786
109.786
109.786
109.786
109.786
109.786
109.786
109.787
109.787
109.787
109.787
109.787
109.787
109.787
109.787
109.787
109.787
109.787
109.787
109.787
109.788
109.788
109.788
109.788
109.788
109.788
109.788
109.788
109.788
109.788
109.788
109.788
109.788
109.789
109.789
109.789
109.789
109.789
109.789
109.789
109.789
109.789
109.789
109.789
109.789
109.789
109.79
109.79
109.79
109.79
109.79
109.79
109.79
109.79
109.79
109.79
109.79
109.79
109.79
109.791
109.791

and the y axis:

-0.0693423
-0.0383312
-0.0130822
0.00771434
-0.00475569
-0.0288578
-0.00323742
0.000307108
-0.0181949
0.00129764
0.00661946
-0.0116734
0.0439911
-0.0189704
0.0134336
0.017783
-0.00059444
0.00129813
-0.0146921
-0.0178051
0.00210355
0.00739107
0.0193562
0.0177199
-0.0115096
-0.0148834
-0.0359211
0.0268527
0.0159948
0.0214348
0.015795
0.00807647
-0.0597478
-0.037623
0.000166686
0.0119881
0.0127355
0.00687692
0.00479245
-0.0207917
0.0627117
0.0133312
0.011981
0.0308865
0.0323675
-0.0353238
0.0498601
0.00484114
-0.00354253
-0.0181545
0.0476038
0.019046
0.0195323
-0.013426
-0.0154619
0.0129866
-0.0158984
0.0126304
0.0269754
-0.00217857
0.0206669
-0.0219605
-0.0224113
0.00217749
-0.0359304
0.0273953
0.0133183
0.0202708
-0.0144499
0.0351752
-0.0202478
-0.0074738
0.0127188
-0.0116596
0.00869577
-0.0234507
0.0373167
0.00263353
0.0166561
-0.0043449
-0.0229105
-0.00741182
0.0467549
-0.0235804
-0.0191783
0.0528504
-0.00901956
0.043926
0.0223436
0.0181945
-0.0400392
0.0220731
-0.0167595
0.0214929
0.028309
-0.0234769
-0.0419024
0.0131882
-0.00421679
0.00359541
-0.055839
-0.0599337
-0.0283572
0.00686772
-0.00965801
0.0164275
0.00458221
-0.00909531
0.138937
0.297971
0.247663
0.124508
0.0365572
-0.00971529
0.0238192
-0.0509615
-0.0101447
-0.0298155
-0.0196555
0.0224242
-0.0329058
-0.00786179
-0.00347346
-0.0102662
0.0111553
0.013002
-0.0375893
0.00996665
-0.0125302
-0.00829957
0.0366645
0.0219919
-0.038467
-0.0260219
-0.0375669
0.00625599
-0.0498297
0.0258702
-0.0217369
-0.0349204
-0.014657
-0.0180611
-0.0420286
-0.000379184
-0.0333805
-0.0551173
-0.0224908
0.0179898
0.020866
0.0288823
-0.0182207
-0.0413725
-0.0162658
0.00223817
0.0243006
-0.0170214
0.0320711
0.0012465
0.00344509
0.00150138
-0.00169928
-0.0139581
0.0552647
0.0229482
-0.00316584
-0.033333
0.000161762
-0.00905961
-0.00685663
-0.0162735
-0.0399026
0.0270222
0.00798811
-0.00408101
-0.0072991
0.0112089
-0.012056
0.0146916
-0.00340297
0.0217221
0.00722562
-0.0203967
-0.0150112
0.00900151
0.0322559
0.00482019
-0.000814166
-0.0225995
-0.00817639
0.0201735
-0.0285309
0.0355886
0.000298672
-0.0129141
0.0428829
-0.028223
0.0183822
-6.62023e-05
0.0358768
-0.0293772
0.0125377
-0.00919312
0.00703798
0.00537255
-0.00413266
0.0505678
-0.00586183
0.0087835
-0.0113064
-0.0198051
0.0477742
0.00607189
-0.0112695
0.0288124
0.0354801
-0.0550288
-0.00167514
-0.0440247
-0.00573284
0.0138037
0.0170393
-0.0350715
0.0333013


Solution

  • The typical reason for the fail is: wrong starting parameters. The formulae used here are somewhat those that would be used for a measurement statistic, while the data here has to be considered the according histogram. The use of n, hence, does not make sense. It is more like

    ## smoothing the data with its own noisy Gaussian
    ysmooth = np.convolve( y, y[::-1], mode="same")
    mu0 = sum( x * y ) / sum( y )
    ## the abs() is wrong but the strong noise forces it
    sigma = np.sqrt( sum( np.abs( ysmooth ) * (  ( x - mu0 ) )**2 ) / sum( np.abs(ysmooth)) )
    peak = max( y )
    

    The total scale n is unknown but the relative amount of x values is gives as the value of the histogram, i.e. y. The guess for sigma is a bit messy, but works here. It is quite of but the fit converges without increasing maxfev