16#include <TCollection.h>
18#include <TDirectory.h>
25#include <TMatrixDfwd.h>
29#include <TPaletteAxis.h>
33#include <TVirtualPad.h>
45 void RemoveNan(TH1* h, Double_t fill, Double_t fill_e) {
46 if (h->InheritsFrom(
"TH3")) {
47 for (
int i = 0; i <= h->GetNbinsX() + 1; i++) {
48 for (
int j = 0; j <= h->GetNbinsY() + 1; j++) {
49 for (
int k = 0; k <= h->GetNbinsZ() + 1; k++) {
50 if (TMath::IsNaN(h->GetBinContent(i, j, k))) {
51 h->SetBinContent(i, j, k, fill);
52 h->SetBinError(i, j, k, fill_e);
57 }
else if (h->InheritsFrom(
"TH2")) {
58 for (
int i = 0; i <= h->GetNbinsX() + 1; i++) {
59 for (
int j = 0; j <= h->GetNbinsY() + 1; j++) {
60 if (TMath::IsNaN(h->GetBinContent(i, j))) {
61 h->SetBinContent(i, j, fill);
62 h->SetBinError(i, j, fill_e);
67 for (
int i = 0; i <= h->GetNbinsX() + 1; i++) {
68 if (TMath::IsNaN(h->GetBinContent(i))) {
69 h->SetBinContent(i, fill);
70 h->SetBinError(i, fill_e);
76 TH1D* GetProjection1D(
const TH3* histo, Double_t min1, Double_t max1, Double_t min2, Double_t max2, Option_t* opt) {
78 Bool_t sumw = Hal::Std::FindParam(option,
"sumw", kTRUE);
79 const TAxis *axisA, *axisB, *axisC;
82 if (option.Contains(
"z")) {
83 axisA = histo->GetXaxis();
84 axisB = histo->GetYaxis();
85 axisC = histo->GetZaxis();
87 if (!option.Contains(
"noautoname")) { name = Form(
"%i_pz", anonymCounter++); }
88 if (option.Contains(
"bins")) {
89 projection = histo->ProjectionZ(name, min1, max1, min2, max2,
"e");
91 projection = histo->ProjectionZ(
92 name, axisA->FindFixBin(min1), axisA->FindFixBin(max1), axisB->FindFixBin(min2), axisB->FindFixBin(max2),
"o");
94 }
else if (option.Contains(
"y")) {
95 axisA = histo->GetXaxis();
96 axisB = histo->GetZaxis();
97 axisC = histo->GetYaxis();
99 if (!option.Contains(
"noautoname")) { name = Form(
"%i_py", anonymCounter++); }
100 if (option.Contains(
"bins")) {
101 projection = histo->ProjectionY(name, min1, max1, min2, max2,
"e");
103 projection = histo->ProjectionY(
104 name, axisA->FindFixBin(min1), axisA->FindFixBin(max1), axisB->FindFixBin(min2), axisB->FindFixBin(max2),
"o");
107 axisA = histo->GetYaxis();
108 axisB = histo->GetZaxis();
109 axisC = histo->GetXaxis();
110 TString name =
"_px";
111 if (!option.Contains(
"noautoname")) { name = Form(
"%i_px", anonymCounter++); }
112 if (option.Contains(
"bins")) {
113 projection = histo->ProjectionX(name, min1, max1, min2, max2,
"e");
115 projection = histo->ProjectionX(
116 name, axisA->FindFixBin(min1), axisA->FindFixBin(max1), axisB->FindFixBin(min2), axisB->FindFixBin(max2),
"o");
119 if (option.Contains(
"bins")) {
120 nbins = (max1 - min1 + 1) * (max2 - min2 + 1);
122 nbins = axisA->FindFixBin(max1) - axisA->FindFixBin(min1) + 1;
123 nbins = nbins * (axisB->FindFixBin(max2) - axisB->FindFixBin(min2) + 1);
125 if (sumw) projection->Sumw2();
126 if (option.Contains(
"scale")) {
127 if (nbins != 0) projection->Scale(1.0 / nbins);
129 projection->GetXaxis()->SetTitle(axisC->GetTitle());
134 TH1D* GetProjection1D(
const TH2* histo, Double_t min, Double_t max, Option_t* opt) {
135 TString option = opt;
137 Bool_t sumw = Hal::Std::FindParam(option,
"sumw", kTRUE);
139 if (option.Contains(
"y")) {
140 TString name =
"_py";
141 if (!option.Contains(
"noautoname")) { name = Form(
"%i_py", anonymCounter++); }
142 if (option.Contains(
"bins")) {
143 projection = histo->ProjectionY(name, min, max);
146 projection = histo->ProjectionY(name, histo->GetXaxis()->FindBin(min), histo->GetXaxis()->FindBin(max));
147 nbins = histo->GetXaxis()->FindBin(max) - histo->GetXaxis()->FindBin(min);
149 projection->GetXaxis()->SetTitle(histo->GetYaxis()->GetTitle());
151 TString name =
"_px";
152 if (!option.Contains(
"noautoname")) { name = Form(
"%i_px", anonymCounter++); }
153 if (option.Contains(
"bins")) {
154 projection = histo->ProjectionX(name, min, max);
157 projection = histo->ProjectionX(name, histo->GetYaxis()->FindBin(min), histo->GetYaxis()->FindBin(max));
158 nbins = histo->GetYaxis()->FindBin(max) - histo->GetYaxis()->FindBin(min);
160 projection->GetXaxis()->SetTitle(histo->GetXaxis()->GetTitle());
162 if (sumw) projection->Sumw2();
163 if (option.Contains(
"scale")) {
164 if (nbins != 0) projection->Scale(1.0 / (nbins + 1));
166 projection->SetDirectory(0);
170 TH2D* GetProjection2D(
const TH3* histo, Double_t min, Double_t max, Option_t* opt) {
171 TString option = opt;
172 TString title = histo->GetTitle();
173 TH3* histo_cloned = (TH3*) histo->Clone();
176 Bool_t sumw = Hal::Std::FindParam(option,
"sumw", kTRUE);
179 TString projection_option;
180 if (Hal::Std::FindParam(option,
"yz")) {
181 axis = histo_cloned->GetXaxis();
182 projection_option =
"yze";
183 }
else if (Hal::Std::FindParam(option,
"zy")) {
184 axis = histo_cloned->GetXaxis();
185 projection_option =
"zye";
186 }
else if (Hal::Std::FindParam(option,
"xz")) {
187 axis = histo_cloned->GetYaxis();
188 projection_option =
"xze";
191 }
else if (Hal::Std::FindParam(option,
"zx")) {
192 axis = histo_cloned->GetYaxis();
193 projection_option =
"zxe";
194 }
else if (Hal::Std::FindParam(option,
"yx")) {
195 axis = histo_cloned->GetZaxis();
196 projection_option =
"yxe";
198 axis = histo_cloned->GetZaxis();
199 projection_option =
"xye";
203 if (Hal::Std::FindParam(option,
"bins")) {
204 axis->SetRange(min, max);
205 nbins = 1 + max - min;
208 max = min + axis->GetBinWidth(1) * 0.1;
210 axis->SetRangeUser(min, max);
211 nbins = 1 + axis->FindBin(max) - axis->FindBin(min);
213 projection = (TH2D*) histo_cloned->Project3D(projection_option);
216 if (sumw) projection->Sumw2();
217 if (option.Contains(
"scale")) { projection->Scale(1.0 / nbins); }
218 if (!option.Contains(
"noautoname")) {
219 TString name = Form(
"%i_2dproj", anonymCounter++);
220 projection->SetName(name);
222 projection->SetDirectory(0);
226 TH1D* SmearHistogram(TH1D* input_histogram, TH2D* smear_matrix, Option_t* opt) {
227 TString option = opt;
228 Bool_t bad_map = kFALSE;
229 if (input_histogram->GetNbinsX() != smear_matrix->GetNbinsX()) {
230 if (!option.Contains(
"forced"))
Hal::Cout::PrintInfo(
"Incompatible histograms for smearing", Hal::EInfo::kWarning);
233 if (input_histogram->GetNbinsX() != smear_matrix->GetNbinsY()) {
234 if (!option.Contains(
"forced"))
Hal::Cout::PrintInfo(
"Incompatible histograms for smearing", Hal::EInfo::kWarning);
237 if (option.Contains(
"forced") && bad_map) {
240 TH2D* smear_new =
new TH2D(
"smear_temp",
242 input_histogram->GetNbinsX(),
243 input_histogram->GetXaxis()->GetXmin(),
244 input_histogram->GetXaxis()->GetXmax(),
245 input_histogram->GetNbinsX(),
246 input_histogram->GetXaxis()->GetXmin(),
247 input_histogram->GetXaxis()->GetXmax());
248 for (
int i = 0; i <= input_histogram->GetNbinsX() + 1; i++) {
249 Double_t x = smear_new->GetXaxis()->GetBinCenter(i);
250 for (
int j = 0; j <= input_histogram->GetNbinsX() + 1; j++) {
251 Double_t y = smear_new->GetYaxis()->GetBinCenter(j);
252 if (m_map->
Eval(x, y) >= 0) {
253 smear_new->SetBinContent(i, j, m_map->
Eval(x, y));
254 smear_new->SetBinError(i, j, m_map->
GetError(x, y));
258 smear_matrix = smear_new;
261 if (bad_map)
return NULL;
264 TH1D* cloned = (TH1D*) input_histogram->Clone(Form(
"%s_smeared", input_histogram->GetName()));
266 Int_t N = smear_matrix->GetNbinsX() + 2;
268 TH2D* norm_matrix = smear_matrix;
269 for (
int i = 0; i <= N - 1; i++) {
271 for (
int j = 0; j < N; j++) {
272 val += smear_matrix->GetBinContent(i, j);
274 for (
int j = 0; j < N; j++) {
276 norm_matrix->SetBinContent(i, j, smear_matrix->GetBinContent(i, j) / val);
277 norm_matrix->SetBinError(i, j, smear_matrix->GetBinError(i, j) / val);
280 if (j == i) diag = 1.0;
281 norm_matrix->SetBinContent(i, j, diag);
282 norm_matrix->SetBinError(i, j, 0);
291 TMatrixD YM(N, 1), YME(N, 1);
293 for (
int i = 0; i < N; i++) {
294 XM[i][0] = input_histogram->GetBinContent(i);
295 XME[i][0] = input_histogram->GetBinError(i);
296 for (
int j = 0; j < N; j++) {
297 AM[i][j] = norm_matrix->GetBinContent(j, i);
298 AME[i][j] = norm_matrix->GetBinError(j, i);
302 if (option.Contains(
"REV") || option.Contains(
"rev")) {
306 for (
int i = 0; i < N; i++) {
307 cloned->SetBinContent(i, YM[i][0]);
308 cloned->SetBinError(i, YME[i][0]);
313 TMatrixD YME2 = AME * XM;
314 for (
int i = 0; i < N; i++) {
315 cloned->SetBinContent(i, YM[i][0]);
316 cloned->SetBinError(i, YME[i][0]);
319 if (bad_map)
delete smear_matrix;
324 TH1* MakeHisto1D(TString name, TString title, TVector3 Xaxis, Char_t type) {
326 case 'D':
return new TH1D(name, title, (
int) Xaxis.X(), Xaxis.Y(), Xaxis.Z());
break;
327 case 'F':
return new TH1F(name, title, (
int) Xaxis.X(), Xaxis.Y(), Xaxis.Z());
break;
328 case 'I':
return new TH1I(name, title, (
int) Xaxis.X(), Xaxis.Y(), Xaxis.Z());
break;
333 TH2* MakeHisto2D(TString name, TString title, TVector3 Xaxis, TVector3 Yaxis, Char_t type) {
336 return new TH2D(name, title, (
int) Xaxis.X(), Xaxis.Y(), Xaxis.Z(), (
int) Yaxis.X(), Yaxis.Y(), Yaxis.Z());
339 return new TH2F(name, title, (
int) Xaxis.X(), Xaxis.Y(), Xaxis.Z(), (
int) Yaxis.X(), Yaxis.Y(), Yaxis.Z());
342 return new TH2I(name, title, (
int) Xaxis.X(), Xaxis.Y(), Xaxis.Z(), (
int) Yaxis.X(), Yaxis.Y(), Yaxis.Z());
348 TH3* MakeHisto3D(TString name, TString title, TVector3 Xaxis, TVector3 Yaxis, TVector3 Zaxis, Char_t type) {
351 return new TH3D(name,
364 return new TH3F(name,
377 return new TH3I(name,
393 void HistogramEdges(TH1* h, TString option, Double_t value) {
395 enum eFill { kByVal, kByNeighbour };
396 enum eBin { kFirst, kLast };
397 if (option.Contains(
"y")) { axis =
'y'; }
398 if (option.Contains(
"z")) { axis =
'z'; }
400 if (option.Contains(
"ov")) { bin = kLast; }
401 eFill fill = kByNeighbour;
402 if (option.Contains(
"val")) {
404 }
else if (h->InheritsFrom(
"TH3")) {
406 for (
int i = 0; i <= h->GetNbinsX(); i++) {
407 for (
int j = 0; j < h->GetNbinsY(); j++) {
412 h->SetBinContent(i, j, 0, h->GetBinContent(i, j, 1));
415 h->SetBinContent(i, j, 0, value);
422 h->SetBinContent(i, j, h->GetNbinsX() + 1, h->GetBinContent(i, j, 1));
425 h->SetBinContent(i, j, h->GetNbinsX() + 1, value);
432 }
else if (axis ==
'y') {
433 for (
int i = 0; i <= h->GetNbinsX(); i++) {
434 for (
int j = 0; j < h->GetNbinsZ(); j++) {
439 h->SetBinContent(i, 0, j, h->GetBinContent(i, 1, j));
442 h->SetBinContent(i, 0, j, value);
449 h->SetBinContent(i, h->GetNbinsX() + 1, j, h->GetBinContent(i, 1, j));
452 h->SetBinContent(i, h->GetNbinsX() + 1, j, value);
460 for (
int i = 0; i <= h->GetNbinsY(); i++) {
461 for (
int j = 0; j < h->GetNbinsZ(); j++) {
466 h->SetBinContent(0, i, j, h->GetBinContent(1, i, j));
469 h->SetBinContent(0, i, j, value);
476 h->SetBinContent(h->GetNbinsX() + 1, i, j, h->GetBinContent(1, i, j));
479 h->SetBinContent(h->GetNbinsX() + 1, i, j, value);
487 }
else if (h->InheritsFrom(
"TH2")) {
489 for (
int i = 0; i <= h->GetNbinsX() + 1; i++) {
494 h->SetBinContent(i, 0, h->GetBinContent(i, 1));
497 h->SetBinContent(i, 0, value);
504 h->SetBinContent(i, h->GetNbinsY() + 1, h->GetBinContent(i, h->GetNbinsY()));
507 h->SetBinContent(i, h->GetNbinsY() + 1, value);
514 for (
int i = 0; i <= h->GetNbinsY() + 1; i++) {
519 h->SetBinContent(0, i, h->GetBinContent(1, i));
522 h->SetBinContent(0, i, value);
529 h->SetBinContent(h->GetNbinsX() + 1, i, h->GetBinContent(h->GetNbinsX(), i));
532 h->SetBinContent(h->GetNbinsX() + 1, i, value);
542 if (fill == kByVal) { h->SetBinContent(0, value); }
543 if (fill == kByNeighbour) { h->SetBinContent(0, h->GetBinContent(1)); }
546 if (fill == kByVal) { h->SetBinContent(h->GetNbinsX() + 1, value); }
547 if (fill == kByNeighbour) { h->SetBinContent(h->GetNbinsX() + 1, h->GetBinContent(h->GetNbinsX())); }
552 void HistogramExtend(TH1* h, Char_t axis, Double_t factor) {
565 if (x->IsVariableBinSize()) {
566 const TArrayD* ar = x->GetXbins();
567 Int_t size = ar->GetSize();
568 Double_t* edges =
new Double_t[size];
569 for (
int i = 0; i < ar->GetSize(); i++) {
570 edges[i] = ar->At(i) * factor;
572 x->Set(size - 1, edges);
575 x->Set(x->GetNbins(), x->GetXmin() * factor, x->GetXmax() * factor);
580 void CopyAxisProp(
const TAxis* from, TAxis* to, TString option) {
581 TAxis default_axis = TAxis();
582 if (default_axis.GetCenterTitle() != from->GetCenterTitle()) to->CenterTitle(from->GetCenterTitle());
583 if (default_axis.GetNdivisions() != from->GetNdivisions()) to->SetNdivisions(from->GetNdivisions());
584 if (default_axis.GetTitleColor() != from->GetTitleColor()) to->SetTitleColor(from->GetTitleColor());
585 if (default_axis.GetTitleFont() != from->GetTitleFont()) to->SetTitleFont(from->GetTitleFont());
586 if (default_axis.GetTitleOffset() != from->GetTitleOffset()) to->SetTitleOffset(from->GetTitleOffset());
587 if (0.035 != from->GetTitleSize()) to->SetTitleSize(from->GetTitleSize());
588 if (default_axis.GetLabelColor() != from->GetLabelColor()) to->SetLabelColor(from->GetLabelColor());
589 if (default_axis.GetLabelFont() != from->GetLabelFont()) to->SetLabelFont(from->GetLabelFont());
590 if (default_axis.GetLabelOffset() != from->GetLabelOffset()) to->SetLabelOffset(from->GetLabelOffset());
591 if (default_axis.GetLabelSize() != from->GetLabelSize()) to->SetLabelSize(from->GetLabelSize());
592 if (!Hal::Std::FindParam(option,
"!tit", kTRUE)) { to->SetTitle(from->GetTitle()); }
595 TH1D* GetDiagonalProjection1D(TH3* h, TString dir, Double_t start, Double_t start2) {
596 if (h->GetNbinsX() != h->GetNbinsY() || h->GetNbinsX() != h->GetNbinsZ()) {
601 Double_t xmin = h->GetXaxis()->GetBinLowEdge(1);
602 Double_t xmax = h->GetXaxis()->GetBinUpEdge(h->GetNbinsX());
603 Int_t binsTot = h->GetXaxis()->GetNbins();
604 TString titleX = h->GetXaxis()->GetTitle();
605 TString titleY = h->GetYaxis()->GetTitle();
606 TString titleZ = h->GetZaxis()->GetTitle();
607 TString randname = Form(
"%i", (
int) gRandom->Uniform(1E+9));
608 TH1D* res =
new TH1D(randname,
"res", binsTot, xmin, xmax);
609 res->SetMarkerStyle(h->GetMarkerStyle());
610 res->SetMarkerColor(h->GetMarkerColor());
611 res->SetMarkerSize(h->GetMarkerSize());
612 res->SetLineColor(h->GetLineColor());
613 res->SetLineStyle(h->GetLineStyle());
614 res->SetLineWidth(h->GetLineWidth());
615 TString newTitle =
"";
616 std::vector<int> binsVecX(binsTot), binsVecY(binsTot), binsVecZ(binsTot);
617 if (temp.Length() == 6 && temp.BeginsWith(
"xyz")) {
618 for (
int i = 1; i <= binsTot; i++) {
623 if (temp[3] ==
'-') std::sort(binsVecX.begin(), binsVecX.end(), std::greater<int>());
624 if (temp[4] ==
'-') std::sort(binsVecY.begin(), binsVecY.end(), std::greater<int>());
625 if (temp[5] ==
'-') std::sort(binsVecZ.begin(), binsVecZ.end(), std::greater<int>());
626 newTitle = titleX + temp[3] + titleY + temp[4] + titleZ + temp[5];
627 }
else if (temp.Length() == 4) {
628 if (temp.BeginsWith(
"yz")) {
629 Int_t binMid = h->GetXaxis()->FindBin(start);
630 for (
int i = 1; i <= binsTot; i++) {
631 binsVecX[i - 1] = binMid;
635 if (temp[2] ==
'-') std::sort(binsVecY.begin(), binsVecY.end(), std::greater<int>());
636 if (temp[3] ==
'-') std::sort(binsVecZ.begin(), binsVecZ.end(), std::greater<int>());
637 newTitle = titleY + temp[2] + titleZ + temp[3];
638 }
else if (temp.BeginsWith(
"xz")) {
639 Int_t binMid = h->GetYaxis()->FindBin(start);
640 for (
int i = 1; i <= binsTot; i++) {
642 binsVecY[i - 1] = binMid;
645 if (temp[2] ==
'-') std::sort(binsVecX.begin(), binsVecX.end(), std::greater<int>());
646 if (temp[3] ==
'-') std::sort(binsVecZ.begin(), binsVecZ.end(), std::greater<int>());
647 newTitle = titleX + temp[2] + titleZ + temp[3];
649 Int_t binMid = h->GetZaxis()->FindBin(start);
650 for (
int i = 1; i <= binsTot; i++) {
653 binsVecZ[i - 1] = binMid;
655 if (temp[2] ==
'-') std::sort(binsVecX.begin(), binsVecX.end(), std::greater<int>());
656 if (temp[3] ==
'-') std::sort(binsVecY.begin(), binsVecY.end(), std::greater<int>());
657 newTitle = titleX + temp[2] + titleY + temp[3];
659 }
else if (temp.Length() == 2 || temp.Length() == 1) {
660 TString signFlag =
"";
661 if (temp.Length() == 2) {
662 if (temp[1] ==
'-') signFlag =
"-";
663 if (temp[1] ==
'+') signFlag =
"+";
666 if (signFlag.EqualTo(
"-")) rev = kTRUE;
667 if (temp[0] ==
'y') {
668 Int_t bin1 = h->GetXaxis()->FindBin(start);
669 Int_t bin2 = h->GetZaxis()->FindBin(start2);
670 for (
int i = 1; i <= binsTot; i++) {
671 binsVecX[i - 1] = bin1;
673 binsVecZ[i - 1] = bin2;
675 if (rev) std::sort(binsVecY.begin(), binsVecY.end(), std::greater<int>());
676 newTitle = titleY + signFlag;
677 }
else if (temp[0] ==
'z') {
678 Int_t bin1 = h->GetXaxis()->FindBin(start);
679 Int_t bin2 = h->GetYaxis()->FindBin(start2);
680 for (
int i = 1; i <= binsTot; i++) {
681 binsVecX[i - 1] = bin1;
682 binsVecY[i - 1] = bin2;
685 if (rev) std::sort(binsVecZ.begin(), binsVecZ.end(), std::greater<int>());
686 newTitle = titleZ + signFlag;
688 Int_t bin1 = h->GetYaxis()->FindBin(start);
689 Int_t bin2 = h->GetZaxis()->FindBin(start2);
690 for (
int i = 1; i <= binsTot; i++) {
692 binsVecY[i - 1] = bin1;
693 binsVecZ[i - 1] = bin2;
695 if (rev) std::sort(binsVecX.begin(), binsVecX.end(), std::greater<int>());
696 newTitle = titleX + signFlag;
704 for (
int i = 1; i <= binsTot; i++) {
705 res->SetBinContent(i, h->GetBinContent(binsVecX[i - 1], binsVecY[i - 1], binsVecZ[i - 1]));
706 res->SetBinError(i, h->GetBinError(binsVecX[i - 1], binsVecY[i - 1], binsVecZ[i - 1]));
708 res->GetXaxis()->SetTitle(newTitle);
712 Bool_t AreSimilar(
const TH1* x,
const TH1* y, Bool_t classes) {
714 TString classname1 = x->ClassName();
715 TString classname2 = y->ClassName();
716 if (!classname1.EqualTo(classname2))
return kFALSE;
718 if (x->InheritsFrom(
"TH3") && y->InheritsFrom(
"TH3")) {
719 const TH3* h1 =
static_cast<const TH3*
>(x);
720 const TH3* h2 =
static_cast<const TH3*
>(y);
721 if (h1->GetNbinsX() != h2->GetNbinsX())
return kFALSE;
722 if (h1->GetNbinsY() != h2->GetNbinsY())
return kFALSE;
723 if (h1->GetNbinsZ() != h2->GetNbinsZ())
return kFALSE;
724 if (h1->GetXaxis()->GetXmin() != h2->GetXaxis()->GetXmin())
return kFALSE;
725 if (h1->GetXaxis()->GetXmax() != h2->GetXaxis()->GetXmax())
return kFALSE;
726 if (h1->GetYaxis()->GetXmin() != h2->GetYaxis()->GetXmin())
return kFALSE;
727 if (h1->GetYaxis()->GetXmax() != h2->GetYaxis()->GetXmax())
return kFALSE;
728 if (h1->GetZaxis()->GetXmin() != h2->GetZaxis()->GetXmin())
return kFALSE;
729 if (h1->GetZaxis()->GetXmax() != h2->GetZaxis()->GetXmax())
return kFALSE;
730 }
else if (x->InheritsFrom(
"TH2") && y->InheritsFrom(
"TH2")) {
731 const TH2* h1 =
static_cast<const TH2*
>(x);
732 const TH2* h2 =
static_cast<const TH2*
>(y);
733 if (h1->GetNbinsX() != h2->GetNbinsX())
return kFALSE;
734 if (h1->GetNbinsY() != h2->GetNbinsY())
return kFALSE;
735 if (h1->GetXaxis()->GetXmin() != h2->GetXaxis()->GetXmin())
return kFALSE;
736 if (h1->GetXaxis()->GetXmax() != h2->GetXaxis()->GetXmax())
return kFALSE;
737 if (h1->GetYaxis()->GetXmin() != h2->GetYaxis()->GetXmin())
return kFALSE;
738 if (h1->GetYaxis()->GetXmax() != h2->GetYaxis()->GetXmax())
return kFALSE;
740 const TH1* h1 =
static_cast<const TH1*
>(x);
741 const TH1* h2 =
static_cast<const TH1*
>(y);
742 if (h1->GetNbinsX() != h2->GetNbinsX())
return kFALSE;
743 if (h1->GetXaxis()->GetXmin() != h2->GetXaxis()->GetXmin())
return kFALSE;
744 if (h1->GetXaxis()->GetXmax() != h2->GetXaxis()->GetXmax())
return kFALSE;
749 void GetAxisPar(
const TH1& obj, Int_t& nbins, Double_t& min, Double_t& max, Option_t* opt) {
750 TString option = opt;
751 if (option ==
"x" || option ==
"X") {
752 const TAxis* x = obj.GetXaxis();
753 nbins = x->GetNbins();
754 min = x->GetBinLowEdge(1);
755 max = x->GetBinUpEdge(nbins);
756 }
else if (option ==
"y" || option ==
"Y") {
757 const TAxis* x = obj.GetYaxis();
758 nbins = x->GetNbins();
759 min = x->GetBinLowEdge(1);
760 max = x->GetBinUpEdge(nbins);
761 }
else if (option ==
"z" || option ==
"Z") {
762 const TAxis* x = obj.GetZaxis();
763 nbins = x->GetNbins();
764 min = x->GetBinLowEdge(1);
765 max = x->GetBinUpEdge(nbins);
769 std::vector<double> GetAxisCenters(
const TH1& obj, Option_t* opt) {
770 TString option = opt;
771 auto getAxis = [](TString& opti,
const TH1& hst) {
772 if (Hal::Std::FindParam(opti,
"x", kTRUE)) {
return hst.GetXaxis(); }
773 if (Hal::Std::FindParam(opti,
"y", kTRUE)) {
return hst.GetYaxis(); }
774 if (Hal::Std::FindParam(opti,
"z", kTRUE)) {
return hst.GetZaxis(); }
775 return (
const TAxis*)
nullptr;
777 auto axis = (
const TAxis*) getAxis(option, obj);
778 if (axis ==
nullptr)
return std::vector<double>();
780 int bins = axis->GetNbins();
781 std::vector<double> vec;
783 if (Hal::Std::FindParam(option,
"o", kTRUE)) {
787 for (
int i = startbin; i <= bins; i++) {
788 vec.push_back(axis->GetBinCenter(i));
795 std::vector<int> FoldAxis(
const TAxis& x, Double_t val) {
796 const Int_t nBins = x.GetNbins();
797 Int_t binFold = x.FindBin(val);
798 Double_t center = x.GetBinCenter(binFold);
800 std::vector<int> foldBinMap(nBins + 1);
802 if (val != center) shift = 1;
803 for (
int i = 1; i <= nBins; i++) {
804 Int_t delta = binFold - i + shift;
805 Int_t bin = binFold + delta;
806 if (bin < 1) bin = bin + nBins;
807 if (bin > nBins) bin = bin - nBins;
813 void CropAxis(
const TAxis* x,
815 std::pair<int, int>& binId,
816 std::pair<double, double>& val,
821 binId.first = x->FindBin(lmin);
822 binId.second = x->FindBin(lmax);
827 binId.first = TMath::Max(1, binId.first);
828 binId.second = TMath::Min(binId.second, x->GetNbins());
829 val.first = x->GetBinLowEdge(binId.first);
830 val.second = x->GetBinUpEdge(binId.second);
831 nbins = binId.second - binId.first + 1;
836 void Fold1D(Double_t val, TH1& h) {
837 TH1* tempCopy = (TH1*) h.Clone();
838 const Int_t nBins = h.GetXaxis()->GetNbins();
839 std::vector<int> foldBinMap = FoldAxis(*h.GetXaxis(), val);
841 for (
int i = 1; i <= nBins; i++) {
842 Double_t old = h.GetBinContent(i);
843 h.SetBinContent(i, old + tempCopy->GetBinContent(foldBinMap[i]));
844 Double_t sumv = tempCopy->GetSumw2()->GetAt(foldBinMap[i]);
845 h.GetSumw2()->SetAt(h.GetSumw2()->At(i) + sumv, i);
850 void Fold2D(Double_t val, TH2& h, TString opt) {
851 TH2* tempCopy = (TH2*) h.Clone();
852 const Int_t nBinsX = h.GetXaxis()->GetNbins();
853 const Int_t nBinsY = h.GetYaxis()->GetNbins();
854 if (Hal::Std::FindParam(opt,
"x", kTRUE)) {
855 std::vector<int> foldBinMap = FoldAxis(*h.GetXaxis(), val);
856 for (
int i = 1; i <= nBinsX; i++) {
857 for (
int j = 1; j <= nBinsY; j++) {
858 Double_t old = h.GetBinContent(i, j);
859 Double_t add = tempCopy->GetBinContent(foldBinMap[i], j);
860 h.SetBinContent(i, j, old + add);
863 }
else if (Hal::Std::FindParam(opt,
"y", kTRUE)) {
864 std::vector<int> foldBinMap = FoldAxis(*h.GetYaxis(), val);
865 for (
int i = 1; i <= nBinsX; i++) {
866 for (
int j = 1; j <= nBinsY; j++) {
867 Double_t old = h.GetBinContent(i, j);
868 Double_t add = tempCopy->GetBinContent(i, foldBinMap[j]);
869 h.SetBinContent(i, j, old + add);
877 void Fold3D(Double_t val, TH2& h, TString opt) {
878 TH3* tempCopy = (TH3*) h.Clone();
879 const Int_t nBinsX = h.GetXaxis()->GetNbins();
880 const Int_t nBinsY = h.GetYaxis()->GetNbins();
881 const Int_t nBinsZ = h.GetZaxis()->GetNbins();
882 if (Hal::Std::FindParam(opt,
"x", kTRUE)) {
883 std::vector<int> foldBinMap = FoldAxis(*h.GetXaxis(), val);
884 for (
int i = 1; i <= nBinsX; i++) {
885 for (
int j = 1; j <= nBinsY; j++) {
886 for (
int k = 1; k <= nBinsZ; k++) {
887 Double_t old = h.GetBinContent(i, j, k);
888 Double_t add = tempCopy->GetBinContent(foldBinMap[i], j, k);
889 h.SetBinContent(i, j, k, old + add);
893 }
else if (Hal::Std::FindParam(opt,
"y", kTRUE)) {
894 std::vector<int> foldBinMap = FoldAxis(*h.GetYaxis(), val);
895 for (
int i = 1; i <= nBinsX; i++) {
896 for (
int j = 1; j <= nBinsY; j++) {
897 for (
int k = 1; k <= nBinsZ; k++) {
898 Double_t old = h.GetBinContent(i, j, k);
899 Double_t add = tempCopy->GetBinContent(i, foldBinMap[j], k);
900 h.SetBinContent(i, j, k, old + add);
904 }
else if (Hal::Std::FindParam(opt,
"z", kTRUE)) {
905 std::vector<int> foldBinMap = FoldAxis(*h.GetZaxis(), val);
906 for (
int i = 1; i <= nBinsX; i++) {
907 for (
int j = 1; j <= nBinsY; j++) {
908 for (
int k = 1; k <= nBinsZ; k++) {
909 Double_t old = h.GetBinContent(i, j, k);
910 Double_t add = tempCopy->GetBinContent(i, j, foldBinMap[k]);
911 h.SetBinContent(i, j, k, old + add);
920 void SetColor(TH1& h, Color_t color) {
921 h.SetLineColor(color);
922 h.SetMarkerColor(color);
925 void SetColorAndMarker(TH1& h, Color_t color, Marker_t m, Size_t s) {
926 h.SetLineColor(color);
927 h.SetMarkerColor(color);
932 void MakeBeautiful() {
933 gStyle->SetPalette(kRainBow);
934 TGaxis::SetMaxDigits(3);
935 gStyle->SetCanvasPreferGL(kTRUE);
938 void SetRainbow(TH2& h, Double_t x1, Double_t y1, Double_t x2, Double_t y2) {
940 TPaletteAxis* palette = (TPaletteAxis*) h.GetListOfFunctions()->FindObject(
"palette");
941 palette->SetX1NDC(x1);
942 palette->SetX2NDC(x2);
943 palette->SetY1NDC(y1);
944 palette->SetY2NDC(y2);
949 Int_t GetAntiColor(Int_t col) {
950 if (col < 0)
return -1;
953 TObjArray* colors = (TObjArray*) ::ROOT::GetROOT()->GetListOfColors();
954 Int_t ncolors = colors->GetSize();
956 TColor* color =
nullptr;
957 if (col < ncolors) color = (TColor*) colors->At(col);
958 if (!color)
return -1;
963 color->GetRGB(r, g, b);
969 Int_t nb = col + 150;
970 TColor* colorb =
nullptr;
971 if (nb < ncolors) colorb = (TColor*) colors->At(nb);
972 if (colorb)
return nb;
973 colorb =
new TColor(nb, r, g, b);
974 colorb->SetName(Form(
"%s_bright", color->GetName()));
975 colors->AddAtAndExpand(colorb, nb);
979 Int_t GetListOfSubPads(TVirtualPad* pad) {
980 TList* l = pad->GetListOfPrimitives();
982 for (
int i = 0; i < l->GetEntries(); i++) {
983 if (
dynamic_cast<TVirtualPad*
>(l->At(i))) subpads++;
988 TH1D* Crop1D(
const TH1& h, Double_t min, Double_t max, TString option) {
989 std::pair<int, int> binsX;
990 std::pair<double, double> valsX;
992 CropAxis(h.GetXaxis(), nBins, binsX, valsX, min, max, option);
994 TH1D* nh =
new TH1D(h.GetName(), h.GetTitle(), nBins, valsX.first, valsX.second);
996 for (
int i = binsX.first; i <= binsX.second; i++) {
997 nh->SetBinContent(++count, h.GetBinContent(i));
998 nh->SetBinError(count, h.GetBinError(i));
1003 TH2D* Crop2D(
const TH2& h, Double_t minX, Double_t maxX, Double_t minY, Double_t maxY, TString option) {
1004 Int_t nBinsX, nBinsY;
1005 std::pair<int, int> binsX, binsY;
1006 std::pair<double, double> valsX, valsY;
1007 CropAxis(h.GetXaxis(), nBinsX, binsX, valsX, minX, maxX, option);
1008 CropAxis(h.GetYaxis(), nBinsY, binsY, valsY, minY, maxY, option);
1009 TH2D* nh =
new TH2D(h.GetName(), h.GetTitle(), nBinsX, valsX.first, valsX.second, nBinsY, valsY.first, valsY.second);
1012 for (
int i = binsX.first; i <= binsX.second; i++) {
1014 for (
int j = binsY.first; j <= binsY.second; j++) {
1016 nh->SetBinContent(countX, countY, h.GetBinContent(i, j));
1017 nh->SetBinError(countX, countY, h.GetBinError(i, j));
1023 TH3D* Crop3D(
const TH3& h,
1031 std::pair<int, int> X, Y, Z;
1032 std::pair<double, double> valsX, valsY, valsZ;
1034 Int_t nBinsX, nBinsY, nBinsZ;
1035 CropAxis(h.GetXaxis(), nBinsX, X, valsX, minX, maxX, option);
1036 CropAxis(h.GetYaxis(), nBinsY, Y, valsY, minY, maxY, option);
1037 CropAxis(h.GetZaxis(), nBinsZ, Z, valsZ, minZ, maxZ, option);
1038 TH3D* nh =
new TH3D(h.GetName(),
1052 for (
int i = X.first; i <= X.second; i++) {
1055 for (
int j = Y.first; j <= Y.second; j++) {
1058 for (
int k = Z.first; k <= Z.second; k++) {
1060 nh->SetBinContent(countX, countY, countZ, h.GetBinContent(i, j, k));
1061 nh->SetBinError(countX, countY, countZ, h.GetBinError(i, j, k));
1067 std::vector<TObject*> GetPadChildren(TString objName, TString className, TVirtualPad* pad) {
1068 if (!pad) pad = gPad;
1069 std::vector<TObject*> list;
1070 if (!pad)
return list;
1071 TList* l = gPad->GetListOfPrimitives();
1072 for (
int i = 0; i < l->GetEntries(); i++) {
1073 auto obj = l->At(i);
1074 TString classNameObj = obj->ClassName();
1075 TString objectName = obj->GetName();
1076 Bool_t objNameSame = ((objName == objectName) || objName.Length() == 0);
1077 Bool_t classNameSame = (className == classNameObj || className.Length() == 0);
1078 if (objNameSame && classNameSame) { list.push_back(obj); }
1082 Bool_t CheckHistogramData(
const TH1& h1,
const TH1& h2, Double_t thres, Option_t* opt) {
1083 TString option = opt;
1084 Bool_t debug = Hal::Std::FindParam(option,
"print", kTRUE);
1085 Bool_t skiperr = Hal::Std::FindParam(option,
"skiperr", kTRUE);
1086 Bool_t relative = Hal::Std::FindParam(option,
"rel", kTRUE);
1087 if (!AreSimilar(&h1, &h2, kFALSE)) {
1088 if (debug) std::cout << __FILE__ << __LINE__ <<
" histograms are not similiar" << std::endl;
1091 auto compare = [&](
double x1,
double e1,
double x2,
double e2) {
1093 double relval = TMath::Abs((x1 - x2) / x1);
1094 if (relval > thres)
return kFALSE;
1096 if (TMath::Abs(x1 - x2) > thres)
return kFALSE;
1099 if (skiperr)
return kTRUE;
1101 double relval = TMath::Abs((e1 - e2) / e1);
1102 if (relval > thres)
return kFALSE;
1104 if (TMath::Abs(e1 - e2) > thres)
return kFALSE;
1108 if (
dynamic_cast<const TH3*
>(&h1)) {
1109 auto H1 =
static_cast<const TH3*
>(&h1);
1110 auto H2 =
static_cast<const TH3*
>(&h2);
1111 for (
int i = 1; i <= H1->GetNbinsX(); i++) {
1112 for (
int j = 1; j <= H1->GetNbinsY(); j++) {
1113 for (
int k = 1; k <= H1->GetNbinsZ(); k++) {
1114 bool compared = compare(
1115 H1->GetBinContent(i, j, k), H1->GetBinError(i, j, k), H2->GetBinContent(i, j, k), H2->GetBinError(i, j, k));
1117 if (debug) { std::cout <<
"Detected difference at bin " << i <<
" " << j <<
" " << k << std::endl; }
1123 }
else if (
dynamic_cast<const TH2*
>(&h1)) {
1124 auto H1 =
static_cast<const TH2*
>(&h1);
1125 auto H2 =
static_cast<const TH2*
>(&h2);
1126 for (
int i = 1; i <= H1->GetNbinsX(); i++) {
1127 for (
int j = 1; j <= H1->GetNbinsY(); j++) {
1129 compare(H1->GetBinContent(i, j), H1->GetBinError(i, j), H2->GetBinContent(i, j), H2->GetBinError(i, j));
1131 if (debug) { std::cout <<
"Detected difference at bin " << i <<
" " << j <<
" " << std::endl; }
1137 auto H1 =
static_cast<const TH1*
>(&h1);
1138 auto H2 =
static_cast<const TH1*
>(&h2);
1139 for (
int i = 1; i <= H1->GetNbinsX(); i++) {
1140 bool compared = compare(H1->GetBinContent(i), H1->GetBinError(i), H2->GetBinContent(i), H2->GetBinError(i));
1142 if (debug) { std::cout <<
"Detected difference at bin " << i <<
" " << std::endl; }
1149 void CopyHistProp(
const TH1& from, TH1& to, TString opt) {
1150 auto d3 =
static_cast<const TH3*
>(&from);
1152 CopyAxisProp(from.GetXaxis(), to.GetXaxis(), opt);
1153 CopyAxisProp(from.GetYaxis(), to.GetYaxis(), opt);
1154 if (d3) CopyAxisProp(from.GetZaxis(), to.GetZaxis(), opt);
1155 to.SetMarkerSize(from.GetMarkerSize());
1156 to.SetMarkerStyle(from.GetMarkerStyle());
1157 to.SetMarkerColor(from.GetMarkerColor());
1158 to.SetLineStyle(from.GetLineStyle());
1159 to.SetLineWidth(from.GetLineWidth());
1160 to.SetLineColor(from.GetLineColor());
1161 to.SetFillColor(from.GetFillColor());
1162 to.SetFillStyle(from.GetFillStyle());
static void PrintInfo(TString text, Hal::EInfo status)
Double_t Eval(Double_t x, Double_t y) const
Double_t GetError(Double_t x, Double_t y) const