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