28def generateBinnedAsimov(pdf, x, n_events):

30 Generate binned Asimov dataset for a continuous pdf.
31 One should in principle be able to use
32 pdf.generateBinned(x, n_events, RooFit::ExpectedData()).
33 Unfortunately it has a problem: it also has the bin bias that this tutorial
34 demonstrates, to if we would use it, the biases would cancel out.
36 data_h = ROOT.RooDataHist(

"dataH",

"dataH", {x})

37 x_binning = x.getBinning()

39 for i_bin

in range(x.numBins()):

40 x.setRange(

"bin", x_binning.binLow(i_bin), x_binning.binHigh(i_bin))

41 integ = pdf.createIntegral(x, NormSet=x, Range=

"bin")

42 ROOT.SetOwnership(integ,

True)

44 data_h.set(i_bin, n_events * integ.getVal(), -1)

49def enableBinIntegrator(func, num_bins):

51 Force numeric integration and do this numeric integration with the
52 RooBinIntegrator, which sums the function values at the bin centers.
54 custom_config = ROOT.RooNumIntConfig(func.getIntegratorConfig())

55 custom_config.method1D().setLabel(

"RooBinIntegrator")

56 custom_config.getConfigSection(

"RooBinIntegrator").setRealValue(

"numBins", num_bins)

57 func.setIntegratorConfig(custom_config)

58 func.forceNumInt(

True)

61def disableBinIntegrator(func):

63 Reset the integrator config to disable the RooBinIntegrator.
65 func.setIntegratorConfig()

66 func.forceNumInt(

False)

70ROOT.RooMsgService.instance().getStream(1).removeTopic(ROOT.RooFit.Minimization)

71ROOT.RooMsgService.instance().getStream(1).removeTopic(ROOT.RooFit.Fitting)

72ROOT.RooMsgService.instance().getStream(1).removeTopic(ROOT.RooFit.Generation)

78x = ROOT.RooRealVar(

"x",

"x", 0.1, 5.1)

83c = ROOT.RooRealVar(

"c",

"c", -1.8, -5, 5)

84expo = ROOT.RooExponential(

"expo",

"expo", x, c)

88expo_data = generateBinnedAsimov(expo, x, 10000)

93fit1 = expo.fitTo(expo_data, Save=

True, PrintLevel=-1, SumW2Error=

False)

103enableBinIntegrator(expo, x.numBins())

104fit2 = expo.fitTo(expo_data, Save=

True, PrintLevel=-1, SumW2Error=

False)

106disableBinIntegrator(expo)

112a = ROOT.RooRealVar(

"a",

"a", -0.3, -5.0, 5.0)

113powerlaw = ROOT.RooPower(

"powerlaw",

"powerlaw", x, ROOT.RooFit.RooConst(1.0), a)

114powerlaw_data = generateBinnedAsimov(powerlaw, x, 10000)

117fit3 = powerlaw.fitTo(powerlaw_data, Save=

True, PrintLevel=-1, SumW2Error=

False)

127enableBinIntegrator(powerlaw, x.numBins())

128fit4 = powerlaw.fitTo(powerlaw_data, Save=

True, PrintLevel=-1, SumW2Error=

False)

130disableBinIntegrator(powerlaw)

138fit5 = powerlaw.fitTo(powerlaw_data, IntegrateBins=1e-3, Save=

True, PrintLevel=-1, SumW2Error=

False)

162mu = ROOT.RooRealVar(

"mu",

"mu", 3.0, 0.1, 5.1)

163sigma = ROOT.RooRealVar(

"sigma",

"sigma", 0.5, 0.01, 5.0)

164gauss = ROOT.RooGaussian(

"gauss",

"gauss", x, mu, sigma)

166nsig = ROOT.RooRealVar(

"nsig",

"nsig", 10000, 0, 1e9)

167nbkg = ROOT.RooRealVar(

"nbkg",

"nbkg", 10000000, 0, 1e9)

168frac = ROOT.RooRealVar(

"frac",

"frac", nsig.getVal() / (nsig.getVal() + nbkg.getVal()), 0.0, 1.0)

170model = ROOT.RooAddPdf(

"model",

"model", [gauss, expo], [nsig, nbkg])

172model_data = model.generateBinned(x)

179fit6 = model.fitTo(model_data, Save=

True, PrintLevel=-1, SumW2Error=

False)

194fit7 = model.fitTo(model_data, Offset=

"bin", Save=

True, PrintLevel=-1, SumW2Error=

False)