def lmfit_ngauss(x,y, *params): params = params[0] mods = [] prefixes = [] for i in range(0, len(params), 3): pref = "g%02i_" % (i/3) gauss_i = GaussianModel(prefix=pref) if i == 0: pars = gauss_i.guess(y, x=x) else: pars.update(gauss_i.make_params()) A = params[i] l_cen = params[i+1] sigma = params[i+2] pars[pref+'amplitude'].set(A) pars[pref+'center'].set(l_cen) pars[pref+'sigma'].set(sigma) mods.append(gauss_i) prefixes.append(pref) mod = mods[0] if len(mods) > 1: for m in mods[1:]: mod += m print mod init = mod.eval(pars, x=x) out = mod.fit(y, pars, x=x) return mod, out, init
def test_2gaussians(): x = np.linspace(0.0, 10.0, num=1000) y = gaussian(x, -1, 3, 0.75) + gaussian(x, -0.5, 5, 0.8) + np.random.normal(0, 0.01, x.shape[0]) gauss1 = GaussianModel(prefix='g1_') pars = gauss1.guess(y, x=x) pars['g1_amplitude'].set(-0.9) pars['g1_center'].set(2.5) pars['g1_sigma'].set(0.5) gauss2 = GaussianModel(prefix='g2_') pars.update(gauss2.make_params()) pars['g2_amplitude'].set(-0.4) pars['g2_center'].set(5) pars['g2_sigma'].set(0.5) mod = gauss1 + gauss2 init = mod.eval(pars, x=x) plt.plot(x, y) plt.plot(x, init, 'k--') out = mod.fit(y, pars, x=x) print(out.fit_report(min_correl=0.5)) plt.plot(x, out.best_fit, 'r-') plt.show()
def GaussConst(signal, guess): amp, centre, stdev, offset = guess data = np.array([range(len(signal)), signal]).T X = data[:,0] Y = data[:,1] gauss_mod = GaussianModel(prefix='gauss_') const_mod = ConstantModel(prefix='const_') pars = gauss_mod.make_params(center=centre, sigma=stdev, amplitude=amp) pars += const_mod.guess(Y, x=X) pars['gauss_center'].min = centre - 5. pars['gauss_center'].max = centre + 5. pars['gauss_sigma'].max = stdev + 5. mod = gauss_mod + const_mod result = mod.fit(Y, pars, x=X) fwhm = result.best_values['gauss_sigma'] #* 2.3548 centr = result.best_values['gauss_center'] # Values within two stdevs i.e. 95% pl.plot(np.repeat(centr - fwhm * 2, len(Y)), np.arange(len(Y)), 'b-') pl.plot(np.repeat(centr + fwhm * 2, len(Y)), np.arange(len(Y)), 'b-') return X, result.best_fit, result.best_values['gauss_sigma'] * 4
def call_gauss(x, y, cen, count, pars): label='g'+str(count)+'_' gauss = GaussianModel(prefix=label) pars.update(gauss.make_params()) pars[label+'center'].set(cen, min=cen-0.01, max=cen+0.01) pars[label+'amplitude'].set(-0.5, min=-10., max=0.0001) pars[label+'sigma'].set(0.1, min=0.005, max=0.25) return gauss
def xrf_calib_init_roi(mca, roiname): """initial calibration step for MCA: find energy locations for one ROI """ if not isLarchMCAGroup(mca): print( 'Not a valid MCA') return energy = 1.0*mca.energy chans = 1.0*np.arange(len(energy)) counts = mca.counts bgr = getattr(mca, 'bgr', None) if bgr is not None: counts = counts - bgr if not hasattr(mca, 'init_calib'): mca.init_calib = OrderedDict() roi = None for xroi in mca.rois: if xroi.name == roiname: roi = xroi break if roi is None: return words = roiname.split() elem = words[0].title() family = 'Ka' if len(words) > 1: family = words[1].title() if family == 'Lb': family = 'Lb1' eknown = xray_line(elem, family)[0]/1000.0 llim = max(0, roi.left - roi.bgr_width) hlim = min(len(chans)-1, roi.right + roi.bgr_width) segcounts = counts[llim:hlim] maxcounts = max(segcounts) ccen = llim + np.where(segcounts==maxcounts)[0] ecen = ccen * mca.slope + mca.offset bkgcounts = counts[llim] + counts[hlim] if maxcounts < 2*bkgcounts: mca.init_calib[roiname] = (eknown, ecen, 0.0, ccen, None) else: model = GaussianModel() + ConstantModel() params = model.make_params(amplitude=maxcounts, sigma=(chans[hlim]-chans[llim])/2.0, center=ccen-llim, c=0.00) params['center'].min = -10 params['center'].max = hlim - llim + 10 params['c'].min = -10 out = model.fit(counts[llim:hlim], params, x=chans[llim:hlim]) ccen = llim + out.params['center'].value ecen = ccen * mca.slope + mca.offset fwhm = out.params['fwhm'].value * mca.slope mca.init_calib[roiname] = (eknown, ecen, fwhm, ccen, out)
def create_model_params(x, y): """Create the model and parameters.""" exp_mod = ExponentialModel(prefix='exp_') params = exp_mod.guess(y, x=x) gauss1 = GaussianModel(prefix='g1_') params.update(gauss1.make_params()) gauss2 = GaussianModel(prefix='g2_') params.update(gauss2.make_params()) params['g1_center'].set(value=105, min=75, max=125) params['g1_sigma'].set(value=15, min=3) params['g1_amplitude'].set(value=2000, min=10) params['g2_center'].set(value=155, min=125, max=175) params['g2_sigma'].set(value=15, min=3) params['g2_amplitude'].set(value=2000, min=10) model = gauss1 + gauss2 + exp_mod return model, params
def get_gaussianmodel(amplitude=1.0, center=5.0, sigma=1.0, noise=0.1): # create data to be fitted np.random.seed(7392) x = np.linspace(-20, 20, 201) y = gaussian(x, amplitude, center=center, sigma=sigma) y = y + np.random.normal(size=len(x), scale=noise) model = GaussianModel() params = model.make_params(amplitude=amplitude/5.0, center=center-1.0, sigma=sigma*2.0) return x, y, model, params
def fitTwoGaussians(x,y): background = PolynomialModel(2) pars = background.make_params() peak1 = GaussianModel(prefix='p1_') pars.update( peak1.make_params()) peak2 = GaussianModel(prefix='p2_') pars.update( peak2.make_params()) # Guess some parameters from data to help the fitting span = max(x)-min(x) c1Guess = (y[-1]-y[0])/(x[-1]-x[0]) c0Guess = y[0]-c1Guess*x[0] bgGuess = background.func(x=x,c0=c0Guess,c1=c1Guess,c2=0.) signalGuess=min(y-bgGuess) sigmaGuess = span/30. amplitudeGuess = signalGuess*(sigmaGuess*np.sqrt(2.0*np.pi)) # Fit variables initialization # pars.add('splitting',0.0001,max=span) pars['c2'].set(0.,min=-0.000001,max=0.001) pars['c1'].set(c1Guess) pars['c0'].set(c0Guess) pars['p1_center'].set(min(x)+span*0.35,min=min(x),max=max(x)) pars['p2_center'].set(min(x)+span*0.55,min=min(x),max=max(x)) # pars['p2_center'].set(min(x)+span*0.65,expr='p1_center+splitting') pars['p1_amplitude'].set(amplitudeGuess,max=amplitudeGuess/10000.) pars['p2_amplitude'].set(amplitudeGuess,max=amplitudeGuess/10000.) pars['p1_sigma'].set(sigmaGuess, min=sigmaGuess/100.,max=sigmaGuess*10000.) pars['p2_sigma'].set(sigmaGuess, min=sigmaGuess/100.,max=sigmaGuess*10000.) #Add some useful parameters to evaluate pars.add('p1_signal', expr='p1_amplitude/(p1_sigma*sqrt(2.0*pi))') pars.add('p2_signal', expr='p2_amplitude/(p2_sigma*sqrt(2.0*pi))') pars.add('p1_contrast', expr='-p1_amplitude/(p1_sigma*sqrt(2.0*pi)*(c0+c1*p1_center+c2*p1_center**2))') pars.add('p2_contrast', expr='-p2_amplitude/(p2_sigma*sqrt(2.0*pi)*(c0+c1*p2_center+c2*p2_center**2))') pars.add('splitting',pars['p2_center']-pars['p1_center'],expr='p2_center-p1_center',min=0.00001) model = peak1 + peak2 + background init = model.eval(pars, x=x) out = model.fit(y, pars, x=x) # print out.fit_report() return init,out
def test_example_2_Gaussians_1_exp(): dat = np.loadtxt('NIST_Gauss2.dat') x = dat[:, 1] y = dat[:, 0] exp_mod = ExponentialModel(prefix='exp_') pars = exp_mod.guess(y, x=x) gauss1 = GaussianModel(prefix='g1_') pars.update(gauss1.make_params()) pars['g1_center'].set(105, min=75, max=125) pars['g1_sigma'].set(15, min=3) pars['g1_amplitude'].set(2000, min=10) gauss2 = GaussianModel(prefix='g2_') pars.update(gauss2.make_params()) pars['g2_center'].set(155, min=125, max=175) pars['g2_sigma'].set(15, min=3) pars['g2_amplitude'].set(2000, min=10) mod = gauss1 + gauss2 + exp_mod init = mod.eval(pars, x=x) plt.plot(x, y) plt.plot(x, init, 'k--') out = mod.fit(y, pars, x=x) print(out.fit_report(min_correl=0.5)) plt.plot(x, out.best_fit, 'r-') plt.show()
def lmfit_ngauss_constrains(x,y, params, constrains): """ INPUT: x - is the wavelength array y - is the normalized flux params - is a list/array of initial guess values for the parameters (this controls the number of gaussians to be fitted number of gaussians: len(params)/3 - 3 parameters per Gaussian) contrains - the limits of the constrains for the fit of the parameters OUTPUT: mod - the lmfit model object used for the fit out - the lmfit fit object that contains all the results of the fit init- array with the initial guess model (usefull to see the initial guess when plotting) """ mods = [] prefixes = [] for i in range(0, len(params), 3): pref = "g%02i_" % (i/3) gauss_i = GaussianModel(prefix=pref) if i == 0: pars = gauss_i.guess(y, x=x) else: pars.update(gauss_i.make_params()) A = params[i] limA = constrains[i] l_cen = params[i+1] limL = constrains[i+1] sigma = params[i+2] limS = constrains[i+2] pars[pref+'amplitude'].set(A, min=limA[0], max=limA[1]) pars[pref+'center'].set(l_cen, min=limL[0], max=limL[1]) pars[pref+'sigma'].set(sigma, min=limS[0], max=limS[1]) mods.append(gauss_i) prefixes.append(pref) mod = mods[0] if len(mods) > 1: for m in mods[1:]: mod += m init = mod.eval(pars, x=x) out = mod.fit(y, pars, x=x) return mod, out, init
def test_itercb(): x = np.linspace(0, 20, 401) y = gaussian(x, amplitude=24.56, center=7.6543, sigma=1.23) y = y - .20*x + 3.333 + np.random.normal(scale=0.23, size=len(x)) mod = GaussianModel(prefix='peak_') + LinearModel(prefix='bkg_') pars = mod.make_params(peak_amplitude=21.0, peak_center=7.0, peak_sigma=2.0, bkg_intercept=2, bkg_slope=0.0) out = mod.fit(y, pars, x=x, iter_cb=per_iteration) assert(out.nfev == 23) assert(out.aborted) assert(not out.errorbars) assert(not out.success)
def GaussConst(signal, guess): """ Fits a Gaussian function Plots fwhm and 2*sigma gap widths for comparison with the analytically calculated one """ amp, centre, stdev, offset = guess data = np.array([range(len(signal)), signal]).T X = data[:,0] Y = data[:,1] gauss_mod = GaussianModel(prefix='gauss_') const_mod = ConstantModel(prefix='const_') pars = gauss_mod.make_params(center=centre, sigma=stdev, amplitude=amp) pars += const_mod.guess(Y, x=X) pars['gauss_center'].min = centre - 5. pars['gauss_center'].max = centre + 5. pars['gauss_sigma'].max = stdev + 5. mod = gauss_mod + const_mod result = mod.fit(Y, pars, x=X) fwhm = result.best_values['gauss_sigma'] #* 2.3548 centr = result.best_values['gauss_center'] # Values within two stdevs i.e. 95% pl.plot(np.repeat(centr - fwhm * 2, len(Y)), np.arange(len(Y)), 'b-') pl.plot(np.repeat(centr + fwhm * 2, len(Y)), np.arange(len(Y)), 'b-', label="Sigma * 2") pl.plot(np.repeat(centr - fwhm * 2.3548 / 2., len(Y)), np.arange(len(Y)), 'y--') pl.plot(np.repeat(centr + fwhm * 2.3548 / 2., len(Y)), np.arange(len(Y)), 'y--', label="FWHM") return X, result.best_fit, result.best_values['gauss_sigma'] * 4, centr
def measure_line_index_recover_spectrum(wave, params, norm=False): """ recover the fitted line profile from params Parameters ---------- wave: array-like the wavelength to which the recovered flux correspond params: 5-element tuple the 1 to 5 elements are: mod_linear_slope mod_linear_intercept mod_gauss_amplitude mod_gauss_center mod_gauss_sigma norm: bool if True, linear model (continuum) is deprecated else linear + Gaussian model is used """ from lmfit.models import LinearModel, GaussianModel mod_linear = LinearModel(prefix='mod_linear_') mod_gauss = GaussianModel(prefix='mod_gauss_') par_linear = mod_linear.make_params() par_gauss = mod_gauss.make_params() par_linear['mod_linear_slope'].value = params[0] par_linear['mod_linear_intercept'].value = params[1] par_gauss['mod_gauss_amplitude'].value = params[2] par_gauss['mod_gauss_center'].value = params[3] par_gauss['mod_gauss_sigma'].value = params[4] if not norm: flux = 1 - mod_gauss.eval(params=par_gauss, x=wave) else: flux = \ (1 - mod_gauss.eval(params=par_gauss, x=wave)) * \ mod_linear.eval(params=par_linear, x=wave) return flux
def lmfit_ngauss_constrains(x,y, params, constrains): #params = params[0] #constrains = constrains[0] mods = [] prefixes = [] for i in range(0, len(params), 3): pref = "g%02i_" % (i/3) gauss_i = GaussianModel(prefix=pref) if i == 0: pars = gauss_i.guess(y, x=x) else: pars.update(gauss_i.make_params()) A = params[i] limA = constrains[i] l_cen = params[i+1] limL = constrains[i+1] sigma = params[i+2] limS = constrains[i+2] pars[pref+'amplitude'].set(A, min=limA[0], max=limA[1]) pars[pref+'center'].set(l_cen, min=limL[0], max=limL[1]) pars[pref+'sigma'].set(sigma, min=limS[0], max=limS[1]) mods.append(gauss_i) prefixes.append(pref) mod = mods[0] if len(mods) > 1: for m in mods[1:]: mod += m init = mod.eval(pars, x=x) out = mod.fit(y, pars, x=x) return mod, out, init
def test_reports_created(): """do a simple Model fit but with all the bells-and-whistles and verify that the reports are created """ x = np.linspace(0, 12, 601) data = gaussian(x, amplitude=36.4, center=6.70, sigma=0.88) data = data + np.random.normal(size=len(x), scale=3.2) model = GaussianModel() params = model.make_params(amplitude=50, center=5, sigma=2) params['amplitude'].min = 0 params['sigma'].min = 0 params['sigma'].brute_step = 0.001 result = model.fit(data, params, x=x) report = result.fit_report() assert(len(report) > 500) html_params = result.params._repr_html_() assert(len(html_params) > 500) html_report = result._repr_html_() assert(len(html_report) > 1000)
def fit_cu_line(xin, yin, line_c=8.04, use_weights=True): ''' PURPOSE: Fit the Cu Ka line (8.04 keV), the model is a polynomial(2) + a Gaussian line. INPUTS: xin is the energy channel (in keV) yin is the counts line_c is the initial energy of the line (in keV) OUTPUTS: a tuple of the full fit output class and the results line in ascii. NOTES: the Gaussian sigma of the line is only allowed within a certain range: 80 to 250 eV ''' i1max = np.argmax(yin) y1max = yin[i1max] # poly_mod = PolynomialModel(1, prefix='poly_') pars = poly_mod.guess(yin, x=xin) # pname = 'cuka' gauss1 = GaussianModel(prefix=f"{pname}_") pars.update(gauss1.make_params()) pars[f'{pname}_center'].set(line_c, min=line_c - 0.25, max=line_c + 0.25) pars[f'{pname}_sigma'].set(0.1, min=0.08, max=0.250) #pars[f'{pname}_amplitude'].set(y1max,min=1.0,max=y1max) # mod = poly_mod + gauss1 #init = mod.eval(pars, x=x) #out = mod.fit(yin, pars, x=xin, weights=1.0/np.sqrt(yin)) if (use_weights): yerr = np.sqrt(yin) w = np.divide(1.0, yerr, where=yerr != 0) try: out = mod.fit(yin, pars, x=xin, weights=w, nan_policy='omit') except: return None else: try: out = mod.fit(yin, pars, x=xin, nan_policy='omit') except: return None # # confidence intervals on parameters, if needed # #ci_out = out.conf_interval() #print (ci_out['cuka_center']) # #cen = out.params['g1_center'].value #cen_err = out.params['g1_center'].stderr #fwhm = out.params['g1_fwhm'].value #fwhm_err = out.params['g1_fwhm'].stderr #chi2 = out.chisqr #df = len(xin) #try: # results = f"{cen:.3f},{cen_err:.3f},{fwhm:.5f},{fwhm_err:.5f},{chi2:.3f},{df}" #except: # results = None # return out
gauss_x.append(iterator) gauss_y.append(list_data[iterator]) x = np.asarray(gauss_x) y = np.asarray(gauss_y) fit_channel.append(list_data[iterator]) list_data[iterator] = 0 iterator += 1 i += 1 ''' information for plotting the Gaussian function. ''' mod = GaussianModel(prefix='g1_') line_mod = LinearModel(prefix='line') pars = mod.guess(y, x=x) pars.update(line_mod.make_params(intercept=y.min(), slope=0)) pars.update( mod.make_params()) pars['g1_center'].set(gauss_x[np.argmax(gauss_y)], min=gauss_x[np.argmax(gauss_y)]\ - 3) pars['g1_sigma'].set(3, min=0.25) pars['g1_amplitude'].set(max(gauss_y), min=max(gauss_y)-10) mod = mod + line_mod out = mod.fit(y, pars, x=x) center = out.params['g1_center'].value center_std = out.params['g1_center'].stderr channel_max_list.append(center) channel_std_list.append(center_std) gauss_x = []; gauss_y = []; fit_channel = [] #print(out.fit_report(min_correl=10)) #for key in out.params: # print(key, "=", out.params[key].value, "+/-", out.params[key].stderr)
# <examples/doc_builtinmodels_nistgauss.py> import matplotlib.pyplot as plt import numpy as np from lmfit.models import ExponentialModel, GaussianModel dat = np.loadtxt('NIST_Gauss2.dat') x = dat[:, 1] y = dat[:, 0] exp_mod = ExponentialModel(prefix='exp_') pars = exp_mod.guess(y, x=x) gauss1 = GaussianModel(prefix='g1_') pars.update(gauss1.make_params()) pars['g1_center'].set(105, min=75, max=125) pars['g1_sigma'].set(15, min=3) pars['g1_amplitude'].set(2000, min=10) gauss2 = GaussianModel(prefix='g2_') pars.update(gauss2.make_params()) pars['g2_center'].set(155, min=125, max=175) pars['g2_sigma'].set(15, min=3) pars['g2_amplitude'].set(2000, min=10) mod = gauss1 + gauss2 + exp_mod
amps=y_real[peakind]/twopisig amps=amps.clip(min=0) print "peaks GS" print pks print "real GS" print len(real_lines) modlist=[] for i in range(pks): gauss = GaussianModel(prefix='g'+str(i)+'_') if i==0: pars=gauss.make_params() else: pars.update(gauss.make_params()) pars['g'+str(i)+'_center'].set(means[i],min=f_pos-bw/2.0,max=f_pos+bw/2.0) #pars['g'+str(i)+'_center'].set(means[i]) pars['g'+str(i)+'_sigma'].set(sigmas[i], min=0.0001, max=10*sigma_up) pars['g'+str(i)+'_amplitude'].set(amps[i], min=0) if i==0: mod=gauss else: mod = mod + gauss #print pars out = mod.fit(y_real,pars, x=x) fq=[]
def NewFit5(amp1, amp2, amp3, amp4, amp5, mu1, mu2, mu3, mu4, mu5, sig1, sig2, sig3, sig4, sig5, x, y): '==========================================' 'Define the first gaussian' gauss1 = GaussianModel(prefix='g1_') # Model first as a gaussian pars = gauss1.guess(y, x=x) # Make a gautomatic guess of the parameters 'Set the Parameters values' pars['g1_center'].set(mu1, vary=True) pars['g1_sigma'].set(sig1, vary=True) pars['g1_amplitude'].set(amp1, vary=True) '===========================================' 'Define the second Gaussian' gauss2 = GaussianModel(prefix='g2_') pars.update( gauss2.make_params()) #update the parameter list with another gaussian pars['g2_center'].set(mu2, vary=True) pars['g2_sigma'].set(sig2, vary=True) pars['g2_amplitude'].set(amp2, min=0, vary=True) '===========================================' 'Define the third Gaussian' gauss3 = GaussianModel(prefix='g3_') pars.update( gauss3.make_params()) #update the parameter list with another gaussian pars['g3_center'].set(mu3, min=0.2, vary=True) pars['g3_sigma'].set(sig3, vary=True) pars['g3_amplitude'].set(amp3, min=0, vary=True) '===========================================' 'Define the four Gaussian' gauss4 = GaussianModel(prefix='g4_') pars.update( gauss4.make_params()) #update the parameter list with another gaussian pars['g4_center'].set(mu4, min=0.3, vary=True) pars['g4_sigma'].set(sig4, max=0.4, vary=True) pars['g4_amplitude'].set(amp4, min=0, vary=True) '===========================================' 'Define the fith Gaussian' gauss5 = GaussianModel(prefix='g5_') pars.update( gauss5.make_params()) #update the parameter list with another gaussian pars['g5_center'].set(mu5, max=3.7, vary=True) pars['g5_sigma'].set(sig5, min=0, max=0.35, vary=True) pars['g5_amplitude'].set(amp5, min=0, vary=True) '===========================================' 'Make the model as the sum of gaussians' mod = gauss1 + gauss2 + gauss3 + gauss4 + gauss5 'Fit and print the data' out = mod.fit(y, pars, x=x) print(out.fit_report(min_correl=0.5)) plt.plot(x, out.best_fit, 'r-', linewidth=1.50) plt.show() return pars
def per_iteration(pars, iter, resid, *args, **kws): if iter < 3 or iter % 10 == 0: out = ['== %i ' % iter] for key, val in pars.valuesdict().items(): out.append('%s=%.3f' % (key, val)) print ', '.join(out) print args, kws x = linspace(0., 20, 401) y = gaussian(x, amplitude=24.56, center=7.6543, sigma=1.23) y = y - .20*x + 3.333 + random.normal(scale=0.23, size=len(x)) mod = GaussianModel(prefix='peak_') + LinearModel(prefix='bkg_') pars = mod.make_params() pars['peak_amplitude'].value = 3.0 pars['peak_center'].value = 6.0 pars['peak_sigma'].value = 2.0 pars['bkg_intercept'].value = 0.0 pars['bkg_slope'].value = 0.0 out = mod.fit(y, pars, x=x, iter_cb=per_iteration) pylab.plot(x, y, 'b--') # print(' Nfev = ', out.nfev) print( out.fit_report()) pylab.plot(x, out.best_fit, 'k-')
def lmfit_mngauss(x,y, *params): """ Fit multiple gaussians from two spectra that are multiplied together INPUT: x - is the wavelength array y - is the normalized flux params - is a tuple of 2 list/arrays of initial guess values for the each spectras parameters (this controls the number of gaussians to be fitted number of gaussians: len(params)/3 - 3 parameters per Gaussian) OUTPUT: mod - the lmfit model object used for the fit out - the lmfit fit object that contains all the results of the fit init- array with the initial guess model (usefull to see the initial guess when plotting) """ m_params = params[0] m_mods = [] prefixes = [] for i in range(0, len(m_params), 3): pref = "gm%02i_" % (i/3) gauss_i = GaussianModel(prefix=pref) if i == 0: pars = gauss_i.guess(y, x=x) else: pars.update(gauss_i.make_params()) A = m_params[i] l_cen = m_params[i+1] sigma = m_params[i+2] pars[pref+'amplitude'].set(A) pars[pref+'center'].set(l_cen) pars[pref+'sigma'].set(sigma) m_mods.append(gauss_i) prefixes.append(pref) m_mod = m_mods[0] if len(m_mods) > 1: for m in m_mods[1:]: m_mod += m m_one = ConstantModel(prefix="m_one_") prefixes.append("m_one_") pars.update(m_one.make_params()) pars['m_one_c'].set(value=1, vary=False) try: n_params = params[1] n_mods = [] #prefixes = [] for j in range(0, len(n_params), 3): pref = "gn%02i_" % (j/3) gauss_j = GaussianModel(prefix=pref) pars.update(gauss_j.make_params()) A = n_params[j] l_cen = n_params[j+1] sigma = n_params[j+2] pars[pref+'amplitude'].set(A) pars[pref+'center'].set(l_cen) pars[pref+'sigma'].set(sigma) n_mods.append(gauss_j) prefixes.append(pref) n_mod = n_mods[0] if len(n_mods) > 1: for n in n_mods[1:]: n_mod += n n_one = ConstantModel(prefix="n_one_") prefixes.append("n_one_") pars.update(n_one.make_params()) pars['n_one_c'].set(value=1, vary=False) mod = (m_one + m_mod) * (n_one + n_mod) except: print("Error with second spectra, only fitting first") mod = m_one + m_mod init = mod.eval(pars, x=x) out = mod.fit(y, pars, x=x) print("Printed prefixes", prefixes) #print(init) return mod, out, init
def spectrum_gauss_fit(real_data, clean_right, channel_width, energy_spectrum, cal): ''' The while loop goes through and identifies the largest peak in the spectrum and it records the position of that peak. It then removes the peak by removing 10 channels from the right and left of the peak. The code will then search for the next largest position. ''' list_data = np.array(real_data).tolist() iterator = 0 while iterator < clean_right: list_data[iterator] = 0 iterator += 1 ''' merging the data for the calibration Also converting merged data into a list so channels can be removed easier. ''' spectrum_data = np.array(real_data).tolist() ''' Attempting to iterate through the peaks and identify all of the peaks for plotting purposes. All of the peaks are found from the trimmed data and the corresponding count rates are found. A list is created and then the list is sorted based by the position of the counts. ''' i = 0 energy_list_2 = [] gauss_x = [] gauss_y = [] real_y_gauss = [] parameter_list_2 = [] gauss_fit_parameters = [] sigma_list = [] amplitude_list = [] fit_params = {} while i < len(energy_spectrum): channel_max = np.argmax(list_data) energy_list_2.append(list_data[channel_max]) data_left = channel_max - channel_width data_right = channel_max + channel_width ''' Instead of deleting the items from the list. I am placing them to zero. The while loop iterates over the peak and sets it to zero. I am still using a place holder in the real data so the zero's do not obscure my fits. ''' calibration = [] iterator = data_left while iterator < (data_right): calibration.append(cal[iterator]) gauss_x.append(iterator) gauss_y.append(list_data[iterator]) real_y_gauss.append(spectrum_data[iterator]) list_data[iterator] = 0 iterator += 1 x = np.asarray(calibration) y = np.asarray(gauss_y) print("The amplitude sum is %0.2f" % sum(y)) real_y = np.asarray(real_y_gauss) ''' information for plotting the Gaussian function. ''' mod_gauss = GaussianModel(prefix='g1_') line_mod = LinearModel(prefix='line') pars = mod_gauss.guess(real_y, x=x) pars.update(line_mod.make_params(intercept=y.min(), slope=0)) pars.update(mod_gauss.make_params()) pars['g1_center'].set(x[np.argmax(real_y)], min=x[np.argmax(real_y)]\ - 3) pars['g1_sigma'].set(3, min=0.25) pars['g1_amplitude'].set(max(real_y), min=max(real_y) - 10) mod = mod_gauss + line_mod out = mod.fit(real_y, pars, x=x) plt.plot(x, real_y) plt.plot(x, out.best_fit, 'k--') energy_title = np.argmax(x) max_y = np.argmax(real_y) # Find the maximum y value max_x = x[( max_y)] # Find the x value corresponding to the maximum y value #plt.title('Gaussian fit around %0.1f keV' % x[max_y]) plt.xlabel('Channel Number') plt.ylabel('CPS') gauss_x = [] gauss_y = [] parameter_list_1 = [] real_y_gauss = [] plt.show() i += 1 #print(out.fit_report(min_correl=10)) sigma = out.params['g1_sigma'].value amplitude = out.params['g1_amplitude'].value sigma_list.append(sigma) amplitude_list.append(amplitude) fit_params = {} #gauss_fit_parameters = [out.params[key].value for k in out.params] #print(key, "=", out.params[key].value, "+/-", out.params[key].stderr) parameter_list_2.append(out) gauss_fit_parameters = [] ''' The below line sorts the channels by energy_list_2 ''' #energy_channel = list(zip(channel_max_list, energy_list_2, parameter_list_2)) #energy_channel.sort(key=operator.itemgetter(0)) plt.clf() ''' This sequence plots the energy of the peaks and with their corresponding energies. ''' return out
from lmfit.models import GaussianModel, LinearModel try: import numdifftools # noqa: F401 calc_covar_options = [False, True] except ImportError: calc_covar_options = [False] np.random.seed(7) x = np.linspace(0, 20, 401) y = gaussian(x, amplitude=24.56, center=7.6543, sigma=1.23) y -= 0.20*x + 3.333 + np.random.normal(scale=0.23, size=len(x)) mod = GaussianModel(prefix='peak_') + LinearModel(prefix='bkg_') pars = mod.make_params(peak_amplitude=21.0, peak_center=7.0, peak_sigma=2.0, bkg_intercept=2, bkg_slope=0.0) # set bounds for use with 'differential_evolution' and 'brute' pars['bkg_intercept'].set(min=0, max=10) pars['bkg_slope'].set(min=-5, max=5) pars['peak_amplitude'].set(min=20, max=25) pars['peak_center'].set(min=5, max=10) pars['peak_sigma'].set(min=0.5, max=2) def per_iteration(pars, iter, resid, *args, **kws): """Iteration callback, will abort at iteration 23.""" return iter == 23 @pytest.mark.parametrize("calc_covar", calc_covar_options)
def fit_gaussian_sample(sample, absolute=False, components=False, svg=False, verbose=False, center=None, cmin=None, cmax=None, amp=None, amin=None, sigma=None, smin=None, suffix=None): '''Fits gaussian curve to dyad coverage for a single sample.''' print('Fits gaussian curve to dyad coverage of sample {}'.format(sample)) input = sample + (suffix if suffix else '') + '-dyad.txt' dyads = pd.read_csv(input, sep='\t', index_col=0, comment='#') x = dyads.index.values yheader = 'Frequency' if absolute else 'Relative Frequency' y = dyads[yheader].values if not amp: amp = dyads[yheader].max() * 100 if not center: center = 0.0 if not sigma: sigma = dyads.index.max() / 2 plt.figure() plt.title(sample) plt.xlabel('Position relative to dyad (bp)') plt.ylabel('Frequency' if absolute else 'Relative Frequency') plt.xlim(x[0], x[len(x) - 1]) plt.xticks(list(range(x[0], x[len(x) - 1] + 1, 25))) plt.plot(x, y, color='red') plot_output = sample + (suffix if suffix else '') + '-dyad-gaussian.png' try: constant = ConstantModel(prefix='c_') pars = constant.make_params() pars['c_c'].set(value=dyads[yheader].min(), min=0.0, max=dyads[yheader].max()) gauss = GaussianModel(prefix='g_') pars.update(gauss.make_params()) pars['g_center'].set(value=center, min=cmin, max=cmax) pars['g_sigma'].set(value=sigma, min=smin) pars['g_amplitude'].set(value=amp, min=amin) mod = constant + gauss init = mod.eval(pars, x=x) out = mod.fit(y, pars, x=x) if components: plt.plot(x, init, 'b--', label='Initial fit') if verbose: print(out.fit_report(min_correl=0.5)) plt.plot(x, out.best_fit, 'b-', label='Best fit') if components: comps = out.eval_components(x=x) plt.plot(x, np.repeat(comps['c_'], len(x)), 'g--', label='Constant component') plt.plot(x, comps['g_'], 'm--', label='Gaussian component') except Exception as e: logging.warning( 'could not fit gaussian curve to sample {}'.format(sample), e) if components: plt.legend(loc='lower right') plt.savefig(plot_output) if svg: plot_svg_output = sample + (suffix if suffix else '') + '-dyad-gaussian.svg' plt.savefig(plot_svg_output, transparent=True) plt.close()