20 #include <TKDTreeBinning.h> 25 #include <TPaveStats.h> 30 inline TH1 *
getPull(TH1 *Histogram1, TH1 *Histogram2, TString Name =
"pull_") {
31 if (Histogram1->GetNbinsX() != Histogram2->GetNbinsX() ||
32 Histogram1->GetNbinsY() != Histogram2->GetNbinsY() ||
33 Histogram1->GetNbinsZ() != Histogram2->GetNbinsZ()) {
34 std::cout <<
"binning doesn't match" << std::endl;
37 TH1 *PullHistogram = (TH1 *)Histogram1->Clone(Name + Histogram1->GetName());
38 PullHistogram->Reset();
40 for (
int i = 1; i <= Histogram1->GetNbinsX(); ++i) {
41 for (
int j = 1; j <= Histogram1->GetNbinsY(); ++j) {
42 for (
int k = 1; k <= Histogram1->GetNbinsZ(); ++k) {
43 unsigned int bin = Histogram1->GetBin(i, j, k);
44 double c1 = Histogram1->GetBinContent(bin);
45 double c2 = Histogram2->GetBinContent(bin);
46 double c1Err = Histogram1->GetBinError(bin);
47 double c2Err = Histogram2->GetBinError(bin);
49 if (c1 > 0 && c2 > 0) {
50 Pull = (c1 - c2) / sqrt(c1Err * c1Err + c2Err * c2Err);
51 PullHistogram->SetBinContent(bin, Pull);
52 if (std::fabs(Pull) > PullLimit)
53 PullLimit = std::abs(Pull);
55 PullHistogram->SetBinContent(
58 PullHistogram->SetBinError(bin, .0001);
65 PullHistogram->GetXaxis()->SetTitleSize(.14);
66 PullHistogram->GetXaxis()->SetTitleOffset(.93);
67 PullHistogram->GetXaxis()->SetLabelSize(.12);
68 if (PullHistogram->GetDimension() == 1) {
69 PullHistogram->GetYaxis()->SetRangeUser(-PullLimit, PullLimit);
70 PullHistogram->GetYaxis()->SetTitle(
"deviation [#sigma]");
71 PullHistogram->GetYaxis()->SetTitleOffset(0.36);
72 PullHistogram->GetYaxis()->SetTitleSize(0.12);
73 PullHistogram->GetYaxis()->SetLabelSize(0.12);
74 PullHistogram->GetYaxis()->SetNdivisions(504);
75 PullHistogram->GetYaxis()->CenterTitle();
77 if (PullHistogram->GetDimension() ==
79 PullHistogram->GetZaxis()->SetRangeUser(-PullLimit, PullLimit);
80 PullHistogram->GetZaxis()->SetTitle(
"deviation [#sigma]");
81 PullHistogram->GetYaxis()->SetTitleSize(.14);
82 PullHistogram->GetYaxis()->SetTitleOffset(.93);
83 PullHistogram->GetYaxis()->SetLabelSize(.12);
85 PullHistogram->SetTitle(
"");
86 PullHistogram->SetStats(0);
91 TString Name =
"res_") {
92 if (Histogram1->GetNbinsX() != Histogram2->GetNbinsX() ||
93 Histogram1->GetNbinsY() != Histogram2->GetNbinsY() ||
94 Histogram1->GetNbinsZ() != Histogram2->GetNbinsZ()) {
95 std::cout <<
"binning doesn't match" << std::endl;
98 TH1 *Residuals = (TH1 *)Histogram1->Clone(Name + Histogram1->GetName());
101 Histogram2->Scale(Histogram1->Integral() / Histogram2->Integral());
103 for (
int i = 1; i <= Histogram1->GetNbinsX(); ++i) {
104 for (
int j = 1; j <= Histogram1->GetNbinsY(); ++j) {
105 for (
int k = 1; k <= Histogram1->GetNbinsZ(); ++k) {
106 unsigned int Bin = Histogram1->GetBin(i, j, k);
107 double BinContent1 = Histogram1->GetBinContent(Bin);
108 double BinContent2 = Histogram2->GetBinContent(Bin);
109 if (BinContent1 == 0 && BinContent2 == 0) {
111 Residuals->SetBinContent(Bin, res);
113 double res = BinContent1 - BinContent2;
114 Residuals->SetBinContent(Bin, res);
115 if (std::fabs(res) > Limit)
116 Limit = std::abs(res);
118 Residuals->SetBinError(Bin, 0);
123 if (Residuals->GetDimension() == 1)
124 Residuals->GetYaxis()->SetRangeUser(
126 if (Residuals->GetDimension() == 2)
127 Residuals->GetZaxis()->SetRangeUser(
132 inline TPad *
drawHist(std::vector<TH1D *> Histograms,
133 std::vector<TString> DrawOption,
double Min = 0,
135 if (Histograms.size() != DrawOption.size())
136 throw std::runtime_error(
"drawPull() | Number of histograms and number " 137 "of draw options does not match!");
139 gStyle->SetOptTitle(0);
140 gStyle->SetOptStat(0);
142 TPad *Pad =
new TPad();
143 if (!Histograms.size())
145 for (
unsigned int i = 0; i < Histograms.size(); i++)
146 Histograms.at(i)->Draw(DrawOption.at(i));
150 inline TPad *
drawPull(std::vector<TH1D *> Histogram,
151 std::vector<TString> DrawOptions,
double Min = 0,
153 if (Histogram.size() != DrawOptions.size())
154 throw std::runtime_error(
"drawPull() | Number of histograms and number " 155 "of draw options does not match!");
157 if (!Histogram.size())
158 LOG(ERROR) <<
"drawPull() | No histograms given.";
160 Int_t OldOptTitle = gStyle->GetOptTitle();
161 Int_t OldOptStat = gStyle->GetOptStat();
162 gStyle->SetOptTitle(0);
163 gStyle->SetOptStat(0);
166 if (Histogram.size() == 1) {
168 Histogram.at(0)->Draw(DrawOptions.at(0));
170 Pad =
new TPad(
"hist",
"hist", 0.0, 0.3, 1, 1);
172 Pad->SetMargin(0.1, 0.05, 0.0, 0.05);
173 auto PullPad =
new TPad(
"pull",
"pull", 0.0, 0.0, 1, 0.3);
175 PullPad->SetMargin(0.1, 0.05, 0.3, 0.0);
177 if (Histogram.at(0)->GetDimension() != 1 ||
178 Histogram.at(1)->GetDimension() != 1) {
179 std::cout <<
"Dimension of histograms larger 1!" << std::endl;
182 if (Histogram.at(0)->GetNbinsX() != Histogram.at(1)->GetNbinsX()) {
183 std::cout <<
"binning doesn't match" << std::endl;
188 Histogram.at(0)->GetYaxis()->SetRangeUser(
189 0.00000001, Histogram.at(0)->GetMaximum() * 1.3);
190 Histogram.at(0)->GetYaxis()->SetTitleOffset(1.0);
191 Histogram.at(0)->GetYaxis()->SetTitleSize(0.05);
192 Histogram.at(0)->GetYaxis()->SetLabelSize(0.05);
194 Histogram.at(0)->Draw(DrawOptions.at(0));
195 Histogram.at(1)->Draw(DrawOptions.at(1));
196 for (
unsigned int i = 2; i < Histogram.size(); ++i)
197 Histogram.at(i)->Draw(DrawOptions.at(i));
200 Double_t Chi2Results[Histogram.at(0)->GetNbinsX()];
202 Histogram.at(0)->Chi2TestX(Histogram.at(1), chi2, NDF, IGood,
"UW",
206 sprintf(Chi2Char,
"#chi^{2}_{1D}/ndf = %.2f/%d", chi2, NDF);
211 TAxis *XAxis = ((TH1 *)Histogram.at(0))->GetXaxis();
212 Int_t NPoints = XAxis->GetNbins();
213 Double_t Points[NPoints];
214 for (Int_t i = 0; i < NPoints; i++)
215 Points[i] = XAxis->GetBinCenter(i + 1);
217 TGraph *PullGraph =
new TGraph(NPoints, Points, Chi2Results);
218 PullGraph->SetName(
"dataAdaptiveBinned");
222 PullGraph->Draw(
"AP");
223 PullGraph->SetTitle(
"Normalized residuals");
224 PullGraph->GetXaxis()->SetTitle(XAxis->GetTitle());
225 PullGraph->GetXaxis()->SetTitleOffset(0.8);
226 PullGraph->GetXaxis()->SetTitleSize(0.15);
227 PullGraph->GetXaxis()->SetLabelSize(0.10);
228 PullGraph->GetXaxis()->SetLimits(XAxis->GetBinLowEdge(1),
229 XAxis->GetBinLowEdge(NPoints + 1));
230 PullGraph->GetYaxis()->SetTitle(
"Dev. [#sigma]");
231 PullGraph->GetYaxis()->SetTitleOffset(0.4);
232 PullGraph->GetYaxis()->SetNdivisions(504);
234 PullGraph->GetYaxis()->SetRangeUser(Min, Max);
236 PullGraph->GetYaxis()->SetRangeUser(-5, 5.5);
237 PullGraph->GetYaxis()->SetTitleSize(0.10);
238 PullGraph->GetYaxis()->SetLabelSize(0.12);
239 PullGraph->GetYaxis()->CenterTitle(1);
241 TLine *Line =
new TLine(XAxis->GetBinLowEdge(1), 0.0,
242 XAxis->GetBinUpEdge(NPoints + 1), 0.0);
243 Line->SetLineStyle(2);
247 gStyle->SetOptTitle(OldOptTitle);
248 gStyle->SetOptTitle(OldOptStat);
253 inline TPad *
drawPull(TH1D *Histogram1, TH1D *Histogram2, TString DrawOption1,
254 TString DrawOption2,
double Min = 0,
double Max = 0) {
255 std::vector<TH1D *> Histograms;
256 Histograms.push_back(Histogram1);
257 Histograms.push_back(Histogram2);
258 std::vector<TString> DrawOptions;
259 DrawOptions.push_back(DrawOption1);
260 DrawOptions.push_back(DrawOption2);
261 return drawPull(Histograms, DrawOptions, Min, Max);
265 std::vector<TString> DrawOptions,
double Min = 0,
267 if (Histograms.size() != DrawOptions.size())
268 throw std::runtime_error(
"drawResidual() | Number of histograms and number " 269 "of draw options does not match!");
271 Int_t OldOptTitle = gStyle->GetOptTitle();
272 Int_t OldOptStat = gStyle->GetOptStat();
273 gStyle->SetOptTitle(0);
274 gStyle->SetOptStat(0);
277 if (Histograms.size() == 1) {
279 Histograms.at(0)->Draw(DrawOptions.at(0));
280 Histograms.at(0)->GetYaxis()->SetTitleSize(0.06);
281 }
else if (Histograms.size() == 2) {
282 Pad =
new TPad(
"hist",
"hist", 0.0, 0.3, 1, 1);
284 Pad->SetMargin(0.1, 0.05, 0.0, 0.05);
285 TPad *PullPad =
new TPad(
"pull",
"pull", 0.0, 0.0, 1, 0.3);
287 PullPad->SetMargin(0.1, 0.05, 0.3, 0.0);
289 if (Histograms.at(0)->GetDimension() != 1 ||
290 Histograms.at(1)->GetDimension() != 1) {
291 std::cout <<
"Dimension of histograms larger 1!" << std::endl;
294 if (Histograms.at(0)->GetNbinsX() != Histograms.at(1)->GetNbinsX()) {
295 std::cout <<
"binning doesn't match" << std::endl;
300 Histograms.at(0)->GetYaxis()->SetRangeUser(
301 0.00000001, Histograms.at(0)->GetMaximum() * 1.1);
302 Histograms.at(0)->GetYaxis()->SetTitleOffset(0.83);
304 Histograms.at(0)->Draw(DrawOptions.at(0));
305 Histograms.at(1)->Draw(DrawOptions.at(1));
306 Histograms.at(0)->GetYaxis()->SetTitleSize(0.06);
307 for (
unsigned int i = 2; i < Histograms.size(); ++i) {
308 Histograms.at(i)->Draw(DrawOptions.at(i));
312 Double_t Chi2Result[Histograms.at(0)->GetNbinsX()];
314 Histograms.at(0)->Chi2TestX(Histograms.at(1), Chi2, NDF, IGood,
"UW",
318 sprintf(Chi2Char,
"#chi^{2}_{1D}/ndf = %.2f/%d", Chi2, NDF);
320 TAxis *XAxis = ((TH1 *)Histograms.at(0))->GetXaxis();
321 Int_t NPoints = XAxis->GetNbins();
323 TH1D *Residuals = (TH1D *)Histograms.at(0)->Clone(
"resHist");
324 Residuals->Add(Histograms.at(1), -1);
326 Residuals->Draw(
"E");
327 Residuals->SetTitle(
"Residuals");
328 Residuals->GetXaxis()->SetTitle(XAxis->GetTitle());
329 Residuals->GetXaxis()->SetTitleOffset(0.8);
330 Residuals->GetXaxis()->SetTitleSize(0.15);
331 Residuals->GetXaxis()->SetLabelSize(0.10);
332 Residuals->GetXaxis()->SetLimits(XAxis->GetBinLowEdge(1),
333 XAxis->GetBinLowEdge(NPoints + 1));
334 Residuals->GetYaxis()->SetTitle(
"Deviation");
335 Residuals->GetYaxis()->SetTitleOffset(0.4);
336 Residuals->GetYaxis()->SetNdivisions(504);
338 Residuals->GetYaxis()->SetRangeUser(Min, Max);
339 Residuals->GetYaxis()->SetTitleSize(0.12);
340 Residuals->GetYaxis()->SetLabelSize(0.12);
341 Residuals->GetYaxis()->CenterTitle(1);
342 Residuals->SetMarkerStyle(20);
344 TLine *Line =
new TLine(XAxis->GetBinLowEdge(1), 0.0,
345 XAxis->GetBinUpEdge(NPoints + 1), 0.0);
346 Line->SetLineStyle(2);
350 gStyle->SetOptTitle(OldOptTitle);
351 gStyle->SetOptTitle(OldOptStat);
357 TString DrawOption1, TString DrawOption2,
358 double Min = 0,
double Max = 0) {
359 std::vector<TH1D *> Histograms;
360 Histograms.push_back(Histogram1);
361 Histograms.push_back(Histogram2);
362 std::vector<TString> DrawOptions;
363 DrawOptions.push_back(DrawOption1);
364 DrawOptions.push_back(DrawOption2);
369 double &Chi2,
int &NDF,
int &IGood) {
370 if (Histogram1->GetBins()->GetEntries() !=
371 Histogram2->GetBins()->GetEntries()) {
372 std::cout <<
"binning doesn't match" << std::endl;
377 for (
int Bin = 1; Bin <= Histogram1->GetBins()->GetEntries(); Bin++) {
378 double BinContent1 = Histogram1->GetBinContent(Bin);
379 double BinContent2 = Histogram2->GetBinContent(Bin);
380 double BinError1 = Histogram1->GetBinError(Bin);
381 double BinError2 = Histogram2->GetBinError(Bin);
382 if (BinContent1 > 0 || BinContent2 > 0) {
383 Chi2 += (BinContent1 - BinContent2) * (BinContent1 - BinContent2) /
384 (BinError1 * BinError1 + BinError2 * BinError2);
393 if (Histogram1->GetBins()->GetEntries() !=
394 Histogram2->GetBins()->GetEntries()) {
395 std::cout <<
"binning doesn't match" << std::endl;
399 (TH2Poly *)Histogram1->Clone(Name + Histogram1->GetName());
400 Residuals->Reset(
"");
402 Histogram2->Scale(Histogram1->Integral() / Histogram2->Integral());
406 for (
int bin = 1; bin <= Histogram1->GetBins()->GetEntries(); bin++) {
407 double BinContent1 = Histogram1->GetBinContent(bin);
408 double BinContent2 = Histogram2->GetBinContent(bin);
409 double BinError1 = Histogram1->GetBinError(bin);
410 double BinError2 = Histogram2->GetBinError(bin);
411 if (BinContent1 > 0 && BinContent2 > 0) {
412 double Pull = (BinContent1 - BinContent2) /
413 sqrt(BinError1 * BinError1 + BinError2 * BinError2);
416 Residuals->SetBinContent(bin, Pull);
417 if (std::fabs(Pull) > Limit)
418 Limit = std::abs(Pull);
420 Residuals->SetBinContent(bin, -999);
421 Residuals->SetBinError(bin, 0);
425 Residuals->GetZaxis()->SetRangeUser(
427 Residuals->GetZaxis()->SetTitle(
"deviation [#sigma]");
428 Residuals->GetZaxis()->SetTitleOffset(0.5);
429 std::cout <<
"Creating pull histogram for TH2Poly! integral=" << Integral
430 <<
" nBins=" << NBins << std::endl;
436 Double_t *Data, UInt_t NBins = 100) {
438 UInt_t(DataSize / NBins) * NBins;
440 TH2Poly *Histogram =
new TH2Poly();
441 Histogram->AddBin(0, 1, 0, 1);
445 TKDTreeBinning KDBins(Size, DataDimension, Data, NBins);
447 UInt_t NKDBins = KDBins.GetNBins();
448 UInt_t Dimension = KDBins.GetDim();
450 const Double_t *binsMinEdges = KDBins.GetBinsMinEdges();
451 const Double_t *binsMaxEdges = KDBins.GetBinsMaxEdges();
453 TH2Poly *Histogram =
new TH2Poly(
"h2PolyBinTest",
"", KDBins.GetDataMin(0),
454 KDBins.GetDataMax(0), KDBins.GetDataMin(1),
455 KDBins.GetDataMax(1));
457 for (UInt_t i = 0; i < NKDBins; ++i) {
458 UInt_t EdgeDim = i * Dimension;
459 Histogram->AddBin(binsMinEdges[EdgeDim], binsMinEdges[EdgeDim + 1],
460 binsMaxEdges[EdgeDim], binsMaxEdges[EdgeDim + 1]);