Logo ROOT  
Reference Guide
rf611_weightedfits.C
Go to the documentation of this file.
1/// \file
2/// \ingroup tutorial_roofit
3/// \notebook -js
4/// Likelihood and minimization: Parameter uncertainties for weighted unbinned ML fits
5///
6/// ## Parameter uncertainties for weighted unbinned ML fits
7///
8/// Based on example from https://arxiv.org/abs/1911.01303
9///
10/// This example compares different approaches to determining parameter uncertainties in weighted unbinned maximum likelihood fits.
11/// Performing a weighted unbinned maximum likelihood fits can be useful to account for acceptance effects and to statistically subtract background events using the sPlot formalism.
12/// It is however well known that the inverse Hessian matrix does not yield parameter uncertainties with correct coverage in the presence of event weights.
13/// Three approaches to the determination of parameter uncertainties are compared in this example:
14///
15/// 1. Using the inverse weighted Hessian matrix [`SumW2Error(false)`]
16///
17/// 2. Using the expression [`SumW2Error(true)`]
18/// \f[
19/// V_{ij} = H_{ik}^{-1} C_{kl} H_{lj}^{-1}
20/// \f]
21/// where H is the weighted Hessian matrix and C is the Hessian matrix with squared weights
22///
23/// 3. The asymptotically correct approach (for details please see https://arxiv.org/abs/1911.01303) [`Asymptotic(true)`]
24/// \f[
25/// V_{ij} = H_{ik}^{-1} D_{kl} H_{lj}^{-1}
26/// \f]
27/// where H is the weighted Hessian matrix and D is given by
28/// \f[
29/// D_{kl} = \sum_{e=1}^{N} w_e^2 \frac{\partial \log(P)}{\partial \lambda_k}\frac{\partial \log(P)}{\partial \lambda_l}
30/// \f]
31/// with the event weight \f$w_e\f$.
32///
33/// The example performs the fit of a second order polynomial in the angle cos(theta) [-1,1] to a weighted data set.
34/// The polynomial is given by
35/// \f[
36/// P = \frac{ 1 + c_0 \cdot \cos(\theta) + c_1 \cdot \cos(\theta) \cdot \cos(\theta) }{\mathrm{Norm}}
37/// \f]
38/// The two coefficients \f$ c_0 \f$ and \f$ c_1 \f$ and their uncertainties are to be determined in the fit.
39///
40/// The per-event weight is used to correct for an acceptance effect, two different acceptance models can be studied:
41/// - `acceptancemodel==1`: eff = \f$ 0.3 + 0.7 \cdot \cos(\theta) \cdot \cos(\theta) \f$
42/// - `acceptancemodel==2`: eff = \f$ 1.0 - 0.7 \cdot \cos(\theta) \cdot \cos(\theta) \f$
43/// The data is generated to be flat before the acceptance effect.
44///
45/// The performance of the different approaches to determine parameter uncertainties is compared using the pull distributions from a large number of pseudoexperiments.
46/// The pull is defined as \f$ (\lambda_i - \lambda_{gen})/\sigma(\lambda_i) \f$, where \f$ \lambda_i \f$ is the fitted parameter and \f$ \sigma(\lambda_i) \f$ its
47/// uncertainty for pseudoexperiment number i.
48/// If the fit is unbiased and the parameter uncertainties are estimated correctly, the pull distribution should be a Gaussian centered around zero with a width of one.
49///
50/// \macro_image
51/// \macro_output
52/// \macro_code
53/// \date 11/2019
54/// \author Christoph Langenbruch
55
56#include "TH1D.h"
57#include "TCanvas.h"
58#include "TROOT.h"
59#include "TStyle.h"
60#include "TRandom3.h"
61#include "TLegend.h"
62#include "RooRealVar.h"
63#include "RooFitResult.h"
64#include "RooDataSet.h"
65#include "RooPolynomial.h"
66
67using namespace RooFit;
68
69
70int rf611_weightedfits(int acceptancemodel=2) {
71 // I n i t i a l i s a t i o n a n d S e t u p
72 //------------------------------------------------
73
74 //plotting options
77 gStyle->SetTitleSize(0.05, "XY");
78 gStyle->SetLabelSize(0.05, "XY");
79 gStyle->SetTitleOffset(0.9, "XY");
80 gStyle->SetTextSize(0.05);
83 gStyle->SetPadTopMargin(0.075);
89
90 //initialise TRandom3
91 TRandom3* rnd = new TRandom3();
92 rnd->SetSeed(191101303);
93
94 //accepted events and events weighted to account for the acceptance
95 TH1D* haccepted = new TH1D("haccepted", "Generated events;cos(#theta);#events", 40, -1.0, 1.0);
96 TH1D* hweighted = new TH1D("hweighted", "Generated events;cos(#theta);#events", 40, -1.0, 1.0);
97 //histograms holding pull distributions
98 //using the inverse Hessian matrix
99 TH1D* hc0pull1 = new TH1D("hc0pull1", "Inverse weighted Hessian matrix [SumW2Error(false)];Pull (c_{0}^{fit}-c_{0}^{gen})/#sigma(c_{0});", 20, -5.0, 5.0);
100 TH1D* hc1pull1 = new TH1D("hc1pull1", "Inverse weighted Hessian matrix [SumW2Error(false)];Pull (c_{1}^{fit}-c_{1}^{gen})/#sigma(c_{1});", 20, -5.0, 5.0);
101 //using the correction with the Hessian matrix with squared weights
102 TH1D* hc0pull2 = new TH1D("hc0pull2", "Hessian matrix with squared weights [SumW2Error(true)];Pull (c_{0}^{fit}-c_{0}^{gen})/#sigma(c_{0});", 20, -5.0, 5.0);
103 TH1D* hc1pull2 = new TH1D("hc1pull2", "Hessian matrix with squared weights [SumW2Error(true)];Pull (c_{1}^{fit}-c_{1}^{gen})/#sigma(c_{1});", 20, -5.0, 5.0);
104 //asymptotically correct approach
105 TH1D* hc0pull3 = new TH1D("hc0pull3", "Asymptotically correct approach [Asymptotic(true)];Pull (c_{0}^{fit}-c_{0}^{gen})/#sigma(c_{0});", 20, -5.0, 5.0);
106 TH1D* hc1pull3 = new TH1D("hc1pull3", "Asymptotically correct approach [Asymptotic(true)];Pull (c_{1}^{fit}-c_{1}^{gen})/#sigma(c_{1});", 20, -5.0, 5.0);
107
108 //number of pseudoexperiments (toys) and number of events per pseudoexperiment
109 constexpr unsigned int ntoys = 500;
110 constexpr unsigned int nstats = 5000;
111 //parameters used in the generation
112 constexpr double c0gen = 0.0;
113 constexpr double c1gen = 0.0;
114
115 // Silence fitting and minimisation messages
116 auto& msgSv = RooMsgService::instance();
117 msgSv.getStream(1).removeTopic(RooFit::Minimization);
118 msgSv.getStream(1).removeTopic(RooFit::Fitting);
119
120 std::cout << "Running " << ntoys*3 << " toy fits ..." << std::endl;
121
122 // M a i n l o o p : r u n p s e u d o e x p e r i m e n t s
123 //----------------------------------------------------------------
124 for (unsigned int i=0; i<ntoys; i++) {
125 //S e t u p p a r a m e t e r s a n d P D F
126 //-----------------------------------------------
127 //angle theta and the weight to account for the acceptance effect
128 RooRealVar costheta("costheta","costheta", -1.0, 1.0);
129 RooRealVar weight("weight","weight", 0.0, 1000.0);
130
131 //initialise parameters to fit
132 RooRealVar c0("c0","0th-order coefficient", c0gen, -1.0, 1.0);
133 RooRealVar c1("c1","1st-order coefficient", c1gen, -1.0, 1.0);
134 c0.setError(0.01);
135 c1.setError(0.01);
136 //create simple second-order polynomial as probability density function
137 RooPolynomial pol("pol", "pol", costheta, RooArgList(c0, c1), 1);
138
139 //G e n e r a t e d a t a s e t f o r p s e u d o e x p e r i m e n t i
140 //-------------------------------------------------------------------------------
141 RooDataSet data("data","data",RooArgSet(costheta, weight), WeightVar("weight"));
142 //generate nstats events
143 for (unsigned int j=0; j<nstats; j++) {
144 bool finished = false;
145 //use simple accept/reject for generation
146 while (!finished) {
147 costheta = 2.0*rnd->Rndm()-1.0;
148 //efficiency for the specific value of cos(theta)
149 double eff = 1.0;
150 if (acceptancemodel == 1)
151 eff = 1.0 - 0.7 * costheta.getVal()*costheta.getVal();
152 else
153 eff = 0.3 + 0.7 * costheta.getVal()*costheta.getVal();
154 //use 1/eff as weight to account for acceptance
155 weight = 1.0/eff;
156 //accept/reject
157 if (10.0*rnd->Rndm() < eff*pol.getVal())
158 finished = true;
159 }
160 haccepted->Fill(costheta.getVal());
161 hweighted->Fill(costheta.getVal(), weight.getVal());
162 data.add(RooArgSet(costheta, weight), weight.getVal());
163 }
164
165 //F i t t o y u s i n g t h e t h r e e d i f f e r e n t a p p r o a c h e s t o u n c e r t a i n t y d e t e r m i n a t i o n
166 //-------------------------------------------------------------------------------------------------------------------------------------------------
167 //this uses the inverse weighted Hessian matrix
168 RooFitResult* result = pol.fitTo(data, Save(true), SumW2Error(false), PrintLevel(-1), BatchMode(true));
169 hc0pull1->Fill((c0.getVal()-c0gen)/c0.getError());
170 hc1pull1->Fill((c1.getVal()-c1gen)/c1.getError());
171
172 //this uses the correction with the Hesse matrix with squared weights
173 result = pol.fitTo(data, Save(true), SumW2Error(true), PrintLevel(-1), BatchMode(true));
174 hc0pull2->Fill((c0.getVal()-c0gen)/c0.getError());
175 hc1pull2->Fill((c1.getVal()-c1gen)/c1.getError());
176
177 //this uses the asymptotically correct approach
178 result = pol.fitTo(data, Save(true), AsymptoticError(true), PrintLevel(-1), BatchMode(true));
179 hc0pull3->Fill((c0.getVal()-c0gen)/c0.getError());
180 hc1pull3->Fill((c1.getVal()-c1gen)/c1.getError());
181 }
182
183 std::cout << "... done." << std::endl;
184
185 // P l o t o u t p u t d i s t r i b u t i o n s
186 //--------------------------------------------------
187
188 //plot accepted (weighted) events
189 gStyle->SetOptStat(0);
190 gStyle->SetOptFit(0);
191 TCanvas* cevents = new TCanvas("cevents", "cevents", 800, 600);
192 cevents->cd(1);
193 hweighted->SetMinimum(0.0);
194 hweighted->SetLineColor(2);
195 hweighted->Draw("hist");
196 haccepted->Draw("same hist");
197 TLegend* leg = new TLegend(0.6, 0.8, 0.9, 0.9);
198 leg->AddEntry(haccepted, "Accepted");
199 leg->AddEntry(hweighted, "Weighted");
200 leg->Draw();
201 cevents->Update();
202
203 //plot pull distributions
204 TCanvas* cpull = new TCanvas("cpull", "cpull", 1200, 800);
205 cpull->Divide(3,2);
206 cpull->cd(1);
207 gStyle->SetOptStat(1100);
208 gStyle->SetOptFit(11);
209 hc0pull1->Fit("gaus");
210 hc0pull1->Draw("ep");
211 cpull->cd(2);
212 hc0pull2->Fit("gaus");
213 hc0pull2->Draw("ep");
214 cpull->cd(3);
215 hc0pull3->Fit("gaus");
216 hc0pull3->Draw("ep");
217 cpull->cd(4);
218 hc1pull1->Fit("gaus");
219 hc1pull1->Draw("ep");
220 cpull->cd(5);
221 hc1pull2->Fit("gaus");
222 hc1pull2->Draw("ep");
223 cpull->cd(6);
224 hc1pull3->Fit("gaus");
225 hc1pull3->Draw("ep");
226 cpull->Update();
227
228 return 0;
229}
R__EXTERN TStyle * gStyle
Definition: TStyle.h:407
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
RooFitResult is a container class to hold the input and output of a PDF fit to a dataset.
Definition: RooFitResult.h:40
static RooMsgService & instance()
Return reference to singleton instance.
RooPolynomial implements a polynomial p.d.f of the form.
Definition: RooPolynomial.h:28
RooRealVar represents a variable that can be changed from the outside.
Definition: RooRealVar.h:35
virtual void SetLineColor(Color_t lcolor)
Set the line color.
Definition: TAttLine.h:40
virtual void SetMarkerStyle(Style_t mstyle=1)
Set the marker style.
Definition: TAttMarker.h:40
virtual void SetMarkerSize(Size_t msize=1)
Set the marker size.
Definition: TAttMarker.h:41
virtual void SetTextSize(Float_t tsize=1)
Set the text size.
Definition: TAttText.h:46
The Canvas class.
Definition: TCanvas.h:31
virtual void Update()
Update canvas pad buffers.
Definition: TCanvas.cxx:2339
TVirtualPad * cd(Int_t subpadnumber=0)
Set current canvas & pad.
Definition: TCanvas.cxx:696
1-D histogram with a double per channel (see TH1 documentation)}
Definition: TH1.h:614
virtual TFitResultPtr Fit(const char *formula, Option_t *option="", Option_t *goption="", Double_t xmin=0, Double_t xmax=0)
Fit histogram with function fname.
Definition: TH1.cxx:3808
virtual Int_t Fill(Double_t x)
Increment bin with abscissa X by 1.
Definition: TH1.cxx:3275
virtual void SetMinimum(Double_t minimum=-1111)
Definition: TH1.h:395
virtual void Draw(Option_t *option="")
Draw this histogram with options.
Definition: TH1.cxx:2998
This class displays a legend box (TPaveText) containing several legend entries.
Definition: TLegend.h:23
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
Random number generator class based on M.
Definition: TRandom3.h:27
virtual Double_t Rndm()
Machine independent random number generator.
Definition: TRandom3.cxx:100
virtual void SetSeed(ULong_t seed=0)
Set the random generator sequence if seed is 0 (default value) a TUUID is generated and used to fill ...
Definition: TRandom3.cxx:207
void SetPadTopMargin(Float_t margin=0.1)
Definition: TStyle.h:337
void SetOptStat(Int_t stat=1)
The type of information printed in the histogram statistics box can be selected via the parameter mod...
Definition: TStyle.cxx:1450
void SetPadBottomMargin(Float_t margin=0.1)
Definition: TStyle.h:336
void SetPaintTextFormat(const char *format="g")
Definition: TStyle.h:364
void SetEndErrorSize(Float_t np=2)
Set the size (in pixels) of the small lines drawn at the end of the error bars (TH1 or TGraphErrors).
Definition: TStyle.cxx:1152
void SetPadRightMargin(Float_t margin=0.1)
Definition: TStyle.h:339
void SetTitleOffset(Float_t offset=1, Option_t *axis="X")
Specify a parameter offset to control the distance between the axis and the axis title.
Definition: TStyle.cxx:1609
void SetPadLeftMargin(Float_t margin=0.1)
Definition: TStyle.h:338
void SetHistLineColor(Color_t color=1)
Definition: TStyle.h:358
void SetTitleSize(Float_t size=0.02, Option_t *axis="X")
Definition: TStyle.cxx:1628
void SetHistLineWidth(Width_t width=1)
Definition: TStyle.h:361
void SetLabelSize(Float_t size=0.04, Option_t *axis="X")
Set size of axis labels.
Definition: TStyle.cxx:1256
void SetOptFit(Int_t fit=1)
The type of information about fit parameters printed in the histogram statistics box can be selected ...
Definition: TStyle.cxx:1402
return c1
Definition: legend1.C:41
leg
Definition: legend1.C:34
The namespace RooFit contains mostly switches that change the behaviour of functions of PDFs (or othe...
RooCmdArg WeightVar(const char *name, Bool_t reinterpretAsWeight=kFALSE)
RooCmdArg SumW2Error(Bool_t flag)
@ Minimization
Definition: RooGlobalFunc.h:67
RooCmdArg Save(Bool_t flag=kTRUE)
RooCmdArg PrintLevel(Int_t code)
RooCmdArg BatchMode(bool flag=true)
RooCmdArg AsymptoticError(Bool_t flag)