MaCh3  2.5.0
Reference Guide
PredictivePlotting.cpp
Go to the documentation of this file.
1 //MaCh3 Includes
2 #include "PlottingUtils/PlottingUtils.h"
3 #include "PlottingUtils/PlottingManager.h"
4 
5 //this file has lots of usage of the ROOT plotting interface that only takes floats, turn this warning off for this CU for now
6 #pragma GCC diagnostic ignored "-Wfloat-conversion"
7 #pragma GCC diagnostic ignored "-Wconversion"
8 
12 
14 MaCh3Plotting::PlottingManager* PlotMan;
15 constexpr const double ScalingFactor = 10;
16 
17 std::vector<std::string> FindSamples(const std::string& File)
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 
39  SampleNames.push_back(dirname);
40  MACH3LOG_DEBUG("Entering Sample {}", dirname);
41  }
42 
43  file->Close();
44  delete file;
45  return SampleNames;
46 }
47 
48 std::vector<int> FindDimensions(const std::string& File, const std::vector<std::string>& Samples)
49 {
50  TFile *file = M3::Open(File, "READ", __FILE__, __LINE__);
51  TDirectoryFile *PredicitveDir = file->Get<TDirectoryFile>("Predictive");
52 
53  std::vector<int> SampleDimension;
54  for (const auto& sample : Samples)
55  {
56  // Get directory for this sample
57  TDirectoryFile* SampleDir = PredicitveDir->Get<TDirectoryFile>(sample.c_str());
58 
59  int Dimension = 0;
60 
61  while (true)
62  {
63  // Construct name Tutorial_mc_dimX
64  std::string histName = fmt::format("{}_mc_dim{}", sample, Dimension);
65 
66  TH2D* hist = SampleDir->Get<TH2D>(histName.c_str());
67  if (!hist) break; // stop when next dimension does not exist
68 
69  Dimension++;
70  }
71 
72  MACH3LOG_DEBUG("Sample '{}' has dimension {}", sample, Dimension);
73  SampleDimension.push_back(Dimension);
74  }
75 
76  file->Close();
77  delete file;
78 
79  return SampleDimension;
80 }
81 
82 double GetPValue(const TH2D* hist)
83 {
84  double pvalue = 0;
85  std::string TempTile = hist->GetTitle();
86  std::string temp = "=";
87 
88  std::string::size_type SizeType = TempTile.find(temp);
89  TempTile.erase(0, SizeType+1);
90  pvalue = atof(TempTile.c_str());
91  return pvalue;
92 }
93 
94 void PrintPosteriorPValue(const YAML::Node& Settings,
95  const std::vector<TFile*>& InputFiles,
96  const std::vector<std::string>& SampleNames)
97 {
98  MACH3LOG_INFO("Starting {}", __func__);
99  auto Titles = Get<std::vector<std::string>>(Settings["FileTitle"], __FILE__, __LINE__);
100  std::vector<std::vector<double>> FlucDrawVec(InputFiles.size());
101  // KS: Alternatively try "_drawfluc_draw"
102  std::string FlucutationType = "_predfluc_draw";
103  //KS: P-values per each sample
104  std::cout<<"\\begin{table}[htb]"<<std::endl;
105  std::cout<<"\\centering"<<std::endl;
106  std::cout<<"\\begin{tabular}{ | l | ";
107 
108  for(unsigned int f = 0; f < InputFiles.size(); f++)
109  {
110  std::cout<<"c | ";
111  }
112 
113  std::cout<<"} \\hline"<<std::endl;
114  std::cout<<"Sample ";
115  for(unsigned int f = 0; f < InputFiles.size(); f++)
116  {
117  std::cout<<"& \\multicolumn{1}{| c |}{" + Titles[f] +" p-value} ";
118  }
119  std::cout<<"\\\\"<<std::endl;
120  for(unsigned int f = 0; f < InputFiles.size(); f++)
121  {
122  std::cout<<" & Fluctuation of Prediction ";
123  }
124  std::cout<<"\\\\ \\hline"<<std::endl;
125  for(unsigned int i = 0; i < SampleNames.size(); i++)
126  {
127  std::cout<<SampleNames[i];
128  for(unsigned int f = 0; f < InputFiles.size(); f++)
129  {
130  std::string TempString = "Predictive/" + SampleNames[i]+"/"+SampleNames[i] + FlucutationType;
131  TH2D *hist2D = InputFiles[f]->Get<TH2D>(TempString.c_str());
132  double FlucDraw = GetPValue(hist2D);
133  std::cout<<" & "<<FlucDraw;
134  FlucDrawVec[f].push_back(FlucDraw);
135  }
136  std::cout<<" \\\\"<<std::endl;
137  }
138  std::cout<<"Total ";
139  for(unsigned int f = 0; f < InputFiles.size(); f++)
140  {
141  TH2D *hFlucPred = InputFiles[f]->Get<TH2D>(("Predictive/Total/Total" + FlucutationType).c_str());
142  double FlucDraw = GetPValue(hFlucPred);
143  std::cout<<" & "<<FlucDraw;
144  }
145  std::cout<<" \\\\ \\hline"<<std::endl;
146  std::cout<<"\\hline"<<std::endl;
147  std::cout<<"\\end{tabular}"<<std::endl;
148  std::cout<<"\\end{table}"<<std::endl;
149 
150  auto Threshold = GetFromManager<double>(Settings["Significance"], 0.05);
151  for(unsigned int f = 0; f < InputFiles.size(); f++)
152  {
153  MACH3LOG_INFO("Calculating Shape for file {}", Titles[f]);
154 
155  CheckBonferoniCorrectedpValue(SampleNames, FlucDrawVec[f], Threshold);
156  MACH3LOG_INFO("Combined pvalue following Fisher method: {:.4f}", FisherCombinedPValue(FlucDrawVec[f]));
157  }
158 }
159 
160 void OverlayViolin(const YAML::Node& Settings,
161  const std::vector<TFile*>& InputFiles,
162  const std::vector<std::string>& SampleNames,
163  const std::vector<int>& SampleDimension,
164  const std::unique_ptr<TCanvas>& canv)
165 {
166  MACH3LOG_INFO("Starting {}", __func__);
167  canv->Clear();
168 
169  canv->SetTopMargin(0.10);
170  canv->SetBottomMargin(0.12);
171  canv->SetRightMargin(0.075);
172  canv->SetLeftMargin(0.14);
173 
174  auto PosteriorColor = Get<std::vector<Color_t >>(Settings["PosteriorColor"], __FILE__, __LINE__);
175  auto Titles = Get<std::vector<std::string>>(Settings["FileTitle"], __FILE__, __LINE__);
176  const int nFiles = static_cast<int>(InputFiles.size());
177 
178  //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.
179  TCandle::SetScaledViolin(false);
180  for(size_t iSample = 0; iSample < SampleNames.size(); iSample++)
181  {
182  for(int iDim = 0; iDim < SampleDimension[iSample]; iDim++)
183  {
184  std::vector<std::unique_ptr<TH2D>> ViolinHist(nFiles);
185  for(int iFile = 0; iFile < nFiles; iFile++)
186  {
187  InputFiles[iFile]->cd();
188  ViolinHist[iFile] = M3::Clone(InputFiles[iFile]->Get<TH2D>(("Predictive/" + SampleNames[iSample]
189  + "/" + SampleNames[iSample] + "_mc_dim" + iDim).Data()));
190  ViolinHist[iFile]->SetTitle(PlotMan->style().prettifySampleName(SampleNames[iSample]).c_str());
191  ViolinHist[iFile]->SetLineColor(PosteriorColor[iFile]);
192  ViolinHist[iFile]->SetMarkerColor(PosteriorColor[iFile]);
193  ViolinHist[iFile]->SetFillColorAlpha(PosteriorColor[iFile], 0.35);
194  ViolinHist[iFile]->SetFillStyle(1001);
195  ViolinHist[iFile]->GetXaxis()->SetTitle(PlotMan->style().prettifyKinematicName(
196  ViolinHist[iFile]->GetXaxis()->GetTitle()).c_str());
197  ViolinHist[iFile]->GetYaxis()->SetTitle("Events");
198  }
199 
200  ViolinHist[0]->Draw("violinX(03100300)");
201  for(int iFile = 1; iFile < nFiles; iFile++) {
202  ViolinHist[iFile]->Draw("violinX(03100300) same");
203  }
204 
205  TLegend legend(0.50, 0.52, 0.90, 0.88);
206  for(int ig = 0; ig < nFiles; ig++) {
207  legend.AddEntry(ViolinHist[ig].get(), Form("%s", Titles[ig].c_str()), "lpf");
208  }
209  legend.SetLineStyle(0);
210  legend.SetTextSize(0.03);
211  legend.Draw();
212 
213  canv->Print("Overlay_Predictive.pdf", "pdf");
214  }
215  }
216 }
217 
218 void OverlayPredicitve(const YAML::Node& Settings,
219  const std::vector<TFile*>& InputFiles,
220  const std::vector<std::string>& SampleNames,
221  const std::vector<int>& SampleDimension,
222  const std::unique_ptr<TCanvas>& canv)
223 {
224  MACH3LOG_INFO("Starting {}", __func__);
225  canv->Clear();
226 
227  TPad* pad1 = new TPad("pad1","pad1",0,0.25,1,1);
228  pad1->AppendPad();
229  TPad* pad2 = new TPad("pad2","pad2",0,0,1,0.25);
230  pad2->AppendPad();
231 
232  pad1->SetGrid();
233  pad2->SetGrid();
234 
235  pad1->SetLeftMargin(canv->GetLeftMargin());
236  pad1->SetRightMargin(canv->GetRightMargin());
237  pad1->SetTopMargin(canv->GetTopMargin());
238  pad1->SetBottomMargin(0);
239 
240  pad2->SetLeftMargin(canv->GetLeftMargin());
241  pad2->SetRightMargin(canv->GetRightMargin());
242  pad2->SetTopMargin(0);
243  pad2->SetBottomMargin(0.28);
244 
245  auto PosteriorColor = Get<std::vector<Color_t >>(Settings["PosteriorColor"], __FILE__, __LINE__);
246  auto Titles = Get<std::vector<std::string>>(Settings["FileTitle"], __FILE__, __LINE__);
247 
248  if(Titles.size() < InputFiles.size() || PosteriorColor.size() < InputFiles.size()){
249  MACH3LOG_ERROR("Passed {} files, while only {} titles and {} colors", InputFiles.size(), Titles.size(), PosteriorColor.size());
250  throw MaCh3Exception(__FILE__, __LINE__);
251  }
252  for(size_t iSample = 0; iSample < SampleNames.size(); iSample++)
253  {
254  const int nFiles = static_cast<int>(InputFiles.size());
255  auto SampleName = SampleNames[iSample];
256  const int nDims = (SampleDimension[iSample] == 2) ? 2 : 1;
257  for(int iDim = 0; iDim < nDims; iDim++) {
258  std::string DataLocation = "";
259  if(nDims == 2) {
260  DataLocation = "Predictive/" + SampleName + "/Data_" + SampleName + "_Dim" + std::to_string(iDim);
261  } else {
262  DataLocation = "SampleFolder/data_" + SampleName;
263  }
264  TH1D* hist = InputFiles[0]->Get<TH1D>((DataLocation).c_str());
265 
266  std::unique_ptr<TH1D> DataHist = M3::Clone(hist);
267  DataHist->GetYaxis()->SetTitle(fmt::format("Events/{:.0f}", ScalingFactor).c_str());
268  M3::ScaleHistogram(DataHist.get(), ScalingFactor);
269  DataHist->SetLineColor(kBlack);
270  //KS: +1 for data, we want to get integral before scaling of the histogram
271  std::vector<double> Integral(nFiles+1);
272  Integral[nFiles] = DataHist->Integral();
273  std::vector<std::unique_ptr<TH1D>> PredHist(nFiles);
274 
275  for(int iFile = 0; iFile < nFiles; iFile++)
276  {
277  InputFiles[iFile]->cd();
278  std::string HistLocation = "";
279  if(nDims == 2) {
280  HistLocation = "Predictive/" + SampleName + "/" + SampleName + "_mc_PostPred_dim" + std::to_string(iDim);
281  } else {
282  HistLocation = "Predictive/" + SampleName + "/" + SampleName + "_mc_PostPred";
283  }
284  PredHist[iFile] = M3::Clone(InputFiles[iFile]->Get<TH1D>((HistLocation).c_str()));
285  Integral[iFile] = PredHist[iFile]->Integral();
286  PredHist[iFile]->SetTitle(PlotMan->style().prettifySampleName(SampleName).c_str());
287  PredHist[iFile]->SetLineColor(PosteriorColor[iFile]);
288  PredHist[iFile]->SetMarkerColor(PosteriorColor[iFile]);
289  PredHist[iFile]->SetFillColorAlpha(PosteriorColor[iFile], 0.35);
290  PredHist[iFile]->SetFillStyle(1001);
291  PredHist[iFile]->GetYaxis()->SetTitle(fmt::format("Events/{:.0f}", ScalingFactor).c_str());
292  M3::ScaleHistogram(PredHist[iFile].get(), ScalingFactor);
293  }
294  pad1->cd();
295 
296  PredHist[0]->Draw("p e2");
297  for(int iFile = 1; iFile < nFiles; iFile++)
298  {
299  PredHist[iFile]->Draw("p e2 same");
300  }
301  DataHist->Draw("he same");
302 
303  auto legend = std::make_unique<TLegend>(0.50,0.52,0.90,0.88);
304  legend->AddEntry(DataHist.get(), Form("Data, #int=%.0f", Integral[nFiles]),"le");
305  for(int ig = 0; ig < nFiles; ig++ ) {
306  legend->AddEntry(PredHist[ig].get(), Form("%s, #int=%.2f", Titles[ig].c_str(), Integral[ig]), "lpf");
307  }
308  legend->SetLineStyle(0);
309  legend->SetTextSize(0.03);
310  legend->Draw();
311 
313  pad2->cd();
314 
315  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);
316 
317  line->SetLineWidth(2);
318  line->SetLineColor(kBlack);
319  line->Draw("");
320 
321  std::unique_ptr<TH1D> RatioPlotData = M3::Clone(DataHist.get());
322  std::vector<std::unique_ptr<TH1D>> RatioPlot(nFiles);
323 
324  for(int ig = 0; ig < nFiles; ig++ )
325  {
326  RatioPlot[ig] = M3::Clone(DataHist.get());
327  RatioPlot[ig]->SetLineColor(PosteriorColor[ig]);
328  RatioPlot[ig]->SetMarkerColor(PosteriorColor[ig]);
329  RatioPlot[ig]->SetFillColorAlpha(PosteriorColor[ig], 0.35);
330  RatioPlot[ig]->SetFillStyle(1001);
331  RatioPlot[ig]->GetYaxis()->SetTitle("Data/MC");
332  auto PrettyX = PlotMan->style().prettifyKinematicName(PredHist[0]->GetXaxis()->GetTitle());
333  RatioPlot[ig]->GetXaxis()->SetTitle(PrettyX.c_str());
334  RatioPlot[ig]->SetBit(TH1D::kNoTitle);
335  RatioPlot[ig]->GetXaxis()->SetTitleSize(0.12);
336  RatioPlot[ig]->GetYaxis()->SetTitleOffset(0.4);
337  RatioPlot[ig]->GetYaxis()->SetTitleSize(0.10);
338 
339  RatioPlot[ig]->GetXaxis()->SetLabelSize(0.10);
340  RatioPlot[ig]->GetYaxis()->SetLabelSize(0.10);
341 
342  RatioPlot[ig]->Divide(PredHist[ig].get());
343  PassErrorToRatioPlot(RatioPlot[ig].get(), PredHist[ig].get(), DataHist.get());
344  }
345 
346  RatioPlotData->Divide(DataHist.get());
347  PassErrorToRatioPlot(RatioPlotData.get(), DataHist.get(), DataHist.get());
348 
349  double maxz = -999;
350  double minz = +999;
351  for (int j = 0; j < nFiles; j++) {
352  for (int i = 1; i < RatioPlot[0]->GetXaxis()->GetNbins(); i++) {
353  maxz = std::max(maxz, RatioPlot[j]->GetBinContent(i));
354  minz = std::min(minz, RatioPlot[j]->GetBinContent(i));
355  }
356  }
357  maxz = maxz*1.001;
358  minz = minz*1.001;
359 
360  if (std::fabs(1 - maxz) > std::fabs(1-minz))
361  RatioPlot[0]->GetYaxis()->SetRangeUser(1-std::fabs(1-maxz),1+std::fabs(1-maxz));
362  else
363  RatioPlot[0]->GetYaxis()->SetRangeUser(1-std::fabs(1-minz),1+std::fabs(1-minz));
364 
365  RatioPlot[0]->Draw("p e2");
366  for(int ig = 1; ig < nFiles; ig++ ) {
367  RatioPlot[ig]->Draw("p e2 same");
368  }
369  RatioPlotData->Draw("he same");
370 
371  canv->Print("Overlay_Predictive.pdf", "pdf");
372  }
373  }
374 
375  delete pad1;
376  delete pad2;
377 }
378 
380 void GetMeanError(TH1D* hist, double &Mean, double &Error){
381  TF1 *Gauss = hist->GetFunction("Fit"); //This name is hardcoded be careful
382  //KS: Get mean and error from Gauss
383  Mean = Gauss->GetParameter(1);
384  Error = Gauss->GetParameter(2);
385 
386  //KS: Get mean and error from HPD
387  //Mean = hist->GetMean();
388  //Error = hpost->GetRMS();
389 }
390 
392 void PrintPosteriorEventRates(const std::vector<TFile*>& InputFiles,
393  const std::vector<std::string>& SampleNames) {
394  MACH3LOG_INFO("Starting {}", __func__);
395  MACH3LOG_INFO("");
396 
397  double mean, error;
398  //KS: We now prepare to make tables for TN etc.
399  std::cout<<"\\begin{table}[htb]"<<std::endl;
400  std::cout<<"\\centering"<<std::endl;
401  std::cout<<"\\begin{tabular}{ | l |";
402  for(unsigned int f = 0; f < InputFiles.size(); f++)
403  {
404  std::cout<<" c |";
405  }
406  std::cout<<"} \\hline"<<std::endl;
407  std::cout<<"Sample ";
408  for(unsigned int f = 0; f < InputFiles.size(); f++)
409  {
410  std::cout<<"& Event Rates ";
411  }
412  std::cout<<"\\\\ \\hline"<<std::endl;
413  for(unsigned int i = 0; i < SampleNames.size(); i++)
414  {
415  std::cout<<SampleNames[i];
416  std::string TempString = "Predictive/" + SampleNames[i]+"/"+SampleNames[i]+"_sum";
417  for(unsigned int f = 0; f < InputFiles.size(); f++)
418  {
419  TH1D *hist = static_cast<TH1D*>(InputFiles[f]->Get(TempString.c_str()));
420  GetMeanError(hist, mean, error);
421  std::cout<<" & "<<mean<<" $\\pm$ "<<error;
422  }
423  std::cout<<" \\\\"<<std::endl;
424  }
425  std::cout<<"Total";
426  for(unsigned int f = 0; f < InputFiles.size(); f++)
427  {
428  TH1D *histTot = static_cast<TH1D*>(InputFiles[f]->Get("Predictive/Total/Total_sum"));
429  GetMeanError(histTot, mean, error);
430  std::cout<<" & "<<mean<<" $\\pm$ "<<error;
431  }
432  std::cout<<" \\\\"<<std::endl;
433  std::cout<<"\\hline"<<std::endl;
434  std::cout<<"\\end{tabular}"<<std::endl;
435  std::cout<<"\\end{table}"<<std::endl;
436  MACH3LOG_INFO("");
437 }
438 
440 void PrintPosteriorFractionalUncertainties(const std::vector<TFile*>& InputFiles,
441  const std::vector<std::string>& SampleNames) {
442  MACH3LOG_INFO("Starting {}", __func__);
443  MACH3LOG_INFO("");
444  double mean, error;
445 
446  //KS: Fractional uncertainties on the prior and posterior predictive event rates.
447  std::cout<<"\\begin{table}[htb]"<<std::endl;
448  std::cout<<"\\centering"<<std::endl;
449  std::cout<<"\\begin{tabular}{ | l |";
450  for(unsigned int f = 0; f < InputFiles.size(); f++)
451  {
452  std::cout<<" c |";
453  }
454  std::cout<<"} \\hline"<<std::endl;
455 
456  std::cout<<"Sample ";
457  for(unsigned int f = 0; f < InputFiles.size(); f++)
458  {
459  std::cout<<"& $\\delta N / N (\\%)$";
460  }
461  std::cout<<"\\\\ \\hline"<<std::endl;
462 
463  for(unsigned int i = 0; i < SampleNames.size(); i++)
464  {
465  std::cout<<SampleNames[i];
466  std::string TempString = "Predictive/" + SampleNames[i]+"/"+SampleNames[i]+"_sum";
467  for(unsigned int f = 0; f < InputFiles.size(); f++)
468  {
469  TH1D *hist = static_cast<TH1D*>(InputFiles[f]->Get(TempString.c_str()));
470  GetMeanError(hist, mean, error);
471  std::cout<<" & "<<error/mean*100;
472  }
473  std::cout<<" \\\\"<<std::endl;
474  }
475  std::cout<<"Total";
476  for(unsigned int f = 0; f < InputFiles.size(); f++)
477  {
478  TH1D *histTotal = static_cast<TH1D*>(InputFiles[f]->Get("Predictive/Total/Total_sum"));
479  GetMeanError(histTotal, mean, error);
480  std::cout<<" & "<<error/mean*100;
481  }
482  std::cout<<"\\\\ \\hline"<<std::endl;
483  std::cout<<"\\end{tabular}"<<std::endl;
484  std::cout<<"\\end{table}"<<std::endl;
485  MACH3LOG_INFO("");
486 }
487 
488 double GetLLH(TH1* hist)
489 {
490  std::string TempTile = hist->GetTitle();
491  std::string temp = "=";
492 
493  std::string::size_type SizeType = TempTile.find(temp);
494  TempTile.erase(0, SizeType+1);
495  double llh = atof(TempTile.c_str());
496  return llh;
497 }
498 
500 void PrintPredictiveLLH(const std::vector<TFile*>& InputFiles,
501  const std::vector<std::string>& SampleNames) {
502  MACH3LOG_INFO("Starting {}", __func__);
503  MACH3LOG_INFO("");
504 
505  std::vector<double> Total(InputFiles.size());
506  //KS: We now prepare to make tables for TN etc.
507  std::cout<<"\\begin{table}[htb]"<<std::endl;
508  std::cout<<"\\centering"<<std::endl;
509  std::cout<<"\\begin{tabular}{ | l |";
510  for(unsigned int f = 0; f < InputFiles.size(); f++)
511  {
512  Total[f] = 0.;
513  std::cout<<" c |";
514  }
515  std::cout<<"} \\hline"<<std::endl;
516  std::cout<<"Sample ";
517  for(unsigned int f = 0; f < InputFiles.size(); f++)
518  {
519  std::cout<<"& 2#log#mathcal{L}_{stat} ";
520  }
521  std::cout<<"\\\\ \\hline"<<std::endl;
522  for(unsigned int i = 0; i < SampleNames.size(); i++)
523  {
524  std::cout<<SampleNames[i];
525  std::string TempString = "Predictive/" + SampleNames[i]+"/"+SampleNames[i]+"_mc_PostPred";
526  for(unsigned int f = 0; f < InputFiles.size(); f++)
527  {
528  TH1 *hist = static_cast<TH1*>(InputFiles[f]->Get(TempString.c_str()));
529 
530  double llh = GetLLH(hist);
531  std::cout<<" & "<<llh;
532  Total[f] += llh;
533  }
534  std::cout<<" \\\\"<<std::endl;
535  }
536  std::cout<<"Total";
537  for(unsigned int f = 0; f < InputFiles.size(); f++) {
538  std::cout<<" & "<<Total[f];
539  }
540  std::cout<<" \\\\"<<std::endl;
541  std::cout<<"\\hline"<<std::endl;
542  std::cout<<"\\end{tabular}"<<std::endl;
543  std::cout<<"\\end{table}"<<std::endl;
544  std::cout<<" "<<std::endl;
545 }
546 
547 void PredictivePlotting(const std::string& ConfigName,
548  const std::vector<std::string>& FileNames)
549 {
550  auto canvas = std::make_unique<TCanvas>("canv", "canv", 1080, 1080);
551  // set the paper & margin sizes
552  canvas->SetTopMargin(0.11);
553  canvas->SetBottomMargin(0.16);
554  canvas->SetRightMargin(0.075);
555  canvas->SetLeftMargin(0.12);
556  canvas->SetGrid();
557 
558  gStyle->SetOptStat(0); //Set 0 to disable statistic box
559  gStyle->SetPalette(51);
560  gStyle->SetLegendBorderSize(0); //This option disables legends borders
561  gStyle->SetFillStyle(0);
562 
563  //To avoid TCanvas::Print> messages
564  gErrorIgnoreLevel = kWarning;
565 
566  auto Samples = FindSamples(FileNames[0]);
567  auto Dimensions = FindDimensions(FileNames[0], Samples);
568 
569  std::vector<TFile*> InputFiles(FileNames.size());
570  for(size_t i = 0; i < FileNames.size(); i++)
571  {
572  InputFiles[i] = M3::Open(FileNames[i], "READ", __FILE__, __LINE__);
573  }
574 
575  // Load the YAML file
576  YAML::Node Config = M3OpenConfig(ConfigName);
577  // Access the "MatrixPlotter" section
578  YAML::Node settings = Config["PredictivePlotting"];
579  canvas->Print("Overlay_Predictive.pdf[", "pdf");
580 
581  // Make overlay of 1D hists
582  OverlayPredicitve(settings, InputFiles, Samples, Dimensions, canvas);
583  // Make overlay of violin plots
584  OverlayViolin(settings, InputFiles, Samples, Dimensions, canvas);
585  // Get PValue per sample
586  PrintPosteriorPValue(settings, InputFiles, Samples);
587  // KS: Print Fractional Uncertainties into Latex table format
588  PrintPosteriorEventRates(InputFiles, Samples);
589  // KS: Print Fractional Uncertainties into Latex table format
590  PrintPosteriorFractionalUncertainties(InputFiles, Samples);
591  // KS: Print Predictive LLH into Latex table format
592  PrintPredictiveLLH(InputFiles, Samples);
593  canvas->Print("Overlay_Predictive.pdf]", "pdf");
594 
595  for(size_t i = 0; i < FileNames.size(); i++)
596  {
597  InputFiles[i]->Close();
598  delete InputFiles[i];
599  }
600 }
601 
602 
603 int main(int argc, char **argv)
604 {
606  if (argc < 3)
607  {
608  MACH3LOG_ERROR("Need at least two arguments, {} <Config.Yaml> <Prior/Post_PredOutput.root>", argv[0]);
609  throw MaCh3Exception(__FILE__, __LINE__);
610  }
611  std::string ConfigName = std::string(argv[1]);
612  // Collect all remaining arguments as file names
613  std::vector<std::string> FileNames;
614  for (int i = 2; i < argc; ++i) {
615  FileNames.emplace_back(argv[i]);
616  }
617 
618  PlotMan = new MaCh3Plotting::PlottingManager();
619  PlotMan->initialise();
620 
621  PredictivePlotting(ConfigName, FileNames);
622 
623  if(PlotMan) delete PlotMan;
624  return 0;
625 }
#define MACH3LOG_DEBUG
Definition: MaCh3Logger.h:34
#define MACH3LOG_ERROR
Definition: MaCh3Logger.h:37
#define MACH3LOG_INFO
Definition: MaCh3Logger.h:35
void SetMaCh3LoggerFormat()
Set messaging format of the logger.
Definition: MaCh3Logger.h:61
double GetLLH(TH1 *hist)
constexpr const double ScalingFactor
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)
double GetPValue(const TH2D *hist)
void PrintPosteriorPValue(const YAML::Node &Settings, const std::vector< TFile * > &InputFiles, const std::vector< std::string > &SampleNames)
void PredictivePlotting(const std::string &ConfigName, const std::vector< std::string > &FileNames)
int main(int argc, char **argv)
MaCh3Plotting::PlottingManager * PlotMan
std::vector< std::string > FindSamples(const std::string &File)
void GetMeanError(TH1D *hist, double &Mean, double &Error)
KS: Get mean and error from gaussian fit to event distribution.
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< 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.
int nFiles
Definition: ProcessMCMC.cpp:27
std::vector< std::string > FileNames
Definition: ProcessMCMC.cpp:28
double ** Mean
Definition: RHat.cpp:63
double FisherCombinedPValue(const std::vector< double > &pvalues)
KS: Combine p-values using Fisher's method.
void PassErrorToRatioPlot(TH1D *RatioHist, TH1D *Hist1, TH1D *DataHist)
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.
#define M3OpenConfig(filename)
Macro to simplify calling LoadYaml with file and line info.
Definition: YamlHelper.h:589
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.
void ScaleHistogram(TH1 *Sample_Hist, const double scale)
Scale histogram to get divided by bin width.
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.