Logo ROOT  
Reference Guide
rf709_BarlowBeeston.C
Go to the documentation of this file.
1/// \file rf709_BarlowBeeston.C
2/// \ingroup tutorial_roofit
3/// \notebook -js
4/// Implementing the Barlow-Beeston method for taking into account the statistical uncertainty of a Monte-Carlo fit template.
5/// \macro_image
6/// \macro_output
7/// \macro_code
8/// \author 06/2019 - Stephan Hageboeck, CERN
9/// Based on a demo by Wouter Verkerke
10
11#include "RooRealVar.h"
12#include "RooGaussian.h"
13#include "RooUniform.h"
14#include "RooDataSet.h"
15#include "RooDataHist.h"
16#include "RooHistFunc.h"
17#include "RooRealSumPdf.h"
18#include "RooParamHistFunc.h"
19#include "RooHistConstraint.h"
20#include "RooProdPdf.h"
21#include "RooPlot.h"
22
23#include "TCanvas.h"
24#include "TPaveText.h"
25
26#include <iostream>
27#include <memory>
28
29using namespace RooFit;
30
31void rf709_BarlowBeeston()
32{
33 // First, construct a likelihood model with a Gaussian signal on top of a uniform background
34 RooRealVar x("x", "x", -20, 20);
35 x.setBins(25);
36
37 RooRealVar meanG("meanG", "meanG", 1, -10, 10);
38 RooRealVar sigG("sigG", "sigG", 1.5, -10, 10);
39 RooGaussian g("g", "Gauss", x, meanG, sigG);
40 RooUniform u("u", "Uniform", x);
41
42
43 // Generate the data to be fitted
44 std::unique_ptr<RooDataSet> sigData(g.generate(x, 50));
45 std::unique_ptr<RooDataSet> bkgData(u.generate(x, 1000));
46
47 RooDataSet sumData("sumData", "Gauss + Uniform", x);
48 sumData.append(*sigData);
49 sumData.append(*bkgData);
50
51
52 // Make histogram templates for signal and background.
53 // Let's take a signal distribution with low statistics and a more accurate
54 // background distribution.
55 // Normally, these come from Monte Carlo simulations, but we will just generate them.
56 std::unique_ptr<RooDataHist> dh_sig( g.generateBinned(x, 50) );
57 std::unique_ptr<RooDataHist> dh_bkg( u.generateBinned(x, 10000) );
58
59
60 // ***** Case 0 - 'Rigid templates' *****
61
62 // Construct histogram shapes for signal and background
63 RooHistFunc p_h_sig("p_h_sig","p_h_sig",x,*dh_sig);
64 RooHistFunc p_h_bkg("p_h_bkg","p_h_bkg",x,*dh_bkg);
65
66 // Construct scale factors for adding the two distributions
67 RooRealVar Asig0("Asig","Asig",1,0.01,5000);
68 RooRealVar Abkg0("Abkg","Abkg",1,0.01,5000);
69
70 // Construct the sum model
71 RooRealSumPdf model0("model0","model0",
72 RooArgList(p_h_sig,p_h_bkg),
73 RooArgList(Asig0,Abkg0),
74 true);
75
76
77
78 // ***** Case 1 - 'Barlow Beeston' *****
79
80 // Construct parameterized histogram shapes for signal and background
81 RooParamHistFunc p_ph_sig1("p_ph_sig","p_ph_sig",*dh_sig);
82 RooParamHistFunc p_ph_bkg1("p_ph_bkg","p_ph_bkg",*dh_bkg);
83
84 RooRealVar Asig1("Asig","Asig",1,0.01,5000);
85 RooRealVar Abkg1("Abkg","Abkg",1,0.01,5000);
86
87 // Construct the sum of these
88 RooRealSumPdf model_tmp("sp_ph", "sp_ph",
89 RooArgList(p_ph_sig1,p_ph_bkg1),
90 RooArgList(Asig1,Abkg1),
91 true);
92
93 // Construct the subsidiary poisson measurements constraining the histogram parameters
94 // These ensure that the bin contents of the histograms are only allowed to vary within
95 // the statistical uncertainty of the Monte Carlo.
96 RooHistConstraint hc_sig("hc_sig","hc_sig",p_ph_sig1);
97 RooHistConstraint hc_bkg("hc_bkg","hc_bkg",p_ph_bkg1);
98
99 // Construct the joint model with template PDFs and constraints
100 RooProdPdf model1("model1","model1",RooArgSet(hc_sig,hc_bkg),Conditional(model_tmp,x));
101
102
103
104 // ***** Case 2 - 'Barlow Beeston' light (one parameter per bin for all samples) *****
105
106 // Construct the histogram shapes, using the same parameters for signal and background
107 // This requires passing the first histogram to the second, so that their common parameters
108 // can be re-used.
109 // The first ParamHistFunc will create one parameter per bin, such as `p_ph_sig2_gamma_bin_0`.
110 // This allows bin 0 to fluctuate up and down.
111 // Then, the SAME parameters are connected to the background histogram, so the bins flucutate
112 // synchronously. This reduces the number of parameters.
113 RooParamHistFunc p_ph_sig2("p_ph_sig2", "p_ph_sig2", *dh_sig);
114 RooParamHistFunc p_ph_bkg2("p_ph_bkg2", "p_ph_bkg2", *dh_bkg, p_ph_sig2, true);
115
116 RooRealVar Asig2("Asig","Asig",1,0.01,5000);
117 RooRealVar Abkg2("Abkg","Abkg",1,0.01,5000);
118
119 // As before, construct the sum of signal2 and background2
120 RooRealSumPdf model2_tmp("sp_ph","sp_ph",
121 RooArgList(p_ph_sig2,p_ph_bkg2),
122 RooArgList(Asig2,Abkg2),
123 true);
124
125 // Construct the subsidiary poisson measurements constraining the statistical fluctuations
126 RooHistConstraint hc_sigbkg("hc_sigbkg","hc_sigbkg",RooArgSet(p_ph_sig2,p_ph_bkg2));
127
128 // Construct the joint model
129 RooProdPdf model2("model2","model2",hc_sigbkg, RooFit::Conditional(model2_tmp,x));
130
131
132
133 // ************ Fit all models to data and plot *********************
134
135 auto result0 = model0.fitTo(sumData, PrintLevel(0), Save());
136 auto result1 = model1.fitTo(sumData, PrintLevel(0), Save());
137 auto result2 = model2.fitTo(sumData, PrintLevel(0), Save());
138
139
140 TCanvas* can = new TCanvas("can", "", 1500, 600);
141 can->Divide(3,1);
142
143 TPaveText pt(-19.5, 1, -2, 25);
144 pt.SetFillStyle(0);
145 pt.SetBorderSize(0);
146
147
148 can->cd(1);
149 auto frame = x.frame(Title("No template uncertainties"));
150 // Plot data to enable automatic determination of model0 normalisation:
151 sumData.plotOn(frame);
152 model0.plotOn(frame, LineColor(kBlue), VisualizeError(*result0));
153 // Plot data again to show it on top of model0 error bands:
154 sumData.plotOn(frame);
155 // Plot model components
156 model0.plotOn(frame, LineColor(kBlue));
157 model0.plotOn(frame, Components(p_h_sig), LineColor(kAzure));
158 model0.plotOn(frame, Components(p_h_bkg), LineColor(kRed));
159 model0.paramOn(frame);
160
161 sigData->plotOn(frame, MarkerColor(kBlue));
162 frame->Draw();
163
164 for (auto text : {
165 "No template uncertainties",
166 "are taken into account.",
167 "This leads to low errors",
168 "for the parameters A, since",
169 "the only source of errors",
170 "are the data statistics."}) {
171 pt.AddText(text);
172 }
173 pt.DrawClone();
174
175
176 can->cd(2);
177 frame = x.frame(Title("Barlow Beeston for Sig & Bkg separately"));
178 sumData.plotOn(frame);
179 model1.plotOn(frame, LineColor(kBlue), VisualizeError(*result1));
180 // Plot data again to show it on top of error bands:
181 sumData.plotOn(frame);
182 model1.plotOn(frame, LineColor(kBlue));
183 model1.plotOn(frame, Components(p_ph_sig1), LineColor(kAzure));
184 model1.plotOn(frame, Components(p_ph_bkg1), LineColor(kRed));
185 model1.paramOn(frame, Parameters(RooArgSet(Asig1, Abkg1)));
186
187 sigData->plotOn(frame, MarkerColor(kBlue));
188 frame->Draw();
189
190 pt.Clear();
191 for (auto text : {
192 "With gamma parameters, the",
193 "signal & background templates",
194 "can adapt to the data.",
195 "Note how the blue signal",
196 "template changes its shape.",
197 "This leads to higher errors",
198 "of the scale parameters A."}) {
199 pt.AddText(text);
200 }
201 pt.DrawClone();
202
203 can->cd(3);
204 frame = x.frame(Title("Barlow Beeston light for (Sig+Bkg)"));
205 sumData.plotOn(frame);
206 model2.plotOn(frame, LineColor(kBlue), VisualizeError(*result2));
207 // Plot data again to show it on top of model0 error bands:
208 sumData.plotOn(frame);
209 model2.plotOn(frame, LineColor(kBlue));
210 model2.plotOn(frame, Components(p_ph_sig2), LineColor(kAzure));
211 model2.plotOn(frame, Components(p_ph_bkg2), LineColor(kRed));
212 model2.paramOn(frame, Parameters(RooArgSet(Asig2, Abkg2)));
213
214 sigData->plotOn(frame, MarkerColor(kBlue));
215 frame->Draw();
216
217 pt.Clear();
218 for (auto text : {
219 "When signal and background",
220 "template share one gamma para-",
221 "meter per bin, they adapt less.",
222 "The errors of the A parameters",
223 "also shrink slightly."}) {
224 pt.AddText(text);
225 }
226 pt.DrawClone();
227
228
229 std::cout << "Asig [normal ] = " << Asig0.getVal() << " +/- " << Asig0.getError() << std::endl;
230 std::cout << "Asig [BB ] = " << Asig1.getVal() << " +/- " << Asig1.getError() << std::endl;
231 std::cout << "Asig [BBlight] = " << Asig2.getVal() << " +/- " << Asig2.getError() << std::endl;
232
233}
#define g(i)
Definition: RSha256.hxx:105
@ kRed
Definition: Rtypes.h:64
@ kBlue
Definition: Rtypes.h:64
@ kAzure
Definition: Rtypes.h:65
RooArgList is a container object that can hold multiple RooAbsArg objects.
Definition: RooArgList.h:21
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition: RooArgSet.h:28
RooDataSet is a container class to hold unbinned data.
Definition: RooDataSet.h:31
Plain Gaussian p.d.f.
Definition: RooGaussian.h:25
The RooHistConstraint implements constraint terms for a binned PDF with statistical uncertainties.
RooHistFunc implements a real-valued function sampled from a multidimensional histogram.
Definition: RooHistFunc.h:29
A histogram function that assigns scale parameters to every bin.
RooProdPdf is an efficient implementation of a product of PDFs of the form.
Definition: RooProdPdf.h:31
The class RooRealSumPdf implements a PDF constructed from a sum of functions:
Definition: RooRealSumPdf.h:24
RooRealVar represents a variable that can be changed from the outside.
Definition: RooRealVar.h:35
Flat p.d.f.
Definition: RooUniform.h:24
virtual void SetFillStyle(Style_t fstyle)
Set the fill area style.
Definition: TAttFill.h:39
The Canvas class.
Definition: TCanvas.h:31
TVirtualPad * cd(Int_t subpadnumber=0)
Set current canvas & pad.
Definition: TCanvas.cxx:696
virtual TObject * DrawClone(Option_t *option="") const
Draw a clone of this object in the current selected pad for instance with: gROOT->SetSelectedPad(gPad...
Definition: TObject.cxx:219
virtual void Divide(Int_t nx=1, Int_t ny=1, Float_t xmargin=0.01, Float_t ymargin=0.01, Int_t color=0)
Automatic pad generation by division.
Definition: TPad.cxx:1163
A Pave (see TPave) with text, lines or/and boxes inside.
Definition: TPaveText.h:21
virtual TText * AddText(Double_t x1, Double_t y1, const char *label)
Add a new Text line to this pavetext at given coordinates.
Definition: TPaveText.cxx:182
virtual void Clear(Option_t *option="")
Clear all lines in this pavetext.
Definition: TPaveText.cxx:208
virtual void SetBorderSize(Int_t bordersize=4)
Definition: TPave.h:73
TPaveText * pt
TText * text
Double_t x[n]
Definition: legend1.C:17
The namespace RooFit contains mostly switches that change the behaviour of functions of PDFs (or othe...
RooCmdArg VisualizeError(const RooDataSet &paramData, Double_t Z=1)
RooCmdArg MarkerColor(Color_t color)
RooCmdArg Parameters(const RooArgSet &params)
RooCmdArg Components(const RooArgSet &compSet)
RooCmdArg Save(Bool_t flag=kTRUE)
RooCmdArg PrintLevel(Int_t code)
RooCmdArg LineColor(Color_t color)
RooCmdArg Conditional(const RooArgSet &pdfSet, const RooArgSet &depSet, Bool_t depsAreCond=kFALSE)
const char * Title
Definition: TXMLSetup.cxx:67