Nonlinear model no frills
import numpy # numerics (matrix operations, etc) import scipy.optimize, scipy.stats.stats #Fitting and Statistics import pylab # Plotting
- Read in the data and check (print) that we read in correctly
x, counts = numpy.loadtxt('counts.txt', unpack=True) print x print counts
- Because these are counts, we can use poisson statistics to define
- the standard deviation
std = numpy.sqrt(counts)
- Plot Data
pylab.errorbar(x,counts,std, fmt='o') pylab.xlabel('x (units)') pylab.ylabel('Counts') pylab.savefig('data.png') pylab.clf()
- Define a function that we want to fit
def gaussian_with_background(x,A,B,C,D,E):
return A*numpy.exp(-(x-B)**2/(2.*C**2)) + D*x + E
- Call the non-linear (Levenburg-Marquardt-based) fitting routine
- scipy.optimize.curve_fit
- http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.curve_fit.html
- returns answer and covariance
ans, cov = scipy.optimize.curve_fit(gaussian_with_background, x, counts, sigma=std)
print "A=", ans[0], "+/-", numpy.sqrt(cov[0][0]) print "B=", ans[1], "+/-", numpy.sqrt(cov[1][1]) print "C=", ans[2], "+/-", numpy.sqrt(cov[2][2]) print "D=", ans[3], "+/-", numpy.sqrt(cov[3][3]) print "E=", ans[4], "+/-", numpy.sqrt(cov[4][4])
- Write out result for later reference
numpy.savetxt('counts_best_fit.txt', ans) numpy.savetxt('counts_cov.txt', cov)
- Plot data, best-fit model, and residual
model = gaussian_with_background(x,ans[0], ans[1], ans[2], ans[3], ans[4]) pylab.plot(x, model, label='Model') pylab.errorbar(x, counts, std, label='Data', fmt='o') residual = counts - model pylab.errorbar(x, residual, std, label='Residual', fmt='o') pylab.legend() pylab.xlabel('x (units)') pylab.ylabel('Counts') pylab.savefig('counts_with_fit.png') pylab.clf()
- compute model chi-sq
chisq = (residual**2/std**2).sum() dof = len(counts)-len(ans) print 'Chi-Sq =', chisq print 'dof = ', dof print 'PTE = ', scipy.stats.stats.chisqprob(chisq,dof)