Logo ROOT  
Reference Guide
 
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
Loading...
Searching...
No Matches
TEfficiency.cxx
Go to the documentation of this file.
1#ifndef ROOT_TEfficiency_cxx
2#define ROOT_TEfficiency_cxx
3
4//standard header
5#include <vector>
6#include <string>
7#include <cmath>
8#include <cstdlib>
9#include <cassert>
10
11//ROOT headers
14#include "TDirectory.h"
15#include "TF1.h"
16#include "TGraphAsymmErrors.h"
17#include "TGraph2DAsymmErrors.h"
18#include "TH1.h"
19#include "TH2.h"
20#include "TH3.h"
21#include "TList.h"
22#include "TMath.h"
23#include "TROOT.h"
24#include "TStyle.h"
25#include "TVirtualPad.h"
26#include "TError.h"
29
30//custom headers
31#include "TEfficiency.h"
32
33// file with extra class for FC method
34#include "TEfficiencyHelper.h"
35
36//default values
39const Double_t kDefConfLevel = 0.682689492137; // 1 sigma
42
44
45////////////////////////////////////////////////////////////////////////////////
46/** \class TEfficiency
47 \ingroup Hist
48 \brief Class to handle efficiency histograms
49
50- [I. Overview](\ref EFF01)
51- [II. Creating a TEfficiency object](\ref EFF02)
52 - [Example 1](\ref EFF02a)
53 - [Example 2](\ref EFF02b)
54- [III. Filling with events](\ref EFF03)
55- [IV. Statistic options](\ref EFF04)
56 - [Frequentist methods](\ref EFF04a)
57 - [Bayesian methods](\ref EFF04b)
58 - [IV.1 Coverage probabilities for different methods](\ref EFF041)
59- [V. Merging and combining TEfficiency objects](\ref EFF05)
60 - [Example](\ref EFF05a)
61 - [V.1 When should I use merging?](\ref EFF051)
62 - [Example](\ref EFF05b)
63 - [V.2 When should I use combining?](\ref EFF052)
64 - [Example](\ref EFF05c)
65- [VI. Further operations](\ref EFF06)
66 - [VI.1 Information about the internal histograms](\ref EFF061)
67 - [VI.2 Fitting](\ref EFF062)
68 - [VI.3 Draw a TEfficiency object](\ref EFF063)
69 - [VI.4 TEfficiency object's axis customisation](\ref EFF064)
70
71\anchor EFF01
72## I. Overview
73This class handles the calculation of efficiencies and their uncertainties. It
74provides several statistical methods for calculating frequentist and Bayesian
75confidence intervals as well as a function for combining several efficiencies.
76
77Efficiencies have a lot of applications and meanings but in principle, they can
78be described by the fraction of good/passed events k out of sample containing
79N events. One is usually interested in the dependency of the efficiency on other
80(binned) variables. The number of passed and total events is therefore stored
81internally in two histograms (TEfficiency::fTotalHistogram and TEfficiency::fPassedHistogram).
82Then the efficiency, as well as its upper and lower error, can be calculated for each bin
83individually.
84
85As the efficiency can be regarded as a parameter of a binomial distribution, the
86number of passed and total events must always be integer numbers. Therefore a
87filling with weights is not possible. However, you can assign a global weight to each
88TEfficiency object (TEfficiency::SetWeight).
89It is necessary to create one TEfficiency object
90for each weight if you investigate a process involving different weights. This
91procedure needs more effort but enables you to re-use the filled object in cases
92where you want to change one or more weights. This would not be possible if all
93events with different weights were filled in the same histogram.
94
95\anchor EFF02
96## II. Creating a TEfficiency object
97If you start a new analysis, it is highly recommended to use the TEfficiency class
98from the beginning. You can then use one of the constructors for fixed or
99variable bin size and your desired dimension. These constructors append the
100created TEfficiency object to the current directory. So it will be written
101automatically to a file during the next TFile::Write command.
102
103Example: create a two-dimensional TEfficiency object with
104- name = "eff"
105- title = "my efficiency"
106- axis titles: x, y and LaTeX-formatted epsilon as a label for Z axis
107- 10 bins with constant bin width (= 1) along X axis starting at 0 (lower edge
108 from the first bin) up to 10 (upper edge of last bin)
109- 20 bins with constant bin width (= 0.5) along Y axis starting at -5 (lower
110 edge from the first bin) up to 5 (upper edge of last bin)
111
112 TEfficiency* pEff = new TEfficiency("eff","my efficiency;x;y;#epsilon",10,0,10,20,-5,5);
113
114If you already have two histograms filled with the number of passed and total
115events, you will use the constructor TEfficiency(const TH1& passed,const TH1& total)
116to construct the TEfficiency object. The histograms "passed" and "total" have
117to fulfill the conditions mentioned in TEfficiency::CheckConsistency, otherwise the construction will fail.
118As the histograms already exist, the new TEfficiency is by default **not** attached
119to the current directory to avoid duplication of data. If you want to store the
120new object anyway, you can either write it directly by calling TObject::Write or attach it to a directory using TEfficiency::SetDirectory.
121This also applies to TEfficiency objects created by the copy constructor TEfficiency::TEfficiency(const TEfficiency& rEff).
122
123\anchor EFF02a
124### Example 1
125
126~~~~~~~~~~~~~~~{.cpp}
127TEfficiency* pEff = 0;
128TFile* pFile = new TFile("myfile.root","recreate");
129
130//h_pass and h_total are valid and consistent histograms
131if(TEfficiency::CheckConsistency(h_pass,h_total))
132{
133 pEff = new TEfficiency(h_pass,h_total);
134 // this will write the TEfficiency object to "myfile.root"
135 // AND pEff will be attached to the current directory
136 pEff->Write();
137}
138~~~~~~~~~~~~~~~
139
140\anchor EFF02b
141### Example 2
142
143~~~~~~~~~~~~~~~{.cpp}
144TEfficiency* pEff = 0;
145TFile* pFile = new TFile("myfile.root","recreate");
146
147//h_pass and h_total are valid and consistent histograms
148if(TEfficiency::CheckConsistency(h_pass,h_total))
149{
150 pEff = new TEfficiency(h_pass,h_total);
151 //this will attach the TEfficiency object to the current directory
152 pEff->SetDirectory(gDirectory);
153 //now all objects in gDirectory will be written to "myfile.root"
154 pFile->Write();
155}
156~~~~~~~~~~~~~~~
157
158In case you already have two filled histograms and you only want to
159plot them as a graph, you should rather use TGraphAsymmErrors::TGraphAsymmErrors(const TH1* pass,const TH1* total,Option_t* opt)
160to create a graph object.
161
162\anchor EFF03
163## III. Filling with events
164You can fill the TEfficiency object by calling the TEfficiency::Fill(Bool_t bPassed,Double_t x,Double_t y,Double_t z) method.
165The "bPassed" boolean flag indicates whether the current event is good
166(both histograms are filled) or not (only TEfficiency::fTotalHistogram is filled).
167The x, y and z variables determine the bin which is filled. For lower dimensions, the z- or even the y-value may be omitted.
168
169Begin_Macro(source)
170{
171 //canvas only needed for this documentation
172 TCanvas* c1 = new TCanvas("example","",600,400);
173 c1->SetFillStyle(1001);
174 c1->SetFillColor(kWhite);
175
176 //create one-dimensional TEfficiency object with fixed bin size
177 TEfficiency* pEff = new TEfficiency("eff","my efficiency;x;#epsilon",20,0,10);
178 TRandom3 rand3;
179
180 bool bPassed;
181 double x;
182 for(int i=0; i<10000; ++i)
183 {
184 //simulate events with variable under investigation
185 x = rand3.Uniform(10);
186 //check selection: bPassed = DoesEventPassSelection(x)
187 bPassed = rand3.Rndm() < TMath::Gaus(x,5,4);
188 pEff->Fill(bPassed,x);
189 }
190
191 pEff->Draw("AP");
192}
193End_Macro
194
195You can also set the number of passed or total events for a bin directly by
196using the TEfficiency::SetPassedEvents or TEfficiency::SetTotalEvents method.
197
198\anchor EFF04
199## IV. Statistic options
200The calculation of the estimated efficiency depends on the chosen statistic
201option. Let k denotes the number of passed events and N the number of total
202events.
203
204\anchor EFF04a
205### Frequentist methods
206The expectation value of the number of passed events is given by the true
207efficiency times the total number of events. One can estimate the efficiency
208by replacing the expected number of passed events by the observed number of
209passed events.
210
211\f[
212 k = \epsilon \times N \Rightarrow \hat{\varepsilon} = \frac{k}{N}
213\f]
214
215\anchor EFF04b
216### Bayesian methods
217In Bayesian statistics a likelihood-function (how probable is it to get the
218observed data assuming a true efficiency) and a prior probability (what is the
219probability that a certain true efficiency is actually realised) are used to
220determine a posterior probability by using Bayes theorem. At the moment,
221only beta distributions (with 2 free parameters) are supported as prior
222probabilities, as explained in D. Casadei, Estimating the selection efficiency,
2232012 JINST 7 P08021, https://doi.org/10.1088/1748-0221/7/08/P08021 (https://arxiv.org/abs/0908.0130).
224
225\f{eqnarray*}{
226 P(\epsilon | k ; N) &=& \frac{1}{norm} \times P(k | \epsilon ; N) \times Prior(\epsilon) \
227 P(k | \epsilon ; N) &=& Binomial(N,k) \times \epsilon^{k} \times (1 - \epsilon)^{N - k} ...\ binomial\ distribution \
228 Prior(\epsilon) &=& \frac{1}{B(\alpha,\beta)} \times \epsilon ^{\alpha - 1} \times (1 - \epsilon)^{\beta - 1} \equiv Beta(\epsilon; \alpha,\beta) \
229 \Rightarrow P(\epsilon | k ; N) &=& \frac{1}{norm'} \times \epsilon^{k + \alpha - 1} \times (1 - \epsilon)^{N - k + \beta - 1} \equiv Beta(\epsilon; k + \alpha, N - k + \beta)
230\f}
231
232By default the expectation value of this posterior distribution is used as an estimator for the efficiency:
233
234\f[
235 \hat{\varepsilon} = \frac{k + \alpha}{N + \alpha + \beta}
236\f]
237
238Optionally the mode can also be used as a value for the estimated efficiency. This can be done by calling
239SetBit(kPosteriorMode) or TEfficiency::SetPosteriorMode. In this case, the estimated efficiency is:
240
241\f[
242 \hat{\varepsilon} = \frac{k + \alpha -1}{N + \alpha + \beta - 2}
243\f]
244
245In the case of a uniform prior distribution, B(x,1,1), the posterior mode is k/n, equivalent to the frequentist
246estimate (the maximum likelihood value).
247
248The statistic options also specify which confidence interval is used for calculating
249the uncertainties of the efficiency. The following properties define the error
250calculation:
251- **fConfLevel:** desired confidence level: 0 < fConfLevel < 1 (TEfficiency::GetConfidenceLevel / TEfficiency::SetConfidenceLevel)
252- **fStatisticOption** defines which method is used to calculate the boundaries of the confidence interval (TEfficiency::SetStatisticOption)
253- **fBeta_alpha, fBeta_beta:** parameters for the prior distribution which is only used in the bayesian case (TEfficiency::GetBetaAlpha / TEfficiency::GetBetaBeta / TEfficiency::SetBetaAlpha / TEfficiency::SetBetaBeta)
254- **kIsBayesian:** flag whether bayesian statistics are used or not (TEfficiency::UsesBayesianStat)
255- **kShortestInterval:** flag whether shortest interval (instead of central one) are used in case of Bayesian statistics (TEfficiency::UsesShortestInterval). Normally shortest interval should be used in combination with the mode (see TEfficiency::UsesPosteriorMode)
256- **fWeight:** global weight for this TEfficiency object which is used during combining or merging with other TEfficiency objects(TEfficiency::GetWeight / TEfficiency::SetWeight)
257
258In the following table, the implemented confidence intervals are listed
259with their corresponding statistic option. For more details on the calculation,
260please have a look at the mentioned functions.
261
262
263| name | statistic option | function | kIsBayesian | parameters |
264|------------------|------------------|---------------------|-------------|------------|
265| Clopper-Pearson | kFCP | TEfficiency::ClopperPearson |false |total events, passed events, confidence level |
266| normal approximation | kFNormal | TEfficiency::Normal | false | total events, passed events, confidence level |
267| Wilson | kFWilson | TEfficiency::Wilson | false | total events, passed events, confidence level |
268| Agresti-Coull | kFAC | TEfficiency::AgrestiCoull | false | total events, passed events. confidence level |
269| Feldman-Cousins | kFFC | TEfficiency::FeldmanCousins | false | total events, passed events, confidence level |
270| Mid-P Lancaster | kMidP | TEfficiency::MidPInterval | false | total events, passed events, confidence level |
271| Jeffrey | kBJeffrey | TEfficiency::Bayesian | true | total events, passed events, confidence level, fBeta_alpha = 0.5, fBeta_beta = 0.5 |
272| Uniform prior | kBUniform |TEfficiency::Bayesian | true |total events, passed events, confidence level, fBeta_alpha = 1, fBeta_beta = 1 |
273| custom prior | kBBayesian |TEfficiency::Bayesian | true |total events, passed events, confidence level, fBeta_alpha, fBeta_beta |
274
275The following example demonstrates the effect of different statistic options and
276confidence levels.
277
278Begin_Macro(source)
279{
280 //canvas only needed for the documentation
281 TCanvas* c1 = new TCanvas("c1","",600,400);
282 c1->Divide(2);
283 c1->SetFillStyle(1001);
284 c1->SetFillColor(kWhite);
285
286 //create one-dimensional TEfficiency object with fixed bin size
287 TEfficiency* pEff = new TEfficiency("eff","different confidence levels;x;#epsilon",20,0,10);
288 TRandom3 rand3;
289
290 bool bPassed;
291 double x;
292 for(int i=0; i<1000; ++i)
293 {
294 //simulate events with variable under investigation
295 x = rand3.Uniform(10);
296 //check selection: bPassed = DoesEventPassSelection(x)
297 bPassed = rand3.Rndm() < TMath::Gaus(x,5,4);
298 pEff->Fill(bPassed,x);
299 }
300
301 //set style attributes
302 pEff->SetFillStyle(3004);
303 pEff->SetFillColor(kRed);
304
305 //copy current TEfficiency object and set new confidence level
306 TEfficiency* pCopy = new TEfficiency(*pEff);
307 pCopy->SetConfidenceLevel(0.90);
308
309 //set style attributes
310 pCopy->SetFillStyle(3005);
311 pCopy->SetFillColor(kBlue);
312
313 c1->cd(1);
314
315 //add legend
316 TLegend* leg1 = new TLegend(0.3,0.1,0.7,0.5);
317 leg1->AddEntry(pEff,"68.3%","F");
318 leg1->AddEntry(pCopy,"90%","F");
319
320 pEff->Draw("A4");
321 pCopy->Draw("same4");
322 leg1->Draw("same");
323
324 //use same confidence level but different statistic methods
325 TEfficiency* pEff2 = new TEfficiency(*pEff);
326 TEfficiency* pCopy2 = new TEfficiency(*pEff);
327
328 pEff2->SetStatisticOption(TEfficiency::kFNormal);
329 pCopy2->SetStatisticOption(TEfficiency::kFAC);
330
331 pEff2->SetTitle("different statistic options;x;#epsilon");
332
333 //set style attributes
334 pCopy2->SetFillStyle(3005);
335 pCopy2->SetFillColor(kBlue);
336
337 c1->cd(2);
338
339 //add legend
340 TLegend* leg2 = new TLegend(0.3,0.1,0.7,0.5);
341 leg2->AddEntry(pEff2,"kFNormal","F");
342 leg2->AddEntry(pCopy2,"kFAC","F");
343
344 pEff2->Draw("a4");
345 pCopy2->Draw("same4");
346 leg2->Draw("same");
347}
348End_Macro
349
350The prior probability of the efficiency in Bayesian statistics can be given
351in terms of a beta distribution. The beta distribution has two positive shape
352parameters. The resulting priors for different combinations of these shape
353parameters are shown in the plot below.
354
355Begin_Macro(source)
356{
357 //canvas only needed for the documentation
358 TCanvas* c1 = new TCanvas("c1","",600,400);
359 c1->SetFillStyle(1001);
360 c1->SetFillColor(kWhite);
361
362 //create different beta distributions
363 TF1* f1 = new TF1("f1","TMath::BetaDist(x,1,1)",0,1);
364 f1->SetLineColor(kBlue);
365 TF1* f2 = new TF1("f2","TMath::BetaDist(x,0.5,0.5)",0,1);
366 f2->SetLineColor(kRed);
367 TF1* f3 = new TF1("f3","TMath::BetaDist(x,1,5)",0,1);
368 f3->SetLineColor(kGreen+3);
369 f3->SetTitle("Beta distributions as priors;#epsilon;P(#epsilon)");
370 TF1* f4 = new TF1("f4","TMath::BetaDist(x,4,3)",0,1);
371 f4->SetLineColor(kViolet);
372
373 //add legend
374 TLegend* leg = new TLegend(0.25,0.5,0.85,0.89);
375 leg->SetFillColor(kWhite);
376 leg->SetFillStyle(1001);
377 leg->AddEntry(f1,"a=1, b=1","L");
378 leg->AddEntry(f2,"a=0.5, b=0.5","L");
379 leg->AddEntry(f3,"a=1, b=5","L");
380 leg->AddEntry(f4,"a=4, b=3","L");
381
382 f3->Draw();
383 f1->Draw("same");
384 f2->Draw("Same");
385 f4->Draw("same");
386 leg->Draw("same");
387}
388End_Macro
389
390
391\anchor EFF041
392### IV.1 Coverage probabilities for different methods
393The following pictures illustrate the actual coverage probability for the
394different values of the true efficiency and the total number of events when a
395confidence level of 95% is desired.
396
397\image html normal95.gif "Normal Approximation"
398
399
400\image html wilson95.gif "Wilson"
401
402
403\image html ac95.gif "Agresti Coull"
404
405
406\image html cp95.gif "Clopper Pearson"
407
408
409\image html uni95.gif "Bayesian with Uniform Prior"
410
411
412\image html jeffrey95.gif "Bayesian with Jeffrey Prior"
413
414The average (over all possible true efficiencies) coverage probability for
415different number of total events is shown in the next picture.
416
417\image html av_cov.png "Average Coverage"
418
419\anchor EFF05
420## V. Merging and combining TEfficiency objects
421In many applications, the efficiency should be calculated for an inhomogeneous
422sample in the sense that it contains events with different weights. In order
423to be able to determine the correct overall efficiency, it is necessary to
424use for each subsample (= all events with the same weight) a different
425TEfficiency object. After finishing your analysis you can then construct the
426overall efficiency with its uncertainty.
427
428This procedure has the advantage that you can change the weight of one
429subsample easily without rerunning the whole analysis. On the other hand, more
430effort is needed to handle several TEfficiency objects instead of one
431histogram. In the case of many different or even continuously distributed
432weights, this approach becomes cumbersome. One possibility to overcome this
433problem is the usage of binned weights.
434
435\anchor EFF05a
436### Example
437In particle physics weights arises from the fact that you want to
438normalise your results to a certain reference value. A very common formula for
439calculating weights is
440
441\f{eqnarray*}{
442 w &=& \frac{\sigma L}{N_{gen} \epsilon_{trig}} \
443 &-& \sigma ...\ cross\ section \
444 &-& L ...\ luminosity \
445 &-& N_{gen}\ ... number\ of\ generated\ events \
446 &-& \epsilon_{trig}\ ...\ (known)\ trigger\ efficiency \
447\f}
448
449The reason for different weights can therefore be:
450- different processes
451- other integrated luminosity
452- varying trigger efficiency
453- different sample sizes
454- ...
455- or even combination of them
456
457Depending on the actual meaning of different weights in your case, you
458should either merge or combine them to get the overall efficiency.
459
460\anchor EFF051
461### V.1 When should I use merging?
462If the weights are artificial and do not represent real alternative hypotheses,
463you should merge the different TEfficiency objects. That means especially for
464the Bayesian case that the prior probability should be the same for all merged
465TEfficiency objects. The merging can be done by invoking one of the following
466operations:
467- eff1.Add(eff2)
468- eff1 += eff2
469- eff1 = eff1 + eff2
470
471The result of the merging is stored in the TEfficiency object which is marked
472bold above. The contents of the internal histograms of both TEfficiency
473objects are added and a new weight is assigned. The statistic options are not
474changed.
475
476\f[
477 \frac{1}{w_{new}} = \frac{1}{w_{1}} + \frac{1}{w_{2}}
478\f]
479
480\anchor EFF05b
481### Example:
482If you use two samples with different numbers of generated events for the same
483process and you want to normalise both to the same integrated luminosity and
484trigger efficiency, the different weights then arise just from the fact that
485you have different numbers of events. The TEfficiency objects should be merged
486because the samples do not represent true alternatives. You expect the same
487result as if you would have a big sample with all events in it.
488
489\f[
490 w_{1} = \frac{\sigma L}{\epsilon N_{1}}, w_{2} = \frac{\sigma L}{\epsilon N_{2}} \Rightarrow w_{new} = \frac{\sigma L}{\epsilon (N_{1} + N_{2})} = \frac{1}{\frac{1}{w_{1}} + \frac{1}{w_{2}}}
491\f]
492
493\anchor EFF052
494### V.2 When should I use combining?
495You should combine TEfficiency objects whenever the weights represent
496alternatives processes for the efficiency. As the combination of two TEfficiency
497objects is not always consistent with the representation by two internal
498histograms, the result is not stored in a TEfficiency object but a TGraphAsymmErrors
499is returned which shows the estimated combined efficiency and its uncertainty
500for each bin.
501At the moment the combination method TEfficiency::Combine only supports a combination of 1-dimensional
502efficiencies in a Bayesian approach.
503
504
505For calculating the combined efficiency and its uncertainty for each bin only Bayesian statistics
506is used. No frequentists methods are presently supported for computing the combined efficiency and
507its confidence interval.
508In the case of the Bayesian statistics, a combined posterior is constructed taking into account the
509weight of each TEfficiency object. The same prior is used for all the TEfficiency objects.
510
511\f{eqnarray*}{
512 P_{comb}(\epsilon | {w_{i}}, {k_{i}} , {N_{i}}) = \frac{1}{norm} \prod_{i}{L(k_{i} | N_{i}, \epsilon)}^{w_{i}} \Pi( \epsilon )\
513L(k_{i} | N_{i}, \epsilon)\ is\ the\ likelihood\ function\ for\ the\ sample\ i\ (a\ Binomial\ distribution)\
514\Pi( \epsilon)\ is\ the\ prior,\ a\ beta\ distribution\ B(\epsilon, \alpha, \beta).\
515The\ resulting\ combined\ posterior\ is \
516P_{comb}(\epsilon |{w_{i}}; {k_{i}}; {N_{i}}) = B(\epsilon, \sum_{i}{ w_{i} k_{i}} + \alpha, \sum_{i}{ w_{i}(n_{i}-k_{i})}+\beta) \
517\hat{\varepsilon} = \int_{0}^{1} \epsilon \times P_{comb}(\epsilon | {k_{i}} , {N_{i}}) d\epsilon \
518confidence\ level = 1 - \alpha \
519\frac{\alpha}{2} = \int_{0}^{\epsilon_{low}} P_{comb}(\epsilon | {k_{i}} , {N_{i}}) d\epsilon ...\ defines\ lower\ boundary \
5201- \frac{\alpha}{2} = \int_{0}^{\epsilon_{up}} P_{comb}(\epsilon | {k_{i}} , {N_{i}}) d\epsilon ...\ defines\ upper\ boundary
521\f}
522
523
524\anchor EFF05c
525###Example:
526If you use cuts to select electrons which can originate from two different
527processes, you can determine the selection efficiency for each process. The
528overall selection efficiency is then the combined efficiency. The weights to be used in the
529combination should be the probability that an
530electron comes from the corresponding process.
531
532\f[
533p_{1} = \frac{\sigma_{1}}{\sigma_{1} + \sigma_{2}} = \frac{N_{1}w_{1}}{N_{1}w_{1} + N_{2}w_{2}}\
534p_{2} = \frac{\sigma_{2}}{\sigma_{1} + \sigma_{2}} = \frac{N_{2}w_{2}}{N_{1}w_{1} + N_{2}w_{2}}
535\f]
536
537\anchor EFF06
538## VI. Further operations
539
540\anchor EFF061
541### VI.1 Information about the internal histograms
542The methods TEfficiency::GetPassedHistogram and TEfficiency::GetTotalHistogram
543return a constant pointer to the internal histograms. They can be used to
544obtain information about the internal histograms (e.g., the binning, number of passed / total events in a bin, mean values...).
545One can obtain a clone of the internal histograms by calling TEfficiency::GetCopyPassedHisto or TEfficiency::GetCopyTotalHisto.
546The returned histograms are completely independent from the current
547TEfficiency object. By default, they are not attached to a directory to
548avoid the duplication of data and the user is responsible for deleting them.
549
550
551~~~~~~~~~~~~~~~{.cpp}
552//open a root file which contains a TEfficiency object
553TFile* pFile = new TFile("myfile.root","update");
554
555//get TEfficiency object with name "my_eff"
556TEfficiency* pEff = (TEfficiency*)pFile->Get("my_eff");
557
558//get clone of total histogram
559TH1* clone = pEff->GetCopyTotalHisto();
560
561//change clone...
562//save changes of clone directly
563clone->Write();
564//or append it to the current directory and write the file
565//clone->SetDirectory(gDirectory);
566//pFile->Write();
567
568//delete histogram object
569delete clone;
570clone = 0;
571~~~~~~~~~~~~~~~
572
573It is also possible to set the internal total or passed histogram by using the
574methods TEfficiency::SetPassedHistogram or TEfficiency::SetTotalHistogram.
575
576In order to ensure the validity of the TEfficiency object, the consistency of the
577new histogram and the stored histogram is checked. It might be
578impossible sometimes to change the histograms in a consistent way. Therefore one can force
579the replacement by passing the "f" option. Then the user has to ensure that the
580other internal histogram is replaced as well and that the TEfficiency object is
581in a valid state.
582
583\anchor EFF062
584### VI.2 Fitting
585The efficiency can be fitted using the TEfficiency::Fit function which internally uses
586the TBinomialEfficiencyFitter::Fit method.
587As this method is using a maximum-likelihood-fit, it is necessary to initialise
588the given fit function with reasonable start values.
589The resulting fit function is attached to the list of associated functions and
590will be drawn automatically during the next TEfficiency::Draw command.
591The list of associated function can be modified by using the pointer returned
592by TEfficiency::GetListOfFunctions.
593
594Begin_Macro(source)
595{
596 //canvas only needed for this documentation
597 TCanvas* c1 = new TCanvas("example","",600,400);
598 c1->SetFillStyle(1001);
599 c1->SetFillColor(kWhite);
600
601 //create one-dimensional TEfficiency object with fixed bin size
602 TEfficiency* pEff = new TEfficiency("eff","my efficiency;x;#epsilon",20,0,10);
603 TRandom3 rand3;
604
605 bool bPassed;
606 double x;
607 for (int i=0; i<10000; ++i) {
608 //simulate events with variable under investigation
609 x = rand3.Uniform(10);
610 //check selection: bPassed = DoesEventPassSelection(x)
611 bPassed = rand3.Rndm() < TMath::Gaus(x,5,4);
612 pEff->Fill(bPassed,x);
613 }
614
615 //create a function for fitting and do the fit
616 TF1* f1 = new TF1("f1","gaus",0,10);
617 f1->SetParameters(1,5,2);
618 pEff->Fit(f1);
619
620 //create a threshold function
621 TF1* f2 = new TF1("thres","0.8",0,10);
622 f2->SetLineColor(kRed);
623 //add it to the list of functions
624 //use add first because the parameters of the last function will be displayed
625 pEff->GetListOfFunctions()->AddFirst(f2);
626
627 pEff->Draw("AP");
628}
629End_Macro
630
631\anchor EFF063
632### VI.3 Draw a TEfficiency object
633A TEfficiency object can be drawn by calling the usual TEfficiency::Draw method.
634At the moment drawing is only supported for 1- and 2-dimensional TEfficiency objects.
635In the 1-dimensional case, you can use the same options as for the TGraphAsymmErrors::Draw
636method. For 2-dimensional TEfficiency objects, you can pass the same options as
637for a TH2::Draw object.
638
639\anchor EFF064
640### VI.4 TEfficiency object's axis customisation
641The axes of a TEfficiency object can be accessed and customised by calling the
642GetPaintedGraph method and then GetXaxis() or GetYaxis() and the corresponding TAxis
643methods.
644Note that in order to access the painted graph via GetPaintedGraph(), one should either
645call Paint or, better, gPad->Update().
646
647Begin_Macro(source)
648{
649 //canvas only needed for this documentation
650 TCanvas* c1 = new TCanvas("example","",600,400);
651 c1->SetFillStyle(1001);
652 c1->SetFillColor(kWhite);
653 c1->Divide(2,1);
654
655 //create one-dimensional TEfficiency object with fixed bin size
656 TEfficiency* pEff = new TEfficiency("eff","my efficiency;x;#epsilon",20,0,10);
657 TRandom3 rand3;
658
659 bool bPassed;
660 double x;
661 for(int i=0; i<10000; ++i)
662 {
663 //simulate events with variable under investigation
664 x = rand3.Uniform(10);
665 //check selection: bPassed = DoesEventPassSelection(x)
666 bPassed = rand3.Rndm() < TMath::Gaus(x,5,4);
667 pEff->Fill(bPassed,x);
668 }
669 c1->cd(1);
670 pEff->Draw("AP");
671 c1->cd(2);
672 pEff->Draw("AP");
673 gPad->Update();
674 pEff->GetPaintedGraph()->GetXaxis()->SetTitleSize(0.05);
675 pEff->GetPaintedGraph()->GetXaxis()->SetLabelFont(42);
676 pEff->GetPaintedGraph()->GetXaxis()->SetLabelSize(0.05);
677 pEff->GetPaintedGraph()->GetYaxis()->SetTitleOffset(0.85);
678 pEff->GetPaintedGraph()->GetYaxis()->SetTitleSize(0.05);
679 pEff->GetPaintedGraph()->GetYaxis()->SetLabelFont(42);
680 pEff->GetPaintedGraph()->GetYaxis()->SetLabelSize(0.05);
681 pEff->GetPaintedGraph()->GetXaxis()->SetRangeUser(3,7);
682}
683End_Macro
684
685*/
686
687////////////////////////////////////////////////////////////////////////////////
688/// Default constructor
689///
690/// Should not be used explicitly
691
693fBeta_alpha(kDefBetaAlpha),
694fBeta_beta(kDefBetaBeta),
695fBoundary(nullptr),
696fConfLevel(kDefConfLevel),
697fDirectory(nullptr),
698fFunctions(nullptr),
699fPaintGraph(nullptr),
700fPaintHisto(nullptr),
701fPassedHistogram(nullptr),
702fTotalHistogram(nullptr),
703fWeight(kDefWeight)
704{
706
707 // create 2 dummy histograms
708 fPassedHistogram = new TH1F("h_passed","passed",10,0,10);
709 fTotalHistogram = new TH1F("h_total","total",10,0,10);
710}
711
712////////////////////////////////////////////////////////////////////////////////
713/// Constructor using two existing histograms as input
714///
715///Input: passed - contains the events fulfilling some criteria
716/// total - contains all investigated events
717///
718///Notes: - both histograms have to fulfill the conditions of CheckConsistency
719/// - dimension of the resulting efficiency object depends
720/// on the dimension of the given histograms
721/// - Clones of both histograms are stored internally
722/// - The function SetName(total.GetName() + "_clone") is called to set
723/// the names of the new object and the internal histograms..
724/// - The created TEfficiency object is NOT appended to a directory. It
725/// will not be written to disk during the next TFile::Write() command
726/// in order to prevent duplication of data. If you want to save this
727/// TEfficiency object anyway, you can either append it to a
728/// directory by calling SetDirectory(TDirectory*) or write it
729/// explicitly to disk by calling Write().
730
732fBeta_alpha(kDefBetaAlpha),
733fBeta_beta(kDefBetaBeta),
734fConfLevel(kDefConfLevel),
735fDirectory(nullptr),
736fFunctions(nullptr),
737fPaintGraph(nullptr),
738fPaintHisto(nullptr),
739fWeight(kDefWeight)
740{
741 //check consistency of histograms
743 // do not add cloned histograms to gDirectory
744 {
745 TDirectory::TContext ctx(nullptr);
746 fTotalHistogram = (TH1*)total.Clone();
747 fPassedHistogram = (TH1*)passed.Clone();
748 }
749
750 TString newName = total.GetName();
751 newName += TString("_clone");
753
754 // are the histograms filled with weights?
756 {
757 Info("TEfficiency","given histograms are filled with weights");
759 }
760 }
761 else {
762 Error("TEfficiency(const TH1&,const TH1&)","histograms are not consistent -> results are useless");
763 Warning("TEfficiency(const TH1&,const TH1&)","using two empty TH1D('h1','h1',10,0,10)");
764
765 // do not add new created histograms to gDirectory
766 TDirectory::TContext ctx(nullptr);
767 fTotalHistogram = new TH1D("h1_total","h1 (total)",10,0,10);
768 fPassedHistogram = new TH1D("h1_passed","h1 (passed)",10,0,10);
769 }
770
771 SetBit(kPosteriorMode,false);
773
775 SetDirectory(nullptr);
776}
777
778////////////////////////////////////////////////////////////////////////////////
779/// Create 1-dimensional TEfficiency object with variable bin size.
780///
781/// Constructor creates two new and empty histograms with a given binning
782///
783/// Input:
784///
785/// - `name`: the common part of the name for both histograms (no blanks)
786/// fTotalHistogram has name: name + "_total"
787/// fPassedHistogram has name: name + "_passed"
788/// - `title`: the common part of the title for both histogram
789/// fTotalHistogram has title: title + " (total)"
790/// fPassedHistogram has title: title + " (passed)"
791/// It is possible to label the axis by passing a title with
792/// the following format: "title;xlabel;ylabel".
793/// - `nbins`: number of bins on the x-axis
794/// - `xbins`: array of length (nbins + 1) with low-edges for each bin
795/// xbins[nbinsx] ... lower edge for overflow bin
796
797TEfficiency::TEfficiency(const char* name,const char* title,Int_t nbins,
798 const Double_t* xbins):
799fBeta_alpha(kDefBetaAlpha),
800fBeta_beta(kDefBetaBeta),
801fConfLevel(kDefConfLevel),
802fDirectory(nullptr),
803fFunctions(nullptr),
804fPaintGraph(nullptr),
805fPaintHisto(nullptr),
806fWeight(kDefWeight)
807{
808 // do not add new created histograms to gDirectory
809 {
810 // use separate scope for TContext
811 TDirectory::TContext ctx(nullptr);
812 fTotalHistogram = new TH1D("total","total",nbins,xbins);
813 fPassedHistogram = new TH1D("passed","passed",nbins,xbins);
814 }
815
816 Build(name,title);
817}
818
819////////////////////////////////////////////////////////////////////////////////
820/// Create 1-dimensional TEfficiency object with fixed bins size.
821///
822/// Constructor creates two new and empty histograms with a fixed binning.
823///
824/// Input:
825///
826/// - `name`: the common part of the name for both histograms(no blanks)
827/// fTotalHistogram has name: name + "_total"
828/// fPassedHistogram has name: name + "_passed"
829/// - `title`: the common part of the title for both histogram
830/// fTotalHistogram has title: title + " (total)"
831/// fPassedHistogram has title: title + " (passed)"
832/// It is possible to label the axis by passing a title with
833/// the following format: "title;xlabel;ylabel".
834/// - `nbinsx`: number of bins on the x-axis
835/// - `xlow`: lower edge of first bin
836/// - `xup`: upper edge of last bin
837
838TEfficiency::TEfficiency(const char* name,const char* title,Int_t nbinsx,
839 Double_t xlow,Double_t xup):
840fBeta_alpha(kDefBetaAlpha),
841fBeta_beta(kDefBetaBeta),
842fConfLevel(kDefConfLevel),
843fDirectory(nullptr),
844fFunctions(nullptr),
845fPaintGraph(nullptr),
846fPaintHisto(nullptr),
847fWeight(kDefWeight)
848{
849 // do not add new created histograms to gDirectory
850 {
851 TDirectory::TContext ctx(nullptr);
852 fTotalHistogram = new TH1D("total","total",nbinsx,xlow,xup);
853 fPassedHistogram = new TH1D("passed","passed",nbinsx,xlow,xup);
854 }
855 Build(name,title);
856}
857
858////////////////////////////////////////////////////////////////////////////////
859/// Create 2-dimensional TEfficiency object with fixed bin size.
860///
861/// Constructor creates two new and empty histograms with a fixed binning.
862///
863/// Input:
864///
865/// - `name`: the common part of the name for both histograms(no blanks)
866/// fTotalHistogram has name: name + "_total"
867/// fPassedHistogram has name: name + "_passed"
868/// - `title`: the common part of the title for both histogram
869/// fTotalHistogram has title: title + " (total)"
870/// fPassedHistogram has title: title + " (passed)"
871/// It is possible to label the axis by passing a title with
872/// the following format: "title;xlabel;ylabel;zlabel".
873/// - `nbinsx`: number of bins on the x-axis
874/// - `xlow`: lower edge of first x-bin
875/// - `xup`: upper edge of last x-bin
876/// - `nbinsy`: number of bins on the y-axis
877/// - `ylow`: lower edge of first y-bin
878/// - `yup`: upper edge of last y-bin
879
880TEfficiency::TEfficiency(const char* name,const char* title,Int_t nbinsx,
881 Double_t xlow,Double_t xup,Int_t nbinsy,
882 Double_t ylow,Double_t yup):
883fBeta_alpha(kDefBetaAlpha),
884fBeta_beta(kDefBetaBeta),
885fConfLevel(kDefConfLevel),
886fDirectory(nullptr),
887fFunctions(nullptr),
888fPaintGraph(nullptr),
889fPaintHisto(nullptr),
890fWeight(kDefWeight)
891{
892 // do not add new created histograms to gDirectory
893 {
894 TDirectory::TContext ctx(nullptr);
895 fTotalHistogram = new TH2D("total","total",nbinsx,xlow,xup,nbinsy,ylow,yup);
896 fPassedHistogram = new TH2D("passed","passed",nbinsx,xlow,xup,nbinsy,ylow,yup);
897 }
898 Build(name,title);
899}
900
901////////////////////////////////////////////////////////////////////////////////
902/// Create 2-dimensional TEfficiency object with variable bin size.
903///
904/// Constructor creates two new and empty histograms with a given binning.
905///
906/// Input:
907///
908/// - `name`: the common part of the name for both histograms(no blanks)
909/// fTotalHistogram has name: name + "_total"
910/// fPassedHistogram has name: name + "_passed"
911/// - `title`: the common part of the title for both histogram
912/// fTotalHistogram has title: title + " (total)"
913/// fPassedHistogram has title: title + " (passed)"
914/// It is possible to label the axis by passing a title with
915/// the following format: "title;xlabel;ylabel;zlabel".
916/// - `nbinsx`: number of bins on the x-axis
917/// - `xbins`: array of length (nbins + 1) with low-edges for each bin
918/// xbins[nbinsx] ... lower edge for overflow x-bin
919/// - `nbinsy`: number of bins on the y-axis
920/// - `ybins`: array of length (nbins + 1) with low-edges for each bin
921/// ybins[nbinsy] ... lower edge for overflow y-bin
922
923TEfficiency::TEfficiency(const char* name,const char* title,Int_t nbinsx,
924 const Double_t* xbins,Int_t nbinsy,
925 const Double_t* ybins):
926fBeta_alpha(kDefBetaAlpha),
927fBeta_beta(kDefBetaBeta),
928fConfLevel(kDefConfLevel),
929fDirectory(nullptr),
930fFunctions(nullptr),
931fPaintGraph(nullptr),
932fPaintHisto(nullptr),
933fWeight(kDefWeight)
934{
935 // do not add new created histograms to gDirectory
936 {
937 TDirectory::TContext ctx(nullptr);
938 fTotalHistogram = new TH2D("total","total",nbinsx,xbins,nbinsy,ybins);
939 fPassedHistogram = new TH2D("passed","passed",nbinsx,xbins,nbinsy,ybins);
940 }
941 Build(name,title);
942}
943
944////////////////////////////////////////////////////////////////////////////////
945/// Create 3-dimensional TEfficiency object with fixed bin size.
946///
947/// Constructor creates two new and empty histograms with a fixed binning.
948///
949/// Input:
950///
951/// - `name`: the common part of the name for both histograms(no blanks)
952/// fTotalHistogram has name: name + "_total"
953/// fPassedHistogram has name: name + "_passed"
954/// - `title`: the common part of the title for both histogram
955/// fTotalHistogram has title: title + " (total)"
956/// fPassedHistogram has title: title + " (passed)"
957/// It is possible to label the axis by passing a title with
958/// the following format: "title;xlabel;ylabel;zlabel".
959/// - `nbinsx`: number of bins on the x-axis
960/// - `xlow`: lower edge of first x-bin
961/// - `xup`: upper edge of last x-bin
962/// - `nbinsy`: number of bins on the y-axis
963/// - `ylow`: lower edge of first y-bin
964/// - `yup`: upper edge of last y-bin
965/// - `nbinsz`: number of bins on the z-axis
966/// - `zlow`: lower edge of first z-bin
967/// - `zup`: upper edge of last z-bin
968
969TEfficiency::TEfficiency(const char* name,const char* title,Int_t nbinsx,
970 Double_t xlow,Double_t xup,Int_t nbinsy,
971 Double_t ylow,Double_t yup,Int_t nbinsz,
973fBeta_alpha(kDefBetaAlpha),
974fBeta_beta(kDefBetaBeta),
975fConfLevel(kDefConfLevel),
976fDirectory(nullptr),
977fFunctions(nullptr),
978fPaintGraph(nullptr),
979fPaintHisto(nullptr),
980fWeight(kDefWeight)
981{
982 // do not add new created histograms to gDirectory
983 {
984 TDirectory::TContext ctx(nullptr);
985 fTotalHistogram = new TH3D("total","total",nbinsx,xlow,xup,nbinsy,ylow,yup,nbinsz,zlow,zup);
986 fPassedHistogram = new TH3D("passed","passed",nbinsx,xlow,xup,nbinsy,ylow,yup,nbinsz,zlow,zup);
987 }
988 Build(name,title);
989}
990
991////////////////////////////////////////////////////////////////////////////////
992/// Create 3-dimensional TEfficiency object with variable bin size.
993///
994/// Constructor creates two new and empty histograms with a given binning.
995///
996/// Input:
997///
998/// - `name`: the common part of the name for both histograms(no blanks)
999/// fTotalHistogram has name: name + "_total"
1000/// fPassedHistogram has name: name + "_passed"
1001/// - `title`: the common part of the title for both histogram
1002/// fTotalHistogram has title: title + " (total)"
1003/// fPassedHistogram has title: title + " (passed)"
1004/// It is possible to label the axis by passing a title with
1005/// the following format: "title;xlabel;ylabel;zlabel".
1006/// - `nbinsx`: number of bins on the x-axis
1007/// - `xbins`: array of length (nbins + 1) with low-edges for each bin
1008/// xbins[nbinsx] ... lower edge for overflow x-bin
1009/// - `nbinsy`: number of bins on the y-axis
1010/// - `ybins`: array of length (nbins + 1) with low-edges for each bin
1011/// xbins[nbinsx] ... lower edge for overflow y-bin
1012/// - `nbinsz`: number of bins on the z-axis
1013/// - `zbins`: array of length (nbins + 1) with low-edges for each bin
1014/// xbins[nbinsx] ... lower edge for overflow z-bin
1015
1016TEfficiency::TEfficiency(const char* name,const char* title,Int_t nbinsx,
1017 const Double_t* xbins,Int_t nbinsy,
1018 const Double_t* ybins,Int_t nbinsz,
1019 const Double_t* zbins):
1020fBeta_alpha(kDefBetaAlpha),
1021fBeta_beta(kDefBetaBeta),
1022fConfLevel(kDefConfLevel),
1023fDirectory(nullptr),
1024fFunctions(nullptr),
1025fPaintGraph(nullptr),
1026fPaintHisto(nullptr),
1027fWeight(kDefWeight)
1028{
1029 // do not add new created histograms to gDirectory
1030 {
1031 TDirectory::TContext ctx(nullptr);
1032 fTotalHistogram = new TH3D("total","total",nbinsx,xbins,nbinsy,ybins,nbinsz,zbins);
1033 fPassedHistogram = new TH3D("passed","passed",nbinsx,xbins,nbinsy,ybins,nbinsz,zbins);
1034 }
1035 Build(name,title);
1036}
1037
1038////////////////////////////////////////////////////////////////////////////////
1039/// Copy constructor.
1040///
1041///The list of associated objects (e.g. fitted functions) is not copied.
1042///
1043///Note:
1044///
1045/// - SetName(rEff.GetName() + "_copy") is called to set the names of the
1046/// object and the histograms.
1047/// - The titles are set by calling SetTitle("[copy] " + rEff.GetTitle()).
1048/// - The copied TEfficiency object is NOT appended to a directory. It
1049/// will not be written to disk during the next TFile::Write() command
1050/// in order to prevent duplication of data. If you want to save this
1051/// TEfficiency object anyway, you can either append it to a directory
1052/// by calling SetDirectory(TDirectory*) or write it explicitly to disk
1053/// by calling Write().
1054
1056 TNamed(),
1057 TAttLine(),
1058 TAttFill(),
1059 TAttMarker(),
1060 fBeta_alpha(rEff.fBeta_alpha),
1061 fBeta_beta(rEff.fBeta_beta),
1062 fBeta_bin_params(rEff.fBeta_bin_params),
1063 fConfLevel(rEff.fConfLevel),
1064 fDirectory(nullptr),
1065 fFunctions(nullptr),
1066 fPaintGraph(nullptr),
1067 fPaintHisto(nullptr),
1068 fWeight(rEff.fWeight)
1069{
1070 // copy TObject bits
1071 rEff.TObject::Copy(*this);
1072
1073 // do not add cloned histograms to gDirectory
1074 {
1075 TDirectory::TContext ctx(nullptr);
1076 fTotalHistogram = (TH1*)((rEff.fTotalHistogram)->Clone());
1077 fPassedHistogram = (TH1*)((rEff.fPassedHistogram)->Clone());
1078 }
1079
1080 TString name = rEff.GetName();
1081 name += "_copy";
1082 SetName(name);
1083 TString title = "[copy] ";
1084 title += rEff.GetTitle();
1085 SetTitle(title);
1086
1087 SetStatisticOption(rEff.GetStatisticOption());
1088
1089 SetDirectory(nullptr);
1090
1091 //copy style
1092 rEff.TAttLine::Copy(*this);
1093 rEff.TAttFill::Copy(*this);
1094 rEff.TAttMarker::Copy(*this);
1095}
1096
1097////////////////////////////////////////////////////////////////////////////////
1098///default destructor
1099
1101{
1102 //delete all function in fFunctions
1103 // use same logic as in TH1 destructor
1104 // (see TH1::~TH1 code in TH1.cxx)
1105 if(fFunctions) {
1107 TObject* obj = nullptr;
1108 while ((obj = fFunctions->First())) {
1109 while(fFunctions->Remove(obj)) { }
1111 break;
1112 }
1113 delete obj;
1114 obj = nullptr;
1115 }
1116 delete fFunctions;
1117 fFunctions = nullptr;
1118 }
1119
1120 if(fDirectory)
1121 fDirectory->Remove(this);
1122
1123 delete fTotalHistogram;
1124 delete fPassedHistogram;
1125 delete fPaintGraph;
1126 delete fPaintHisto;
1127}
1128
1129////////////////////////////////////////////////////////////////////////////////
1130/**
1131 Calculates the boundaries for the frequentist Agresti-Coull interval
1132
1133 \param total number of total events
1134 \param passed 0 <= number of passed events <= total
1135 \param level confidence level
1136 \param bUpper true - upper boundary is returned
1137 false - lower boundary is returned
1138
1139
1140 \f{eqnarray*}{
1141 \alpha &=& 1 - \frac{level}{2} \
1142 \kappa &=& \Phi^{-1}(1 - \alpha,1)\ ... normal\ quantile\ function\
1143 mode &=& \frac{passed + \frac{\kappa^{2}}{2}}{total + \kappa^{2}}\
1144 \Delta &=& \kappa * \sqrt{\frac{mode * (1 - mode)}{total + \kappa^{2}}}\
1145 return &=& max(0,mode - \Delta)\ or\ min(1,mode + \Delta)
1146 \f}
1147
1148*/
1149
1151{
1152 Double_t alpha = (1.0 - level)/2;
1153 Double_t kappa = ROOT::Math::normal_quantile(1 - alpha,1);
1154
1155 Double_t mode = (passed + 0.5 * kappa * kappa) / (total + kappa * kappa);
1156 Double_t delta = kappa * std::sqrt(mode * (1 - mode) / (total + kappa * kappa));
1157
1158 if(bUpper)
1159 return ((mode + delta) > 1) ? 1.0 : (mode + delta);
1160 else
1161 return ((mode - delta) < 0) ? 0.0 : (mode - delta);
1162}
1163
1164////////////////////////////////////////////////////////////////////////////////
1165/// Calculates the boundaries for the frequentist Feldman-Cousins interval
1166///
1167/// \param total number of total events
1168/// \param passed 0 <= number of passed events <= total
1169/// \param level confidence level
1170/// \param bUpper: true - upper boundary is returned
1171/// false - lower boundary is returned
1172
1174{
1175 Double_t lower = 0;
1176 Double_t upper = 1;
1178 ::Error("FeldmanCousins","Error running FC method - return 0 or 1");
1179 }
1180 return (bUpper) ? upper : lower;
1181}
1182
1183////////////////////////////////////////////////////////////////////////////////
1184/// Calculates the interval boundaries using the frequentist methods of Feldman-Cousins
1185///
1186/// \param[in] total number of total events
1187/// \param[in] passed 0 <= number of passed events <= total
1188/// \param[in] level confidence level
1189/// \param[out] lower lower boundary returned on exit
1190/// \param[out] upper lower boundary returned on exit
1191/// \return a flag with the status of the calculation
1192///
1193/// Calculation:
1194///
1195/// The Feldman-Cousins is a frequentist method where the interval is estimated using a Neyman construction where the ordering
1196/// is based on the likelihood ratio:
1197/// \f[
1198/// LR = \frac{Binomial(k | N, \epsilon)}{Binomial(k | N, \hat{\epsilon} ) }
1199/// \f]
1200/// See G. J. Feldman and R. D. Cousins, Phys. Rev. D57 (1998) 3873
1201/// and R. D. Cousins, K. E. Hymes, J. Tucker, Nuclear Instruments and Methods in Physics Research A 612 (2010) 388
1202///
1203/// Implemented using classes developed by Jordan Tucker and Luca Lista
1204/// See File hist/hist/src/TEfficiencyHelper.h
1205
1207{
1209 double alpha = 1.-level;
1210 fc.Init(alpha);
1211 fc.Calculate(passed, total);
1212 lower = fc.Lower();
1213 upper = fc.Upper();
1214 return true;
1215}
1216
1217////////////////////////////////////////////////////////////////////////////////
1218/// Calculates the boundaries using the mid-P binomial
1219/// interval (Lancaster method) from B. Cousing and J. Tucker.
1220/// See http://arxiv.org/abs/0905.3831 for a description and references for the method
1221///
1222/// Modify equal_tailed to get the kind of interval you want.
1223/// Can also be converted to interval on ratio of poisson means X/Y by the substitutions
1224/// ~~~ {.cpp}
1225/// X = passed
1226/// total = X + Y
1227/// lower_poisson = lower/(1 - lower)
1228/// upper_poisson = upper/(1 - upper)
1229/// ~~~
1230
1232{
1233 const double alpha = 1. - level;
1234 const bool equal_tailed = true; // change if you don;t want equal tailed interval
1235 const double alpha_min = equal_tailed ? alpha/2 : alpha;
1236 const double tol = 1e-9; // tolerance
1237 double pmin = 0;
1238 double pmax = 0;
1239 double p = 0;
1240
1241 pmin = 0; pmax = 1;
1242
1243
1244 // treat special case for 0<passed<1
1245 // do a linear interpolation of the upper limit values
1246 if ( passed > 0 && passed < 1) {
1247 double p0 = MidPInterval(total,0.0,level,bUpper);
1248 double p1 = MidPInterval(total,1.0,level,bUpper);
1249 p = (p1 - p0) * passed + p0;
1250 return p;
1251 }
1252
1253 while (std::abs(pmax - pmin) > tol) {
1254 p = (pmin + pmax)/2;
1255 //double v = 0.5 * ROOT::Math::binomial_pdf(int(passed), p, int(total));
1256 // make it work for non integer using the binomial - beta relationship
1257 double v = 0.5 * ROOT::Math::beta_pdf(p, passed+1., total-passed+1)/(total+1);
1258 //if (passed > 0) v += ROOT::Math::binomial_cdf(int(passed - 1), p, int(total));
1259 // compute the binomial cdf at passed -1
1260 if ( (passed-1) >= 0) v += ROOT::Math::beta_cdf_c(p, passed, total-passed+1);
1261
1262 double vmin = (bUpper) ? alpha_min : 1.- alpha_min;
1263 if (v > vmin)
1264 pmin = p;
1265 else
1266 pmax = p;
1267 }
1268
1269 return p;
1270}
1271
1272
1273////////////////////////////////////////////////////////////////////////////////
1274/**
1275Calculates the boundaries for a Bayesian confidence interval (shortest or central
1276interval depending on the option) as explained in D. Casadei, Estimating the selection efficiency,
12772012 JINST 7 P08021, https://doi.org/10.1088/1748-0221/7/08/P08021 (https://arxiv.org/abs/0908.0130).
1278
1279
1280\param[in] total number of total events
1281\param[in] passed 0 <= number of passed events <= total
1282\param[in] level confidence level
1283\param[in] alpha shape parameter > 0 for the prior distribution (fBeta_alpha)
1284\param[in] beta shape parameter > 0 for the prior distribution (fBeta_beta)
1285\param[in] bUpper
1286 - true - upper boundary is returned
1287 - false - lower boundary is returned
1288\param[in] bShortest ??
1289
1290Note: In the case central confidence interval is calculated.
1291 when passed = 0 (or passed = total) the lower (or upper)
1292 interval values will be larger than 0 (or smaller than 1).
1293
1294Calculation:
1295
1296The posterior probability in bayesian statistics is given by:
1297\f[
1298 P(\varepsilon |k,N) \propto L(\varepsilon|k,N) \times Prior(\varepsilon)
1299\f]
1300As an efficiency can be interpreted as probability of a positive outcome of
1301a Bernoullli trial the likelihood function is given by the binomial
1302distribution:
1303\f[
1304 L(\varepsilon|k,N) = Binomial(N,k) \varepsilon ^{k} (1 - \varepsilon)^{N-k}
1305\f]
1306At the moment only beta distributions are supported as prior probabilities
1307of the efficiency (\f$ B(\alpha,\beta)\f$ is the beta function):
1308\f[
1309 Prior(\varepsilon) = \frac{1}{B(\alpha,\beta)} \varepsilon ^{\alpha - 1} (1 - \varepsilon)^{\beta - 1}
1310\f]
1311The posterior probability is therefore again given by a beta distribution:
1312\f[
1313 P(\varepsilon |k,N) \propto \varepsilon ^{k + \alpha - 1} (1 - \varepsilon)^{N - k + \beta - 1}
1314\f]
1315In case of central intervals
1316the lower boundary for the equal-tailed confidence interval is given by the
1317inverse cumulative (= quantile) function for the quantile \f$ \frac{1 - level}{2} \f$.
1318The upper boundary for the equal-tailed confidence interval is given by the
1319inverse cumulative (= quantile) function for the quantile \f$ \frac{1 + level}{2} \f$.
1320Hence it is the solution \f$ \varepsilon \f$ of the following equation:
1321\f[
1322 I_{\varepsilon}(k + \alpha,N - k + \beta) = \frac{1}{norm} \int_{0}^{\varepsilon} dt t^{k + \alpha - 1} (1 - t)^{N - k + \beta - 1} = \frac{1 \pm level}{2}
1323\f]
1324In the case of shortest interval the minimum interval around the mode is found by minimizing the length of all intervals width the
1325given probability content. See TEfficiency::BetaShortestInterval
1326*/
1327
1329{
1330 Double_t a = double(passed)+alpha;
1331 Double_t b = double(total-passed)+beta;
1332
1333 if (bShortest) {
1334 double lower = 0;
1335 double upper = 1;
1337 return (bUpper) ? upper : lower;
1338 }
1339 else
1340 return BetaCentralInterval(level, a, b, bUpper);
1341}
1342
1343////////////////////////////////////////////////////////////////////////////////
1344/// Calculates the boundaries for a central confidence interval for a Beta distribution
1345///
1346/// \param[in] level confidence level
1347/// \param[in] a parameter > 0 for the beta distribution (for a posterior is passed + prior_alpha
1348/// \param[in] b parameter > 0 for the beta distribution (for a posterior is (total-passed) + prior_beta
1349/// \param[in] bUpper true - upper boundary is returned
1350/// false - lower boundary is returned
1351
1353{
1354 if(bUpper) {
1355 if((a > 0) && (b > 0))
1356 return ROOT::Math::beta_quantile((1+level)/2,a,b);
1357 else {
1358 gROOT->Error("TEfficiency::BayesianCentral","Invalid input parameters - return 1");
1359 return 1;
1360 }
1361 }
1362 else {
1363 if((a > 0) && (b > 0))
1364 return ROOT::Math::beta_quantile((1-level)/2,a,b);
1365 else {
1366 gROOT->Error("TEfficiency::BayesianCentral","Invalid input parameters - return 0");
1367 return 0;
1368 }
1369 }
1370}
1371
1374 fCL(level), fAlpha(alpha), fBeta(beta)
1375 {}
1376
1378 // max allowed value of lower given the interval size
1380 }
1381
1383 // return length of interval
1385 Double_t pup = plow + fCL;
1387 return upper-lower;
1388 }
1389 Double_t fCL; // interval size (confidence level)
1390 Double_t fAlpha; // beta distribution alpha parameter
1391 Double_t fBeta; // beta distribution beta parameter
1392
1393};
1394
1395////////////////////////////////////////////////////////////////////////////////
1396/// Calculates the boundaries for a shortest confidence interval for a Beta distribution
1397///
1398/// \param[in] level confidence level
1399/// \param[in] a parameter > 0 for the beta distribution (for a posterior is passed + prior_alpha
1400/// \param[in] b parameter > 0 for the beta distribution (for a posterior is (total-passed) + prior_beta
1401/// \param[out] upper upper boundary is returned
1402/// \param[out] lower lower boundary is returned
1403///
1404/// The lower/upper boundary are then obtained by finding the shortest interval of the beta distribution
1405/// contained the desired probability level.
1406/// The length of all possible intervals is minimized in order to find the shortest one
1407
1409{
1410 if (a <= 0 || b <= 0) {
1411 lower = 0; upper = 1;
1412 gROOT->Error("TEfficiency::BayesianShortest","Invalid input parameters - return [0,1]");
1413 return kFALSE;
1414 }
1415
1416 // treat here special cases when mode == 0 or 1
1417 double mode = BetaMode(a,b);
1418 if (mode == 0.0) {
1419 lower = 0;
1421 return kTRUE;
1422 }
1423 if (mode == 1.0) {
1425 upper = 1.0;
1426 return kTRUE;
1427 }
1428 // special case when the shortest interval is undefined return the central interval
1429 // can happen for a posterior when passed=total=0
1430 //
1431 if ( a==b && a<=1.0) {
1434 return kTRUE;
1435 }
1436
1437 // for the other case perform a minimization
1438 // make a function of the length of the posterior interval as a function of lower bound
1440 // minimize the interval length
1443 minim.SetFunction(func, 0, intervalLength.LowerMax() );
1444 minim.SetNpx(2); // no need to bracket with many iterations. Just do few times to estimate some better points
1445 bool ret = minim.Minimize(100, 1.E-10,1.E-10);
1446 if (!ret) {
1447 gROOT->Error("TEfficiency::BayesianShortes","Error finding the shortest interval");
1448 return kFALSE;
1449 }
1450 lower = minim.XMinimum();
1451 upper = lower + minim.FValMinimum();
1452 return kTRUE;
1453}
1454
1455////////////////////////////////////////////////////////////////////////////////
1456/// Compute the mean (average) of the beta distribution
1457///
1458/// \param[in] a parameter > 0 for the beta distribution (for a posterior is passed + prior_alpha
1459/// \param[in] b parameter > 0 for the beta distribution (for a posterior is (total-passed) + prior_beta
1460///
1461
1463{
1464 if (a <= 0 || b <= 0 ) {
1465 gROOT->Error("TEfficiency::BayesianMean","Invalid input parameters - return 0");
1466 return 0;
1467 }
1468
1469 Double_t mean = a / (a + b);
1470 return mean;
1471}
1472
1473////////////////////////////////////////////////////////////////////////////////
1474/// Compute the mode of the beta distribution
1475///
1476/// \param[in] a parameter > 0 for the beta distribution (for a posterior is passed + prior_alpha
1477/// \param[in] b parameter > 0 for the beta distribution (for a posterior is (total-passed) + prior_beta
1478///
1479/// note the mode is defined for a Beta(a,b) only if (a,b)>1 (a = passed+alpha; b = total-passed+beta)
1480/// return then the following in case (a,b) < 1:
1481/// - if (a==b) return 0.5 (it is really undefined)
1482/// - if (a < b) return 0;
1483/// - if (a > b) return 1;
1484
1486{
1487 if (a <= 0 || b <= 0 ) {
1488 gROOT->Error("TEfficiency::BayesianMode","Invalid input parameters - return 0");
1489 return 0;
1490 }
1491 if ( a <= 1 || b <= 1) {
1492 if ( a < b) return 0;
1493 if ( a > b) return 1;
1494 if (a == b) return 0.5; // cannot do otherwise
1495 }
1496
1497 // since a and b are > 1 here denominator cannot be 0 or < 0
1498 Double_t mode = (a - 1.0) / (a + b -2.0);
1499 return mode;
1500}
1501////////////////////////////////////////////////////////////////////////////////
1502/// Building standard data structure of a TEfficiency object
1503///
1504/// Notes:
1505/// - calls: SetName(name), SetTitle(title)
1506/// - set the statistic option to the default (kFCP)
1507/// - appends this object to the current directory SetDirectory(gDirectory)
1508
1509void TEfficiency::Build(const char* name,const char* title)
1510{
1511 SetName(name);
1512 SetTitle(title);
1513
1516
1517 SetBit(kPosteriorMode,false);
1519 SetBit(kUseWeights,false);
1520
1521 //set normalisation factors to 0, otherwise the += may not work properly
1524}
1525
1526////////////////////////////////////////////////////////////////////////////////
1527/// Checks binning for each axis
1528///
1529/// It is assumed that the passed histograms have the same dimension.
1530
1532{
1533
1534 const TAxis* ax1 = nullptr;
1535 const TAxis* ax2 = nullptr;
1536
1537 //check binning along axis
1538 for(Int_t j = 0; j < pass.GetDimension(); ++j) {
1539 switch(j) {
1540 case 0:
1541 ax1 = pass.GetXaxis();
1542 ax2 = total.GetXaxis();
1543 break;
1544 case 1:
1545 ax1 = pass.GetYaxis();
1546 ax2 = total.GetYaxis();
1547 break;
1548 case 2:
1549 ax1 = pass.GetZaxis();
1550 ax2 = total.GetZaxis();
1551 break;
1552 }
1553
1554 if(ax1->GetNbins() != ax2->GetNbins()) {
1555 gROOT->Info("TEfficiency::CheckBinning","Histograms are not consistent: they have different number of bins");
1556 return false;
1557 }
1558
1559 for(Int_t i = 1; i <= ax1->GetNbins() + 1; ++i)
1560 if(!TMath::AreEqualRel(ax1->GetBinLowEdge(i), ax2->GetBinLowEdge(i), 1.E-15)) {
1561 gROOT->Info("TEfficiency::CheckBinning","Histograms are not consistent: they have different bin edges");
1562 return false;
1563 }
1564
1565
1566 }
1567
1568 return true;
1569}
1570
1571////////////////////////////////////////////////////////////////////////////////
1572/// Checks the consistence of the given histograms
1573///
1574/// The histograms are considered as consistent if:
1575/// - both have the same dimension
1576/// - both have the same binning
1577/// - pass.GetBinContent(i) <= total.GetBinContent(i) for each bin i
1578///
1579
1581{
1582 if(pass.GetDimension() != total.GetDimension()) {
1583 gROOT->Error("TEfficiency::CheckConsistency","passed TEfficiency objects have different dimensions");
1584 return false;
1585 }
1586
1587 if(!CheckBinning(pass,total)) {
1588 gROOT->Error("TEfficiency::CheckConsistency","passed TEfficiency objects have different binning");
1589 return false;
1590 }
1591
1592 if(!CheckEntries(pass,total)) {
1593 gROOT->Error("TEfficiency::CheckConsistency","passed TEfficiency objects do not have consistent bin contents");
1594 return false;
1595 }
1596
1597 return true;
1598}
1599
1600////////////////////////////////////////////////////////////////////////////////
1601/// Checks whether bin contents are compatible with binomial statistics
1602///
1603/// The following inequality has to be valid for each bin i:
1604/// total.GetBinContent(i) >= pass.GetBinContent(i)
1605///
1606///
1607///
1608/// Note:
1609///
1610/// - It is assumed that both histograms have the same dimension and binning.
1611
1613{
1614
1615 //check: pass <= total
1616 Int_t nbinsx, nbinsy, nbinsz, nbins;
1617
1618 nbinsx = pass.GetNbinsX();
1619 nbinsy = pass.GetNbinsY();
1620 nbinsz = pass.GetNbinsZ();
1621
1622 switch(pass.GetDimension()) {
1623 case 1: nbins = nbinsx + 2; break;
1624 case 2: nbins = (nbinsx + 2) * (nbinsy + 2); break;
1625 case 3: nbins = (nbinsx + 2) * (nbinsy + 2) * (nbinsz + 2); break;
1626 default: nbins = 0;
1627 }
1628
1629 for(Int_t i = 0; i < nbins; ++i) {
1630 if(pass.GetBinContent(i) > total.GetBinContent(i)) {
1631 gROOT->Info("TEfficiency::CheckEntries","Histograms are not consistent: passed bin content > total bin content");
1632 return false;
1633 }
1634 }
1635
1636 return true;
1637}
1638
1639////////////////////////////////////////////////////////////////////////////////
1640/// Check if both histogram are weighted. If they are weighted a true is returned
1641///
1643{
1644 if (pass.GetSumw2N() == 0 && total.GetSumw2N() == 0) return false;
1645
1646 // check also that the total sum of weight and weight squares are consistent
1649
1650 pass.GetStats(statpass);
1651 total.GetStats(stattotal);
1652
1653 double tolerance = (total.IsA() == TH1F::Class() ) ? 1.E-5 : 1.E-12;
1654
1655 //require: sum of weights == sum of weights^2
1658 return true;
1659 }
1660
1661 // histograms are not weighted
1662 return false;
1663
1664}
1665
1666
1667////////////////////////////////////////////////////////////////////////////////
1668/// Create the graph used be painted (for dim=1 TEfficiency)
1669/// The return object is managed by the caller
1670
1672{
1673 if (GetDimension() != 1) {
1674 Error("CreatePaintingGraph","Call this function only for dimension == 1");
1675 return nullptr;
1676 }
1677
1680 graph->SetName("eff_graph");
1681 FillGraph(graph,opt);
1682
1683 return graph;
1684}
1685
1686///////////////////////////////////////////////////////////////////////////////
1687/// Create the graph used be painted (for dim=1 TEfficiency)
1688/// The return object is managed by the caller
1689
1691{
1692 if (GetDimension() != 2) {
1693 Error("CreatePaintingGraph","Call this function only for dimension == 2");
1694 return nullptr;
1695 }
1696
1699 graph->SetName("eff_graph");
1700 FillGraph2D(graph,opt);
1701
1702 return graph;
1703}
1704
1705////////////////////////////////////////////////////////////////////////////////
1706/// Fill the graph to be painted with information from TEfficiency
1707/// Internal method called by TEfficiency::Paint or TEfficiency::CreateGraph
1708
1710{
1711 TString option = opt;
1712 option.ToLower();
1713
1714 Bool_t plot0Bins = false;
1715 if (option.Contains("e0") ) plot0Bins = true;
1716
1717 //point i corresponds to bin i+1 in histogram
1718 // point j is point graph index
1719 // LM: cannot use TGraph::SetPoint because it deletes the underlying
1720 // histogram each time (see TGraph::SetPoint)
1721 // so use it only when extra points are added to the graph
1722 int ipoint = 0;
1723 double * px = graph->GetX();
1724 double * py = graph->GetY();
1725 double * pz = graph->GetZ();
1726 double * exl = graph->GetEXlow();
1727 double * exh = graph->GetEXhigh();
1728 double * eyl = graph->GetEYlow();
1729 double * eyh = graph->GetEYhigh();
1730 double * ezl = graph->GetEZlow();
1731 double * ezh = graph->GetEZhigh();
1732 for (int i = 0; i < fTotalHistogram->GetNbinsX(); ++i) {
1733 double x = fTotalHistogram->GetXaxis()->GetBinCenter(i+1);
1735 double xup = fTotalHistogram->GetXaxis()->GetBinWidth(i+1) - xlow;
1736 for (int j = 0; j < fTotalHistogram->GetNbinsY(); ++j) {
1737 if (!plot0Bins && fTotalHistogram->GetBinContent(i+1,j+1) == 0 )
1738 continue;
1739 double y = fTotalHistogram->GetYaxis()->GetBinCenter(j+1);
1741 double yup = fTotalHistogram->GetYaxis()->GetBinWidth(j+1) - ylow;
1742
1743 int ibin = GetGlobalBin(i+1,j+1);
1744 double z = GetEfficiency(ibin);
1746 double zup = GetEfficiencyErrorUp(ibin);
1747 // in the case the graph already existed and extra points have been added
1748 if (ipoint >= graph->GetN() ) {
1749 graph->SetPoint(ipoint,x,y,z);
1750 graph->SetPointError(ipoint,xlow,xup,ylow,yup,zlow,zup);
1751 }
1752 else {
1753 px[ipoint] = x;
1754 py[ipoint] = y;
1755 pz[ipoint] = z;
1756 exl[ipoint] = xlow;
1757 exh[ipoint] = xup;
1758 eyl[ipoint] = ylow;
1759 eyh[ipoint] = yup;
1760 ezl[ipoint] = zlow;
1761 ezh[ipoint] = zup;
1762 }
1763 ipoint++;
1764 }
1765 }
1766
1767 // tell the graph the effective number of points
1768 graph->Set(ipoint);
1769 //refresh title before painting if changed
1770 TString oldTitle = graph->GetTitle();
1772 if (oldTitle != newTitle ) {
1773 graph->SetTitle(newTitle);
1774 }
1775
1776 // set the axis labels
1780 if (xlabel) graph->GetXaxis()->SetTitle(xlabel);
1781 if (ylabel) graph->GetYaxis()->SetTitle(ylabel);
1782 if (zlabel) graph->GetZaxis()->SetTitle(zlabel);
1783
1784 //copying style information
1785 TAttLine::Copy(*graph);
1786 TAttFill::Copy(*graph);
1787 TAttMarker::Copy(*graph);
1788
1789 // copy axis bin labels if existing. Assume are there in the total histogram
1790 if (fTotalHistogram->GetXaxis()->GetLabels() != nullptr) {
1791 for (int ibin = 1; ibin <= fTotalHistogram->GetXaxis()->GetNbins(); ++ibin) {
1792 // we need to fnd the right bin for the Histogram representing the xaxis of the graph
1795 }
1796 }
1797 if (fTotalHistogram->GetYaxis()->GetLabels() != nullptr) {
1798 for (int ibin = 1; ibin <= fTotalHistogram->GetYaxis()->GetNbins(); ++ibin) {
1799 // we need to fnd the right bin for the Histogram representing the xaxis of the graph
1802 }
1803 }
1804 // this method forces the graph to compute correctly the axis
1805 // according to the given points
1806 graph->GetHistogram();
1807}
1808////////////////////////////////////////////////////////////////////////////////
1809/// Fill the graph to be painted with information from TEfficiency
1810/// Internal method called by TEfficiency::Paint or TEfficiency::CreateGraph
1811
1813{
1814 TString option = opt;
1815 option.ToLower();
1816
1817 Bool_t plot0Bins = false;
1818 if (option.Contains("e0") ) plot0Bins = true;
1819
1820 Double_t x,y,xlow,xup,ylow,yup;
1821 //point i corresponds to bin i+1 in histogram
1822 // point j is point graph index
1823 // LM: cannot use TGraph::SetPoint because it deletes the underlying
1824 // histogram each time (see TGraph::SetPoint)
1825 // so use it only when extra points are added to the graph
1826 Int_t j = 0;
1827 double * px = graph->GetX();
1828 double * py = graph->GetY();
1829 double * exl = graph->GetEXlow();
1830 double * exh = graph->GetEXhigh();
1831 double * eyl = graph->GetEYlow();
1832 double * eyh = graph->GetEYhigh();
1834 for (Int_t i = 0; i < npoints; ++i) {
1835 if (!plot0Bins && fTotalHistogram->GetBinContent(i+1) == 0 ) continue;
1837 y = GetEfficiency(i+1);
1839 xup = fTotalHistogram->GetBinWidth(i+1) - xlow;
1840 ylow = GetEfficiencyErrorLow(i+1);
1841 yup = GetEfficiencyErrorUp(i+1);
1842 // in the case the graph already existed and extra points have been added
1843 if (j >= graph->GetN() ) {
1844 graph->SetPoint(j,x,y);
1845 graph->SetPointError(j,xlow,xup,ylow,yup);
1846 }
1847 else {
1848 px[j] = x;
1849 py[j] = y;
1850 exl[j] = xlow;
1851 exh[j] = xup;
1852 eyl[j] = ylow;
1853 eyh[j] = yup;
1854 }
1855 j++;
1856 }
1857
1858 // tell the graph the effective number of points
1859 graph->Set(j);
1860 //refresh title before painting if changed
1861 TString oldTitle = graph->GetTitle();
1863 if (oldTitle != newTitle ) {
1864 graph->SetTitle(newTitle);
1865 }
1866
1867 // set the axis labels
1870 if (xlabel) graph->GetXaxis()->SetTitle(xlabel);
1871 if (ylabel) graph->GetYaxis()->SetTitle(ylabel);
1872
1873 //copying style information
1874 TAttLine::Copy(*graph);
1875 TAttFill::Copy(*graph);
1876 TAttMarker::Copy(*graph);
1877
1878 // copy axis labels if existing. Assume are there in the total histogram
1879 if (fTotalHistogram->GetXaxis()->GetLabels() != nullptr) {
1880 for (int ibin = 1; ibin <= fTotalHistogram->GetXaxis()->GetNbins(); ++ibin) {
1881 // we need to find the right bin for the Histogram representing the xaxis of the graph
1884 }
1885 }
1886 // this method forces the graph to compute correctly the axis
1887 // according to the given points
1888 graph->GetHistogram();
1889
1890}
1891
1892////////////////////////////////////////////////////////////////////////////////
1893/// Create the histogram used to be painted (for dim=2 TEfficiency)
1894/// The return object is managed by the caller
1895
1897{
1898 if (GetDimension() != 2) {
1899 Error("CreatePaintingistogram","Call this function only for dimension == 2");
1900 return nullptr;
1901 }
1902
1907 TH2 * hist = nullptr;
1908
1909 if (xaxis->IsVariableBinSize() && yaxis->IsVariableBinSize() )
1910 hist = new TH2F("eff_histo",GetTitle(),nbinsx,xaxis->GetXbins()->GetArray(),
1911 nbinsy,yaxis->GetXbins()->GetArray());
1912 else if (xaxis->IsVariableBinSize() && ! yaxis->IsVariableBinSize() )
1913 hist = new TH2F("eff_histo",GetTitle(),nbinsx,xaxis->GetXbins()->GetArray(),
1914 nbinsy,yaxis->GetXmin(), yaxis->GetXmax());
1915 else if (!xaxis->IsVariableBinSize() && yaxis->IsVariableBinSize() )
1916 hist = new TH2F("eff_histo",GetTitle(),nbinsx,xaxis->GetXmin(), xaxis->GetXmax(),
1917 nbinsy,yaxis->GetXbins()->GetArray());
1918 else
1919 hist = new TH2F("eff_histo",GetTitle(),nbinsx,xaxis->GetXmin(), xaxis->GetXmax(),
1920 nbinsy,yaxis->GetXmin(), yaxis->GetXmax());
1921
1922
1923 hist->SetDirectory(nullptr);
1924
1925 FillHistogram(hist);
1926
1927 return hist;
1928}
1929
1930////////////////////////////////////////////////////////////////////////////////
1931/// Fill the 2d histogram to be painted with information from TEfficiency 2D
1932/// Internal method called by TEfficiency::Paint or TEfficiency::CreatePaintingGraph
1933
1935{
1936 //refresh title before each painting
1937 hist->SetTitle(GetTitle());
1938
1939 // set the axis labels
1943 if (xlabel) hist->GetXaxis()->SetTitle(xlabel);
1944 if (ylabel) hist->GetYaxis()->SetTitle(ylabel);
1945 if (zlabel) hist->GetZaxis()->SetTitle(zlabel);
1946
1947 Int_t bin;
1948 Int_t nbinsx = hist->GetNbinsX();
1949 Int_t nbinsy = hist->GetNbinsY();
1950 for(Int_t i = 0; i < nbinsx + 2; ++i) {
1951 for(Int_t j = 0; j < nbinsy + 2; ++j) {
1952 bin = GetGlobalBin(i,j);
1953 hist->SetBinContent(bin,GetEfficiency(bin));
1954 }
1955 }
1956
1957 // copy axis labels if existing. Assume are there in the total histogram
1958 if (fTotalHistogram->GetXaxis()->GetLabels() != nullptr) {
1959 for (int ibinx = 1; ibinx <= fTotalHistogram->GetXaxis()->GetNbins(); ++ibinx)
1961 }
1962 if (fTotalHistogram->GetYaxis()->GetLabels() != nullptr) {
1963 for (int ibiny = 1; ibiny <= fTotalHistogram->GetYaxis()->GetNbins(); ++ibiny)
1965 }
1966
1967 //copying style information
1968 TAttLine::Copy(*hist);
1969 TAttFill::Copy(*hist);
1970 TAttMarker::Copy(*hist);
1971 hist->SetStats(false);
1972
1973 return;
1974
1975}
1976////////////////////////////////////////////////////////////////////////////////
1977/**
1978Calculates the boundaries for the frequentist Clopper-Pearson interval
1979
1980This interval is recommended by the PDG.
1981
1982\param[in] total number of total events
1983\param[in] passed 0 <= number of passed events <= total
1984\param[in] level confidence level
1985\param[in] bUpper true - upper boundary is returned
1986 ;false - lower boundary is returned
1987
1988Calculation:
1989
1990The lower boundary of the Clopper-Pearson interval is the "exact" inversion
1991of the test:
1992 \f{eqnarray*}{
1993 P(x \geq passed; total) &=& \frac{1 - level}{2}\
1994 P(x \geq passed; total) &=& 1 - P(x \leq passed - 1; total)\
1995 &=& 1 - \frac{1}{norm} * \int_{0}^{1 - \varepsilon} t^{total - passed} (1 - t)^{passed - 1} dt\
1996 &=& 1 - \frac{1}{norm} * \int_{\varepsilon}^{1} t^{passed - 1} (1 - t)^{total - passed} dt\
1997 &=& \frac{1}{norm} * \int_{0}^{\varepsilon} t^{passed - 1} (1 - t)^{total - passed} dt\
1998 &=& I_{\varepsilon}(passed,total - passed + 1)
1999 \f}
2000The lower boundary is therefore given by the \f$ \frac{1 - level}{2}\f$ quantile
2001of the beta distribution.
2002
2003The upper boundary of the Clopper-Pearson interval is the "exact" inversion
2004of the test:
2005 \f{eqnarray*}{
2006 P(x \leq passed; total) &=& \frac{1 - level}{2}\
2007 P(x \leq passed; total) &=& \frac{1}{norm} * \int_{0}^{1 - \varepsilon} t^{total - passed - 1} (1 - t)^{passed} dt\
2008 &=& \frac{1}{norm} * \int_{\varepsilon}^{1} t^{passed} (1 - t)^{total - passed - 1} dt\
2009 &=& 1 - \frac{1}{norm} * \int_{0}^{\varepsilon} t^{passed} (1 - t)^{total - passed - 1} dt\
2010 \Rightarrow 1 - \frac{1 - level}{2} &=& \frac{1}{norm} * \int_{0}^{\varepsilon} t^{passed} (1 - t)^{total - passed -1} dt\
2011 \frac{1 + level}{2} &=& I_{\varepsilon}(passed + 1,total - passed)
2012 \f}
2013The upper boundary is therefore given by the \f$\frac{1 + level}{2}\f$ quantile
2014of the beta distribution.
2015
2016Note: The connection between the binomial distribution and the regularized
2017 incomplete beta function \f$ I_{\varepsilon}(\alpha,\beta)\f$ has been used.
2018*/
2019
2021{
2022 Double_t alpha = (1.0 - level) / 2;
2023 if(bUpper)
2024 return ((passed == total) ? 1.0 : ROOT::Math::beta_quantile(1 - alpha,passed + 1,total-passed));
2025 else
2026 return ((passed == 0) ? 0.0 : ROOT::Math::beta_quantile(alpha,passed,total-passed+1.0));
2027}
2028////////////////////////////////////////////////////////////////////////////////
2029/**
2030 Calculates the combined efficiency and its uncertainties
2031
2032 This method does a bayesian combination of the given samples.
2033
2034 \param[in] up contains the upper limit of the confidence interval afterwards
2035 \param[in] low contains the lower limit of the confidence interval afterwards
2036 \param[in] n number of samples which are combined
2037 \param[in] pass array of length n containing the number of passed events
2038 \param[in] total array of length n containing the corresponding numbers of total events
2039 \param[in] alpha shape parameters for the beta distribution as prior
2040 \param[in] beta shape parameters for the beta distribution as prior
2041 \param[in] level desired confidence level
2042 \param[in] w weights for each sample; if not given, all samples get the weight 1
2043 The weights do not need to be normalized, since they are internally renormalized
2044 to the number of effective entries.
2045 \param[in] opt
2046 - mode : The mode is returned instead of the mean of the posterior as best value
2047 When using the mode the shortest interval is also computed instead of the central one
2048 - shortest: compute shortest interval (done by default if mode option is set)
2049 - central: compute central interval (done by default if mode option is NOT set)
2050
2051 Calculation:
2052
2053 The combined posterior distributions is calculated from the Bayes theorem assuming a common prior Beta distribution.
2054 It is easy to proof that the combined posterior is then:
2055 \f{eqnarray*}{
2056 P_{comb}(\epsilon |{w_{i}}; {k_{i}}; {N_{i}}) &=& B(\epsilon, \sum_{i}{ w_{i} k_{i}} + \alpha, \sum_{i}{ w_{i}(n_{i}-k_{i})}+\beta)\
2057 w_{i} &=& weight\ for\ each\ sample\ renormalized\ to\ the\ effective\ entries\
2058 w^{'}_{i} &=& w_{i} \frac{ \sum_{i} {w_{i} } } { \sum_{i} {w_{i}^{2} } }
2059 \f}
2060
2061 The estimated efficiency is the mode (or the mean) of the obtained posterior distribution
2062
2063 The boundaries of the confidence interval for a confidence level (1 - a)
2064 are given by the a/2 and 1-a/2 quantiles of the resulting cumulative
2065 distribution.
2066
2067 Example (uniform prior distribution):
2068
2069Begin_Macro(source)
2070{
2071 TCanvas* c1 = new TCanvas("c1","",600,800);
2072 c1->Divide(1,2);
2073 c1->SetFillStyle(1001);
2074 c1->SetFillColor(kWhite);
2075
2076 TF1* p1 = new TF1("p1","TMath::BetaDist(x,19,9)",0,1);
2077 TF1* p2 = new TF1("p2","TMath::BetaDist(x,4,8)",0,1);
2078 TF1* comb = new TF1("comb2","TMath::BetaDist(x,[0],[1])",0,1);
2079 double nrm = 1./(0.6*0.6+0.4*0.4); // weight normalization
2080 double a = 0.6*18.0 + 0.4*3.0 + 1.0; // new alpha parameter of combined beta dist.
2081 double b = 0.6*10+0.4*7+1.0; // new beta parameter of combined beta dist.
2082 comb->SetParameters(nrm*a ,nrm *b );
2083 TF1* const1 = new TF1("const1","0.05",0,1);
2084 TF1* const2 = new TF1("const2","0.95",0,1);
2085
2086 p1->SetLineColor(kRed);
2087 p1->SetTitle("combined posteriors;#epsilon;P(#epsilon|k,N)");
2088 p2->SetLineColor(kBlue);
2089 comb->SetLineColor(kGreen+2);
2090
2091 TLegend* leg1 = new TLegend(0.12,0.65,0.5,0.85);
2092 leg1->AddEntry(p1,"k1 = 18, N1 = 26","l");
2093 leg1->AddEntry(p2,"k2 = 3, N2 = 10","l");
2094 leg1->AddEntry(comb,"combined: p1 = 0.6, p2=0.4","l");
2095
2096 c1->cd(1);
2097 comb->Draw();
2098 p1->Draw("same");
2099 p2->Draw("same");
2100 leg1->Draw("same");
2101 c1->cd(2);
2102 const1->SetLineWidth(1);
2103 const2->SetLineWidth(1);
2104 TGraph* gr = (TGraph*)comb->DrawIntegral();
2105 gr->SetTitle("cumulative function of combined posterior with boundaries for cl = 95%;#epsilon;CDF");
2106 const1->Draw("same");
2107 const2->Draw("same");
2108
2109 c1->cd(0);
2110 return c1;
2111}
2112End_Macro
2113
2114**/
2115////////////////////////////////////////////////////////////////////
2117 const Int_t* pass,const Int_t* total,
2118 Double_t alpha, Double_t beta,
2119 Double_t level,const Double_t* w,Option_t* opt)
2120{
2121 TString option(opt);
2122 option.ToLower();
2123
2124 //LM: new formula for combination
2125 // works only if alpha beta are the same always
2126 // the weights are normalized to w(i) -> N_eff w(i)/ Sum w(i)
2127 // i.e. w(i) -> Sum (w(i) / Sum (w(i)^2) * w(i)
2128 // norm = Sum (w(i) / Sum (w(i)^2)
2129 double ntot = 0;
2130 double ktot = 0;
2131 double sumw = 0;
2132 double sumw2 = 0;
2133 for (int i = 0; i < n ; ++i) {
2134 if(pass[i] > total[i]) {
2135 ::Error("TEfficiency::Combine","total events = %i < passed events %i",total[i],pass[i]);
2136 ::Info("TEfficiency::Combine","stop combining");
2137 return -1;
2138 }
2139
2140 ntot += w[i] * total[i];
2141 ktot += w[i] * pass[i];
2142 sumw += w[i];
2143 sumw2 += w[i]*w[i];
2144 //mean += w[i] * (pass[i] + alpha[i])/(total[i] + alpha[i] + beta[i]);
2145 }
2146 double norm = sumw/sumw2;
2147 ntot *= norm;
2148 ktot *= norm;
2149 if(ktot > ntot) {
2150 ::Error("TEfficiency::Combine","total = %f < passed %f",ntot,ktot);
2151 ::Info("TEfficiency::Combine","stop combining");
2152 return -1;
2153 }
2154
2155 double a = ktot + alpha;
2156 double b = ntot - ktot + beta;
2157
2158 double mean = a/(a+b);
2159 double mode = BetaMode(a,b);
2160
2161
2162 Bool_t shortestInterval = option.Contains("sh") || ( option.Contains("mode") && !option.Contains("cent") );
2163
2164 if (shortestInterval)
2165 BetaShortestInterval(level, a, b, low, up);
2166 else {
2167 low = BetaCentralInterval(level, a, b, false);
2168 up = BetaCentralInterval(level, a, b, true);
2169 }
2170
2171 if (option.Contains("mode")) return mode;
2172 return mean;
2173
2174}
2175////////////////////////////////////////////////////////////////////////////////
2176/// Combines a list of 1-dimensional TEfficiency objects
2177///
2178/// A TGraphAsymmErrors object is returned which contains the estimated
2179/// efficiency and its uncertainty for each bin.
2180/// If the combination fails, a zero pointer is returned.
2181///
2182/// At the moment the combining is only implemented for bayesian statistics.
2183///
2184/// \param[in] pList list containing TEfficiency objects which should be combined
2185/// only one-dimensional efficiencies are taken into account
2186/// \param[in] option
2187/// - s : strict combining; only TEfficiency objects with the same beta
2188/// prior and the flag kIsBayesian == true are combined
2189/// If not specified the prior parameter of the first TEfficiency object is used
2190/// - v : verbose mode; print information about combining
2191/// - cl=x : set confidence level (0 < cl < 1). If not specified, the
2192/// confidence level of the first TEfficiency object is used.
2193/// - mode Use mode of combined posterior as estimated value for the efficiency
2194/// - shortest: compute shortest interval (done by default if mode option is set)
2195/// - central: compute central interval (done by default if mode option is NOT set)
2196/// \param[in] n number of weights (has to be the number of one-dimensional
2197/// TEfficiency objects in pList)
2198/// If no weights are passed, the internal weights GetWeight() of
2199/// the given TEfficiency objects are used.
2200/// \param[in] w array of length n with weights for each TEfficiency object in
2201/// pList (w[0] correspond to pList->First ... w[n-1] -> pList->Last)
2202/// The weights do not have to be normalised.
2203///
2204/// For each bin the calculation is done by the Combine(double&, double& ...) method.
2205
2207 Int_t n,const Double_t* w)
2208{
2209 TString opt = option;
2210 opt.ToLower();
2211
2212 //parameter of prior distribution, confidence level and normalisation factor
2213 Double_t alpha = -1;
2214 Double_t beta = -1;
2215 Double_t level = 0;
2216
2217 //flags for combining
2218 Bool_t bStrict = false;
2219 Bool_t bOutput = false;
2220 Bool_t bWeights = false;
2221 //list of all information needed to weight and combine efficiencies
2222 std::vector<TH1*> vTotal; vTotal.reserve(n);
2223 std::vector<TH1*> vPassed; vPassed.reserve(n);
2224 std::vector<Double_t> vWeights; vWeights.reserve(n);
2225 // std::vector<Double_t> vAlpha;
2226 // std::vector<Double_t> vBeta;
2227
2228 if(opt.Contains("s")) {
2229 opt.ReplaceAll("s","");
2230 bStrict = true;
2231 }
2232
2233 if(opt.Contains("v")) {
2234 opt.ReplaceAll("v","");
2235 bOutput = true;
2236 }
2237
2238 if(opt.Contains("cl=")) {
2239 Ssiz_t pos = opt.Index("cl=") + 3;
2240 level = atof( opt(pos,opt.Length() ).Data() );
2241 if((level <= 0) || (level >= 1))
2242 level = 0;
2243 opt.ReplaceAll("cl=","");
2244 }
2245
2246 //are weights explicitly given
2247 if(n && w) {
2248 bWeights = true;
2249 for(Int_t k = 0; k < n; ++k) {
2250 if(w[k] > 0)
2251 vWeights.push_back(w[k]);
2252 else {
2253 gROOT->Error("TEfficiency::Combine","invalid custom weight found w = %.2lf",w[k]);
2254 gROOT->Info("TEfficiency::Combine","stop combining");
2255 return nullptr;
2256 }
2257 }
2258 }
2259
2260 TIter next(pList);
2261 TObject* obj = nullptr;
2262 TEfficiency* pEff = nullptr;
2263 while((obj = next())) {
2264 pEff = dynamic_cast<TEfficiency*>(obj);
2265 //is object a TEfficiency object?
2266 if(pEff) {
2267 if(pEff->GetDimension() > 1)
2268 continue;
2269 if(!level) level = pEff->GetConfidenceLevel();
2270
2271 if(alpha<1) alpha = pEff->GetBetaAlpha();
2272 if(beta<1) beta = pEff->GetBetaBeta();
2273
2274 //if strict combining, check priors, confidence level and statistic
2275 if(bStrict) {
2276 if(alpha != pEff->GetBetaAlpha())
2277 continue;
2278 if(beta != pEff->GetBetaBeta())
2279 continue;
2280 if(!pEff->UsesBayesianStat())
2281 continue;
2282 }
2283
2284 vTotal.push_back(pEff->fTotalHistogram);
2285 vPassed.push_back(pEff->fPassedHistogram);
2286
2287 //no weights given -> use weights of TEfficiency objects
2288 if(!bWeights)
2289 vWeights.push_back(pEff->fWeight);
2290
2291 //strict combining -> using global prior
2292 // if(bStrict) {
2293 // vAlpha.push_back(alpha);
2294 // vBeta.push_back(beta);
2295 // }
2296 // else {
2297 // vAlpha.push_back(pEff->GetBetaAlpha());
2298 // vBeta.push_back(pEff->GetBetaBeta());
2299 // }
2300 }
2301 }
2302
2303 //no TEfficiency objects found
2304 if(vTotal.empty()) {
2305 gROOT->Error("TEfficiency::Combine","no TEfficiency objects in given list");
2306 gROOT->Info("TEfficiency::Combine","stop combining");
2307 return nullptr;
2308 }
2309
2310 //invalid number of custom weights
2311 if(bWeights && (n != (Int_t)vTotal.size())) {
2312 gROOT->Error("TEfficiency::Combine","number of weights n=%i differs from number of TEfficiency objects k=%i which should be combined",n,(Int_t)vTotal.size());
2313 gROOT->Info("TEfficiency::Combine","stop combining");
2314 return nullptr;
2315 }
2316
2317 Int_t nbins_max = vTotal.at(0)->GetNbinsX();
2318 //check binning of all histograms
2319 for(UInt_t i=0; i<vTotal.size(); ++i) {
2320 if (!TEfficiency::CheckBinning(*vTotal.at(0),*vTotal.at(i)) )
2321 gROOT->Warning("TEfficiency::Combine","histograms have not the same binning -> results may be useless");
2322 if(vTotal.at(i)->GetNbinsX() < nbins_max) nbins_max = vTotal.at(i)->GetNbinsX();
2323 }
2324
2325 //display information about combining
2326 if(bOutput) {
2327 gROOT->Info("TEfficiency::Combine","combining %i TEfficiency objects",(Int_t)vTotal.size());
2328 if(bWeights)
2329 gROOT->Info("TEfficiency::Combine","using custom weights");
2330 if(bStrict) {
2331 gROOT->Info("TEfficiency::Combine","using the following prior probability for the efficiency: P(e) ~ Beta(e,%.3lf,%.3lf)",alpha,beta);
2332 }
2333 else
2334 gROOT->Info("TEfficiency::Combine","using individual priors of each TEfficiency object");
2335 gROOT->Info("TEfficiency::Combine","confidence level = %.2lf",level);
2336 }
2337
2338 //create TGraphAsymmErrors with efficiency
2339 std::vector<Double_t> x(nbins_max);
2340 std::vector<Double_t> xlow(nbins_max);
2341 std::vector<Double_t> xhigh(nbins_max);
2342 std::vector<Double_t> eff(nbins_max);
2343 std::vector<Double_t> efflow(nbins_max);
2344 std::vector<Double_t> effhigh(nbins_max);
2345
2346 //parameters for combining:
2347 //number of objects
2348 Int_t num = vTotal.size();
2349 std::vector<Int_t> pass(num);
2350 std::vector<Int_t> total(num);
2351
2352 //loop over all bins
2353 Double_t low = 0;
2354 Double_t up = 0;
2355 for(Int_t i=1; i <= nbins_max; ++i) {
2356 //the binning of the x-axis is taken from the first total histogram
2357 x[i-1] = vTotal.at(0)->GetBinCenter(i);
2358 xlow[i-1] = x[i-1] - vTotal.at(0)->GetBinLowEdge(i);
2359 xhigh[i-1] = vTotal.at(0)->GetBinWidth(i) - xlow[i-1];
2360
2361 for(Int_t j = 0; j < num; ++j) {
2362 pass[j] = (Int_t)(vPassed.at(j)->GetBinContent(i) + 0.5);
2363 total[j] = (Int_t)(vTotal.at(j)->GetBinContent(i) + 0.5);
2364 }
2365
2366 //fill efficiency and errors
2367 eff[i-1] = Combine(up,low,num,&pass[0],&total[0],alpha,beta,level,&vWeights[0],opt.Data());
2368 //did an error occurred ?
2369 if(eff[i-1] == -1) {
2370 gROOT->Error("TEfficiency::Combine","error occurred during combining");
2371 gROOT->Info("TEfficiency::Combine","stop combining");
2372 return nullptr;
2373 }
2374 efflow[i-1]= eff[i-1] - low;
2375 effhigh[i-1]= up - eff[i-1];
2376 }//loop over all bins
2377
2378 TGraphAsymmErrors* gr = new TGraphAsymmErrors(nbins_max,&x[0],&eff[0],&xlow[0],&xhigh[0],&efflow[0],&effhigh[0]);
2379
2380 return gr;
2381}
2382
2383////////////////////////////////////////////////////////////////////////////////
2384/// Compute distance from point px,py to a graph.
2385///
2386/// Compute the closest distance of approach from point px,py to this line.
2387/// The distance is computed in pixels units.
2388///
2389/// Forward the call to the painted graph
2390
2392{
2393 if (fPaintGraph) return fPaintGraph->DistancetoPrimitive(px,py);
2394 if (fPaintHisto) return fPaintHisto->DistancetoPrimitive(px,py);
2395 return 0;
2396}
2397
2398
2399////////////////////////////////////////////////////////////////////////////////
2400/// Draws the current TEfficiency object
2401///
2402/// \param[in] opt
2403/// - 1-dimensional case: same options as TGraphAsymmErrors::Draw()
2404/// but as default "AP" is used
2405/// - 2-dimensional case: by default use an histogram and in this case same options as TH2::Draw()
2406/// if using instad option "GRAPH" a TGraph2DAsymmErrors is used and
2407/// the same options as for TGraph2D applies
2408/// - 3-dimensional case: not yet supported
2409///
2410/// Specific TEfficiency drawing options:
2411/// - E0 - plot bins where the total number of passed events is zero
2412/// (the error interval will be [0,1] )
2413
2415{
2416 //check options
2417 TString option = opt;
2418 option.ToLower();
2419
2420 if(gPad && !option.Contains("same"))
2421 gPad->Clear();
2422
2423 if (GetDimension() == 2) {
2424 if (option.IsNull()) option = "colz";
2425 } else {
2426 // use by default "AP"
2427 if (option.IsNull()) option = "ap";
2428 // add always "a" if not present
2429 if (!option.Contains("same") && !option.Contains("a") ) option += "a";
2430 // add always p to the option
2431 if (!option.Contains("p") ) option += "p";
2432 }
2433
2434 AppendPad(option.Data());
2435}
2436
2437////////////////////////////////////////////////////////////////////////////////
2438/// Execute action corresponding to one event.
2439///
2440/// This member function is called when the drawn class is clicked with the locator
2441/// If Left button clicked on one of the line end points, this point
2442/// follows the cursor until button is released.
2443///
2444/// if Middle button clicked, the line is moved parallel to itself
2445/// until the button is released.
2446/// Forward the call to the underlying graph
2447
2449{
2450 if (fPaintGraph) fPaintGraph->ExecuteEvent(event,px,py);
2451 else if (fPaintHisto) fPaintHisto->ExecuteEvent(event,px,py);
2452}
2453
2454////////////////////////////////////////////////////////////////////////////////
2455/// This function is used for filling the two histograms.
2456///
2457/// \param[in] bPassed flag whether the current event passed the selection
2458/// - true: both histograms are filled
2459/// - false: only the total histogram is filled
2460/// \param[in] x x-value
2461/// \param[in] y y-value (use default=0 for 1-D efficiencies)
2462/// \param[in] z z-value (use default=0 for 2-D or 1-D efficiencies)
2463
2465{
2466 switch(GetDimension()) {
2467 case 1:
2469 if(bPassed)
2471 break;
2472 case 2:
2473 ((TH2*)(fTotalHistogram))->Fill(x,y);
2474 if(bPassed)
2475 ((TH2*)(fPassedHistogram))->Fill(x,y);
2476 break;
2477 case 3:
2478 ((TH3*)(fTotalHistogram))->Fill(x,y,z);
2479 if(bPassed)
2480 ((TH3*)(fPassedHistogram))->Fill(x,y,z);
2481 break;
2482 }
2483}
2484
2485////////////////////////////////////////////////////////////////////////////////
2486///This function is used for filling the two histograms with a weight.
2487///
2488/// \param[in] bPassed flag whether the current event passed the selection
2489/// - true: both histograms are filled
2490/// - false: only the total histogram is filled
2491/// \param[in] weight weight for the event
2492/// \param[in] x x-value
2493/// \param[in] y y-value (use default=0 for 1-D efficiencies)
2494/// \param[in] z z-value (use default=0 for 2-D or 1-D efficiencies)
2495///
2496/// Note: - this function will call SetUseWeightedEvents if it was not called by the user before
2497
2499{
2500 if(!TestBit(kUseWeights))
2501 {
2502 // Info("FillWeighted","call SetUseWeightedEvents() manually to ensure correct storage of sum of weights squared");
2504 }
2505
2506 switch(GetDimension()) {
2507 case 1:
2508 fTotalHistogram->Fill(x,weight);
2509 if(bPassed)
2510 fPassedHistogram->Fill(x,weight);
2511 break;
2512 case 2:
2513 ((TH2*)(fTotalHistogram))->Fill(x,y,weight);
2514 if(bPassed)
2515 ((TH2*)(fPassedHistogram))->Fill(x,y,weight);
2516 break;
2517 case 3:
2518 ((TH3*)(fTotalHistogram))->Fill(x,y,z,weight);
2519 if(bPassed)
2520 ((TH3*)(fPassedHistogram))->Fill(x,y,z,weight);
2521 break;
2522 }
2523}
2524
2525////////////////////////////////////////////////////////////////////////////////
2526/// Returns the global bin number containing the given values
2527///
2528/// Note:
2529///
2530/// - values which belong to dimensions higher than the current dimension
2531/// of the TEfficiency object are ignored (i.e. for 1-dimensional
2532/// efficiencies only the x-value is considered)
2533
2535{
2537 Int_t ny = 0;
2538 Int_t nz = 0;
2539
2540 switch(GetDimension()) {
2541 case 3: nz = fTotalHistogram->GetZaxis()->FindFixBin(z);
2542 case 2: ny = fTotalHistogram->GetYaxis()->FindFixBin(y);break;
2543 }
2544
2545 return GetGlobalBin(nx,ny,nz);
2546}
2547
2548///////////////////////////////////////////////////////////////////////////////
2549/// Fits the efficiency using the TBinomialEfficiencyFitter class
2550///
2551/// The resulting fit function is added to the list of associated functions.
2552///
2553/// Options:
2554/// - "+": previous fitted functions in the list are kept, by default
2555/// all functions in the list are deleted
2556/// - "N": do not store fitted function
2557/// - for more fitting options see TBinomialEfficiencyFitter::Fit
2558
2560{
2561 TString option = opt;
2562 option.ToUpper();
2563
2564 //replace existing functions in list with same name
2565 Bool_t bDeleteOld = true;
2566 if(option.Contains("+")) {
2567 option.ReplaceAll("+","");
2568 bDeleteOld = false;
2569 }
2570
2572
2573 TFitResultPtr result = Fitter.Fit(f1,option.Data());
2574
2575 //create copy which is appended to the list
2576 if (!option.Contains("N")) { // option "N" is not store fit function
2577 TF1* pFunc = (TF1*)f1->IsA()->New();
2578 f1->Copy(*pFunc);
2579
2580 if(bDeleteOld) {
2581 TIter next(fFunctions);
2582 TObject* obj = nullptr;
2583 while((obj = next())) {
2584 if(obj->InheritsFrom(TF1::Class())) {
2585 fFunctions->Remove(obj);
2586 delete obj;
2587 }
2588 }
2589 }
2590 // create list if necessary
2591 if(!fFunctions)
2592 fFunctions = new TList();
2593
2595 }
2596
2597 return result;
2598}
2599
2600////////////////////////////////////////////////////////////////////////////////
2601/// Returns a cloned version of fPassedHistogram
2602///
2603/// Notes:
2604/// - The histogram is filled with unit weights. You might want to scale
2605/// it with the global weight GetWeight().
2606/// - The returned object is owned by the user who has to care about the
2607/// deletion of the new TH1 object.
2608/// - This histogram is by default NOT attached to the current directory
2609/// to avoid duplication of data. If you want to store it automatically
2610/// during the next TFile::Write() command, you have to attach it to
2611/// the corresponding directory.
2612///
2613/// ~~~~~~~{.cpp}
2614/// TFile* pFile = new TFile("passed.root","update");
2615/// TEfficiency* pEff = (TEfficiency*)gDirectory->Get("my_eff");
2616/// TH1* copy = pEff->GetCopyPassedHisto();
2617/// copy->SetDirectory(gDirectory);
2618/// pFile->Write();
2619/// ~~~~~~~
2620
2622{
2623 // do not add cloned histogram to gDirectory
2624 TDirectory::TContext ctx(nullptr);
2625 TH1* tmp = (TH1*)(fPassedHistogram->Clone());
2626
2627 return tmp;
2628}
2629
2630////////////////////////////////////////////////////////////////////////////////
2631/// Returns a cloned version of fTotalHistogram
2632///
2633/// Notes:
2634/// - The histogram is filled with unit weights. You might want to scale
2635/// it with the global weight GetWeight().
2636/// - The returned object is owned by the user who has to care about the
2637/// deletion of the new TH1 object.
2638/// - This histogram is by default NOT attached to the current directory
2639/// to avoid duplication of data. If you want to store it automatically
2640/// during the next TFile::Write() command, you have to attach it to
2641/// the corresponding directory.
2642///
2643/// ~~~~~~~{.cpp}
2644/// TFile* pFile = new TFile("total.root","update");
2645/// TEfficiency* pEff = (TEfficiency*)gDirectory->Get("my_eff");
2646/// TH1* copy = pEff->GetCopyTotalHisto();
2647/// copy->SetDirectory(gDirectory);
2648/// pFile->Write();
2649/// ~~~~~~~
2650
2652{
2653 // do not add cloned histogram to gDirectory
2654 TDirectory::TContext ctx(nullptr);
2655 TH1* tmp = (TH1*)(fTotalHistogram->Clone());
2656
2657 return tmp;
2658}
2659
2660////////////////////////////////////////////////////////////////////////////////
2661///returns the dimension of the current TEfficiency object
2662
2667
2668////////////////////////////////////////////////////////////////////////////////
2669/// Returns the efficiency in the given global bin
2670///
2671/// Note:
2672/// - The estimated efficiency depends on the chosen statistic option:
2673/// for frequentist ones:
2674/// \f$ \hat{\varepsilon} = \frac{passed}{total} \f$
2675/// for bayesian ones the expectation value of the resulting posterior
2676/// distribution is returned:
2677/// \f$ \hat{\varepsilon} = \frac{passed + \alpha}{total + \alpha + \beta} \f$
2678/// If the bit kPosteriorMode is set (or the method TEfficiency::UsePosteriorMode() has been called ) the
2679/// mode (most probable value) of the posterior is returned:
2680/// \f$ \hat{\varepsilon} = \frac{passed + \alpha -1}{total + \alpha + \beta -2} \f$
2681/// - If the denominator is equal to 0, an efficiency of 0 is returned.
2682/// - When \f$ passed + \alpha < 1 \f$ or \f$ total - passed + \beta < 1 \f$ the above
2683/// formula for the mode is not valid. In these cases values the estimated efficiency is 0 or 1.
2684
2686{
2689
2690 if(TestBit(kIsBayesian)) {
2691
2692 // parameters for the beta prior distribution
2695
2696 Double_t aa,bb;
2697 if(TestBit(kUseWeights))
2698 {
2700 Double_t tw2 = fTotalHistogram->GetSumw2()->At(bin);
2702
2703 if (tw2 <= 0 ) return pw/tw;
2704
2705 // tw/tw2 renormalize the weights
2706 double norm = tw/tw2;
2707 aa = pw * norm + alpha;
2708 bb = (tw - pw) * norm + beta;
2709 }
2710 else
2711 {
2712 aa = passed + alpha;
2713 bb = total - passed + beta;
2714 }
2715
2716 if (!TestBit(kPosteriorMode) )
2717 return BetaMean(aa,bb);
2718 else
2719 return BetaMode(aa,bb);
2720
2721 }
2722 else
2723 return (total)? ((Double_t)passed)/total : 0;
2724}
2725
2726////////////////////////////////////////////////////////////////////////////////
2727/// Returns the lower error on the efficiency in the given global bin
2728///
2729/// The result depends on the current confidence level fConfLevel and the
2730/// chosen statistic option fStatisticOption. See SetStatisticOption(Int_t) for
2731/// more details.
2732///
2733/// Note: If the histograms are filled with weights, only bayesian methods and the
2734/// normal approximation are supported.
2735
2737{
2740
2741 Double_t eff = GetEfficiency(bin);
2742
2743 // check whether weights have been used
2744 if(TestBit(kUseWeights))
2745 {
2747 Double_t tw2 = fTotalHistogram->GetSumw2()->At(bin);
2749 Double_t pw2 = fPassedHistogram->GetSumw2()->At(bin);
2750
2751 if(TestBit(kIsBayesian))
2752 {
2755
2756 if (tw2 <= 0) return 0;
2757
2758 // tw/tw2 renormalize the weights
2759 Double_t norm = tw/tw2;
2760 Double_t aa = pw * norm + alpha;
2761 Double_t bb = (tw - pw) * norm + beta;
2762 Double_t low = 0;
2763 Double_t upper = 1;
2766 }
2767 else {
2769 }
2770
2771 return eff - low;
2772 }
2773 else
2774 {
2776 {
2777 Warning("GetEfficiencyErrorLow","frequentist confidence intervals for weights are only supported by the normal approximation");
2778 Info("GetEfficiencyErrorLow","setting statistic option to kFNormal");
2779 const_cast<TEfficiency*>(this)->SetStatisticOption(kFNormal);
2780 }
2781
2782 Double_t variance = ( pw2 * (1. - 2 * eff) + tw2 * eff *eff ) / ( tw * tw) ;
2783 Double_t sigma = sqrt(variance);
2784
2785 Double_t prob = 0.5 * (1.- fConfLevel);
2787
2788 // avoid to return errors which makes eff-err < 0
2789 return (eff - delta < 0) ? eff : delta;
2790 }
2791 }
2792 else
2793 {
2794 if(TestBit(kIsBayesian))
2795 {
2796 // parameters for the beta prior distribution
2799 return (eff - Bayesian(total,passed,fConfLevel,alpha,beta,false,TestBit(kShortestInterval)));
2800 }
2801 else
2802 return (eff - fBoundary(total,passed,fConfLevel,false));
2803 }
2804}
2805
2806////////////////////////////////////////////////////////////////////////////////
2807/// Returns the upper error on the efficiency in the given global bin
2808///
2809/// The result depends on the current confidence level fConfLevel and the
2810/// chosen statistic option fStatisticOption. See SetStatisticOption(Int_t) for
2811/// more details.
2812///
2813/// Note: If the histograms are filled with weights, only bayesian methods and the
2814/// normal approximation are supported.
2815
2817{
2820
2821 Double_t eff = GetEfficiency(bin);
2822
2823 // check whether weights have been used
2824 if(TestBit(kUseWeights))
2825 {
2827 Double_t tw2 = fTotalHistogram->GetSumw2()->At(bin);
2829 Double_t pw2 = fPassedHistogram->GetSumw2()->At(bin);
2830
2831 if(TestBit(kIsBayesian))
2832 {
2835
2836 if (tw2 <= 0) return 0;
2837
2838 // tw/tw2 renormalize the weights
2839 Double_t norm = tw/tw2;
2840 Double_t aa = pw * norm + alpha;
2841 Double_t bb = (tw - pw) * norm + beta;
2842 Double_t low = 0;
2843 Double_t upper = 1;
2846 }
2847 else {
2849 }
2850
2851 return upper - eff;
2852 }
2853 else
2854 {
2856 {
2857 Warning("GetEfficiencyErrorUp","frequentist confidence intervals for weights are only supported by the normal approximation");
2858 Info("GetEfficiencyErrorUp","setting statistic option to kFNormal");
2859 const_cast<TEfficiency*>(this)->SetStatisticOption(kFNormal);
2860 }
2861
2862 Double_t variance = ( pw2 * (1. - 2 * eff) + tw2 * eff *eff ) / ( tw * tw) ;
2863 Double_t sigma = sqrt(variance);
2864
2865 Double_t prob = 0.5 * (1.- fConfLevel);
2867
2868 return (eff + delta > 1) ? 1.-eff : delta;
2869 }
2870 }
2871 else
2872 {
2873 if(TestBit(kIsBayesian))
2874 {
2875 // parameters for the beta prior distribution
2878 return (Bayesian(total,passed,fConfLevel,alpha,beta,true,TestBit(kShortestInterval)) - eff);
2879 }
2880 else
2881 return fBoundary(total,passed,fConfLevel,true) - eff;
2882 }
2883}
2884
2885////////////////////////////////////////////////////////////////////////////////
2886/// Returns the global bin number which can be used as argument for the
2887/// following functions:
2888///
2889/// - GetEfficiency(bin), GetEfficiencyErrorLow(bin), GetEfficiencyErrorUp(bin)
2890/// - SetPassedEvents(bin), SetTotalEvents(bin)
2891///
2892/// see TH1::GetBin() for conventions on numbering bins
2893
2898
2899////////////////////////////////////////////////////////////////////////////////
2900
2905
2906////////////////////////////////////////////////////////////////////////////////
2907/// Merges the TEfficiency objects in the given list to the given
2908/// TEfficiency object using the operator+=(TEfficiency&)
2909///
2910/// The merged result is stored in the current object. The statistic options and
2911/// the confidence level are taken from the current object.
2912///
2913/// This function should be used when all TEfficiency objects correspond to
2914/// the same process.
2915///
2916/// The new weight is set according to:
2917/// \f$ \frac{1}{w_{new}} = \sum_{i} \frac{1}{w_{i}} \f$
2918
2920{
2921 if(!pList->IsEmpty()) {
2922 TIter next(pList);
2923 TObject* obj = nullptr;
2924 TEfficiency* pEff = nullptr;
2925 while((obj = next())) {
2926 pEff = dynamic_cast<TEfficiency*>(obj);
2927 if(pEff) {
2928 *this += *pEff;
2929 }
2930 }
2931 }
2933}
2934
2935////////////////////////////////////////////////////////////////////////////////
2936/**
2937Returns the confidence limits for the efficiency supposing that the
2938efficiency follows a normal distribution with the rms below
2939
2940\param[in] total number of total events
2941\param[in] passed 0 <= number of passed events <= total
2942\param[in] level confidence level
2943\param[in] bUpper
2944 - true - upper boundary is returned
2945 - false - lower boundary is returned
2946
2947Calculation:
2948
2949\f{eqnarray*}{
2950 \hat{\varepsilon} &=& \frac{passed}{total}\
2951 \sigma_{\varepsilon} &=& \sqrt{\frac{\hat{\varepsilon} (1 - \hat{\varepsilon})}{total}}\
2952 \varepsilon_{low} &=& \hat{\varepsilon} \pm \Phi^{-1}(\frac{level}{2},\sigma_{\varepsilon})
2953\f}
2954*/
2955
2957{
2958 Double_t alpha = (1.0 - level)/2;
2959 if (total == 0) return (bUpper) ? 1 : 0;
2960 Double_t average = passed / total;
2961 Double_t sigma = std::sqrt(average * (1 - average) / total);
2962 Double_t delta = ROOT::Math::normal_quantile(1 - alpha,sigma);
2963
2964 if(bUpper)
2965 return ((average + delta) > 1) ? 1.0 : (average + delta);
2966 else
2967 return ((average - delta) < 0) ? 0.0 : (average - delta);
2968}
2969
2970////////////////////////////////////////////////////////////////////////////////
2971/// Adds the histograms of another TEfficiency object to current histograms
2972///
2973/// The statistic options and the confidence level remain unchanged.
2974///
2975/// fTotalHistogram += rhs.fTotalHistogram;
2976/// fPassedHistogram += rhs.fPassedHistogram;
2977///
2978/// calculates a new weight:
2979/// current weight of this TEfficiency object = \f$ w_{1} \f$
2980/// weight of rhs = \f$ w_{2} \f$
2981/// \f$ w_{new} = \frac{w_{1} \times w_{2}}{w_{1} + w_{2}} \f$
2982
2984{
2985
2986 if (fTotalHistogram == nullptr && fPassedHistogram == nullptr) {
2987 // efficiency is empty just copy it over
2988 *this = rhs;
2989 return *this;
2990 }
2991 else if (fTotalHistogram == nullptr || fPassedHistogram == nullptr) {
2992 Fatal("operator+=","Adding to a non consistent TEfficiency object which has not a total or a passed histogram ");
2993 return *this;
2994 }
2995
2996 if (rhs.fTotalHistogram == nullptr && rhs.fPassedHistogram == nullptr ) {
2997 Warning("operator+=","no operation: adding an empty object");
2998 return *this;
2999 }
3000 else if (rhs.fTotalHistogram == nullptr || rhs.fPassedHistogram == nullptr ) {
3001 Fatal("operator+=","Adding a non consistent TEfficiency object which has not a total or a passed histogram ");
3002 return *this;
3003 }
3004
3007
3008 fTotalHistogram->Add(rhs.fTotalHistogram);
3009 fPassedHistogram->Add(rhs.fPassedHistogram);
3010
3011 SetWeight((fWeight * rhs.GetWeight())/(fWeight + rhs.GetWeight()));
3012
3013 return *this;
3014}
3015
3016////////////////////////////////////////////////////////////////////////////////
3017/// Assignment operator
3018///
3019/// The histograms, statistic option, confidence level, weight and paint styles
3020/// of rhs are copied to the this TEfficiency object.
3021///
3022/// Note: - The list of associated functions is not copied. After this
3023/// operation the list of associated functions is empty.
3024
3026{
3027 if(this != &rhs)
3028 {
3029 //statistic options
3030 SetStatisticOption(rhs.GetStatisticOption());
3031 SetConfidenceLevel(rhs.GetConfidenceLevel());
3032 SetBetaAlpha(rhs.GetBetaAlpha());
3033 SetBetaBeta(rhs.GetBetaBeta());
3034 SetWeight(rhs.GetWeight());
3035
3036 //associated list of functions
3037 if(fFunctions)
3038 fFunctions->Delete();
3039
3040 //copy histograms
3041 delete fTotalHistogram;
3042 delete fPassedHistogram;
3043
3044 // do not add cloned histogram to gDirectory
3045 {
3046 TDirectory::TContext ctx(nullptr);
3047 fTotalHistogram = (TH1*)(rhs.fTotalHistogram->Clone());
3048 fPassedHistogram = (TH1*)(rhs.fPassedHistogram->Clone());
3049 }
3050 //delete temporary paint objects
3051 delete fPaintHisto;
3052 delete fPaintGraph;
3053 delete fPaintGraph2D;
3054 fPaintHisto = nullptr;
3055 fPaintGraph = nullptr;
3056 fPaintGraph2D = nullptr;
3057
3058 //copy style
3059 rhs.TAttLine::Copy(*this);
3060 rhs.TAttFill::Copy(*this);
3061 rhs.TAttMarker::Copy(*this);
3062 }
3063
3064 return *this;
3065}
3066
3067////////////////////////////////////////////////////////////////////////////////
3068/// Paints this TEfficiency object
3069///
3070/// For details on the possible option see Draw(Option_t*)
3071///
3072/// Note for 1D classes
3073/// In 1D the TEfficiency uses a TGraphAsymmErrors for drawing
3074/// The TGraph is created only the first time Paint is used. The user can manipulate the
3075/// TGraph via the method TEfficiency::GetPaintedGraph()
3076/// The TGraph creates behing an histogram for the axis. The histogram is created also only the first time.
3077/// If the axis needs to be updated because in the meantime the class changed use this trick
3078/// which will trigger a re-calculation of the axis of the graph
3079/// TEfficiency::GetPaintedGraph()->Set(0)
3080///
3081/// Note that in order to access the painted graph via GetPaintedGraph() you need either to call Paint or better
3082/// gPad->Update();
3083///
3084
3086{
3087
3088
3089 if(!gPad)
3090 return;
3091
3092 TString option(opt);
3093 option.ToUpper();
3094
3095
3096 //use TGraphAsymmErrors for painting
3097 if(GetDimension() == 1) {
3098 if(!fPaintGraph) {
3099 fPaintGraph = CreateGraph(opt);
3100 }
3101 else
3102 // update existing graph already created
3103 FillGraph(fPaintGraph, opt);
3104
3105 //paint graph
3106 fPaintGraph->Paint(opt);
3107 // paint all associated functions
3108 if (fFunctions) {
3109 // paint box with fit parameters
3110 // the fit statistics will be painted if gStyle->SetOptFit(1) has been
3111 // called by the user
3112 TIter next(fFunctions);
3113 TObject *obj = nullptr;
3114 while ((obj = next())) {
3115 if (obj->InheritsFrom(TF1::Class())) {
3116 fPaintGraph->PaintStats((TF1 *)obj);
3117 ((TF1 *)obj)->Paint("sameC");
3118 }
3119 }
3120 }
3121 return;
3122 }
3123 //use TH2 or optionally a TGraph2DAsymmErrors for painting
3124 if(GetDimension() == 2) {
3125 bool drawGraph2D = false;
3126 if (option.Contains("GRAPH")) {
3127 option.ReplaceAll("GRAPH","");
3128 drawGraph2D = true;
3129 }
3130 if (drawGraph2D) {
3131 //paint a TGraph2DAsymmErrors
3132 if(!fPaintGraph2D)
3134 else
3136 // set some sensible marker size and type
3139 // use PCOL Z as default option
3140 if (option.IsNull()) option += "ERR PCOL Z";
3142 } else {
3143 //paint histogram
3144 if (!fPaintHisto)
3146 else
3149 }
3150 // should we also paint the functions??
3151 return;
3152 }
3153 Warning("Paint","Painting 3D efficiency is not implemented");
3154}
3155
3156////////////////////////////////////////////////////////////////////////////////
3157/// Recursively remove object from the list of functions
3158
3160{
3161 if (fFunctions) {
3164 }
3165 if (fPaintGraph == obj)
3166 fPaintGraph = nullptr;
3167 if (fPaintGraph2D == obj)
3168 fPaintGraph2D = nullptr;
3169 if (fPaintHisto == obj)
3170 fPaintHisto = nullptr;
3171 if (fPassedHistogram == obj)
3172 fPassedHistogram = nullptr;
3173 if (fTotalHistogram == obj)
3174 fTotalHistogram = nullptr;
3175}
3176
3177
3178////////////////////////////////////////////////////////////////////////////////
3179/// Save primitive as a C++ statement(s) on output stream out.
3180
3182{
3183 //TEfficiency pointer has efficiency name + counter
3184 thread_local Int_t eff_count = 0;
3185 ++eff_count;
3186 TString name = GetName();
3187 name += eff_count;
3188 name = gInterpreter->MapCppName(name);
3189
3190 out <<" \n";
3191
3193
3194 // Check if the histogram has equidistant X bins or not. If not, we
3195 // create an array holding the bins.
3196 if (fTotalHistogram->GetXaxis()->GetXbins()->fN && fTotalHistogram->GetXaxis()->GetXbins()->fArray)
3198 // If the histogram is 2 or 3 dimensional, check if the histogram
3199 // has equidistant Y bins or not. If not, we create an array
3200 // holding the bins.
3201 if (GetDimension() > 1 && fTotalHistogram->GetYaxis()->GetXbins()->fN && fTotalHistogram->GetYaxis()->GetXbins()->fArray)
3203 // IF the histogram is 3 dimensional, check if the histogram
3204 // has equidistant Z bins or not. If not, we create an array
3205 // holding the bins.
3206 if (GetDimension() > 2 && fTotalHistogram->GetZaxis()->GetXbins()->fN && fTotalHistogram->GetZaxis()->GetXbins()->fArray)
3208
3209 out << " " << ClassName() << " *" << name << " = new " << ClassName() << "(\"" << GetName() << "\", \""
3210 << TString(GetTitle()).ReplaceSpecialCppChars() << "\"";
3211 // X dimentsion args
3212 out << ", " << fTotalHistogram->GetXaxis()->GetNbins() << ", ";
3213 if (!sxaxis.IsNull())
3214 out << sxaxis << ".data()";
3215 else
3216 out << fTotalHistogram->GetXaxis()->GetXmin() << "," << fTotalHistogram->GetXaxis()->GetXmax();
3217
3218 if (GetDimension() > 1) {
3219 out << ", " << fTotalHistogram->GetYaxis()->GetNbins() << ", ";
3220 if (!syaxis.IsNull())
3221 out << syaxis << ".data()";
3222 else
3223 out << fTotalHistogram->GetYaxis()->GetXmin() << ", " << fTotalHistogram->GetYaxis()->GetXmax();
3224 }
3225
3226 if (GetDimension() > 2) {
3227 out << ", " << fTotalHistogram->GetZaxis()->GetNbins() << ", ";
3228 if (!szaxis.IsNull())
3229 out << szaxis << ".data()";
3230 else
3231 out << fTotalHistogram->GetZaxis()->GetXmin() << ", " << fTotalHistogram->GetZaxis()->GetXmax();
3232 }
3233
3234 out << ");\n";
3235 out << " \n";
3236
3237 //set statistic options
3238 out << " " << name << "->SetConfidenceLevel(" << fConfLevel << ");\n";
3239 out << " " << name << "->SetBetaAlpha(" << fBeta_alpha << ");\n";
3240 out << " " << name << "->SetBetaBeta(" << fBeta_beta << ");\n";
3241 out << " " << name << "->SetWeight(" << fWeight << ");\n";
3242 out << " " << name << "->SetStatisticOption(static_cast<TEfficiency::EStatOption>(" << fStatisticOption << "));\n";
3243 out << " " << name << "->SetPosteriorMode(" << TestBit(kPosteriorMode) << ");\n";
3244 out << " " << name << "->SetShortestInterval(" << TestBit(kShortestInterval) << ");\n";
3245 if(TestBit(kUseWeights))
3246 out << " " << name << "->SetUseWeightedEvents();\n";
3247
3248 // save bin-by-bin prior parameters
3249 for (unsigned int i = 0; i < fBeta_bin_params.size(); ++i) {
3250 out << " " << name << "->SetBetaBinParameters(" << i << "," << fBeta_bin_params.at(i).first << ","
3251 << fBeta_bin_params.at(i).second << ");\n";
3252 }
3253
3254 //set bin contents
3255 Int_t nbins = fTotalHistogram->GetNbinsX() + 2;
3256 if(GetDimension() > 1)
3257 nbins *= fTotalHistogram->GetNbinsY() + 2;
3258 if(GetDimension() > 2)
3259 nbins *= fTotalHistogram->GetNbinsZ() + 2;
3260
3261 //important: set first total number than passed number
3262 for (Int_t i = 0; i < nbins; ++i) {
3263 out << " " << name << "->SetTotalEvents(" << i << "," << fTotalHistogram->GetBinContent(i) << ");\n";
3264 out << " " << name << "->SetPassedEvents(" << i << "," << fPassedHistogram->GetBinContent(i) << ");\n";
3265 }
3266
3268
3269 //set style
3273
3275}
3276
3277////////////////////////////////////////////////////////////////////////////////
3278/// Sets the shape parameter &alpha;
3279///
3280/// The prior probability of the efficiency is given by the beta distribution:
3281/// \f[
3282/// f(\varepsilon;\alpha;\beta) = \frac{1}{B(\alpha,\beta)} \varepsilon^{\alpha-1} (1 - \varepsilon)^{\beta-1}
3283/// \f]
3284///
3285/// Note: - both shape parameters have to be positive (i.e. > 0)
3286
3288{
3289 if(alpha > 0)
3290 fBeta_alpha = alpha;
3291 else
3292 Warning("SetBetaAlpha(Double_t)","invalid shape parameter %.2lf",alpha);
3293}
3294
3295////////////////////////////////////////////////////////////////////////////////
3296/// Sets the shape parameter &beta;
3297///
3298/// The prior probability of the efficiency is given by the beta distribution:
3299/// \f[
3300/// f(\varepsilon;\alpha,\beta) = \frac{1}{B(\alpha,\beta)} \varepsilon^{\alpha-1} (1 - \varepsilon)^{\beta-1}
3301/// \f]
3302///
3303/// Note: - both shape parameters have to be positive (i.e. > 0)
3304
3306{
3307 if(beta > 0)
3308 fBeta_beta = beta;
3309 else
3310 Warning("SetBetaBeta(Double_t)","invalid shape parameter %.2lf",beta);
3311}
3312
3313////////////////////////////////////////////////////////////////////////////////
3314/// Sets different shape parameter &alpha; and &beta;
3315/// for the prior distribution for each bin. By default the global parameter are used if they are not set
3316/// for the specific bin
3317/// The prior probability of the efficiency is given by the beta distribution:
3318/// \f[
3319/// f(\varepsilon;\alpha;\beta) = \frac{1}{B(\alpha,\beta)} \varepsilon^{\alpha-1} (1 - \varepsilon)^{\beta-1}
3320/// \f]
3321///
3322/// Note:
3323/// - both shape parameters have to be positive (i.e. > 0)
3324/// - bin gives the global bin number (cf. GetGlobalBin)
3325
3327{
3328 if (!fPassedHistogram || !fTotalHistogram) return;
3330 // doing this I get h1->fN which is available only for a TH1D
3331 UInt_t n = h1->GetBin(h1->GetNbinsX()+1, h1->GetNbinsY()+1, h1->GetNbinsZ()+1 ) + 1;
3332
3333 // in case vector is not created do with default alpha, beta params
3334 if (fBeta_bin_params.size() != n )
3335 fBeta_bin_params = std::vector<std::pair<Double_t, Double_t> >(n, std::make_pair(fBeta_alpha, fBeta_beta) );
3336
3337 // vector contains also values for under/overflows
3338 fBeta_bin_params[bin] = std::make_pair(alpha,beta);
3339 SetBit(kUseBinPrior,true);
3340
3341}
3342
3343////////////////////////////////////////////////////////////////////////////////
3344/// Set the bins for the underlined passed and total histograms
3345/// If the class have been already filled the previous contents will be lost
3346
3348{
3349 if (GetDimension() != 1) {
3350 Error("SetBins","Using wrong SetBins function for a %d-d histogram",GetDimension());
3351 return kFALSE;
3352 }
3353 if (fTotalHistogram->GetEntries() != 0 ) {
3354 Warning("SetBins","Histogram entries will be lost after SetBins");
3357 }
3360 return kTRUE;
3361}
3362
3363////////////////////////////////////////////////////////////////////////////////
3364/// Set the bins for the underlined passed and total histograms
3365/// If the class have been already filled the previous contents will be lost
3366
3368{
3369 if (GetDimension() != 1) {
3370 Error("SetBins","Using wrong SetBins function for a %d-d histogram",GetDimension());
3371 return kFALSE;
3372 }
3373 if (fTotalHistogram->GetEntries() != 0 ) {
3374 Warning("SetBins","Histogram entries will be lost after SetBins");
3377 }
3380 return kTRUE;
3381}
3382
3383////////////////////////////////////////////////////////////////////////////////
3384/// Set the bins for the underlined passed and total histograms
3385/// If the class have been already filled the previous contents will be lost
3386
3388{
3389 if (GetDimension() != 2) {
3390 Error("SetBins","Using wrong SetBins function for a %d-d histogram",GetDimension());
3391 return kFALSE;
3392 }
3393 if (fTotalHistogram->GetEntries() != 0 ) {
3394 Warning("SetBins","Histogram entries will be lost after SetBins");
3397 }
3400 return kTRUE;
3401}
3402
3403////////////////////////////////////////////////////////////////////////////////
3404/// Set the bins for the underlined passed and total histograms
3405/// If the class have been already filled the previous contents will be lost
3406
3408{
3409 if (GetDimension() != 2) {
3410 Error("SetBins","Using wrong SetBins function for a %d-d histogram",GetDimension());
3411 return kFALSE;
3412 }
3413 if (fTotalHistogram->GetEntries() != 0 ) {
3414 Warning("SetBins","Histogram entries will be lost after SetBins");
3417 }
3420 return kTRUE;
3421}
3422
3423////////////////////////////////////////////////////////////////////////////////
3424/// Set the bins for the underlined passed and total histograms
3425/// If the class have been already filled the previous contents will be lost
3426
3428 Int_t nz, Double_t zmin, Double_t zmax)
3429{
3430 if (GetDimension() != 3) {
3431 Error("SetBins","Using wrong SetBins function for a %d-d histogram",GetDimension());
3432 return kFALSE;
3433 }
3434 if (fTotalHistogram->GetEntries() != 0 ) {
3435 Warning("SetBins","Histogram entries will be lost after SetBins");
3438 }
3441 return kTRUE;
3442}
3443
3444////////////////////////////////////////////////////////////////////////////////
3445/// Set the bins for the underlined passed and total histograms
3446/// If the class have been already filled the previous contents will be lost
3447
3449 const Double_t *zBins )
3450{
3451 if (GetDimension() != 3) {
3452 Error("SetBins","Using wrong SetBins function for a %d-d histogram",GetDimension());
3453 return kFALSE;
3454 }
3455 if (fTotalHistogram->GetEntries() != 0 ) {
3456 Warning("SetBins","Histogram entries will be lost after SetBins");
3459 }
3462 return kTRUE;
3463}
3464
3465////////////////////////////////////////////////////////////////////////////////
3466/// Sets the confidence level (0 < level < 1)
3467/// The default value is 1-sigma :~ 0.683
3468
3470{
3471 if((level > 0) && (level < 1))
3472 fConfLevel = level;
3473 else
3474 Warning("SetConfidenceLevel(Double_t)","invalid confidence level %.2lf",level);
3475}
3476
3477////////////////////////////////////////////////////////////////////////////////
3478/// Sets the directory holding this TEfficiency object
3479///
3480/// A reference to this TEfficiency object is removed from the current
3481/// directory (if it exists) and a new reference to this TEfficiency object is
3482/// added to the given directory.
3483///
3484/// Notes: - If the given directory is 0, the TEfficiency object does not
3485/// belong to any directory and will not be written to file during the
3486/// next TFile::Write() command.
3487
3489{
3490 if(fDirectory == dir)
3491 return;
3492 if(fDirectory)
3493 fDirectory->Remove(this);
3494 fDirectory = dir;
3495 if(fDirectory)
3496 fDirectory->Append(this);
3497}
3498
3499////////////////////////////////////////////////////////////////////////////////
3500/// Sets the name
3501///
3502/// Note: The names of the internal histograms are set to "name + _total" and
3503/// "name + _passed" respectively.
3504
3506{
3508
3509 //setting the names (appending the correct ending)
3510 TString name_total = name + TString("_total");
3511 TString name_passed = name + TString("_passed");
3514}
3515
3516////////////////////////////////////////////////////////////////////////////////
3517/// Sets the number of passed events in the given global bin
3518///
3519/// returns "true" if the number of passed events has been updated
3520/// otherwise "false" ist returned
3521///
3522/// Note: - requires: 0 <= events <= fTotalHistogram->GetBinContent(bin)
3523
3525{
3526 if(events <= fTotalHistogram->GetBinContent(bin)) {
3527 fPassedHistogram->SetBinContent(bin,events);
3528 return true;
3529 }
3530 else {
3531 Error("SetPassedEvents(Int_t,Double_t)","total number of events (%.1lf) in bin %i is less than given number of passed events %.1lf",fTotalHistogram->GetBinContent(bin),bin,events);
3532 return false;
3533 }
3534}
3535
3536////////////////////////////////////////////////////////////////////////////////
3537/// Sets the histogram containing the passed events
3538///
3539/// The given histogram is cloned and stored internally as histogram containing
3540/// the passed events. The given histogram has to be consistent with the current
3541/// fTotalHistogram (see CheckConsistency(const TH1&,const TH1&)).
3542/// The method returns whether the fPassedHistogram has been replaced (true) or
3543/// not (false).
3544///
3545/// Note: The list of associated functions fFunctions is cleared.
3546///
3547/// Option:
3548/// - "f": force the replacement without checking the consistency
3549/// This can lead to inconsistent histograms and useless results
3550/// or unexpected behaviour. But sometimes it might be the only
3551/// way to change the histograms. If you use this option, you
3552/// should ensure that the fTotalHistogram is replaced by a
3553/// consistent one (with respect to rPassed) as well.
3554
3556{
3557 TString option = opt;
3558 option.ToLower();
3559
3560 Bool_t bReplace = option.Contains("f");
3561
3562 if(!bReplace)
3564
3565 if(bReplace) {
3566 delete fPassedHistogram;
3567 // do not add cloned histogram to gDirectory
3568 {
3569 TDirectory::TContext ctx(nullptr);
3570 fPassedHistogram = (TH1*)(rPassed.Clone());
3572 }
3573
3574 if(fFunctions)
3575 fFunctions->Delete();
3576
3577 //check whether both histograms are filled with weights
3579
3581
3582 return true;
3583 }
3584 else
3585 return false;
3586}
3587
3588////////////////////////////////////////////////////////////////////////////////
3589/// Sets the statistic option which affects the calculation of the confidence interval
3590///
3591/// Options:
3592/// - kFCP (=0)(default): using the Clopper-Pearson interval (recommended by PDG)
3593/// sets kIsBayesian = false
3594/// see also ClopperPearson
3595/// - kFNormal (=1) : using the normal approximation
3596/// sets kIsBayesian = false
3597/// see also Normal
3598/// - kFWilson (=2) : using the Wilson interval
3599/// sets kIsBayesian = false
3600/// see also Wilson
3601/// - kFAC (=3) : using the Agresti-Coull interval
3602/// sets kIsBayesian = false
3603/// see also AgrestiCoull
3604/// - kFFC (=4) : using the Feldman-Cousins frequentist method
3605/// sets kIsBayesian = false
3606/// see also FeldmanCousins
3607/// - kBJeffrey (=5) : using the Jeffrey interval
3608/// sets kIsBayesian = true, fBeta_alpha = 0.5 and fBeta_beta = 0.5
3609/// see also Bayesian
3610/// - kBUniform (=6) : using a uniform prior
3611/// sets kIsBayesian = true, fBeta_alpha = 1 and fBeta_beta = 1
3612/// see also Bayesian
3613/// - kBBayesian (=7) : using a custom prior defined by fBeta_alpha and fBeta_beta
3614/// sets kIsBayesian = true
3615/// see also Bayesian
3616/// - kMidP (=8) : using the Lancaster Mid-P method
3617/// sets kIsBayesian = false
3618
3619
3621{
3623
3624 switch(option)
3625 {
3626 case kFCP:
3628 SetBit(kIsBayesian,false);
3629 break;
3630 case kFNormal:
3631 fBoundary = &Normal;
3632 SetBit(kIsBayesian,false);
3633 break;
3634 case kFWilson:
3635 fBoundary = &Wilson;
3636 SetBit(kIsBayesian,false);
3637 break;
3638 case kFAC:
3640 SetBit(kIsBayesian,false);
3641 break;
3642 case kFFC:
3644 SetBit(kIsBayesian,false);
3645 break;
3646 case kMidP:
3648 SetBit(kIsBayesian,false);
3649 break;
3650 case kBJeffrey:
3651 fBeta_alpha = 0.5;
3652 fBeta_beta = 0.5;
3653 SetBit(kIsBayesian,true);
3654 SetBit(kUseBinPrior,false);
3655 break;
3656 case kBUniform:
3657 fBeta_alpha = 1;
3658 fBeta_beta = 1;
3659 SetBit(kIsBayesian,true);
3660 SetBit(kUseBinPrior,false);
3661 break;
3662 case kBBayesian:
3663 SetBit(kIsBayesian,true);
3664 break;
3665 default:
3668 SetBit(kIsBayesian,false);
3669 }
3670}
3671
3672////////////////////////////////////////////////////////////////////////////////
3673/// Sets the title
3674///
3675/// Notes:
3676/// - The titles of the internal histograms are set to "title + (total)"
3677/// or "title + (passed)" respectively.
3678/// - It is possible to label the axis of the histograms as usual (see
3679/// TH1::SetTitle).
3680///
3681/// Example: Setting the title to "My Efficiency" and label the axis
3682/// pEff->SetTitle("My Efficiency;x label;eff");
3683
3684void TEfficiency::SetTitle(const char* title)
3685{
3686
3687 //setting the titles (looking for the first semicolon and insert the tokens there)
3688 TString title_passed = title;
3689 TString title_total = title;
3690 Ssiz_t pos = title_passed.First(";");
3691 if (pos != kNPOS) {
3692 title_passed.Insert(pos," (passed)");
3693 title_total.Insert(pos," (total)");
3694 }
3695 else {
3696 title_passed.Append(" (passed)");
3697 title_total.Append(" (total)");
3698 }
3701
3702 // strip (total) for the TEfficiency title
3703 // HIstogram SetTitle has already stripped the axis
3705 teffTitle.ReplaceAll(" (total)","");
3707
3708}
3709
3710////////////////////////////////////////////////////////////////////////////////
3711/// Sets the number of total events in the given global bin
3712///
3713/// returns "true" if the number of total events has been updated
3714/// otherwise "false" ist returned
3715///
3716/// Note: - requires: fPassedHistogram->GetBinContent(bin) <= events
3717
3719{
3720 if(events >= fPassedHistogram->GetBinContent(bin)) {
3721 fTotalHistogram->SetBinContent(bin,events);
3722 return true;
3723 }
3724 else {
3725 Error("SetTotalEvents(Int_t,Double_t)","passed number of events (%.1lf) in bin %i is bigger than given number of total events %.1lf",fPassedHistogram->GetBinContent(bin),bin,events);
3726 return false;
3727 }
3728}
3729
3730////////////////////////////////////////////////////////////////////////////////
3731/// Sets the histogram containing all events
3732///
3733/// The given histogram is cloned and stored internally as histogram containing
3734/// all events. The given histogram has to be consistent with the current
3735/// fPassedHistogram (see CheckConsistency(const TH1&,const TH1&)).
3736/// The method returns whether the fTotalHistogram has been replaced (true) or
3737/// not (false).
3738///
3739/// Note: The list of associated functions fFunctions is cleared.
3740///
3741/// Option:
3742/// - "f": force the replacement without checking the consistency
3743/// This can lead to inconsistent histograms and useless results
3744/// or unexpected behaviour. But sometimes it might be the only
3745/// way to change the histograms. If you use this option, you
3746/// should ensure that the fPassedHistogram is replaced by a
3747/// consistent one (with respect to rTotal) as well.
3748
3750{
3751 TString option = opt;
3752 option.ToLower();
3753
3754 Bool_t bReplace = option.Contains("f");
3755
3756 if(!bReplace)
3758
3759 if(bReplace) {
3760 delete fTotalHistogram;
3761 // do not add cloned histogram to gDirectory
3762 {
3763 TDirectory::TContext ctx(nullptr);
3764 fTotalHistogram = (TH1*)(rTotal.Clone());
3765 }
3767
3768 if(fFunctions)
3769 fFunctions->Delete();
3770
3771 //check whether both histograms are filled with weights
3774
3775 return true;
3776 }
3777 else
3778 return false;
3779}
3780
3781////////////////////////////////////////////////////////////////////////////////
3782
3784{
3785 if (on && !TestBit(kUseWeights) )
3786 gROOT->Info("TEfficiency::SetUseWeightedEvents","Handle weighted events for computing efficiency");
3787
3789
3794}
3795
3796////////////////////////////////////////////////////////////////////////////////
3797/// Sets the global weight for this TEfficiency object
3798///
3799/// Note: - weight has to be positive ( > 0)
3800
3802{
3803 if(weight > 0)
3804 fWeight = weight;
3805 else
3806 Warning("SetWeight","invalid weight %.2lf",weight);
3807}
3808
3809////////////////////////////////////////////////////////////////////////////////
3810/**
3811Calculates the boundaries for the frequentist Wilson interval
3812
3813\param[in] total number of total events
3814\param[in] passed 0 <= number of passed events <= total
3815\param[in] level confidence level
3816\param[in] bUpper
3817 - true - upper boundary is returned
3818 - false - lower boundary is returned
3819
3820Calculation:
3821\f{eqnarray*}{
3822 \alpha &=& 1 - \frac{level}{2}\
3823 \kappa &=& \Phi^{-1}(1 - \alpha,1) ...\ normal\ quantile\ function\
3824 mode &=& \frac{passed + \frac{\kappa^{2}}{2}}{total + \kappa^{2}}\
3825 \Delta &=& \frac{\kappa}{total + \kappa^{2}} * \sqrt{passed (1 - \frac{passed}{total}) + \frac{\kappa^{2}}{4}}\
3826 return &=& max(0,mode - \Delta)\ or\ min(1,mode + \Delta)
3827\f}
3828
3829*/
3830
3832{
3833 Double_t alpha = (1.0 - level)/2;
3834 if (total == 0) return (bUpper) ? 1 : 0;
3835 Double_t average = ((Double_t)passed) / total;
3836 Double_t kappa = ROOT::Math::normal_quantile(1 - alpha,1);
3837
3838 Double_t mode = (passed + 0.5 * kappa * kappa) / (total + kappa * kappa);
3839 Double_t delta = kappa / (total + kappa*kappa) * std::sqrt(total * average
3840 * (1 - average) + kappa * kappa / 4);
3841 if(bUpper)
3842 return ((mode + delta) > 1) ? 1.0 : (mode + delta);
3843 else
3844 return ((mode - delta) < 0) ? 0.0 : (mode - delta);
3845}
3846
3847////////////////////////////////////////////////////////////////////////////////
3848/// Addition operator
3849///
3850/// adds the corresponding histograms:
3851/// ~~~ {.cpp}
3852/// lhs.GetTotalHistogram() + rhs.GetTotalHistogram()
3853/// lhs.GetPassedHistogram() + rhs.GetPassedHistogram()
3854/// ~~~
3855/// the statistic option and the confidence level are taken from lhs
3856
3858{
3859 TEfficiency tmp(lhs);
3860 tmp += rhs;
3861 return tmp;
3862}
3863
3864#endif
#define b(i)
Definition RSha256.hxx:100
#define a(i)
Definition RSha256.hxx:99
#define e(i)
Definition RSha256.hxx:103
int Int_t
Definition RtypesCore.h:45
constexpr Bool_t kFALSE
Definition RtypesCore.h:94
double Double_t
Definition RtypesCore.h:59
constexpr Ssiz_t kNPOS
Definition RtypesCore.h:117
constexpr Bool_t kTRUE
Definition RtypesCore.h:93
const char Option_t
Definition RtypesCore.h:66
#define ClassImp(name)
Definition Rtypes.h:374
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
#define gDirectory
Definition TDirectory.h:384
const TEfficiency operator+(const TEfficiency &lhs, const TEfficiency &rhs)
Addition operator.
const Double_t kDefBetaAlpha
const Double_t kDefWeight
const Double_t kDefBetaBeta
const TEfficiency::EStatOption kDefStatOpt
const Double_t kDefConfLevel
static unsigned int total
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t option
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void on
Option_t Option_t TPoint TPoint const char mode
char name[80]
Definition TGX11.cxx:110
float xmin
float ymin
float xmax
float ymax
#define gInterpreter
#define gROOT
Definition TROOT.h:406
#define gPad
User class for performing function minimization.
Template class to wrap any C++ callable object which takes one argument i.e.
Fill Area Attributes class.
Definition TAttFill.h:20
void Copy(TAttFill &attfill) const
Copy this fill attributes to a new TAttFill.
Definition TAttFill.cxx:207
virtual void SaveFillAttributes(std::ostream &out, const char *name, Int_t coldef=1, Int_t stydef=1001)
Save fill attributes as C++ statement(s) on output stream out.
Definition TAttFill.cxx:239
Line Attributes class.
Definition TAttLine.h:20
void Copy(TAttLine &attline) const
Copy this line attributes to a new TAttLine.
Definition TAttLine.cxx:177
virtual void SaveLineAttributes(std::ostream &out, const char *name, Int_t coldef=1, Int_t stydef=1, Int_t widdef=1)
Save line attributes as C++ statement(s) on output stream out.
Definition TAttLine.cxx:275
Marker Attributes class.
Definition TAttMarker.h:20
virtual void SaveMarkerAttributes(std::ostream &out, const char *name, Int_t coldef=1, Int_t stydef=1, Int_t sizdef=1)
Save line attributes as C++ statement(s) on output stream out.
virtual void SetMarkerStyle(Style_t mstyle=1)
Set the marker style.
Definition TAttMarker.h:41
void Copy(TAttMarker &attmarker) const
Copy this marker attributes to a new TAttMarker.
virtual void SetMarkerSize(Size_t msize=1)
Set the marker size.
Definition TAttMarker.h:46
Class to manage histogram axis.
Definition TAxis.h:32
virtual void SetBinLabel(Int_t bin, const char *label)
Set label for bin.
Definition TAxis.cxx:876
const char * GetTitle() const override
Returns title of object.
Definition TAxis.h:137
virtual Double_t GetBinCenter(Int_t bin) const
Return center of bin.
Definition TAxis.cxx:482
const TArrayD * GetXbins() const
Definition TAxis.h:138
Double_t GetXmax() const
Definition TAxis.h:142
const char * GetBinLabel(Int_t bin) const
Return label for bin.
Definition TAxis.cxx:444
virtual Int_t FindBin(Double_t x)
Find bin number corresponding to abscissa x.
Definition TAxis.cxx:296
virtual Double_t GetBinLowEdge(Int_t bin) const
Return low edge of bin.
Definition TAxis.cxx:522
virtual Int_t FindFixBin(Double_t x) const
Find bin number corresponding to abscissa x
Definition TAxis.cxx:423
Double_t GetXmin() const
Definition TAxis.h:141
Int_t GetNbins() const
Definition TAxis.h:127
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width.
Definition TAxis.cxx:546
THashList * GetLabels() const
Definition TAxis.h:123
Binomial fitter for the division of two histograms.
TFitResultPtr Fit(TF1 *f1, Option_t *option="")
Carry out the fit of the given function to the given histograms.
void * New(ENewType defConstructor=kClassNew, Bool_t quiet=kFALSE) const
Return a pointer to a newly allocated object of this class.
Definition TClass.cxx:5100
Collection abstract base class.
Definition TCollection.h:65
TDirectory::TContext keeps track and restore the current directory.
Definition TDirectory.h:89
Describe directory structure in memory.
Definition TDirectory.h:45
virtual void Append(TObject *obj, Bool_t replace=kFALSE)
Append object to this directory.
virtual TObject * Remove(TObject *)
Remove an object from the in-memory list.
Class to handle efficiency histograms.
Definition TEfficiency.h:29
void FillGraph2D(TGraph2DAsymmErrors *graph, Option_t *opt) const
Fill the graph to be painted with information from TEfficiency Internal method called by TEfficiency:...
void Draw(Option_t *opt="") override
Draws the current TEfficiency object.
void ExecuteEvent(Int_t event, Int_t px, Int_t py) override
Execute action corresponding to one event.
static Bool_t FeldmanCousinsInterval(Double_t total, Double_t passed, Double_t level, Double_t &lower, Double_t &upper)
Calculates the interval boundaries using the frequentist methods of Feldman-Cousins.
static Double_t BetaMode(Double_t alpha, Double_t beta)
Compute the mode of the beta distribution.
TH2 * CreateHistogram(Option_t *opt="") const
Create the histogram used to be painted (for dim=2 TEfficiency) The return object is managed by the c...
static Bool_t BetaShortestInterval(Double_t level, Double_t alpha, Double_t beta, Double_t &lower, Double_t &upper)
Calculates the boundaries for a shortest confidence interval for a Beta distribution.
static Bool_t CheckWeights(const TH1 &pass, const TH1 &total)
Check if both histogram are weighted.
static Double_t BetaMean(Double_t alpha, Double_t beta)
Compute the mean (average) of the beta distribution.
TEfficiency()
Default constructor.
Double_t GetBetaAlpha(Int_t bin=-1) const
void FillWeighted(Bool_t bPassed, Double_t weight, Double_t x, Double_t y=0, Double_t z=0)
This function is used for filling the two histograms with a weight.
~TEfficiency() override
default destructor
TList * GetListOfFunctions()
static Double_t Bayesian(Double_t total, Double_t passed, Double_t level, Double_t alpha, Double_t beta, Bool_t bUpper, Bool_t bShortest=false)
Calculates the boundaries for a Bayesian confidence interval (shortest or central interval depending ...
static Double_t AgrestiCoull(Double_t total, Double_t passed, Double_t level, Bool_t bUpper)
Calculates the boundaries for the frequentist Agresti-Coull interval.
Long64_t Merge(TCollection *list)
Merges the TEfficiency objects in the given list to the given TEfficiency object using the operator+=...
std::vector< std::pair< Double_t, Double_t > > fBeta_bin_params
Parameter for prior beta distribution different bin by bin (default vector is empty)
Definition TEfficiency.h:49
static Double_t FeldmanCousins(Double_t total, Double_t passed, Double_t level, Bool_t bUpper)
Calculates the boundaries for the frequentist Feldman-Cousins interval.
EStatOption fStatisticOption
Defines how the confidence intervals are determined.
Definition TEfficiency.h:59
void SetStatisticOption(EStatOption option)
Sets the statistic option which affects the calculation of the confidence interval.
void Paint(Option_t *opt) override
Paints this TEfficiency object.
void SetWeight(Double_t weight)
Sets the global weight for this TEfficiency object.
TH1 * fTotalHistogram
Histogram for total number of events.
Definition TEfficiency.h:60
Int_t GetDimension() const
returns the dimension of the current TEfficiency object
TGraph2DAsymmErrors * fPaintGraph2D
! Temporary graph for painting
Definition TEfficiency.h:56
TEfficiency & operator+=(const TEfficiency &rhs)
Adds the histograms of another TEfficiency object to current histograms.
Bool_t SetBins(Int_t nx, Double_t xmin, Double_t xmax)
Set the bins for the underlined passed and total histograms If the class have been already filled the...
void Build(const char *name, const char *title)
Building standard data structure of a TEfficiency object.
TH1 * GetCopyPassedHisto() const
Returns a cloned version of fPassedHistogram.
Double_t GetEfficiencyErrorUp(Int_t bin) const
Returns the upper error on the efficiency in the given global bin.
Double_t fBeta_alpha
Global parameter for prior beta distribution (default = 1)
Definition TEfficiency.h:47
void SavePrimitive(std::ostream &out, Option_t *opt="") override
Save primitive as a C++ statement(s) on output stream out.
void SetBetaBeta(Double_t beta)
Sets the shape parameter β.
static Bool_t CheckBinning(const TH1 &pass, const TH1 &total)
Checks binning for each axis.
void SetName(const char *name) override
Sets the name.
TGraph2DAsymmErrors * CreateGraph2D(Option_t *opt="") const
Create the graph used be painted (for dim=1 TEfficiency) The return object is managed by the caller.
Bool_t SetPassedEvents(Int_t bin, Double_t events)
Sets the number of passed events in the given global bin.
static Double_t BetaCentralInterval(Double_t level, Double_t alpha, Double_t beta, Bool_t bUpper)
Calculates the boundaries for a central confidence interval for a Beta distribution.
Int_t GetGlobalBin(Int_t binx, Int_t biny=0, Int_t binz=0) const
Returns the global bin number which can be used as argument for the following functions:
TH1 * fPassedHistogram
Histogram for events which passed certain criteria.
Definition TEfficiency.h:58
static Double_t MidPInterval(Double_t total, Double_t passed, Double_t level, Bool_t bUpper)
Calculates the boundaries using the mid-P binomial interval (Lancaster method) from B.
void SetBetaAlpha(Double_t alpha)
Sets the shape parameter α.
@ kIsBayesian
Bayesian statistics are used.
Definition TEfficiency.h:64
@ kUseWeights
Use weights.
Definition TEfficiency.h:68
@ kPosteriorMode
Use posterior mean for best estimate (Bayesian statistics)
Definition TEfficiency.h:65
@ kUseBinPrior
Use a different prior for each bin.
Definition TEfficiency.h:67
@ kShortestInterval
Use shortest interval.
Definition TEfficiency.h:66
static Bool_t CheckEntries(const TH1 &pass, const TH1 &total, Option_t *opt="")
Checks whether bin contents are compatible with binomial statistics.
static Double_t Normal(Double_t total, Double_t passed, Double_t level, Bool_t bUpper)
Returns the confidence limits for the efficiency supposing that the efficiency follows a normal distr...
Double_t fWeight
Weight for all events (default = 1)
Definition TEfficiency.h:61
Bool_t SetPassedHistogram(const TH1 &rPassed, Option_t *opt)
Sets the histogram containing the passed events.
Double_t GetBetaBeta(Int_t bin=-1) const
Double_t(* fBoundary)(Double_t, Double_t, Double_t, Bool_t)
! Pointer to a method calculating the boundaries of confidence intervals
Definition TEfficiency.h:51
void FillGraph(TGraphAsymmErrors *graph, Option_t *opt) const
Fill the graph to be painted with information from TEfficiency Internal method called by TEfficiency:...
static Double_t Combine(Double_t &up, Double_t &low, Int_t n, const Int_t *pass, const Int_t *total, Double_t alpha, Double_t beta, Double_t level=0.683, const Double_t *w=nullptr, Option_t *opt="")
void FillHistogram(TH2 *h2) const
Fill the 2d histogram to be painted with information from TEfficiency 2D Internal method called by TE...
Int_t FindFixBin(Double_t x, Double_t y=0, Double_t z=0) const
Returns the global bin number containing the given values.
TDirectory * fDirectory
! Pointer to directory holding this TEfficiency object
Definition TEfficiency.h:53
void SetUseWeightedEvents(Bool_t on=kTRUE)
static Double_t Wilson(Double_t total, Double_t passed, Double_t level, Bool_t bUpper)
Calculates the boundaries for the frequentist Wilson interval.
TEfficiency & operator=(const TEfficiency &rhs)
Assignment operator.
Int_t DistancetoPrimitive(Int_t px, Int_t py) override
Compute distance from point px,py to a graph.
Double_t fConfLevel
Confidence level (default = 0.683, 1 sigma)
Definition TEfficiency.h:52
Double_t fBeta_beta
Global parameter for prior beta distribution (default = 1)
Definition TEfficiency.h:48
Double_t GetEfficiency(Int_t bin) const
Returns the efficiency in the given global bin.
Bool_t SetTotalHistogram(const TH1 &rTotal, Option_t *opt)
Sets the histogram containing all events.
void Fill(Bool_t bPassed, Double_t x, Double_t y=0, Double_t z=0)
This function is used for filling the two histograms.
void SetDirectory(TDirectory *dir)
Sets the directory holding this TEfficiency object.
TGraphAsymmErrors * fPaintGraph
! Temporary graph for painting
Definition TEfficiency.h:55
TGraphAsymmErrors * CreateGraph(Option_t *opt="") const
Create the graph used be painted (for dim=1 TEfficiency) The return object is managed by the caller.
TList * fFunctions
->Pointer to list of functions
Definition TEfficiency.h:54
Bool_t SetTotalEvents(Int_t bin, Double_t events)
Sets the number of total events in the given global bin.
void SetBetaBinParameters(Int_t bin, Double_t alpha, Double_t beta)
Sets different shape parameter α and β for the prior distribution for each bin.
static Bool_t CheckConsistency(const TH1 &pass, const TH1 &total, Option_t *opt="")
Checks the consistence of the given histograms.
TH1 * GetCopyTotalHisto() const
Returns a cloned version of fTotalHistogram.
static Double_t ClopperPearson(Double_t total, Double_t passed, Double_t level, Bool_t bUpper)
Calculates the boundaries for the frequentist Clopper-Pearson interval.
void SetConfidenceLevel(Double_t level)
Sets the confidence level (0 < level < 1) The default value is 1-sigma :~ 0.683.
Double_t GetEfficiencyErrorLow(Int_t bin) const
Returns the lower error on the efficiency in the given global bin.
EStatOption
Enumeration type for different statistic options for calculating confidence intervals kF* ....
Definition TEfficiency.h:33
@ kBJeffrey
Jeffrey interval (Prior ~ Beta(0.5,0.5)
Definition TEfficiency.h:39
@ kFWilson
Wilson interval.
Definition TEfficiency.h:36
@ kFAC
Agresti-Coull interval.
Definition TEfficiency.h:37
@ kMidP
Mid-P Lancaster interval.
Definition TEfficiency.h:42
@ kBUniform
Prior ~ Uniform = Beta(1,1)
Definition TEfficiency.h:40
@ kFFC
Feldman-Cousins interval.
Definition TEfficiency.h:38
@ kBBayesian
User specified Prior ~ Beta(fBeta_alpha,fBeta_beta)
Definition TEfficiency.h:41
@ kFNormal
Normal approximation.
Definition TEfficiency.h:35
@ kFCP
Clopper-Pearson interval (recommended by PDG)
Definition TEfficiency.h:34
void SetTitle(const char *title) override
Sets the title.
TFitResultPtr Fit(TF1 *f1, Option_t *opt="")
Fits the efficiency using the TBinomialEfficiencyFitter class.
void RecursiveRemove(TObject *obj) override
Recursively remove object from the list of functions.
TH2 * fPaintHisto
! Temporary histogram for painting
Definition TEfficiency.h:57
1-Dim function class
Definition TF1.h:234
static TClass * Class()
void Copy(TObject &f1) const override
Copy this F1 to a new F1.
Definition TF1.cxx:1007
TClass * IsA() const override
Definition TF1.h:763
Provides an indirection to the TFitResult class and with a semantics identical to a TFitResult pointe...
Graph 2D class with errors.
Double_t * GetEYlow() const override
virtual void SetPointError(Int_t i, Double_t exl, Double_t exh, Double_t eyl, Double_t eyh, Double_t ezl, Double_t ezh)
Set ex, ey and ez values for point number i.
Double_t * GetEYhigh() const override
Double_t * GetEZhigh() const override
Double_t * GetEXhigh() const override
Double_t * GetEZlow() const override
void Set(Int_t n) override
Set number of points in the 2D graph.
void SetPoint(Int_t i, Double_t x, Double_t y, Double_t z) override
Set x, y and z values for point number i.
Double_t * GetEXlow() const override
Double_t * GetY() const
Definition TGraph2D.h:123
Double_t * GetX() const
Definition TGraph2D.h:122
TH2D * GetHistogram(Option_t *option="")
By default returns a pointer to the Delaunay histogram.
TAxis * GetZaxis() const
Get z axis of the graph.
Definition TGraph2D.cxx:903
void SetName(const char *name) override
Changes the name of this 2D graph.
void SetTitle(const char *title="") override
Sets the 2D graph title.
TAxis * GetYaxis() const
Get y axis of the graph.
Definition TGraph2D.cxx:892
Int_t GetN() const
Definition TGraph2D.h:121
void Paint(Option_t *option="") override
Paints this 2D graph with its current attributes.
TAxis * GetXaxis() const
Get x axis of the graph.
Definition TGraph2D.cxx:881
Double_t * GetZ() const
Definition TGraph2D.h:124
TGraph with asymmetric error bars.
Double_t * GetEXlow() const override
virtual void SetPointError(Double_t exl, Double_t exh, Double_t eyl, Double_t eyh)
Set ex and ey values for point pointed by the mouse.
Double_t * GetEYhigh() const override
Double_t * GetEXhigh() const override
Double_t * GetEYlow() const override
virtual void SetPoint(Int_t i, Double_t x, Double_t y)
Set x and y values for point number i.
Definition TGraph.cxx:2291
Double_t * GetY() const
Definition TGraph.h:139
void Paint(Option_t *chopt="") override
Draw this graph with its current attributes.
Definition TGraph.cxx:1978
Int_t GetN() const
Definition TGraph.h:131
void ExecuteEvent(Int_t event, Int_t px, Int_t py) override
Execute action corresponding to one event.
Definition TGraph.cxx:1058
Double_t * GetX() const
Definition TGraph.h:138
void SetName(const char *name="") override
Set graph name.
Definition TGraph.cxx:2330
TAxis * GetXaxis() const
Get x axis of the graph.
Definition TGraph.cxx:1567
virtual void PaintStats(TF1 *fit)
Draw the stats.
Definition TGraph.cxx:2005
TAxis * GetYaxis() const
Get y axis of the graph.
Definition TGraph.cxx:1576
virtual TH1F * GetHistogram() const
Returns a pointer to the histogram used to draw the axis Takes into account the two following cases.
Definition TGraph.cxx:1429
void SetTitle(const char *title="") override
Change (i.e.
Definition TGraph.cxx:2346
Int_t DistancetoPrimitive(Int_t px, Int_t py) override
Compute distance from point px,py to a graph.
Definition TGraph.cxx:881
virtual void Set(Int_t n)
Set number of points in the graph Existing coordinates are preserved New coordinates above fNpoints a...
Definition TGraph.cxx:2226
1-D histogram with a double per channel (see TH1 documentation)
Definition TH1.h:695
1-D histogram with a float per channel (see TH1 documentation)
Definition TH1.h:647
static TClass * Class()
TH1 is the base class of all histogram classes in ROOT.
Definition TH1.h:59
virtual void SetDirectory(TDirectory *dir)
By default, when a histogram is created, it is added to the list of histogram objects in the current ...
Definition TH1.cxx:8928
virtual void SetNormFactor(Double_t factor=1)
Definition TH1.h:427
virtual Double_t GetBinCenter(Int_t bin) const
Return bin center for 1D histogram.
Definition TH1.cxx:9132
TAxis * GetZaxis()
Definition TH1.h:343
Int_t DistancetoPrimitive(Int_t px, Int_t py) override
Compute distance from point px,py to a line.
Definition TH1.cxx:2795
void SetTitle(const char *title) override
Change/set the title.
Definition TH1.cxx:6721
virtual Int_t GetNbinsY() const
Definition TH1.h:315
virtual Int_t GetNbinsZ() const
Definition TH1.h:316
virtual Int_t GetDimension() const
Definition TH1.h:300
@ kIsAverage
Bin contents are average (used by Add)
Definition TH1.h:182
virtual void Reset(Option_t *option="")
Reset this histogram: contents, errors, etc.
Definition TH1.cxx:7106
TAxis * GetXaxis()
Definition TH1.h:341
virtual Int_t GetNcells() const
Definition TH1.h:317
virtual Int_t GetBin(Int_t binx, Int_t biny=0, Int_t binz=0) const
Return Global bin number corresponding to binx,y,z.
Definition TH1.cxx:4964
virtual Int_t GetNbinsX() const
Definition TH1.h:314
virtual Bool_t Add(TF1 *h1, Double_t c1=1, Option_t *option="")
Performs the operation: this = this + c1*f1 if errors are defined (see TH1::Sumw2),...
Definition TH1.cxx:814
virtual Int_t Fill(Double_t x)
Increment bin with abscissa X by 1.
Definition TH1.cxx:3316
TAxis * GetYaxis()
Definition TH1.h:342
virtual void SetBinContent(Int_t bin, Double_t content)
Set bin content see convention for numbering bins in TH1::GetBin In case the bin number is greater th...
Definition TH1.cxx:9213
virtual Double_t GetBinLowEdge(Int_t bin) const
Return bin lower edge for 1D histogram.
Definition TH1.cxx:9143
virtual Double_t GetEntries() const
Return the current number of entries.
Definition TH1.cxx:4401
void SetName(const char *name) override
Change the name of this histogram.
Definition TH1.cxx:8951
void Paint(Option_t *option="") override
Control routine to paint any kind of histograms.
Definition TH1.cxx:6209
@ kNstat
Size of statistics data (up to TProfile3D)
Definition TH1.h:195
void ExecuteEvent(Int_t event, Int_t px, Int_t py) override
Execute action corresponding to one event.
Definition TH1.cxx:3212
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition TH1.cxx:5064
virtual TArrayD * GetSumw2()
Definition TH1.h:330
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width for 1D histogram.
Definition TH1.cxx:9154
virtual Int_t GetSumw2N() const
Definition TH1.h:332
TObject * Clone(const char *newname="") const override
Make a complete copy of the underlying object.
Definition TH1.cxx:2724
virtual void SetBins(Int_t nx, Double_t xmin, Double_t xmax)
Redefine x axis parameters.
Definition TH1.cxx:8758
virtual void Sumw2(Bool_t flag=kTRUE)
Create structure to store sum of squares of weights.
Definition TH1.cxx:9011
static void SavePrimitiveFunctions(std::ostream &out, const char *varname, TList *lst)
Save list of functions Also can be used by TGraph classes.
Definition TH1.cxx:7426
virtual void SetStats(Bool_t stats=kTRUE)
Set statistics option on/off.
Definition TH1.cxx:8981
2-D histogram with a double per channel (see TH1 documentation)
Definition TH2.h:356
2-D histogram with a float per channel (see TH1 documentation)
Definition TH2.h:307
Service class for 2-D histogram classes.
Definition TH2.h:30
void SetBinContent(Int_t bin, Double_t content) override
Set bin content.
Definition TH2.cxx:2577
3-D histogram with a double per channel (see TH1 documentation)
Definition TH3.h:362
The 3-D histogram classes derived from the 1-D histogram classes.
Definition TH3.h:31
A doubly linked list.
Definition TList.h:38
void RecursiveRemove(TObject *obj) override
Remove object from this collection and recursively remove the object from all other objects (and coll...
Definition TList.cxx:762
void Add(TObject *obj) override
Definition TList.h:81
TObject * Remove(TObject *obj) override
Remove object from the list.
Definition TList.cxx:820
TObject * First() const override
Return the first object in the list. Returns 0 when list is empty.
Definition TList.cxx:657
void Delete(Option_t *option="") override
Remove all objects from the list AND delete all heap based objects.
Definition TList.cxx:468
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition TNamed.cxx:174
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
const char * GetTitle() const override
Returns title of object.
Definition TNamed.h:50
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition TNamed.cxx:150
Mother of all ROOT objects.
Definition TObject.h:41
R__ALWAYS_INLINE Bool_t TestBit(UInt_t f) const
Definition TObject.h:205
static TString SavePrimitiveVector(std::ostream &out, const char *prefix, Int_t len, Double_t *arr, Bool_t empty_line=kFALSE)
Save array in the output stream "out" as vector.
Definition TObject.cxx:788
virtual const char * ClassName() const
Returns name of class to which the object belongs.
Definition TObject.cxx:226
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:1057
virtual void AppendPad(Option_t *option="")
Append graphics object to current pad.
Definition TObject.cxx:203
void SetBit(UInt_t f, Bool_t set)
Set or unset the user status bits as specified in f.
Definition TObject.cxx:864
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition TObject.cxx:543
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1071
virtual void Fatal(const char *method, const char *msgfmt,...) const
Issue fatal error message.
Definition TObject.cxx:1099
static void SavePrimitiveDraw(std::ostream &out, const char *variable_name, Option_t *option=nullptr)
Save invocation of primitive Draw() method Skipped if option contains "nodraw" string.
Definition TObject.cxx:822
void ResetBit(UInt_t f)
Definition TObject.h:204
@ kInvalidObject
if object ctor succeeded but object should not be used
Definition TObject.h:78
Basic string class.
Definition TString.h:139
Ssiz_t Length() const
Definition TString.h:417
void ToLower()
Change string to lower-case.
Definition TString.cxx:1182
TString & ReplaceSpecialCppChars()
Find special characters which are typically used in printf() calls and replace them by appropriate es...
Definition TString.cxx:1114
const char * Data() const
Definition TString.h:376
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition TString.h:704
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:632
Ssiz_t Index(const char *pat, Ssiz_t i=0, ECaseCompare cmp=kExact) const
Definition TString.h:651
double beta_pdf(double x, double a, double b)
Probability density function of the beta distribution.
double beta_cdf(double x, double a, double b)
Cumulative distribution function of the beta distribution Upper tail of the integral of the beta_pdf.
double beta_cdf_c(double x, double a, double b)
Complement of the cumulative distribution function of the beta distribution.
double normal_quantile(double z, double sigma)
Inverse ( ) of the cumulative distribution function of the lower tail of the normal (Gaussian) distri...
double normal_quantile_c(double z, double sigma)
Inverse ( ) of the cumulative distribution function of the upper tail of the normal (Gaussian) distri...
double beta_quantile_c(double x, double a, double b)
Inverse ( ) of the cumulative distribution function of the lower tail of the beta distribution (beta_...
double beta_quantile(double x, double a, double b)
Inverse ( ) of the cumulative distribution function of the upper tail of the beta distribution (beta_...
const Double_t sigma
std::ostream & Info()
Definition hadd.cxx:171
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
TGraphErrors * gr
Definition legend1.C:25
TH1F * h1
Definition legend1.C:5
TF1 * f1
Definition legend1.C:11
R__ALWAYS_INLINE bool HasBeenDeleted(const TObject *obj)
Check if the TObject's memory has been deleted.
Definition TObject.h:408
Bool_t AreEqualRel(Double_t af, Double_t bf, Double_t relPrec)
Comparing floating points.
Definition TMath.h:426
Beta_interval_length(Double_t level, Double_t alpha, Double_t beta)
Double_t operator()(double lower) const