MaCh3 2.2.1
Reference Guide
Loading...
Searching...
No Matches
PlotMCMCDiag.cpp
Go to the documentation of this file.
1// MaCh3 includes
4#include "THStack.h"
5#include "TGraphAsymmErrors.h"
6#include "TLegend.h"
7#include <TSystem.h>
8
13
14TString DUMMYFILE = "DummyFile";
15TString DUMMYNAME = "DummyName";
16
17// Utilities
18
20double GetMinimumInRange(TH1D *hist, double minRange, double maxRange)
21{
22 double MinVale = 1234567890.;
23 TAxis *xaxis = hist->GetXaxis();
24 for (int x = 1; x <= hist->GetNbinsX(); x++)
25 {
26 if (xaxis->GetBinLowEdge(x) > minRange && xaxis->GetBinUpEdge(x) < maxRange)
27 {
28 if (MinVale > hist->GetBinContent(x))
29 MinVale = hist->GetBinContent(x);
30 }
31 }
32 return MinVale;
33}
34
36// Utility functions
37bool IsHistogramAllOnes(TH1D *hist, double tolerance = 0.001, int max_failures = 100)
38{
39 int failure_count = 0;
40
41 for (int bin = 2; bin <= hist->GetNbinsX(); ++bin)
42 {
43 if (fabs(hist->GetBinContent(bin) - 1.0) > tolerance)
44 {
45 if (++failure_count > max_failures)
46 {
47 return false;
48 }
49 }
50 }
51 return true;
52}
53
54void MakePlot(TString fname1, TString flabel1, TString fname2, TString flabel2, TString fname3, TString flabel3, TString fname4, TString flabel4)
55{
56 TCanvas *c1 = new TCanvas("c1", " ", 0, 0, 800, 630);
57 gStyle->SetOptStat(0); // Set 0 to disable statistic box
58 // To avoid TCanvas::Print> messages
59 gErrorIgnoreLevel = kWarning;
60
61 TKey *key;
62 TFile *infile = TFile::Open(fname1.Data());
63
64 bool add_legend = false;
65
66 TFile *infile2 = NULL;
67 if (fname2 != DUMMYFILE)
68 {
69 infile2 = TFile::Open(fname2.Data());
70 add_legend = true;
71 }
72 TFile *infile3 = NULL;
73 if (fname3 != DUMMYFILE)
74 {
75 infile3 = TFile::Open(fname3.Data());
76 add_legend = true;
77 }
78 TFile *infile4 = NULL;
79 if (fname4 != DUMMYFILE)
80 {
81 infile4 = TFile::Open(fname4.Data());
82 add_legend = true;
83 }
84
85 TIter next(infile->GetListOfKeys());
86 while ((key = static_cast<TKey *>(next())))
87 {
88 std::string dirname = std::string(key->GetName());
89 if (std::string(key->GetClassName()) != "TDirectoryFile")
90 continue;
91 // KS: Script will work with LogL and Batched_means, you can comment it if you are interested in it
92 if ((dirname == "LogL") || (dirname == "Batched_means"))
93 continue;
94 // KS: Trace wo longer chains is super big, the way to avoid is to plot as png but I don't like png,
95 // keep possibility to skip it
96 // if( (dirname == "Trace") ) continue;
97 infile->cd(dirname.c_str());
98 TIter nextsub(gDirectory->GetListOfKeys());
99 c1->Print(Form("%s.pdf[", dirname.c_str()), "pdf");
100 TKey *subkey;
101 while ((subkey = static_cast<TKey *>(nextsub())))
102 {
103
104 TLegend *leg = new TLegend(0.7, 0.7, 0.9, 0.9);
105 leg->SetFillColorAlpha(kWhite, float(0.7));
106 std::string name = std::string(subkey->GetName());
107 name = dirname + "/" + name;
108 MACH3LOG_INFO("{}", name);
109 if (std::string(subkey->GetClassName()) != "TH1D")
110 {
111 continue;
112 }
113 else
114 {
115 MACH3LOG_WARN("continuing along my way for {}", dirname);
116 }
117
118 TH1D *blarb[4];
119 MACH3LOG_INFO("Looking for {} from file {}", name.c_str(), fname1.Data());
120 blarb[0] = static_cast<TH1D *>(infile->Get(name.c_str())->Clone());
121 // KS: Some fixe params can go crazy
122 if (TMath::IsNaN(blarb[0]->GetBinContent(1)))
123 continue;
124
125 RemoveFitter(blarb[0], "Fitter");
126 blarb[0]->SetLineStyle(kSolid);
127 blarb[0]->SetLineColor(kRed);
128 blarb[0]->Draw();
129
130 leg->AddEntry(blarb[0], flabel1.Data(), "l");
131
132 if (dirname == "AccProb")
133 blarb[0]->GetYaxis()->SetRangeUser(0, 1.0);
134 if (name == "AccProb/AcceptanceProbability")
135 continue;
136 if (infile2 != NULL)
137 {
138 blarb[1] = static_cast<TH1D *>(infile2->Get(name.c_str())->Clone());
139 RemoveFitter(blarb[1], "Fitter");
140 blarb[1]->SetLineStyle(kDashed);
141 blarb[1]->SetLineColor(kBlue);
142 blarb[1]->Draw("same");
143 leg->AddEntry(blarb[1], flabel2.Data(), "l");
144 }
145 if (infile3 != NULL)
146 {
147 blarb[2] = static_cast<TH1D *>(infile3->Get(name.c_str())->Clone());
148 RemoveFitter(blarb[2], "Fitter");
149 blarb[2]->SetLineStyle(kDotted);
150 blarb[2]->SetLineColor(kGreen);
151 blarb[2]->Draw("same");
152 leg->AddEntry(blarb[2], flabel3.Data(), "l");
153 }
154 if (infile4 != NULL)
155 {
156 blarb[3] = static_cast<TH1D *>(infile4->Get(name.c_str())->Clone());
157 RemoveFitter(blarb[3], "Fitter");
158 blarb[3]->SetLineStyle(kDashDotted);
159 blarb[3]->SetLineColor(kOrange);
160 blarb[3]->Draw("same");
161 leg->AddEntry(blarb[3], flabel4.Data(), "l");
162 }
163 if (add_legend)
164 {
165 leg->Draw();
166 }
167
168 c1->Print(Form("%s.pdf", dirname.c_str()), "pdf");
169 delete leg;
170 }
171 gDirectory->cd("..");
172 c1->Print(Form("%s.pdf]", dirname.c_str()), "pdf");
173 }
174
175 infile->Close();
176 if (infile2 != NULL)
177 infile2->Close();
178 if (infile3 != NULL)
179 infile3->Close();
180 if (infile4 != NULL)
181 infile4->Close();
182}
183
184void PlotAutoCorr(TString fname1, TString flabel1, TString fname2, TString flabel2, TString fname3, TString flabel3, TString fname4, TString flabel4)
185{
186 TString fname[4];
187 fname[0] = fname1;
188 fname[1] = fname2;
189 fname[2] = fname3;
190 fname[3] = fname4;
191 // Color_t PlotColor[4]={kRed, kBlue, kGreen, kOrange};
192 std::vector<TString> flabel = {flabel1, flabel2, flabel3, flabel4};
193
194 TFile *infile[4];
195 infile[0] = TFile::Open(fname[0].Data());
196 // KS" We need to check number of files to loop over in very lazy way
197 int Nfiles = 1;
198
199 if (fname[1] != DUMMYFILE)
200 {
201 infile[1] = TFile::Open(fname[1].Data());
202 Nfiles++;
203 }
204 if (fname[2] != DUMMYFILE)
205 {
206 infile[2] = TFile::Open(fname[2].Data());
207 Nfiles++;
208 }
209 if (fname[3] != DUMMYFILE)
210 {
211 infile[3] = TFile::Open(fname[3].Data());
212 Nfiles++;
213 }
214
215 TCanvas *c1 = new TCanvas("c1", " ", 0, 0, 800, 630);
216 gStyle->SetOptStat(0); // Set 0 to disable statistic box
217 // To avoid TCanvas::Print> messages
218 gErrorIgnoreLevel = kWarning;
219
220 c1->Print("Auto_Corr_PerFile.pdf[", "pdf");
221 for (int ik = 0; ik < Nfiles; ik++)
222 {
223 TIter next(infile[ik]->GetListOfKeys());
224
225 TKey *key;
226 TLegend *leg = new TLegend(0.7, 0.7, 0.9, 0.9);
227
228 while ((key = static_cast<TKey *>(next())))
229 {
230 std::string dirname = std::string(key->GetName());
231
232 // KS: Script We are only interested in auto corr
233 if ((dirname != "Auto_corr"))
234 continue;
235
236 infile[ik]->cd(dirname.c_str());
237 TIter nextsub(gDirectory->GetListOfKeys());
238
239 TKey *subkey;
240 bool FirstTime = true;
241
242 while ((subkey = static_cast<TKey *>(nextsub())))
243 {
244 std::string name = std::string(subkey->GetName());
245 name = dirname + "/" + name;
246
247 if (std::string(subkey->GetClassName()) != "TH1D")
248 continue;
249 MACH3LOG_DEBUG("{}", name.c_str());
250 TH1D *blarb = static_cast<TH1D *>(infile[ik]->Get(name.c_str())->Clone());
251 // KS: Some fixe pramas can go crazy
252 if (TMath::IsNaN(blarb->GetBinContent(1)))
253 continue;
254 // KS: This is unfortunately hardcoded, need to find better way to write this
255 // blarb[0]->GetListOfFunctions()->ls();
256 delete blarb->GetListOfFunctions()->FindObject("Fitter");
257
258 double MinValue = GetMinimumInRange(blarb, 0, 24000);
259
260 if (MinValue >= 0.80)
261 blarb->SetLineColor(kRed);
262 else if (MinValue >= 0.40 && MinValue < 0.80)
263 blarb->SetLineColor(kOrange);
264 else if (MinValue > 0.20 && MinValue < 0.40)
265 blarb->SetLineColor(kYellow);
266 else if (MinValue <= 0.20)
267 blarb->SetLineColor(kGreen);
268 blarb->GetXaxis()->UnZoom();
269
270 if (FirstTime)
271 blarb->SetTitle(Form("Auto_Corr_%s.pdf", fname[ik].Data()));
272
273 blarb->SetLineStyle(kDashed);
274
275 if (FirstTime)
276 blarb->Draw();
277
278 TString integral = Form("Integral: %.2f", blarb->Integral());
279
280 if (!FirstTime)
281 blarb->Draw("same");
282 FirstTime = false;
283 }
284 gDirectory->cd("..");
285 }
286
287 if (Nfiles > 1)
288 {
289 leg->Draw();
290 }
291 c1->Print("Auto_Corr_PerFile.pdf", "pdf");
292 delete leg;
293 }
294 c1->Print("Auto_Corr_PerFile.pdf]", "pdf");
295}
296
297// HW: Utilities for average Auto Correlation plots
298
300std::pair<TGraph *, TGraph *> CreateMinMaxBand(TH1D *hist, Color_t color)
301{
302 int nBins = hist->GetNbinsX();
303 std::vector<double> x(nBins), ymin(nBins), ymax(nBins);
304
305 for (int i = 0; i < nBins; ++i)
306 {
307 x[i] = hist->GetBinCenter(i + 1);
308 ymin[i] = hist->GetBinContent(i + 1);
309 ymax[i] = hist->GetBinContent(i + 1);
310 }
311
312 TGraph *minGraph = new TGraph(nBins, x.data(), ymin.data());
313 TGraph *maxGraph = new TGraph(nBins, x.data(), ymax.data());
314
315 minGraph->SetLineColor(color);
316 maxGraph->SetLineColor(color);
317 minGraph->SetFillColorAlpha(color, float(0.3));
318 maxGraph->SetFillColorAlpha(color, float(0.3));
319
320 return {minGraph, maxGraph};
321}
322
323TGraph *CalculateMinMaxBand(const std::vector<TH1D *> &histograms, Color_t color)
324{
325 if (histograms.empty())
326 {
327 throw std::invalid_argument("Empty histogram vector provided");
328 }
329
330 int nBins = histograms[0]->GetNbinsX();
331 std::vector<double> x(nBins), ymin(nBins, 1e10), ymax(nBins, -1e10);
332
333 for (int bin = 0; bin < nBins; bin++)
334 {
335 x[bin] = histograms[0]->GetBinCenter(bin + 1);
336
337 for (const auto &hist : histograms)
338 {
339 double content = hist->GetBinContent(bin + 1);
340 ymin[bin] = std::min(ymin[bin], content);
341 ymax[bin] = std::max(ymax[bin], content);
342 }
343 }
344
345 // Create a band using TGraphAsymmErrors for the shaded region
346 TGraphAsymmErrors *band = new TGraphAsymmErrors(nBins);
347 for (int i = 0; i < nBins; ++i)
348 {
349 band->SetPoint(i, x[i], (ymax[i] + ymin[i]) / 2.0);
350 band->SetPointError(i, 0, 0, (ymax[i] - ymin[i]) / 2.0, (ymax[i] - ymin[i]) / 2.0);
351 }
352
353 band->SetFillColorAlpha(color, float(0.2));
354 band->SetLineWidth(1);
355
356 return band; // Return band and min graph (min graph can be used for legend)
357}
358
359std::pair<TH1D *, TH1D *> CalculateMinMaxHistograms(const std::vector<TH1D *> &histograms)
360{
361 if (histograms.empty())
362 {
363 throw std::invalid_argument("Empty histogram vector provided");
364 }
365
366 TH1D *min_hist = static_cast<TH1D *>(histograms[0]->Clone());
367 TH1D *max_hist = static_cast<TH1D *>(histograms[0]->Clone());
368
369 for (const auto &hist : histograms)
370 {
371 for (int bin = 1; bin <= min_hist->GetNbinsX(); ++bin)
372 {
373 double current_min = min_hist->GetBinContent(bin);
374 double current_max = max_hist->GetBinContent(bin);
375 double bin_content = hist->GetBinContent(bin);
376
377 min_hist->SetBinContent(bin, std::min(current_min, bin_content));
378 max_hist->SetBinContent(bin, std::max(current_max, bin_content));
379 }
380 }
381
382 return {min_hist, max_hist};
383}
384
385// File processing functions
386void ProcessAutoCorrelationDirectory(TDirectoryFile *autocor_dir,
387 TH1D *&average_hist,
388 int &parameter_count,
389 std::vector<TH1D *> &histograms)
390{
391 TIter next(autocor_dir->GetListOfKeys());
392 TKey *key;
393
394 while ((key = dynamic_cast<TKey *>(next())))
395 {
396 TH1D *current_hist = nullptr;
397 autocor_dir->GetObject(key->GetName(), current_hist);
398
399 if (!current_hist ||
400 current_hist->GetMaximum() <= 0 ||
401 IsHistogramAllOnes(current_hist))
402 {
403 continue;
404 }
405
406 current_hist->SetDirectory(nullptr); // Detach from file
407 histograms.push_back(current_hist);
408
409 if (!average_hist)
410 {
411 average_hist = static_cast<TH1D *>(current_hist->Clone());
412 average_hist->SetDirectory(nullptr);
413 }
414 else
415 {
416 average_hist->Add(current_hist);
417 }
418 parameter_count++;
419 }
420}
421
422void ProcessDiagnosticFile(const TString &file_path,
423 TH1D *&average_hist,
424 int &parameter_count,
425 std::vector<TH1D *> &histograms)
426{
427 std::unique_ptr<TFile> input_file(TFile::Open(file_path));
428 if (!input_file || input_file->IsZombie())
429 {
430 throw std::runtime_error("Could not open file: " + std::string(file_path.Data()));
431 }
432
433 TDirectoryFile *autocor_dir = nullptr;
434 input_file->GetObject("Auto_corr", autocor_dir);
435
436 if (!autocor_dir)
437 {
438 throw MaCh3Exception(__FILE__, __LINE__,
439 "Auto_corr directory not found in file: " + std::string(file_path.Data()));
440 }
441
442 ProcessAutoCorrelationDirectory(autocor_dir, average_hist, parameter_count, histograms);
443}
444
445TH1D *AutocorrProcessInputs(const TString &input_file, std::vector<TH1D *> &histograms)
446{
447
448 TH1D *average_hist = nullptr;
449 int parameter_count = 0;
450
451 try
452 {
453 ProcessDiagnosticFile(input_file, average_hist, parameter_count, histograms);
454 }
455 catch (const std::exception &e)
456 {
457 MACH3LOG_ERROR("Error processing file {} : {}", input_file, e.what());
458 }
459
460 if (average_hist && parameter_count > 0)
461 {
462 MACH3LOG_INFO("Processed {} parameters from {} files", parameter_count, input_file);
463 average_hist->Scale(1.0 / parameter_count);
464 }
465
466 return average_hist;
467}
468
469void CompareAverageAC(const std::vector<std::vector<TH1D *>> &histograms,
470 const std::vector<TH1D *> &averages,
471 const std::vector<TString> &hist_labels,
472 const TString &output_name,
473 bool draw_min_max = true,
474 bool draw_all = false,
475 bool draw_errors = true)
476{
477 TCanvas *canvas = new TCanvas("AverageAC", "Average Auto Correlation", 800, 600);
478 canvas->SetGrid();
479
480 // Setup colour palette
481 Int_t nb = 255.0;
482 Double_t stops[8] = {0.0, 0.25, 0.5, 0.75};
483 Double_t red[8] = {0.83203125, 0.796875, 0.0, 0.9375};
484 Double_t green[8] = {0.3671875, 0.47265625, 0.4453125, 0.890625};
485 Double_t blue[8] = {0.0, 0.65234375, 0.6953125, 0.2578125};
486 TColor::CreateGradientColorTable(8, stops, red, green, blue, nb);
487
488 TLegend *leg = new TLegend(0.5, 0.7, 0.9, 0.9);
489 leg->SetFillColorAlpha(kWhite, float(0.7));
490
491 if (draw_min_max)
492 {
493 for (size_t i = 0; i < histograms.size(); ++i)
494 {
495 auto colour = static_cast<Color_t>(TColor::GetColorPalette(static_cast<Int_t>(i * nb / histograms.size())));
496
497 {
498 auto band = CalculateMinMaxBand(histograms[i], colour);
499 band->SetLineWidth(0);
500 band->SetTitle("Average Auto Correlation");
501 band->GetXaxis()->SetTitle("lag");
502 band->GetYaxis()->SetTitle("Autocorrelation Function");
503 if (i == 0)
504 {
505 band->Draw("A3");
506 }
507 else
508 {
509 band->Draw("3 SAME");
510 }
511 }
512 }
513 }
514
515 for (size_t i = 0; i < averages.size(); ++i)
516 {
517 auto colour = static_cast<Color_t>(TColor::GetColorPalette(static_cast<Int_t>(i * nb / histograms.size())));
518
519 if (draw_errors)
520 {
521 auto error_hist = static_cast<TH1D *>(averages[i]->Clone());
522 error_hist->SetFillColorAlpha(colour, float(0.3));
523 error_hist->SetLineWidth(0);
524 error_hist->SetTitle("Average Auto Correlation");
525 error_hist->GetXaxis()->SetTitle("lag");
526 error_hist->GetYaxis()->SetTitle("Autocorrelation Function");
527 error_hist->Draw("E3 SAME");
528 }
529 if (draw_all)
530 {
531 for (const auto &hist : histograms[i])
532 {
533 hist->SetLineColorAlpha(colour, float(0.05));
534 hist->SetLineWidth(1);
535 hist->Draw("HIST SAME");
536 }
537 }
538
539 averages[i]->SetLineColor(colour);
540 averages[i]->SetLineWidth(2);
541 averages[i]->SetTitle("Average Auto Correlation");
542 averages[i]->GetXaxis()->SetTitle("lag");
543 averages[i]->GetYaxis()->SetTitle("Autocorrelation Function");
544 averages[i]->Draw("HIST SAME");
545
546 TString int_str = TString::Format("Average integrated autocorrelation %f", averages[i]->Integral());
547
548 leg->AddEntry(averages[i], hist_labels[i] + int_str, "l");
549 }
550
551 if (averages.size() > 1)
552 {
553 leg->Draw();
554 }
555
556 canvas->SaveAs(output_name + ".pdf");
557 delete canvas;
558}
559
560void PlotAverageACMult(std::vector<TString> input_files,
561 std::vector<TString> hist_labels,
562 const TString &output_name,
563 bool draw_min_max = true)
564// bool draw_all = false,
565// bool draw_errors = true)
566{
567 // Process first folder
568 std::vector<std::vector<TH1D *>> histograms;
569 std::vector<TH1D *> averages;
570
571 for (int i = 0; i < static_cast<int>(input_files.size()); i++)
572 {
573 TString folder = input_files[i];
574 MACH3LOG_INFO("Folder : {}", folder);
575
576 if (folder.IsNull() || folder == DUMMYFILE)
577 {
578 MACH3LOG_WARN("Skipping empty or dummy folder: {}", folder.Data());
579 continue;
580 }
581
582 std::vector<TH1D *> histograms_i;
583 averages.push_back((AutocorrProcessInputs(folder, histograms_i)));
584 histograms.push_back(histograms_i);
585 }
586
587 CompareAverageAC(histograms, averages, hist_labels, output_name, draw_min_max); // draw_all, draw_errors);
588}
589
590int main(int argc, char *argv[])
591{
593 if (argc != 3 && argc != 5 && argc != 7 && argc != 9)
594 {
595 MACH3LOG_ERROR("Wrong number of arguments ({}) provided", argc);
596 MACH3LOG_ERROR("How to use: {} DiagMCMC_Output.root Plot Name", argv[0]);
597 MACH3LOG_ERROR("Up to 4 files");
598 throw MaCh3Exception(__FILE__, __LINE__);
599 }
600
601 if (argc == 3)
602 {
605 PlotAverageACMult({argv[1]}, {argv[2]}, "Average_Auto_Corr", true);
606 }
607 else if (argc == 5)
608 {
609 MakePlot(argv[1], argv[2], argv[3], argv[4], DUMMYFILE, DUMMYNAME, DUMMYFILE, DUMMYNAME);
610 PlotAutoCorr(argv[1], argv[2], argv[3], argv[4], DUMMYFILE, DUMMYNAME, DUMMYFILE, DUMMYNAME);
611 PlotAverageACMult({argv[1], argv[3]}, {argv[2], argv[4]}, "Average_Auto_Corr", true);
612 }
613 else if (argc == 7)
614 {
615 MakePlot(argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], DUMMYFILE, DUMMYNAME);
616 PlotAutoCorr(argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], DUMMYFILE, DUMMYNAME);
617 PlotAverageACMult({argv[1], argv[3], argv[5]}, {argv[2], argv[4], argv[6]}, "Average_Auto_Corr", true);
618 }
619 else if (argc == 9)
620 {
621 MakePlot(argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8]);
622 PlotAutoCorr(argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], argv[8]);
623 PlotAverageACMult({argv[1], argv[3], argv[5], argv[7]}, {argv[2], argv[4], argv[6], argv[8]}, "Average_Auto_Corr", true);
624 }
625 return 0;
626}
void RemoveFitter(TH1D *hist, const std::string &name)
KS: Remove fitted TF1 from hist to make comparison easier.
#define MACH3LOG_DEBUG
Definition: MaCh3Logger.h:22
#define MACH3LOG_ERROR
Definition: MaCh3Logger.h:25
#define MACH3LOG_INFO
Definition: MaCh3Logger.h:23
void SetMaCh3LoggerFormat()
Set messaging format of the logger.
Definition: MaCh3Logger.h:30
#define MACH3LOG_WARN
Definition: MaCh3Logger.h:24
int main(int argc, char *argv[])
bool IsHistogramAllOnes(TH1D *hist, double tolerance=0.001, int max_failures=100)
HW: Check if histogram is flat within a given tolerance.
void ProcessAutoCorrelationDirectory(TDirectoryFile *autocor_dir, TH1D *&average_hist, int &parameter_count, std::vector< TH1D * > &histograms)
double GetMinimumInRange(TH1D *hist, double minRange, double maxRange)
KS: function which looks for minimum in given range.
void MakePlot(TString fname1, TString flabel1, TString fname2, TString flabel2, TString fname3, TString flabel3, TString fname4, TString flabel4)
std::pair< TH1D *, TH1D * > CalculateMinMaxHistograms(const std::vector< TH1D * > &histograms)
TString DUMMYNAME
void PlotAverageACMult(std::vector< TString > input_files, std::vector< TString > hist_labels, const TString &output_name, bool draw_min_max=true)
void CompareAverageAC(const std::vector< std::vector< TH1D * > > &histograms, const std::vector< TH1D * > &averages, const std::vector< TString > &hist_labels, const TString &output_name, bool draw_min_max=true, bool draw_all=false, bool draw_errors=true)
std::pair< TGraph *, TGraph * > CreateMinMaxBand(TH1D *hist, Color_t color)
HW: Create a band of minimum and maximum values from a histogram.
TGraph * CalculateMinMaxBand(const std::vector< TH1D * > &histograms, Color_t color)
void PlotAutoCorr(TString fname1, TString flabel1, TString fname2, TString flabel2, TString fname3, TString flabel3, TString fname4, TString flabel4)
TH1D * AutocorrProcessInputs(const TString &input_file, std::vector< TH1D * > &histograms)
void ProcessDiagnosticFile(const TString &file_path, TH1D *&average_hist, int &parameter_count, std::vector< TH1D * > &histograms)
TString DUMMYFILE
Custom exception class for MaCh3 errors.