MaCh3  2.5.0
Reference Guide
GetPostfitParamPlots.cpp
Go to the documentation of this file.
1 #include <iostream>
2 #include <sstream>
3 #include <iomanip>
4 #include <algorithm>
5 
6 #include "PlottingUtils/PlottingUtils.h"
7 #include "PlottingUtils/PlottingManager.h"
8 
10 #include "TROOT.h"
11 #include "TGaxis.h"
12 #include "TString.h"
13 #include "TStyle.h"
14 #include "TH1.h"
15 #include "TH2.h"
16 #include "TF1.h"
17 #include "TLegend.h"
18 #include "TPad.h"
19 #include "TCanvas.h"
20 #include "TTree.h"
21 #include "TFile.h"
22 #include "TVectorD.h"
23 #include "TCandle.h"
24 #include "TFrame.h"
25 #include "TGraphAsymmErrors.h"
27 
46 
47 //this file has lots of usage of the ROOT plotting interface that only takes floats, turn this warning off for this CU for now
48 #pragma GCC diagnostic ignored "-Wfloat-conversion"
49 #pragma GCC diagnostic ignored "-Wconversion"
50 
51 MaCh3Plotting::PlottingManager *PlotMan;
52 
55 
56 std::vector<int> NDSamplesBins;
57 std::vector<std::string> NDSamplesNames;
58 
59 std::string SaveName;
60 std::string plotType;
61 
62 void copyParToBlockHist(const int localBin, const std::string& paramName, TH1D* blockHist,
63  const std::string& type, const int fileId, const bool setLabels = true){
64  // Set the values in the sub-histograms
65  MACH3LOG_DEBUG("copying data from at local bin {}: for parameter {}", localBin, paramName);
66  MACH3LOG_DEBUG(" Fitter specific name: {}", PlotMan->input().translateName(fileId, MaCh3Plotting::kPostFit, paramName));
67  MACH3LOG_DEBUG(" value: {:.4f}", PlotMan->input().getPostFitValue(fileId, paramName, type));
68  MACH3LOG_DEBUG(" error: {:.4f}", PlotMan->input().getPostFitError(fileId, paramName, type));
69 
70  blockHist->SetBinContent(localBin +1, PlotMan->input().getPostFitValue(fileId, paramName, type));
71  blockHist->SetBinError(localBin +1, PlotMan->input().getPostFitError(fileId, paramName, type));
72 
73  if(setLabels){
74  blockHist->GetXaxis()->SetBinLabel(localBin +1, paramName.c_str());
75  blockHist->GetXaxis()->LabelsOption("v");
76  }
77 }
78 
79 void InitializePads(const TCanvas* canvas, TPad*& pad3, TPad*& pad4) {
80  // Initialize TPad p3
81  pad3 = new TPad("Top", "Top", 0.0, 0.4, 1.0, 1.0);
82  pad3->SetLeftMargin(canvas->GetLeftMargin());
83  pad3->SetRightMargin(canvas->GetRightMargin());
84  pad3->SetTopMargin(canvas->GetTopMargin());
85  pad3->SetBottomMargin(0);
86  pad3->SetGrid();
87 
88  // Initialize TPad p4
89  pad4 = new TPad("Bottom", "Bottom", 0.0, 0.0, 1.0, 0.4);
90  pad4->SetLeftMargin(canvas->GetLeftMargin());
91  pad4->SetRightMargin(canvas->GetRightMargin());
92  pad4->SetTopMargin(0);
93  pad4->SetBottomMargin(0.75);
94  pad4->SetGrid();
95 }
96 
97 void CopyViolinToBlock(TH2D* FullViolin, TH2D* ReducedViolin, const std::vector<std::string>& ParamNames) {
98  for(unsigned int i = 0; i < ParamNames.size(); i++)
99  {
100  int ParamBinId = M3::_BAD_INT_;
101  for (int ix = 0; ix < FullViolin->GetXaxis()->GetNbins(); ++ix) {
102  if(FullViolin->GetXaxis()->GetBinLabel(ix+1) == ParamNames[i])
103  {
104  ParamBinId = ix+1;
105  break;
106  }
107  }
108  if(ParamBinId == M3::_BAD_INT_) {
109  MACH3LOG_WARN("Didn't find param {}", ParamNames[i]);
110  continue;
111  }
112  //KS Fill content of reduced violin
113  for (int iy = 0; iy < FullViolin->GetYaxis()->GetNbins(); ++iy) {
114  ReducedViolin->SetBinContent(i+1, iy+1, FullViolin->GetBinContent(ParamBinId, iy+1));
115  ReducedViolin->GetXaxis()->SetBinLabel(i+1, ParamNames[i].c_str());
116  }
117  }
118  ReducedViolin->SetFillColor(FullViolin->GetFillColor());
119  ReducedViolin->SetFillColorAlpha(FullViolin->GetMarkerColor(), 0.35);
120  ReducedViolin->SetLineColor(FullViolin->GetMarkerColor());
121 
122  ReducedViolin->SetMarkerColor(FullViolin->GetMarkerColor());
123  ReducedViolin->SetMarkerStyle(FullViolin->GetMarkerStyle());
124  ReducedViolin->SetMarkerSize(FullViolin->GetMarkerSize());
125 
126  ReducedViolin->GetYaxis()->SetTitleOffset(FullViolin->GetTitleOffset());
127  ReducedViolin->GetYaxis()->SetTitle(FullViolin->GetYaxis()->GetTitle());
128  ReducedViolin->GetXaxis()->LabelsOption("v");
129 }
130 
131 template <typename HistType>
132 void PrettifyTitles(HistType* hist) {
133  int nBins = hist->GetXaxis()->GetNbins();
134  for(int i = 0; i < nBins; ++i) {
135  std::string title = hist->GetXaxis()->GetBinLabel(i+1);
136  title = PlotMan->style().prettifyParamName(title);
137  hist->GetXaxis()->SetBinLabel(i+1, title.c_str());
138  }
139 }
140 
141 bool ReadSettings(const std::shared_ptr<TFile>& File1)
142 {
143  MACH3LOG_DEBUG("Reading settings for file {}", File1->GetName());
144  #ifdef MACH3_DEBUG
145  File1->ls();
146  #endif
147  TTree *Settings = (File1->Get<TTree>("Settings"));
148 
149  // can't find settings tree :(
150  if (!Settings) return false;
151 
152  MACH3LOG_DEBUG("Got settings tree");
153  M3::Utils::Print(Settings);
154 
155  Settings->SetBranchAddress("NDParameters", &NDParameters);
156  Settings->SetBranchAddress("NDParametersStartingPos", &NDParametersStartingPos);
157 
158  std::vector<int> *NDSamples_Bins = 0;
159  std::vector<std::string> *NDSamples_Names = 0;
160  Settings->SetBranchAddress("NDSamplesNames", &NDSamples_Names);
161  Settings->SetBranchAddress("NDSamplesBins", &NDSamples_Bins);
162 
163  Settings->GetEntry(0);
164 
165  NDSamplesNames = *NDSamples_Names;
166  NDSamplesBins = *NDSamples_Bins;
167 
168  MACH3LOG_DEBUG("Read settings tree successfully");
169  return true;
170 }
171 
172 std::unique_ptr<TH1D> makeRatio(TH1D *PrefitCopy, TH1D *PostfitCopy, bool setAxes) {
173  // set up the ratio hist
174  std::unique_ptr<TH1D> Ratio = M3::Clone(PrefitCopy);
175  Ratio->GetYaxis()->SetTitle("(x_{Post}-#mu_{Prior})/#sigma_{Prior}");
176  Ratio->SetMinimum(-3.7);
177  Ratio->SetMaximum(3.7);
178 
179  for (int j = 0; j < Ratio->GetXaxis()->GetNbins(); ++j)
180  {
181  if ( PrefitCopy->GetBinError(j+1) > 1.e-5 )
182  {
183  Ratio->SetBinContent(j+1, (PostfitCopy->GetBinContent(j+1)-PrefitCopy->GetBinContent(j+1))/PrefitCopy->GetBinError(j+1));
184 
185  double up = (PostfitCopy->GetBinContent(j+1)+PostfitCopy->GetBinError(j+1)-PrefitCopy->GetBinContent(j+1))/PrefitCopy->GetBinError(j+1);
186  double down = (PostfitCopy->GetBinContent(j+1)-PostfitCopy->GetBinError(j+1)-PrefitCopy->GetBinContent(j+1))/PrefitCopy->GetBinError(j+1);
187 
188  double maximum = up-Ratio->GetBinContent(j+1);
189  double minimum = Ratio->GetBinContent(j+1)-down;
190 
191  Ratio->SetBinError(j+1, std::max(maximum, minimum));
192  }
193  //KS: Most likely flat prior
194  else {
195  Ratio->SetBinContent(j+1, (PostfitCopy->GetBinContent(j+1)-PrefitCopy->GetBinContent(j+1)));
196 
197  double up = (PostfitCopy->GetBinContent(j+1)+PostfitCopy->GetBinError(j+1)-PrefitCopy->GetBinContent(j+1));
198  double down = (PostfitCopy->GetBinContent(j+1)-PostfitCopy->GetBinError(j+1)-PrefitCopy->GetBinContent(j+1));
199 
200  double maximum = up-Ratio->GetBinContent(j+1);
201  double minimum = Ratio->GetBinContent(j+1)-down;
202 
203  Ratio->SetBinError(j+1, std::max(maximum, minimum));
204  }
205  } //end loop over parameters
206 
207  if(setAxes){
208  Ratio->SetFillStyle(0);
209  Ratio->SetFillColor(0);
210 
211  Ratio->SetLineColor(PostfitCopy->GetLineColor());
212  if (Ratio->GetLineColor() == 0) Ratio->SetLineColor(kBlack);
213  Ratio->SetMarkerColor(PostfitCopy->GetMarkerColor());
214 
215  Ratio->SetLineWidth(PlotMan->getOption<int>("plotLineWidth"));
216  Ratio->SetTitle("");
217 
218  Ratio->SetMarkerSize(2);
219  Ratio->SetMarkerStyle(20);
220 
221  Ratio->GetYaxis()->SetTitleSize(25);
222  Ratio->GetYaxis()->SetTitleFont(43);
223  Ratio->GetYaxis()->SetTitleOffset(2.0);
224  Ratio->GetYaxis()->SetLabelFont(43);
225  Ratio->GetYaxis()->SetLabelSize(25);
226  Ratio->GetYaxis()->CenterTitle();
227  Ratio->GetYaxis()->SetNdivisions(5,2,0);
228 
229  Ratio->GetXaxis()->SetTitleSize(25);
230  Ratio->GetXaxis()->SetTitleFont(43);
231  Ratio->GetXaxis()->SetTitleOffset(4.0);
232  Ratio->GetXaxis()->SetLabelOffset(0.025);
233  Ratio->GetXaxis()->SetLabelFont(43);
234  Ratio->GetXaxis()->SetLabelSize(25);
235  }
236 
237  return Ratio;
238 }
239 
240 bool IsInvalidHist(const TH1D* hist, double invalid = M3::_BAD_DOUBLE_)
241 {
242  if (!hist) return true;
243 
244  const int nBins = hist->GetNbinsX();
245 
246  for (int i = 1; i <= nBins; i++) {
247  double val = hist->GetBinContent(i);
248 
249  // If ANY bin is valid → histogram is usable
250  if (val != invalid) {
251  return false;
252  }
253  }
254 
255  // All bins are invalid
256  return true;
257 }
258 
259 void DrawPlots(TCanvas *plotCanv, TH1D* PrefitCopy, const std::vector<std::unique_ptr<TH1D>>& PostfitVec,
260  TPad *mainPad, TPad *ratioPad, const std::string& OutName) {
261  // KS: If plot is invalid for some reason simply do not plot
262  if(IsInvalidHist(PrefitCopy)) return;
263 
264  // Draw!
265  plotCanv->cd();
266  mainPad->Draw();
267  mainPad->cd();
268  PrefitCopy->GetYaxis()->SetTitle("Parameter Value");
269 
270  PrefitCopy->GetYaxis()->SetLabelSize(0.);
271  PrefitCopy->GetYaxis()->SetTitleSize(0.05);
272  PrefitCopy->GetYaxis()->SetTitleOffset(1.3);
273  PrefitCopy->Draw("e2");
274 
275  for (int fileId = 0; fileId < static_cast<int>(PostfitVec.size()); fileId++) {
276  TH1D *postFitHist = PostfitVec[fileId].get();
277 
278  postFitHist->SetMarkerColor(TColor::GetColorPalette(fileId));
279  postFitHist->SetLineColor(TColor::GetColorPalette(fileId));
280  postFitHist->SetMarkerStyle(7);
281  postFitHist->SetLineStyle(1+fileId);
282  postFitHist->SetLineWidth(PlotMan->getOption<int>("plotLineWidth"));
283 
284  postFitHist->Draw("e1, same");
285  }
286 
287  plotCanv->Update();
288  auto axis = std::make_unique<TGaxis>(PrefitCopy->GetXaxis()->GetBinLowEdge(PrefitCopy->GetXaxis()->GetFirst()), gPad->GetUymin()+0.01,
289  PrefitCopy->GetXaxis()->GetBinLowEdge(PrefitCopy->GetXaxis()->GetFirst()), gPad->GetUymax(),
290  gPad->GetUymin()+0.01, gPad->GetUymax(), 510, "");
291  axis->SetLabelFont(43);
292  axis->SetLabelSize(25);
293  axis->Draw();
294 
295  plotCanv->cd();
296  ratioPad->Draw();
297  ratioPad->cd();
298 
299  std::vector<std::unique_ptr<TH1D>> ratioHists;
300  // save pointers to these so we can delete them once we are done
301  ratioHists.push_back(makeRatio(PrefitCopy, PostfitVec[0].get(), true));
302 
303  ratioHists[0]->Draw("p");
304  for(int postFitIdx = 1; postFitIdx < static_cast<int>(PostfitVec.size()); postFitIdx++){
305  ratioHists.push_back(makeRatio(PrefitCopy, PostfitVec[postFitIdx].get(), true));
306 
307  ratioHists[postFitIdx]->SetMarkerColor(TColor::GetColorPalette(postFitIdx));
308  ratioHists[postFitIdx]->SetLineColor(TColor::GetColorPalette(postFitIdx));
309  ratioHists[postFitIdx]->SetMarkerStyle(7);
310  ratioHists[postFitIdx]->SetLineStyle(1+postFitIdx);
311  ratioHists[postFitIdx]->SetLineWidth(PlotMan->getOption<int>("plotLineWidth"));
312 
313  ratioHists[postFitIdx]->Draw("p same");
314  }
315 
316  // draw lines across the plot at +-1 and 0
317  TLine line(ratioHists[0]->GetXaxis()->GetBinLowEdge(ratioHists[0]->GetXaxis()->GetFirst()), 0.0, ratioHists[0]->GetXaxis()->GetBinLowEdge(ratioHists[0]->GetXaxis()->GetLast()+1), 0.0);
318  TLine line2(ratioHists[0]->GetXaxis()->GetBinLowEdge(ratioHists[0]->GetXaxis()->GetFirst()), 1.0, ratioHists[0]->GetXaxis()->GetBinLowEdge(ratioHists[0]->GetXaxis()->GetLast()+1), 1.0);
319  TLine line3(ratioHists[0]->GetXaxis()->GetBinLowEdge(ratioHists[0]->GetXaxis()->GetFirst()), -1.0, ratioHists[0]->GetXaxis()->GetBinLowEdge(ratioHists[0]->GetXaxis()->GetLast()+1), -1.0);
320 
321  line.SetLineColor(kRed);
322  line.SetLineStyle(kDashed);
323  line.SetLineWidth(PlotMan->getOption<int>("refLineWidth"));
324  line2.SetLineColor(kRed);
325  line2.SetLineStyle(kDashed);
326  line2.SetLineWidth(PlotMan->getOption<int>("refLineWidth"));
327  line3.SetLineColor(kRed);
328  line3.SetLineStyle(kDashed);
329  line3.SetLineWidth(PlotMan->getOption<int>("refLineWidth"));
330 
331  line.Draw("same");
332  line2.Draw("same");
333  line3.Draw("same");
334 
335  plotCanv->Print((OutName).c_str());
336 }
337 
338 void MakeParameterPlots(TCanvas* canv)
339 {
340  // get the names of the blocks of parameters to group together
341  std::vector<std::string> const blockNames = PlotMan->getOption<std::vector<std::string>>("paramGroups");
342  const int nPlots = static_cast<int>(blockNames.size());
343 
344  TPad *p3 = nullptr;
345  TPad *p4 = nullptr;
346  // these for named parameters where we need a nice big gap at the botto to fit the names
347  InitializePads(canv, p3, p4);
348 
349  for (int i = 0; i < nPlots; i++)
350  {
351  // get the configuration for this parameter
352  std::string blockName = blockNames[i];
353  YAML::Node paramBlock = PlotMan->getOption(blockName);
354  auto blockTitle = paramBlock[0].as<std::string>();
355  auto blockLimits = paramBlock[1].as<std::vector<double>>();
356  auto blockContents = paramBlock[2].as<std::vector<std::string>>();
357 
358  // get num of params in the block
359  const int nParams = static_cast<int>(blockContents.size());
360 
361  // set some plot things
362  auto blockHist_prefit = std::make_unique<TH1D>(blockName.c_str(), blockTitle.c_str(),
363  nParams, 0.0, static_cast<double>(nParams));
364 
365  PlotMan->style().setTH1Style(blockHist_prefit.get(), PlotMan->getOption<std::string>("prefitHistStyle"));
366 
367  // set the errors for the prefit block hist
368  for(int localBin=0; localBin < nParams; localBin ++){
369  // the "local" bin is the params index within the group of parameters
370  std::string paramName = blockContents[localBin];
371  copyParToBlockHist(localBin, paramName, blockHist_prefit.get(), "Prior", 0);
372  }
373 
374  // now set for the postfit blocks for all files
375  std::vector <std::unique_ptr<TH1D>> blockHist_postfit_Vec;
376  for(unsigned int fileId = 0; fileId < PlotMan->getNFiles(); fileId++) {
377  auto blockHist_postfit = std::make_unique<TH1D>((blockName + PlotMan->getFileName(fileId)).c_str(),
378  blockTitle.c_str(), nParams, 0.0, static_cast<double>(nParams));
379 
380  // loop through all the parameters in this block and set the contents in the blocks TH1
381  for(int localBin=0; localBin < nParams; localBin ++){
382  // the "local" bin is the params index within the group of parameters
383  std::string paramName = blockContents[localBin];
384  copyParToBlockHist(localBin, paramName, blockHist_postfit.get(), "", fileId);
385  }
386  blockHist_postfit_Vec.push_back(std::move(blockHist_postfit));
387  }
388  // set the y axis limits we got from config
389  blockHist_prefit->GetYaxis()->SetRangeUser(blockLimits[0], blockLimits[1]);
390 
391  // Do some fancy replacements
392  PrettifyTitles(blockHist_prefit.get());
393 
394  DrawPlots(canv, blockHist_prefit.get(), blockHist_postfit_Vec, p3, p4, SaveName);
395  }
396  delete p3;
397  delete p4;
398 }
399 
400 void MakeFluxPlots(TCanvas* canv)
401 {
402  // these for non named params where we don't need as much space
403  auto p1 = std::make_unique<TPad>("p1", "p1", 0.0, 0.3, 1.0, 1.0);
404  auto p2 = std::make_unique<TPad>("p2", "p2", 0.0, 0.0, 1.0, 0.3);
405  p1->SetLeftMargin(canv->GetLeftMargin());
406  p1->SetRightMargin(canv->GetRightMargin());
407  p1->SetTopMargin(canv->GetTopMargin());
408  p1->SetBottomMargin(0);
409  p1->SetGrid();
410  p2->SetLeftMargin(canv->GetLeftMargin());
411  p2->SetRightMargin(canv->GetRightMargin());
412  p2->SetTopMargin(0);
413  p2->SetBottomMargin(0.25);
414  p2->SetGrid();
415 
416  p1->SetLogx(true);
417  p2->SetLogx(true);
418 
419  // get the names of the blocks of parameters to group together
420  std::vector<std::string> const fluxBlockNames = PlotMan->getOption<std::vector<std::string>>("fluxGroups");
421  auto const fluxBinningTable = PlotMan->getOption("FluxBinning");
422 
423  const int FluxPlots = static_cast<int>(fluxBlockNames.size());
424 
425  for (int i = 0; i < FluxPlots; i++)
426  {
427  // get the configuration for this block
428  std::string fluxBlockName = fluxBlockNames[i];
429  YAML::Node paramBlock = PlotMan->getOption(fluxBlockName);
430  std::string blockTitle = paramBlock[0].as<std::string>();
431  std::vector<double> blockLimits = paramBlock[1].as<std::vector<double>>();
432  std::string blockBinningName = paramBlock[2].as<std::string>();
433  std::vector<int> blockContents = paramBlock[3].as<std::vector<int>>();
434 
435  // get the binning for this block of flux params
436  std::vector<double> binning = fluxBinningTable[blockBinningName].as<std::vector<double>>();
437 
438  // get num of params in the block
439  int nParams = blockContents[1] - blockContents[0] +1;
440  // check for sanity
441  if(nParams <= 0 || blockContents.size() > 2){
442  MACH3LOG_CRITICAL("Invalid flux parameter block endpoints specified for {}", fluxBlockName);
443  MACH3LOG_CRITICAL(" Should have the form [<low index>, <up index>]");
444  throw MaCh3Exception(__FILE__ , __LINE__ );
445  }
446  if (nParams != static_cast<int>(binning.size()) - 1) {
447  MACH3LOG_CRITICAL("Binning provided for flux param block {} does not match the number of parameters specified for the block", fluxBlockName);
448  MACH3LOG_CRITICAL(" Provided {} parameters but {} bins", nParams, binning.size() -1);
449  throw MaCh3Exception(__FILE__ , __LINE__ );
450  }
451 
452  auto blockHist_prefit = std::make_unique<TH1D>(fluxBlockName.c_str(), blockTitle.c_str(), nParams, binning.data());
453  blockHist_prefit->GetYaxis()->SetTitle("Parameter Variation");
454  blockHist_prefit->GetXaxis()->SetTitle("E_{#nu} (GeV)");
455  blockHist_prefit->GetXaxis()->SetTitleOffset(blockHist_prefit->GetXaxis()->GetTitleOffset()*1.2);
456  PlotMan->style().setTH1Style(blockHist_prefit.get(), PlotMan->getOption<std::string>("prefitHistStyle"));
457  // set the errors for the prefit block hist
458  for(int fluxParId = blockContents[0]; fluxParId <= blockContents[1]; fluxParId++){
459  int localBin = fluxParId - blockContents[0];
460  std::string paramName = "b_" + std::to_string(fluxParId);
461  copyParToBlockHist(localBin, paramName, blockHist_prefit.get(), "Prior", 0, false);
462  }
463 
464  // now set for the postfit blocks for all files
465  std::vector <std::unique_ptr<TH1D>> blockHist_postfit_Vec;
466  for(unsigned int fileId = 0; fileId < PlotMan->getNFiles(); fileId++){
467  auto blockHist_postfit = std::make_unique<TH1D>(fluxBlockName.c_str(), blockTitle.c_str(), nParams, binning.data());
468 
469  for(int fluxParId = blockContents[0]; fluxParId <= blockContents[1]; fluxParId++){
470  int localBin = fluxParId - blockContents[0];
471  std::string paramName = "b_" + std::to_string(fluxParId);
472 
473  copyParToBlockHist(localBin, paramName, blockHist_postfit.get(), "", fileId, false);
474  }
475  blockHist_postfit_Vec.push_back(std::move(blockHist_postfit));
476  }
477  // set the y axis limits we got from config
478  blockHist_prefit->GetYaxis()->SetRangeUser(blockLimits[0], blockLimits[1]);
479  DrawPlots(canv, blockHist_prefit.get(), blockHist_postfit_Vec, p1.get(), p2.get(), SaveName);
480  }
481 
482  canv->cd();
483  canv->SetLogx(false);
484  canv->SetBottomMargin(canv->GetBottomMargin()*1.7);
485 }
486 
489 {
490  MACH3LOG_INFO("ND detector parameters: {}", NDParameters);
491  auto canv = std::make_unique<TCanvas>("canv", "canv", 1024, 1024);
492  //gStyle->SetPalette(51);
493  gStyle->SetOptStat(0); //Set 0 to disable statistic box
494  canv->SetLeftMargin(0.12);
495  canv->SetBottomMargin(0.12);
496  canv->SetTopMargin(0.08);
497  canv->SetRightMargin(0.04);
498 
499  // make a dummy TH1 to set out legend
500  TH1D* Prefit = new TH1D();
501  PlotMan->style().setTH1Style(Prefit, PlotMan->getOption<std::string>("prefitHistStyle"));
502  Prefit->GetYaxis()->SetTitleOffset(Prefit->GetYaxis()->GetTitleOffset()*1.2);
503 
504  TPad* pTop = nullptr;
505  TPad* pDown = nullptr;
506  InitializePads(canv.get(), pTop, pDown);
507 
508  int NDbinCounter = NDParametersStartingPos;
509  int Start = NDbinCounter;
510 
511  MACH3LOG_INFO("Running on {} samples", NDSamplesNames.size());
512 
513  for (unsigned int i = 0; i < NDSamplesNames.size(); ++i)
514  {
515  MACH3LOG_DEBUG("--- On sample {}", NDSamplesNames[i]);
516  NDbinCounter += NDSamplesBins[i];
517 
518  std::vector<std::unique_ptr<TH1D>> PostfitNDDetHistVec(PlotMan->getNFiles());
519  TH1D *PreFitNDDetHist = PlotMan->input().getFile(0).file->Get<TH1D>(Form("param_%s_prefit", NDSamplesNames[i].c_str()));
520  PlotMan->style().setTH1Style(PreFitNDDetHist, PlotMan->getOption<std::string>("prefitHistStyle"));
521 
522  std::string temp = NDSamplesNames[i].c_str();
523  while (temp.find("_") != std::string::npos) {
524  temp.replace(temp.find("_"), 1, std::string(" "));
525  }
526  PreFitNDDetHist->SetTitle(temp.c_str());
527  PreFitNDDetHist->GetXaxis()->SetRangeUser(Start, NDbinCounter);
528 
529  MACH3LOG_DEBUG(" Start bin: {} :: End bin: {}", Start, NDbinCounter);
530  // set the x range for the postfits
531  for(unsigned int fileId = 0; fileId < PlotMan->getNFiles(); fileId++){
532  PostfitNDDetHistVec[fileId] = M3::Clone(PlotMan->input().getFile(fileId).file->Get<TH1D>(Form("param_%s_%s", NDSamplesNames[i].c_str(), plotType.c_str())));
533  }
534 
535  //KS: We don't' need name for every nd param
536  for(int j = 0; j < NDSamplesBins[i]; ++j)
537  {
538  bool ProductOfTen = false;
539  if(j % 10) ProductOfTen = true;
540  if(j != 0 && ProductOfTen) PreFitNDDetHist->GetXaxis()->SetBinLabel(Start+j+1, " ");
541  else{
542  PreFitNDDetHist->GetXaxis()->SetBinLabel(Start+j+1, Form("Det Variation Bin %i", Start+j));
543  }
544  }
545 
546  PreFitNDDetHist->GetYaxis()->SetRangeUser(PlotMan->getOption<double>("detParYRange_low"), PlotMan->getOption<double>("detParYRange_high"));
547 
548  Start += NDSamplesBins[i];
549 
550  DrawPlots(canv.get(), PreFitNDDetHist, PostfitNDDetHistVec, pTop, pDown, SaveName);
551  canv->Update();
552  }
553  delete pTop;
554  delete pDown;
555  delete Prefit;
556 }
557 
559 {
560  gStyle->SetPalette(51);
561 
562  auto blankCanv = std::make_unique<TCanvas>("blankCanv", "blankCanv", 2048, 2048);
563  blankCanv->SaveAs("RidgePlots.pdf[");
564 
565  // get the names of the blocks of parameters to group together
566  const auto blockNames = PlotMan->getOption<std::vector<std::string>>("paramGroups");
567  const int nPlots = static_cast<int>(blockNames.size());
568 
569  constexpr double padTopMargin = 0.9;
570  constexpr double padBottomMargin = 0.1;
571  constexpr double padOverlap = 0.9;
572  constexpr double ridgeLineWidth = 1.0;
573  for (int i = 0; i < nPlots; i++)
574  {
575  // get the configuration for this parameter
576  std::string blockName = blockNames[i];
577  auto const &paramBlock = PlotMan->getOption(blockName);
578  auto blockTitle = paramBlock[0].as<std::string>();
579  auto blockLimits = paramBlock[1].as<std::vector<double>>();
580  auto blockContents = paramBlock[2].as<std::vector<std::string>>();
581 
582  // the directory of histograms
583  TDirectoryFile *posteriorDir = PlotMan->input().getFile(0).file->Get<TDirectoryFile>("Post_1d_hists");
584 
585  // get num of params in the block
586  int nParams = static_cast<int>(blockContents.size());
587 
588  if (nParams == 1) {
589  MACH3LOG_WARN("{} doesn't work for single param", __func__);
590  continue;
591  }
592  auto ridgeCanv = std::make_unique<TCanvas>("RidgePlotCanv", "RidgePlotCanv", 2048, 2048);
593  ridgeCanv->Divide(1,1+nParams, 0.01, 0.0);
594 
595  auto title = std::make_unique<TLatex>();
596  title->SetTextAlign(21);
597  title->SetTextSize(0.03);
598  title->DrawLatex(0.5, 0.95, blockTitle.c_str());
599 
600  auto label = std::make_unique<TLatex>();
601  label->SetTextAlign(31);
602  label->SetTextSize(0.02);
603 
604  auto line = std::make_unique<TLine>();
605  line->SetLineColor(kBlack);
606  line->SetLineWidth(ridgeLineWidth);
607 
608  // use this to set the limits and also to plot the x axis and grid
609  auto axisPlot = std::make_unique<TH1D>("axis plot", "", 1, blockLimits[0], blockLimits[1]);
610 
611  std::vector<std::unique_ptr<TH1D>> axisPlot_holder(nParams);
612  std::vector<std::unique_ptr<TPad>> graph_holder(nParams);
613  for(int parId = 0; parId < nParams; parId++) {
614  std::string paramName = blockContents[parId];
615 
616  TH1D *posteriorDist = nullptr;
617  // get the list of objects in the directory
618  TIter next(posteriorDir->GetListOfKeys());
619  while (TKey* key = static_cast<TKey*>(next())) {
620  // check if the end of the param name matches with the MaCh3 name, do this so we exclude things like nds_ at the start of the name
621  std::string str(key->GetTitle());
622  std::string name = PlotMan->input().translateName(0, MaCh3Plotting::kPostFit, paramName);
623  uint pos = str.find(name);
624  bool foundPar = (pos == str.length() - name.length());
625 
626  MACH3LOG_TRACE("Looking for {} in {}", name, str);
627  if(foundPar){
628  MACH3LOG_TRACE("Found it");
629  posteriorDist = posteriorDir->Get<TH1D>(key->GetName());
630  }
631  }
632 
633  if(posteriorDist == nullptr){
634  MACH3LOG_WARN("Couldn't find parameter {} when making ridgeline plots", paramName);
635  MACH3LOG_WARN("It could be fixed param");
636  continue;
637  }
638 
639  // EM: do some funky scaling so that we always get evenly spaced pads in the range [bottomMargin, TopMargin] with the specified overlap
640  double padAnchor = padBottomMargin + (static_cast<double>(nParams - parId - 1) /
641  static_cast<double>(nParams - 1)) * (padTopMargin - padBottomMargin);
642  double padWidth = (padTopMargin - padBottomMargin) / static_cast<double>(nParams);
643  double norm = (padTopMargin - padBottomMargin);
644 
645  double padTop = padWidth * (1.0 + padOverlap) * (padTopMargin - padAnchor) / norm + padAnchor;
646  double padBottom = padAnchor - padWidth * (1.0 + padOverlap) * (padAnchor - padBottomMargin) / norm;
647 
648  auto pad = std::make_unique<TPad>(paramName.c_str(), "", 0.3, padBottom, 0.9, padTop, -1, 0, -1);
649  ridgeCanv->cd();
650 
651  pad->SetBottomMargin(0.0);
652  pad->SetTopMargin(0.0);
653  pad->SetLeftMargin(0.0);
654  pad->SetRightMargin(0.0);
655 
656  pad->Draw();
657  pad->cd();
658  pad->SetFillStyle(4000);
659 
660  gPad->SetFrameFillStyle(4000);
661  posteriorDist->GetFunction("Gauss")->SetBit(TF1::kNotDraw);
662  posteriorDist->SetTitle("");
663  posteriorDist->SetLineWidth(ridgeLineWidth);
664 
665  auto axisPlot_tmp = M3::Clone(axisPlot.get(), Form("AxisPlot_%s", paramName.c_str()));
666  axisPlot_tmp->Draw("A");
667  posteriorDist->Draw("H SAME");
668 
669  axisPlot_tmp->GetYaxis()->SetRangeUser(0.0, 0.7 *posteriorDist->GetMaximum());
670  posteriorDist->SetLineColor(kWhite);
671  posteriorDist->SetFillColorAlpha(TColor::GetColorPalette(floor(static_cast<float>(parId) *
672  TColor::GetNumberOfColors() / static_cast<float>(nParams))), 0.85);
673 
674  posteriorDist->GetXaxis()->SetRangeUser(blockLimits[0], blockLimits[1]);
675  posteriorDist->GetYaxis()->SetTitle(paramName.c_str());
676 
677  //EM: Have to get the frame drawn by the histogram and then set it to be transparent... it took me an hour to get rid of this one line on a plot
678  gPad->Modified(); gPad->Update();
679  TFrame *frame = gPad->GetFrame();
680  frame->SetLineColorAlpha(0, 0.0);
681 
682  ridgeCanv->cd();
683  label->DrawLatexNDC(0.29, padBottom + 0.005, PlotMan->style().prettifyParamName(paramName).c_str());
684  line->DrawLine(0.1, padBottom, 0.9, padBottom);
685 
686  axisPlot_holder[parId] = std::move(axisPlot_tmp);
687  graph_holder[parId] = std::move(pad);
688  }
689 
690  ridgeCanv->cd();
691  ridgeCanv->SetGrid(1,1);
692  auto axisPad = std::make_unique<TPad>("AxisPad", "", 0.3, 0.0, 0.9, 1.0, -1, 0, -1);
693  axisPad->SetLeftMargin(0.0);
694  axisPad->SetRightMargin(0.0);
695  axisPad->Draw();
696  axisPad->cd();
697  axisPad->SetGrid(1,1);
698  axisPad->SetFrameFillStyle(4000);
699 
700  axisPlot->GetXaxis()->SetTickSize(0.01);
701  axisPlot->GetXaxis()->SetTitle("Parameter Variation");
702  axisPlot->GetYaxis()->SetLabelOffset(9999);
703  axisPlot->GetYaxis()->SetLabelSize(0);
704  axisPlot->GetYaxis()->SetTickSize(0);
705  axisPlot->GetYaxis()->SetAxisColor(0,0.0);
706  axisPlot->Draw("AXIS");
707  axisPlot->Draw("AXIG SAME");
708 
709  axisPlot->SetFillStyle(4000);
710  axisPad->SetFillStyle(4000);
711 
712  axisPad->SetGrid(1,1);
713  gPad->Modified(); gPad->Update();
714  gPad->SetFrameFillStyle(4000);
715 
716  gPad->Modified(); gPad->Update();
717  TFrame *frame = gPad->GetFrame();
718  frame->SetLineColorAlpha(0, 0.0);
719 
720  ridgeCanv->SaveAs("RidgePlots.pdf");
721  }
722  blankCanv->SaveAs("RidgePlots.pdf]");
723 }
724 
726 {
727  SaveName = PlotMan->getOutputName();
728 
729  //KS: By default we take HPD values, but by changing "plotType" you can use for example Gauss
730  plotType = "HPD";
731  //plotType = "gaus";
732 
733  MACH3LOG_INFO("Plotting {} errors", plotType);
734 
735  // if we have one MaCh3 nd file then we can get settings from it
736  bool plotNDDet = false;
737  for (size_t fileId = 0; fileId < PlotMan->input().getNInputFiles(); fileId++) {
738  if(!ReadSettings(PlotMan->input().getFile(0).file)) {
739  MACH3LOG_INFO("at least one file provided does not have 'settings' tree indicating it is not MaCh3 ND file");
740  MACH3LOG_INFO(" sadly this means I cannot plot ND Det parameters as this is only supported for MaCh3 ND files for now... sorry :(");
741  plotNDDet = false;
742  }
743  }
744 
745  auto canv = std::make_unique<TCanvas>("canv", "canv", 1024, 1024);
746  //gStyle->SetPalette(51);
747  gStyle->SetOptStat(0); //Set 0 to disable statistic box
748  canv->SetLeftMargin(0.12);
749  canv->SetBottomMargin(0.12);
750  canv->SetTopMargin(0.08);
751  canv->SetRightMargin(0.04);
752  canv->Print((SaveName+"[").c_str());
753 
754  // Make a Legend page
755  auto leg = std::make_unique<TLegend>(0.0, 0.0, 1.0, 1.0);
756  // make a dummy TH1 to set out legend
757  auto Prefit = std::make_unique<TH1D>();
758  Prefit->SetDirectory(nullptr);
759  PlotMan->style().setTH1Style(Prefit.get(), PlotMan->getOption<std::string>("prefitHistStyle"));
760  leg->AddEntry(Prefit.get(), "Prior", "lpf");
761 
762  std::vector<std::unique_ptr<TH1D>> postFitHist_tmp(PlotMan->getNFiles());
763  for(unsigned int fileId = 0; fileId < PlotMan->getNFiles(); fileId++){
764  postFitHist_tmp[fileId] = std::make_unique<TH1D>();
765  postFitHist_tmp[fileId]->SetDirectory(nullptr);
766 
767  postFitHist_tmp[fileId]->SetMarkerColor(TColor::GetColorPalette(fileId));
768  postFitHist_tmp[fileId]->SetLineColor(TColor::GetColorPalette(fileId));
769  postFitHist_tmp[fileId]->SetMarkerStyle(7);
770  postFitHist_tmp[fileId]->SetLineStyle(1+fileId);
771  postFitHist_tmp[fileId]->SetLineWidth(PlotMan->getOption<int>("plotLineWidth"));
772  leg->AddEntry(postFitHist_tmp[fileId].get(), PlotMan->getFileLabel(fileId).c_str(), "lpf");
773  }
774 
775  canv->cd();
776  canv->Clear();
777  leg->Draw();
778  canv->Print((SaveName).c_str());
779 
780  MakeParameterPlots(canv.get());
781 
782  MakeFluxPlots(canv.get());
783 
784  //KS: By default we don't run ProcessMCMC with PlotDet as this take some time, in case we did let's make fancy plots
785  if(plotNDDet & (NDParameters > 0)) MakeNDDetPlots();
786 
787  canv->Print((SaveName+"]").c_str());
788 
789  MakeRidgePlots();
790 }
791 
792 std::unique_ptr<TGraphAsymmErrors> MakeTGraphAsymmErrors(const std::shared_ptr<TFile>& File, std::vector<int> Index = {})
793 {
794  int GraphBins = Index.size();
795  std::vector<double> x(GraphBins);
796  std::vector<double> y(GraphBins);
797  std::vector<double> exl(GraphBins);
798  std::vector<double> eyl(GraphBins);
799  std::vector<double> exh(GraphBins);
800  std::vector<double> eyh(GraphBins);
801 
802  TH1D* PostHist = static_cast<TH1D*>(File->Get( ("param_xsec_"+plotType).c_str() ));
803 
804  auto Errors_HPD_Positive = static_cast<TVectorD*>(File->Get( "Errors_HPD_Positive" ));
805  auto Errors_HPD_Negative = static_cast<TVectorD*>(File->Get( "Errors_HPD_Negative" ));
806  //KS: I am tempted to multithread this...
807  for(int i = 0; i < GraphBins; ++i)
808  {
809  int Counter = Index.size() == 0 ? i : Index[i];
810  //KS: We are extracting value from three object each having different numbering scheme, I have checked carefully so this is correct please don't change all these +1 +0.5 etc. it just work...
811  x[i] = i + 0.5;
812  y[i] = PostHist->GetBinContent(Counter+1);
813 
814  //KS: We don't want x axis errors as they are confusing in Violin plot
815  exh[i] = 0.00001;
816  exl[i] = 0.00001;
817  eyh[i] = (*Errors_HPD_Positive)(Counter);
818  eyl[i] = (*Errors_HPD_Negative)(Counter);
819  }
820  auto PostGraph = std::make_unique<TGraphAsymmErrors>(GraphBins, x.data(), y.data(), exl.data(), exh.data(), eyl.data(), eyh.data());
821  PostGraph->SetTitle("");
822 
823  return PostGraph;
824 }
825 
828 {
829  //KS: Should be in some config... either way it control whether you plot symmetric or asymmetric error bars
830  bool PlotAssym = true;
831 
832  //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.
833  TCandle::SetScaledViolin(false);
834 
835  std::string OutputName = "";
836  for(unsigned int fileId = 0; fileId < PlotMan->getNFiles(); fileId++){
837  MACH3LOG_INFO("File {}: {} ", fileId, PlotMan->getFileName(fileId));
838  OutputName += PlotMan->getFileName(fileId);
839  OutputName = OutputName.substr(0, OutputName.find(".root"));
840  }
841  MACH3LOG_INFO("Making Violin Plot");
842  OutputName += "_Violin";
843  if(PlotAssym) OutputName += "_Assym";
844 
845  auto canvas = std::make_unique<TCanvas>("canv", "canv", 1024, 1024);
846  canvas->SetGrid();
847  gStyle->SetOptStat(0);
848  //KS: Remove errors on X axis as they are confusing in violin type of plot
849  if(!PlotAssym) gStyle->SetErrorX(0.0001);
850  canvas->SetTickx();
851  canvas->SetTicky();
852  canvas->SetBottomMargin(0.25);
853  canvas->SetTopMargin(0.08);
854  canvas->SetRightMargin(0.03);
855  canvas->SetLeftMargin(0.10);
856  canvas->Print((OutputName+".pdf[").c_str());
857  canvas->SetGrid();
858 
859  if(PlotMan->input().getFile(0).file->Get<TH2D>( "param_violin_prior" ) == nullptr)
860  {
861  MACH3LOG_WARN("Couldn't find violin plot, make sure method from MCMCProcessor is being called");
862  return;
863  }
864  std::unique_ptr<TH2D> ViolinPre = M3::Clone(PlotMan->input().getFile(0).file->Get<TH2D>( "param_violin_prior" ));
865  // Do some fancy replacements
866  ViolinPre->SetFillColor(kRed);
867  ViolinPre->SetFillColorAlpha(kRed, 0.35);
868  ViolinPre->SetMarkerColor(kRed);
869  ViolinPre->SetMarkerStyle(20);
870  ViolinPre->SetMarkerSize(0.5);
871 
872  ViolinPre->GetYaxis()->SetTitleOffset(1.3);
873  ViolinPre->GetYaxis()->SetTitle("Parameter Value");
874  ViolinPre->GetXaxis()->LabelsOption("v");
875 
876  std::unique_ptr<TH1D> Postfit = M3::Clone(PlotMan->input().getFile(0).file->Get<TH1D>( ("param_xsec_"+plotType).c_str() ));
877  Postfit->SetMarkerColor(kRed);
878  Postfit->SetLineColor(kRed);
879  Postfit->SetMarkerStyle(7);
880 
881  std::vector<std::unique_ptr<TH2D>> Violin(PlotMan->getNFiles());
882  //KS: I know hardcoded but we can figure out later...
883  const std::vector<Color_t> FillColors = { kBlue, kGreen, kMagenta };
884  for(unsigned int fileId = 0; fileId < PlotMan->getNFiles(); fileId++) {
885  Violin[fileId] = M3::Clone(PlotMan->input().getFile(fileId).file->Get<TH2D>( "param_violin" ));
886  if(Violin[fileId] == nullptr)
887  {
888  MACH3LOG_ERROR("Couldn't find violin plot, make sure method from MCMCProcessor is being called");
889  return;
890  }
891  Violin[fileId]->SetMarkerColor(FillColors.at(fileId));
892  Violin[fileId]->SetLineColor(FillColors.at(fileId));
893  Violin[fileId]->SetFillColor(FillColors.at(fileId));
894  Violin[fileId]->SetFillColorAlpha(FillColors.at(fileId), 0.35);
895 
896  if(fileId == 0){
897  Violin[fileId]->SetMarkerStyle(20);
898  Violin[fileId]->SetMarkerSize(0.5);
899  }
900  }
901 
902  std::unique_ptr<TGraphAsymmErrors> PostGraphAll = MakeTGraphAsymmErrors(PlotMan->input().getFile(0).file);
903  // Make a Legend page
904  auto leg = std::make_unique<TLegend>(0.0, 0.0, 1.0, 1.0);
905  if (ViolinPre != nullptr) leg->AddEntry(ViolinPre.get(), "Prior", "lpf");
906  for(unsigned int fileId = 0; fileId < PlotMan->getNFiles(); fileId++) {
907  leg->AddEntry(Violin[fileId].get(), PlotMan->getFileLabel(fileId).c_str(), "lpf");
908  }
909  if(PlotAssym) leg->AddEntry(PostGraphAll.get(), "HPD Assym", "lp");
910  else leg->AddEntry(Postfit.get(), "HPD", "lpf");
911 
912  canvas->cd();
913  canvas->Clear();
914  leg->Draw();
915  canvas->Print((OutputName+".pdf").c_str());
916 
917  // get the names of the blocks of parameters to group together
918  std::vector<std::string> const blockNames = PlotMan->getOption<std::vector<std::string>>("paramGroups");
919  const int nPlots = static_cast<int>(blockNames.size());
920 
921  for (int i = 0; i < nPlots; i++)
922  {
923  // get the configuration for this parameter
924  std::string blockName = blockNames[i];
925  YAML::Node paramBlock = PlotMan->getOption(blockName);
926  std::string blockTitle = paramBlock[0].as<std::string>();
927  std::vector<double> blockLimits = paramBlock[1].as<std::vector<double>>();
928  std::vector<std::string> blockContents = paramBlock[2].as<std::vector<std::string>>();
929 
930  // get num of params in the block
931  const int nParams = static_cast<int>(blockContents.size());
932 
933  // set some plot things
934  auto blockHist_prefit = std::make_unique<TH2D>((blockName + "_Prefit").c_str(), blockTitle.c_str(), nParams, 0.0, static_cast<double>(nParams),
935  ViolinPre->GetYaxis()->GetNbins(), ViolinPre->GetYaxis()->GetXmin(), ViolinPre->GetYaxis()->GetXmax());
936  CopyViolinToBlock(ViolinPre.get(), blockHist_prefit.get(), blockContents);
937  // set the y axis limits we got from config
938  blockHist_prefit->GetYaxis()->SetRangeUser(blockLimits[0], blockLimits[1]);
939 
940  std::vector<std::unique_ptr<TH2D>> blockHist(PlotMan->getNFiles());
941  for(unsigned int fileId = 0; fileId < PlotMan->getNFiles(); fileId++) {
942  blockHist[fileId] = std::make_unique<TH2D>((blockTitle + "Violin" + fileId).Data(), (blockTitle + "Violin" + fileId).Data(),
943  nParams, 0.0, static_cast<double>(nParams), Violin[fileId]->GetYaxis()->GetNbins(),
944  Violin[fileId]->GetYaxis()->GetXmin(), Violin[fileId]->GetYaxis()->GetXmax());
945  CopyViolinToBlock(Violin[fileId].get(), blockHist[fileId].get(), blockContents);
946  blockHist[fileId]->GetYaxis()->SetRangeUser(blockLimits[fileId], blockLimits[1]);
947  }
948  // Do some fancy replacements
949  PrettifyTitles(blockHist_prefit.get());
950 
951  // set some plot things
952  auto blockHist_Best = std::make_unique<TH1D>(blockName.c_str(), blockTitle.c_str(),
953  nParams, 0.0, static_cast<double>(nParams));
954  // set the errors for the prefit block hist
955  for(int localBin=0; localBin < nParams; localBin ++){
956  // the "local" bin is the params index within the group of parameters
957  std::string paramName = blockContents[localBin];
958  copyParToBlockHist(localBin, paramName, blockHist_Best.get(), "", 0);
959  }
960 
961  std::vector<int> Index;
962  for(unsigned int is = 0; is < blockContents.size(); is++) {
963  int ParamBinId = M3::_BAD_INT_;
964  for (int ix = 0; ix < ViolinPre->GetXaxis()->GetNbins(); ++ix) {
965  if(ViolinPre->GetXaxis()->GetBinLabel(ix+1) == blockContents[is]) {
966  ParamBinId = ix;
967  break;
968  }
969  }
970  Index.push_back(ParamBinId);
971  }
972  std::unique_ptr<TGraphAsymmErrors> PostGraph = MakeTGraphAsymmErrors(PlotMan->input().getFile(0).file, Index);
973  PostGraph->SetMarkerColor(kBlack);
974  PostGraph->SetLineColor(kBlack);
975  PostGraph->SetMarkerStyle(7);
976  PostGraph->SetLineWidth(2);
977  PostGraph->SetLineStyle(kSolid);
978 
979  blockHist_prefit->Draw("violinX(03100300)");
980  for(unsigned int fileId = 0; fileId < PlotMan->getNFiles(); fileId++) {
981  blockHist[fileId]->Draw("violinX(03100300) SAME");
982  }
983 
984  if(PlotAssym) PostGraph->Draw("P SAME");
985  else Postfit->Draw("SAME");
986  canvas->Print((OutputName+".pdf").c_str());
987  }
988  canvas->Print((OutputName+".pdf]").c_str());
989 }
990 
992 void Get2DComparison(const std::string& FileName1, const std::string& FileName2)
993 {
994  auto canvas = std::make_unique<TCanvas>("canvas", "canvas", 0, 0, 1024, 1024);
995  canvas->SetBottomMargin(0.1f);
996  canvas->SetTopMargin(0.05f);
997  canvas->SetRightMargin(0.03f);
998  canvas->SetLeftMargin(0.15f);
999 
1000  // Open the two ROOT files
1001  TFile* File1 = M3::Open(FileName1, "READ", __FILE__, __LINE__);
1002  TFile* File2 = M3::Open(FileName2, "READ", __FILE__, __LINE__);
1003 
1004  // Get the Post_2d_hists directory from both files
1005  TDirectory* Dir1 = File1->Get<TDirectory>("Post_2d_hists");
1006  TDirectory* Dir2 = File2->Get<TDirectory>("Post_2d_hists");
1007 
1008  if (!Dir1 || !Dir2) {
1009  MACH3LOG_WARN("Post_2d_hists directory not found in one or both files while running {}.", __func__);
1010  File1->Close();
1011  delete File1;
1012  File2->Close();
1013  delete File2;
1014  return;
1015  }
1016 
1017  // Get the list of keys in the first directory
1018  TIter next1(Dir1->GetListOfKeys());
1019  TKey* key1 = nullptr;
1020 
1021  // Prepare the output PDF filename
1022  std::string SaveName2D = "2DComparison_" + FileName1 + "_" + FileName2;
1023  SaveName2D = SaveName2D.substr(0, SaveName2D.find(".root"));
1024  SaveName2D = SaveName2D + ".pdf";
1025 
1026  canvas->Print((SaveName2D+"[").c_str());
1027  // Loop over keys in the first directory
1028  while ((key1 = static_cast<TKey*>(next1()))) {
1029  TString histName = key1->GetName();
1030 
1031  // Check if the key is a TH2D
1032  if (TString(key1->GetClassName()) == "TH2D") {
1033  TH2D* hist1 = static_cast<TH2D*>(key1->ReadObj());
1034 
1035  // Try to get the histogram with the same name from the second directory
1036  TH2D* hist2 = static_cast<TH2D*>(Dir2->Get(histName));
1037 
1038  if (hist2) {
1039  hist1->SetTitle("");
1040  hist1->SetTitle("");
1041 
1042  // Prettify axis titles
1043  std::string Xtitle = PlotMan->style().prettifyParamName(hist1->GetXaxis()->GetTitle());
1044  std::string Ytitle = PlotMan->style().prettifyParamName(hist1->GetYaxis()->GetTitle());
1045 
1046  // Adjust the axis ranges of hist1 to include both histograms
1047  double xmin = std::min(hist1->GetXaxis()->GetXmin(), hist2->GetXaxis()->GetXmin());
1048  double xmax = std::max(hist1->GetXaxis()->GetXmax(), hist2->GetXaxis()->GetXmax());
1049  double ymin = std::min(hist1->GetYaxis()->GetXmin(), hist2->GetYaxis()->GetXmin());
1050  double ymax = std::max(hist1->GetYaxis()->GetXmax(), hist2->GetYaxis()->GetXmax());
1051 
1052  hist1->GetXaxis()->SetRangeUser(xmin, xmax);
1053  hist1->GetYaxis()->SetRangeUser(ymin, ymax);
1054 
1055  hist1->GetXaxis()->SetTitle(Xtitle.c_str());
1056  hist1->GetYaxis()->SetTitle(Ytitle.c_str());
1057 
1058  hist1->SetLineColor(kBlue);
1059  hist1->SetLineStyle(kSolid);
1060  hist1->SetLineWidth(2);
1061 
1062  hist2->SetLineColor(kRed);
1063  hist2->SetLineStyle(kDashed);
1064  hist2->SetLineWidth(2);
1065 
1066  hist1->Draw("CONT3");
1067  hist2->Draw("CONT3 SAME");
1068 
1069  auto Legend = std::make_unique<TLegend>(0.20, 0.7, 0.4, 0.92);
1070  Legend->AddEntry(hist1, PlotMan->getFileLabel(0).c_str(), "l");
1071  Legend->AddEntry(hist2, PlotMan->getFileLabel(1).c_str(), "l");
1072  Legend->SetTextSize(0.03);
1073  Legend->SetLineColor(0);
1074  Legend->SetLineStyle(0);
1075  Legend->SetFillColor(0);
1076  Legend->SetFillStyle(0);
1077  Legend->SetBorderSize(0);
1078  Legend->Draw("SAME");
1079  canvas->Print((SaveName2D).c_str());
1080  }
1081  }
1082  }
1083  canvas->Print((SaveName2D+"]").c_str());
1084 
1085  File1->Close();
1086  delete File1;
1087  File2->Close();
1088  delete File2;
1089 }
1090 
1091 int main(int argc, char *argv[])
1092 {
1094  // Avoid Info in <TCanvas::Print>
1095  gErrorIgnoreLevel = kWarning;
1096 
1097  PlotMan = new MaCh3Plotting::PlottingManager();
1098  PlotMan->parseInputs(argc, argv);
1099  #ifdef MACH3_DEBUG
1100  PlotMan->input().getFile(0).file->ls();
1101  #endif
1102  PlotMan->setExec("GetPostfitParamPlots");
1103 
1104  PlotMan->style().setPalette(PlotMan->getOption<std::string>("colorPalette"));
1105 
1107  GetViolinPlots();
1108 
1109  if (PlotMan->input().getNInputFiles() == 2)
1110  {
1111  std::string filename1 = PlotMan->getFileName(0);
1112  std::string filename2 = PlotMan->getFileName(1);
1113  Get2DComparison(filename1, filename2);
1114  }
1115 
1116  if(PlotMan) delete PlotMan;
1117  return 0;
1118 }
#define _MaCh3_Safe_Include_Start_
KS: Avoiding warning checking for headers.
Definition: Core.h:126
#define _MaCh3_Safe_Include_End_
KS: Restore warning checking after including external headers.
Definition: Core.h:141
int main(int argc, char *argv[])
void MakeFluxPlots(TCanvas *canv)
void InitializePads(const TCanvas *canvas, TPad *&pad3, TPad *&pad4)
std::vector< int > NDSamplesBins
void copyParToBlockHist(const int localBin, const std::string &paramName, TH1D *blockHist, const std::string &type, const int fileId, const bool setLabels=true)
MaCh3Plotting::PlottingManager * PlotMan
void MakeParameterPlots(TCanvas *canv)
void MakeNDDetPlots()
std::unique_ptr< TH1D > makeRatio(TH1D *PrefitCopy, TH1D *PostfitCopy, bool setAxes)
bool ReadSettings(const std::shared_ptr< TFile > &File1)
void PrettifyTitles(HistType *hist)
std::string SaveName
void Get2DComparison(const std::string &FileName1, const std::string &FileName2)
KS: Make comparison of 2D Posteriors.
void MakeRidgePlots()
void GetViolinPlots()
KS: Make fancy violin plots.
int NDParametersStartingPos
std::vector< std::string > NDSamplesNames
std::unique_ptr< TGraphAsymmErrors > MakeTGraphAsymmErrors(const std::shared_ptr< TFile > &File, std::vector< int > Index={})
void GetPostfitParamPlots()
int NDParameters
void CopyViolinToBlock(TH2D *FullViolin, TH2D *ReducedViolin, const std::vector< std::string > &ParamNames)
void DrawPlots(TCanvas *plotCanv, TH1D *PrefitCopy, const std::vector< std::unique_ptr< TH1D >> &PostfitVec, TPad *mainPad, TPad *ratioPad, const std::string &OutName)
std::string plotType
bool IsInvalidHist(const TH1D *hist, double invalid=M3::_BAD_DOUBLE_)
#define MACH3LOG_CRITICAL
Definition: MaCh3Logger.h:38
#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
#define MACH3LOG_WARN
Definition: MaCh3Logger.h:36
#define MACH3LOG_TRACE
Definition: MaCh3Logger.h:33
Custom exception class used throughout MaCh3.
void Print(const TTree *tree)
Definition: Monitor.cpp:326
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.
constexpr static const double _BAD_DOUBLE_
Default value used for double initialisation.
Definition: Core.h:53
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.
constexpr static const int _BAD_INT_
Default value used for int initialisation.
Definition: Core.h:55