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
Exemple #4
0
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
Exemple #5
0
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)
Exemple #6
0
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
Exemple #11
0
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
Exemple #13
0
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
Exemple #15
0
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)
Exemple #16
0
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=[]
Exemple #20
0
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
Exemple #24
0
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()