 |
Fitting data using Minuit and the Chi2 method
Source code name: "fit_minuit_plot.py"
Programming language: Python
Topic: Data fitting/minuit
DMelt Version 1. Last modified: 12/08/2015. License: Pro
https://datamelt.org/code/cache/fit_minuit_plot_3060.py
To run this script using the DMelt IDE,
copy the above URL link to the menu [File]→[Read script from URL] of the DMelt IDE.
from org.freehep.math.minuit import FCNBase,MnMigrad,MnUserParameters
from java.lang.Math import *
from jhplot import *
from java.awt import Color
data=P1D("data") # input data
data.add(5,4,2); data.add(10,8,3) # each point has X, Y, standard error on Y
data.add(20,10,3); data.add(30,12,3)
data.add(40,18,4); data.add(70,20,4)
data.add(90,26,5); data.add(150,37,6)
data.add(200,50,6); data.add(300,60,7)
data.add(500,90,9); data.add(700,120,10)
class PowerLawFunc(FNon): # function describing a power law
def value(self, x):
return self.p[0]*pow(x[0],self.p[1])
class PowerLawChi2FCN(FCNBase): # define chi2 function
def __init__(self, meas, pos, mvar):
self.meas=meas;
self.pos=pos;
self.mvar=mvar;
def valueOf(self, par):
pl = PowerLawFunc("PowerLaw",1,2)
pl.setParameters(par)
chi2 = 0
for n in range(len(self.meas)):
delta = pl.value([self.pos[n]]) - self.meas[n]
sigma2=self.mvar[n]*self.mvar[n]
if (sigma2>0): chi2=chi2+(delta*delta)/sigma2
print "Chi2=",chi2
return chi2;
theFCN = PowerLawChi2FCN(data.getArrayY(), data.getArrayX(), data.getArrayErr())
upar = MnUserParameters()
upar.add("p0", 1.0, 0.1) # initial value and expected error
upar.add("p1", 0.2, 0.1);
migrad =MnMigrad(theFCN, upar)
print "start Migrad "
vmin = migrad.minimize()
if vmin.isValid()==False:
print "Alternative strategy"
migrad = MnMigrad(theFCN, upar, 2)
vmin = migrad.minimize()
state=vmin.userState()
output=state.params() # output parameters
print vmin # print details of the fit
c1 = HPlot() # plot data and the fit function
c1.visible()
min=0; max=800 # min and max values for plotting
c1.setRangeX(min,max)
c1.setRangeY(0,150)
c1.draw(data) # plot data
pl = PowerLawFunc("PowerLaw",1,2) # plot fit result
pl.setParameters(output)
ff=F1D(pl,min,max)
ff.setPenWidth(2); ff.setColor(Color.blue)
c1.draw(ff)
You see the box below because you did not login.