5 #include "TGraphAsymmErrors.h"
22 double MinVale = 1234567890.;
23 TAxis *xaxis = hist->GetXaxis();
24 for (
int x = 1; x <= hist->GetNbinsX(); x++)
26 if (xaxis->GetBinLowEdge(x) > minRange && xaxis->GetBinUpEdge(x) < maxRange)
28 if (MinVale > hist->GetBinContent(x))
29 MinVale = hist->GetBinContent(x);
38 int failure_count = 0;
40 for (
int bin = 2; bin <= hist->GetNbinsX(); ++bin)
42 if (std::fabs(hist->GetBinContent(bin) - 1.0) > tolerance)
44 if (++failure_count > max_failures)
55 std::vector<TString> hist_labels)
57 auto c1 = std::make_unique<TCanvas>(
"c1",
" ", 0, 0, 800, 630);
58 gStyle->SetOptStat(0);
60 gErrorIgnoreLevel = kWarning;
63 std::vector<TFile*> infiles;
64 bool add_legend =
false;
66 for (
const auto& fname : input_files)
68 TFile* f =
M3::Open(fname.Data(),
"UPDATE", __FILE__, __LINE__);
71 add_legend = (input_files.size() > 1);
74 constexpr
int NFiles_hard = 4;
75 constexpr Color_t Colour[NFiles_hard] = {kRed, kBlue, kGreen, kOrange};
76 constexpr Style_t
Style[NFiles_hard] = {kSolid, kDashed, kDotted, kDashDotted};
77 if(input_files.size() > NFiles_hard){
78 MACH3LOG_ERROR(
"Passed {}, while I have nasty hardcoding for max {} filse", input_files.size(), NFiles_hard);
81 TIter next(infiles[0]->GetListOfKeys());
82 while ((key =
static_cast<TKey *
>(next())))
84 std::string dirname = std::string(key->GetName());
85 if (std::string(key->GetClassName()) !=
"TDirectoryFile")
88 if ((dirname ==
"LogL") || (dirname ==
"Batched_means") || (dirname ==
"PowerSpectrum"))
93 infiles[0]->cd(dirname.c_str());
94 TIter nextsub(gDirectory->GetListOfKeys());
95 c1->Print(Form(
"%s_%s.pdf[", hist_labels[0].Data(), dirname.c_str()),
"pdf");
97 while ((subkey =
static_cast<TKey *
>(nextsub())))
99 auto leg = std::make_unique<TLegend>(0.7, 0.7, 0.9, 0.9);
100 leg->SetFillColorAlpha(kWhite, 0.7f);
101 std::string name = std::string(subkey->GetName());
102 name = dirname +
"/" + name;
104 if (std::string(subkey->GetClassName()) !=
"TH1D") {
109 if (name ==
"AccProb/AcceptanceProbability")
continue;
111 std::vector<std::unique_ptr<TH1D>> blarb(infiles.size());
112 MACH3LOG_INFO(
"Looking for {} from file {}", name.c_str(), input_files[0].Data());
113 blarb[0] =
M3::Clone(
static_cast<TH1D *
>(infiles[0]->
Get(name.c_str())));
115 if (std::isnan(blarb[0]->GetBinContent(1)))
119 if (dirname ==
"AccProb")
120 blarb[0]->GetYaxis()->SetRangeUser(0, 1.0);
122 blarb[0]->SetLineStyle(
Style[0]);
123 blarb[0]->SetLineColor(Colour[0]);
125 leg->AddEntry(blarb[0].get(), hist_labels[0].Data(),
"l");
127 for (
size_t i = 1; i < infiles.size(); ++i)
129 blarb[i] =
M3::Clone(
static_cast<TH1D *
>(infiles[i]->
Get(name.c_str())));
131 blarb[i]->SetLineStyle(
Style[i]);
132 blarb[i]->SetLineColor(Colour[i]);
134 blarb[i]->Draw(i == 0 ?
"" :
"same");
135 leg->AddEntry(blarb[i].get(), hist_labels[i].Data(),
"l");
141 c1->Print(Form(
"%s_%s.pdf", hist_labels[0].Data(), dirname.c_str()),
"pdf");
143 gDirectory->cd(
"..");
144 c1->Print(Form(
"%s_%s.pdf]", hist_labels[0].Data(), dirname.c_str()),
"pdf");
147 for (
size_t i = 0; i < infiles.size(); ++i)
157 std::vector<TFile*> infile(fname.size());
159 for(
size_t i = 0; i < fname.size(); i++)
161 infile[i] =
M3::Open(fname[i].Data(),
"open", __FILE__, __LINE__);
165 auto c1 = std::make_unique<TCanvas>(
"c1",
" ", 0, 0, 800, 630);
166 gStyle->SetOptStat(0);
168 gErrorIgnoreLevel = kWarning;
170 c1->Print(
"Auto_Corr_PerFile.pdf[",
"pdf");
171 for (
int ik = 0; ik < Nfiles; ik++)
173 TIter next(infile[ik]->GetListOfKeys());
177 std::vector<std::unique_ptr<TH1D>> histos;
178 while ((key =
static_cast<TKey *
>(next())))
180 std::string dirname = std::string(key->GetName());
183 if ((dirname !=
"Auto_corr"))
186 infile[ik]->cd(dirname.c_str());
187 TIter nextsub(gDirectory->GetListOfKeys());
190 bool FirstTime =
true;
191 while ((subkey =
static_cast<TKey *
>(nextsub())))
193 std::string name = std::string(subkey->GetName());
194 name = dirname +
"/" + name;
196 if (std::string(subkey->GetClassName()) !=
"TH1D")
199 histos.push_back(
M3::Clone(
static_cast<TH1D *
>(infile[ik]->
Get(name.c_str()))));
201 if (std::isnan(histos.back()->GetBinContent(1)))
207 double UpperEdgeBeforeLast = histos.back()->GetXaxis()->GetBinUpEdge(histos.back()->GetNbinsX()/2);
208 double MinValue =
GetMinimumInRange(histos.back().get(), 0, UpperEdgeBeforeLast);
210 if (MinValue >= 0.80)
211 histos.back()->SetLineColor(kRed);
212 else if (MinValue >= 0.40 && MinValue < 0.80)
213 histos.back()->SetLineColor(kOrange);
214 else if (MinValue > 0.20 && MinValue < 0.40)
215 histos.back()->SetLineColor(kYellow);
216 else if (MinValue <= 0.20)
217 histos.back()->SetLineColor(kGreen);
218 histos.back()->GetXaxis()->UnZoom();
221 histos.back()->SetTitle(Form(
"Auto_Corr_%s.pdf", fname[ik].Data()));
223 histos.back()->SetLineStyle(kDashed);
226 histos.back()->Draw();
228 TString integral = Form(
"Integral: %.2f", histos.back()->Integral());
231 histos.back()->Draw(
"same");
234 gDirectory->cd(
"..");
236 c1->Print(
"Auto_Corr_PerFile.pdf",
"pdf");
238 c1->Print(
"Auto_Corr_PerFile.pdf]",
"pdf");
244 std::pair<std::unique_ptr<TGraph>, std::unique_ptr<TGraph>>
CreateMinMaxBand(TH1D *hist, Color_t color)
246 int nBins = hist->GetNbinsX();
249 for (
int i = 0; i <
nBins; ++i)
251 x[i] = hist->GetBinCenter(i + 1);
252 ymin[i] = hist->GetBinContent(i + 1);
253 ymax[i] = hist->GetBinContent(i + 1);
256 auto minGraph = std::make_unique<TGraph>(
nBins, x.data(), ymin.data());
257 auto maxGraph = std::make_unique<TGraph>(
nBins, x.data(), ymax.data());
259 minGraph->SetLineColor(color);
260 maxGraph->SetLineColor(color);
261 minGraph->SetFillColorAlpha(color, 0.3f);
262 maxGraph->SetFillColorAlpha(color, 0.3f);
264 return {std::move(minGraph), std::move(maxGraph)};
267 std::unique_ptr<TGraphAsymmErrors>
CalculateMinMaxBand(
const std::vector<std::unique_ptr<TH1D>> &histograms, Color_t color)
269 if (histograms.empty()) {
270 throw MaCh3Exception(__FILE__, __LINE__,
"Empty histogram vector provided");
273 int nBins = histograms[0]->GetNbinsX();
276 for (
int bin = 0; bin <
nBins; bin++)
278 x[bin] = histograms[0]->GetBinCenter(bin + 1);
280 for (
const auto &hist : histograms)
282 double content = hist->GetBinContent(bin + 1);
283 ymin[bin] = std::min(ymin[bin], content);
284 ymax[bin] = std::max(ymax[bin], content);
289 auto band = std::make_unique<TGraphAsymmErrors>(
nBins);
290 for (
int i = 0; i <
nBins; ++i)
292 band->SetPoint(i, x[i], (ymax[i] + ymin[i]) / 2.0);
293 band->SetPointError(i, 0, 0, (ymax[i] - ymin[i]) / 2.0, (ymax[i] - ymin[i]) / 2.0);
296 band->SetFillColorAlpha(color, 0.2f);
297 band->SetLineWidth(1);
304 std::unique_ptr<TH1D>& average_hist,
305 int ¶meter_count,
306 std::vector<std::unique_ptr<TH1D>> &histograms)
308 TIter next(autocor_dir->GetListOfKeys());
311 while ((key =
dynamic_cast<TKey *
>(next())))
313 TH1D *current_hist =
nullptr;
314 autocor_dir->GetObject(key->GetName(), current_hist);
317 current_hist->GetMaximum() <= 0 ||
323 histograms.push_back(
M3::Clone(current_hist));
327 average_hist->Add(current_hist);
334 std::unique_ptr<TH1D>& average_hist,
335 int ¶meter_count,
336 std::vector<std::unique_ptr<TH1D>> &histograms)
338 std::unique_ptr<TFile> input_file(
TFile::Open(file_path));
339 if (!input_file || input_file->IsZombie())
341 throw MaCh3Exception(__FILE__, __LINE__,
"Could not open file: " + std::string(file_path.Data()));
344 TDirectoryFile *autocor_dir =
nullptr;
345 input_file->GetObject(
"Auto_corr", autocor_dir);
350 "Auto_corr directory not found in file: " + std::string(file_path.Data()));
356 std::unique_ptr<TH1D>
AutocorrProcessInputs(
const TString &input_file, std::vector<std::unique_ptr<TH1D>> &histograms)
358 std::unique_ptr<TH1D> average_hist =
nullptr;
359 int parameter_count = 0;
363 }
catch (
const std::exception &e) {
364 MACH3LOG_ERROR(
"Error processing file {} : {}", input_file, e.what());
367 if (average_hist && parameter_count > 0)
369 MACH3LOG_INFO(
"Processed {} parameters from {} files", parameter_count, input_file);
370 average_hist->Scale(1.0 / parameter_count);
377 const std::vector<std::unique_ptr<TH1D>> &averages,
378 const std::vector<TString> &hist_labels,
379 const TString &output_name,
380 bool draw_min_max =
true,
381 bool draw_all =
false,
382 bool draw_errors =
true)
384 auto canvas = std::make_unique<TCanvas>(
"AverageAC",
"Average Auto Correlation", 800, 600);
388 constexpr Int_t nb = 255.0;
389 Double_t stops[8] = {0.0, 0.25, 0.5, 0.75};
390 Double_t red[8] = {0.83203125, 0.796875, 0.0, 0.9375};
391 Double_t green[8] = {0.3671875, 0.47265625, 0.4453125, 0.890625};
392 Double_t blue[8] = {0.0, 0.65234375, 0.6953125, 0.2578125};
393 TColor::CreateGradientColorTable(8, stops, red, green, blue, nb);
395 auto leg = std::make_unique<TLegend>(0.5, 0.7, 0.9, 0.9);
396 leg->SetFillColorAlpha(kWhite, 0.7f);
399 for (
size_t i = 0; i < histograms.size(); ++i)
401 auto colour =
static_cast<Color_t
>(TColor::GetColorPalette(
static_cast<Int_t
>(i * nb / histograms.size())));
403 band->SetLineWidth(0);
404 band->SetTitle(
"Average Auto Correlation");
405 band->GetXaxis()->SetTitle(
"lag");
406 band->GetYaxis()->SetTitle(
"Autocorrelation Function");
410 band->Draw(
"3 SAME");
414 std::vector<std::unique_ptr<TH1D>> error_hist(averages.size());
415 for (
size_t i = 0; i < averages.size(); ++i)
417 auto colour =
static_cast<Color_t
>(TColor::GetColorPalette(
static_cast<Int_t
>(i * nb / histograms.size())));
421 error_hist[i] =
M3::Clone(averages[i].get());
422 error_hist[i]->SetFillColorAlpha(colour, 0.3f);
423 error_hist[i]->SetLineWidth(0);
424 error_hist[i]->SetTitle(
"Average Auto Correlation");
425 error_hist[i]->GetXaxis()->SetTitle(
"lag");
426 error_hist[i]->GetYaxis()->SetTitle(
"Autocorrelation Function");
427 error_hist[i]->Draw(
"E3 SAME");
431 for (
const auto &hist : histograms[i])
433 hist->SetLineColorAlpha(colour, 0.05f);
434 hist->SetLineWidth(1);
435 hist->Draw(
"HIST SAME");
438 averages[i]->SetLineColor(colour);
439 averages[i]->SetLineWidth(2);
440 averages[i]->SetTitle(
"Average Auto Correlation");
441 averages[i]->GetXaxis()->SetTitle(
"lag");
442 averages[i]->GetYaxis()->SetTitle(
"Autocorrelation Function");
443 averages[i]->Draw(
"HIST SAME");
445 TString int_str = TString::Format(
"Average integrated autocorrelation %.2f", averages[i]->Integral());
446 leg->AddEntry(averages[i].get(), hist_labels[i] + int_str,
"l");
449 if (averages.size() > 1)
454 canvas->SaveAs(output_name +
".pdf");
459 std::vector<TString> hist_labels,
460 const TString &output_name,
461 bool draw_min_max =
true,
462 bool draw_all =
false,
463 bool draw_errors =
true)
466 std::vector<std::vector<std::unique_ptr<TH1D>>> histograms;
467 std::vector<std::unique_ptr<TH1D>> averages;
469 for (
int i = 0; i < static_cast<int>(input_files.size()); i++)
471 TString folder = input_files[i];
476 MACH3LOG_WARN(
"Skipping empty or dummy folder: {}", folder.Data());
480 std::vector<std::unique_ptr<TH1D>> histograms_i;
482 histograms.push_back(std::move(histograms_i));
485 CompareAverageAC(histograms, averages, hist_labels, output_name, draw_min_max, draw_all, draw_errors);
488 int main(
int argc,
char *argv[])
492 if (argc < 3 || (argc - 1) % 2 != 0)
495 MACH3LOG_ERROR(
"Usage: {} file1 title1 [file2 title2 ... fileN titleN]", argv[0]);
496 MACH3LOG_ERROR(
"Example: {} DiagMCMC_Output.root PlotName", argv[0]);
499 std::vector<TString> filename;
500 std::vector<TString> title;
502 std::vector<TString> filenames;
503 std::vector<TString> titles;
506 for (
int i = 1; i < argc; i += 2)
508 filenames.emplace_back(argv[i]);
509 titles.emplace_back(argv[i + 1]);
518 PlotAverageACMult(filenames, titles, Form(
"%s_Average_Auto_Corr", argv[2]),
true);
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.