39 ClassImp(TGraphMultiErrors)
78 TGraphMultiErrors::TGraphMultiErrors()
79 : TGraph(), fNYErrors(0), fSumErrorsMode(TGraphMultiErrors::kOnlyFirst), fExL(
nullptr), fExH(
nullptr)
86 TGraphMultiErrors::TGraphMultiErrors(
const Char_t *name,
const Char_t *title) : TGraphMultiErrors()
88 SetNameTitle(name, title);
96 TGraphMultiErrors::TGraphMultiErrors(Int_t np, Int_t ne)
97 : TGraph(np), fNYErrors(ne), fSumErrorsMode(TGraphMultiErrors::kOnlyFirst)
107 TGraphMultiErrors::TGraphMultiErrors(
const Char_t *name,
const Char_t *title, Int_t np, Int_t ne)
108 : TGraphMultiErrors(np, ne)
110 SetNameTitle(name, title);
119 TGraphMultiErrors::TGraphMultiErrors(Int_t np,
const Float_t *x,
const Float_t *y,
const Float_t *exL,
120 const Float_t *exH,
const Float_t *eyL,
const Float_t *eyH, Int_t m)
121 : TGraph(np, x, y), fNYErrors(1), fSumErrorsMode(m)
126 for (Int_t i = 0; i < fNpoints; i++) {
153 TGraphMultiErrors::TGraphMultiErrors(
const Char_t *name,
const Char_t *title, Int_t np,
const Float_t *x,
154 const Float_t *y,
const Float_t *exL,
const Float_t *exH,
const Float_t *eyL,
155 const Float_t *eyH, Int_t m)
156 : TGraphMultiErrors(np, x, y, exL, exH, eyL, eyH, m)
158 SetNameTitle(name, title);
167 TGraphMultiErrors::TGraphMultiErrors(Int_t np,
const Double_t *x,
const Double_t *y,
const Double_t *exL,
168 const Double_t *exH,
const Double_t *eyL,
const Double_t *eyH, Int_t m)
169 : TGraph(np, x, y), fNYErrors(1), fSumErrorsMode(m)
174 Int_t n = fNpoints *
sizeof(Double_t);
177 memcpy(fExL, exL, n);
181 memcpy(fExH, exH, n);
186 fEyL[0].Set(fNpoints, eyL);
191 fEyH[0].Set(fNpoints, eyH);
203 TGraphMultiErrors::TGraphMultiErrors(
const Char_t *name,
const Char_t *title, Int_t np,
const Double_t *x,
204 const Double_t *y,
const Double_t *exL,
const Double_t *exH,
const Double_t *eyL,
205 const Double_t *eyH, Int_t m)
206 : TGraphMultiErrors(np, x, y, exL, exH, eyL, eyH, m)
208 SetNameTitle(name, title);
217 TGraphMultiErrors::TGraphMultiErrors(Int_t np, Int_t ne,
const Float_t *x,
const Float_t *y,
const Float_t *exL,
218 const Float_t *exH, std::vector<std::vector<Float_t>> eyL,
219 std::vector<std::vector<Float_t>> eyH, Int_t m)
220 : TGraph(np, x, y), fNYErrors(ne), fSumErrorsMode(m)
225 for (Int_t i = 0; i < fNpoints; i++) {
235 for (Int_t j = 0; j < fNYErrors; j++) {
236 if (Int_t(eyL.size()) > j && Int_t(eyL[j].size()) > i)
237 fEyL[j][i] = eyL[j][i];
240 if (Int_t(eyH.size()) > j && Int_t(eyH[j].size()) > i)
241 fEyH[j][i] = eyH[j][i];
256 TGraphMultiErrors::TGraphMultiErrors(
const Char_t *name,
const Char_t *title, Int_t np, Int_t ne,
const Float_t *x,
257 const Float_t *y,
const Float_t *exL,
const Float_t *exH,
258 std::vector<std::vector<Float_t>> eyL, std::vector<std::vector<Float_t>> eyH,
260 : TGraphMultiErrors(np, ne, x, y, exL, exH, eyL, eyH, m)
262 SetNameTitle(name, title);
271 TGraphMultiErrors::TGraphMultiErrors(Int_t np, Int_t ne,
const Double_t *x,
const Double_t *y,
const Double_t *exL,
272 const Double_t *exH, std::vector<std::vector<Double_t>> eyL,
273 std::vector<std::vector<Double_t>> eyH, Int_t m)
274 : TGraph(np, x, y), fNYErrors(ne), fSumErrorsMode(m)
279 Int_t n = fNpoints *
sizeof(Double_t);
282 memcpy(fExL, exL, n);
286 memcpy(fExH, exH, n);
290 for (Int_t i = 0; i < fNpoints; i++) {
291 for (Int_t j = 0; j < fNYErrors; j++) {
292 if (Int_t(eyL.size()) > j && Int_t(eyL[j].size()) > i)
293 fEyL[j][i] = eyL[j][i];
296 if (Int_t(eyH.size()) > j && Int_t(eyH[j].size()) > i)
297 fEyH[j][i] = eyH[j][i];
312 TGraphMultiErrors::TGraphMultiErrors(
const Char_t *name,
const Char_t *title, Int_t np, Int_t ne,
const Double_t *x,
313 const Double_t *y,
const Double_t *exL,
const Double_t *exH,
314 std::vector<std::vector<Double_t>> eyL, std::vector<std::vector<Double_t>> eyH,
316 : TGraphMultiErrors(np, ne, x, y, exL, exH, eyL, eyH, m)
318 SetNameTitle(name, title);
327 TGraphMultiErrors::TGraphMultiErrors(Int_t np, Int_t ne,
const Float_t *x,
const Float_t *y,
const Float_t *exL,
328 const Float_t *exH, std::vector<TArrayF> eyL, std::vector<TArrayF> eyH, Int_t m)
329 : TGraph(np, x, y), fNYErrors(ne), fSumErrorsMode(m)
334 for (Int_t i = 0; i < fNpoints; i++) {
344 for (Int_t j = 0; j < fNYErrors; j++) {
345 if (Int_t(eyL.size()) > j && eyL[j].GetSize() > i)
346 fEyL[j][i] = eyL[j][i];
349 if (Int_t(eyH.size()) > j && eyH[j].GetSize() > i)
350 fEyH[j][i] = eyH[j][i];
365 TGraphMultiErrors::TGraphMultiErrors(
const Char_t *name,
const Char_t *title, Int_t np, Int_t ne,
const Float_t *x,
366 const Float_t *y,
const Float_t *exL,
const Float_t *exH, std::vector<TArrayF> eyL,
367 std::vector<TArrayF> eyH, Int_t m)
368 : TGraphMultiErrors(np, ne, x, y, exL, exH, eyL, eyH, m)
370 SetNameTitle(name, title);
379 TGraphMultiErrors::TGraphMultiErrors(Int_t np, Int_t ne,
const Double_t *x,
const Double_t *y,
const Double_t *exL,
380 const Double_t *exH, std::vector<TArrayD> eyL, std::vector<TArrayD> eyH, Int_t m)
381 : TGraph(np, x, y), fNYErrors(ne), fSumErrorsMode(m)
386 Int_t n = fNpoints *
sizeof(Double_t);
389 memcpy(fExL, exL, n);
393 memcpy(fExH, exH, n);
397 for (Int_t i = 0; i < fNpoints; i++) {
398 for (Int_t j = 0; j < fNYErrors; j++) {
399 if (Int_t(eyL.size()) > j && eyL[j].GetSize() > i)
400 fEyL[j][i] = eyL[j][i];
403 if (Int_t(eyH.size()) > j && eyH[j].GetSize() > i)
404 fEyH[j][i] = eyH[j][i];
419 TGraphMultiErrors::TGraphMultiErrors(
const Char_t *name,
const Char_t *title, Int_t np, Int_t ne,
const Double_t *x,
420 const Double_t *y,
const Double_t *exL,
const Double_t *exH,
421 std::vector<TArrayD> eyL, std::vector<TArrayD> eyH, Int_t m)
422 : TGraphMultiErrors(np, ne, x, y, exL, exH, eyL, eyH, m)
424 SetNameTitle(name, title);
435 TGraphMultiErrors::TGraphMultiErrors(
const TVectorF &tvX,
const TVectorF &tvY,
const TVectorF &tvExL,
436 const TVectorF &tvExH,
const TVectorF &tvEyL,
const TVectorF &tvEyH, Int_t m)
437 : TGraph(), fNYErrors(1), fSumErrorsMode(m)
439 fNpoints = TMath::Min(tvX.GetNrows(), tvY.GetNrows());
441 if (!TGraph::CtorAllocate())
447 Int_t itvXL = tvX.GetLwb();
448 Int_t itvYL = tvY.GetLwb();
449 Int_t itvExLL = tvExL.GetLwb();
450 Int_t itvExHL = tvExH.GetLwb();
451 Int_t itvEyLL = tvEyL.GetLwb();
452 Int_t itvEyHL = tvEyH.GetLwb();
454 for (Int_t i = 0; i < fNpoints; i++) {
455 fX[i] = tvX(itvXL + i);
456 fY[i] = tvY(itvYL + i);
457 fExL[i] = tvExL(itvExLL + i);
458 fExH[i] = tvExH(itvExHL + i);
459 fEyL[0][i] = tvEyL(itvEyLL + i);
460 fEyH[0][i] = tvEyH(itvEyHL + i);
474 TGraphMultiErrors::TGraphMultiErrors(
const TVectorD &tvX,
const TVectorD &tvY,
const TVectorD &tvExL,
475 const TVectorD &tvExH,
const TVectorD &tvEyL,
const TVectorD &tvEyH, Int_t m)
476 : TGraph(), fNYErrors(1), fSumErrorsMode(m)
478 fNpoints = TMath::Min(tvX.GetNrows(), tvY.GetNrows());
480 if (!TGraph::CtorAllocate())
486 Int_t itvXL = tvX.GetLwb();
487 Int_t itvYL = tvY.GetLwb();
488 Int_t itvExLL = tvExL.GetLwb();
489 Int_t itvExHL = tvExH.GetLwb();
490 Int_t itvEyLL = tvEyL.GetLwb();
491 Int_t itvEyHL = tvEyH.GetLwb();
493 for (Int_t i = 0; i < fNpoints; i++) {
494 fX[i] = tvX(i + itvXL);
495 fY[i] = tvY(i + itvYL);
496 fExL[i] = tvExL(i + itvExLL);
497 fExH[i] = tvExH(i + itvExHL);
498 fEyL[0][i] = tvEyL(i + itvEyLL);
499 fEyH[0][i] = tvEyH(i + itvEyHL);
512 TGraphMultiErrors::TGraphMultiErrors(Int_t ne,
const TVectorF &tvX,
const TVectorF &tvY,
const TVectorF &tvExL,
513 const TVectorF &tvExH,
const TVectorF *tvEyL,
const TVectorF *tvEyH, Int_t m)
514 : TGraph(), fNYErrors(ne), fSumErrorsMode(m)
516 fNpoints = TMath::Min(tvX.GetNrows(), tvY.GetNrows());
518 if (!TGraph::CtorAllocate())
524 Int_t itvXL = tvX.GetLwb();
525 Int_t itvYL = tvY.GetLwb();
526 Int_t itvExLL = tvExL.GetLwb();
527 Int_t itvExHL = tvExH.GetLwb();
529 for (Int_t i = 0; i < fNpoints; i++) {
530 fX[i] = tvX(i + itvXL);
531 fY[i] = tvY(i + itvYL);
532 fExL[i] = tvExL(i + itvExLL);
533 fExH[i] = tvExH(i + itvExHL);
535 for (Int_t j = 0; j < ne; j++) {
536 fEyL[j][i] = tvEyL[j](i + tvEyL[j].GetLwb());
537 fEyH[j][i] = tvEyH[j](i + tvEyH[j].GetLwb());
551 TGraphMultiErrors::TGraphMultiErrors(Int_t ne,
const TVectorD &tvX,
const TVectorD &tvY,
const TVectorD &tvExL,
552 const TVectorD &tvExH,
const TVectorD *tvEyL,
const TVectorD *tvEyH, Int_t m)
553 : TGraph(), fNYErrors(ne), fSumErrorsMode(m)
555 fNpoints = TMath::Min(tvX.GetNrows(), tvY.GetNrows());
557 if (!TGraph::CtorAllocate())
563 Int_t itvXL = tvX.GetLwb();
564 Int_t itvYL = tvY.GetLwb();
565 Int_t itvExLL = tvExL.GetLwb();
566 Int_t itvExHL = tvExH.GetLwb();
568 for (Int_t i = 0; i < fNpoints; i++) {
569 fX[i] = tvX(i + itvXL);
570 fY[i] = tvY(i + itvYL);
571 fExL[i] = tvExL(i + itvExLL);
572 fExH[i] = tvExH(i + itvExHL);
574 for (Int_t j = 0; j < ne; j++) {
575 fEyL[j][i] = tvEyL[j](i + tvEyL[j].GetLwb());
576 fEyH[j][i] = tvEyH[j](i + tvEyH[j].GetLwb());
586 TGraphMultiErrors::TGraphMultiErrors(
const TGraphMultiErrors &tgme) : TGraph(tgme)
588 fNYErrors = tgme.fNYErrors;
589 fSumErrorsMode = tgme.fSumErrorsMode;
594 Int_t n = fNpoints *
sizeof(Double_t);
595 memcpy(fExL, tgme.fExL, n);
596 memcpy(fExH, tgme.fExH, n);
598 for (Int_t j = 0; j < fNYErrors; j++) {
599 fEyL[j] = tgme.fEyL[j];
600 fEyH[j] = tgme.fEyH[j];
601 tgme.fAttFill[j].Copy(fAttFill[j]);
602 tgme.fAttLine[j].Copy(fAttLine[j]);
611 TGraphMultiErrors &TGraphMultiErrors::operator=(
const TGraphMultiErrors &tgme)
614 TGraph::operator=(tgme);
625 fNYErrors = tgme.fNYErrors;
626 fSumErrorsMode = tgme.fSumErrorsMode;
631 Int_t n = fNpoints *
sizeof(Double_t);
632 memcpy(fExL, tgme.fExL, n);
633 memcpy(fExH, tgme.fExH, n);
634 memcpy(fEyLSum, tgme.fEyLSum, n);
635 memcpy(fEyHSum, tgme.fEyHSum, n);
637 for (Int_t j = 0; j < fNYErrors; j++) {
638 fEyL[j] = tgme.fEyL[j];
639 fEyH[j] = tgme.fEyH[j];
640 tgme.fAttFill[j].Copy(fAttFill[j]);
641 tgme.fAttLine[j].Copy(fAttLine[j]);
651 TGraphMultiErrors::TGraphMultiErrors(
const TH1 *h, Int_t ne)
652 : TGraph(h), fNYErrors(ne), fSumErrorsMode(TGraphMultiErrors::kOnlyFirst)
657 for (Int_t i = 0; i < fNpoints; i++) {
658 fExL[i] = h->GetBinWidth(i + 1) * gStyle->GetErrorX();
659 fExH[i] = h->GetBinWidth(i + 1) * gStyle->GetErrorX();
660 fEyL[0][i] = h->GetBinError(i + 1);
661 fEyH[0][i] = h->GetBinError(i + 1);
663 for (Int_t j = 1; j < fNYErrors; j++) {
671 TAttFill::Copy(fAttFill[0]);
672 TAttLine::Copy(fAttLine[0]);
679 TGraphMultiErrors::TGraphMultiErrors(
const TH1 *pass,
const TH1 *total, Int_t ne, Option_t *option)
680 : TGraph(pass ? pass->GetNbinsX() : 0), fNYErrors(ne), fSumErrorsMode(TGraphMultiErrors::kOnlyFirst)
682 if (!pass || !total) {
683 Error(
"TGraphMultiErrors",
"Invalid histogram pointers");
690 std::string sname =
"divide_" + std::string(pass->GetName()) +
"_by_" + std::string(total->GetName());
691 SetName(sname.c_str());
692 SetTitle(pass->GetTitle());
695 pass->TAttLine::Copy(*
this);
696 pass->TAttFill::Copy(*
this);
697 pass->TAttMarker::Copy(*
this);
699 Divide(pass, total, option);
702 TAttFill::Copy(fAttFill[0]);
703 TAttLine::Copy(fAttLine[0]);
709 TGraphMultiErrors::~TGraphMultiErrors()
730 Bool_t TGraphMultiErrors::CtorAllocate()
732 if (!fNpoints || !fNYErrors) {
733 fExL = fExH =
nullptr;
739 fExL =
new Double_t[fMaxSize];
740 fExH =
new Double_t[fMaxSize];
741 fEyL.resize(fNYErrors, TArrayD(fMaxSize));
742 fEyH.resize(fNYErrors, TArrayD(fMaxSize));
743 fEyLSum =
new Double_t[fMaxSize];
744 fEyHSum =
new Double_t[fMaxSize];
745 fAttFill.resize(fNYErrors);
746 fAttLine.resize(fNYErrors);
748 Int_t n = fMaxSize *
sizeof(Double_t);
751 memset(fEyLSum, 0, n);
752 memset(fEyHSum, 0, n);
760 void TGraphMultiErrors::CopyAndRelease(Double_t **newarrays, Int_t ibegin, Int_t iend, Int_t obegin)
762 CopyPoints(newarrays, ibegin, iend, obegin);
776 fEyLSum = newarrays[4];
779 fEyHSum = newarrays[5];
789 Bool_t TGraphMultiErrors::CopyPoints(Double_t **arrays, Int_t ibegin, Int_t iend, Int_t obegin)
791 if (TGraph::CopyPoints(arrays, ibegin, iend, obegin)) {
792 Int_t n = (iend - ibegin) *
sizeof(Double_t);
795 memmove(&arrays[2][obegin], &fExL[ibegin], n);
796 memmove(&arrays[3][obegin], &fExH[ibegin], n);
797 memmove(&arrays[4][obegin], &fEyLSum[ibegin], n);
798 memmove(&arrays[5][obegin], &fEyHSum[ibegin], n);
800 memmove(&fExL[obegin], &fExL[ibegin], n);
801 memmove(&fExH[obegin], &fExH[ibegin], n);
802 memmove(&fEyLSum[obegin], &fEyLSum[ibegin], n);
803 memmove(&fEyHSum[obegin], &fEyHSum[ibegin], n);
814 void TGraphMultiErrors::FillZero(Int_t begin, Int_t end, Bool_t from_ctor)
817 TGraph::FillZero(begin, end, from_ctor);
819 Int_t n = (end - begin) *
sizeof(Double_t);
820 memset(fExL + begin, 0, n);
821 memset(fExH + begin, 0, n);
822 memset(fEyLSum + begin, 0, n);
823 memset(fEyHSum + begin, 0, n);
825 for (Int_t j = 0; j < fNYErrors; j++) {
826 memset(fEyL[j].GetArray() + begin, 0, n);
827 memset(fEyH[j].GetArray() + begin, 0, n);
834 void TGraphMultiErrors::CalcYErrorsSum()
const
837 fEyLSum =
new Double_t[fNpoints];
839 fEyHSum =
new Double_t[fNpoints];
841 for (Int_t i = 0; i < fNpoints; i++) {
842 fEyLSum[i] = GetErrorYlow(i);
843 fEyHSum[i] = GetErrorYhigh(i);
850 Bool_t TGraphMultiErrors::DoMerge(
const TGraph *tg)
855 if (tg->IsA() == TGraphMultiErrors::Class()) {
856 auto tgme = (TGraphMultiErrors *)tg;
858 for (Int_t i = 0; i < tgme->GetN(); i++) {
859 Int_t ipoint = GetN();
861 tgme->GetPoint(i, x, y);
862 SetPoint(ipoint, x, y);
863 SetPointEX(ipoint, tgme->GetErrorXlow(i), tgme->GetErrorXhigh(i));
864 for (Int_t j = 0; j < tgme->GetNYErrors(); j++)
865 SetPointEY(ipoint, j, tgme->GetErrorYlow(i, j), tgme->GetErrorYhigh(i, j));
870 Warning(
"DoMerge",
"Merging a %s is not compatible with a TGraphMultiErrors - Errors will be ignored",
871 tg->IsA()->GetName());
872 return TGraph::DoMerge(tg);
881 void TGraphMultiErrors::SwapPoints(Int_t pos1, Int_t pos2)
883 SwapValues(fExL, pos1, pos2);
884 SwapValues(fExH, pos1, pos2);
886 for (Int_t j = 0; j <= fNYErrors; j++) {
887 SwapValues(fEyL[j].GetArray(), pos1, pos2);
888 SwapValues(fEyH[j].GetArray(), pos1, pos2);
891 TGraph::SwapPoints(pos1, pos2);
897 void TGraphMultiErrors::AddYError(Int_t np,
const Double_t *eyL,
const Double_t *eyH)
899 fEyL.emplace_back(np, eyL);
900 fEyH.emplace_back(np, eyH);
901 fEyL.back().Set(fNpoints);
902 fEyH.back().Set(fNpoints);
903 fAttFill.emplace_back();
904 fAttLine.emplace_back();
913 Double_t **TGraphMultiErrors::Allocate(Int_t size)
915 return AllocateArrays(6, size);
929 void TGraphMultiErrors::Apply(TF1 *f)
931 Double_t x, y, eyL, eyH, eyLNew, eyHNew, fxy;
935 fHistogram =
nullptr;
938 for (Int_t i = 0; i < fNpoints; i++) {
940 eyL = GetErrorYlow(i, 0);
941 eyH = GetErrorYhigh(i, 0);
946 if (f->Eval(x, y - eyL) < f->Eval(x, y + eyH)) {
947 eyLNew = TMath::Abs(fxy - f->Eval(x, y - eyL));
948 eyHNew = TMath::Abs(f->Eval(x, y + eyH) - fxy);
950 eyHNew = TMath::Abs(fxy - f->Eval(x, y - eyL));
951 eyLNew = TMath::Abs(f->Eval(x, y + eyH) - fxy);
955 SetPointEY(i, 0, eyLNew, eyHNew);
968 void TGraphMultiErrors::BayesDivide(
const TH1 *pass,
const TH1 *total, Option_t *)
970 Divide(pass, total,
"cl=0.683 b(1,1) mode");
979 void TGraphMultiErrors::Divide(
const TH1 *pass,
const TH1 *total, Option_t *opt)
982 if (!pass || !total) {
983 Error(
"Divide",
"one of the passed pointers is zero");
988 if ((pass->GetDimension() > 1) || (total->GetDimension() > 1)) {
989 Error(
"Divide",
"passed histograms are not one-dimensional");
995 Bool_t bEffective =
false;
1000 if (pass->GetSumw2()->fN > 0) {
1001 for (
int i = 0; i < pass->GetNbinsX(); ++i) {
1002 psumw += pass->GetBinContent(i);
1003 psumw2 += pass->GetSumw2()->At(i);
1006 psumw = pass->GetSumOfWeights();
1009 if (TMath::Abs(psumw - psumw2) > 1e-6)
1013 Double_t tsumw2 = 0;
1014 if (total->GetSumw2()->fN > 0) {
1015 for (
int i = 0; i < total->GetNbinsX(); ++i) {
1016 tsumw += total->GetBinContent(i);
1017 tsumw2 += total->GetSumw2()->At(i);
1020 tsumw = total->GetSumOfWeights();
1023 if (TMath::Abs(tsumw - tsumw2) > 1e-6)
1033 TString option = opt;
1036 Bool_t bVerbose =
false;
1040 Double_t (*pBound)(Double_t, Double_t, Double_t, Bool_t) = &TEfficiency::ClopperPearson;
1042 Double_t conf = 0.682689492137;
1044 Bool_t bIsBayesian =
false;
1049 if (option.Contains(
"v")) {
1050 option.ReplaceAll(
"v",
"");
1053 Info(
"Divide",
"weight will be considered in the Histogram Ratio");
1057 if (option.Contains(
"cl=")) {
1058 Double_t level = -1;
1060 sscanf(strstr(option.Data(),
"cl="),
"cl=%lf", &level);
1061 if ((level > 0) && (level < 1))
1064 Warning(
"Divide",
"given confidence level %.3lf is invalid", level);
1065 option.ReplaceAll(
"cl=",
"");
1069 if (option.Contains(
"n")) {
1070 option.ReplaceAll(
"n",
"");
1071 pBound = &TEfficiency::Normal;
1075 if (option.Contains(
"cp")) {
1076 option.ReplaceAll(
"cp",
"");
1077 pBound = &TEfficiency::ClopperPearson;
1081 if (option.Contains(
"w")) {
1082 option.ReplaceAll(
"w",
"");
1083 pBound = &TEfficiency::Wilson;
1087 if (option.Contains(
"ac")) {
1088 option.ReplaceAll(
"ac",
"");
1089 pBound = &TEfficiency::AgrestiCoull;
1092 if (option.Contains(
"fc")) {
1093 option.ReplaceAll(
"fc",
"");
1094 pBound = &TEfficiency::FeldmanCousins;
1097 if (option.Contains(
"midp")) {
1098 option.ReplaceAll(
"midp",
"");
1103 if (option.Contains(
"b(")) {
1106 sscanf(strstr(option.Data(),
"b("),
"b(%lf,%lf)", &a, &b);
1110 Warning(
"Divide",
"given shape parameter for alpha %.2lf is invalid", a);
1114 Warning(
"Divide",
"given shape parameter for beta %.2lf is invalid", b);
1115 option.ReplaceAll(
"b(",
"");
1120 Bool_t usePosteriorMode =
false;
1121 if (bIsBayesian && option.Contains(
"mode")) {
1122 usePosteriorMode =
true;
1123 option.ReplaceAll(
"mode",
"");
1126 Bool_t plot0Bins =
false;
1127 if (option.Contains(
"e0")) {
1129 option.ReplaceAll(
"e0",
"");
1132 Bool_t useShortestInterval =
false;
1133 if (bIsBayesian && (option.Contains(
"sh") || (usePosteriorMode && !option.Contains(
"cen")))) {
1134 useShortestInterval =
true;
1138 Bool_t bPoissonRatio =
false;
1139 if (option.Contains(
"pois")) {
1140 bPoissonRatio =
true;
1141 option.ReplaceAll(
"pois",
"");
1146 if ((bEffective && !bPoissonRatio) && !bIsBayesian && pBound != &TEfficiency::Normal) {
1147 Warning(
"Divide",
"Histograms have weights: only Normal or Bayesian error calculation is supported");
1148 Info(
"Divide",
"Using now the Normal approximation for weighted histograms");
1151 if (bPoissonRatio) {
1152 if (pass->GetDimension() != total->GetDimension()) {
1153 Error(
"Divide",
"passed histograms are not of the same dimension");
1157 if (!TEfficiency::CheckBinning(*pass, *total)) {
1158 Error(
"Divide",
"passed histograms are not consistent");
1163 if (!TEfficiency::CheckConsistency(*pass, *total,
"w")) {
1164 Error(
"Divide",
"passed histograms are not consistent");
1171 Int_t nbins = pass->GetNbinsX();
1181 Double_t t = 0, p = 0;
1182 Double_t tw = 0, tw2 = 0, pw = 0, pw2 = 0, wratio = 1;
1184 for (Int_t b = 1; b <= nbins; ++b) {
1186 Double_t eff = 0., low = 0., upper = 0.;
1190 tw = total->GetBinContent(b);
1191 tw2 = (total->GetSumw2()->fN > 0) ? total->GetSumw2()->At(b) : tw;
1192 pw = pass->GetBinContent(b);
1193 pw2 = (pass->GetSumw2()->fN > 0) ? pass->GetSumw2()->At(b) : pw;
1195 if (bPoissonRatio) {
1201 if (pw == 0 && pw2 == 0)
1204 p = (pw * pw) / pw2;
1206 if (tw == 0 && tw2 == 0)
1209 t = (tw * tw) / tw2;
1211 if (pw > 0 && tw > 0)
1213 wratio = (pw * t) / (p * tw);
1214 else if (pw == 0 && tw > 0)
1217 wratio = (psumw2 * t) / (psumw * tw);
1218 else if (tw == 0 && pw > 0)
1221 wratio = (pw * tsumw) / (p * tsumw2);
1232 }
else if (tw <= 0 && !plot0Bins)
1242 t = TMath::Nint(total->GetBinContent(b));
1243 p = TMath::Nint(pass->GetBinContent(b));
1248 if (t == 0. && !plot0Bins)
1254 if ((bEffective && !bPoissonRatio) && tw2 <= 0) {
1262 if (bEffective && !bPoissonRatio) {
1264 double norm = tw / tw2;
1265 aa = pw * norm + alpha;
1266 bb = (tw - pw) * norm + beta;
1268 aa = double(p) + alpha;
1269 bb = double(t - p) + beta;
1271 if (usePosteriorMode)
1272 eff = TEfficiency::BetaMode(aa, bb);
1274 eff = TEfficiency::BetaMean(aa, bb);
1276 if (useShortestInterval) {
1277 TEfficiency::BetaShortestInterval(conf, aa, bb, low, upper);
1279 low = TEfficiency::BetaCentralInterval(conf, aa, bb,
false);
1280 upper = TEfficiency::BetaCentralInterval(conf, aa, bb,
true);
1286 if (bEffective && !bPoissonRatio) {
1295 double variance = (pw2 * (1. - 2 * eff) + tw2 * eff * eff) / (tw * tw);
1296 double sigma = sqrt(variance);
1298 double prob = 0.5 * (1. - conf);
1299 double delta = ROOT::Math::normal_quantile_c(prob, sigma);
1301 upper = eff + delta;
1310 eff = ((Double_t)p) / t;
1312 low = pBound(t, p, conf,
false);
1313 upper = pBound(t, p, conf,
true);
1317 if (bPoissonRatio) {
1318 Double_t ratio = eff / (1 - eff);
1320 low = low / (1. - low);
1321 upper = upper / (1. - upper);
1331 if (TMath::Finite(eff)) {
1332 SetPoint(npoint, pass->GetBinCenter(b), eff);
1333 SetPointEX(npoint, pass->GetBinCenter(b) - pass->GetBinLowEdge(b),
1334 pass->GetBinLowEdge(b) - pass->GetBinCenter(b) + pass->GetBinWidth(b));
1335 SetPointEY(npoint, 0, eff - low, upper - eff);
1342 Warning(
"Divide",
"Number of graph points is different than histogram bins - %d points have been skipped",
1346 Info(
"Divide",
"made a graph with %d points from %d bins", npoint, nbins);
1347 Info(
"Divide",
"used confidence level: %.2lf\n", conf);
1349 Info(
"Divide",
"used prior probability ~ beta(%.2lf,%.2lf)", alpha, beta);
1357 void TGraphMultiErrors::ComputeRange(Double_t &xmin, Double_t &ymin, Double_t &xmax, Double_t &ymax)
const
1359 TGraph::ComputeRange(xmin, ymin, xmax, ymax);
1361 for (Int_t i = 0; i < fNpoints; i++) {
1362 if (fX[i] - fExL[i] < xmin) {
1363 if (gPad && gPad->GetLogx()) {
1364 if (fExL[i] < fX[i])
1365 xmin = fX[i] - fExL[i];
1367 xmin = TMath::Min(xmin, fX[i] / 3.);
1369 xmin = fX[i] - fExL[i];
1372 if (fX[i] + fExH[i] > xmax)
1373 xmax = fX[i] + fExH[i];
1375 Double_t eyLMax = 0., eyHMax = 0.;
1376 for (Int_t j = 0; j < fNYErrors; j++) {
1377 eyLMax = TMath::Max(eyLMax, fEyL[j][i]);
1378 eyHMax = TMath::Max(eyHMax, fEyH[j][i]);
1381 if (fY[i] - eyLMax < ymin) {
1382 if (gPad && gPad->GetLogy()) {
1384 ymin = fY[i] - eyLMax;
1386 ymin = TMath::Min(ymin, fY[i] / 3.);
1388 ymin = fY[i] - eyLMax;
1391 if (fY[i] + eyHMax > ymax)
1392 ymax = fY[i] + eyHMax;
1400 void TGraphMultiErrors::DeleteYError(Int_t e)
1402 if (fNYErrors == 1 || e >= fNYErrors)
1405 fEyL.erase(fEyL.begin() + e);
1406 fEyH.erase(fEyH.begin() + e);
1407 fAttFill.erase(fAttFill.begin() + e);
1408 fAttLine.erase(fAttLine.begin() + e);
1417 Double_t TGraphMultiErrors::GetErrorX(Int_t i)
const
1419 if (i < 0 || i >= fNpoints || (!fExL && !fExH))
1422 Double_t exL = fExL ? fExL[i] : 0.;
1423 Double_t exH = fExH ? fExH[i] : 0.;
1424 return TMath::Sqrt((exL * exL + exH * exH) / 2.);
1432 Double_t TGraphMultiErrors::GetErrorY(Int_t i)
const
1434 if (i < 0 || i >= fNpoints || (fEyL.empty() && fEyH.empty()))
1437 Double_t eyL = GetErrorYlow(i);
1438 Double_t eyH = GetErrorYhigh(i);
1439 return TMath::Sqrt((eyL * eyL + eyH * eyH) / 2.);
1446 Double_t TGraphMultiErrors::GetErrorY(Int_t i, Int_t e)
const
1448 if (i < 0 || i >= fNpoints || e >= fNYErrors || (fEyL.empty() && fEyH.empty()))
1451 Double_t eyL = fEyL.empty() ? 0. : fEyL[e][i];
1452 Double_t eyH = fEyH.empty() ? 0. : fEyH[e][i];
1453 return TMath::Sqrt((eyL * eyL + eyH * eyH) / 2.);
1459 Double_t TGraphMultiErrors::GetErrorXlow(Int_t i)
const
1461 if (i < 0 || i >= fNpoints || !fExL)
1470 Double_t TGraphMultiErrors::GetErrorXhigh(Int_t i)
const
1472 if (i < 0 || i >= fNpoints || !fExH)
1482 Double_t TGraphMultiErrors::GetErrorYlow(Int_t i)
const
1484 if (i < 0 || i >= fNpoints || fEyL.empty())
1487 if (fSumErrorsMode == TGraphMultiErrors::kOnlyFirst)
1489 else if (fSumErrorsMode == TGraphMultiErrors::kSquareSum) {
1491 for (Int_t j = 0; j < fNYErrors; j++)
1492 sum += fEyL[j][i] * fEyL[j][i];
1493 return TMath::Sqrt(sum);
1494 }
else if (fSumErrorsMode == TGraphMultiErrors::kAbsSum) {
1496 for (Int_t j = 0; j < fNYErrors; j++)
1508 Double_t TGraphMultiErrors::GetErrorYhigh(Int_t i)
const
1510 if (i < 0 || i >= fNpoints || fEyH.empty())
1513 if (fSumErrorsMode == TGraphMultiErrors::kOnlyFirst)
1515 else if (fSumErrorsMode == TGraphMultiErrors::kSquareSum) {
1517 for (Int_t j = 0; j < fNYErrors; j++)
1518 sum += fEyH[j][i] * fEyH[j][i];
1519 return TMath::Sqrt(sum);
1520 }
else if (fSumErrorsMode == TGraphMultiErrors::kAbsSum) {
1522 for (Int_t j = 0; j < fNYErrors; j++)
1533 Double_t TGraphMultiErrors::GetErrorYlow(Int_t i, Int_t e)
const
1535 if (i < 0 || i >= fNpoints || e >= fNYErrors || fEyL.empty())
1544 Double_t TGraphMultiErrors::GetErrorYhigh(Int_t i, Int_t e)
const
1546 if (i < 0 || i >= fNpoints || e >= fNYErrors || fEyH.empty())
1555 Double_t *TGraphMultiErrors::GetEYlow()
const
1566 Double_t *TGraphMultiErrors::GetEYhigh()
const
1577 Double_t *TGraphMultiErrors::GetEYlow(Int_t e)
1579 if (e >= fNYErrors || fEyL.empty())
1582 return fEyL[e].GetArray();
1588 Double_t *TGraphMultiErrors::GetEYhigh(Int_t e)
1590 if (e >= fNYErrors || fEyH.empty())
1593 return fEyH[e].GetArray();
1599 TAttFill *TGraphMultiErrors::GetAttFill(Int_t e)
1601 if (e >= 0 && e < fNYErrors)
1602 return &fAttFill.at(e);
1610 TAttLine *TGraphMultiErrors::GetAttLine(Int_t e)
1612 if (e >= 0 && e < fNYErrors)
1613 return &fAttLine.at(e);
1621 Color_t TGraphMultiErrors::GetFillColor(Int_t e)
const
1624 return GetFillColor();
1625 else if (e >= 0 && e < fNYErrors)
1626 return fAttFill[e].GetFillColor();
1634 Style_t TGraphMultiErrors::GetFillStyle(Int_t e)
const
1637 return GetFillStyle();
1638 else if (e >= 0 && e < fNYErrors)
1639 return fAttFill[e].GetFillStyle();
1647 Color_t TGraphMultiErrors::GetLineColor(Int_t e)
const
1650 return GetLineColor();
1651 else if (e >= 0 && e < fNYErrors)
1652 return fAttLine[e].GetLineColor();
1660 Style_t TGraphMultiErrors::GetLineStyle(Int_t e)
const
1663 return GetLineStyle();
1664 else if (e >= 0 && e < fNYErrors)
1665 return fAttLine[e].GetLineStyle();
1673 Width_t TGraphMultiErrors::GetLineWidth(Int_t e)
const
1676 return GetLineWidth();
1677 else if (e >= 0 && e < fNYErrors)
1678 return fAttLine[e].GetLineWidth();
1686 void TGraphMultiErrors::Print(Option_t *)
const
1688 for (Int_t i = 0; i < fNpoints; i++) {
1689 printf(
"x[%d]=%g, y[%d]=%g", i, fX[i], i, fY[i]);
1691 printf(
", exl[%d]=%g", i, fExL[i]);
1693 printf(
", exh[%d]=%g", i, fExH[i]);
1695 for (Int_t j = 0; j < fNYErrors; j++)
1696 printf(
", eyl[%d][%d]=%g", j, i, fEyL[j][i]);
1698 for (Int_t j = 0; j < fNYErrors; j++)
1699 printf(
", eyh[%d][%d]=%g", j, i, fEyH[j][i]);
1707 void TGraphMultiErrors::SavePrimitive(std::ostream &out, Option_t *option)
1710 out <<
" " << std::endl;
1712 if (gROOT->ClassSaved(TGraphMultiErrors::Class()))
1715 out <<
" TGraphMultiErrors* ";
1717 out <<
"tgme = new TGraphMultiErrors(" << fNpoints <<
", " << fNYErrors <<
");" << std::endl;
1718 out <<
" tgme->SetName(" << quote << GetName() << quote <<
");" << std::endl;
1719 out <<
" tgme->SetTitle(" << quote << GetTitle() << quote <<
");" << std::endl;
1721 SaveFillAttributes(out,
"tgme", 0, 1001);
1722 SaveLineAttributes(out,
"tgme", 1, 1, 1);
1723 SaveMarkerAttributes(out,
"tgme", 1, 1, 1);
1725 for (Int_t j = 0; j < fNYErrors; j++) {
1726 fAttFill[j].SaveFillAttributes(out, Form(
"tgme->GetAttFill(%d)", j), 0, 1001);
1727 fAttLine[j].SaveLineAttributes(out, Form(
"tgme->GetAttLine(%d)", j), 1, 1, 1);
1730 for (Int_t i = 0; i < fNpoints; i++) {
1731 out <<
" tgme->SetPoint(" << i <<
", " << fX[i] <<
", " << fY[i] <<
");" << std::endl;
1732 out <<
" tgme->SetPointEX(" << i <<
", " << fExL[i] <<
", " << fExH[i] <<
");" << std::endl;
1734 for (Int_t j = 0; j < fNYErrors; j++)
1735 out <<
" tgme->SetPointEY(" << i <<
", " << j <<
", " << fEyL[j][i] <<
", " << fEyH[j][i] <<
");"
1739 static Int_t frameNumber = 0;
1742 TString hname = fHistogram->GetName();
1743 hname += frameNumber;
1744 fHistogram->SetName(Form(
"Graph_%s", hname.Data()));
1745 fHistogram->SavePrimitive(out,
"nodraw");
1746 out <<
" tgme->SetHistogram(" << fHistogram->GetName() <<
");" << std::endl;
1747 out <<
" " << std::endl;
1751 TIter next(fFunctions);
1753 while ((obj = next())) {
1754 obj->SavePrimitive(out,
"nodraw");
1755 if (obj->InheritsFrom(
"TPaveStats")) {
1756 out <<
" tgme->GetListOfFunctions()->Add(ptstats);" << std::endl;
1757 out <<
" ptstats->SetParent(tgme->GetListOfFunctions());" << std::endl;
1759 out <<
" tgme->GetListOfFunctions()->Add(" << obj->GetName() <<
");" << std::endl;
1762 const char *l = strstr(option,
"multigraph");
1764 out <<
" multigraph->Add(tgme, " << quote << l + 10 << quote <<
");" << std::endl;
1766 out <<
" tgme->Draw(" << quote << option << quote <<
");" << std::endl;
1774 void TGraphMultiErrors::SetPointError(Double_t exL, Double_t exH, Double_t eyL1, Double_t eyH1, Double_t eyL2,
1775 Double_t eyH2, Double_t eyL3, Double_t eyH3)
1777 Int_t px = gPad->GetEventX();
1778 Int_t py = gPad->GetEventY();
1784 for (i = 0; i < fNpoints; i++) {
1785 Int_t dpx = px - gPad->XtoAbsPixel(gPad->XtoPad(fX[i]));
1786 Int_t dpy = py - gPad->YtoAbsPixel(gPad->YtoPad(fY[i]));
1788 if (dpx * dpx + dpy * dpy < 25) {
1797 SetPointEX(ipoint, exL, exH);
1800 SetPointEY(ipoint, 0, eyL1, eyH1);
1802 SetPointEY(ipoint, 1, eyL2, eyH2);
1804 SetPointEY(ipoint, 2, eyL3, eyH3);
1811 void TGraphMultiErrors::SetPointError(Int_t i, Int_t ne, Double_t exL, Double_t exH,
const Double_t *eyL,
1812 const Double_t *eyH)
1814 SetPointEX(i, exL, exH);
1815 SetPointEY(i, ne, eyL, eyH);
1821 void TGraphMultiErrors::SetPointEX(Int_t i, Double_t exL, Double_t exH)
1823 SetPointEXlow(i, exL);
1824 SetPointEXhigh(i, exH);
1830 void TGraphMultiErrors::SetPointEXlow(Int_t i, Double_t exL)
1835 if (i >= fNpoints) {
1837 TGraphMultiErrors::SetPoint(i, 0., 0.);
1846 void TGraphMultiErrors::SetPointEXhigh(Int_t i, Double_t exH)
1851 if (i >= fNpoints) {
1853 TGraphMultiErrors::SetPoint(i, 0., 0.);
1862 void TGraphMultiErrors::SetPointEY(Int_t i, Int_t ne,
const Double_t *eyL,
const Double_t *eyH)
1864 SetPointEYlow(i, ne, eyL);
1865 SetPointEYhigh(i, ne, eyH);
1871 void TGraphMultiErrors::SetPointEYlow(Int_t i, Int_t ne,
const Double_t *eyL)
1873 for (Int_t j = 0; j < fNYErrors; j++) {
1875 SetPointEYlow(i, j, eyL[j]);
1877 SetPointEYlow(i, j, 0.);
1884 void TGraphMultiErrors::SetPointEYhigh(Int_t i, Int_t ne,
const Double_t *eyH)
1886 for (Int_t j = 0; j < fNYErrors; j++) {
1888 SetPointEYhigh(i, j, eyH[j]);
1890 SetPointEYhigh(i, j, 0.);
1897 void TGraphMultiErrors::SetPointEY(Int_t i, Int_t e, Double_t eyL, Double_t eyH)
1899 SetPointEYlow(i, e, eyL);
1900 SetPointEYhigh(i, e, eyH);
1906 void TGraphMultiErrors::SetPointEYlow(Int_t i, Int_t e, Double_t eyL)
1913 TGraphMultiErrors::SetPoint(i, 0., 0.);
1915 while (e >= fNYErrors)
1916 AddYError(fNpoints);
1920 fEyLSum[i] = GetErrorYlow(i);
1928 void TGraphMultiErrors::SetPointEYhigh(Int_t i, Int_t e, Double_t eyH)
1935 TGraphMultiErrors::SetPoint(i, 0., 0.);
1937 while (e >= fNYErrors)
1938 AddYError(fNpoints);
1942 fEyHSum[i] = GetErrorYhigh(i);
1950 void TGraphMultiErrors::SetEY(Int_t e, Int_t np,
const Double_t *eyL,
const Double_t *eyH)
1952 SetEYlow(e, np, eyL);
1953 SetEYhigh(e, np, eyH);
1959 void TGraphMultiErrors::SetEYlow(Int_t e, Int_t np,
const Double_t *eyL)
1961 for (Int_t i = 0; i < fNpoints; i++) {
1963 SetPointEYlow(i, e, eyL[i]);
1965 SetPointEYlow(i, e, 0.);
1972 void TGraphMultiErrors::SetEYhigh(Int_t e, Int_t np,
const Double_t *eyH)
1974 for (Int_t i = 0; i < fNpoints; i++) {
1976 SetPointEYhigh(i, e, eyH[i]);
1978 SetPointEYhigh(i, e, 0.);
1984 void TGraphMultiErrors::SetSumErrorsMode(Int_t m)
1986 if (fSumErrorsMode == m)
1995 void TGraphMultiErrors::SetAttFill(Int_t e, TAttFill *taf)
1998 taf->TAttFill::Copy(*
this);
1999 else if (e >= 0 && e < fNYErrors)
2000 taf->TAttFill::Copy(fAttFill[e]);
2006 void TGraphMultiErrors::SetAttLine(Int_t e, TAttLine *taf)
2009 taf->TAttLine::Copy(*
this);
2010 else if (e >= 0 && e < fNYErrors)
2011 taf->TAttLine::Copy(fAttLine[e]);
2017 void TGraphMultiErrors::SetFillColor(Int_t e, Color_t fcolor)
2020 SetFillColor(fcolor);
2021 else if (e >= 0 && e < fNYErrors)
2022 fAttFill[e].SetFillColor(fcolor);
2028 void TGraphMultiErrors::SetFillColorAlpha(Int_t e, Color_t fcolor, Float_t falpha)
2031 SetFillColorAlpha(fcolor, falpha);
2032 else if (e >= 0 && e < fNYErrors)
2033 fAttFill[e].SetFillColorAlpha(fcolor, falpha);
2039 void TGraphMultiErrors::SetFillStyle(Int_t e, Style_t fstyle)
2042 SetFillStyle(fstyle);
2043 else if (e >= 0 && e < fNYErrors)
2044 fAttFill[e].SetFillStyle(fstyle);
2050 void TGraphMultiErrors::SetLineColor(Int_t e, Color_t lcolor)
2053 SetLineColor(lcolor);
2054 else if (e >= 0 && e < fNYErrors)
2055 fAttLine[e].SetLineColor(lcolor);
2061 void TGraphMultiErrors::SetLineColorAlpha(Int_t e, Color_t lcolor, Float_t lalpha)
2064 SetLineColorAlpha(lcolor, lalpha);
2065 else if (e >= 0 && e < fNYErrors)
2066 fAttLine[e].SetLineColorAlpha(lcolor, lalpha);
2072 void TGraphMultiErrors::SetLineStyle(Int_t e, Style_t lstyle)
2075 SetLineStyle(lstyle);
2076 else if (e >= 0 && e < fNYErrors)
2077 fAttLine[e].SetLineStyle(lstyle);
2083 void TGraphMultiErrors::SetLineWidth(Int_t e, Width_t lwidth)
2086 SetLineWidth(lwidth);
2087 else if (e >= 0 && e < fNYErrors)
2088 fAttLine[e].SetLineWidth(lwidth);