rf311_rangeplot

Multidimensional models: projecting pdf and data ranges in continuous observables

Author: Clemens Lange, Wouter Verkerke (C++ version)
This notebook tutorial was automatically generated with ROOTBOOK-izer from the macro found in the ROOT repository on Sunday, November 27, 2022 at 11:07 AM.

In [1]:
import ROOT
Welcome to JupyROOT 6.27/01

Create 3D pdf and data

Create observables

In [2]:
x = ROOT.RooRealVar("x", "x", -5, 5)
y = ROOT.RooRealVar("y", "y", -5, 5)
z = ROOT.RooRealVar("z", "z", -5, 5)

Create signal pdf gauss(x)gauss(y)gauss(z)

In [3]:
gx = ROOT.RooGaussian("gx", "gx", x, ROOT.RooFit.RooConst(0), ROOT.RooFit.RooConst(1))
gy = ROOT.RooGaussian("gy", "gy", y, ROOT.RooFit.RooConst(0), ROOT.RooFit.RooConst(1))
gz = ROOT.RooGaussian("gz", "gz", z, ROOT.RooFit.RooConst(0), ROOT.RooFit.RooConst(1))
sig = ROOT.RooProdPdf("sig", "sig", [gx, gy, gz])

Create background pdf poly(x)poly(y)poly(z)

In [4]:
px = ROOT.RooPolynomial("px", "px", x, [-0.1, 0.004])
py = ROOT.RooPolynomial("py", "py", y, [0.1, -0.004])
pz = ROOT.RooPolynomial("pz", "pz", z)
bkg = ROOT.RooProdPdf("bkg", "bkg", [px, py, pz])

Create composite pdf sig+bkg

In [5]:
fsig = ROOT.RooRealVar("fsig", "signal fraction", 0.1, 0.0, 1.0)
model = ROOT.RooAddPdf("model", "model", [sig, bkg], [fsig])

data = model.generate({x, y, z}, 20000)

Project pdf and data on x

Make plain projection of data and pdf on x observable

In [6]:
frame = x.frame(Title="Projection of 3D data and pdf on X", Bins=40)
data.plotOn(frame)
model.plotOn(frame)
Out[6]:
<cppyy.gbl.RooPlot object at 0x9b93af0>
[#1] INFO:Plotting -- RooAbsReal::plotOn(model) plot on x integrates over variables (y,z)

Project pdf and data on x in signal range

Define signal region in y and z observables

In [7]:
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

In [8]:
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)

In [9]:
data.plotOn(frame2, CutRange="sigRegion")
Out[9]:
<cppyy.gbl.RooPlot object at 0x7463310>
[#1] INFO:Plotting -- RooTreeData::plotOn: plotting 1692 events out of 20000 total events

Project model on x, projected observables (y,z) only in "sigRegion"

In [10]:
model.plotOn(frame2, ProjectionRange="sigRegion")

c = ROOT.TCanvas("rf311_rangeplot", "rf310_rangeplot", 800, 400)
c.Divide(2)
c.cd(1)
ROOT.gPad.SetLeftMargin(0.15)
frame.GetYaxis().SetTitleOffset(1.4)
frame.Draw()
c.cd(2)
ROOT.gPad.SetLeftMargin(0.15)
frame2.GetYaxis().SetTitleOffset(1.4)
frame2.Draw()

c.SaveAs("rf311_rangeplot.png")
[#1] INFO:Plotting -- RooAbsReal::plotOn(model) plot on x integrates over variables (y,z) in range sigRegion
Info in <TCanvas::Print>: png file rf311_rangeplot.png has been created

Draw all canvases

In [11]:
from ROOT import gROOT 
gROOT.GetListOfCanvases().Draw()