Hi, I am having trouble fitting a simple TH1D with a Gaussian function. It appears that my SetParLimits calls are not being obeyed. Here is a fragment of my PyROOT code that does this:
[code]
# h is a TH2D, h_binedges is a python list of pairs of floats
projs, fit_gaus = {}, {}
for i in range(len(h_binedges)-1):
projs[i] = h.ProjectionY("_%d" % i,h_binedges[i],h_binedges[i+1]-1)
hs.Add(projs[i])
fg_min,fg_max = projs[i].GetXaxis().GetXmin(),projs[i].GetXaxis().GetXmax()
fg_height = projs[i].GetMaximum()
fg_centre = projs[i].GetMean()
fg_width = projs[i].GetRMS()
fit_gaus[i] = ROOT.TF1("fit_gaus_%d" % i,"gaus",fg_min,fg_max)
fit_gaus[i].SetParameters(fg_height, fg_centre, fg_width/3.5)
fit_gaus[i].SetParLimits(0,0.5*fg_height,2*fg_height)
fit_gaus[i].SetParLimits(1,fg_min,fg_max)
fit_gaus[i].SetParLimits(2,1e-3,fg_width*2)
fit_gaus[i].SetLineWidth(1)
fit_gaus[i].SetLineColor(ROOT.kRed)
ftr_p = projs[i].Fit(fit_gaus[i],"SRQ+")
ftr = ftr_p.Get()
if int(ftr_p) != 0 or not (0.5*fg_height < ftr.Parameter(0) < 2*fg_height) or not (1e-3 < ftr.Parameter(2) < 2*fg_width) or abs(ftr.Parameter(1) - fg_centre)/ftr.Parameter(2) > 5 :
refit_func = fit_gaus[i].Clone("refit_%d" % i)
refit_func.SetLineColor(ROOT.kBlue)
ftr_p = projs[i].Fit(refit_func,"SRW+")
ftr = ftr_p.Get()
fit_gaus[i] = refit_func
print i, ftr.Parameter(0), ftr.Parameter(1), ftr.Parameter(2)[/code]
After the fit, the printed values of the parameters are often outside of the limits that I set. This happens even on iterations where the “refit” clause was not executed, so I don’t think it’s related to that.
So what could cause my SetParLimits to be ignored here? Any help would be appreciated.
Jean-François