7 #include "TGraphAsymmErrors.h"
25 double MinVale = 1234567890.;
26 TAxis *xaxis = hist->GetXaxis();
27 for (
int x = 1; x <= hist->GetNbinsX(); x++)
29 if (xaxis->GetBinLowEdge(x) > minRange && xaxis->GetBinUpEdge(x) < maxRange)
31 if (MinVale > hist->GetBinContent(x))
32 MinVale = hist->GetBinContent(x);
41 int failure_count = 0;
43 for (
int bin = 2; bin <= hist->GetNbinsX(); ++bin)
45 if (std::fabs(hist->GetBinContent(bin) - 1.0) > tolerance)
47 if (++failure_count > max_failures)
58 std::vector<TString> hist_labels)
60 auto c1 = std::make_unique<TCanvas>(
"c1",
" ", 0, 0, 800, 630);
61 gStyle->SetOptStat(0);
63 gErrorIgnoreLevel = kWarning;
66 std::vector<TFile*> infiles;
67 bool add_legend =
false;
69 for (
const auto& fname : input_files)
71 TFile* f =
M3::Open(fname.Data(),
"UPDATE", __FILE__, __LINE__);
74 add_legend = (input_files.size() > 1);
77 constexpr
int NFiles_hard = 4;
78 constexpr Color_t Colour[NFiles_hard] = {kRed, kBlue, kGreen, kOrange};
79 constexpr Style_t
Style[NFiles_hard] = {kSolid, kDashed, kDotted, kDashDotted};
80 if(input_files.size() > NFiles_hard){
81 MACH3LOG_ERROR(
"Passed {}, while I have nasty hardcoding for max {} filse", input_files.size(), NFiles_hard);
84 TIter next(infiles[0]->GetListOfKeys());
85 while ((key =
static_cast<TKey *
>(next())))
87 std::string dirname = std::string(key->GetName());
88 if (std::string(key->GetClassName()) !=
"TDirectoryFile")
91 if ((dirname ==
"LogL") || (dirname ==
"Batched_means") || (dirname ==
"PowerSpectrum"))
96 infiles[0]->cd(dirname.c_str());
97 TIter nextsub(gDirectory->GetListOfKeys());
98 c1->Print(Form(
"%s_%s.pdf[", hist_labels[0].Data(), dirname.c_str()),
"pdf");
100 while ((subkey =
static_cast<TKey *
>(nextsub())))
102 auto leg = std::make_unique<TLegend>(0.7, 0.7, 0.9, 0.9);
103 leg->SetFillColorAlpha(kWhite, 0.7f);
104 std::string name = std::string(subkey->GetName());
105 name = dirname +
"/" + name;
107 if (std::string(subkey->GetClassName()) !=
"TH1D") {
112 if (name ==
"AccProb/AcceptanceProbability")
continue;
114 std::vector<std::unique_ptr<TH1D>> blarb(infiles.size());
115 MACH3LOG_INFO(
"Looking for {} from file {}", name.c_str(), input_files[0].Data());
116 blarb[0] =
M3::Clone(
static_cast<TH1D *
>(infiles[0]->
Get(name.c_str())));
118 if (std::isnan(blarb[0]->GetBinContent(1)))
122 if (dirname ==
"AccProb")
123 blarb[0]->GetYaxis()->SetRangeUser(0, 1.0);
125 blarb[0]->SetLineStyle(
Style[0]);
126 blarb[0]->SetLineColor(Colour[0]);
128 leg->AddEntry(blarb[0].get(), hist_labels[0].Data(),
"l");
130 for (
size_t i = 1; i < infiles.size(); ++i)
132 blarb[i] =
M3::Clone(
static_cast<TH1D *
>(infiles[i]->
Get(name.c_str())));
134 blarb[i]->SetLineStyle(
Style[i]);
135 blarb[i]->SetLineColor(Colour[i]);
137 blarb[i]->Draw(i == 0 ?
"" :
"same");
138 leg->AddEntry(blarb[i].get(), hist_labels[i].Data(),
"l");
144 c1->Print(Form(
"%s_%s.pdf", hist_labels[0].Data(), dirname.c_str()),
"pdf");
146 gDirectory->cd(
"..");
147 c1->Print(Form(
"%s_%s.pdf]", hist_labels[0].Data(), dirname.c_str()),
"pdf");
150 for (
size_t i = 0; i < infiles.size(); ++i)
160 std::vector<TFile*> infile(fname.size());
162 for(
size_t i = 0; i < fname.size(); i++)
164 infile[i] =
M3::Open(fname[i].Data(),
"open", __FILE__, __LINE__);
168 auto c1 = std::make_unique<TCanvas>(
"c1",
" ", 0, 0, 800, 630);
169 gStyle->SetOptStat(0);
171 gErrorIgnoreLevel = kWarning;
173 c1->Print(
"Auto_Corr_PerFile.pdf[",
"pdf");
174 for (
int ik = 0; ik < Nfiles; ik++)
176 TIter next(infile[ik]->GetListOfKeys());
180 std::vector<std::unique_ptr<TH1D>> histos;
181 while ((key =
static_cast<TKey *
>(next())))
183 std::string dirname = std::string(key->GetName());
186 if ((dirname !=
"Auto_corr"))
189 infile[ik]->cd(dirname.c_str());
190 TIter nextsub(gDirectory->GetListOfKeys());
193 bool FirstTime =
true;
194 while ((subkey =
static_cast<TKey *
>(nextsub())))
196 std::string name = std::string(subkey->GetName());
197 name = dirname +
"/" + name;
199 if (std::string(subkey->GetClassName()) !=
"TH1D")
202 histos.push_back(
M3::Clone(
static_cast<TH1D *
>(infile[ik]->
Get(name.c_str()))));
204 if (std::isnan(histos.back()->GetBinContent(1)))
210 double UpperEdgeBeforeLast = histos.back()->GetXaxis()->GetBinUpEdge(histos.back()->GetNbinsX()/2);
211 double MinValue =
GetMinimumInRange(histos.back().get(), 0, UpperEdgeBeforeLast);
213 if (MinValue >= 0.80)
214 histos.back()->SetLineColor(kRed);
215 else if (MinValue >= 0.40 && MinValue < 0.80)
216 histos.back()->SetLineColor(kOrange);
217 else if (MinValue > 0.20 && MinValue < 0.40)
218 histos.back()->SetLineColor(kYellow);
219 else if (MinValue <= 0.20)
220 histos.back()->SetLineColor(kGreen);
221 histos.back()->GetXaxis()->UnZoom();
224 histos.back()->SetTitle(Form(
"Auto_Corr_%s.pdf", fname[ik].Data()));
226 histos.back()->SetLineStyle(kDashed);
229 histos.back()->Draw();
231 TString integral = Form(
"Integral: %.2f", histos.back()->Integral());
234 histos.back()->Draw(
"same");
237 gDirectory->cd(
"..");
239 c1->Print(
"Auto_Corr_PerFile.pdf",
"pdf");
241 c1->Print(
"Auto_Corr_PerFile.pdf]",
"pdf");
247 std::pair<std::unique_ptr<TGraph>, std::unique_ptr<TGraph>>
CreateMinMaxBand(TH1D *hist, Color_t color)
249 int nBins = hist->GetNbinsX();
250 std::vector<double> x(nBins), ymin(nBins), ymax(nBins);
252 for (
int i = 0; i < nBins; ++i)
254 x[i] = hist->GetBinCenter(i + 1);
255 ymin[i] = hist->GetBinContent(i + 1);
256 ymax[i] = hist->GetBinContent(i + 1);
259 auto minGraph = std::make_unique<TGraph>(nBins, x.data(), ymin.data());
260 auto maxGraph = std::make_unique<TGraph>(nBins, x.data(), ymax.data());
262 minGraph->SetLineColor(color);
263 maxGraph->SetLineColor(color);
264 minGraph->SetFillColorAlpha(color, 0.3f);
265 maxGraph->SetFillColorAlpha(color, 0.3f);
267 return {std::move(minGraph), std::move(maxGraph)};
270 std::unique_ptr<TGraphAsymmErrors>
CalculateMinMaxBand(
const std::vector<std::unique_ptr<TH1D>> &histograms, Color_t color)
272 if (histograms.empty()) {
273 throw MaCh3Exception(__FILE__, __LINE__,
"Empty histogram vector provided");
276 int nBins = histograms[0]->GetNbinsX();
277 std::vector<double> x(nBins), ymin(nBins, 1e10), ymax(nBins, -1e10);
279 for (
int bin = 0; bin < nBins; bin++)
281 x[bin] = histograms[0]->GetBinCenter(bin + 1);
283 for (
const auto &hist : histograms)
285 double content = hist->GetBinContent(bin + 1);
286 ymin[bin] = std::min(ymin[bin], content);
287 ymax[bin] = std::max(ymax[bin], content);
292 auto band = std::make_unique<TGraphAsymmErrors>(nBins);
293 for (
int i = 0; i < nBins; ++i)
295 band->SetPoint(i, x[i], (ymax[i] + ymin[i]) / 2.0);
296 band->SetPointError(i, 0, 0, (ymax[i] - ymin[i]) / 2.0, (ymax[i] - ymin[i]) / 2.0);
299 band->SetFillColorAlpha(color, 0.2f);
300 band->SetLineWidth(1);
307 std::unique_ptr<TH1D>& average_hist,
308 int ¶meter_count,
309 std::vector<std::unique_ptr<TH1D>> &histograms)
311 TIter next(autocor_dir->GetListOfKeys());
314 while ((key =
dynamic_cast<TKey *
>(next())))
316 TH1D *current_hist =
nullptr;
317 autocor_dir->GetObject(key->GetName(), current_hist);
320 current_hist->GetMaximum() <= 0 ||
326 histograms.push_back(
M3::Clone(current_hist));
330 average_hist->Add(current_hist);
337 std::unique_ptr<TH1D>& average_hist,
338 int ¶meter_count,
339 std::vector<std::unique_ptr<TH1D>> &histograms)
341 std::unique_ptr<TFile> input_file(
TFile::Open(file_path));
342 if (!input_file || input_file->IsZombie())
344 throw MaCh3Exception(__FILE__, __LINE__,
"Could not open file: " + std::string(file_path.Data()));
347 TDirectoryFile *autocor_dir =
nullptr;
348 input_file->GetObject(
"Auto_corr", autocor_dir);
353 "Auto_corr directory not found in file: " + std::string(file_path.Data()));
359 std::unique_ptr<TH1D>
AutocorrProcessInputs(
const TString &input_file, std::vector<std::unique_ptr<TH1D>> &histograms)
361 std::unique_ptr<TH1D> average_hist =
nullptr;
362 int parameter_count = 0;
366 }
catch (
const std::exception &e) {
367 MACH3LOG_ERROR(
"Error processing file {} : {}", input_file, e.what());
370 if (average_hist && parameter_count > 0)
372 MACH3LOG_INFO(
"Processed {} parameters from {} files", parameter_count, input_file);
373 average_hist->Scale(1.0 / parameter_count);
380 const std::vector<std::unique_ptr<TH1D>> &averages,
381 const std::vector<TString> &hist_labels,
382 const TString &output_name,
383 bool draw_min_max =
true,
384 bool draw_all =
false,
385 bool draw_errors =
true)
387 auto canvas = std::make_unique<TCanvas>(
"AverageAC",
"Average Auto Correlation", 800, 600);
391 constexpr Int_t nb = 255.0;
392 Double_t stops[8] = {0.0, 0.25, 0.5, 0.75};
393 Double_t red[8] = {0.83203125, 0.796875, 0.0, 0.9375};
394 Double_t green[8] = {0.3671875, 0.47265625, 0.4453125, 0.890625};
395 Double_t blue[8] = {0.0, 0.65234375, 0.6953125, 0.2578125};
396 TColor::CreateGradientColorTable(8, stops, red, green, blue, nb);
398 auto leg = std::make_unique<TLegend>(0.5, 0.7, 0.9, 0.9);
399 leg->SetFillColorAlpha(kWhite, 0.7f);
402 for (
size_t i = 0; i < histograms.size(); ++i)
404 auto colour =
static_cast<Color_t
>(TColor::GetColorPalette(
static_cast<Int_t
>(i * nb / histograms.size())));
406 band->SetLineWidth(0);
407 band->SetTitle(
"Average Auto Correlation");
408 band->GetXaxis()->SetTitle(
"lag");
409 band->GetYaxis()->SetTitle(
"Autocorrelation Function");
413 band->Draw(
"3 SAME");
417 std::vector<std::unique_ptr<TH1D>> error_hist(averages.size());
418 for (
size_t i = 0; i < averages.size(); ++i)
420 auto colour =
static_cast<Color_t
>(TColor::GetColorPalette(
static_cast<Int_t
>(i * nb / histograms.size())));
424 error_hist[i] =
M3::Clone(averages[i].get());
425 error_hist[i]->SetFillColorAlpha(colour, 0.3f);
426 error_hist[i]->SetLineWidth(0);
427 error_hist[i]->SetTitle(
"Average Auto Correlation");
428 error_hist[i]->GetXaxis()->SetTitle(
"lag");
429 error_hist[i]->GetYaxis()->SetTitle(
"Autocorrelation Function");
430 error_hist[i]->Draw(
"E3 SAME");
434 for (
const auto &hist : histograms[i])
436 hist->SetLineColorAlpha(colour, 0.05f);
437 hist->SetLineWidth(1);
438 hist->Draw(
"HIST SAME");
441 averages[i]->SetLineColor(colour);
442 averages[i]->SetLineWidth(2);
443 averages[i]->SetTitle(
"Average Auto Correlation");
444 averages[i]->GetXaxis()->SetTitle(
"lag");
445 averages[i]->GetYaxis()->SetTitle(
"Autocorrelation Function");
446 averages[i]->Draw(
"HIST SAME");
448 TString int_str = TString::Format(
"Average integrated autocorrelation %.2f", averages[i]->Integral());
449 leg->AddEntry(averages[i].get(), hist_labels[i] + int_str,
"l");
452 if (averages.size() > 1)
457 canvas->SaveAs(output_name +
".pdf");
462 std::vector<TString> hist_labels,
463 const TString &output_name,
464 bool draw_min_max =
true,
465 bool draw_all =
false,
466 bool draw_errors =
true)
469 std::vector<std::vector<std::unique_ptr<TH1D>>> histograms;
470 std::vector<std::unique_ptr<TH1D>> averages;
472 for (
int i = 0; i < static_cast<int>(input_files.size()); i++)
474 TString folder = input_files[i];
479 MACH3LOG_WARN(
"Skipping empty or dummy folder: {}", folder.Data());
483 std::vector<std::unique_ptr<TH1D>> histograms_i;
485 histograms.push_back(std::move(histograms_i));
488 CompareAverageAC(histograms, averages, hist_labels, output_name, draw_min_max, draw_all, draw_errors);
491 int main(
int argc,
char *argv[])
495 if (argc < 3 || (argc - 1) % 2 != 0)
498 MACH3LOG_ERROR(
"Usage: {} file1 title1 [file2 title2 ... fileN titleN]", argv[0]);
499 MACH3LOG_ERROR(
"Example: {} DiagMCMC_Output.root PlotName", argv[0]);
502 std::vector<TString> filename;
503 std::vector<TString> title;
505 std::vector<TString> filenames;
506 std::vector<TString> titles;
509 for (
int i = 1; i < argc; i += 2)
511 filenames.emplace_back(argv[i]);
512 titles.emplace_back(argv[i + 1]);
521 PlotAverageACMult(filenames, titles, Form(
"%s_Average_Auto_Corr", argv[2]),
true);
#define _MaCh3_Safe_Include_Start_
KS: Avoiding warning checking for headers.
#define _MaCh3_Safe_Include_End_
void RemoveFitter(TH1D *hist, const std::string &name)
KS: Remove fitted TF1 from hist to make comparison easier.
void SetMaCh3LoggerFormat()
Set messaging format of the logger.
std::unique_ptr< TH1D > AutocorrProcessInputs(const TString &input_file, std::vector< std::unique_ptr< TH1D >> &histograms)
int main(int argc, char *argv[])
void CompareAverageAC(const std::vector< std::vector< std::unique_ptr< TH1D >>> &histograms, const std::vector< std::unique_ptr< 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)
bool IsHistogramAllOnes(TH1D *hist, double tolerance=0.001, int max_failures=100)
HW: Check if histogram is flat within a given tolerance.
double GetMinimumInRange(TH1D *hist, const double minRange, const double maxRange)
KS: function which looks for minimum in given range.
void PlotAverageACMult(std::vector< TString > input_files, std::vector< TString > hist_labels, const TString &output_name, bool draw_min_max=true, bool draw_all=false, bool draw_errors=true)
Calculate mean AC based on all parameters with error band. Great for comparing AC between different c...
std::pair< std::unique_ptr< TGraph >, std::unique_ptr< TGraph > > CreateMinMaxBand(TH1D *hist, Color_t color)
HW: Create a band of minimum and maximum values from a histogram.
void ProcessAutoCorrelationDirectory(TDirectoryFile *autocor_dir, std::unique_ptr< TH1D > &average_hist, int ¶meter_count, std::vector< std::unique_ptr< TH1D >> &histograms)
Loop over directory get histograms into vector and add to averaged hist.
std::unique_ptr< TGraphAsymmErrors > CalculateMinMaxBand(const std::vector< std::unique_ptr< TH1D >> &histograms, Color_t color)
void PlotAutoCorr(const std::vector< TString > &fname)
Plot autocorrelation for all params into single plot with color codding helping whether on average it...
void ProcessDiagnosticFile(const TString &file_path, std::unique_ptr< TH1D > &average_hist, int ¶meter_count, std::vector< std::unique_ptr< TH1D >> &histograms)
void MakeDiagPlot(std::vector< TString > input_files, std::vector< TString > hist_labels)
function which loops over Diag MCMC output and prints everything to PDF
constexpr ELineStyle Style[NVars]
Type Get(const YAML::Node &node, const std::string &File, const int Line)
Get content of config file.
Custom exception class used throughout MaCh3.
std::unique_ptr< ObjectType > Clone(const ObjectType *obj, const std::string &name="")
KS: Creates a copy of a ROOT-like object and wraps it in a smart pointer.
TFile * Open(const std::string &Name, const std::string &Type, const std::string &File, const int Line)
Opens a ROOT file with the given name and mode.