Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TGraphAsymmErrors.cxx
Go to the documentation of this file.
1// @(#)root/hist:$Id$
2// Author: Rene Brun 03/03/99
3
4/*************************************************************************
5 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6 * All rights reserved. *
7 * *
8 * For the licensing terms see $ROOTSYS/LICENSE. *
9 * For the list of contributors see $ROOTSYS/README/CREDITS. *
10 *************************************************************************/
11
12
13#include "TEfficiency.h"
14#include "TROOT.h"
15#include "TBuffer.h"
16#include "TGraphAsymmErrors.h"
17#include "TGraphErrors.h"
18#include "TStyle.h"
19#include "TMath.h"
20#include "TVirtualPad.h"
21#include "TF1.h"
22#include "TH1.h"
23#include "TVector.h"
24#include "TVectorD.h"
25#include "TSystem.h"
27#include "strtok.h"
28
29#include <cstring>
30#include <iostream>
31#include <fstream>
32
33
35
36/** \class TGraphAsymmErrors
37 \ingroup Graphs
38TGraph with asymmetric error bars.
39
40The TGraphAsymmErrors painting is performed thanks to the TGraphPainter
41class. All details about the various painting options are given in this class.
42
43The picture below gives an example:
44
45Begin_Macro(source)
46{
47 auto c1 = new TCanvas("c1","A Simple Graph with asymmetric error bars",200,10,700,500);
48 c1->SetFillColor(42);
49 c1->SetGrid();
50 c1->GetFrame()->SetFillColor(21);
51 c1->GetFrame()->SetBorderSize(12);
52 const Int_t n = 10;
53 Double_t x[n] = {-0.22, 0.05, 0.25, 0.35, 0.5, 0.61,0.7,0.85,0.89,0.95};
54 Double_t y[n] = {1,2.9,5.6,7.4,9,9.6,8.7,6.3,4.5,1};
55 Double_t exl[n] = {.05,.1,.07,.07,.04,.05,.06,.07,.08,.05};
56 Double_t eyl[n] = {.8,.7,.6,.5,.4,.4,.5,.6,.7,.8};
57 Double_t exh[n] = {.02,.08,.05,.05,.03,.03,.04,.05,.06,.03};
58 Double_t eyh[n] = {.6,.5,.4,.3,.2,.2,.3,.4,.5,.6};
59 auto gr = new TGraphAsymmErrors(n,x,y,exl,exh,eyl,eyh);
60 gr->SetTitle("TGraphAsymmErrors Example");
61 gr->SetMarkerColor(4);
62 gr->SetMarkerStyle(21);
63 gr->Draw("ALP");
64}
65End_Macro
66*/
67
68
69////////////////////////////////////////////////////////////////////////////////
70/// TGraphAsymmErrors default constructor.
71
73
74
75////////////////////////////////////////////////////////////////////////////////
76/// TGraphAsymmErrors copy constructor
77
79 : TGraph(gr)
80{
81 if (!CtorAllocate()) return;
82 Int_t n = fNpoints*sizeof(Double_t);
83 memcpy(fEXlow, gr.fEXlow, n);
84 memcpy(fEYlow, gr.fEYlow, n);
85 memcpy(fEXhigh, gr.fEXhigh, n);
86 memcpy(fEYhigh, gr.fEYhigh, n);
87}
88
89
90////////////////////////////////////////////////////////////////////////////////
91/// TGraphAsymmErrors assignment operator.
92
94{
95 if(this!=&gr) {
97 // delete arrays
98 if (fEXlow) delete [] fEXlow;
99 if (fEYlow) delete [] fEYlow;
100 if (fEXhigh) delete [] fEXhigh;
101 if (fEYhigh) delete [] fEYhigh;
102
103 if (!CtorAllocate()) return *this;
104 Int_t n = fNpoints*sizeof(Double_t);
105 memcpy(fEXlow, gr.fEXlow, n);
106 memcpy(fEYlow, gr.fEYlow, n);
107 memcpy(fEXhigh, gr.fEXhigh, n);
108 memcpy(fEYhigh, gr.fEYhigh, n);
109 }
110 return *this;
111}
112
113
114////////////////////////////////////////////////////////////////////////////////
115/// TGraphAsymmErrors normal constructor.
116///
117/// the arrays are preset to zero
118
120 : TGraph(n)
121{
122 if (!CtorAllocate()) return;
123 FillZero(0, fNpoints);
124}
125
126
127////////////////////////////////////////////////////////////////////////////////
128/// TGraphAsymmErrors normal constructor.
129///
130/// if exl,h or eyl,h are null, the corresponding arrays are preset to zero
131
133 : TGraph(n,x,y)
134{
135 if (!CtorAllocate()) return;
136
137 for (Int_t i=0;i<n;i++) {
138 if (exl) fEXlow[i] = exl[i];
139 else fEXlow[i] = 0;
140 if (exh) fEXhigh[i] = exh[i];
141 else fEXhigh[i] = 0;
142 if (eyl) fEYlow[i] = eyl[i];
143 else fEYlow[i] = 0;
144 if (eyh) fEYhigh[i] = eyh[i];
145 else fEYhigh[i] = 0;
146 }
147}
148
149
150////////////////////////////////////////////////////////////////////////////////
151/// TGraphAsymmErrors normal constructor.
152///
153/// if exl,h or eyl,h are null, the corresponding arrays are preset to zero
154
156 : TGraph(n,x,y)
157{
158 if (!CtorAllocate()) return;
159
160 n = fNpoints*sizeof(Double_t);
161 if (exl)
162 memcpy(fEXlow, exl, n);
163 else
164 memset(fEXlow, 0, n);
165 if (exh)
166 memcpy(fEXhigh, exh, n);
167 else
168 memset(fEXhigh, 0, n);
169 if (eyl)
170 memcpy(fEYlow, eyl, n);
171 else
172 memset(fEYlow, 0, n);
173 if (eyh)
174 memcpy(fEYhigh, eyh, n);
175 else
176 memset(fEYhigh, 0, n);
177}
178
179
180////////////////////////////////////////////////////////////////////////////////
181/// Constructor with six vectors of floats in input
182/// A grapherrors is built with the X coordinates taken from vx and Y coord from vy
183/// and the errors from vectors vexl/h and veyl/h.
184/// The number of points in the graph is the minimum of number of points
185/// in vx and vy.
186
188{
189 fNpoints = TMath::Min(vx.GetNrows(), vy.GetNrows());
190 if (!TGraph::CtorAllocate()) return;
191 if (!CtorAllocate()) return;
192 Int_t ivxlow = vx.GetLwb();
193 Int_t ivylow = vy.GetLwb();
194 Int_t ivexllow = vexl.GetLwb();
195 Int_t ivexhlow = vexh.GetLwb();
196 Int_t iveyllow = veyl.GetLwb();
197 Int_t iveyhlow = veyh.GetLwb();
198 for (Int_t i=0;i<fNpoints;i++) {
199 fX[i] = vx(i+ivxlow);
200 fY[i] = vy(i+ivylow);
201 fEXlow[i] = vexl(i+ivexllow);
202 fEYlow[i] = veyl(i+iveyllow);
203 fEXhigh[i] = vexh(i+ivexhlow);
204 fEYhigh[i] = veyh(i+iveyhlow);
205 }
206}
207
208
209////////////////////////////////////////////////////////////////////////////////
210/// Constructor with six vectors of doubles in input
211/// A grapherrors is built with the X coordinates taken from vx and Y coord from vy
212/// and the errors from vectors vexl/h and veyl/h.
213/// The number of points in the graph is the minimum of number of points
214/// in vx and vy.
215
217{
218 fNpoints = TMath::Min(vx.GetNrows(), vy.GetNrows());
219 if (!TGraph::CtorAllocate()) return;
220 if (!CtorAllocate()) return;
221 Int_t ivxlow = vx.GetLwb();
222 Int_t ivylow = vy.GetLwb();
223 Int_t ivexllow = vexl.GetLwb();
224 Int_t ivexhlow = vexh.GetLwb();
225 Int_t iveyllow = veyl.GetLwb();
226 Int_t iveyhlow = veyh.GetLwb();
227 for (Int_t i=0;i<fNpoints;i++) {
228 fX[i] = vx(i+ivxlow);
229 fY[i] = vy(i+ivylow);
230 fEXlow[i] = vexl(i+ivexllow);
231 fEYlow[i] = veyl(i+iveyllow);
232 fEXhigh[i] = vexh(i+ivexhlow);
233 fEYhigh[i] = veyh(i+iveyhlow);
234 }
235}
236
237
238////////////////////////////////////////////////////////////////////////////////
239/// TGraphAsymmErrors constructor importing its parameters from the TH1 object passed as argument
240/// the low and high errors are set to the bin error of the histogram.
241
243 : TGraph(h)
244{
245 if (!CtorAllocate()) return;
246
247 for (Int_t i = 0; i < fNpoints; i++) {
248 fEXlow[i] = h->GetBinWidth(i+1)*gStyle->GetErrorX();
249 fEXhigh[i] = fEXlow[i];
250 fEYlow[i] = h->GetBinErrorLow(i+1);
251 fEYhigh[i] = h->GetBinErrorUp(i+1);
252 }
253}
254
255
256////////////////////////////////////////////////////////////////////////////////
257/// Creates a TGraphAsymmErrors by dividing two input TH1 histograms:
258/// pass/total. (see TGraphAsymmErrors::Divide)
259
261 : TGraph((pass)?pass->GetNbinsX():0)
262{
263 if (!pass || !total) {
264 Error("TGraphAsymmErrors","Invalid histogram pointers");
265 return;
266 }
267 if (!CtorAllocate()) return;
268
269 std::string sname = "divide_" + std::string(pass->GetName()) + "_by_" +
270 std::string(total->GetName());
271 SetName(sname.c_str());
272 SetTitle(pass->GetTitle());
273
274 //copy style from pass
275 pass->TAttLine::Copy(*this);
276 pass->TAttFill::Copy(*this);
277 pass->TAttMarker::Copy(*this);
278
280}
281
282
283////////////////////////////////////////////////////////////////////////////////
284/// TGraphAsymmErrors constructor reading input from filename
285/// filename is assumed to contain at least 2 columns of numbers
286///
287/// Convention for format (default=`"%lg %lg %lg %lg %lg %lg"`)
288///
289/// - format = `"%lg %lg"` read only 2 first columns into X, Y
290/// - format = `"%lg %lg %lg %lg"` read only 4 first columns into X, Y, EYL, EYH
291/// - format = `"%lg %lg %lg %lg %lg %lg"` read only 6 first columns into X, Y, EXL, EXH, EYL, EYH
292///
293/// For files separated by a specific delimiter different from ' ' and `\\t` (e.g. `;` in csv files)
294/// you can avoid using `%*s` to bypass this delimiter by explicitly specify the `option` argument,
295/// e.g. `option=" \\t,;"` for columns of figures separated by any of these characters (`' ', '\\t', ',', ';'`)
296/// used once (e.g. `"1;1"`) or in a combined way (`" 1;,;; 1"`).
297///
298/// Note in that case, the instantiation is about 2 times slower.
299/// In case a delimiter is specified, the format `"%lg %lg %lg"` will read X,Y,EXL.
300
302 : TGraph(100)
303{
304 if (!CtorAllocate()) return;
305 Double_t x, y, exl, exh, eyl, eyh;
308 std::ifstream infile(fname.Data());
309 if (!infile.good()) {
310 MakeZombie();
311 Error("TGraphAsymmErrors", "Cannot open file: %s, TGraphAsymmErrors is Zombie", filename);
312 fNpoints = 0;
313 return;
314 }
315 std::string line;
316 Int_t np = 0;
317
318 if (strcmp(option, "") == 0) { // No delimiters specified (standard constructor).
319
320 Int_t ncol = TGraphErrors::CalculateScanfFields(format); //count number of columns in format
321 Int_t res;
322 while (std::getline(infile, line, '\n')) {
323 exl = exh = eyl = eyh = 0.;
324 if (ncol < 3) {
325 res = sscanf(line.c_str(), format, &x, &y);
326 } else if (ncol < 5) {
327 res = sscanf(line.c_str(), format, &x, &y, &eyl, &eyh);
328 } else {
329 res = sscanf(line.c_str(), format, &x, &y, &exl, &exh, &eyl, &eyh);
330 }
331 if (res < 2) {
332 continue; //skip empty and ill-formed lines
333 }
334 SetPoint(np, x, y);
336 np++;
337 }
338 Set(np);
339
340 } else { // A delimiter has been specified in "option"
341
342 // Checking format and creating its boolean equivalent
344 format_.ReplaceAll(" ", "") ;
345 format_.ReplaceAll("\t", "") ;
346 format_.ReplaceAll("lg", "") ;
347 format_.ReplaceAll("s", "") ;
348 format_.ReplaceAll("%*", "0") ;
349 format_.ReplaceAll("%", "1") ;
350 if (!format_.IsDigit()) {
351 Error("TGraphAsymmErrors", "Incorrect input format! Allowed format tags are {\"%%lg\",\"%%*lg\" or \"%%*s\"}");
352 return ;
353 }
354 Int_t ntokens = format_.Length() ;
355 if (ntokens < 2) {
356 Error("TGraphAsymmErrors", "Incorrect input format! Only %d tag(s) in format whereas at least 2 \"%%lg\" tags are expected!", ntokens);
357 return ;
358 }
361 for (Int_t idx = 0; idx < ntokens; idx++) {
362 isTokenToBeSaved[idx] = TString::Format("%c", format_[idx]).Atoi(); //atoi(&format_[idx]) does not work for some reason...
363 if (isTokenToBeSaved[idx] == 1) {
365 }
366 }
367 if (ntokens >= 2 && (ntokensToBeSaved < 2 || ntokensToBeSaved > 6)) { //first condition not to repeat the previous error message
368 Error("TGraphAsymmErrors", "Incorrect input format! There are %d \"%%lg\" tag(s) in format whereas 2, 3, 4, 5 or 6 are expected!", ntokensToBeSaved);
369 delete [] isTokenToBeSaved;
370 return ;
371 }
372
373 // Initializing loop variables
374 Bool_t isLineToBeSkipped = kFALSE; //empty and ill-formed lines
375 char *token = nullptr;
376 TString token_str = "";
377 Int_t token_idx = 0;
378 Double_t value[6]; //x,y,exl, exh, eyl, eyh buffers
379 for (Int_t k = 0; k < 6; k++)
380 value[k] = 0.;
381 Int_t value_idx = 0;
382
383 // Looping
384 char *rest;
385 while (std::getline(infile, line, '\n')) {
386 if (!line.empty()) {
387 if (line[line.size() - 1] == char(13)) { // removing DOS CR character
388 line.erase(line.end() - 1, line.end()) ;
389 }
390 token = R__STRTOK_R(const_cast<char*>(line.c_str()), option, &rest) ;
391 while (token != nullptr && value_idx < ntokensToBeSaved) {
394 token_str.ReplaceAll("\t", "") ;
395 if (!token_str.IsFloat()) {
397 break ;
398 } else {
399 value[value_idx] = token_str.Atof() ;
400 value_idx++ ;
401 }
402 }
403 token = R__STRTOK_R(nullptr, option, &rest); // next token
404 token_idx++ ;
405 }
406 if (!isLineToBeSkipped && value_idx > 1) { //i.e. 2, 3, 4, 5 or 6
407 x = value[0];
408 y = value[1];
409 exl = value[2];
410 exh = value[3];
411 eyl = value[4];
412 eyh = value[5];
413 SetPoint(np, x, y);
415 np++ ;
416 }
417 }
419 token = nullptr;
420 token_idx = 0;
421 value_idx = 0;
422 }
423 Set(np) ;
424
425 // Cleaning
426 delete [] isTokenToBeSaved;
427 delete token;
428 }
429 infile.close();
430}
431
432////////////////////////////////////////////////////////////////////////////////
433/// TGraphAsymmErrors default destructor.
434
436{
437 if(fEXlow) delete [] fEXlow;
438 if(fEXhigh) delete [] fEXhigh;
439 if(fEYlow) delete [] fEYlow;
440 if(fEYhigh) delete [] fEYhigh;
441}
442
443////////////////////////////////////////////////////////////////////////////////
444/// Allocate internal data structures for `size` points.
445
449
450////////////////////////////////////////////////////////////////////////////////
451/// Add a point with asymmetric errorbars to the graph.
452
458
459////////////////////////////////////////////////////////////////////////////////
460/// Apply a function to all data points \f$ y = f(x,y) \f$
461///
462/// Errors are calculated as \f$ eyh = f(x,y+eyh)-f(x,y) \f$ and
463/// \f$ eyl = f(x,y)-f(x,y-eyl) \f$
464///
465/// Special treatment has to be applied for the functions where the
466/// role of "up" and "down" is reversed.
467///
468/// Function suggested/implemented by Miroslav Helbich <helbich@mail.desy.de>
469
471{
473
474 if (fHistogram) {
475 delete fHistogram;
476 fHistogram = nullptr;
477 }
478 for (Int_t i=0;i<GetN();i++) {
479 GetPoint(i,x,y);
480 exl = GetErrorXlow(i);
481 exh = GetErrorXhigh(i);
482 eyl = GetErrorYlow(i);
483 eyh = GetErrorYhigh(i);
484
485 fxy = f->Eval(x,y);
486 SetPoint(i,x,fxy);
487
488 // in the case of the functions like y-> -1*y the roles of the
489 // upper and lower error bars is reversed
490 if (f->Eval(x,y-eyl)<f->Eval(x,y+eyh)) {
491 eyl_new = TMath::Abs(fxy - f->Eval(x,y-eyl));
492 eyh_new = TMath::Abs(f->Eval(x,y+eyh) - fxy);
493 } else {
494 eyh_new = TMath::Abs(fxy - f->Eval(x,y-eyl));
495 eyl_new = TMath::Abs(f->Eval(x,y+eyh) - fxy);
496 }
497
498 //error on x doesn't change
500 }
501 if (gPad) gPad->Modified();
502}
503
504////////////////////////////////////////////////////////////////////////////////
505///This function is only kept for backward compatibility.
506///You should rather use the Divide method.
507///It calls `Divide(pass,total,"cl=0.683 b(1,1) mode")` which is equivalent to the
508///former BayesDivide method.
509
511{
512 Divide(pass,total,"cl=0.683 b(1,1) mode");
513}
514
515////////////////////////////////////////////////////////////////////////////////
516/// Fill this TGraphAsymmErrors by dividing two 1-dimensional histograms pass/total
517///
518/// This method serves two purposes:
519///
520/// ### 1) calculating efficiencies:
521///
522/// The assumption is that the entries in "pass" are a subset of those in
523/// "total". That is, we create an "efficiency" graph, where each entry is
524/// between 0 and 1, inclusive.
525///
526/// If the histograms are not filled with unit weights, the number of effective
527/// entries is used to normalise the bin contents which might lead to wrong results.
528/// \f[
529/// \text{effective entries} = \frac{(\sum w_{i})^{2}}{\sum w_{i}^{2}}
530/// \f]
531/// The points are assigned a x value at the center of each histogram bin.
532/// The y values are \f$\text{eff} = \frac{\text{pass}}{\text{total}}\f$
533/// for all options except for the
534/// bayesian methods where the result depends on the chosen option.
535///
536/// If the denominator becomes 0 or pass > total, the corresponding bin is
537/// skipped.
538///
539/// ### 2) calculating ratios of two Poisson means (option 'pois'):
540///
541/// The two histograms are interpreted as independent Poisson processes and the ratio
542/// \f[
543/// \tau = \frac{n_{1}}{n_{2}} = \frac{\varepsilon}{1 - \varepsilon}
544/// \f]
545/// with \f$\varepsilon = \frac{n_{1}}{n_{1} + n_{2}}\f$.
546/// The histogram 'pass' is interpreted as \f$n_{1}\f$ and the total histogram
547/// is used for \f$n_{2}\f$.
548///
549/// The (asymmetric) uncertainties of the Poisson ratio are linked to the uncertainties
550/// of efficiency by a parameter transformation:
551/// \f[
552/// \Delta \tau_{low/up} = \frac{1}{(1 - \varepsilon)^{2}} \Delta \varepsilon_{low/up}
553/// \f]
554///
555/// The x errors span each histogram bin (lowedge ... lowedge+width)
556/// The y errors depend on the chosen statistic methode which can be determined
557/// by the options given below. For a detailed description of the used statistic
558/// calculations please have a look at the corresponding functions!
559///
560/// Options:
561/// - v : verbose mode: prints information about the number of used bins
562/// and calculated efficiencies with their errors
563/// - cl=x : determine the used confidence level (0<x<1) (default is 0.683)
564/// - cp : Clopper-Pearson interval (see TEfficiency::ClopperPearson)
565/// - w : Wilson interval (see TEfficiency::Wilson)
566/// - n : normal approximation propagation (see TEfficiency::Normal)
567/// - ac : Agresti-Coull interval (see TEfficiency::AgrestiCoull)
568/// - fc : Feldman-Cousins interval (see TEfficiency::FeldmanCousinsInterval)
569/// - midp : Lancaster mid-P interval (see TEfficiency::MidPInterval)
570/// - b(a,b): bayesian interval using a prior probability ~Beta(a,b); a,b > 0
571/// (see TEfficiency::Bayesian)
572/// - mode : use mode of posterior for Bayesian interval (default is mean)
573/// - shortest: use shortest interval (done by default if mode is set)
574/// - central: use central interval (done by default if mode is NOT set)
575/// - pois: interpret histograms as poisson ratio instead of efficiency
576/// - e0 : plot efficiency and interval for bins where total=0
577/// (default is to skip them)
578///
579/// Note:
580/// Unfortunately there is no straightforward approach for determining a confidence
581/// interval for a given confidence level. The actual coverage probability of the
582/// confidence interval oscillates significantly according to the total number of
583/// events and the true efficiency. In order to decrease the impact of this
584/// oscillation on the actual coverage probability a couple of approximations and
585/// methodes has been developed. For a detailed discussion, please have a look at
586/// this statistical paper:
587/// http://www-stat.wharton.upenn.edu/~tcai/paper/Binomial-StatSci.pdf
588
589
591{
592 //check pointers
593 if(!pass || !total) {
594 Error("Divide","one of the passed pointers is zero");
595 return;
596 }
597
598 //check dimension of histograms; only 1-dimensional ones are accepted
599 if((pass->GetDimension() > 1) || (total->GetDimension() > 1)) {
600 Error("Divide","passed histograms are not one-dimensional");
601 return;
602 }
603
604 //check whether histograms are filled with weights -> use number of effective
605 //entries
606 Bool_t bEffective = false;
607 //compare sum of weights with sum of squares of weights
608 // re-compute here to be sure to get the right values
609 Double_t psumw = 0;
610 Double_t psumw2 = 0;
611 if (pass->GetSumw2()->fN > 0) {
612 for (int i = 0; i < pass->GetNcells(); ++i) {
613 psumw += pass->GetBinContent(i);
614 psumw2 += pass->GetSumw2()->At(i);
615 }
616 }
617 else {
618 psumw = pass->GetSumOfWeights();
619 psumw2 = psumw;
620 }
621 if (TMath::Abs(psumw - psumw2) > 1e-6)
622 bEffective = true;
623
624 Double_t tsumw = 0;
625 Double_t tsumw2 = 0;
626 if (total->GetSumw2()->fN > 0) {
627 for (int i = 0; i < total->GetNcells(); ++i) {
628 tsumw += total->GetBinContent(i);
629 tsumw2 += total->GetSumw2()->At(i);
630 }
631 }
632 else {
633 tsumw = total->GetSumOfWeights();
634 tsumw2 = tsumw;
635 }
636 if (TMath::Abs(tsumw - tsumw2) > 1e-6)
637 bEffective = true;
638
639
640
641 // we do not want to ignore the weights
642 // if (bEffective && (pass->GetSumw2()->fN == 0 || total->GetSumw2()->fN == 0) ) {
643 // Warning("Divide","histogram have been computed with weights but the sum of weight squares are not stored in the histogram. Error calculation is performed ignoring the weights");
644 // bEffective = false;
645 // }
646
647 //parse option
648 TString option = opt;
649 option.ToLower();
650
651 Bool_t bVerbose = false;
652 //pointer to function returning the boundaries of the confidence interval
653 //(is only used in the frequentist cases.)
655 //confidence level
656 Double_t conf = 0.682689492137;
657 //values for bayesian statistics
658 Bool_t bIsBayesian = false;
659 Double_t alpha = 1;
660 Double_t beta = 1;
661
662 //verbose mode
663 if(option.Contains("v")) {
664 option.ReplaceAll("v","");
665 bVerbose = true;
666 if (bEffective)
667 Info("Divide","weight will be considered in the Histogram Ratio");
668 }
669
670
671 //confidence level
672 if(option.Contains("cl=")) {
673 Double_t level = -1;
674 // coverity [secure_coding : FALSE]
675 sscanf(strstr(option.Data(),"cl="),"cl=%lf",&level);
676 if((level > 0) && (level < 1))
677 conf = level;
678 else
679 Warning("Divide","given confidence level %.3lf is invalid",level);
680 option.ReplaceAll("cl=","");
681 }
682
683 // look for statistic options
684 // check first Bayesian case
685 // bayesian with prior
686 Bool_t usePosteriorMode = false;
688 if (option.Contains("b(")) {
689 Double_t a = 0;
690 Double_t b = 0;
691 sscanf(strstr(option.Data(), "b("), "b(%lf,%lf)", &a, &b);
692 if (a > 0)
693 alpha = a;
694 else
695 Warning("Divide", "given shape parameter for alpha %.2lf is invalid", a);
696 if (b > 0)
697 beta = b;
698 else
699 Warning("Divide", "given shape parameter for beta %.2lf is invalid", b);
700 option.ReplaceAll("b(", "");
701 bIsBayesian = true;
702
703 // look for specific bayesian options
704
705 // use posterior mode
706
707 if (option.Contains("mode")) {
708 usePosteriorMode = true;
709 option.ReplaceAll("mode", "");
710 }
711 if (option.Contains("sh") || (usePosteriorMode && !option.Contains("cen"))) {
712 useShortestInterval = true;
713 }
714 }
715 // normal approximation
716 else if (option.Contains("n")) {
717 option.ReplaceAll("n", "");
719 }
720 // clopper pearson interval
721 else if (option.Contains("cp")) {
722 option.ReplaceAll("cp", "");
724 }
725 // wilson interval
726 else if (option.Contains("w")) {
727 option.ReplaceAll("w", "");
729 }
730 // agresti coull interval
731 else if (option.Contains("ac")) {
732 option.ReplaceAll("ac", "");
734 }
735 // Feldman-Cousins interval
736 else if (option.Contains("fc")) {
737 option.ReplaceAll("fc", "");
739 }
740 // mid-P Lancaster interval
741 else if (option.Contains("midp")) {
742 option.ReplaceAll("midp", "");
744 }
745
746 // interpret as Poisson ratio
747 Bool_t bPoissonRatio = false;
748 if (option.Contains("pois")) {
749 bPoissonRatio = true;
750 option.ReplaceAll("pois", "");
751 }
752 Bool_t plot0Bins = false;
753 if (option.Contains("e0")) {
754 plot0Bins = true;
755 option.ReplaceAll("e0", "");
756 }
757
758 // weights works only in case of Normal approximation or Bayesian for binomial interval
759 // in case of Poisson ratio we can use weights by rescaling the obtained results using the effective entries
761 Warning("Divide", "Histograms have weights: only Normal or Bayesian error calculation is supported");
762 Info("Divide", "Using now the Normal approximation for weighted histograms");
763 }
764
765 if (bPoissonRatio) {
766 if (pass->GetDimension() != total->GetDimension()) {
767 Error("Divide", "passed histograms are not of the same dimension");
768 return;
769 }
770
772 Error("Divide", "passed histograms are not consistent");
773 return;
774 }
775 } else {
776 // check consistency of histograms, allowing weights
778 Error("Divide", "passed histograms are not consistent");
779 return;
780 }
781 }
782
783 // Set the graph to have a number of points equal to the number of histogram
784 // bins
785 Int_t nbins = pass->GetNbinsX();
786 Set(nbins);
787
788 // Ok, now set the points for each bin
789 // (Note: the TH1 bin content is shifted to the right by one:
790 // bin=0 is underflow, bin=nbins+1 is overflow.)
791
792 //efficiency with lower and upper boundary of confidence interval
793 double eff, low, upper;
794 //this keeps track of the number of points added to the graph
795 int npoint=0;
796 //number of total and passed events
797 Double_t t = 0 , p = 0;
798 Double_t tw = 0, tw2 = 0, pw = 0, pw2 = 0, wratio = 1; // for the case of weights
799 //loop over all bins and fill the graph
800 for (Int_t b=1; b<=nbins; ++b) {
801
802 // default value when total =0;
803 eff = 0;
804 low = 0;
805 upper = 0;
806
807 // special case in case of weights we have to consider the sum of weights and the sum of weight squares
808 if (bEffective) {
809 tw = total->GetBinContent(b);
810 tw2 = (total->GetSumw2()->fN > 0) ? total->GetSumw2()->At(b) : tw;
811 pw = pass->GetBinContent(b);
812 pw2 = (pass->GetSumw2()->fN > 0) ? pass->GetSumw2()->At(b) : pw;
813
814 if (bPoissonRatio) {
815 // tw += pw;
816 // tw2 += pw2;
817 // compute ratio on the effective entries ( p and t)
818 // special case is when (pw=0, pw2=0) in this case we cannot get the bin weight.
819 // we use then the overall weight of the full histogram
820 if (pw == 0 && pw2 == 0)
821 p = 0;
822 else
823 p = (pw * pw) / pw2;
824
825 if (tw == 0 && tw2 == 0)
826 t = 0;
827 else
828 t = (tw * tw) / tw2;
829
830 if (pw > 0 && tw > 0)
831 // this is the ratio of the two bin weights ( pw/p / t/tw )
832 wratio = (pw * t) / (p * tw);
833 else if (pw == 0 && tw > 0)
834 // case p histogram has zero compute the weights from all the histogram
835 // weight of histogram - sumw2/sumw
836 wratio = (psumw2 * t) / (psumw * tw);
837 else if (tw == 0 && pw > 0)
838 // case t histogram has zero compute the weights from all the histogram
839 // weight of histogram - sumw2/sumw
840 wratio = (pw * tsumw) / (p * tsumw2);
841 else if (p > 0)
842 wratio = pw / p; // not sure if needed
843 else {
844 // case both pw and tw are zero - we skip these bins
845 if (!plot0Bins) continue; // skip bins with total <= 0
846 }
847
848 t += p;
849 // std::cout << p << " " << t << " " << wratio << std::endl;
850 } else if (tw <= 0 && !plot0Bins)
851 continue; // skip bins with total <= 0
852
853 // in the case of weights have the formula only for
854 // the normal and bayesian statistics (see below)
855
856 }
857
858 // use bin contents
859 else {
860 t = std::round(total->GetBinContent(b));
861 p = std::round(pass->GetBinContent(b));
862
863 if (bPoissonRatio)
864 t += p;
865
866 if (t == 0.0 && !plot0Bins)
867 continue; // skip bins with total = 0
868 }
869
870 //using bayesian statistics
871 if(bIsBayesian) {
872 double aa,bb;
873
874 if ((bEffective && !bPoissonRatio) && tw2 <= 0) {
875 // case of bins with zero errors
876 eff = pw/tw;
877 low = eff; upper = eff;
878 }
879 else {
880
881 if (bEffective && !bPoissonRatio) {
882 // tw/tw2 re-normalize the weights
883 double norm = tw/tw2; // case of tw2 = 0 is treated above
884 aa = pw * norm + alpha;
885 bb = (tw - pw) * norm + beta;
886 }
887 else {
888 aa = double(p) + alpha;
889 bb = double(t-p) + beta;
890 }
893 else
895
898 }
899 else {
902 }
903 }
904 }
905 // case of non-bayesian statistics
906 else {
907 if (bEffective && !bPoissonRatio) {
908
909 if (tw > 0) {
910
911 eff = pw/tw;
912
913 // use normal error calculation using variance of MLE with weights (F.James 8.5.2)
914 // this is the same formula used in ROOT for TH1::Divide("B")
915
916 double variance = ( pw2 * (1. - 2 * eff) + tw2 * eff *eff ) / ( tw * tw) ;
917 double sigma = sqrt(variance);
918
919 double prob = 0.5 * (1.-conf);
921 low = eff - delta;
922 upper = eff + delta;
923 if (low < 0) low = 0;
924 if (upper > 1) upper = 1.;
925 }
926 }
927 else {
928 // when not using weights (all cases) or in case of Poisson ratio with weights
929 if(t != 0.0)
930 eff = ((Double_t)p)/t;
931
932 low = pBound(t,p,conf,false);
933 upper = pBound(t,p,conf,true);
934 }
935 }
936 // treat as Poisson ratio
937 if(bPoissonRatio)
938 {
939 Double_t ratio = eff/(1 - eff);
940 // take the intervals in eff as intervals in the Poisson ratio
941 low = low/(1. - low);
942 upper = upper/(1.-upper);
943 eff = ratio;
944 if (bEffective) {
945 //scale result by the ratio of the weight
946 eff *= wratio;
947 low *= wratio;
948 upper *= wratio;
949 }
950 }
951 //Set the point center and its errors
952 if (TMath::Finite(eff)) {
953 SetPoint(npoint,pass->GetBinCenter(b),eff);
955 pass->GetBinCenter(b)-pass->GetBinLowEdge(b),
956 pass->GetBinLowEdge(b)-pass->GetBinCenter(b)+pass->GetBinWidth(b),
957 eff-low,upper-eff);
958 npoint++;//we have added a point to the graph
959 }
960 }
961
962 Set(npoint);//tell the graph how many points we've really added
963 if (npoint < nbins)
964 Warning("Divide","Number of graph points is different than histogram bins - %d points have been skipped",nbins-npoint);
965
966
967 if (bVerbose) {
968 Info("Divide","made a graph with %d points from %d bins",npoint,nbins);
969 Info("Divide","used confidence level: %.2lf\n",conf);
970 if(bIsBayesian)
971 Info("Divide","used prior probability ~ beta(%.2lf,%.2lf)",alpha,beta);
972 Print();
973 }
974}
975
976////////////////////////////////////////////////////////////////////////////////
977/// Compute Range.
978
980{
982
983 for (Int_t i=0;i<fNpoints;i++) {
984 if (fX[i] -fEXlow[i] < xmin) {
985 if (gPad && gPad->GetLogx()) {
986 if (fEXlow[i] < fX[i]) xmin = fX[i]-fEXlow[i];
987 else xmin = TMath::Min(xmin,fX[i]/3);
988 } else {
989 xmin = fX[i]-fEXlow[i];
990 }
991 }
992 if (fX[i] +fEXhigh[i] > xmax) xmax = fX[i]+fEXhigh[i];
993 if (fY[i] -fEYlow[i] < ymin) {
994 if (gPad && gPad->GetLogy()) {
995 if (fEYlow[i] < fY[i]) ymin = fY[i]-fEYlow[i];
996 else ymin = TMath::Min(ymin,fY[i]/3);
997 } else {
998 ymin = fY[i]-fEYlow[i];
999 }
1000 }
1001 if (fY[i] +fEYhigh[i] > ymax) ymax = fY[i]+fEYhigh[i];
1002 }
1003}
1004
1005
1006////////////////////////////////////////////////////////////////////////////////
1007/// Copy and release.
1008
1011{
1013 if (newarrays) {
1014 delete[] fEXlow;
1015 fEXlow = newarrays[0];
1016 delete[] fEXhigh;
1017 fEXhigh = newarrays[1];
1018 delete[] fEYlow;
1019 fEYlow = newarrays[2];
1020 delete[] fEYhigh;
1021 fEYhigh = newarrays[3];
1022 delete[] fX;
1023 fX = newarrays[4];
1024 delete[] fY;
1025 fY = newarrays[5];
1026 delete[] newarrays;
1027 }
1028}
1029
1030
1031////////////////////////////////////////////////////////////////////////////////
1032/// Copy errors from `fE***` to `arrays[***]`
1033/// or to `f***` Copy points.
1034
1037{
1038 if (TGraph::CopyPoints(arrays ? arrays+4 : nullptr, ibegin, iend, obegin)) {
1039 Int_t n = (iend - ibegin)*sizeof(Double_t);
1040 if (arrays) {
1041 memmove(&arrays[0][obegin], &fEXlow[ibegin], n);
1042 memmove(&arrays[1][obegin], &fEXhigh[ibegin], n);
1043 memmove(&arrays[2][obegin], &fEYlow[ibegin], n);
1044 memmove(&arrays[3][obegin], &fEYhigh[ibegin], n);
1045 } else {
1050 }
1051 return kTRUE;
1052 } else {
1053 return kFALSE;
1054 }
1055}
1056
1057
1058////////////////////////////////////////////////////////////////////////////////
1059/// Should be called from ctors after `fNpoints` has been set.
1060/// Note: This function should be called only from the constructor
1061/// since it does not delete previously existing arrays
1062
1064{
1065 if (!fNpoints) {
1066 fEXlow = fEYlow = fEXhigh = fEYhigh = nullptr;
1067 return kFALSE;
1068 }
1069 fEXlow = new Double_t[fMaxSize];
1070 fEYlow = new Double_t[fMaxSize];
1071 fEXhigh = new Double_t[fMaxSize];
1072 fEYhigh = new Double_t[fMaxSize];
1073 return kTRUE;
1074}
1075
1076////////////////////////////////////////////////////////////////////////////////
1077/// Protected function to perform the merge operation of a graph with asymmetric errors.
1078
1080{
1081 if (g->GetN() == 0) return kFALSE;
1082
1083 Double_t * exl = g->GetEXlow();
1084 Double_t * exh = g->GetEXhigh();
1085 Double_t * eyl = g->GetEYlow();
1086 Double_t * eyh = g->GetEYhigh();
1087 if (exl == nullptr || exh == nullptr || eyl == nullptr || eyh == nullptr) {
1088 if (g->IsA() != TGraph::Class() )
1089 Warning("DoMerge","Merging a %s is not compatible with a TGraphAsymmErrors - errors will be ignored",g->IsA()->GetName());
1090 return TGraph::DoMerge(g);
1091 }
1092 for (Int_t i = 0 ; i < g->GetN(); i++) {
1093 Int_t ipoint = GetN();
1094 Double_t x = g->GetX()[i];
1095 Double_t y = g->GetY()[i];
1096 SetPoint(ipoint, x, y);
1097 SetPointError(ipoint, exl[i], exh[i], eyl[i], eyh[i] );
1098 }
1099
1100 return kTRUE;
1101}
1102
1103////////////////////////////////////////////////////////////////////////////////
1104/// Set zero values for point arrays in the range `[begin, end]`
1105
1108{
1109 if (!from_ctor) {
1110 TGraph::FillZero(begin, end, from_ctor);
1111 }
1112 Int_t n = (end - begin)*sizeof(Double_t);
1113 memset(fEXlow + begin, 0, n);
1114 memset(fEXhigh + begin, 0, n);
1115 memset(fEYlow + begin, 0, n);
1116 memset(fEYhigh + begin, 0, n);
1117}
1118
1119
1120////////////////////////////////////////////////////////////////////////////////
1121/// Returns the combined error along X at point i by computing the average
1122/// of the lower and upper variance.
1123
1125{
1126 if (i < 0 || i >= fNpoints) return -1;
1127 if (!fEXlow && !fEXhigh) return -1;
1128 Double_t elow=0, ehigh=0;
1129 if (fEXlow) elow = fEXlow[i];
1130 if (fEXhigh) ehigh = fEXhigh[i];
1131 return TMath::Sqrt(0.5*(elow*elow + ehigh*ehigh));
1132}
1133
1134
1135////////////////////////////////////////////////////////////////////////////////
1136/// Returns the combined error along Y at point i by computing the average
1137/// of the lower and upper variance.
1138
1140{
1141 if (i < 0 || i >= fNpoints) return -1;
1142 if (!fEYlow && !fEYhigh) return -1;
1143 Double_t elow=0, ehigh=0;
1144 if (fEYlow) elow = fEYlow[i];
1145 if (fEYhigh) ehigh = fEYhigh[i];
1146 return TMath::Sqrt(0.5*(elow*elow + ehigh*ehigh));
1147}
1148
1149
1150////////////////////////////////////////////////////////////////////////////////
1151/// Get high error on X.
1152
1154{
1155 if (i<0 || i>fNpoints) return -1;
1156 if (fEXhigh) return fEXhigh[i];
1157 return -1;
1158}
1159
1160
1161////////////////////////////////////////////////////////////////////////////////
1162/// Get low error on X.
1163
1165{
1166 if (i<0 || i>fNpoints) return -1;
1167 if (fEXlow) return fEXlow[i];
1168 return -1;
1169}
1170
1171
1172////////////////////////////////////////////////////////////////////////////////
1173/// Get high error on Y.
1174
1176{
1177 if (i<0 || i>fNpoints) return -1;
1178 if (fEYhigh) return fEYhigh[i];
1179 return -1;
1180}
1181
1182
1183////////////////////////////////////////////////////////////////////////////////
1184/// Get low error on Y.
1185
1187{
1188 if (i<0 || i>fNpoints) return -1;
1189 if (fEYlow) return fEYlow[i];
1190 return -1;
1191}
1192
1193
1194////////////////////////////////////////////////////////////////////////////////
1195/// Adds all graphs with asymmetric errors from the collection to this graph.
1196/// Returns the total number of points in the result or -1 in case of an error.
1197
1199{
1200 TIter next(li);
1201 while (TObject* o = next()) {
1202 TGraph *g = dynamic_cast<TGraph*>(o);
1203 if (!g) {
1204 Error("Merge",
1205 "Cannot merge - an object which doesn't inherit from TGraph found in the list");
1206 return -1;
1207 }
1208 int n0 = GetN();
1209 int n1 = n0+g->GetN();
1210 Set(n1);
1211 Double_t * x = g->GetX();
1212 Double_t * y = g->GetY();
1213 Double_t * exlow = g->GetEXlow();
1214 Double_t * exhigh = g->GetEXhigh();
1215 Double_t * eylow = g->GetEYlow();
1216 Double_t * eyhigh = g->GetEYhigh();
1217 for (Int_t i = 0 ; i < g->GetN(); i++) {
1218 SetPoint(n0+i, x[i], y[i]);
1219 if (exlow) fEXlow[n0+i] = exlow[i];
1220 if (exhigh) fEXhigh[n0+i] = exhigh[i];
1221 if (eylow) fEYlow[n0+i] = eylow[i];
1222 if (eyhigh) fEYhigh[n0+i] = eyhigh[i];
1223 }
1224 }
1225 return GetN();
1226}
1227
1228////////////////////////////////////////////////////////////////////////////////
1229/// Print graph and errors values.
1230
1232{
1233 for (Int_t i=0;i<fNpoints;i++) {
1234 printf("x[%d]=%g, y[%d]=%g, exl[%d]=%g, exh[%d]=%g, eyl[%d]=%g, eyh[%d]=%g\n"
1235 ,i,fX[i],i,fY[i],i,fEXlow[i],i,fEXhigh[i],i,fEYlow[i],i,fEYhigh[i]);
1236 }
1237}
1238
1239
1240////////////////////////////////////////////////////////////////////////////////
1241/// Save primitive as a C++ statement(s) on output stream out.
1242
1243void TGraphAsymmErrors::SavePrimitive(std::ostream &out, Option_t *option /*= ""*/)
1244{
1245 auto xname = SavePrimitiveArray(out, "grae_fx", fNpoints, fX, kTRUE);
1246 auto yname = SavePrimitiveArray(out, "grae_fy", fNpoints, fY);
1247 auto exlname = SavePrimitiveArray(out, "grae_fexl", fNpoints, fEXlow);
1248 auto exhname = SavePrimitiveArray(out, "grae_fexh", fNpoints, fEXhigh);
1249 auto eylname = SavePrimitiveArray(out, "grae_feyl", fNpoints, fEYlow);
1250 auto eyhname = SavePrimitiveArray(out, "grae_feyh", fNpoints, fEYhigh);
1251
1253 out, Class(), "grae",
1254 TString::Format("%d, %s, %s, %s, %s, %s, %s", fNpoints,
1255 xname.Data(), yname.Data(), exlname.Data(), exhname.Data(), eylname.Data(), eyhname.Data()), kFALSE);
1256
1257 SaveHistogramAndFunctions(out, "grae", option);
1258}
1259
1260////////////////////////////////////////////////////////////////////////////////
1261/// Multiply the values and errors of a TGraphAsymmErrors by a constant c1.
1262///
1263/// If option contains "x" the x values and errors are scaled
1264/// If option contains "y" the y values and errors are scaled
1265/// If option contains "xy" both x and y values and errors are scaled
1266
1268{
1270 TString opt = option; opt.ToLower();
1271 if (opt.Contains("x") && GetEXlow()) {
1272 for (Int_t i=0; i<GetN(); i++)
1273 GetEXlow()[i] *= c1;
1274 }
1275 if (opt.Contains("x") && GetEXhigh()) {
1276 for (Int_t i=0; i<GetN(); i++)
1277 GetEXhigh()[i] *= c1;
1278 }
1279 if (opt.Contains("y") && GetEYlow()) {
1280 for (Int_t i=0; i<GetN(); i++)
1281 GetEYlow()[i] *= c1;
1282 }
1283 if (opt.Contains("y") && GetEYhigh()) {
1284 for (Int_t i=0; i<GetN(); i++)
1285 GetEYhigh()[i] *= c1;
1286 }
1287}
1288
1289////////////////////////////////////////////////////////////////////////////////
1290/// Set ex and ey values for point pointed by the mouse.
1291
1293{
1294 if (!gPad) {
1295 Error("SetPointError", "Cannot be used without gPad, requires last mouse position");
1296 return;
1297 }
1298
1299 Int_t px = gPad->GetEventX();
1300 Int_t py = gPad->GetEventY();
1301
1302 //localize point to be deleted
1303 Int_t ipoint = -2;
1304 Int_t i;
1305 // start with a small window (in case the mouse is very close to one point)
1306 for (i=0;i<fNpoints;i++) {
1307 Int_t dpx = px - gPad->XtoAbsPixel(gPad->XtoPad(fX[i]));
1308 Int_t dpy = py - gPad->YtoAbsPixel(gPad->YtoPad(fY[i]));
1309 if (dpx*dpx+dpy*dpy < 25) {ipoint = i; break;}
1310 }
1311 if (ipoint == -2) return;
1312
1313 fEXlow[ipoint] = exl;
1314 fEYlow[ipoint] = eyl;
1315 fEXhigh[ipoint] = exh;
1316 fEYhigh[ipoint] = eyh;
1317 gPad->Modified();
1318}
1319
1320
1321////////////////////////////////////////////////////////////////////////////////
1322/// Set ex and ey values for point number i.
1323
1325{
1326 if (i < 0) return;
1327 if (i >= fNpoints) {
1328 // re-allocate the object
1330 }
1331 fEXlow[i] = exl;
1332 fEYlow[i] = eyl;
1333 fEXhigh[i] = exh;
1334 fEYhigh[i] = eyh;
1335}
1336
1337
1338////////////////////////////////////////////////////////////////////////////////
1339/// Set EXlow for point `i`.
1340
1342{
1343 if (i < 0) return;
1344 if (i >= fNpoints) {
1345 // re-allocate the object
1347 }
1348 fEXlow[i] = exl;
1349}
1350
1351
1352////////////////////////////////////////////////////////////////////////////////
1353/// Set EXhigh for point `i`.
1354
1356{
1357 if (i < 0) return;
1358 if (i >= fNpoints) {
1359 // re-allocate the object
1361 }
1362 fEXhigh[i] = exh;
1363}
1364
1365
1366////////////////////////////////////////////////////////////////////////////////
1367/// Set EYlow for point `i`.
1368
1370{
1371 if (i < 0) return;
1372 if (i >= fNpoints) {
1373 // re-allocate the object
1375 }
1376 fEYlow[i] = eyl;
1377}
1378
1379
1380////////////////////////////////////////////////////////////////////////////////
1381/// Set EYhigh for point `i`.
1382
1384{
1385 if (i < 0) return;
1386 if (i >= fNpoints) {
1387 // re-allocate the object
1389 }
1390 fEYhigh[i] = eyh;
1391}
1392
1393
1394////////////////////////////////////////////////////////////////////////////////
1395/// Stream an object of class TGraphAsymmErrors.
1396
1398{
1399 if (b.IsReading()) {
1400 UInt_t R__s, R__c;
1401 Version_t R__v = b.ReadVersion(&R__s, &R__c);
1402 if (R__v > 2) {
1403 b.ReadClassBuffer(TGraphAsymmErrors::Class(), this, R__v, R__s, R__c);
1404 return;
1405 }
1406 //====process old versions before automatic schema evolution
1408 fEXlow = new Double_t[fNpoints];
1409 fEYlow = new Double_t[fNpoints];
1410 fEXhigh = new Double_t[fNpoints];
1411 fEYhigh = new Double_t[fNpoints];
1412 if (R__v < 2) {
1413 Float_t *exlow = new Float_t[fNpoints];
1414 Float_t *eylow = new Float_t[fNpoints];
1417 b.ReadFastArray(exlow,fNpoints);
1418 b.ReadFastArray(eylow,fNpoints);
1419 b.ReadFastArray(exhigh,fNpoints);
1420 b.ReadFastArray(eyhigh,fNpoints);
1421 for (Int_t i=0;i<fNpoints;i++) {
1422 fEXlow[i] = exlow[i];
1423 fEYlow[i] = eylow[i];
1424 fEXhigh[i] = exhigh[i];
1425 fEYhigh[i] = eyhigh[i];
1426 }
1427 delete [] eylow;
1428 delete [] exlow;
1429 delete [] eyhigh;
1430 delete [] exhigh;
1431 } else {
1432 b.ReadFastArray(fEXlow,fNpoints);
1433 b.ReadFastArray(fEYlow,fNpoints);
1434 b.ReadFastArray(fEXhigh,fNpoints);
1435 b.ReadFastArray(fEYhigh,fNpoints);
1436 }
1437 b.CheckByteCount(R__s, R__c, TGraphAsymmErrors::IsA());
1438 //====end of old versions
1439
1440 } else {
1441 b.WriteClassBuffer(TGraphAsymmErrors::Class(),this);
1442 }
1443}
1444
1445
1446////////////////////////////////////////////////////////////////////////////////
1447/// Swap points.
1448
1457
1458////////////////////////////////////////////////////////////////////////////////
1459/// Update the fX, fY, fEXlow, fEXhigh, fEYlow and fEYhigh arrays with the sorted values.
1460
1462{
1463 std::vector<Double_t> fEXlowSorted(numSortedPoints);
1464 std::vector<Double_t> fEXhighSorted(numSortedPoints);
1465 std::vector<Double_t> fEYlowSorted(numSortedPoints);
1466 std::vector<Double_t> fEYhighSorted(numSortedPoints);
1467
1468 // Fill the sorted X and Y error values based on the sorted indices
1469 std::generate(fEXlowSorted.begin(), fEXlowSorted.end(),
1470 [begin = low, &sorting_indices, this]() mutable { return fEXlow[sorting_indices[begin++]]; });
1471 std::generate(fEXhighSorted.begin(), fEXhighSorted.end(),
1472 [begin = low, &sorting_indices, this]() mutable { return fEXhigh[sorting_indices[begin++]]; });
1473 std::generate(fEYlowSorted.begin(), fEYlowSorted.end(),
1474 [begin = low, &sorting_indices, this]() mutable { return fEYlow[sorting_indices[begin++]]; });
1475 std::generate(fEYhighSorted.begin(), fEYhighSorted.end(),
1476 [begin = low, &sorting_indices, this]() mutable { return fEYhigh[sorting_indices[begin++]]; });
1477
1478 // Copy the sorted X and Y error values back to the original arrays
1479 std::copy(fEXlowSorted.begin(), fEXlowSorted.end(), fEXlow + low);
1480 std::copy(fEXhighSorted.begin(), fEXhighSorted.end(), fEXhigh + low);
1481 std::copy(fEYlowSorted.begin(), fEYlowSorted.end(), fEYlow + low);
1482 std::copy(fEYhighSorted.begin(), fEYhighSorted.end(), fEYhigh + low);
1483
1485}
#define b(i)
Definition RSha256.hxx:100
#define f(i)
Definition RSha256.hxx:104
#define g(i)
Definition RSha256.hxx:105
#define a(i)
Definition RSha256.hxx:99
#define h(i)
Definition RSha256.hxx:106
#define e(i)
Definition RSha256.hxx:103
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
bool Bool_t
Definition RtypesCore.h:63
short Version_t
Definition RtypesCore.h:65
float Float_t
Definition RtypesCore.h:57
constexpr Bool_t kFALSE
Definition RtypesCore.h:94
double Double_t
Definition RtypesCore.h:59
constexpr Bool_t kTRUE
Definition RtypesCore.h:93
const char Option_t
Definition RtypesCore.h:66
#define ClassImp(name)
Definition Rtypes.h:374
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
static unsigned int total
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t option
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char filename
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t np
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t format
float xmin
float ymin
float xmax
float ymax
R__EXTERN TStyle * gStyle
Definition TStyle.h:442
R__EXTERN TSystem * gSystem
Definition TSystem.h:572
#define gPad
const_iterator begin() const
const_iterator end() const
Buffer base class used for serializing objects.
Definition TBuffer.h:43
Collection abstract base class.
Definition TCollection.h:65
static Double_t BetaMode(Double_t alpha, Double_t beta)
Compute the mode of the beta distribution.
static Bool_t BetaShortestInterval(Double_t level, Double_t alpha, Double_t beta, Double_t &lower, Double_t &upper)
Calculates the boundaries for a shortest confidence interval for a Beta distribution.
static Double_t BetaMean(Double_t alpha, Double_t beta)
Compute the mean (average) of the beta distribution.
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.
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.
static Bool_t CheckBinning(const TH1 &pass, const TH1 &total)
Checks binning for each axis.
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.
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.
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...
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.
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.
1-Dim function class
Definition TF1.h:234
TGraph with asymmetric error bars.
Double_t * GetEXlow() const override
virtual void SetPointEYlow(Int_t i, Double_t eyl)
Set EYlow for point i.
Double_t * fEXhigh
[fNpoints] array of X high errors
Double_t GetErrorY(Int_t bin) const override
Returns the combined error along Y at point i by computing the average of the lower and upper varianc...
void FillZero(Int_t begin, Int_t end, Bool_t from_ctor=kTRUE) override
Set zero values for point arrays in the range [begin, end]
virtual void Divide(const TH1 *pass, const TH1 *total, Option_t *opt="cp")
Fill this TGraphAsymmErrors by dividing two 1-dimensional histograms pass/total.
Bool_t CtorAllocate()
Should be called from ctors after fNpoints has been set.
static TClass * Class()
virtual void SetPointError(Double_t exl, Double_t exh, Double_t eyl, Double_t eyh)
Set ex and ey values for point pointed by the mouse.
Double_t GetErrorXhigh(Int_t i) const override
Get high error on X.
Double_t * fEYhigh
[fNpoints] array of Y high errors
Bool_t CopyPoints(Double_t **arrays, Int_t ibegin, Int_t iend, Int_t obegin) override
Copy errors from fE*** to arrays[***] or to f*** Copy points.
virtual void AddPointError(Double_t x, Double_t y, Double_t exl=0., Double_t exh=0., Double_t eyl=0., Double_t eyh=0.)
Add a point with asymmetric errorbars to the graph.
void ComputeRange(Double_t &xmin, Double_t &ymin, Double_t &xmax, Double_t &ymax) const override
Compute Range.
virtual void SetPointEXlow(Int_t i, Double_t exl)
Set EXlow for point i.
void Streamer(TBuffer &) override
Stream an object of class TGraphAsymmErrors.
virtual void SetPointEYhigh(Int_t i, Double_t eyh)
Set EYhigh for point i.
void SavePrimitive(std::ostream &out, Option_t *option="") override
Save primitive as a C++ statement(s) on output stream out.
virtual void BayesDivide(const TH1 *pass, const TH1 *total, Option_t *opt="")
This function is only kept for backward compatibility.
Double_t * GetEYhigh() const override
void Print(Option_t *chopt="") const override
Print graph and errors values.
Double_t GetErrorYhigh(Int_t i) const override
Get high error on Y.
Int_t Merge(TCollection *list) override
Adds all graphs with asymmetric errors from the collection to this graph.
Double_t GetErrorXlow(Int_t i) const override
Get low error on X.
Double_t * fEYlow
[fNpoints] array of Y low errors
void UpdateArrays(const std::vector< Int_t > &sorting_indices, Int_t numSortedPoints, Int_t low) override
Update the fX, fY, fEXlow, fEXhigh, fEYlow and fEYhigh arrays with the sorted values.
void SwapPoints(Int_t pos1, Int_t pos2) override
Swap points.
Double_t * GetEXhigh() const override
Double_t * fEXlow
[fNpoints] array of X low errors
void Apply(TF1 *f) override
Apply a function to all data points .
Double_t ** Allocate(Int_t size) override
Allocate internal data structures for size points.
Double_t * GetEYlow() const override
Bool_t DoMerge(const TGraph *g) override
Protected function to perform the merge operation of a graph with asymmetric errors.
void CopyAndRelease(Double_t **newarrays, Int_t ibegin, Int_t iend, Int_t obegin) override
Copy and release.
TClass * IsA() const override
virtual void SetPointEXhigh(Int_t i, Double_t exh)
Set EXhigh for point i.
Double_t GetErrorYlow(Int_t i) const override
Get low error on Y.
Double_t GetErrorX(Int_t bin) const override
Returns the combined error along X at point i by computing the average of the lower and upper varianc...
TGraphAsymmErrors()
TGraphAsymmErrors default constructor.
TGraphAsymmErrors & operator=(const TGraphAsymmErrors &gr)
TGraphAsymmErrors assignment operator.
~TGraphAsymmErrors() override
TGraphAsymmErrors default destructor.
void Scale(Double_t c1=1., Option_t *option="y") override
Multiply the values and errors of a TGraphAsymmErrors by a constant c1.
static Int_t CalculateScanfFields(const char *fmt)
Calculate scan fields.
A TGraph is an object made of two arrays X and Y with npoints each.
Definition TGraph.h:41
static TClass * Class()
virtual void AddPoint(Double_t x, Double_t y)
Append a new point to the graph.
Definition TGraph.h:97
Int_t fNpoints
Number of points <= fMaxSize.
Definition TGraph.h:46
virtual void SetPoint(Int_t i, Double_t x, Double_t y)
Set x and y values for point number i.
Definition TGraph.cxx:2291
Int_t fMaxSize
!Current dimension of arrays fX and fY
Definition TGraph.h:45
TH1F * fHistogram
Pointer to histogram used for drawing axis.
Definition TGraph.h:50
virtual void UpdateArrays(const std::vector< Int_t > &sorting_indices, Int_t numSortedPoints, Int_t low)
Update the fX and fY arrays with the sorted values.
Definition TGraph.cxx:2541
Int_t GetN() const
Definition TGraph.h:131
Double_t * fY
[fNpoints] array of Y points
Definition TGraph.h:48
Bool_t CtorAllocate()
In constructors set fNpoints than call this method.
Definition TGraph.cxx:807
virtual void ComputeRange(Double_t &xmin, Double_t &ymin, Double_t &xmax, Double_t &ymax) const
Compute the x/y range of the points in this graph.
Definition TGraph.cxx:733
Double_t ** AllocateArrays(Int_t Narrays, Int_t arraySize)
Allocate arrays.
Definition TGraph.cxx:600
virtual void Scale(Double_t c1=1., Option_t *option="y")
Multiply the values of a TGraph by a constant c1.
Definition TGraph.cxx:2208
static void SwapValues(Double_t *arr, Int_t pos1, Int_t pos2)
Swap values.
Definition TGraph.cxx:2560
void Streamer(TBuffer &) override
Stream an object of class TGraph.
Definition TGraph.cxx:2465
virtual Bool_t DoMerge(const TGraph *g)
protected function to perform the merge operation of a graph
Definition TGraph.cxx:2625
void SetName(const char *name="") override
Set graph name.
Definition TGraph.cxx:2330
virtual void SwapPoints(Int_t pos1, Int_t pos2)
Swap points.
Definition TGraph.cxx:2532
virtual void FillZero(Int_t begin, Int_t end, Bool_t from_ctor=kTRUE)
Set zero values for point arrays in the range [begin, end) Should be redefined in descendant classes.
Definition TGraph.cxx:1104
void SaveHistogramAndFunctions(std::ostream &out, const char *varname, Option_t *option)
Save histogram and list of functions of TGraph as C++ statement Used in all TGraph-derived classes.
Definition TGraph.cxx:2164
Double_t * fX
[fNpoints] array of X points
Definition TGraph.h:47
void SetTitle(const char *title="") override
Change (i.e.
Definition TGraph.cxx:2346
virtual void Set(Int_t n)
Set number of points in the graph Existing coordinates are preserved New coordinates above fNpoints a...
Definition TGraph.cxx:2226
virtual Int_t GetPoint(Int_t i, Double_t &x, Double_t &y) const
Get x and y values for point number i.
Definition TGraph.cxx:1534
virtual Bool_t CopyPoints(Double_t **newarrays, Int_t ibegin, Int_t iend, Int_t obegin)
Copy points from fX and fY to arrays[0] and arrays[1] or to fX and fY if arrays == 0 and ibegin !...
Definition TGraph.cxx:781
TGraph & operator=(const TGraph &)
Equal operator for this graph.
Definition TGraph.cxx:234
TH1 is the base class of all histogram classes in ROOT.
Definition TH1.h:59
Mother of all ROOT objects.
Definition TObject.h:41
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition TObject.cxx:1040
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1054
void MakeZombie()
Definition TObject.h:53
static TString SavePrimitiveArray(std::ostream &out, const char *prefix, Int_t len, Double_t *arr, Bool_t empty_line=kFALSE)
Save array in the output stream "out".
Definition TObject.cxx:786
static void SavePrimitiveConstructor(std::ostream &out, TClass *cl, const char *variable_name, const char *constructor_agrs="", Bool_t empty_line=kTRUE)
Save object constructor in the output stream "out".
Definition TObject.cxx:771
Basic string class.
Definition TString.h:139
void ToLower()
Change string to lower-case.
Definition TString.cxx:1182
static TString Format(const char *fmt,...)
Static method which formats a string using a printf style format descriptor and return a TString.
Definition TString.cxx:2378
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition TString.h:632
Float_t GetErrorX() const
Definition TStyle.h:188
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition TSystem.cxx:1274
TVectorT.
Definition TVectorT.h:29
TLine * line
double normal_quantile_c(double z, double sigma)
Inverse ( ) of the cumulative distribution function of the upper tail of the normal (Gaussian) distri...
const Double_t sigma
std::ostream & Info()
Definition hadd.cxx:171
Double_t y[n]
Definition legend1.C:17
return c1
Definition legend1.C:41
Double_t x[n]
Definition legend1.C:17
const Int_t n
Definition legend1.C:16
TGraphErrors * gr
Definition legend1.C:25
Int_t Finite(Double_t x)
Check if it is finite with a mask in order to be consistent in presence of fast math.
Definition TMath.h:774
Double_t Sqrt(Double_t x)
Returns the square root of x.
Definition TMath.h:666
Short_t Min(Short_t a, Short_t b)
Returns the smallest of a and b.
Definition TMathBase.h:198
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:123