Multidimensional models: projecting pdf and data ranges in continuous observables
Author: Wouter Verkerke
This notebook tutorial was automatically generated with ROOTBOOK-izer from the macro found in the ROOT repository on Tuesday, March 19, 2024 at 07:15 PM.
%%cpp -d
#include "RooRealVar.h"
#include "RooDataSet.h"
#include "RooGaussian.h"
#include "RooConstVar.h"
#include "RooProdPdf.h"
#include "RooAddPdf.h"
#include "RooPolynomial.h"
#include "TCanvas.h"
#include "TAxis.h"
#include "RooPlot.h"
using namespace RooFit;
Create observables
RooRealVar x("x", "x", -5, 5);
RooRealVar y("y", "y", -5, 5);
RooRealVar z("z", "z", -5, 5);
Create signal pdf gauss(x)gauss(y)gauss(z)
RooGaussian gx("gx", "gx", x, 0.0, 1.0);
RooGaussian gy("gy", "gy", y, 0.0, 1.0);
RooGaussian gz("gz", "gz", z, 0.0, 1.0);
RooProdPdf sig("sig", "sig", RooArgSet(gx, gy, gz));
Create background pdf poly(x)poly(y)poly(z)
RooPolynomial px("px", "px", x, RooArgSet(-0.1, 0.004));
RooPolynomial py("py", "py", y, RooArgSet(0.1, -0.004));
RooPolynomial pz("pz", "pz", z);
RooProdPdf bkg("bkg", "bkg", RooArgSet(px, py, pz));
Create composite pdf sig+bkg
RooRealVar fsig("fsig", "signal fraction", 0.1, 0., 1.);
RooAddPdf model("model", "model", RooArgList(sig, bkg), fsig);
std::unique_ptr<RooDataSet> data{model.generate({x, y, z}, 20000)};
input_line_51:5:1: warning: 'data' shadows a declaration with the same name in the 'std' namespace; use '::data' to reference this declaration std::unique_ptr<RooDataSet> data{model.generate({x, y, z}, 20000)}; ^
Make plain projection of data and pdf on x observable
RooPlot *frame = x.frame(Title("Projection of 3D data and pdf on X"), Bins(40));
data->plotOn(frame);
model.plotOn(frame);
input_line_52:3:1: error: reference to 'data' is ambiguous data->plotOn(frame); ^ input_line_51:5:29: note: candidate found by name lookup is 'data' std::unique_ptr<RooDataSet> data{model.generate({x, y, z}, 20000)}; ^ /usr/include/c++/9/bits/range_access.h:318:5: note: candidate found by name lookup is 'std::data' data(initializer_list<_Tp> __il) noexcept ^ /usr/include/c++/9/bits/range_access.h:289:5: note: candidate found by name lookup is 'std::data' data(_Container& __cont) noexcept(noexcept(__cont.data())) ^ /usr/include/c++/9/bits/range_access.h:299:5: note: candidate found by name lookup is 'std::data' data(const _Container& __cont) noexcept(noexcept(__cont.data())) ^ /usr/include/c++/9/bits/range_access.h:309:5: note: candidate found by name lookup is 'std::data' data(_Tp (&__array)[_Nm]) noexcept ^
Define signal region in y and z observables
y.setRange("sigRegion", -1, 1);
z.setRange("sigRegion", -1, 1);
[#1] INFO:Eval -- RooRealVar::setRange(y) new range named 'sigRegion' created with bounds [-1,1] [#1] INFO:Eval -- RooRealVar::setRange(z) new range named 'sigRegion' created with bounds [-1,1]
Make plot frame
RooPlot *frame2 = x.frame(Title("Same projection on X in signal range of (Y,Z)"), Bins(40));
Plot subset of data in which all observables are inside "sigRegion" For observables that do not have an explicit "sigRegion" range defined (e.g. observable) an implicit definition is used that is identical to the full range (i.e. [-5,5] for x)
data->plotOn(frame2, CutRange("sigRegion"));
input_line_55:2:2: error: reference to 'data' is ambiguous data->plotOn(frame2, CutRange("sigRegion")); ^ input_line_51:5:29: note: candidate found by name lookup is 'data' std::unique_ptr<RooDataSet> data{model.generate({x, y, z}, 20000)}; ^ /usr/include/c++/9/bits/range_access.h:318:5: note: candidate found by name lookup is 'std::data' data(initializer_list<_Tp> __il) noexcept ^ /usr/include/c++/9/bits/range_access.h:289:5: note: candidate found by name lookup is 'std::data' data(_Container& __cont) noexcept(noexcept(__cont.data())) ^ /usr/include/c++/9/bits/range_access.h:299:5: note: candidate found by name lookup is 'std::data' data(const _Container& __cont) noexcept(noexcept(__cont.data())) ^ /usr/include/c++/9/bits/range_access.h:309:5: note: candidate found by name lookup is 'std::data' data(_Tp (&__array)[_Nm]) noexcept ^
Project model on x, integrating projected observables (y,z) only in "sigRegion"
model.plotOn(frame2, ProjectionRange("sigRegion"));
TCanvas *c = new TCanvas("rf311_rangeplot", "rf310_rangeplot", 800, 400);
c->Divide(2);
c->cd(1);
gPad->SetLeftMargin(0.15);
frame->GetYaxis()->SetTitleOffset(1.4);
frame->Draw();
c->cd(2);
gPad->SetLeftMargin(0.15);
frame2->GetYaxis()->SetTitleOffset(1.4);
frame2->Draw();
input_line_57:2:3: error: use of undeclared identifier 'frame' (frame->GetYaxis()->SetTitleOffset(1.3999999999999999)) ^ Error in <HandleInterpreterException>: Error evaluating expression (frame->GetYaxis()->SetTitleOffset(1.3999999999999999)) Execution of your code was aborted.
Draw all canvases
%jsroot on
gROOT->GetListOfCanvases()->Draw()