Logo ROOT  
Reference Guide
TGraphMultiErrors.cxx
Go to the documentation of this file.
1// @(#)root/hist:$Id$
2// Author: Simon Spies 18/02/19
3
4/*************************************************************************
5 * Copyright (C) 2018-2019, 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#include "TROOT.h"
13#include "TStyle.h"
14#include "TVirtualPad.h"
15#include "TEfficiency.h"
16#include "Riostream.h"
17
18#include "TArrayD.h"
19#include "TVector.h"
20#include "TH1.h"
21#include "TF1.h"
22#include "TMath.h"
24
25#include "TGraphMultiErrors.h"
26
28
29/** \class TGraphMultiErrors
30 \ingroup Graphs
31TGraph with asymmetric error bars and multiple y error dimensions.
32
33The TGraphMultiErrors painting is performed thanks to the TGraphPainter
34class. All details about the various painting options are given in this class.
35
36The picture below gives an example:
37
38Begin_Macro(source)
39{
40 auto c1 = new TCanvas("c1", "A Simple Graph with multiple y-errors", 200, 10, 700, 500);
41 c1->SetGrid();
42 c1->GetFrame()->SetBorderSize(12);
43 const Int_t np = 5;
44 Double_t x[np] = {0, 1, 2, 3, 4};
45 Double_t y[np] = {0, 2, 4, 1, 3};
46 Double_t exl[np] = {0.3, 0.3, 0.3, 0.3, 0.3};
47 Double_t exh[np] = {0.3, 0.3, 0.3, 0.3, 0.3};
48 Double_t eylstat[np] = {1, 0.5, 1, 0.5, 1};
49 Double_t eyhstat[np] = {0.5, 1, 0.5, 1, 2};
50 Double_t eylsys[np] = {0.5, 0.4, 0.8, 0.3, 1.2};
51 Double_t eyhsys[np] = {0.6, 0.7, 0.6, 0.4, 0.8};
52 auto gme = new TGraphMultiErrors("gme", "TGraphMultiErrors Example", np, x, y, exl, exh, eylstat, eyhstat);
53 gme->AddYError(np, eylsys, eyhsys);
54 gme->SetMarkerStyle(20);
55 gme->SetLineColor(kRed);
56 gme->GetAttLine(0)->SetLineColor(kRed);
57 gme->GetAttLine(1)->SetLineColor(kBlue);
58 gme->GetAttFill(1)->SetFillStyle(0);
59 gme->Draw("APS ; Z ; 5 s=0.5");
60}
61End_Macro
62*/
63////////////////////////////////////////////////////////////////////////////////
64/// TGraphMultiErrors default constructor.
65
67 : TGraph(), fNYErrors(0), fSumErrorsMode(TGraphMultiErrors::kOnlyFirst), fExL(nullptr), fExH(nullptr)
68{
69}
70
71////////////////////////////////////////////////////////////////////////////////
72/// TGraphMultiErrors default constructor with name and title.
73
75{
76 SetNameTitle(name, title);
77}
78
79////////////////////////////////////////////////////////////////////////////////
80/// TGraphMultiErrors normal constructor with np points and ne y-errors.
81///
82/// All values are initialized to 0.
83
85 : TGraph(np), fNYErrors(ne), fSumErrorsMode(TGraphMultiErrors::kOnlyFirst)
86{
88}
89
90////////////////////////////////////////////////////////////////////////////////
91/// TGraphMultiErrors normal constructor with `name`, `title`, `np` points and `ne` y-errors.
92///
93/// All values are initialized to 0.
94
96 : TGraphMultiErrors(np, ne)
97{
98 SetNameTitle(name, title);
99}
100
101////////////////////////////////////////////////////////////////////////////////
102/// TGraphMultiErrors normal constructor with `np` points and a single y-error.
103///
104/// The signature of this constructor is equal to the corresponding constructor of TGraphAsymmErrors.
105/// If `exL`,`exH` or `eyL`,`exH` are NULL, the corresponding values are preset to zero.
106
108 const Float_t *exH, const Float_t *eyL, const Float_t *eyH, Int_t m)
109 : TGraph(np, x, y), fNYErrors(1), fSumErrorsMode(m)
110{
111 if (!CtorAllocate())
112 return;
113
114 for (Int_t i = 0; i < fNpoints; i++) {
115 if (exL)
116 fExL[i] = exL[i];
117 else
118 fExL[i] = 0.;
119 if (exH)
120 fExH[i] = exH[i];
121 else
122 fExH[i] = 0.;
123 if (eyL)
124 fEyL[0][i] = eyL[i];
125 else
126 fEyL[0][i] = 0.;
127 if (eyH)
128 fEyH[0][i] = eyH[i];
129 else
130 fEyH[0][i] = 0.;
131 }
132
134}
135
136////////////////////////////////////////////////////////////////////////////////
137/// TGraphMultiErrors normal constructor with `name`, `title`, `np` points and a single y-error.
138///
139/// If `exL`,`exH` or `eyL`,`eyH` are NULL, the corresponding values are preset to zero.
140
142 const Float_t *y, const Float_t *exL, const Float_t *exH, const Float_t *eyL,
143 const Float_t *eyH, Int_t m)
144 : TGraphMultiErrors(np, x, y, exL, exH, eyL, eyH, m)
145{
146 SetNameTitle(name, title);
147}
148
149////////////////////////////////////////////////////////////////////////////////
150/// TGraphMultiErrors normal constructor with `np` points and a single y-error.
151///
152/// The signature of this constructor is equal to the corresponding constructor of TGraphAsymmErrors.
153/// If `exL`,`exH` or `eyL`,`exH` are NULL, the corresponding values are preset to zero.
154
156 const Double_t *exH, const Double_t *eyL, const Double_t *eyH, Int_t m)
157 : TGraph(np, x, y), fNYErrors(1), fSumErrorsMode(m)
158{
159 if (!CtorAllocate())
160 return;
161
162 Int_t n = fNpoints * sizeof(Double_t);
163
164 if (exL)
165 memcpy(fExL, exL, n);
166 else
167 memset(fExL, 0, n);
168 if (exH)
169 memcpy(fExH, exH, n);
170 else
171 memset(fExH, 0, n);
172
173 if (eyL)
174 fEyL[0].Set(fNpoints, eyL);
175 else
176 fEyL[0].Reset(0.);
177
178 if (eyH)
179 fEyH[0].Set(fNpoints, eyH);
180 else
181 fEyH[0].Reset(0.);
182
184}
185
186////////////////////////////////////////////////////////////////////////////////
187/// TGraphMultiErrors normal constructor with name, title, `np` points and a single y-error.
188///
189/// If `exL`,`exH` or `eyL`,`exH` are NULL, the corresponding values are preset to zero.
190
192 const Double_t *y, const Double_t *exL, const Double_t *exH, const Double_t *eyL,
193 const Double_t *eyH, Int_t m)
194 : TGraphMultiErrors(np, x, y, exL, exH, eyL, eyH, m)
195{
196 SetNameTitle(name, title);
197}
198
199////////////////////////////////////////////////////////////////////////////////
200/// TGraphMultiErrors normal constructor with `np` points and `ne` y-errors.
201///
202/// If `exL`,`exH` are NULL, the corresponding values are preset to zero.
203/// The multiple y-errors are passed as std::vectors of std::vectors.
204
206 const Float_t *exH, std::vector<std::vector<Float_t>> eyL,
207 std::vector<std::vector<Float_t>> eyH, Int_t m)
208 : TGraph(np, x, y), fNYErrors(ne), fSumErrorsMode(m)
209{
210 if (!CtorAllocate())
211 return;
212
213 for (Int_t i = 0; i < fNpoints; i++) {
214 if (exL)
215 fExL[i] = exL[i];
216 else
217 fExL[i] = 0.;
218 if (exH)
219 fExH[i] = exH[i];
220 else
221 fExH[i] = 0.;
222
223 for (Int_t j = 0; j < fNYErrors; j++) {
224 if (Int_t(eyL.size()) > j && Int_t(eyL[j].size()) > i)
225 fEyL[j][i] = eyL[j][i];
226 else
227 fEyL[j][i] = 0.;
228 if (Int_t(eyH.size()) > j && Int_t(eyH[j].size()) > i)
229 fEyH[j][i] = eyH[j][i];
230 else
231 fEyH[j][i] = 0.;
232 }
233 }
234
236}
237
238////////////////////////////////////////////////////////////////////////////////
239/// TGraphMultiErrors normal constructor with name, title, `np` points and `ne` y-errors.
240///
241/// If `exL`,`exH` are NULL, the corresponding values are preset to zero.
242/// The multiple y-errors are passed as std::vectors of std::vectors.
243
245 const Float_t *y, const Float_t *exL, const Float_t *exH,
246 std::vector<std::vector<Float_t>> eyL, std::vector<std::vector<Float_t>> eyH,
247 Int_t m)
248 : TGraphMultiErrors(np, ne, x, y, exL, exH, eyL, eyH, m)
249{
250 SetNameTitle(name, title);
251}
252
253////////////////////////////////////////////////////////////////////////////////
254/// TGraphMultiErrors normal constructor with `np` points and `ne` y-errors.
255///
256/// If `exL`,`exH` are NULL, the corresponding values are preset to zero.
257/// The multiple y-errors are passed as std::vectors of std::vectors.
258
260 const Double_t *exH, std::vector<std::vector<Double_t>> eyL,
261 std::vector<std::vector<Double_t>> eyH, Int_t m)
262 : TGraph(np, x, y), fNYErrors(ne), fSumErrorsMode(m)
263{
264 if (!CtorAllocate())
265 return;
266
267 Int_t n = fNpoints * sizeof(Double_t);
268
269 if (exL)
270 memcpy(fExL, exL, n);
271 else
272 memset(fExL, 0, n);
273 if (exH)
274 memcpy(fExH, exH, n);
275 else
276 memset(fExH, 0, n);
277
278 for (Int_t i = 0; i < fNpoints; i++) {
279 for (Int_t j = 0; j < fNYErrors; j++) {
280 if (Int_t(eyL.size()) > j && Int_t(eyL[j].size()) > i)
281 fEyL[j][i] = eyL[j][i];
282 else
283 fEyL[j][i] = 0.;
284 if (Int_t(eyH.size()) > j && Int_t(eyH[j].size()) > i)
285 fEyH[j][i] = eyH[j][i];
286 else
287 fEyH[j][i] = 0.;
288 }
289 }
290
292}
293
294////////////////////////////////////////////////////////////////////////////////
295/// TGraphMultiErrors normal constructor with `name`, `title`, `np` points and `ne` y-errors.
296///
297/// If `exL`,`exH` are NULL, the corresponding values are preset to zero.
298/// The multiple y-errors are passed as std::vectors of std::vectors.
299
301 const Double_t *y, const Double_t *exL, const Double_t *exH,
302 std::vector<std::vector<Double_t>> eyL, std::vector<std::vector<Double_t>> eyH,
303 Int_t m)
304 : TGraphMultiErrors(np, ne, x, y, exL, exH, eyL, eyH, m)
305{
306 SetNameTitle(name, title);
307}
308
309////////////////////////////////////////////////////////////////////////////////
310/// TGraphMultiErrors normal constructor with `np` points and `ne` y-errors.
311///
312/// If `exL`,`exH` are NULL, the corresponding values are preset to zero.
313/// The multiple y-errors are passed as std::vectors of TArrayF objects.
314
316 const Float_t *exH, std::vector<TArrayF> eyL, std::vector<TArrayF> eyH, Int_t m)
317 : TGraph(np, x, y), fNYErrors(ne), fSumErrorsMode(m)
318{
319 if (!CtorAllocate())
320 return;
321
322 for (Int_t i = 0; i < fNpoints; i++) {
323 if (exL)
324 fExL[i] = exL[i];
325 else
326 fExL[i] = 0.;
327 if (exH)
328 fExH[i] = exH[i];
329 else
330 fExH[i] = 0.;
331
332 for (Int_t j = 0; j < fNYErrors; j++) {
333 if (Int_t(eyL.size()) > j && eyL[j].GetSize() > i)
334 fEyL[j][i] = eyL[j][i];
335 else
336 fEyL[j][i] = 0.;
337 if (Int_t(eyH.size()) > j && eyH[j].GetSize() > i)
338 fEyH[j][i] = eyH[j][i];
339 else
340 fEyH[j][i] = 0.;
341 }
342 }
343
345}
346
347////////////////////////////////////////////////////////////////////////////////
348/// TGraphMultiErrors normal constructor with name, title, `np` points and `ne` y-errors.
349///
350/// If `exL`,`exH` are NULL, the corresponding values are preset to zero.
351/// The multiple y-errors are passed as std::vectors of TArrayF objects.
352
354 const Float_t *y, const Float_t *exL, const Float_t *exH, std::vector<TArrayF> eyL,
355 std::vector<TArrayF> eyH, Int_t m)
356 : TGraphMultiErrors(np, ne, x, y, exL, exH, eyL, eyH, m)
357{
358 SetNameTitle(name, title);
359}
360
361////////////////////////////////////////////////////////////////////////////////
362/// TGraphMultiErrors normal constructor with `np` points and `ne` y-errors.
363///
364/// If `exL`,`exH` are NULL, the corresponding values are preset to zero.
365/// The multiple y-errors are passed as std::vectors of TArrayD objects.
366
368 const Double_t *exH, std::vector<TArrayD> eyL, std::vector<TArrayD> eyH, Int_t m)
369 : TGraph(np, x, y), fNYErrors(ne), fSumErrorsMode(m)
370{
371 if (!CtorAllocate())
372 return;
373
374 Int_t n = fNpoints * sizeof(Double_t);
375
376 if (exL)
377 memcpy(fExL, exL, n);
378 else
379 memset(fExL, 0, n);
380 if (exH)
381 memcpy(fExH, exH, n);
382 else
383 memset(fExH, 0, n);
384
385 for (Int_t i = 0; i < fNpoints; i++) {
386 for (Int_t j = 0; j < fNYErrors; j++) {
387 if (Int_t(eyL.size()) > j && eyL[j].GetSize() > i)
388 fEyL[j][i] = eyL[j][i];
389 else
390 fEyL[j][i] = 0.;
391 if (Int_t(eyH.size()) > j && eyH[j].GetSize() > i)
392 fEyH[j][i] = eyH[j][i];
393 else
394 fEyH[j][i] = 0.;
395 }
396 }
397
399}
400
401////////////////////////////////////////////////////////////////////////////////
402/// TGraphMultiErrors normal constructor with `name`, `title`, `np` points and `ne` y-errors.
403///
404/// If `exL`,`exH` are NULL, the corresponding values are preset to zero.
405/// The multiple y-errors are passed as std::vectors of TArrayD objects.
406
408 const Double_t *y, const Double_t *exL, const Double_t *exH,
409 std::vector<TArrayD> eyL, std::vector<TArrayD> eyH, Int_t m)
410 : TGraphMultiErrors(np, ne, x, y, exL, exH, eyL, eyH, m)
411{
412 SetNameTitle(name, title);
413}
414
415////////////////////////////////////////////////////////////////////////////////
416/// Constructor with six vectors of floats in input and a single y error dimension.
417/// The signature of this constructor is equal to the corresponding constructor of TGraphAsymmErrors.
418/// A grapherrors is built with the X coordinates taken from `tvX` the Y coordinates from `tvY`
419/// and the errors from vectors `tvExL`, `tvExH` and `tvEyL`, `tvEyH`.
420/// The number of points in the graph is the minimum of number of points
421/// in `tvX` and `tvY`.
422
424 const TVectorF &tvExH, const TVectorF &tvEyL, const TVectorF &tvEyH, Int_t m)
425 : TGraph(), fNYErrors(1), fSumErrorsMode(m)
426{
427 fNpoints = TMath::Min(tvX.GetNrows(), tvY.GetNrows());
428
430 return;
431
432 if (!CtorAllocate())
433 return;
434
435 Int_t itvXL = tvX.GetLwb();
436 Int_t itvYL = tvY.GetLwb();
437 Int_t itvExLL = tvExL.GetLwb();
438 Int_t itvExHL = tvExH.GetLwb();
439 Int_t itvEyLL = tvEyL.GetLwb();
440 Int_t itvEyHL = tvEyH.GetLwb();
441
442 for (Int_t i = 0; i < fNpoints; i++) {
443 fX[i] = tvX(itvXL + i);
444 fY[i] = tvY(itvYL + i);
445 fExL[i] = tvExL(itvExLL + i);
446 fExH[i] = tvExH(itvExHL + i);
447 fEyL[0][i] = tvEyL(itvEyLL + i);
448 fEyH[0][i] = tvEyH(itvEyHL + i);
449 }
450
452}
453
454////////////////////////////////////////////////////////////////////////////////
455/// Constructor with six vectors of doubles in input and a single y error dimension.
456/// The signature of this constructor is equal to the corresponding constructor of TGraphAsymmErrors.
457/// A grapherrors is built with the X coordinates taken from `tvX` the Y coordinates from `tvY`
458/// and the errors from vectors `tvExL`, `tvExH` and `tvEyL`, `tvEyH`.
459/// The number of points in the graph is the minimum of number of points
460/// in `tvX` and `tvY`.
461
463 const TVectorD &tvExH, const TVectorD &tvEyL, const TVectorD &tvEyH, Int_t m)
464 : TGraph(), fNYErrors(1), fSumErrorsMode(m)
465{
466 fNpoints = TMath::Min(tvX.GetNrows(), tvY.GetNrows());
467
469 return;
470
471 if (!CtorAllocate())
472 return;
473
474 Int_t itvXL = tvX.GetLwb();
475 Int_t itvYL = tvY.GetLwb();
476 Int_t itvExLL = tvExL.GetLwb();
477 Int_t itvExHL = tvExH.GetLwb();
478 Int_t itvEyLL = tvEyL.GetLwb();
479 Int_t itvEyHL = tvEyH.GetLwb();
480
481 for (Int_t i = 0; i < fNpoints; i++) {
482 fX[i] = tvX(i + itvXL);
483 fY[i] = tvY(i + itvYL);
484 fExL[i] = tvExL(i + itvExLL);
485 fExH[i] = tvExH(i + itvExHL);
486 fEyL[0][i] = tvEyL(i + itvEyLL);
487 fEyH[0][i] = tvEyH(i + itvEyHL);
488 }
489
491}
492
493////////////////////////////////////////////////////////////////////////////////
494/// Constructor with multiple vectors of floats in input and multiple y error dimension.
495/// A grapherrors is built with the X coordinates taken from `tvX` the Y coordinates from `tvY`
496/// and the errors from vectors `tvExL`, `tvExH` and `tvEyL/H[yErrorDimension]`.
497/// The number of points in the graph is the minimum of number of points
498/// in `tvX` and `tvY`.
499
500TGraphMultiErrors::TGraphMultiErrors(Int_t ne, const TVectorF &tvX, const TVectorF &tvY, const TVectorF &tvExL,
501 const TVectorF &tvExH, const TVectorF *tvEyL, const TVectorF *tvEyH, Int_t m)
502 : TGraph(), fNYErrors(ne), fSumErrorsMode(m)
503{
504 fNpoints = TMath::Min(tvX.GetNrows(), tvY.GetNrows());
505
507 return;
508
509 if (!CtorAllocate())
510 return;
511
512 Int_t itvXL = tvX.GetLwb();
513 Int_t itvYL = tvY.GetLwb();
514 Int_t itvExLL = tvExL.GetLwb();
515 Int_t itvExHL = tvExH.GetLwb();
516
517 for (Int_t i = 0; i < fNpoints; i++) {
518 fX[i] = tvX(i + itvXL);
519 fY[i] = tvY(i + itvYL);
520 fExL[i] = tvExL(i + itvExLL);
521 fExH[i] = tvExH(i + itvExHL);
522
523 for (Int_t j = 0; j < ne; j++) {
524 fEyL[j][i] = tvEyL[j](i + tvEyL[j].GetLwb());
525 fEyH[j][i] = tvEyH[j](i + tvEyH[j].GetLwb());
526 }
527 }
528
530}
531
532////////////////////////////////////////////////////////////////////////////////
533/// Constructor with multiple vectors of doubles in input and multiple y error dimensions
534/// A grapherrors is built with the X coordinates taken from `tvX` the Y coordinates from `tvY`
535/// and the errors from vectors `tvExL`, `tvExH` and `tvEyL/H[yErrorDimension]`.
536/// The number of points in the graph is the minimum of number of points
537/// in `tvX` and `tvY`.
538
539TGraphMultiErrors::TGraphMultiErrors(Int_t ne, const TVectorD &tvX, const TVectorD &tvY, const TVectorD &tvExL,
540 const TVectorD &tvExH, const TVectorD *tvEyL, const TVectorD *tvEyH, Int_t m)
541 : TGraph(), fNYErrors(ne), fSumErrorsMode(m)
542{
543 fNpoints = TMath::Min(tvX.GetNrows(), tvY.GetNrows());
544
546 return;
547
548 if (!CtorAllocate())
549 return;
550
551 Int_t itvXL = tvX.GetLwb();
552 Int_t itvYL = tvY.GetLwb();
553 Int_t itvExLL = tvExL.GetLwb();
554 Int_t itvExHL = tvExH.GetLwb();
555
556 for (Int_t i = 0; i < fNpoints; i++) {
557 fX[i] = tvX(i + itvXL);
558 fY[i] = tvY(i + itvYL);
559 fExL[i] = tvExL(i + itvExLL);
560 fExH[i] = tvExH(i + itvExHL);
561
562 for (Int_t j = 0; j < ne; j++) {
563 fEyL[j][i] = tvEyL[j](i + tvEyL[j].GetLwb());
564 fEyH[j][i] = tvEyH[j](i + tvEyH[j].GetLwb());
565 }
566 }
567
569}
570
571////////////////////////////////////////////////////////////////////////////////
572/// TGraphMultiErrors copy constructor.
573
575{
576 fNYErrors = tgme.fNYErrors;
578
579 if (!CtorAllocate())
580 return;
581
582 Int_t n = fNpoints * sizeof(Double_t);
583 memcpy(fExL, tgme.fExL, n);
584 memcpy(fExH, tgme.fExH, n);
585
586 for (Int_t j = 0; j < fNYErrors; j++) {
587 fEyL[j] = tgme.fEyL[j];
588 fEyH[j] = tgme.fEyH[j];
589 tgme.fAttFill[j].Copy(fAttFill[j]);
590 tgme.fAttLine[j].Copy(fAttLine[j]);
591 }
592
594}
595
596////////////////////////////////////////////////////////////////////////////////
597/// TGraphMultiErrors assignment operator.
598
600{
601 if (this != &tgme) {
602 TGraph::operator=(tgme);
603 // delete arrays
604 if (fExL)
605 delete[] fExL;
606 if (fExH)
607 delete[] fExH;
608 if (fEyLSum)
609 delete[] fEyLSum;
610 if (fEyHSum)
611 delete[] fEyHSum;
612
613 fNYErrors = tgme.fNYErrors;
615
616 if (!CtorAllocate())
617 return *this;
618
619 Int_t n = fNpoints * sizeof(Double_t);
620 memcpy(fExL, tgme.fExL, n);
621 memcpy(fExH, tgme.fExH, n);
622 memcpy(fEyLSum, tgme.fEyLSum, n);
623 memcpy(fEyHSum, tgme.fEyHSum, n);
624
625 for (Int_t j = 0; j < fNYErrors; j++) {
626 fEyL[j] = tgme.fEyL[j];
627 fEyH[j] = tgme.fEyH[j];
628 tgme.fAttFill[j].Copy(fAttFill[j]);
629 tgme.fAttLine[j].Copy(fAttLine[j]);
630 }
631 }
632 return *this;
633}
634
635////////////////////////////////////////////////////////////////////////////////
636/// TGraphMultiErrors constructor importing its parameters from the TH1 object passed as argument.
637/// The low and high errors are set to the bin error of the histogram.
638
640 : TGraph(h), fNYErrors(ne), fSumErrorsMode(TGraphMultiErrors::kOnlyFirst)
641{
642 if (!CtorAllocate())
643 return;
644
645 for (Int_t i = 0; i < fNpoints; i++) {
646 fExL[i] = h->GetBinWidth(i + 1) * gStyle->GetErrorX();
647 fExH[i] = h->GetBinWidth(i + 1) * gStyle->GetErrorX();
648 fEyL[0][i] = h->GetBinError(i + 1);
649 fEyH[0][i] = h->GetBinError(i + 1);
650
651 for (Int_t j = 1; j < fNYErrors; j++) {
652 fEyL[j][i] = 0.;
653 fEyH[j][i] = 0.;
654 }
655 }
656
658
661}
662
663////////////////////////////////////////////////////////////////////////////////
664/// Creates a TGraphMultiErrors by dividing two input TH1 histograms:
665/// pass/total. (see TGraphMultiErrors::Divide)
666
668 : TGraph(pass ? pass->GetNbinsX() : 0), fNYErrors(ne), fSumErrorsMode(TGraphMultiErrors::kOnlyFirst)
669{
670 if (!pass || !total) {
671 Error("TGraphMultiErrors", "Invalid histogram pointers");
672 return;
673 }
674
675 if (!CtorAllocate())
676 return;
677
678 std::string sname = "divide_" + std::string(pass->GetName()) + "_by_" + std::string(total->GetName());
679 SetName(sname.c_str());
680 SetTitle(pass->GetTitle());
681
682 // copy style from pass
683 pass->TAttLine::Copy(*this);
684 pass->TAttFill::Copy(*this);
685 pass->TAttMarker::Copy(*this);
686
687 Divide(pass, total, option);
689
692}
693
694////////////////////////////////////////////////////////////////////////////////
695/// TGraphMultiErrors default destructor.
696
698{
699 if (fExL)
700 delete[] fExL;
701 if (fExH)
702 delete[] fExH;
703 fEyL.resize(0);
704 fEyH.resize(0);
705 if (fEyLSum)
706 delete[] fEyLSum;
707 if (fEyHSum)
708 delete[] fEyHSum;
709 fAttFill.resize(0);
710 fAttLine.resize(0);
711}
712
713////////////////////////////////////////////////////////////////////////////////
714/// Should be called from ctors after `fNpoints` has been set
715/// Note: This function should be called only from the constructor
716/// since it does not delete previously existing arrays
717
719{
720 if (!fNpoints || !fNYErrors) {
721 fExL = fExH = nullptr;
722 fEyL.resize(0);
723 fEyH.resize(0);
724 return kFALSE;
725 }
726
727 fExL = new Double_t[fMaxSize];
728 fExH = new Double_t[fMaxSize];
729 fEyL.resize(fNYErrors, TArrayD(fMaxSize));
730 fEyH.resize(fNYErrors, TArrayD(fMaxSize));
733 fAttFill.resize(fNYErrors);
734 fAttLine.resize(fNYErrors);
735
736 Int_t n = fMaxSize * sizeof(Double_t);
737 memset(fExL, 0, n);
738 memset(fExH, 0, n);
739 memset(fEyLSum, 0, n);
740 memset(fEyHSum, 0, n);
741
742 return kTRUE;
743}
744
745////////////////////////////////////////////////////////////////////////////////
746/// Copy and release.
747
748void TGraphMultiErrors::CopyAndRelease(Double_t **newarrays, Int_t ibegin, Int_t iend, Int_t obegin)
749{
750 CopyPoints(newarrays, ibegin, iend, obegin);
751 if (newarrays) {
752 delete[] fX;
753 fX = newarrays[0];
754 delete[] fY;
755 fY = newarrays[1];
756
757 delete[] fExL;
758 fExL = newarrays[2];
759 delete[] fExH;
760 fExH = newarrays[3];
761
762 if (fEyLSum)
763 delete[] fEyLSum;
764 fEyLSum = newarrays[4];
765 if (fEyHSum)
766 delete[] fEyHSum;
767 fEyHSum = newarrays[5];
768
769 delete[] newarrays;
770 }
771}
772
773////////////////////////////////////////////////////////////////////////////////
774/// Copy errors from `fE***` to `arrays[***]`
775/// or to `f***` Copy points.
776
778{
779 if (TGraph::CopyPoints(arrays, ibegin, iend, obegin)) {
780 Int_t n = (iend - ibegin) * sizeof(Double_t);
781
782 if (arrays) {
783 memmove(&arrays[2][obegin], &fExL[ibegin], n);
784 memmove(&arrays[3][obegin], &fExH[ibegin], n);
785 memmove(&arrays[4][obegin], &fEyLSum[ibegin], n);
786 memmove(&arrays[5][obegin], &fEyHSum[ibegin], n);
787 } else {
788 memmove(&fExL[obegin], &fExL[ibegin], n);
789 memmove(&fExH[obegin], &fExH[ibegin], n);
790 memmove(&fEyLSum[obegin], &fEyLSum[ibegin], n);
791 memmove(&fEyHSum[obegin], &fEyHSum[ibegin], n);
792 }
793
794 return kTRUE;
795 } else
796 return kFALSE;
797}
798
799////////////////////////////////////////////////////////////////////////////////
800/// Set zero values for point arrays in the range `[begin, end]`.
801
803{
804 if (!from_ctor)
805 TGraph::FillZero(begin, end, from_ctor);
806
807 Int_t n = (end - begin) * sizeof(Double_t);
808 memset(fExL + begin, 0, n);
809 memset(fExH + begin, 0, n);
810 memset(fEyLSum + begin, 0, n);
811 memset(fEyHSum + begin, 0, n);
812
813 for (Int_t j = 0; j < fNYErrors; j++) {
814 memset(fEyL[j].GetArray() + begin, 0, n);
815 memset(fEyH[j].GetArray() + begin, 0, n);
816 }
817}
818
819////////////////////////////////////////////////////////////////////////////////
820/// Recalculates the summed y error arrays.
821
823{
824 if (!fEyLSum)
826 if (!fEyHSum)
828
829 for (Int_t i = 0; i < fNpoints; i++) {
830 fEyLSum[i] = GetErrorYlow(i);
831 fEyHSum[i] = GetErrorYhigh(i);
832 }
833}
834
835////////////////////////////////////////////////////////////////////////////////
836/// Protected function to perform the merge operation of a graph with multiple asymmetric errors.
837
839{
840 if (tg->GetN() == 0)
841 return kFALSE;
842
843 if (tg->IsA() == TGraphMultiErrors::Class()) {
844 auto tgme = (TGraphMultiErrors *)tg;
845
846 for (Int_t i = 0; i < tgme->GetN(); i++) {
847 Int_t ipoint = GetN();
848 Double_t x, y;
849 tgme->GetPoint(i, x, y);
850 SetPoint(ipoint, x, y);
851 SetPointEX(ipoint, tgme->GetErrorXlow(i), tgme->GetErrorXhigh(i));
852 for (Int_t j = 0; j < tgme->GetNYErrors(); j++)
853 SetPointEY(ipoint, j, tgme->GetErrorYlow(i, j), tgme->GetErrorYhigh(i, j));
854 }
855
856 return kTRUE;
857 } else {
858 Warning("DoMerge", "Merging a %s is not compatible with a TGraphMultiErrors - Errors will be ignored",
859 tg->IsA()->GetName());
860 return TGraph::DoMerge(tg);
861 }
862
863 return kFALSE;
864}
865
866////////////////////////////////////////////////////////////////////////////////
867/// Swap points.
868
870{
871 SwapValues(fExL, pos1, pos2);
872 SwapValues(fExH, pos1, pos2);
873
874 for (Int_t j = 0; j <= fNYErrors; j++) {
875 SwapValues(fEyL[j].GetArray(), pos1, pos2);
876 SwapValues(fEyH[j].GetArray(), pos1, pos2);
877 }
878
879 TGraph::SwapPoints(pos1, pos2);
880}
881
882////////////////////////////////////////////////////////////////////////////////
883/// Add a new y error to the graph and fill it with the values from `eyL` and `eyH`
884
885void TGraphMultiErrors::AddYError(Int_t np, const Double_t *eyL, const Double_t *eyH)
886{
887 fEyL.emplace_back(np, eyL);
888 fEyH.emplace_back(np, eyH);
889 fEyL.back().Set(fNpoints);
890 fEyH.back().Set(fNpoints);
891 fAttFill.emplace_back();
892 fAttLine.emplace_back();
893
894 fNYErrors += 1;
895
897}
898
899////////////////////////////////////////////////////////////////////////////////
900/// Allocate internal data structures for `size` points.
902{
903 return AllocateArrays(6, size);
904}
905
906////////////////////////////////////////////////////////////////////////////////
907/// Apply a function to all data points \f$ y = f(x,y) \f$.
908///
909/// Errors are calculated as \f$ eyh = f(x,y+eyh)-f(x,y) \f$ and
910/// \f$ eyl = f(x,y)-f(x,y-eyl) \f$
911///
912/// Only the first error dimension is affected.
913///
914/// Special treatment has to be applied for the functions where the
915/// role of "up" and "down" is reversed.
916///
917/// Function suggested/implemented by Miroslav Helbich <helbich@mail.desy.de>
918
920{
921 Double_t x, y, eyL, eyH, eyLNew, eyHNew, fxy;
922
923 if (fHistogram) {
924 delete fHistogram;
925 fHistogram = nullptr;
926 }
927
928 for (Int_t i = 0; i < fNpoints; i++) {
929 GetPoint(i, x, y);
930 eyL = GetErrorYlow(i, 0);
931 eyH = GetErrorYhigh(i, 0);
932
933 fxy = f->Eval(x, y);
934 SetPoint(i, x, fxy);
935
936 if (f->Eval(x, y - eyL) < f->Eval(x, y + eyH)) {
937 eyLNew = TMath::Abs(fxy - f->Eval(x, y - eyL));
938 eyHNew = TMath::Abs(f->Eval(x, y + eyH) - fxy);
939 } else {
940 eyHNew = TMath::Abs(fxy - f->Eval(x, y - eyL));
941 eyLNew = TMath::Abs(f->Eval(x, y + eyH) - fxy);
942 }
943
944 // systematic errors and error on x doesn't change
945 SetPointEY(i, 0, eyLNew, eyHNew);
946 }
947
948 if (gPad)
949 gPad->Modified();
950}
951
952////////////////////////////////////////////////////////////////////////////////
953/// This function is only kept for backward compatibility.
954/// You should rather use the Divide method.
955/// It calls `Divide(pass,total,"cl=0.683 b(1,1) mode")` which is equivalent to the
956/// former BayesDivide method.
957
959{
960 Divide(pass, total, "cl=0.683 b(1,1) mode");
961}
962
963////////////////////////////////////////////////////////////////////////////////
964/// This function was adapted from the TGraphAsymmErrors class.
965/// See TGraphAsymmErrors::Divide for the documentation
966///
967/// Only the first error dimension is affected.
968
969void TGraphMultiErrors::Divide(const TH1 *pass, const TH1 *total, Option_t *opt)
970{
971 // check pointers
972 if (!pass || !total) {
973 Error("Divide", "one of the passed pointers is zero");
974 return;
975 }
976
977 // check dimension of histograms; only 1-dimensional ones are accepted
978 if ((pass->GetDimension() > 1) || (total->GetDimension() > 1)) {
979 Error("Divide", "passed histograms are not one-dimensional");
980 return;
981 }
982
983 // check whether histograms are filled with weights -> use number of effective
984 // entries
985 Bool_t bEffective = false;
986 // compare sum of weights with sum of squares of weights
987 // re-compute here to be sure to get the right values
988 Double_t psumw = 0;
989 Double_t psumw2 = 0;
990 if (pass->GetSumw2()->fN > 0) {
991 for (int i = 0; i < pass->GetNbinsX(); ++i) {
992 psumw += pass->GetBinContent(i);
993 psumw2 += pass->GetSumw2()->At(i);
994 }
995 } else {
996 psumw = pass->GetSumOfWeights();
997 psumw2 = psumw;
998 }
999 if (TMath::Abs(psumw - psumw2) > 1e-6)
1000 bEffective = true;
1001
1002 Double_t tsumw = 0;
1003 Double_t tsumw2 = 0;
1004 if (total->GetSumw2()->fN > 0) {
1005 for (int i = 0; i < total->GetNbinsX(); ++i) {
1006 tsumw += total->GetBinContent(i);
1007 tsumw2 += total->GetSumw2()->At(i);
1008 }
1009 } else {
1010 tsumw = total->GetSumOfWeights();
1011 tsumw2 = tsumw;
1012 }
1013 if (TMath::Abs(tsumw - tsumw2) > 1e-6)
1014 bEffective = true;
1015
1016 // we do not want to ignore the weights
1017 // if (bEffective && (pass->GetSumw2()->fN == 0 || total->GetSumw2()->fN == 0) ) {
1018 // Warning("Divide","histogram have been computed with weights but the sum of weight squares are not stored in the
1019 // histogram. Error calculation is performed ignoring the weights"); bEffective = false;
1020 // }
1021
1022 // parse option
1023 TString option = opt;
1024 option.ToLower();
1025
1026 Bool_t bVerbose = false;
1027 // pointer to function returning the boundaries of the confidence interval
1028 //(is only used in the frequentist cases.)
1029 // Double_t (*pBound)(Int_t,Int_t,Double_t,Bool_t) = &TEfficiency::ClopperPearson; // default method
1030 Double_t (*pBound)(Double_t, Double_t, Double_t, Bool_t) = &TEfficiency::ClopperPearson; // default method
1031 // confidence level
1032 Double_t conf = 0.682689492137;
1033 // values for bayesian statistics
1034 Bool_t bIsBayesian = false;
1035 Double_t alpha = 1;
1036 Double_t beta = 1;
1037
1038 // verbose mode
1039 if (option.Contains("v")) {
1040 option.ReplaceAll("v", "");
1041 bVerbose = true;
1042 if (bEffective)
1043 Info("Divide", "weight will be considered in the Histogram Ratio");
1044 }
1045
1046 // confidence level
1047 if (option.Contains("cl=")) {
1048 Double_t level = -1;
1049 // coverity [secure_coding : FALSE]
1050 sscanf(strstr(option.Data(), "cl="), "cl=%lf", &level);
1051 if ((level > 0) && (level < 1))
1052 conf = level;
1053 else
1054 Warning("Divide", "given confidence level %.3lf is invalid", level);
1055 option.ReplaceAll("cl=", "");
1056 }
1057
1058 // normal approximation
1059 if (option.Contains("n")) {
1060 option.ReplaceAll("n", "");
1061 pBound = &TEfficiency::Normal;
1062 }
1063
1064 // clopper pearson interval
1065 if (option.Contains("cp")) {
1066 option.ReplaceAll("cp", "");
1068 }
1069
1070 // wilson interval
1071 if (option.Contains("w")) {
1072 option.ReplaceAll("w", "");
1073 pBound = &TEfficiency::Wilson;
1074 }
1075
1076 // agresti coull interval
1077 if (option.Contains("ac")) {
1078 option.ReplaceAll("ac", "");
1079 pBound = &TEfficiency::AgrestiCoull;
1080 }
1081 // Feldman-Cousins interval
1082 if (option.Contains("fc")) {
1083 option.ReplaceAll("fc", "");
1085 }
1086 // mid-P Lancaster interval (In a later ROOT Version!)
1087 if (option.Contains("midp")) {
1088 option.ReplaceAll("midp", "");
1089 // pBound = &TEfficiency::MidPInterval;
1090 }
1091
1092 // bayesian with prior
1093 if (option.Contains("b(")) {
1094 Double_t a = 0;
1095 Double_t b = 0;
1096 sscanf(strstr(option.Data(), "b("), "b(%lf,%lf)", &a, &b);
1097 if (a > 0)
1098 alpha = a;
1099 else
1100 Warning("Divide", "given shape parameter for alpha %.2lf is invalid", a);
1101 if (b > 0)
1102 beta = b;
1103 else
1104 Warning("Divide", "given shape parameter for beta %.2lf is invalid", b);
1105 option.ReplaceAll("b(", "");
1106 bIsBayesian = true;
1107 }
1108
1109 // use posterior mode
1110 Bool_t usePosteriorMode = false;
1111 if (bIsBayesian && option.Contains("mode")) {
1112 usePosteriorMode = true;
1113 option.ReplaceAll("mode", "");
1114 }
1115
1116 Bool_t plot0Bins = false;
1117 if (option.Contains("e0")) {
1118 plot0Bins = true;
1119 option.ReplaceAll("e0", "");
1120 }
1121
1122 Bool_t useShortestInterval = false;
1123 if (bIsBayesian && (option.Contains("sh") || (usePosteriorMode && !option.Contains("cen")))) {
1124 useShortestInterval = true;
1125 }
1126
1127 // interpret as Poisson ratio
1128 Bool_t bPoissonRatio = false;
1129 if (option.Contains("pois")) {
1130 bPoissonRatio = true;
1131 option.ReplaceAll("pois", "");
1132 }
1133
1134 // weights works only in case of Normal approximation or Bayesian for binomial interval
1135 // in case of Poisson ratio we can use weights by rescaling the obtained results using the effective entries
1136 if ((bEffective && !bPoissonRatio) && !bIsBayesian && pBound != &TEfficiency::Normal) {
1137 Warning("Divide", "Histograms have weights: only Normal or Bayesian error calculation is supported");
1138 Info("Divide", "Using now the Normal approximation for weighted histograms");
1139 }
1140
1141 if (bPoissonRatio) {
1142 if (pass->GetDimension() != total->GetDimension()) {
1143 Error("Divide", "passed histograms are not of the same dimension");
1144 return;
1145 }
1146
1147 if (!TEfficiency::CheckBinning(*pass, *total)) {
1148 Error("Divide", "passed histograms are not consistent");
1149 return;
1150 }
1151 } else {
1152 // check consistency of histograms, allowing weights
1153 if (!TEfficiency::CheckConsistency(*pass, *total, "w")) {
1154 Error("Divide", "passed histograms are not consistent");
1155 return;
1156 }
1157 }
1158
1159 // Set the graph to have a number of points equal to the number of histogram
1160 // bins
1161 Int_t nbins = pass->GetNbinsX();
1162 Set(nbins);
1163
1164 // Ok, now set the points for each bin
1165 // (Note: the TH1 bin content is shifted to the right by one:
1166 // bin=0 is underflow, bin=nbins+1 is overflow.)
1167
1168 // this keeps track of the number of points added to the graph
1169 Int_t npoint = 0;
1170 // number of total and passed events
1171 Double_t t = 0, p = 0;
1172 Double_t tw = 0, tw2 = 0, pw = 0, pw2 = 0, wratio = 1; // for the case of weights
1173 // loop over all bins and fill the graph
1174 for (Int_t b = 1; b <= nbins; ++b) {
1175 // efficiency with lower and upper boundary of confidence interval default value when total =0;
1176 Double_t eff = 0., low = 0., upper = 0.;
1177
1178 // special case in case of weights we have to consider the sum of weights and the sum of weight squares
1179 if (bEffective) {
1180 tw = total->GetBinContent(b);
1181 tw2 = (total->GetSumw2()->fN > 0) ? total->GetSumw2()->At(b) : tw;
1182 pw = pass->GetBinContent(b);
1183 pw2 = (pass->GetSumw2()->fN > 0) ? pass->GetSumw2()->At(b) : pw;
1184
1185 if (bPoissonRatio) {
1186 // tw += pw;
1187 // tw2 += pw2;
1188 // compute ratio on the effective entries ( p and t)
1189 // special case is when (pw=0, pw2=0) in this case we cannot get the bin weight.
1190 // we use then the overall weight of the full histogram
1191 if (pw == 0 && pw2 == 0)
1192 p = 0;
1193 else
1194 p = (pw * pw) / pw2;
1195
1196 if (tw == 0 && tw2 == 0)
1197 t = 0;
1198 else
1199 t = (tw * tw) / tw2;
1200
1201 if (pw > 0 && tw > 0)
1202 // this is the ratio of the two bin weights ( pw/p / t/tw )
1203 wratio = (pw * t) / (p * tw);
1204 else if (pw == 0 && tw > 0)
1205 // case p histogram has zero compute the weights from all the histogram
1206 // weight of histogram - sumw2/sumw
1207 wratio = (psumw2 * t) / (psumw * tw);
1208 else if (tw == 0 && pw > 0)
1209 // case t histogram has zero compute the weights from all the histogram
1210 // weight of histogram - sumw2/sumw
1211 wratio = (pw * tsumw) / (p * tsumw2);
1212 else if (p > 0)
1213 wratio = pw / p; // not sure if needed
1214 else {
1215 // case both pw and tw are zero - we skip these bins
1216 if (!plot0Bins)
1217 continue; // skip bins with total <= 0
1218 }
1219
1220 t += p;
1221 // std::cout << p << " " << t << " " << wratio << std::endl;
1222 } else if (tw <= 0 && !plot0Bins)
1223 continue; // skip bins with total <= 0
1224
1225 // in the case of weights have the formula only for
1226 // the normal and bayesian statistics (see below)
1227
1228 }
1229
1230 // use bin contents
1231 else {
1232 t = TMath::Nint(total->GetBinContent(b));
1233 p = TMath::Nint(pass->GetBinContent(b));
1234
1235 if (bPoissonRatio)
1236 t += p;
1237
1238 if (t == 0. && !plot0Bins)
1239 continue; // skip bins with total = 0
1240 }
1241
1242 // using bayesian statistics
1243 if (bIsBayesian) {
1244 if ((bEffective && !bPoissonRatio) && tw2 <= 0) {
1245 // case of bins with zero errors
1246 eff = pw / tw;
1247 low = eff;
1248 upper = eff;
1249 } else {
1250 Double_t aa, bb;
1251
1252 if (bEffective && !bPoissonRatio) {
1253 // tw/tw2 re-normalize the weights
1254 double norm = tw / tw2; // case of tw2 = 0 is treated above
1255 aa = pw * norm + alpha;
1256 bb = (tw - pw) * norm + beta;
1257 } else {
1258 aa = double(p) + alpha;
1259 bb = double(t - p) + beta;
1260 }
1261 if (usePosteriorMode)
1262 eff = TEfficiency::BetaMode(aa, bb);
1263 else
1264 eff = TEfficiency::BetaMean(aa, bb);
1265
1266 if (useShortestInterval) {
1267 TEfficiency::BetaShortestInterval(conf, aa, bb, low, upper);
1268 } else {
1269 low = TEfficiency::BetaCentralInterval(conf, aa, bb, false);
1270 upper = TEfficiency::BetaCentralInterval(conf, aa, bb, true);
1271 }
1272 }
1273 }
1274 // case of non-bayesian statistics
1275 else {
1276 if (bEffective && !bPoissonRatio) {
1277
1278 if (tw > 0) {
1279
1280 eff = pw / tw;
1281
1282 // use normal error calculation using variance of MLE with weights (F.James 8.5.2)
1283 // this is the same formula used in ROOT for TH1::Divide("B")
1284
1285 double variance = (pw2 * (1. - 2 * eff) + tw2 * eff * eff) / (tw * tw);
1286 double sigma = sqrt(variance);
1287
1288 double prob = 0.5 * (1. - conf);
1289 double delta = ROOT::Math::normal_quantile_c(prob, sigma);
1290 low = eff - delta;
1291 upper = eff + delta;
1292 if (low < 0)
1293 low = 0;
1294 if (upper > 1)
1295 upper = 1.;
1296 }
1297 } else {
1298 // when not using weights (all cases) or in case of Poisson ratio with weights
1299 if (t != 0.)
1300 eff = ((Double_t)p) / t;
1301
1302 low = pBound(t, p, conf, false);
1303 upper = pBound(t, p, conf, true);
1304 }
1305 }
1306 // treat as Poisson ratio
1307 if (bPoissonRatio) {
1308 Double_t ratio = eff / (1 - eff);
1309 // take the intervals in eff as intervals in the Poisson ratio
1310 low = low / (1. - low);
1311 upper = upper / (1. - upper);
1312 eff = ratio;
1313 if (bEffective) {
1314 // scale result by the ratio of the weight
1315 eff *= wratio;
1316 low *= wratio;
1317 upper *= wratio;
1318 }
1319 }
1320 // Set the point center and its errors
1321 if (TMath::Finite(eff)) {
1322 SetPoint(npoint, pass->GetBinCenter(b), eff);
1323 SetPointEX(npoint, pass->GetBinCenter(b) - pass->GetBinLowEdge(b),
1324 pass->GetBinLowEdge(b) - pass->GetBinCenter(b) + pass->GetBinWidth(b));
1325 SetPointEY(npoint, 0, eff - low, upper - eff);
1326 npoint++; // we have added a point to the graph
1327 }
1328 }
1329
1330 Set(npoint); // tell the graph how many points we've really added
1331 if (npoint < nbins)
1332 Warning("Divide", "Number of graph points is different than histogram bins - %d points have been skipped",
1333 nbins - npoint);
1334
1335 if (bVerbose) {
1336 Info("Divide", "made a graph with %d points from %d bins", npoint, nbins);
1337 Info("Divide", "used confidence level: %.2lf\n", conf);
1338 if (bIsBayesian)
1339 Info("Divide", "used prior probability ~ beta(%.2lf,%.2lf)", alpha, beta);
1340 Print();
1341 }
1342}
1343
1344////////////////////////////////////////////////////////////////////////////////
1345/// Compute Range.
1346
1348{
1350
1351 for (Int_t i = 0; i < fNpoints; i++) {
1352 if (fX[i] - fExL[i] < xmin) {
1353 if (gPad && gPad->GetLogx()) {
1354 if (fExL[i] < fX[i])
1355 xmin = fX[i] - fExL[i];
1356 else
1357 xmin = TMath::Min(xmin, fX[i] / 3.);
1358 } else
1359 xmin = fX[i] - fExL[i];
1360 }
1361
1362 if (fX[i] + fExH[i] > xmax)
1363 xmax = fX[i] + fExH[i];
1364
1365 Double_t eyLMax = 0., eyHMax = 0.;
1366 for (Int_t j = 0; j < fNYErrors; j++) {
1367 eyLMax = TMath::Max(eyLMax, fEyL[j][i]);
1368 eyHMax = TMath::Max(eyHMax, fEyH[j][i]);
1369 }
1370
1371 if (fY[i] - eyLMax < ymin) {
1372 if (gPad && gPad->GetLogy()) {
1373 if (eyLMax < fY[i])
1374 ymin = fY[i] - eyLMax;
1375 else
1376 ymin = TMath::Min(ymin, fY[i] / 3.);
1377 } else
1378 ymin = fY[i] - eyLMax;
1379 }
1380
1381 if (fY[i] + eyHMax > ymax)
1382 ymax = fY[i] + eyHMax;
1383 }
1384}
1385
1386////////////////////////////////////////////////////////////////////////////////
1387/// Deletes the y error with the index `e`.
1388/// Note that you must keep at least 1 error
1389
1391{
1392 if (fNYErrors == 1 || e >= fNYErrors)
1393 return;
1394
1395 fEyL.erase(fEyL.begin() + e);
1396 fEyH.erase(fEyH.begin() + e);
1397 fAttFill.erase(fAttFill.begin() + e);
1398 fAttLine.erase(fAttLine.begin() + e);
1399
1400 fNYErrors -= 1;
1401}
1402
1403////////////////////////////////////////////////////////////////////////////////
1404/// Get error on x coordinate for point `i`.
1405/// In case of asymmetric errors the mean of the square sum is returned
1406
1408{
1409 if (i < 0 || i >= fNpoints || (!fExL && !fExH))
1410 return -1.;
1411
1412 Double_t exL = fExL ? fExL[i] : 0.;
1413 Double_t exH = fExH ? fExH[i] : 0.;
1414 return TMath::Sqrt((exL * exL + exH * exH) / 2.);
1415}
1416
1417////////////////////////////////////////////////////////////////////////////////
1418/// Get error on y coordinate for point `i`.
1419/// The multiple errors of the dimensions are summed according to `fSumErrorsMode`.
1420/// In case of asymmetric errors the mean of the square sum is returned
1421
1423{
1424 if (i < 0 || i >= fNpoints || (fEyL.empty() && fEyH.empty()))
1425 return -1.;
1426
1427 Double_t eyL = GetErrorYlow(i);
1428 Double_t eyH = GetErrorYhigh(i);
1429 return TMath::Sqrt((eyL * eyL + eyH * eyH) / 2.);
1430}
1431
1432////////////////////////////////////////////////////////////////////////////////
1433/// Get error e on y coordinate for point `i`.
1434/// In case of asymmetric errors the mean of the square sum is returned
1435
1437{
1438 if (i < 0 || i >= fNpoints || e >= fNYErrors || (fEyL.empty() && fEyH.empty()))
1439 return -1.;
1440
1441 Double_t eyL = fEyL.empty() ? 0. : fEyL[e][i];
1442 Double_t eyH = fEyH.empty() ? 0. : fEyH[e][i];
1443 return TMath::Sqrt((eyL * eyL + eyH * eyH) / 2.);
1444}
1445
1446////////////////////////////////////////////////////////////////////////////////
1447/// Get low error on x coordinate for point `i`.
1448
1450{
1451 if (i < 0 || i >= fNpoints || !fExL)
1452 return -1.;
1453 else
1454 return fExL[i];
1455}
1456
1457////////////////////////////////////////////////////////////////////////////////
1458/// Get high error on x coordinate for point `i`.
1459
1461{
1462 if (i < 0 || i >= fNpoints || !fExH)
1463 return -1.;
1464 else
1465 return fExH[i];
1466}
1467
1468////////////////////////////////////////////////////////////////////////////////
1469/// Get low error on y coordinate for point `i`.
1470/// The multiple errors of the dimensions are summed according to `fSumErrorsMode`.
1471
1473{
1474 if (i < 0 || i >= fNpoints || fEyL.empty())
1475 return -1.;
1476
1478 return fEyL[0][i];
1480 Double_t sum = 0.;
1481 for (Int_t j = 0; j < fNYErrors; j++)
1482 sum += fEyL[j][i] * fEyL[j][i];
1483 return TMath::Sqrt(sum);
1485 Double_t sum = 0.;
1486 for (Int_t j = 0; j < fNYErrors; j++)
1487 sum += fEyL[j][i];
1488 return sum;
1489 }
1490
1491 return -1.;
1492}
1493
1494////////////////////////////////////////////////////////////////////////////////
1495/// Get high error on y coordinate for point `i`.
1496/// The multiple errors of the dimensions are summed according to `fSumErrorsMode`.
1497
1499{
1500 if (i < 0 || i >= fNpoints || fEyH.empty())
1501 return -1.;
1502
1504 return fEyH[0][i];
1506 Double_t sum = 0.;
1507 for (Int_t j = 0; j < fNYErrors; j++)
1508 sum += fEyH[j][i] * fEyH[j][i];
1509 return TMath::Sqrt(sum);
1511 Double_t sum = 0.;
1512 for (Int_t j = 0; j < fNYErrors; j++)
1513 sum += fEyH[j][i];
1514 return sum;
1515 }
1516
1517 return -1.;
1518}
1519
1520////////////////////////////////////////////////////////////////////////////////
1521/// Get low error e on y coordinate for point `i`.
1522
1524{
1525 if (i < 0 || i >= fNpoints || e >= fNYErrors || fEyL.empty())
1526 return -1.;
1527
1528 return fEyL[e][i];
1529}
1530
1531////////////////////////////////////////////////////////////////////////////////
1532/// Get high error e on y coordinate for point `i`.
1533
1535{
1536 if (i < 0 || i >= fNpoints || e >= fNYErrors || fEyH.empty())
1537 return -1.;
1538
1539 return fEyH[e][i];
1540}
1541
1542////////////////////////////////////////////////////////////////////////////////
1543/// Get all low errors on y coordinates as an array summed according to `fSumErrorsMode`.
1544
1546{
1547 if (!fEyLSum)
1549
1550 return fEyLSum;
1551}
1552
1553////////////////////////////////////////////////////////////////////////////////
1554/// Get all high errors on y coordinates as an array summed according to `fSumErrorsMode`.
1555
1557{
1558 if (!fEyHSum)
1560
1561 return fEyHSum;
1562}
1563
1564////////////////////////////////////////////////////////////////////////////////
1565/// Get all low errors `e` on y coordinates as an array.
1566
1568{
1569 if (e >= fNYErrors || fEyL.empty())
1570 return nullptr;
1571 else
1572 return fEyL[e].GetArray();
1573}
1574
1575////////////////////////////////////////////////////////////////////////////////
1576/// Get all high errors `e` on y coordinates as an array.
1577
1579{
1580 if (e >= fNYErrors || fEyH.empty())
1581 return nullptr;
1582 else
1583 return fEyH[e].GetArray();
1584}
1585
1586////////////////////////////////////////////////////////////////////////////////
1587/// Get AttFill pointer for specified error dimension.
1588
1590{
1591 if (e >= 0 && e < fNYErrors)
1592 return &fAttFill.at(e);
1593 else
1594 return nullptr;
1595}
1596
1597////////////////////////////////////////////////////////////////////////////////
1598/// Get AttLine pointer for specified error dimension.
1599
1601{
1602 if (e >= 0 && e < fNYErrors)
1603 return &fAttLine.at(e);
1604 else
1605 return nullptr;
1606}
1607
1608////////////////////////////////////////////////////////////////////////////////
1609/// Get Fill Color for specified error e (-1 = Global and x errors).
1610
1612{
1613 if (e == -1)
1614 return GetFillColor();
1615 else if (e >= 0 && e < fNYErrors)
1616 return fAttFill[e].GetFillColor();
1617 else
1618 return 0;
1619}
1620
1621////////////////////////////////////////////////////////////////////////////////
1622/// Get Fill Style for specified error e (-1 = Global and x errors).
1623
1625{
1626 if (e == -1)
1627 return GetFillStyle();
1628 else if (e >= 0 && e < fNYErrors)
1629 return fAttFill[e].GetFillStyle();
1630 else
1631 return 0;
1632}
1633
1634////////////////////////////////////////////////////////////////////////////////
1635/// Get Line Color for specified error e (-1 = Global and x errors).
1636
1638{
1639 if (e == -1)
1640 return GetLineColor();
1641 else if (e >= 0 && e < fNYErrors)
1642 return fAttLine[e].GetLineColor();
1643 else
1644 return 0;
1645}
1646
1647////////////////////////////////////////////////////////////////////////////////
1648/// Get Line Style for specified error e (-1 = Global and x errors).
1649
1651{
1652 if (e == -1)
1653 return GetLineStyle();
1654 else if (e >= 0 && e < fNYErrors)
1655 return fAttLine[e].GetLineStyle();
1656 else
1657 return 0;
1658}
1659
1660////////////////////////////////////////////////////////////////////////////////
1661/// Get Line Width for specified error e (-1 = Global and x errors).
1662
1664{
1665 if (e == -1)
1666 return GetLineWidth();
1667 else if (e >= 0 && e < fNYErrors)
1668 return fAttLine[e].GetLineWidth();
1669 else
1670 return 0;
1671}
1672
1673////////////////////////////////////////////////////////////////////////////////
1674/// Print graph and errors values.
1675
1677{
1678 for (Int_t i = 0; i < fNpoints; i++) {
1679 printf("x[%d]=%g, y[%d]=%g", i, fX[i], i, fY[i]);
1680 if (fExL)
1681 printf(", exl[%d]=%g", i, fExL[i]);
1682 if (fExH)
1683 printf(", exh[%d]=%g", i, fExH[i]);
1684 if (!fEyL.empty())
1685 for (Int_t j = 0; j < fNYErrors; j++)
1686 printf(", eyl[%d][%d]=%g", j, i, fEyL[j][i]);
1687 if (!fEyH.empty())
1688 for (Int_t j = 0; j < fNYErrors; j++)
1689 printf(", eyh[%d][%d]=%g", j, i, fEyH[j][i]);
1690 printf("\n");
1691 }
1692}
1693
1694////////////////////////////////////////////////////////////////////////////////
1695/// Save primitive as a C++ statement(s) on output stream out
1696
1697void TGraphMultiErrors::SavePrimitive(std::ostream &out, Option_t *option)
1698{
1699 char quote = '"';
1700 out << " " << std::endl;
1701
1702 if (gROOT->ClassSaved(TGraphMultiErrors::Class()))
1703 out << " ";
1704 else
1705 out << " TGraphMultiErrors* ";
1706
1707 out << "tgme = new TGraphMultiErrors(" << fNpoints << ", " << fNYErrors << ");" << std::endl;
1708 out << " tgme->SetName(" << quote << GetName() << quote << ");" << std::endl;
1709 out << " tgme->SetTitle(" << quote << GetTitle() << quote << ");" << std::endl;
1710
1711 SaveFillAttributes(out, "tgme", 0, 1001);
1712 SaveLineAttributes(out, "tgme", 1, 1, 1);
1713 SaveMarkerAttributes(out, "tgme", 1, 1, 1);
1714
1715 for (Int_t j = 0; j < fNYErrors; j++) {
1716 fAttFill[j].SaveFillAttributes(out, Form("tgme->GetAttFill(%d)", j), 0, 1001);
1717 fAttLine[j].SaveLineAttributes(out, Form("tgme->GetAttLine(%d)", j), 1, 1, 1);
1718 }
1719
1720 for (Int_t i = 0; i < fNpoints; i++) {
1721 out << " tgme->SetPoint(" << i << ", " << fX[i] << ", " << fY[i] << ");" << std::endl;
1722 out << " tgme->SetPointEX(" << i << ", " << fExL[i] << ", " << fExH[i] << ");" << std::endl;
1723
1724 for (Int_t j = 0; j < fNYErrors; j++)
1725 out << " tgme->SetPointEY(" << i << ", " << j << ", " << fEyL[j][i] << ", " << fEyH[j][i] << ");"
1726 << std::endl;
1727 }
1728
1729 static Int_t frameNumber = 0;
1730 if (fHistogram) {
1731 frameNumber++;
1732 TString hname = fHistogram->GetName();
1733 hname += frameNumber;
1734 fHistogram->SetName(Form("Graph_%s", hname.Data()));
1735 fHistogram->SavePrimitive(out, "nodraw");
1736 out << " tgme->SetHistogram(" << fHistogram->GetName() << ");" << std::endl;
1737 out << " " << std::endl;
1738 }
1739
1740 // save list of functions
1741 TIter next(fFunctions);
1742 TObject *obj;
1743 while ((obj = next())) {
1744 obj->SavePrimitive(out, "nodraw");
1745 if (obj->InheritsFrom("TPaveStats")) {
1746 out << " tgme->GetListOfFunctions()->Add(ptstats);" << std::endl;
1747 out << " ptstats->SetParent(tgme->GetListOfFunctions());" << std::endl;
1748 } else
1749 out << " tgme->GetListOfFunctions()->Add(" << obj->GetName() << ");" << std::endl;
1750 }
1751
1752 const char *l = strstr(option, "multigraph");
1753 if (l)
1754 out << " multigraph->Add(tgme, " << quote << l + 10 << quote << ");" << std::endl;
1755 else
1756 out << " tgme->Draw(" << quote << option << quote << ");" << std::endl;
1757}
1758
1759////////////////////////////////////////////////////////////////////////////////
1760/// Multiply the values and errors of a TGraphMultiErrors by a constant c1.
1761///
1762/// If option contains "x" the x values and errors are scaled
1763/// If option contains "y" the y values and (multiple) errors are scaled
1764/// If option contains "xy" both x and y values and (multiple) errors are scaled
1765
1767{
1768 TGraph::Scale(c1, option);
1769 TString opt = option; opt.ToLower();
1770 if (opt.Contains("x") && GetEXlow()) {
1771 for (Int_t i=0; i<GetN(); i++)
1772 GetEXlow()[i] *= c1;
1773 }
1774 if (opt.Contains("x") && GetEXhigh()) {
1775 for (Int_t i=0; i<GetN(); i++)
1776 GetEXhigh()[i] *= c1;
1777 }
1778 if (opt.Contains("y")) {
1779 for (size_t d=0; d<fEyL.size(); d++)
1780 for (Int_t i=0; i<fEyL[d].GetSize(); i++)
1781 fEyL[d][i] *= c1;
1782 for (size_t d=0; d<fEyH.size(); d++)
1783 for (Int_t i=0; i<fEyH[d].GetSize(); i++)
1784 fEyH[d][i] *= c1;
1785 }
1786}
1787
1788////////////////////////////////////////////////////////////////////////////////
1789/// Set ex and ey values for point pointed by the mouse.
1790///
1791/// Up to 3 y error dimensions possible.
1792
1794 Double_t eyH2, Double_t eyL3, Double_t eyH3)
1795{
1796 Int_t px = gPad->GetEventX();
1797 Int_t py = gPad->GetEventY();
1798
1799 // localize point to be deleted
1800 Int_t ipoint = -2;
1801 Int_t i;
1802 // start with a small window (in case the mouse is very close to one point)
1803 for (i = 0; i < fNpoints; i++) {
1804 Int_t dpx = px - gPad->XtoAbsPixel(gPad->XtoPad(fX[i]));
1805 Int_t dpy = py - gPad->YtoAbsPixel(gPad->YtoPad(fY[i]));
1806
1807 if (dpx * dpx + dpy * dpy < 25) {
1808 ipoint = i;
1809 break;
1810 }
1811 }
1812
1813 if (ipoint == -2)
1814 return;
1815
1816 SetPointEX(ipoint, exL, exH);
1817
1818 if (fNYErrors > 0)
1819 SetPointEY(ipoint, 0, eyL1, eyH1);
1820 if (fNYErrors > 1)
1821 SetPointEY(ipoint, 1, eyL2, eyH2);
1822 if (fNYErrors > 2)
1823 SetPointEY(ipoint, 2, eyL3, eyH3);
1824 gPad->Modified();
1825}
1826
1827////////////////////////////////////////////////////////////////////////////////
1828/// Set ex and ey values for point `i`.
1829
1831 const Double_t *eyH)
1832{
1833 SetPointEX(i, exL, exH);
1834 SetPointEY(i, ne, eyL, eyH);
1835}
1836
1837////////////////////////////////////////////////////////////////////////////////
1838/// Set ex values for point `i`.
1839
1841{
1842 SetPointEXlow(i, exL);
1843 SetPointEXhigh(i, exH);
1844}
1845
1846////////////////////////////////////////////////////////////////////////////////
1847/// Set exL value for point `i`.
1848
1850{
1851 if (i < 0)
1852 return;
1853
1854 if (i >= fNpoints) {
1855 // re-allocate the object
1856 TGraphMultiErrors::SetPoint(i, 0., 0.);
1857 }
1858
1859 fExL[i] = exL;
1860}
1861
1862////////////////////////////////////////////////////////////////////////////////
1863/// Set exH value for point `i`.
1864
1866{
1867 if (i < 0)
1868 return;
1869
1870 if (i >= fNpoints) {
1871 // re-allocate the object
1872 TGraphMultiErrors::SetPoint(i, 0., 0.);
1873 }
1874
1875 fExH[i] = exH;
1876}
1877
1878////////////////////////////////////////////////////////////////////////////////
1879/// Set ey values for point `i`.
1880
1881void TGraphMultiErrors::SetPointEY(Int_t i, Int_t ne, const Double_t *eyL, const Double_t *eyH)
1882{
1883 SetPointEYlow(i, ne, eyL);
1884 SetPointEYhigh(i, ne, eyH);
1885}
1886
1887////////////////////////////////////////////////////////////////////////////////
1888/// Set eyL values for point `i`.
1889
1891{
1892 for (Int_t j = 0; j < fNYErrors; j++) {
1893 if (j < ne)
1894 SetPointEYlow(i, j, eyL[j]);
1895 else
1896 SetPointEYlow(i, j, 0.);
1897 }
1898}
1899
1900////////////////////////////////////////////////////////////////////////////////
1901/// Set eyH values for point `i`.
1902
1904{
1905 for (Int_t j = 0; j < fNYErrors; j++) {
1906 if (j < ne)
1907 SetPointEYhigh(i, j, eyH[j]);
1908 else
1909 SetPointEYhigh(i, j, 0.);
1910 }
1911}
1912
1913////////////////////////////////////////////////////////////////////////////////
1914/// Set error e ey values for point `i`.
1915
1917{
1918 SetPointEYlow(i, e, eyL);
1919 SetPointEYhigh(i, e, eyH);
1920}
1921
1922////////////////////////////////////////////////////////////////////////////////
1923/// Set error e eyL value for point `i`.
1924
1926{
1927 if (i < 0 || e < 0)
1928 return;
1929
1930 if (i >= fNpoints)
1931 // re-allocate the object
1932 TGraphMultiErrors::SetPoint(i, 0., 0.);
1933
1934 while (e >= fNYErrors)
1936
1937 fEyL[e][i] = eyL;
1938 if (fEyLSum)
1939 fEyLSum[i] = GetErrorYlow(i);
1940 else
1942}
1943
1944////////////////////////////////////////////////////////////////////////////////
1945/// Set error e eyH value for point `i`.
1946
1948{
1949 if (i < 0 || e < 0)
1950 return;
1951
1952 if (i >= fNpoints)
1953 // re-allocate the object
1954 TGraphMultiErrors::SetPoint(i, 0., 0.);
1955
1956 while (e >= fNYErrors)
1958
1959 fEyH[e][i] = eyH;
1960 if (fEyHSum)
1961 fEyHSum[i] = GetErrorYhigh(i);
1962 else
1964}
1965
1966////////////////////////////////////////////////////////////////////////////////
1967/// Set error e ey values.
1968
1969void TGraphMultiErrors::SetEY(Int_t e, Int_t np, const Double_t *eyL, const Double_t *eyH)
1970{
1971 SetEYlow(e, np, eyL);
1972 SetEYhigh(e, np, eyH);
1973}
1974
1975////////////////////////////////////////////////////////////////////////////////
1976/// Set error e eyL values.
1977
1979{
1980 for (Int_t i = 0; i < fNpoints; i++) {
1981 if (i < np)
1982 SetPointEYlow(i, e, eyL[i]);
1983 else
1984 SetPointEYlow(i, e, 0.);
1985 }
1986}
1987
1988////////////////////////////////////////////////////////////////////////////////
1989/// Set error e eyH values.
1990
1992{
1993 for (Int_t i = 0; i < fNpoints; i++) {
1994 if (i < np)
1995 SetPointEYhigh(i, e, eyH[i]);
1996 else
1997 SetPointEYhigh(i, e, 0.);
1998 }
1999}
2000
2001////////////////////////////////////////////////////////////////////////////////
2002/// Set the sum errors mode and recalculate summed errors.
2004{
2005 if (fSumErrorsMode == m)
2006 return;
2007 fSumErrorsMode = m;
2009}
2010
2011////////////////////////////////////////////////////////////////////////////////
2012/// Set TAttFill parameters of error e by copying from another TAttFill (-1 = Global and x errors).
2013
2015{
2016 if (e == -1)
2017 taf->TAttFill::Copy(*this);
2018 else if (e >= 0 && e < fNYErrors)
2019 taf->TAttFill::Copy(fAttFill[e]);
2020}
2021
2022////////////////////////////////////////////////////////////////////////////////
2023/// Set TAttLine parameters of error e by copying from another TAttLine (-1 = Global and x errors).
2024
2026{
2027 if (e == -1)
2028 taf->TAttLine::Copy(*this);
2029 else if (e >= 0 && e < fNYErrors)
2030 taf->TAttLine::Copy(fAttLine[e]);
2031}
2032
2033////////////////////////////////////////////////////////////////////////////////
2034/// Set Fill Color of error e (-1 = Global and x errors).
2035
2037{
2038 if (e == -1)
2039 SetFillColor(fcolor);
2040 else if (e >= 0 && e < fNYErrors)
2041 fAttFill[e].SetFillColor(fcolor);
2042}
2043
2044////////////////////////////////////////////////////////////////////////////////
2045/// Set Fill Color and Alpha of error e (-1 = Global and x errors).
2046
2048{
2049 if (e == -1)
2050 SetFillColorAlpha(fcolor, falpha);
2051 else if (e >= 0 && e < fNYErrors)
2052 fAttFill[e].SetFillColorAlpha(fcolor, falpha);
2053}
2054
2055////////////////////////////////////////////////////////////////////////////////
2056/// Set Fill Style of error e (-1 = Global and x errors).
2057
2059{
2060 if (e == -1)
2061 SetFillStyle(fstyle);
2062 else if (e >= 0 && e < fNYErrors)
2063 fAttFill[e].SetFillStyle(fstyle);
2064}
2065
2066////////////////////////////////////////////////////////////////////////////////
2067/// Set Line Color of error e (-1 = Global and x errors).
2068
2070{
2071 if (e == -1)
2072 SetLineColor(lcolor);
2073 else if (e >= 0 && e < fNYErrors)
2074 fAttLine[e].SetLineColor(lcolor);
2075}
2076
2077////////////////////////////////////////////////////////////////////////////////
2078/// Set Line Color and Alpha of error e (-1 = Global and x errors).
2079
2081{
2082 if (e == -1)
2083 SetLineColorAlpha(lcolor, lalpha);
2084 else if (e >= 0 && e < fNYErrors)
2085 fAttLine[e].SetLineColorAlpha(lcolor, lalpha);
2086}
2087
2088////////////////////////////////////////////////////////////////////////////////
2089/// Set Line Style of error e (-1 = Global and x errors).
2090
2092{
2093 if (e == -1)
2094 SetLineStyle(lstyle);
2095 else if (e >= 0 && e < fNYErrors)
2096 fAttLine[e].SetLineStyle(lstyle);
2097}
2098
2099////////////////////////////////////////////////////////////////////////////////
2100/// Set Line Width of error e (-1 = Global and x errors).
2101
2103{
2104 if (e == -1)
2105 SetLineWidth(lwidth);
2106 else if (e >= 0 && e < fNYErrors)
2107 fAttLine[e].SetLineWidth(lwidth);
2108}
void Class()
Definition: Class.C:29
double
Definition: Converters.cxx:939
#define d(i)
Definition: RSha256.hxx:102
#define b(i)
Definition: RSha256.hxx:100
#define f(i)
Definition: RSha256.hxx:104
#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
int Int_t
Definition: RtypesCore.h:45
char Char_t
Definition: RtypesCore.h:33
const Bool_t kFALSE
Definition: RtypesCore.h:101
short Width_t
Definition: RtypesCore.h:91
bool Bool_t
Definition: RtypesCore.h:63
double Double_t
Definition: RtypesCore.h:59
short Color_t
Definition: RtypesCore.h:92
short Style_t
Definition: RtypesCore.h:89
float Float_t
Definition: RtypesCore.h:57
const Bool_t kTRUE
Definition: RtypesCore.h:100
const char Option_t
Definition: RtypesCore.h:66
#define ClassImp(name)
Definition: Rtypes.h:364
static unsigned int total
char name[80]
Definition: TGX11.cxx:110
float xmin
Definition: THbookFile.cxx:95
float ymin
Definition: THbookFile.cxx:95
float xmax
Definition: THbookFile.cxx:95
float ymax
Definition: THbookFile.cxx:95
#define gROOT
Definition: TROOT.h:404
char * Form(const char *fmt,...)
R__EXTERN TStyle * gStyle
Definition: TStyle.h:413
#define gPad
Definition: TVirtualPad.h:288
Array of doubles (64 bits per element).
Definition: TArrayD.h:27
Double_t At(Int_t i) const
Definition: TArrayD.h:79
Int_t fN
Definition: TArray.h:38
Fill Area Attributes class.
Definition: TAttFill.h:19
void Copy(TAttFill &attfill) const
Copy this fill attributes to a new TAttFill.
Definition: TAttFill.cxx:204
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:236
Line Attributes class.
Definition: TAttLine.h:18
void Copy(TAttLine &attline) const
Copy this line attributes to a new TAttLine.
Definition: TAttLine.cxx:175
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:273
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:345
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 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:213
TGraph with asymmetric error bars and multiple y error dimensions.
virtual void ComputeRange(Double_t &xmin, Double_t &ymin, Double_t &xmax, Double_t &ymax) const
Compute Range.
virtual void Print(Option_t *chopt="") const
Print graph and errors values.
Double_t * fEyLSum
! Array of summed Y low errors for fitting
virtual Color_t GetFillColor() const
Return the fill area color.
Definition: TAttFill.h:30
virtual Style_t GetFillStyle() const
Return the fill area style.
Definition: TAttFill.h:31
virtual Double_t * GetEXhigh() const
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].
virtual void SetPointError(Double_t exL, Double_t exH, Double_t eyL1, Double_t eyH1, Double_t eyL2=0., Double_t eyH2=0., Double_t eyL3=0., Double_t eyH3=0.)
Set ex and ey values for point pointed by the mouse.
virtual TAttLine * GetAttLine(Int_t e)
Get AttLine pointer for specified error dimension.
virtual void SetFillColorAlpha(Int_t e, Color_t fcolor, Float_t falpha)
Set Fill Color and Alpha of error e (-1 = Global and x errors).
virtual Color_t GetLineColor() const
Return the line color.
Definition: TAttLine.h:33
void Divide(const TH1 *pass, const TH1 *total, Option_t *opt="cp")
This function was adapted from the TGraphAsymmErrors class.
virtual void Apply(TF1 *f)
Apply a function to all data points .
std::vector< TAttLine > fAttLine
The AttLine attributes of the different errors.
virtual void AddYError(Int_t np, const Double_t *eyL=nullptr, const Double_t *eyH=nullptr)
Add a new y error to the graph and fill it with the values from eyL and eyH
TGraphMultiErrors()
TGraphMultiErrors default constructor.
virtual void SetEY(Int_t e, Int_t np, const Double_t *eyL, const Double_t *eyH)
Set error e ey values.
virtual void SetSumErrorsMode(Int_t m)
Set the sum errors mode and recalculate summed errors.
virtual ~TGraphMultiErrors()
TGraphMultiErrors default destructor.
virtual void BayesDivide(const TH1 *pass, const TH1 *total, Option_t *opt="")
This function is only kept for backward compatibility.
TGraphMultiErrors & operator=(const TGraphMultiErrors &tgme)
TGraphMultiErrors assignment operator.
virtual Double_t GetErrorXhigh(Int_t i) const
Get high error on x coordinate for point i.
virtual Bool_t DoMerge(const TGraph *tg)
Protected function to perform the merge operation of a graph with multiple asymmetric errors.
Int_t fSumErrorsMode
How y errors are summed: kOnlyFirst = Only First; kSquareSum = Squared Sum; kSum = Absolute Addition.
virtual void Scale(Double_t c1=1., Option_t *option="y")
Multiply the values and errors of a TGraphMultiErrors by a constant c1.
virtual Width_t GetLineWidth() const
Return the line width.
Definition: TAttLine.h:35
virtual Bool_t CopyPoints(Double_t **arrays, Int_t ibegin, Int_t iend, Int_t obegin)
Copy errors from fE*** to arrays[***] or to f*** Copy points.
virtual Double_t GetErrorY(Int_t i) const
Get error on y coordinate for point i.
@ kAbsSum
Calculate the absolute sum of all errors.
@ kSquareSum
Calculate the square sum of all errors.
@ kOnlyFirst
Only take errors from first dimension.
virtual Double_t GetErrorYlow(Int_t i) const
Get low error on y coordinate for point i.
virtual Double_t * GetEYhigh() const
Get all high errors on y coordinates as an array summed according to fSumErrorsMode.
virtual TAttFill * GetAttFill(Int_t e)
Get AttFill pointer for specified error dimension.
virtual void SetLineStyle(Int_t e, Style_t lstyle)
Set Line Style of error e (-1 = Global and x errors).
virtual void SetPointEXhigh(Int_t i, Double_t exH)
Set exH value for point i.
Double_t * fExL
[fNpoints] array of X low errors
virtual Double_t ** Allocate(Int_t size)
Allocate internal data structures for size points.
virtual void SetLineWidth(Int_t e, Width_t lwidth)
Set Line Width of error e (-1 = Global and x errors).
std::vector< TArrayD > fEyH
Two dimensional array of Y high errors.
virtual Style_t GetLineStyle() const
Return the line style.
Definition: TAttLine.h:34
virtual void SetPointEX(Int_t i, Double_t exL, Double_t exH)
Set ex values for point i.
virtual void SetPointEYlow(Int_t i, Int_t ne, const Double_t *eyL)
Set eyL values for point i.
virtual Double_t * GetEXlow() const
virtual void SetLineColorAlpha(Int_t e, Color_t lcolor, Float_t lalpha)
Set Line Color and Alpha of error e (-1 = Global and x errors).
virtual void SetFillColor(Int_t e, Color_t fcolor)
Set Fill Color of error e (-1 = Global and x errors).
void CalcYErrorsSum() const
Recalculates the summed y error arrays.
virtual void SetAttLine(Int_t e, TAttLine *tal)
Set TAttLine parameters of error e by copying from another TAttLine (-1 = Global and x errors).
Double_t * fEyHSum
! Array of summed Y high errors for fitting
virtual void DeleteYError(Int_t e)
Deletes the y error with the index e.
virtual Double_t * GetEYlow() const
Get all low errors on y coordinates as an array summed according to fSumErrorsMode.
virtual Double_t GetErrorX(Int_t i) const
Get error on x coordinate for point i.
virtual void SetFillStyle(Int_t e, Style_t fstyle)
Set Fill Style of error e (-1 = Global and x errors).
virtual void SetEYhigh(Int_t e, Int_t np, const Double_t *eyH)
Set error e eyH values.
virtual Double_t GetErrorXlow(Int_t i) const
Get low error on x coordinate for point i.
virtual void SetAttFill(Int_t e, TAttFill *taf)
Set TAttFill parameters of error e by copying from another TAttFill (-1 = Global and x errors).
virtual void SetEYlow(Int_t e, Int_t np, const Double_t *eyL)
Set error e eyL values.
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save primitive as a C++ statement(s) on output stream out.
std::vector< TAttFill > fAttFill
The AttFill attributes of the different errors.
Bool_t CtorAllocate()
Should be called from ctors after fNpoints has been set Note: This function should be called only fro...
Double_t * fExH
[fNpoints] array of X high errors
virtual void SwapPoints(Int_t pos1, Int_t pos2)
Swap points.
virtual void SetPointEY(Int_t i, Int_t ne, const Double_t *eyL, const Double_t *eyH)
Set ey values for point i.
virtual void SetLineColor(Int_t e, Color_t lcolor)
Set Line Color of error e (-1 = Global and x errors).
virtual void SetPointEXlow(Int_t i, Double_t exL)
Set exL value for point i.
virtual void SetPointEYhigh(Int_t i, Int_t ne, const Double_t *eyH)
Set eyH values for point i.
Int_t fNYErrors
The amount of different y-errors.
std::vector< TArrayD > fEyL
Two dimensional array of Y low errors.
virtual void CopyAndRelease(Double_t **newarrays, Int_t ibegin, Int_t iend, Int_t obegin)
Copy and release.
virtual Double_t GetErrorYhigh(Int_t i) const
Get high error on y coordinate for point i.
A TGraph is an object made of two arrays X and Y with npoints each.
Definition: TGraph.h:41
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:2298
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 SetName(const char *name="")
Set graph name.
Definition: TGraph.cxx:2337
virtual void SetNameTitle(const char *name="", const char *title="")
Set graph name and title.
Definition: TGraph.cxx:2373
Int_t GetN() const
Definition: TGraph.h:125
virtual void SetTitle(const char *title="")
Change (i.e.
Definition: TGraph.cxx:2353
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:743
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:669
Double_t ** AllocateArrays(Int_t Narrays, Int_t arraySize)
Allocate arrays.
Definition: TGraph.cxx:553
virtual void Scale(Double_t c1=1., Option_t *option="y")
Multiply the values of a TGraph by a constant c1.
Definition: TGraph.cxx:2215
TList * fFunctions
Pointer to list of functions (fits and user)
Definition: TGraph.h:49
static void SwapValues(Double_t *arr, Int_t pos1, Int_t pos2)
Swap values.
Definition: TGraph.cxx:2553
virtual Bool_t DoMerge(const TGraph *g)
protected function to perform the merge operation of a graph
Definition: TGraph.cxx:2618
virtual void SwapPoints(Int_t pos1, Int_t pos2)
Swap points.
Definition: TGraph.cxx:2544
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:1037
Double_t * fX
[fNpoints] array of X points
Definition: TGraph.h:47
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:2233
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:1601
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:717
TGraph & operator=(const TGraph &)
Equal operator for this graph.
Definition: TGraph.cxx:192
TH1 is the base class of all histogram classes in ROOT.
Definition: TH1.h:58
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save primitive as a C++ statement(s) on output stream out.
Definition: TH1.cxx:7124
virtual Double_t GetBinCenter(Int_t bin) const
Return bin center for 1D histogram.
Definition: TH1.cxx:8984
virtual Int_t GetDimension() const
Definition: TH1.h:282
virtual Int_t GetNbinsX() const
Definition: TH1.h:296
virtual Double_t GetBinLowEdge(Int_t bin) const
Return bin lower edge for 1D histogram.
Definition: TH1.cxx:8995
virtual void SetName(const char *name)
Change the name of this histogram.
Definition: TH1.cxx:8803
virtual Double_t GetBinContent(Int_t bin) const
Return content of bin number bin.
Definition: TH1.cxx:4994
virtual TArrayD * GetSumw2()
Definition: TH1.h:312
virtual Double_t GetBinWidth(Int_t bin) const
Return bin width for 1D histogram.
Definition: TH1.cxx:9006
virtual Double_t GetSumOfWeights() const
Return the sum of weights excluding under/overflows.
Definition: TH1.cxx:7805
virtual const char * GetTitle() const
Returns title of object.
Definition: TNamed.h:48
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
Mother of all ROOT objects.
Definition: TObject.h:37
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:359
virtual void Warning(const char *method, const char *msgfmt,...) const
Issue warning message.
Definition: TObject.cxx:879
virtual void SavePrimitive(std::ostream &out, Option_t *option="")
Save a primitive as a C++ statement(s) on output stream "out".
Definition: TObject.cxx:666
virtual Bool_t InheritsFrom(const char *classname) const
Returns kTRUE if object inherits from class "classname".
Definition: TObject.cxx:445
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition: TObject.cxx:893
virtual void Info(const char *method, const char *msgfmt,...) const
Issue info message.
Definition: TObject.cxx:867
Basic string class.
Definition: TString.h:136
void ToLower()
Change string to lower-case.
Definition: TString.cxx:1150
const char * Data() const
Definition: TString.h:369
TString & ReplaceAll(const TString &s1, const TString &s2)
Definition: TString.h:692
Bool_t Contains(const char *pat, ECaseCompare cmp=kExact) const
Definition: TString.h:624
Float_t GetErrorX() const
Definition: TStyle.h:178
TVectorT.
Definition: TVectorT.h:27
Int_t GetNrows() const
Definition: TVectorT.h:75
Int_t GetLwb() const
Definition: TVectorT.h:73
double normal_quantile_c(double z, double sigma)
Inverse ( ) of the cumulative distribution function of the upper tail of the normal (Gaussian) distri...
double beta(double x, double y)
Calculates the beta function.
const Double_t sigma
return c1
Definition: legend1.C:41
Double_t y[n]
Definition: legend1.C:17
Double_t x[n]
Definition: legend1.C:17
const Int_t n
Definition: legend1.C:16
VecExpr< UnaryOp< Sqrt< T >, VecExpr< A, T, D >, T >, T, D > sqrt(const VecExpr< A, T, D > &rhs)
Int_t Nint(T x)
Round to nearest integer. Rounds half integers to the nearest even integer.
Definition: TMath.h:663
Short_t Max(Short_t a, Short_t b)
Definition: TMathBase.h:208
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:721
Double_t Sqrt(Double_t x)
Definition: TMath.h:641
Short_t Min(Short_t a, Short_t b)
Definition: TMathBase.h:176
Short_t Abs(Short_t d)
Definition: TMathBase.h:120
auto * m
Definition: textangle.C:8
auto * l
Definition: textangle.C:4
auto * a
Definition: textangle.C:12
static uint64_t sum(uint64_t i)
Definition: Factory.cxx:2345