Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
rf514_RooCustomizer.C
Go to the documentation of this file.
1 /// \ingroup tutorial_roofit
2 /// \notebook -nodraw
3 /// Using the RooCustomizer to create multiple PDFs that share a lot of properties, but have unique parameters for each category.
4 /// As an extra complication, some of the new parameters need to be functions
5 /// of a mass parameter.
6 ///
7 /// \macro_output
8 /// \macro_code
9 /// \author Stephan Hageboeck, CERN
10 
11 
12 #include "RooRealVar.h"
13 #include "RooGaussian.h"
14 #include "RooPolynomial.h"
15 #include "RooAddPdf.h"
16 #include "RooCustomizer.h"
17 #include "RooCategory.h"
18 #include "RooFormulaVar.h"
19 #include <iostream>
20 
21 void rf514_RooCustomizer() {
22 
23  // Define a proto model that will be used as the template for each category
24  // ---------------------------------------------------------------------------
25 
26  RooRealVar E("Energy","Energy",0,3000);
27 
28  RooRealVar meanG("meanG","meanG", 100., 0., 3000.);
29  RooRealVar sigmaG("sigmaG","sigmaG", 3.);
30  RooGaussian gauss("gauss", "gauss", E, meanG, sigmaG);
31 
32  RooRealVar pol1("pol1", "Constant of the polynomial", 1, -10, 10);
33  RooPolynomial linear("linear", "linear", E, pol1);
34 
35  RooRealVar yieldSig("yieldSig", "yieldSig", 1, 0, 1.E4);
36  RooRealVar yieldBkg("yieldBkg", "yieldBkg", 1, 0, 1.E4);
37 
38  RooAddPdf model("model", "S + B model",
39  RooArgList(gauss,linear),
40  RooArgList(yieldSig, yieldBkg));
41 
42  std::cout << "The proto model before customisation:" << std::endl;
43  model.Print("T"); // "T" prints the model as a tree
44 
45 
46  // Build the categories
47  RooCategory sample("sample","sample");
48  sample.defineType("Sample1");
49  sample.defineType("Sample2");
50  sample.defineType("Sample3");
51 
52 
53  // Start to customise the proto model that was defined above.
54  // ---------------------------------------------------------------------------
55 
56  // We need two sets for bookkeeping of PDF nodes:
57  RooArgSet newLeafs; // This set collects leafs that are created in the process.
58  RooArgSet allCustomiserNodes; // This set lists leafs that have been used in a replacement operation.
59 
60 
61  // 1. Each sample should have its own mean for the gaussian
62  // The customiser will make copies of `meanG` for each category.
63  // The they will all appear in the set `newLeafs`, which will own the new nodes.
64  RooCustomizer cust(model, sample, newLeafs, &allCustomiserNodes);
65  cust.splitArg(meanG, sample);
66 
67 
68  // 2. Each sample should have its own signal yield, but there is an extra complication:
69  // We need each yields 1 and 2 to be a function of the variable "mass".
70  // For this, we pre-define nodes with exacly the names that the customiser would have created automatically,
71  // that is, "<nodeName>_<categoryName>", and we register them in the set of customiser nodes.
72  // The customiser will pick them up instead of creating new ones.
73  // If we don't provide one (e.g. for "yieldSig_Sample3"), it will be created by cloning `yieldSig`.
74  RooRealVar mass("M", "M", 1, 0, 12000);
75  RooFormulaVar yield1("yieldSig_Sample1", "Signal yield in the first sample", "M/3.360779", mass);
76  RooFormulaVar yield2("yieldSig_Sample2", "Signal yield in the second sample", "M/2", mass);
77  allCustomiserNodes.add(yield1);
78  allCustomiserNodes.add(yield2);
79 
80  // Instruct the customiser to replace all yieldSig nodes for each sample:
81  cust.splitArg(yieldSig, sample);
82 
83 
84  // Now we can start building the PDFs for all categories:
85  auto pdf1 = cust.build("Sample1");
86  auto pdf2 = cust.build("Sample2");
87  auto pdf3 = cust.build("Sample3");
88 
89  // And we inspect the two PDFs
90  std::cout << "\nPDF 1 with a yield depending on M:" << std::endl;
91  pdf1->Print("T");
92  std::cout << "\nPDF 2 with a yield depending on M:" << std::endl;
93  pdf2->Print("T");
94  std::cout << "\nPDF 3 with a free yield:" << std::endl;
95  pdf3->Print("T");
96 
97  std::cout << "\nThe following leafs have been created automatically while customising:" << std::endl;
98  newLeafs.Print("V");
99 
100 
101  // If we needed to set reasonable values for the means of the gaussians, this could be done as follows:
102  auto& meanG1 = static_cast<RooRealVar&>(allCustomiserNodes["meanG_Sample1"]);
103  meanG1.setVal(200);
104  auto& meanG2 = static_cast<RooRealVar&>(allCustomiserNodes["meanG_Sample2"]);
105  meanG2.setVal(300);
106 
107  std::cout << "\nThe following leafs have been used while customising"
108  << "\n\t(partial overlap with the set of automatically created leaves."
109  << "\n\ta new customiser for a different PDF could reuse them if necessary.):" << std::endl;
110  allCustomiserNodes.Print("V");
111 
112 
113 }