%%cpp -d std::unique_ptr generateBinnedAsimov(RooAbsPdf const &pdf, RooRealVar &x, int nEvents) { auto dataH = std::make_unique("dataH", "dataH", RooArgSet{x}); RooAbsBinning &xBinning = x.getBinning(); for (int iBin = 0; iBin < x.numBins(); ++iBin) { x.setRange("bin", xBinning.binLow(iBin), xBinning.binHigh(iBin)); std::unique_ptr integ{pdf.createIntegral(x, RooFit::NormSet(x), RooFit::Range("bin"))}; integ->getVal(); dataH->set(iBin, nEvents * integ->getVal(), -1); } return dataH; } %%cpp -d void enableBinIntegrator(RooAbsReal &func, int numBins) { RooNumIntConfig customConfig(*func.getIntegratorConfig()); customConfig.method1D().setLabel("RooBinIntegrator"); customConfig.getConfigSection("RooBinIntegrator").setRealValue("numBins", numBins); func.setIntegratorConfig(customConfig); func.forceNumInt(true); } %%cpp -d void disableBinIntegrator(RooAbsReal &func) { func.setIntegratorConfig(); func.forceNumInt(false); } using namespace RooFit; RooMsgService::instance().getStream(1).removeTopic(Minimization); RooMsgService::instance().getStream(1).removeTopic(Fitting); RooMsgService::instance().getStream(1).removeTopic(Generation); RooRealVar x{"x", "x", 0.1, 5.1}; x.setBins(10); // fewer bins so we have larger binning effects for this demo RooRealVar c{"c", "c", -1.8, -5, 5}; RooExponential expo{"expo", "expo", x, c}; std::unique_ptr expoData{generateBinnedAsimov(expo, x, 10000)}; std::unique_ptr fit1{expo.fitTo(*expoData, Save(), PrintLevel(-1), SumW2Error(false))}; fit1->Print(); enableBinIntegrator(expo, x.numBins()); std::unique_ptr fit2{expo.fitTo(*expoData, Save(), PrintLevel(-1), SumW2Error(false))}; fit2->Print(); disableBinIntegrator(expo); RooRealVar a{"a", "a", -0.3, -5.0, 5.0}; RooPower powerlaw{"powerlaw", "powerlaw", x, RooConst(1.0), a}; std::unique_ptr powerlawData{generateBinnedAsimov(powerlaw, x, 10000)}; std::unique_ptr fit3{powerlaw.fitTo(*powerlawData, Save(), PrintLevel(-1), SumW2Error(false))}; fit3->Print(); enableBinIntegrator(powerlaw, x.numBins()); std::unique_ptr fit4{powerlaw.fitTo(*powerlawData, Save(), PrintLevel(-1), SumW2Error(false))}; fit4->Print(); disableBinIntegrator(powerlaw); std::unique_ptr fit5{ powerlaw.fitTo(*powerlawData, IntegrateBins(1e-3), Save(), PrintLevel(-1), SumW2Error(false))}; fit5->Print(); x.setBins(100); // It's not about binning effects anymore, so reset the number of bins. RooRealVar mu{"mu", "mu", 3.0, 0.1, 5.1}; RooRealVar sigma{"sigma", "sigma", 0.5, 0.01, 5.0}; RooGaussian gauss{"gauss", "gauss", x, mu, sigma}; RooRealVar nsig{"nsig", "nsig", 10000, 0, 1e9}; RooRealVar nbkg{"nbkg", "nbkg", 10000000, 0, 1e9}; RooRealVar frac{"frac", "frac", nsig.getVal() / (nsig.getVal() + nbkg.getVal()), 0.0, 1.0}; RooAddPdf model{"model", "model", {gauss, expo}, {nsig, nbkg}}; std::unique_ptr modelData{model.generateBinned(x)}; mu.setVal(2.0); sigma.setVal(1.0); std::unique_ptr fit6{model.fitTo(*modelData, Save(), PrintLevel(-1), SumW2Error(false))}; fit6->Print(); std::unique_ptr fit7{ model.fitTo(*modelData, Offset("bin"), Save(), PrintLevel(-1), SumW2Error(false))}; fit7->Print(); %jsroot on gROOT->GetListOfCanvases()->Draw()