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