User defined Fit

Hey there Root Team,
my problem with the following skript i wrote is, that the fit for the used datasets sometimes doesn’t work. If i change the offset (from 0 to 100 or 1000) the plot mostly works, but not all the time.

Fyi the function is a lorentzian.

maybe you can help me.

cheers,
Paul

[code]import ROOT
import csv
from array import array
import math
import sys
import numpy as py

def main():
c1 = ROOT.TCanvas(“c1”,“Lorentz Fit”,200,10,500,500)
fit = ROOT.TF1(“fit”,fitfkt(),0.0004,0.0017,4)
fit.SetParameters(1,1,1,1)
fit.SetParNames(“vertical”,“width”,“horizontal”,“offset”)

x = array("f", [0])
y = array("f", [0])
z = array("f", [0])

with open('21_90deg_HM1508.csv','r') as file:
	r = csv.reader(file,delimiter=',')
	for row in r:
		x.append( ROOT.Double(row[0])*0.2672*3.363*0.0001)
		y.append( ROOT.Double(row[1])*100+200)
		z.append( -ROOT.Double(row[2])+500)
		

gr = ROOT.TGraph(len(x),x,z)
gr2 = ROOT.TGraph(len(x),x,y)


gr.Fit(fit)
fit.SetLineColor(1)
gr2.SetLineColor(5)
gr.Draw()
gr2.Draw("SAME")
c1.Print("fit_21_90.png")

parameters = fit.GetParameters()
print("fitting result: {parameter1}, {parameter2}, {parameter3}, {parameter4}".format(
	parameter1 = parameters[0],
	parameter2 = parameters[1],
	parameter3 = parameters[2],
	parameter4 = parameters[3]
))

l = 1.054571800 /(parameters[1]*1.4838*9.274*10000000000)
print ("The mean lifetime is:")
print l

class fitfkt:
def call(self, x, parameters):
a = parameters[0] # shape
b = parameters[1] # location of minimum
c = parameters[2] # scale
d = parameters[3] # baseline
x = x[0]
y = (a/3.14159265359)(b/2)/((x-c)(x-c)+0.25bb)+d
return y

if name == “main”:
main()

raw_input()[/code]

21_90deg_HM1508.csv (68 KB)

Hi Paul,

I understand the issue you have is that sometimes the fit does not converge. This is almost never an issue of the fitting algorithm but rather something to improve on the user application’s side.
Perhaps a well thought initialisation of the parameters’ values could help in this case.

Danilo

Thanks for the idea.

I managed to improve the code in a way that the fit is working almost all the time.

[code]import ROOT
import csv
from array import array
import math
import sys
import numpy as py

def main():
c1 = ROOT.TCanvas(“c1”,“Lorentz Fit”,200,10,500,500)
fit = ROOT.TF1(“fit”,fitfkt(),4,20,4)
fit.SetParameters(1,1,1,1)
fit.SetParNames(“vertical”,“width”,“horizontal”,“offset”)

x = array("f", [])
y = array("f", [])
z = array("f", [])

with open('-6_0deg_HM1508.csv','r') as file:
	r = csv.reader(file,delimiter=',')
	for row in r:
		j=ROOT.Double(row[1])
		if j>-1.2 and j<1.2 :	#loop for just using the area of the ramp voltage
			x.append( ROOT.Double(row[0])*0.2672*3.363*0.0001-0.0006)	#factors for the change from time to magnetic field
			y.append( ROOT.Double(row[1])*100+1200)	#offset necessary for viewable ramp voltage 
			z.append( ROOT.Double(row[2])+	00)	#offset sometimes necessary for the fit to work


gr = ROOT.TGraph(len(x),x,z)
gr2 = ROOT.TGraph(len(x),x,y)	
gr.Fit(fit)
gr.SetTitle("Fit;magnetic field B/T;Intensity I/V")
fit.SetLineColor(1)
gr2.SetLineColor(5)
gr.Draw()
gr2.Draw("SAME")


leg=ROOT.TLegend(0.1, 0.7, 0.48, 0.9)
leg.SetTextSize(0.03)
leg.AddEntry(gr, "data", "p")
leg.AddEntry(fit, "Lorentz fit", "l")


parameters = fit.GetParameters()
print("fitting result: {parameter1}, {parameter2}, {parameter3}, {parameter4}".format(
	parameter1 = parameters[0],
	parameter2 = parameters[1],
	parameter3 = parameters[2],
	parameter4 = parameters[3]
))
l = 1.054571800 /(parameters[1]*1.4838*9.274*10000000000)
print ("The mean lifetime is:")
print l

leg.Draw()


c1.Print("fit_-6_0.png")

class fitfkt:
def call(self, x, parameters):
a = parameters[0] # shape
b = parameters[1] # location of minimum
c = parameters[2] # scale
d = parameters[3] # baseline
x = x[0]
y = (a/3.14159265359)(b/2)/((x-c)(x-c)+0.25bb)+d
return y

if name == “main”:
main()

raw_input()[/code]

by introducing a new loop, which cuts of the borders of the data the fit is most of the time accurate, but sometimes it still needs a different offset.

At first i thought it might be because of the positive/negative transition, but that’s not the case.

any ideas where that might come from?

Can anyone explain to me, why the fit is not working all the time??

Hi,

this looks like an issue with the initial value of the parameters. You could improve your initial guessing for their values. Please note that this behaviour is not related to ROOT itself but rather to the fitting procedure.

Danilo

Ok, Thanks, that mainly answers my question.

Thank You!