MaCh3  2.8.0
Reference Guide
Functions | Variables
PredictivePlotting.cpp File Reference
#include "Utils/Plotting/PlottingUtils.h"
#include "Utils/Plotting/PlottingManager.h"
#include <numeric>
Include dependency graph for PredictivePlotting.cpp:

Go to the source code of this file.

Functions

std::vector< std::string > FindSamples (const std::string &File)
 
std::vector< int > FindDimensions (const std::string &File, const std::vector< std::string > &Samples)
 
std::vector< std::vector< std::string > > FindModes (const std::string &File, const std::vector< std::string > &SampleNames)
 
void PretifyHistogram (TH1 *Hist, const std::string &SampleName)
 
double GetPValue (const TH2D *hist)
 
void PrintPosteriorPValue (const YAML::Node &Settings, const std::vector< TFile * > &InputFiles, const std::vector< std::string > &SampleNames)
 
void OverlayViolin (const YAML::Node &Settings, const std::vector< TFile * > &InputFiles, const std::vector< std::string > &SampleNames, const std::vector< int > &SampleDimension, const std::unique_ptr< TCanvas > &canv)
 
void OverlayPredicitve (const YAML::Node &Settings, const std::vector< TFile * > &InputFiles, const std::vector< std::string > &SampleNames, const std::vector< int > &SampleDimension, const std::unique_ptr< TCanvas > &canv)
 
void OverlayPredicitveByMode (const YAML::Node &Settings, const std::vector< TFile * > &InputFiles, const std::vector< std::string > &SampleNames, const std::vector< int > &SampleDimension, const std::vector< std::vector< std::string >> &Modes, const std::unique_ptr< TCanvas > &canv)
 
void GetMeanError (TH1D *hist, double &Mean, double &Error)
 KS: Get mean and error from gaussian fit to event distribution. More...
 
void PrintPosteriorEventRates (const std::vector< TFile * > &InputFiles, const std::vector< std::string > &SampleNames)
 KS Print event rates in Latex like table. More...
 
void PrintPosteriorFractionalUncertainties (const std::vector< TFile * > &InputFiles, const std::vector< std::string > &SampleNames)
 KS: Print Fractional Uncertainties into Latex table format. More...
 
double GetLLH (TH1 *hist)
 
void PrintPredictiveLLH (const std::vector< TFile * > &InputFiles, const std::vector< std::string > &SampleNames)
 KS Print Predictive LLH into Latex table format. More...
 
void PredictivePlotting (const std::string &ConfigName, const std::vector< std::string > &FileNames)
 
int main (int argc, char **argv)
 

Variables

M3::Plotting::PlottingManager * PlotMan = nullptr
 

Detailed Description

Author
Kamil Skwarczynski

Definition in file PredictivePlotting.cpp.

Function Documentation

◆ FindDimensions()

std::vector<int> FindDimensions ( const std::string &  File,
const std::vector< std::string > &  Samples 
)

Definition at line 49 of file PredictivePlotting.cpp.

50 {
51  TFile *file = M3::Open(File, "READ", __FILE__, __LINE__);
52  TDirectoryFile *PredicitveDir = file->Get<TDirectoryFile>("Predictive");
53 
54  std::vector<int> SampleDimension;
55  for (const auto& sample : Samples)
56  {
57  // Get directory for this sample
58  TDirectoryFile* SampleDir = PredicitveDir->Get<TDirectoryFile>(sample.c_str());
59 
60  int Dimension = 0;
61 
62  while (true)
63  {
64  // Construct name Tutorial_mc_dimX
65  std::string histName = fmt::format("{}_mc_dim{}", sample, Dimension);
66 
67  TH2D* hist = SampleDir->Get<TH2D>(histName.c_str());
68  if (!hist) break; // stop when next dimension does not exist
69 
70  Dimension++;
71  }
72 
73  MACH3LOG_DEBUG("Sample '{}' has dimension {}", sample, Dimension);
74  SampleDimension.push_back(Dimension);
75  }
76 
77  file->Close();
78  delete file;
79 
80  return SampleDimension;
81 }
#define MACH3LOG_DEBUG
Definition: MaCh3Logger.h:34
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.

◆ FindModes()

std::vector<std::vector<std::string> > FindModes ( const std::string &  File,
const std::vector< std::string > &  SampleNames 
)

Definition at line 84 of file PredictivePlotting.cpp.

86 {
87  TFile *file = M3::Open(File, "READ", __FILE__, __LINE__);
88  TDirectoryFile *PredictiveDir = file->Get<TDirectoryFile>("Predictive");
89 
90  std::vector<std::vector<std::string>> ModeNames(SampleNames.size());
91 
92  for(size_t iSample = 0; iSample < SampleNames.size(); iSample++)
93  {
94  TDirectoryFile* SampleDir = PredictiveDir->Get<TDirectoryFile>(SampleNames[iSample].c_str());
95  if(!SampleDir) continue;
96 
97  TDirectoryFile* ByModeDir = SampleDir->Get<TDirectoryFile>("ByMode");
98  if(!ByModeDir) continue;
99 
100  // Loop over all keys in ByModeDir
101  TIter next(ByModeDir->GetListOfKeys());
102  TKey* key;
103 
104  while ((key = static_cast<TKey*>(next())))
105  {
106  TObject* obj = key->ReadObj();
107  if (!obj->InheritsFrom("TH1")) continue;
108 
109  std::string histName = obj->GetName();
110 
111  // Example: sample_mode_dim0 → extract "mode"
112  std::string prefix = SampleNames[iSample] + "_";
113  std::string suffix = "_dim0";
114 
115  if (histName.find(prefix) == 0 &&
116  histName.rfind(suffix) == histName.size() - suffix.size())
117  {
118  std::string Mode = histName.substr(prefix.size(),
119  histName.size() - prefix.size() - suffix.size());
120  MACH3LOG_DEBUG("Found mode '{}' for sample {}", Mode, SampleNames[iSample]);
121  ModeNames[iSample].push_back(Mode);
122  }
123  }
124  }
125 
126  file->Close();
127  delete file;
128 
129  return ModeNames;
130 }

◆ FindSamples()

std::vector<std::string> FindSamples ( const std::string &  File)

Definition at line 17 of file PredictivePlotting.cpp.

18 {
19  TFile *file = M3::Open(File, "READ", __FILE__, __LINE__);
20  TDirectoryFile *PredicitveDir = file->Get<TDirectoryFile>("Predictive");
21 
22  std::vector<std::string> SampleNames;
23  //Get all entries in input file
24  TIter next(PredicitveDir->GetListOfKeys());
25  TKey *key = nullptr;
26 
27  // Loop through all entries
28  while ((key = static_cast<TKey*>(next()))) {
29  // get directory names, ignore flux
30  auto classname = std::string(key->GetClassName());
31  auto dirname = std::string(key->GetName());
32 
33  if (classname != "TDirectoryFile") continue;
34  dirname = std::string(key->GetName());
35 
36  if(dirname == "Total") continue;
37  if(dirname == "BetaParameters") continue;
38  if(dirname == "Correlations") continue;
39 
40  SampleNames.push_back(dirname);
41  MACH3LOG_DEBUG("Entering Sample {}", dirname);
42  }
43 
44  file->Close();
45  delete file;
46  return SampleNames;
47 }

◆ GetLLH()

double GetLLH ( TH1 *  hist)

Definition at line 676 of file PredictivePlotting.cpp.

677 {
678  std::string TempTile = hist->GetTitle();
679  std::string temp = "=";
680 
681  std::string::size_type SizeType = TempTile.find(temp);
682  TempTile.erase(0, SizeType+1);
683  double llh = atof(TempTile.c_str());
684  return llh;
685 }

◆ GetMeanError()

void GetMeanError ( TH1D *  hist,
double &  Mean,
double &  Error 
)

KS: Get mean and error from gaussian fit to event distribution.

Definition at line 568 of file PredictivePlotting.cpp.

568  {
569  TF1 *Gauss = hist->GetFunction("Fit"); //This name is hardcoded be careful
570  //KS: Get mean and error from Gauss
571  Mean = Gauss->GetParameter(1);
572  Error = Gauss->GetParameter(2);
573 
574  //KS: Get mean and error from HPD
575  //Mean = hist->GetMean();
576  //Error = hpost->GetRMS();
577 }

◆ GetPValue()

double GetPValue ( const TH2D *  hist)

Definition at line 143 of file PredictivePlotting.cpp.

144 {
145  double pvalue = 0;
146  std::string TempTile = hist->GetTitle();
147  std::string temp = "=";
148 
149  std::string::size_type SizeType = TempTile.find(temp);
150  TempTile.erase(0, SizeType+1);
151  pvalue = atof(TempTile.c_str());
152  return pvalue;
153 }

◆ main()

int main ( int  argc,
char **  argv 
)

Definition at line 793 of file PredictivePlotting.cpp.

794 {
796  if (argc < 3)
797  {
798  MACH3LOG_ERROR("Need at least two arguments, {} <Config.Yaml> <Prior/Post_PredOutput.root>", argv[0]);
799  throw MaCh3Exception(__FILE__, __LINE__);
800  }
801  std::string ConfigName = std::string(argv[1]);
802  // Collect all remaining arguments as file names
803  std::vector<std::string> FileNames;
804  for (int i = 2; i < argc; ++i) {
805  FileNames.emplace_back(argv[i]);
806  }
807 
809  PlotMan->initialise();
810 
811  PredictivePlotting(ConfigName, FileNames);
812 
813  if(PlotMan) delete PlotMan;
814  return 0;
815 }
#define MACH3LOG_ERROR
Definition: MaCh3Logger.h:37
void SetMaCh3LoggerFormat()
Set messaging format of the logger.
Definition: MaCh3Logger.h:60
void PredictivePlotting(const std::string &ConfigName, const std::vector< std::string > &FileNames)
M3::Plotting::PlottingManager * PlotMan
The main class to be used in plotting scripts.
void initialise()
initalise this PlottingManager.
Custom exception class used throughout MaCh3.

◆ OverlayPredicitve()

void OverlayPredicitve ( const YAML::Node &  Settings,
const std::vector< TFile * > &  InputFiles,
const std::vector< std::string > &  SampleNames,
const std::vector< int > &  SampleDimension,
const std::unique_ptr< TCanvas > &  canv 
)

Definition at line 280 of file PredictivePlotting.cpp.

285 {
286  MACH3LOG_INFO("Starting {}", __func__);
287  canv->Clear();
288 
289  TPad* pad1 = new TPad("pad1","pad1",0,0.25,1,1);
290  pad1->AppendPad();
291  TPad* pad2 = new TPad("pad2","pad2",0,0,1,0.25);
292  pad2->AppendPad();
293 
294  pad1->SetGrid();
295  pad2->SetGrid();
296 
297  pad1->SetLeftMargin(canv->GetLeftMargin());
298  pad1->SetRightMargin(canv->GetRightMargin());
299  pad1->SetTopMargin(canv->GetTopMargin());
300  pad1->SetBottomMargin(0);
301 
302  pad2->SetLeftMargin(canv->GetLeftMargin());
303  pad2->SetRightMargin(canv->GetRightMargin());
304  pad2->SetTopMargin(0);
305  pad2->SetBottomMargin(0.28);
306 
307  auto PosteriorColor = Get<std::vector<Color_t >>(Settings["PosteriorColor"], __FILE__, __LINE__);
308  auto Titles = Get<std::vector<std::string>>(Settings["FileTitle"], __FILE__, __LINE__);
309 
310  if(Titles.size() < InputFiles.size() || PosteriorColor.size() < InputFiles.size()){
311  MACH3LOG_ERROR("Passed {} files, while only {} titles and {} colors", InputFiles.size(), Titles.size(), PosteriorColor.size());
312  throw MaCh3Exception(__FILE__, __LINE__);
313  }
314  for(size_t iSample = 0; iSample < SampleNames.size(); iSample++)
315  {
316  const int nFiles = static_cast<int>(InputFiles.size());
317  auto SampleName = SampleNames[iSample];
318  const int nDims = (SampleDimension[iSample] == 2) ? 2 : 1;
319  for(int iDim = 0; iDim < nDims; iDim++) {
320  std::string DataLocation = "";
321  if(nDims == 2) {
322  DataLocation = "Predictive/" + SampleName + "/Data_" + SampleName + "_Dim" + std::to_string(iDim);
323  } else {
324  DataLocation = "SampleFolder/data_" + SampleName;
325  }
326  TH1D* hist = InputFiles[0]->Get<TH1D>((DataLocation).c_str());
327 
328  auto BinWidthScale = PlotMan->style().getBinWidthScale(hist->GetXaxis()->GetTitle());
329  std::unique_ptr<TH1D> DataHist = M3::Clone(hist);
330  //KS: +1 for data, we want to get integral before scaling of the histogram
331  std::vector<double> Integral(nFiles+1);
332  Integral[nFiles] = DataHist->Integral();
333 
334  auto DataPoissonErrors = PoissonGraphScaled(DataHist.get(), BinWidthScale);
335  M3::ScaleHistogram(DataHist.get(), BinWidthScale);
336  DataHist->SetLineColor(kBlack);
337  DataPoissonErrors->SetLineColor(kBlack);
338  std::vector<std::unique_ptr<TH1D>> PredHist(nFiles);
339 
340  for(int iFile = 0; iFile < nFiles; iFile++)
341  {
342  InputFiles[iFile]->cd();
343  std::string HistLocation = "";
344  if(nDims == 2) {
345  HistLocation = "Predictive/" + SampleName + "/" + SampleName + "_mc_PostPred_dim" + std::to_string(iDim);
346  } else {
347  HistLocation = "Predictive/" + SampleName + "/" + SampleName + "_mc_PostPred";
348  }
349  PredHist[iFile] = M3::Clone(InputFiles[iFile]->Get<TH1D>((HistLocation).c_str()));
350  Integral[iFile] = PredHist[iFile]->Integral();
351  PlotMan->style().setTH1XRange(PredHist[iFile].get());
352  PredHist[iFile]->SetLineColor(PosteriorColor[iFile]);
353  PredHist[iFile]->SetMarkerColor(PosteriorColor[iFile]);
354  PredHist[iFile]->SetFillColorAlpha(PosteriorColor[iFile], 0.35);
355  PredHist[iFile]->SetFillStyle(1001);
356  PretifyHistogram(PredHist[iFile].get(), SampleName);
357  }
358  pad1->cd();
359 
360  PredHist[0]->Draw("p e2");
361  for(int iFile = 1; iFile < nFiles; iFile++) {
362  PredHist[iFile]->Draw("p e2 same");
363  }
364  DataPoissonErrors->Draw("p same");
365 
366  auto legend = std::make_unique<TLegend>(0.50,0.52,0.90,0.88);
367  legend->AddEntry(DataPoissonErrors.get(), Form("Data, #int=%.2f", Integral[nFiles]),"le");
368  for(int ig = 0; ig < nFiles; ig++ ) {
369  legend->AddEntry(PredHist[ig].get(), Form("%s, #int=%.2f", Titles[ig].c_str(), Integral[ig]), "lpf");
370  }
371  legend->SetLineStyle(0);
372  legend->SetTextSize(0.03);
373  legend->Draw();
374 
376  pad2->cd();
377 
378  auto line = std::make_unique<TLine>(PredHist[0]->GetXaxis()->GetBinLowEdge(PredHist[0]->GetXaxis()->GetFirst()), 1.0, PredHist[0]->GetXaxis()->GetBinUpEdge(PredHist[0]->GetXaxis()->GetLast()), 1.0);
379 
380  line->SetLineWidth(2);
381  line->SetLineColor(kBlack);
382  line->Draw("");
383 
384  std::unique_ptr<TH1D> RatioPlotData = M3::Clone(DataHist.get());
385  std::vector<std::unique_ptr<TH1D>> RatioPlot(nFiles);
386 
387  for(int ig = 0; ig < nFiles; ig++ )
388  {
389  RatioPlot[ig] = M3::Clone(DataHist.get());
390  RatioPlot[ig]->SetLineColor(PosteriorColor[ig]);
391  RatioPlot[ig]->SetMarkerColor(PosteriorColor[ig]);
392  RatioPlot[ig]->SetFillColorAlpha(PosteriorColor[ig], 0.35);
393  RatioPlot[ig]->SetFillStyle(1001);
394  RatioPlot[ig]->GetYaxis()->SetTitle("Data/MC");
395  PlotMan->style().setTH1XRange(RatioPlot[ig].get());
396  auto PrettyX = PlotMan->style().prettifyKinematicName(PredHist[0]->GetXaxis()->GetTitle());
397  RatioPlot[ig]->GetXaxis()->SetTitle(PrettyX.c_str());
398  RatioPlot[ig]->SetBit(TH1D::kNoTitle);
399  RatioPlot[ig]->GetXaxis()->SetTitleSize(0.12);
400  RatioPlot[ig]->GetYaxis()->SetTitleOffset(0.4);
401  RatioPlot[ig]->GetYaxis()->SetTitleSize(0.10);
402 
403  RatioPlot[ig]->GetXaxis()->SetLabelSize(0.10);
404  RatioPlot[ig]->GetYaxis()->SetLabelSize(0.10);
405 
406  RatioPlot[ig]->Divide(PredHist[ig].get());
407  PassErrorToRatioPlot(RatioPlot[ig].get(), PredHist[ig].get(), DataHist.get());
408  }
409 
410  RatioPlotData->Divide(DataHist.get());
411  PassErrorToRatioPlot(RatioPlotData.get(), DataHist.get(), DataHist.get());
412 
414 
415  RatioPlot[0]->Draw("p e2");
416  for(int ig = 1; ig < nFiles; ig++ ) {
417  RatioPlot[ig]->Draw("p e2 same");
418  }
419  RatioPlotData->Draw("he same");
420 
421  canv->Print("Overlay_Predictive.pdf", "pdf");
422  }
423  }
424 
425  delete pad1;
426  delete pad2;
427 }
#define MACH3LOG_INFO
Definition: MaCh3Logger.h:35
void PretifyHistogram(TH1 *Hist, const std::string &SampleName)
std::unique_ptr< TGraphAsymmErrors > PoissonGraphScaled(const TH1D *hist, double scale, double cl)
Create a TGraphAsymmErrors from a histogram using exact Poisson confidence intervals instead of symme...
void PassErrorToRatioPlot(TH1D *RatioHist, TH1D *Hist1, TH1D *DataHist)
Propagate numerator uncertainties to a ratio histogram.
const StyleManager & style() const
Get the StyleManager contained within this PlottingManager, for doing style related things.
void setTH1XRange(TH1 *hist) const
Set plotting range for histogram.
double getBinWidthScale(const std::string &Name) const
Get bin-width scaling factor for a given kinematic variable.
std::string prettifyKinematicName(const std::string &origName) const
Convert hideous and vulgar internal kinematics name into a beautiful presentable name.
Definition: StyleManager.h:58
void SetSymmetricRatioRange(const std::vector< std::unique_ptr< TH1D >> &RatioPlot)
Set a symmetric Y-axis range around 1 for ratio plots.
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.
void ScaleHistogram(TH1 *Sample_Hist, const double scale)
Scale histogram to get divided by bin width.

◆ OverlayPredicitveByMode()

void OverlayPredicitveByMode ( const YAML::Node &  Settings,
const std::vector< TFile * > &  InputFiles,
const std::vector< std::string > &  SampleNames,
const std::vector< int > &  SampleDimension,
const std::vector< std::vector< std::string >> &  Modes,
const std::unique_ptr< TCanvas > &  canv 
)

Definition at line 429 of file PredictivePlotting.cpp.

435 {
436  MACH3LOG_INFO("Starting {}", __func__);
437  canv->cd();
438  constexpr auto DefaultColor = kBlack;
439  auto Titles = Get<std::vector<std::string>>(Settings["FileTitle"], __FILE__, __LINE__);
440  auto RelevantModesName = Get<std::vector<std::string>>(Settings["RelevantModesName"], __FILE__, __LINE__);
441  auto RelevantColors = Get<std::vector<Color_t>>(Settings["RelevantModesColors"], __FILE__, __LINE__);
442  int nRelevantModes = static_cast<int>(RelevantModesName.size());
443  const int nFiles = static_cast<int>(InputFiles.size());
444  if(Titles.size() < InputFiles.size()){
445  MACH3LOG_ERROR("Passed {} files, while only {} titles", InputFiles.size(), Titles.size());
446  throw MaCh3Exception(__FILE__, __LINE__);
447  }
448  if(RelevantModesName.size() != RelevantColors.size()) {
449  MACH3LOG_ERROR("Colors ({}) doesn't match relevant modes {}", RelevantColors.size(), RelevantModesName.size());
450  throw MaCh3Exception(__FILE__, __LINE__);
451  }
452  for(int iFile = 0; iFile < nFiles; iFile++ )
453  {
454  for(size_t iSample = 0; iSample < SampleNames.size(); iSample++)
455  {
456  auto SampleName = SampleNames[iSample];
457  for(int iDim = 0; iDim < SampleDimension[iSample]; iDim++)
458  {
459  const int nDims = (SampleDimension[iSample] == 2) ? 2 : 1;
460  std::string HistLocation = "";
461  if(nDims == 2) {
462  HistLocation = "Predictive/" + SampleName + "/" + SampleName + "_mc_PostPred_dim" + std::to_string(iDim);
463  } else {
464  HistLocation = "Predictive/" + SampleName + "/" + SampleName + "_mc_PostPred";
465  }
466  std::unique_ptr<TH1D> Sample_MC_Full = M3::Clone(InputFiles[iFile]->Get<TH1D>((HistLocation).c_str()));
467  Sample_MC_Full->SetLineColor(kOrange);
468  Sample_MC_Full->SetLineWidth(2);
469  Sample_MC_Full->SetMarkerColor(kOrange);
470  PretifyHistogram(Sample_MC_Full.get(), SampleName);
471 
472  std::string DataLocation = "";
473  std::unique_ptr<TH1D> Sample_Data;
474  if(nDims == 2) {
475  DataLocation = "Predictive/" + SampleName + "/Data_" + SampleName + "_Dim" + std::to_string(iDim);
476  } else if(nDims == 1) {
477  DataLocation = "SampleFolder/data_" + SampleName;
478  }
479  if(DataLocation != "") {
480  Sample_Data = M3::Clone(InputFiles[iFile]->Get<TH1D>((DataLocation).c_str()));
481  Sample_Data->SetLineColor(kBlack);
482  Sample_Data->SetLineWidth(2);
483  Sample_Data->SetMarkerColor(kBlack);
484  PretifyHistogram(Sample_Data.get(), SampleName);
485  }
486  int nModes = static_cast<int>(Modes[iSample].size());
487  // Simple map to keep track which mode is relevant and which will be added to "Other"
488  std::vector<bool> isRelevantMode(nModes, false);
489  std::vector<Color_t > ColorMap(nModes, DefaultColor);
490  for(int iMode = 0; iMode < nModes; iMode++) {
491  for(int iRelevant = 0; iRelevant < nRelevantModes; iRelevant++) {
492  if(Modes[iSample][iMode] == RelevantModesName[iRelevant]) {
493  isRelevantMode[iMode] = true;
494  ColorMap[iMode] = RelevantColors[iRelevant];
495  }
496  }
497  }
498  auto Sample_Stack = std::make_unique<THStack>(SampleName.c_str(), SampleName.c_str());
499  // This will hold values for "Other" modes
500  std::unique_ptr<TH1D> Sample_MC_Other;
501  // KS: Store histogram for each mode
502  std::vector<std::unique_ptr<TH1D>> Sample_MC(nModes);
503  std::vector<double> Integrals(nModes, 0.);
504  for(int iMode = 0; iMode < nModes; iMode++)
505  {
506  std::string FileLocaction = "Predictive/" + SampleName + "/ByMode/" + SampleName
507  + "_" + Modes[iSample][iMode] + "_dim" + std::to_string(iDim);
508  auto SpectraByMode = InputFiles[iFile]->Get<TH2D>((FileLocaction).c_str());
509  if(SpectraByMode == nullptr){
510  MACH3LOG_ERROR("Something went wrong and didn't find histogram: {}", FileLocaction);
511  throw MaCh3Exception(__FILE__, __LINE__);
512  }
513  Sample_MC[iMode] = MakeSummaryFromSpectra(SpectraByMode, SpectraByMode->GetTitle());
514  Integrals[iMode] = Sample_MC[iMode]->Integral();
515  PretifyHistogram(Sample_MC[iMode].get(), SampleName);
516 
517  if(Sample_MC_Other == nullptr) {
518  Sample_MC_Other = M3::Clone(Sample_MC[iMode].get());
519  Sample_MC_Other->Reset();
520  Sample_MC_Other->SetFillColor(DefaultColor);
521  Sample_MC_Other->SetLineColor(DefaultColor);
522  }
523  if(!isRelevantMode[iMode]) {
524  Sample_MC_Other->Add(Sample_MC[iMode].get());
525  }
526  Sample_MC[iMode]->SetFillColor(ColorMap[iMode]);
527  Sample_MC[iMode]->SetLineColor(ColorMap[iMode]);
528  } // end loop over modes
529  Sample_Stack->Add(Sample_MC_Other.get());
530  // KS: We do this other way around as we want to have most relevant modes first
531  for(int iMode = nModes-1; iMode >= 0; iMode--) {
532  if(isRelevantMode[iMode]) Sample_Stack->Add( Sample_MC[iMode].get() );
533  }
534  Sample_Stack->Draw("hist");
535  Sample_MC_Full->Draw("SAME he");
536  if(Sample_Data) Sample_Data->Draw("SAME pe");
537  canv->cd();
538  Sample_Stack->GetXaxis();
539  Sample_Stack->SetTitle(Sample_MC_Other->GetTitle());
540  Sample_Stack->GetXaxis()->SetTitle(Sample_MC_Other->GetXaxis()->GetTitle());
541  Sample_Stack->GetYaxis()->SetTitle(Sample_MC_Other->GetYaxis()->GetTitle());
542 
543  double FullIntegral = std::accumulate(Integrals.begin(), Integrals.end(), 0.0);
544  double OtherIntegral = 0.;
545  TLegend legend(0.50,0.52,0.85,0.88);
546  if(Sample_Data) legend.AddEntry(Sample_Data.get(), "Data","ple");
547  legend.AddEntry(Sample_MC_Full.get(), Titles[iFile].c_str(),"fple");
548  for(int iMode = 0; iMode < nModes; iMode++) {
549  if(isRelevantMode[iMode]) {
550  std::string Label = Form("%s: %.1f%%", Modes[iSample][iMode].c_str(), Integrals[iMode]/FullIntegral*100);
551  legend.AddEntry(Sample_MC[iMode].get(), Label.c_str() ,"lf");
552  } else{
553  OtherIntegral += Integrals[iMode]/FullIntegral;
554  }
555  }
556  legend.AddEntry(Sample_MC_Other.get(), Form("Other: %.1f%%", OtherIntegral*100), "lf");
557  legend.SetTextSize(0.03);
558  legend.Draw();
559 
560  canv->Print("Overlay_Predictive.pdf", "pdf");
561  } // end loop over dimensions
562  } // end loop over samples
563  } // end loop over files
564 }
std::unique_ptr< TH1D > MakeSummaryFromSpectra(const TH2D *Spectra, const std::string &name)
Build a 1D posterior-predictive summary from a violin spectrum.

◆ OverlayViolin()

void OverlayViolin ( const YAML::Node &  Settings,
const std::vector< TFile * > &  InputFiles,
const std::vector< std::string > &  SampleNames,
const std::vector< int > &  SampleDimension,
const std::unique_ptr< TCanvas > &  canv 
)

Definition at line 221 of file PredictivePlotting.cpp.

226 {
227  MACH3LOG_INFO("Starting {}", __func__);
228  canv->Clear();
229 
230  canv->SetTopMargin(0.10);
231  canv->SetBottomMargin(0.12);
232  canv->SetRightMargin(0.075);
233  canv->SetLeftMargin(0.14);
234 
235  auto PosteriorColor = Get<std::vector<Color_t >>(Settings["PosteriorColor"], __FILE__, __LINE__);
236  auto Titles = Get<std::vector<std::string>>(Settings["FileTitle"], __FILE__, __LINE__);
237  const int nFiles = static_cast<int>(InputFiles.size());
238 
239  //KS: No idea why but ROOT changed treatment of violin in R6. If you have non uniform binning this will results in very hard to see violin plots.
240  TCandle::SetScaledViolin(false);
241  for(size_t iSample = 0; iSample < SampleNames.size(); iSample++)
242  {
243  for(int iDim = 0; iDim < SampleDimension[iSample]; iDim++)
244  {
245  std::vector<std::unique_ptr<TH2D>> ViolinHist(nFiles);
246  for(int iFile = 0; iFile < nFiles; iFile++)
247  {
248  InputFiles[iFile]->cd();
249  ViolinHist[iFile] = M3::Clone(InputFiles[iFile]->Get<TH2D>(("Predictive/" + SampleNames[iSample]
250  + "/" + SampleNames[iSample] + "_mc_dim" + iDim).Data()));
251  ViolinHist[iFile]->SetTitle(PlotMan->style().prettifySampleName(SampleNames[iSample]).c_str());
252  ViolinHist[iFile]->SetLineColor(PosteriorColor[iFile]);
253  ViolinHist[iFile]->SetMarkerColor(PosteriorColor[iFile]);
254  ViolinHist[iFile]->SetFillColorAlpha(PosteriorColor[iFile], 0.35);
255  ViolinHist[iFile]->SetFillStyle(1001);
256  PlotMan->style().setTH1XRange(ViolinHist[iFile].get());
257  ViolinHist[iFile]->GetXaxis()->SetTitle(PlotMan->style().prettifyKinematicName(
258  ViolinHist[iFile]->GetXaxis()->GetTitle()).c_str());
259  ViolinHist[iFile]->GetYaxis()->SetTitle("Events");
260  }
261 
262  ViolinHist[0]->Draw("violinX(03100300)");
263  for(int iFile = 1; iFile < nFiles; iFile++) {
264  ViolinHist[iFile]->Draw("violinX(03100300) same");
265  }
266 
267  TLegend legend(0.50, 0.52, 0.90, 0.88);
268  for(int ig = 0; ig < nFiles; ig++) {
269  legend.AddEntry(ViolinHist[ig].get(), Form("%s", Titles[ig].c_str()), "lpf");
270  }
271  legend.SetLineStyle(0);
272  legend.SetTextSize(0.03);
273  legend.Draw();
274 
275  canv->Print("Overlay_Predictive.pdf", "pdf");
276  }
277  }
278 }
std::string prettifySampleName(const std::string &origName) const
Convert hideous and vulgar internal sample name into a beautiful presentable name.
Definition: StyleManager.h:49

◆ PredictivePlotting()

void PredictivePlotting ( const std::string &  ConfigName,
const std::vector< std::string > &  FileNames 
)

Definition at line 735 of file PredictivePlotting.cpp.

737 {
738  auto canvas = std::make_unique<TCanvas>("canv", "canv", 1080, 1080);
739  // set the paper & margin sizes
740  canvas->SetTopMargin(0.11);
741  canvas->SetBottomMargin(0.16);
742  canvas->SetRightMargin(0.075);
743  canvas->SetLeftMargin(0.12);
744  canvas->SetGrid();
745 
746  gStyle->SetOptStat(0); //Set 0 to disable statistic box
747  gStyle->SetPalette(51);
748  gStyle->SetLegendBorderSize(0); //This option disables legends borders
749  gStyle->SetFillStyle(0);
750 
751  //To avoid TCanvas::Print> messages
752  gErrorIgnoreLevel = kWarning;
753 
754  auto Samples = FindSamples(FileNames[0]);
755  auto Dimensions = FindDimensions(FileNames[0], Samples);
756  auto Modes = FindModes(FileNames[0], Samples);
757 
758  std::vector<TFile*> InputFiles(FileNames.size());
759  for(size_t i = 0; i < FileNames.size(); i++) {
760  InputFiles[i] = M3::Open(FileNames[i], "READ", __FILE__, __LINE__);
761  }
762 
763  // Load the YAML file
764  YAML::Node Config = M3OpenConfig(ConfigName);
765  // Access the "MatrixPlotter" section
766  YAML::Node settings = Config["PredictivePlotting"];
767  canvas->Print("Overlay_Predictive.pdf[", "pdf");
768 
769  // Make overlay of 1D hists
770  OverlayPredicitve(settings, InputFiles, Samples, Dimensions, canvas);
771  // Make overlay of violin plots
772  OverlayViolin(settings, InputFiles, Samples, Dimensions, canvas);
773  // Make By Mode post pred
774  if(Modes[0].size() != 0) OverlayPredicitveByMode(settings, InputFiles, Samples, Dimensions, Modes, canvas);
775  // Get PValue per sample
776  PrintPosteriorPValue(settings, InputFiles, Samples);
777  // KS: Print Fractional Uncertainties into Latex table format
778  PrintPosteriorEventRates(InputFiles, Samples);
779  // KS: Print Fractional Uncertainties into Latex table format
780  PrintPosteriorFractionalUncertainties(InputFiles, Samples);
781  // KS: Print Predictive LLH into Latex table format
782  PrintPredictiveLLH(InputFiles, Samples);
783  canvas->Print("Overlay_Predictive.pdf]", "pdf");
784 
785  for(size_t i = 0; i < FileNames.size(); i++)
786  {
787  InputFiles[i]->Close();
788  delete InputFiles[i];
789  }
790 }
void OverlayPredicitve(const YAML::Node &Settings, const std::vector< TFile * > &InputFiles, const std::vector< std::string > &SampleNames, const std::vector< int > &SampleDimension, const std::unique_ptr< TCanvas > &canv)
void PrintPosteriorPValue(const YAML::Node &Settings, const std::vector< TFile * > &InputFiles, const std::vector< std::string > &SampleNames)
std::vector< std::string > FindSamples(const std::string &File)
void OverlayPredicitveByMode(const YAML::Node &Settings, const std::vector< TFile * > &InputFiles, const std::vector< std::string > &SampleNames, const std::vector< int > &SampleDimension, const std::vector< std::vector< std::string >> &Modes, const std::unique_ptr< TCanvas > &canv)
void PrintPredictiveLLH(const std::vector< TFile * > &InputFiles, const std::vector< std::string > &SampleNames)
KS Print Predictive LLH into Latex table format.
void OverlayViolin(const YAML::Node &Settings, const std::vector< TFile * > &InputFiles, const std::vector< std::string > &SampleNames, const std::vector< int > &SampleDimension, const std::unique_ptr< TCanvas > &canv)
std::vector< std::vector< std::string > > FindModes(const std::string &File, const std::vector< std::string > &SampleNames)
std::vector< int > FindDimensions(const std::string &File, const std::vector< std::string > &Samples)
void PrintPosteriorFractionalUncertainties(const std::vector< TFile * > &InputFiles, const std::vector< std::string > &SampleNames)
KS: Print Fractional Uncertainties into Latex table format.
void PrintPosteriorEventRates(const std::vector< TFile * > &InputFiles, const std::vector< std::string > &SampleNames)
KS Print event rates in Latex like table.
#define M3OpenConfig(filename)
Macro to simplify calling LoadYaml with file and line info.
Definition: YamlHelper.h:589

◆ PretifyHistogram()

void PretifyHistogram ( TH1 *  Hist,
const std::string &  SampleName 
)

Definition at line 133 of file PredictivePlotting.cpp.

133  {
134  Hist->SetTitle(PlotMan->style().prettifySampleName(SampleName).c_str());
135  auto BinWidthScale = PlotMan->style().getBinWidthScale(Hist->GetXaxis()->GetTitle());
136  auto PrettyX = PlotMan->style().prettifyKinematicName(Hist->GetXaxis()->GetTitle());
137  PlotMan->style().setTH1XRange(Hist);
138  Hist->GetXaxis()->SetTitle(PrettyX.c_str());
139  Hist->GetYaxis()->SetTitle(fmt::format("Events/{:.0f}", BinWidthScale).c_str());
140  M3::ScaleHistogram(Hist, BinWidthScale);
141 }

◆ PrintPosteriorEventRates()

void PrintPosteriorEventRates ( const std::vector< TFile * > &  InputFiles,
const std::vector< std::string > &  SampleNames 
)

KS Print event rates in Latex like table.

Definition at line 580 of file PredictivePlotting.cpp.

581  {
582  MACH3LOG_INFO("Starting {}", __func__);
583  MACH3LOG_INFO("");
584 
585  double mean, error;
586  //KS: We now prepare to make tables for TN etc.
587  std::cout<<"\\begin{table}[htb]"<<std::endl;
588  std::cout<<"\\centering"<<std::endl;
589  std::cout<<"\\begin{tabular}{ | l |";
590  for(unsigned int f = 0; f < InputFiles.size(); f++)
591  {
592  std::cout<<" c |";
593  }
594  std::cout<<"} \\hline"<<std::endl;
595  std::cout<<"Sample ";
596  for(unsigned int f = 0; f < InputFiles.size(); f++)
597  {
598  std::cout<<"& Event Rates ";
599  }
600  std::cout<<"\\\\ \\hline"<<std::endl;
601  for(unsigned int i = 0; i < SampleNames.size(); i++)
602  {
603  std::cout<<SampleNames[i];
604  std::string TempString = "Predictive/" + SampleNames[i]+"/"+SampleNames[i]+"_sum";
605  for(unsigned int f = 0; f < InputFiles.size(); f++)
606  {
607  TH1D *hist = static_cast<TH1D*>(InputFiles[f]->Get(TempString.c_str()));
608  GetMeanError(hist, mean, error);
609  std::cout<<" & "<<mean<<" $\\pm$ "<<error;
610  }
611  std::cout<<" \\\\"<<std::endl;
612  }
613  std::cout<<"Total";
614  for(unsigned int f = 0; f < InputFiles.size(); f++)
615  {
616  TH1D *histTot = static_cast<TH1D*>(InputFiles[f]->Get("Predictive/Total/Total_sum"));
617  GetMeanError(histTot, mean, error);
618  std::cout<<" & "<<mean<<" $\\pm$ "<<error;
619  }
620  std::cout<<" \\\\"<<std::endl;
621  std::cout<<"\\hline"<<std::endl;
622  std::cout<<"\\end{tabular}"<<std::endl;
623  std::cout<<"\\end{table}"<<std::endl;
624  MACH3LOG_INFO("");
625 }
void GetMeanError(TH1D *hist, double &Mean, double &Error)
KS: Get mean and error from gaussian fit to event distribution.

◆ PrintPosteriorFractionalUncertainties()

void PrintPosteriorFractionalUncertainties ( const std::vector< TFile * > &  InputFiles,
const std::vector< std::string > &  SampleNames 
)

KS: Print Fractional Uncertainties into Latex table format.

Definition at line 628 of file PredictivePlotting.cpp.

629  {
630  MACH3LOG_INFO("Starting {}", __func__);
631  MACH3LOG_INFO("");
632  double mean, error;
633 
634  //KS: Fractional uncertainties on the prior and posterior predictive event rates.
635  std::cout<<"\\begin{table}[htb]"<<std::endl;
636  std::cout<<"\\centering"<<std::endl;
637  std::cout<<"\\begin{tabular}{ | l |";
638  for(unsigned int f = 0; f < InputFiles.size(); f++)
639  {
640  std::cout<<" c |";
641  }
642  std::cout<<"} \\hline"<<std::endl;
643 
644  std::cout<<"Sample ";
645  for(unsigned int f = 0; f < InputFiles.size(); f++)
646  {
647  std::cout<<"& $\\delta N / N (\\%)$";
648  }
649  std::cout<<"\\\\ \\hline"<<std::endl;
650 
651  for(unsigned int i = 0; i < SampleNames.size(); i++)
652  {
653  std::cout<<SampleNames[i];
654  std::string TempString = "Predictive/" + SampleNames[i]+"/"+SampleNames[i]+"_sum";
655  for(unsigned int f = 0; f < InputFiles.size(); f++)
656  {
657  TH1D *hist = static_cast<TH1D*>(InputFiles[f]->Get(TempString.c_str()));
658  GetMeanError(hist, mean, error);
659  std::cout<<" & "<<error/mean*100;
660  }
661  std::cout<<" \\\\"<<std::endl;
662  }
663  std::cout<<"Total";
664  for(unsigned int f = 0; f < InputFiles.size(); f++)
665  {
666  TH1D *histTotal = static_cast<TH1D*>(InputFiles[f]->Get("Predictive/Total/Total_sum"));
667  GetMeanError(histTotal, mean, error);
668  std::cout<<" & "<<error/mean*100;
669  }
670  std::cout<<"\\\\ \\hline"<<std::endl;
671  std::cout<<"\\end{tabular}"<<std::endl;
672  std::cout<<"\\end{table}"<<std::endl;
673  MACH3LOG_INFO("");
674 }

◆ PrintPosteriorPValue()

void PrintPosteriorPValue ( const YAML::Node &  Settings,
const std::vector< TFile * > &  InputFiles,
const std::vector< std::string > &  SampleNames 
)

Definition at line 155 of file PredictivePlotting.cpp.

158 {
159  MACH3LOG_INFO("Starting {}", __func__);
160  auto Titles = Get<std::vector<std::string>>(Settings["FileTitle"], __FILE__, __LINE__);
161  std::vector<std::vector<double>> FlucDrawVec(InputFiles.size());
162  // KS: Alternatively try "_drawfluc_draw"
163  std::string FlucutationType = "_predfluc_draw";
164  //KS: P-values per each sample
165  std::cout<<"\\begin{table}[htb]"<<std::endl;
166  std::cout<<"\\centering"<<std::endl;
167  std::cout<<"\\begin{tabular}{ | l | ";
168 
169  for(unsigned int f = 0; f < InputFiles.size(); f++)
170  {
171  std::cout<<"c | ";
172  }
173 
174  std::cout<<"} \\hline"<<std::endl;
175  std::cout<<"Sample ";
176  for(unsigned int f = 0; f < InputFiles.size(); f++)
177  {
178  std::cout<<"& \\multicolumn{1}{| c |}{" + Titles[f] +" p-value} ";
179  }
180  std::cout<<"\\\\"<<std::endl;
181  for(unsigned int f = 0; f < InputFiles.size(); f++)
182  {
183  std::cout<<" & Fluctuation of Prediction ";
184  }
185  std::cout<<"\\\\ \\hline"<<std::endl;
186  for(unsigned int i = 0; i < SampleNames.size(); i++)
187  {
188  std::cout<<SampleNames[i];
189  for(unsigned int f = 0; f < InputFiles.size(); f++)
190  {
191  std::string TempString = "Predictive/" + SampleNames[i]+"/"+SampleNames[i] + FlucutationType;
192  TH2D *hist2D = InputFiles[f]->Get<TH2D>(TempString.c_str());
193  double FlucDraw = GetPValue(hist2D);
194  std::cout<<" & "<<FlucDraw;
195  FlucDrawVec[f].push_back(FlucDraw);
196  }
197  std::cout<<" \\\\"<<std::endl;
198  }
199  std::cout<<"Total ";
200  for(unsigned int f = 0; f < InputFiles.size(); f++)
201  {
202  TH2D *hFlucPred = InputFiles[f]->Get<TH2D>(("Predictive/Total/Total" + FlucutationType).c_str());
203  double FlucDraw = GetPValue(hFlucPred);
204  std::cout<<" & "<<FlucDraw;
205  }
206  std::cout<<" \\\\ \\hline"<<std::endl;
207  std::cout<<"\\hline"<<std::endl;
208  std::cout<<"\\end{tabular}"<<std::endl;
209  std::cout<<"\\end{table}"<<std::endl;
210 
211  auto Threshold = GetFromManager<double>(Settings["Significance"], 0.05, __FILE__ , __LINE__);
212  for(unsigned int f = 0; f < InputFiles.size(); f++)
213  {
214  MACH3LOG_INFO("Calculating Shape for file {}", Titles[f]);
215 
216  CheckBonferoniCorrectedpValue(SampleNames, FlucDrawVec[f], Threshold);
217  MACH3LOG_INFO("Combined pvalue following Fisher method: {:.4f}", FisherCombinedPValue(FlucDrawVec[f]));
218  }
219 }
double GetPValue(const TH2D *hist)
double FisherCombinedPValue(const std::vector< double > &pvalues)
KS: Combine p-values using Fisher's method.
void CheckBonferoniCorrectedpValue(const std::vector< std::string > &SampleNameVec, const std::vector< double > &PValVec, const double Threshold)
KS: For more see https://www.t2k.org/docs/technotes/429/TN429_v8#page=63.

◆ PrintPredictiveLLH()

void PrintPredictiveLLH ( const std::vector< TFile * > &  InputFiles,
const std::vector< std::string > &  SampleNames 
)

KS Print Predictive LLH into Latex table format.

Definition at line 688 of file PredictivePlotting.cpp.

689  {
690  MACH3LOG_INFO("Starting {}", __func__);
691  MACH3LOG_INFO("");
692 
693  std::vector<double> Total(InputFiles.size());
694  //KS: We now prepare to make tables for TN etc.
695  std::cout<<"\\begin{table}[htb]"<<std::endl;
696  std::cout<<"\\centering"<<std::endl;
697  std::cout<<"\\begin{tabular}{ | l |";
698  for(unsigned int f = 0; f < InputFiles.size(); f++)
699  {
700  Total[f] = 0.;
701  std::cout<<" c |";
702  }
703  std::cout<<"} \\hline"<<std::endl;
704  std::cout<<"Sample ";
705  for(unsigned int f = 0; f < InputFiles.size(); f++)
706  {
707  std::cout<<"& 2#log#mathcal{L}_{stat} ";
708  }
709  std::cout<<"\\\\ \\hline"<<std::endl;
710  for(unsigned int i = 0; i < SampleNames.size(); i++)
711  {
712  std::cout<<SampleNames[i];
713  std::string TempString = "Predictive/" + SampleNames[i]+"/"+SampleNames[i]+"_mc_PostPred";
714  for(unsigned int f = 0; f < InputFiles.size(); f++)
715  {
716  TH1 *hist = static_cast<TH1*>(InputFiles[f]->Get(TempString.c_str()));
717 
718  double llh = GetLLH(hist);
719  std::cout<<" & "<<llh;
720  Total[f] += llh;
721  }
722  std::cout<<" \\\\"<<std::endl;
723  }
724  std::cout<<"Total";
725  for(unsigned int f = 0; f < InputFiles.size(); f++) {
726  std::cout<<" & "<<Total[f];
727  }
728  std::cout<<" \\\\"<<std::endl;
729  std::cout<<"\\hline"<<std::endl;
730  std::cout<<"\\end{tabular}"<<std::endl;
731  std::cout<<"\\end{table}"<<std::endl;
732  std::cout<<" "<<std::endl;
733 }
double GetLLH(TH1 *hist)

Variable Documentation

◆ PlotMan

M3::Plotting::PlottingManager* PlotMan = nullptr
Warning
KS: keep raw pointer or ensure manual delete of PlotMan. If spdlog in automatically deleted before PlotMan then destructor has some spdlog and this could cause segfault

Definition at line 15 of file PredictivePlotting.cpp.