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