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