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