Special p.d.f.'s: unbinned maximum likelihood fit of an efficiency eff(x) function to a dataset D(x,cut), cut is a category encoding a selection, which the efficiency as function of x should be described by eff(x)
import ROOT
x = ROOT.RooRealVar("x", "x", -10, 10)
a = ROOT.RooRealVar("a", "a", 0.4, 0, 1)
b = ROOT.RooRealVar("b", "b", 5)
c = ROOT.RooRealVar("c", "c", -1, -10, 10)
effFunc = ROOT.RooFormulaVar(
"effFunc", "(1-a)+a*cos((x-c)/b)", ROOT.RooArgList(a, b, c, x))
cut = ROOT.RooCategory("cut", "cutr")
cut.defineType("accept", 1)
cut.defineType("reject", 0)
effPdf = ROOT.RooEfficiency("effPdf", "effPdf", effFunc, cut, "accept")
shapePdf = ROOT.RooPolynomial(
"shapePdf", "shapePdf", x, ROOT.RooArgList(ROOT.RooFit.RooConst(-0.095)))
model = ROOT.RooProdPdf(
"model",
"model",
ROOT.RooArgSet(shapePdf),
ROOT.RooFit.Conditional(
ROOT.RooArgSet(effPdf),
ROOT.RooArgSet(cut)))
data = model.generate(ROOT.RooArgSet(x, cut), 10000)
effPdf.fitTo(data, ROOT.RooFit.ConditionalObservables(ROOT.RooArgSet(x)))
frame1 = x.frame(ROOT.RooFit.Bins(
20), ROOT.RooFit.Title("Data (all, accepted)"))
data.plotOn(frame1)
data.plotOn(
frame1,
ROOT.RooFit.Cut("cut==cut::accept"),
ROOT.RooFit.MarkerColor(
ROOT.kRed),
ROOT.RooFit.LineColor(
ROOT.kRed))
frame2 = x.frame(ROOT.RooFit.Bins(
20), ROOT.RooFit.Title("Fitted efficiency"))
data.plotOn(frame2, ROOT.RooFit.Efficiency(cut))
effFunc.plotOn(frame2, ROOT.RooFit.LineColor(ROOT.kRed))
ca = ROOT.TCanvas("rf701_efficiency", "rf701_efficiency", 800, 400)
ca.Divide(2)
ca.cd(1)
ROOT.gPad.SetLeftMargin(0.15)
frame1.GetYaxis().SetTitleOffset(1.6)
frame1.Draw()
ca.cd(2)
ROOT.gPad.SetLeftMargin(0.15)
frame2.GetYaxis().SetTitleOffset(1.4)
frame2.Draw()
ca.SaveAs("rf701_efficiencyfit.png")