Addition and convolution: tools and utilities for manipulation of composite objects
Author: Wouter Verkerke
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.
%%cpp -d
#include "RooRealVar.h"
#include "RooDataSet.h"
#include "RooGaussian.h"
#include "RooChebychev.h"
#include "RooExponential.h"
#include "RooAddPdf.h"
#include "RooPlot.h"
#include "RooCustomizer.h"
#include "TCanvas.h"
#include "TAxis.h"
#include "TH1.h"
using namespace RooFit;
Declare observable x
RooRealVar x("x", "x", 0, 10);
Create two Gaussian PDFs g1(x,mean1,sigma) anf g2(x,mean2,sigma) and their parameters
RooRealVar mean("mean", "mean of gaussians", 5);
RooRealVar sigma("sigma", "width of gaussians", 0.5);
RooGaussian sig("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 pdf
RooRealVar a0("a0", "a0", 0.5, 0., 1.);
RooRealVar a1("a1", "a1", 0.2, 0., 1.);
RooChebychev bkg1("bkg1", "Background 1", x, RooArgSet(a0, a1));
Build exponential pdf
RooRealVar alpha("alpha", "alpha", -1);
RooExponential bkg2("bkg2", "Background 2", x, alpha);
Sum the background components into a composite background pdf
RooRealVar bkg1frac("bkg1frac", "fraction of component 1 in background", 0.2, 0., 1.);
RooAddPdf bkg("bkg", "Signal", RooArgList(bkg1, bkg2), bkg1frac);
Sum the composite signal and background
RooRealVar bkgfrac("bkgfrac", "fraction of background", 0.5, 0., 1.);
RooAddPdf model("model", "g1+g2+a", RooArgList(bkg, sig), bkgfrac);
Create dummy dataset that has more observables than the above pdf
RooRealVar y("y", "y", -10, 10);
RooDataSet data("data", "data", RooArgSet(x, y));
input_line_54:3:1: warning: 'data' shadows a declaration with the same name in the 'std' namespace; use '::data' to reference this declaration RooDataSet data("data", "data", RooArgSet(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 this case that is the variable 'x'
std::unique_ptr<RooArgSet> model_obs{model.getObservables(data)};
model_obs->Print("v");
input_line_55:2:60: error: reference to 'data' is ambiguous std::unique_ptr<RooArgSet> model_obs{model.getObservables(data)}; ^ input_line_54:3:12: note: candidate found by name lookup is 'data' RooDataSet data("data", "data", RooArgSet(x, y)); ^ /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 ^
Get list of parameters, given list of observables
std::unique_ptr<RooArgSet> model_params{model.getParameters(x)};
model_params->Print("v");
1) 0x7f4e7c138000 RooRealVar:: a0 = 0.5 L(0 - 1) "a0" 2) 0x7f4e7c1383e8 RooRealVar:: a1 = 0.2 L(0 - 1) "a1" 3) 0x7f4e7c039000 RooRealVar:: alpha = -1 C L(-INF - +INF) "alpha" 4) 0x7f4e7c036000 RooRealVar:: bkg1frac = 0.2 L(0 - 1) "fraction of component 1 in background" 5) 0x7f4e7c033000 RooRealVar:: bkgfrac = 0.5 L(0 - 1) "fraction of background" 6) 0x7f4e7c13b000 RooRealVar:: mean = 5 C L(-INF - +INF) "mean of gaussians" 7) 0x7f4e7c13b3e8 RooRealVar:: sigma = 0.5 C L(-INF - +INF) "width of gaussians"
Get list of parameters, given a dataset (Gives identical results to operation above)
std::unique_ptr<RooArgSet> model_params2{model.getParameters(data)};
model_params2->Print();
input_line_57:2:63: error: reference to 'data' is ambiguous std::unique_ptr<RooArgSet> model_params2{model.getParameters(data)}; ^ input_line_54:3:12: note: candidate found by name lookup is 'data' RooDataSet data("data", "data", RooArgSet(x, y)); ^ /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 ^
Get list of component objects, including top-level node
std::unique_ptr<RooArgSet> model_comps{model.getComponents()};
model_comps->Print("v");
1) 0x7f4e7c0333e8 RooAddPdf:: model[ bkgfrac * bkg + [%] * sig ] = 0.582695/1 "g1+g2+a" 2) 0x7f4e7c0363e8 RooAddPdf:: bkg[ bkg1frac * bkg1 + [%] * bkg2 ] = 0.16539/1 "Signal" 3) 0x7f4e7c1387d0 RooChebychev:: bkg1[ x=x coefficients=(a0,a1) ] = 0.8 "Background 1" 4) 0x7f4e7c0393e8 RooExponential:: bkg2[ x=x c=alpha ] = 0.00673795 "Background 2" 5) 0x7f4e7c13b7d0 RooGaussian:: sig[ x=x mean=mean sigma=sigma ] = 1 "Signal component 1"
Create a second Gaussian
RooRealVar sigma2("sigma2", "width of gaussians", 1);
RooGaussian sig2("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 new second Gaussian
RooRealVar sig1frac("sig1frac", "fraction of component 1 in signal", 0.8, 0., 1.);
RooAddPdf sigsum("sigsum", "sig+sig2", RooArgList(sig, sig2), sig1frac);
Construct a customizer utility to customize model
RooCustomizer cust(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.
RooAbsPdf *cust_clone = (RooAbsPdf *)cust.build(true);
[#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");
delete cust_clone;
0x7f4e61848660 RooAddPdf::model_cust = 0.582695/1 [Auto,Clean] 0x7f4e7c0363e8/V- RooAddPdf::bkg = 0.16539/1 [Auto,Clean] 0x7f4e7c1387d0/V- RooChebychev::bkg1 = 0.8 [Auto,Dirty] 0x7f4e7c4a0000/V- RooRealVar::x = 5 0x7f4e7c138000/V- RooRealVar::a0 = 0.5 0x7f4e7c1383e8/V- RooRealVar::a1 = 0.2 0x7f4e7c036000/V- RooRealVar::bkg1frac = 0.2 0x7f4e7c0393e8/V- RooExponential::bkg2 = 0.00673795 [Auto,Dirty] 0x7f4e7c4a0000/V- RooRealVar::x = 5 0x7f4e7c039000/V- RooRealVar::alpha = -1 0x7f4e7c033000/V- RooRealVar::bkgfrac = 0.5 0x7f4e7c0243e8/V- RooAddPdf::sigsum = 1/1 [Auto,Clean] 0x7f4e7c13b7d0/V- RooGaussian::sig = 1 [Auto,Dirty] 0x7f4e7c4a0000/V- RooRealVar::x = 5 0x7f4e7c13b000/V- RooRealVar::mean = 5 0x7f4e7c13b3e8/V- RooRealVar::sigma = 0.5 0x7f4e7c024000/V- RooRealVar::sig1frac = 0.8 0x7f4e7c0273e8/V- RooGaussian::sig2 = 1 [Auto,Dirty] 0x7f4e7c4a0000/V- RooRealVar::x = 5 0x7f4e7c13b000/V- RooRealVar::mean = 5 0x7f4e7c027000/V- RooRealVar::sigma2 = 1