'ADDITION AND CONVOLUTION' RooFit tutorial macro #207 Tools and utilities for manipulation of composite objects
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 Wednesday, April 17, 2024 at 11:17 AM.
import ROOT
Declare observable x
x = ROOT.RooRealVar("x", "x", 0, 10)
Create two Gaussian PDFs g1(x,mean1,sigma) anf g2(x,mean2,sigma) and their parameters
mean = ROOT.RooRealVar("mean", "mean of gaussians", 5)
sigma = ROOT.RooRealVar("sigma", "width of gaussians", 0.5)
sig = ROOT.RooGaussian("sig", "Signal component 1", x, mean, sigma)
[#0] WARNING:InputArguments -- The parameter 'sigma' with range [-inf, inf] of the RooGaussian 'sig' exceeds the safe range of (0, inf). Advise to limit its range.
Build Chebychev polynomial p.d.f.
a0 = ROOT.RooRealVar("a0", "a0", 0.5, 0.0, 1.0)
a1 = ROOT.RooRealVar("a1", "a1", 0.2, 0.0, 1.0)
bkg1 = ROOT.RooChebychev("bkg1", "Background 1", x, [a0, a1])
Build expontential pdf
alpha = ROOT.RooRealVar("alpha", "alpha", -1)
bkg2 = ROOT.RooExponential("bkg2", "Background 2", x, alpha)
Sum the background components into a composite background p.d.f.
bkg1frac = ROOT.RooRealVar("bkg1frac", "fraction of component 1 in background", 0.2, 0.0, 1.0)
bkg = ROOT.RooAddPdf("bkg", "Signal", [bkg1, bkg2], [bkg1frac])
Sum the composite signal and background
bkgfrac = ROOT.RooRealVar("bkgfrac", "fraction of background", 0.5, 0.0, 1.0)
model = ROOT.RooAddPdf("model", "g1+g2+a", [bkg, sig], [bkgfrac])
Create dummy dataset that has more observables than the above pdf
y = ROOT.RooRealVar("y", "y", -10, 10)
data = ROOT.RooDataSet("data", "data", {x, y})
Get list of observables of pdf in context of a dataset
Observables are define each context as the variables shared between a model and a dataset. In self case that is the variable 'x'
model_obs = model.getObservables(data)
model_obs.Print("v")
1) 0x92e9230 RooRealVar:: x = 5 L(0 - 10) "x"
Get list of parameters, list of observables
model_params = model.getParameters({x})
model_params.Print("v")
1) 0x5e27940 RooRealVar:: a0 = 0.5 L(0 - 1) "a0" 2) 0x5cae340 RooRealVar:: a1 = 0.2 L(0 - 1) "a1" 3) 0x96a5e10 RooRealVar:: alpha = -1 C L(-INF - +INF) "alpha" 4) 0x9b0e540 RooRealVar:: bkg1frac = 0.2 L(0 - 1) "fraction of component 1 in background" 5) 0x9c6a260 RooRealVar:: bkgfrac = 0.5 L(0 - 1) "fraction of background" 6) 0x970eee0 RooRealVar:: mean = 5 C L(-INF - +INF) "mean of gaussians" 7) 0x5e31160 RooRealVar:: sigma = 0.5 C L(-INF - +INF) "width of gaussians"
Get list of parameters, a dataset (Gives identical results to operation above)
model_params2 = model.getParameters(data)
model_params2.Print()
RooArgSet::parameters = (a0,a1,alpha,bkg1frac,bkgfrac,mean,sigma)
Get list of component objects, top-level node
model_comps = model.getComponents()
model_comps.Print("v")
1) 0x9c76b00 RooAddPdf:: model[ bkgfrac * bkg + [%] * sig ] = 0.582695/1 "g1+g2+a" 2) 0x9c77e40 RooAddPdf:: bkg[ bkg1frac * bkg1 + [%] * bkg2 ] = 0.16539/1 "Signal" 3) 0x9a887b0 RooChebychev:: bkg1[ x=x coefficients=(a0,a1) ] = 0.8 "Background 1" 4) 0x9bb5c30 RooExponential:: bkg2[ x=x c=alpha ] = 0.00673795 "Background 2" 5) 0x9852c20 RooGaussian:: sig[ x=x mean=mean sigma=sigma ] = 1 "Signal component 1"
Create a second Gaussian
sigma2 = ROOT.RooRealVar("sigma2", "width of gaussians", 1)
sig2 = ROOT.RooGaussian("sig2", "Signal component 1", x, mean, sigma2)
[#0] WARNING:InputArguments -- The parameter 'sigma2' with range [-inf, inf] of the RooGaussian 'sig2' exceeds the safe range of (0, inf). Advise to limit its range.
Create a sum of the original Gaussian plus the second Gaussian
sig1frac = ROOT.RooRealVar("sig1frac", "fraction of component 1 in signal", 0.8, 0.0, 1.0)
sigsum = ROOT.RooAddPdf("sigsum", "sig+sig2", [sig, sig2], [sig1frac])
Construct a customizer utility to customize model
cust = ROOT.RooCustomizer(model, "cust")
Instruct the customizer to replace node 'sig' with node 'sigsum'
cust.replaceArg(sig, sigsum)
Build a clone of the input pdf according to the above customization instructions. Each node that requires modified is clone so that the original pdf remained untouched. The name of each cloned node is that of the original node suffixed by the name of the customizer object
The returned head node own all nodes that were cloned as part of the build process so when cust_clone is deleted so will all other nodes that were created in the process.
cust_clone = cust.build(ROOT.kTRUE)
[#1] INFO:ObjectHandling -- RooCustomizer::build(model): tree node sig will be replaced by sigsum [#1] INFO:ObjectHandling -- RooCustomizer::build(model) Branch node RooAddPdf::model cloned: depends on a replaced parameter [#1] INFO:ObjectHandling -- RooCustomizer::build(model) Branch node sig is already replaced
Print structure of clone of model with sig.sigsum replacement.
cust_clone.Print("t")
0x9fd1a90 RooAddPdf::model_cust = 0.582695/1 [Auto,Clean] 0x9c77e40/V- RooAddPdf::bkg = 0.16539/1 [Auto,Clean] 0x9a887b0/V- RooChebychev::bkg1 = 0.8 [Auto,Dirty] 0x92e9230/V- RooRealVar::x = 5 0x5e27940/V- RooRealVar::a0 = 0.5 0x5cae340/V- RooRealVar::a1 = 0.2 0x9b0e540/V- RooRealVar::bkg1frac = 0.2 0x9bb5c30/V- RooExponential::bkg2 = 0.00673795 [Auto,Dirty] 0x92e9230/V- RooRealVar::x = 5 0x96a5e10/V- RooRealVar::alpha = -1 0x9c6a260/V- RooRealVar::bkgfrac = 0.5 0x9f4cee0/V- RooAddPdf::sigsum = 1/1 [Auto,Clean] 0x9852c20/V- RooGaussian::sig = 1 [Auto,Dirty] 0x92e9230/V- RooRealVar::x = 5 0x970eee0/V- RooRealVar::mean = 5 0x5e31160/V- RooRealVar::sigma = 0.5 0xa3b35c0/V- RooRealVar::sig1frac = 0.8 0x7ef59d0/V- RooGaussian::sig2 = 1 [Auto,Dirty] 0x92e9230/V- RooRealVar::x = 5 0x970eee0/V- RooRealVar::mean = 5 0x9a52950/V- RooRealVar::sigma2 = 1
Draw all canvases
from ROOT import gROOT
gROOT.GetListOfCanvases().Draw()