CMS 3D CMS Logo

DQMHistPlotter.cc
Go to the documentation of this file.
2 
4 
5 // framework & common header files
8 
9 //DQM services
12 
13 #include <TCanvas.h>
14 #include <TPad.h>
15 #include <TPostScript.h>
16 #include <TStyle.h>
17 #include <TROOT.h>
18 #include <TMath.h>
19 
20 #include <iostream>
21 
22 //defaults for cfgEntryProcess
23 const std::string type_smMC = "smMC";
24 const std::string type_bsmMC = "bsmMC";
25 const std::string type_smSumMC = "smSumMC";
26 const std::string type_Data = "Data";
27 
28 //defaults for cfgEntryAxisX
29 const double defaultMinX = -1.;
30 const double defaultMaxX = -1.;
31 const double defaultXaxisTitleOffset = 1.0;
32 const double defaultXaxisTitleSize = 0.05;
33 
34 //defaults for cfgEntryAxisY
35 const double defaultMinY_linear = 0.;
36 const double defaultMinY_log = 1.e-2;
37 const double defaultMaxY_linear = -1.;
38 const double defaultMaxY_log = -1.;
39 const std::string yScale_linear = "linear";
40 const std::string yScale_log = "log";
42 const double defaultYaxisTitleOffset = 1.0;
43 const double defaultYaxisTitleSize = 0.05;
46 
47 // defaults for cfgEntryLegend
48 const double defaultLegendPosX = 0.50;
49 const double defaultLegendPosY = 0.55;
50 const double defaultLegendSizeX = 0.39;
51 const double defaultLegendSizeY = 0.34;
55 const int defaultLegendFillColor = 0;
56 
57 // defaults for cfgEntryLabel
58 const double defaultLabelPosX = 0.66;
59 const double defaultLabelPosY = 0.82;
60 const double defaultLabelSizeX = 0.26;
61 const double defaultLabelSizeY = 0.10;
63 const int defaultLabelBorderSize = 0;
64 const int defaultLabelFillColor = 0;
65 const int defaultLabelTextColor = 1;
66 const double defaultLabelTextSize = 0.05;
67 const int defaultLabelTextAlign = 22; // horizontally and vertically centered, see documentation of TAttText
68 const double defaultLabelTextAngle = 0.;
69 
70 // defaults for cfgEntryDrawOption
71 const int defaultMarkerColor = 1;
72 const int defaultMarkerSize = 1;
73 const int defaultMarkerStyle = 2;
74 const int defaultLineColor = 0;
75 const int defaultLineStyle = 1;
76 const int defaultLineWidth = 2;
77 const int defaultFillColor = 0;
78 const int defaultFillStyle = 1001;
81 
82 const std::string drawOption_eBand = "eBand";
83 
84 // global defaults
85 const int defaultCanvasSizeX = 800;
86 const int defaultCanvasSizeY = 600;
87 
89 
90 const int verbosity = 0;
91 
92 template <class T>
93 void checkCfgDef(const std::string& cfgEntryName,
94  std::map<std::string, T>& def,
95  int& errorFlag,
96  const std::string& defType,
97  const std::string& drawJobName) {
98  if (def.find(cfgEntryName) == def.end()) {
99  edm::LogError("checkCfgDef") << " " << defType << " = " << cfgEntryName
100  << " undefined, needed by drawJob = " << drawJobName << " !!";
101  errorFlag = 1;
102  }
103 }
104 
105 template <class T>
106 void checkCfgDefs(const std::vector<std::string>& cfgEntryNames,
107  std::map<std::string, T>& def,
108  int& errorFlag,
109  const std::string& defType,
110  const std::string& drawJobName) {
111  for (std::vector<std::string>::const_iterator cfgEntryName = cfgEntryNames.begin();
112  cfgEntryName != cfgEntryNames.end();
113  ++cfgEntryName) {
114  checkCfgDef(*cfgEntryName, def, errorFlag, defType, drawJobName);
115  }
116 }
117 
118 template <class T>
119 const T* findCfgDef(const std::string& cfgEntryName,
120  std::map<std::string, T>& def,
121  const std::string& defType,
122  const std::string& drawJobName) {
123  typename std::map<std::string, T>::const_iterator it = def.find(cfgEntryName);
124  if (it != def.end()) {
125  return &(it->second);
126  } else {
127  edm::LogError("findCfgDef") << " " << defType << " = " << cfgEntryName
128  << " undefined, needed by drawJob = " << drawJobName << " !!";
129  return nullptr;
130  }
131 }
132 
133 //
134 //-----------------------------------------------------------------------------------------------------------------------
135 //
136 
137 typedef std::pair<TH1*, std::string> histoDrawEntry;
138 
139 void drawHistograms(const std::list<histoDrawEntry>& histogramList, bool& isFirstHistogram) {
140  for (std::list<histoDrawEntry>::const_iterator it = histogramList.begin(); it != histogramList.end(); ++it) {
141  std::string drawOption = (isFirstHistogram) ? it->second : std::string(it->second).append("same");
142  it->first->Draw(drawOption.data());
143  isFirstHistogram = false;
144  }
145 }
146 
147 //
148 //-----------------------------------------------------------------------------------------------------------------------
149 //
150 
151 bool find_vstring(const std::vector<std::string>& vs, const std::string& s) {
152  for (std::vector<std::string>::const_iterator it = vs.begin(); it != vs.end(); ++it) {
153  if ((*it) == s)
154  return true;
155  }
156  return false;
157 }
158 
159 //
160 //-----------------------------------------------------------------------------------------------------------------------
161 //
162 
164  name_ = name;
165 
166  dqmDirectory_ = cfg.getParameter<std::string>("dqmDirectory");
167 
168  legendEntry_ = cfg.getParameter<std::string>("legendEntry");
169  legendEntryErrorBand_ = (cfg.exists("legendEntryErrorBand")) ? cfg.getParameter<std::string>("legendEntryErrorBand")
170  : std::string(legendEntry_).append(" Uncertainty");
171 
172  type_ = cfg.getParameter<std::string>("type");
173 
174  if (verbosity)
175  print();
176 }
177 
179  std::cout << "<TauDQMHistPlotter::cfgEntryProcess::print>:" << std::endl;
180  std::cout << " name = " << name_ << std::endl;
181  std::cout << " dqmDirectory = " << dqmDirectory_ << std::endl;
182  std::cout << " legendEntry = " << legendEntry_ << std::endl;
183  std::cout << " legendEntryErrorBand = " << legendEntryErrorBand_ << std::endl;
184  std::cout << " type = " << type_ << std::endl;
185 }
186 
187 //
188 //-----------------------------------------------------------------------------------------------------------------------
189 //
190 
192  name_ = name;
193 
194  minX_ = (cfg.exists("minX")) ? cfg.getParameter<double>("minX") : defaultMinX;
195  maxX_ = (cfg.exists("maxX")) ? cfg.getParameter<double>("maxX") : defaultMaxX;
196  xAxisTitle_ = cfg.getParameter<std::string>("xAxisTitle");
197  xAxisTitleOffset_ =
198  (cfg.exists("xAxisTitleOffset")) ? cfg.getParameter<double>("xAxisTitleOffset") : defaultXaxisTitleOffset;
199  xAxisTitleSize_ = (cfg.exists("xAxisTitleSize")) ? cfg.getParameter<double>("xAxisTitleSize") : defaultXaxisTitleSize;
200 
201  if (verbosity)
202  print();
203 }
204 
206  std::cout << "<TauDQMHistPlotter::cfgEntryAxisX::print>:" << std::endl;
207  std::cout << " name = " << name_ << std::endl;
208  std::cout << " minX_ = " << minX_ << std::endl;
209  std::cout << " maxX_ = " << maxX_ << std::endl;
210  std::cout << " xAxisTitle = " << xAxisTitle_ << std::endl;
211  std::cout << " xAxisTitleOffset = " << xAxisTitleOffset_ << std::endl;
212  std::cout << " xAxisTitleSize = " << xAxisTitleSize_ << std::endl;
213 }
214 
215 void TauDQMHistPlotter::cfgEntryAxisX::applyTo(TH1* histogram) const {
216  if (histogram) {
217  double xMin = (minX_ != defaultMinX) ? minX_ : histogram->GetXaxis()->GetXmin();
218  double xMax = (maxX_ != defaultMaxX) ? maxX_ : histogram->GetXaxis()->GetXmax();
219  histogram->SetAxisRange(xMin, xMax, "X");
220  histogram->GetXaxis()->SetTitle(xAxisTitle_.data());
221  histogram->GetXaxis()->SetTitleOffset(xAxisTitleOffset_);
222  histogram->GetXaxis()->SetTitleSize(xAxisTitleSize_);
223  }
224 }
225 
226 //
227 //-----------------------------------------------------------------------------------------------------------------------
228 //
229 
231  name_ = name;
232 
233  minY_linear_ = (cfg.exists("minY_linear")) ? cfg.getParameter<double>("minY_linear") : defaultMinY_linear;
234  minY_log_ = (cfg.exists("minY_log")) ? cfg.getParameter<double>("minY_log") : defaultMinY_log;
235  maxY_linear_ = (cfg.exists("maxY_linear")) ? cfg.getParameter<double>("maxY_linear") : defaultMaxY_linear;
236  maxY_log_ = (cfg.exists("maxY_log")) ? cfg.getParameter<double>("maxY_log") : defaultMaxY_log;
237  yScale_ = (cfg.exists("yScale")) ? cfg.getParameter<std::string>("yScale") : defaultYscale;
238  yAxisTitle_ = cfg.getParameter<std::string>("yAxisTitle");
239  yAxisTitleOffset_ =
240  (cfg.exists("yAxisTitleOffset")) ? cfg.getParameter<double>("yAxisTitleOffset") : defaultYaxisTitleOffset;
241  yAxisTitleSize_ = (cfg.exists("yAxisTitleSize")) ? cfg.getParameter<double>("yAxisTitleSize") : defaultYaxisTitleSize;
242 
243  if (verbosity)
244  print();
245 }
246 
248  std::cout << "<TauDQMHistPlotter::cfgEntryAxisY::print>:" << std::endl;
249  std::cout << " name = " << name_ << std::endl;
250  std::cout << " minY_linear = " << minY_linear_ << std::endl;
251  std::cout << " minY_log = " << minY_log_ << std::endl;
252  std::cout << " maxY_linear = " << maxY_linear_ << std::endl;
253  std::cout << " maxY_log = " << maxY_log_ << std::endl;
254  std::cout << " yScale = " << yScale_ << std::endl;
255  std::cout << " yAxisTitle = " << yAxisTitle_ << std::endl;
256  std::cout << " yAxisTitleOffset = " << yAxisTitleOffset_ << std::endl;
257  std::cout << " yAxisTitleSize = " << yAxisTitleSize_ << std::endl;
258 }
259 
260 void TauDQMHistPlotter::cfgEntryAxisY::applyTo(TH1* histogram, double norm) const {
261  if (histogram) {
262  bool yLogScale = (yScale_ == yScale_log) ? true : false;
263  double minY = (yLogScale) ? minY_log_ : minY_linear_;
264  histogram->SetMinimum(minY);
265  double maxY = (yLogScale) ? maxY_log_ : maxY_linear_;
266  double defaultMaxY = (yLogScale) ? defaultMaxY_log : defaultMaxY_linear;
267  if (maxY != defaultMaxY) {
268  //--- normalize y-axis range using given configuration parameter
269  histogram->SetMaximum(maxY);
270  } else {
271  //--- in case configuration parameter for y-axis range not explicitely given,
272  // normalize y-axis range to maximum of any histogram included in drawJob
273  // times defaultYaxisMaximumScaleFactor (apply scale factor in order to make space for legend)
274  double defaultYaxisMaximumScaleFactor =
276  histogram->SetMaximum(defaultYaxisMaximumScaleFactor * norm);
277  }
278  histogram->GetYaxis()->SetTitle(yAxisTitle_.data());
279  histogram->GetYaxis()->SetTitleOffset(yAxisTitleOffset_);
280  histogram->GetYaxis()->SetTitleSize(yAxisTitleSize_);
281  }
282 }
283 
284 //
285 //-----------------------------------------------------------------------------------------------------------------------
286 //
287 
289  name_ = name;
290 
291  posX_ = (cfg.exists("posX")) ? cfg.getParameter<double>("posX") : defaultLegendPosX;
292  posY_ = (cfg.exists("posY")) ? cfg.getParameter<double>("posY") : defaultLegendPosY;
293  sizeX_ = (cfg.exists("sizeX")) ? cfg.getParameter<double>("sizeX") : defaultLegendSizeX;
294  sizeY_ = (cfg.exists("sizeY")) ? cfg.getParameter<double>("sizeY") : defaultLegendSizeY;
295  header_ = (cfg.exists("header")) ? cfg.getParameter<std::string>("header") : defaultLegendHeader;
296  option_ = (cfg.exists("option")) ? cfg.getParameter<std::string>("option") : defaultLegendOptions;
297  borderSize_ = (cfg.exists("borderSize")) ? cfg.getParameter<int>("borderSize") : defaultLegendBorderSize;
298  fillColor_ = (cfg.exists("fillColor")) ? cfg.getParameter<int>("fillColor") : defaultLegendFillColor;
299 
300  if (verbosity)
301  print();
302 }
303 
305  std::cout << "<TauDQMHistPlotter::cfgEntryLegend::print>:" << std::endl;
306  std::cout << " name = " << name_ << std::endl;
307  std::cout << " posX = " << posX_ << std::endl;
308  std::cout << " posY = " << posY_ << std::endl;
309  std::cout << " sizeX = " << sizeX_ << std::endl;
310  std::cout << " sizeY = " << sizeY_ << std::endl;
311  std::cout << " header = " << header_ << std::endl;
312  std::cout << " option = " << option_ << std::endl;
313  std::cout << " borderSize = " << borderSize_ << std::endl;
314  std::cout << " fillColor = " << fillColor_ << std::endl;
315 }
316 
318  if (legend) {
319  legend->SetX1(posX_);
320  legend->SetY1(posY_);
321  legend->SetX2(posX_ + sizeX_);
322  legend->SetY2(posY_ + sizeY_);
323  legend->SetHeader(header_.data());
324  legend->SetOption(option_.data());
325  legend->SetBorderSize(borderSize_);
326  legend->SetFillColor(fillColor_);
327  }
328 }
329 
330 //
331 //-----------------------------------------------------------------------------------------------------------------------
332 //
333 
335  name_ = name;
336 
337  posX_ = (cfg.exists("posX")) ? cfg.getParameter<double>("posX") : defaultLabelPosX;
338  posY_ = (cfg.exists("posY")) ? cfg.getParameter<double>("posY") : defaultLabelPosY;
339  sizeX_ = (cfg.exists("sizeX")) ? cfg.getParameter<double>("sizeX") : defaultLabelSizeX;
340  sizeY_ = (cfg.exists("sizeY")) ? cfg.getParameter<double>("sizeY") : defaultLabelSizeY;
341  option_ = (cfg.exists("option")) ? cfg.getParameter<std::string>("option") : defaultLabelOptions;
342  borderSize_ = (cfg.exists("borderSize")) ? cfg.getParameter<int>("borderSize") : defaultLabelBorderSize;
343  fillColor_ = (cfg.exists("fillColor")) ? cfg.getParameter<int>("fillColor") : defaultLabelFillColor;
344  textColor_ = (cfg.exists("textColor")) ? cfg.getParameter<int>("textColor") : defaultLabelTextColor;
345  textSize_ = (cfg.exists("textSize")) ? cfg.getParameter<double>("textSize") : defaultLabelTextSize;
346  textAlign_ = (cfg.exists("textAlign")) ? cfg.getParameter<int>("textAlign") : defaultLabelTextAlign;
347  textAngle_ = (cfg.exists("textAngle")) ? cfg.getParameter<double>("textAngle") : defaultLabelTextAngle;
348  text_ = cfg.getParameter<vstring>("text");
349 
350  if (verbosity)
351  print();
352 }
353 
355  std::cout << "<TauDQMHistPlotter::cfgEntryLabel::print>:" << std::endl;
356  std::cout << " name = " << name_ << std::endl;
357  std::cout << " posX = " << posX_ << std::endl;
358  std::cout << " posY = " << posY_ << std::endl;
359  std::cout << " sizeX = " << sizeX_ << std::endl;
360  std::cout << " sizeY = " << sizeY_ << std::endl;
361  std::cout << " option = " << option_ << std::endl;
362  std::cout << " borderSize = " << borderSize_ << std::endl;
363  std::cout << " fillColor = " << fillColor_ << std::endl;
364  std::cout << " textColor = " << textColor_ << std::endl;
365  std::cout << " textSize = " << textSize_ << std::endl;
366  std::cout << " textAlign = " << textAlign_ << std::endl;
367  std::cout << " textAngle = " << textAngle_ << std::endl;
368  std::cout << " text = " << format_vstring(text_) << std::endl;
369 }
370 
372  if (label) {
373  //--- WARNING: need to call TPaveText::SetX1NDC, **not** TPaveText::SetX1 !!
374  // (see documentation of base-class constructor
375  // TPave::TPave(Double_t, Double_t,Double_t, Double_t, Int_t, Option_t*)
376  // in TPave.cxx for details)
377  label->SetX1NDC(posX_);
378  label->SetY1NDC(posY_);
379  label->SetX2NDC(posX_ + sizeX_);
380  label->SetY2NDC(posY_ + sizeY_);
381  label->SetOption(option_.data());
382  label->SetBorderSize(borderSize_);
383  label->SetFillColor(fillColor_);
384  label->SetTextColor(textColor_);
385  label->SetTextSize(textSize_);
386  label->SetTextAlign(textAlign_);
387  label->SetTextAngle(textAngle_);
388  for (vstring::const_iterator line = text_.begin(); line != text_.end(); ++line) {
389  label->AddText(line->data());
390  }
391  }
392 }
393 
394 //
395 //-----------------------------------------------------------------------------------------------------------------------
396 //
397 
399  name_ = name;
400 
401  markerColor_ = (cfg.exists("markerColor")) ? cfg.getParameter<int>("markerColor") : defaultMarkerColor;
402  markerSize_ = (cfg.exists("markerSize")) ? cfg.getParameter<double>("markerSize") : defaultMarkerSize;
403  markerStyle_ = (cfg.exists("markerStyle")) ? cfg.getParameter<int>("markerStyle") : defaultMarkerStyle;
404 
405  lineColor_ = (cfg.exists("lineColor")) ? cfg.getParameter<int>("lineColor") : defaultLineColor;
406  lineStyle_ = (cfg.exists("lineStyle")) ? cfg.getParameter<int>("lineStyle") : defaultLineStyle;
407  lineWidth_ = (cfg.exists("lineWidth")) ? cfg.getParameter<int>("lineWidth") : defaultLineWidth;
408 
409  fillColor_ = (cfg.exists("fillColor")) ? cfg.getParameter<int>("fillColor") : defaultFillColor;
410  fillStyle_ = (cfg.exists("fillStyle")) ? cfg.getParameter<int>("fillStyle") : defaultFillStyle;
411 
412  drawOption_ = (cfg.exists("drawOption")) ? cfg.getParameter<std::string>("drawOption") : defaultDrawOption;
413  drawOptionLegend_ =
414  (cfg.exists("drawOptionLegend")) ? cfg.getParameter<std::string>("drawOptionLegend") : defaultDrawOptionLegend;
415 
416  if (verbosity)
417  print();
418 }
419 
421  : name_(name),
422  markerColor_(blueprint.markerColor_),
423  markerSize_(blueprint.markerSize_),
424  markerStyle_(blueprint.markerStyle_),
425  lineColor_(blueprint.lineColor_),
426  lineStyle_(blueprint.lineStyle_),
427  lineWidth_(blueprint.lineWidth_),
428  fillColor_(blueprint.fillColor_),
429  fillStyle_(blueprint.fillStyle_),
430  drawOption_(blueprint.drawOption_),
431  drawOptionLegend_(blueprint.drawOptionLegend_) {
432  if (verbosity)
433  print();
434 }
435 
437  std::cout << "<TauDQMHistPlotter::cfgEntryDrawOption::print>:" << std::endl;
438  std::cout << " name = " << name_ << std::endl;
439  std::cout << " markerColor = " << markerColor_ << std::endl;
440  std::cout << " markerSize = " << markerSize_ << std::endl;
441  std::cout << " markerStyle = " << markerStyle_ << std::endl;
442  std::cout << " lineColor = " << lineColor_ << std::endl;
443  std::cout << " lineStyle = " << lineStyle_ << std::endl;
444  std::cout << " lineWidth = " << lineWidth_ << std::endl;
445  std::cout << " fillColor = " << fillColor_ << std::endl;
446  std::cout << " fillStyle = " << fillStyle_ << std::endl;
447  std::cout << " drawOption = " << drawOption_ << std::endl;
448  std::cout << " drawOptionLegend = " << drawOptionLegend_ << std::endl;
449 }
450 
452  if (histogram) {
453  histogram->SetMarkerColor(markerColor_);
454  histogram->SetMarkerSize(markerSize_);
455  histogram->SetMarkerStyle(markerStyle_);
456  histogram->SetLineColor(lineColor_);
457  histogram->SetLineStyle(lineStyle_);
458  histogram->SetLineWidth(lineWidth_);
459  histogram->SetFillColor(fillColor_);
460  histogram->SetFillStyle(fillStyle_);
461  }
462 }
463 
464 //
465 //-----------------------------------------------------------------------------------------------------------------------
466 //
467 
469  const std::string& drawOptionEntry,
470  const std::string& legendEntry,
471  const std::string& legendEntryErrorBand,
472  const std::string& process,
473  bool doStack)
474  : dqmMonitorElement_(dqmMonitorElement),
475  drawOptionEntry_(drawOptionEntry),
476  legendEntry_(legendEntry),
477  legendEntryErrorBand_(legendEntryErrorBand),
478  process_(process),
479  doStack_(doStack),
480  isErrorBand_(false) {
481  //if ( verbosity ) print();
482 }
483 
485  : dqmMonitorElement_(blueprint.dqmMonitorElement_),
486  drawOptionEntry_(blueprint.drawOptionEntry_),
487  legendEntry_(blueprint.legendEntry_),
488  legendEntryErrorBand_(blueprint.legendEntryErrorBand_),
489  process_(blueprint.process_),
490  doStack_(blueprint.doStack_),
491  isErrorBand_(false) {
492  //if ( verbosity ) print();
493 }
494 
496  std::cout << "<TauDQMHistPlotter::plotDefEntry::print>:" << std::endl;
497  std::cout << " dqmMonitorElement = " << dqmMonitorElement_ << std::endl;
498  std::cout << " drawOptionEntry = " << drawOptionEntry_ << std::endl;
499  std::cout << " legendEntry = " << legendEntry_ << std::endl;
500  std::cout << " legendEntryErrorBand = " << legendEntryErrorBand_ << std::endl;
501  std::cout << " process = " << process_ << std::endl;
502  std::cout << " doStack = " << doStack_ << std::endl;
503 }
504 
505 //
506 //-----------------------------------------------------------------------------------------------------------------------
507 //
508 
510  const plotDefList& plotDefList,
511  const std::string& title,
512  const std::string& xAxis,
513  const std::string& yAxis,
514  const std::string& legend,
515  const vstring& labels) {
516  name_ = name;
517 
518  for (plotDefList::const_iterator it = plotDefList.begin(); it != plotDefList.end(); ++it) {
519  plots_.push_back(plotDefEntry(*it));
520  }
521 
522  title_ = title;
523 
524  xAxis_ = xAxis;
525  yAxis_ = yAxis;
526 
527  legend_ = legend;
528 
529  for (vstring::const_iterator it = labels.begin(); it != labels.end(); ++it) {
530  labels_.push_back(std::string(*it));
531  }
532 
533  if (verbosity)
534  print();
535 }
536 
538  std::cout << "<TauDQMHistPlotter::cfgSetDrawJob::print>:" << std::endl;
539  std::cout << " name = " << name_ << std::endl;
540  std::cout << "plots = {" << std::endl;
541  for (plotDefList::const_iterator plot = plots_.begin(); plot != plots_.end(); ++plot) {
542  plot->print();
543  }
544  std::cout << "}" << std::endl;
545  std::cout << " title = " << title_ << std::endl;
546  std::cout << " xAxis = " << xAxis_ << std::endl;
547  std::cout << " yAxis = " << yAxis_ << std::endl;
548  std::cout << " legend = " << legend_ << std::endl;
549  std::cout << " labels = " << format_vstring(labels_) << std::endl;
550 }
551 
552 //
553 //-----------------------------------------------------------------------------------------------------------------------
554 //
555 
557  if (verbosity)
558  std::cout << "<TauDQMHistPlotter::TauDQMHistPlotter>:" << std::endl;
559 
560  toFile_ = cfg.getParameter<bool>("PrintToFile");
561  cfgError_ = 0;
562 
563  //--- configure processes
564  //std::cout << "--> configuring processes..." << std::endl;
565  edm::ParameterSet cfgParSet_processes = cfg.getParameter<edm::ParameterSet>("processes");
566  readCfgParameter<cfgEntryProcess>(cfgParSet_processes, processes_);
567 
568  //--- check that process types are defined
569  //std::cout << "--> checking configuration parameters..." << std::endl;
570 
571  int numProcesses_Data = 0;
572  int numProcesses_sumMC = 0;
573  for (std::map<std::string, cfgEntryProcess>::const_iterator process = processes_.begin(); process != processes_.end();
574  ++process) {
575  const std::string& type = process->second.type_;
576 
577  if (!((type == type_smMC) || (type == type_bsmMC) || (type == type_smSumMC) || (type == type_Data))) {
578  edm::LogError("TauDQMHistPlotter") << " Undefined process type = " << type << " !!";
579  cfgError_ = 1;
580  }
581 
582  if (type == type_smSumMC)
583  ++numProcesses_sumMC;
584  if (type == type_Data)
585  ++numProcesses_Data;
586  }
587 
588  if ((numProcesses_Data > 1) || (numProcesses_sumMC > 1)) {
589  edm::LogError("TauDQMHistPlotter") << " Cannot have more than one process of types sumMC and Data !!";
590  cfgError_ = 1;
591  }
592 
593  //--- configure x-axes
594  //std::cout << "--> configuring x-axes..." << std::endl;
595  edm::ParameterSet cfgParSet_xAxes = cfg.getParameter<edm::ParameterSet>("xAxes");
596  readCfgParameter<cfgEntryAxisX>(cfgParSet_xAxes, xAxes_);
597 
598  //--- configure y-axes
599  //std::cout << "--> configuring y-axes..." << std::endl;
600  edm::ParameterSet cfgParSet_yAxes = cfg.getParameter<edm::ParameterSet>("yAxes");
601  readCfgParameter<cfgEntryAxisY>(cfgParSet_yAxes, yAxes_);
602 
603  //--- configure legends
604  //std::cout << "--> configuring legends..." << std::endl;
605  edm::ParameterSet cfgParSet_legends = cfg.getParameter<edm::ParameterSet>("legends");
606  readCfgParameter<cfgEntryLegend>(cfgParSet_legends, legends_);
607 
608  //--- configure labels
609  //std::cout << "--> configuring labels..." << std::endl;
610  edm::ParameterSet cfgParSet_labels = cfg.getParameter<edm::ParameterSet>("labels");
611  readCfgParameter<cfgEntryLabel>(cfgParSet_labels, labels_);
612 
613  //--- configure drawOptions
614  //std::cout << "--> configuring drawOptions..." << std::endl;
615  if (cfg.exists("drawOptionSets")) {
616  edm::ParameterSet drawOptionSets = cfg.getParameter<edm::ParameterSet>("drawOptionSets");
617  vstring drawOptionSetNames = drawOptionSets.getParameterNamesForType<edm::ParameterSet>();
618  for (vstring::const_iterator drawOptionSetName = drawOptionSetNames.begin();
619  drawOptionSetName != drawOptionSetNames.end();
620  ++drawOptionSetName) {
621  edm::ParameterSet drawOptionSet = drawOptionSets.getParameter<edm::ParameterSet>(*drawOptionSetName);
622 
623  vstring drawOptionEntryNames = drawOptionSet.getParameterNamesForType<edm::ParameterSet>();
624  for (vstring::const_iterator drawOptionEntryName = drawOptionEntryNames.begin();
625  drawOptionEntryName != drawOptionEntryNames.end();
626  ++drawOptionEntryName) {
627  edm::ParameterSet drawOptionEntry = drawOptionSet.getParameter<edm::ParameterSet>(*drawOptionEntryName);
628 
629  std::string drawOptionEntryName_full =
630  std::string(*drawOptionSetName).append(drawOptionSeparator).append(*drawOptionEntryName);
631  drawOptionEntries_.insert(std::pair<std::string, cfgEntryDrawOption>(
632  drawOptionEntryName_full, cfgEntryDrawOption(drawOptionEntryName_full, drawOptionEntry)));
633  }
634  }
635  }
636 
637  if (cfg.exists("drawOptionEntries")) {
638  edm::ParameterSet cfgParSet_drawOptionEntries = cfg.getParameter<edm::ParameterSet>("drawOptionEntries");
639  readCfgParameter<cfgEntryDrawOption>(cfgParSet_drawOptionEntries, drawOptionEntries_);
640  }
641 
642  //--- configure drawJobs
643  //std::cout << "--> configuring drawJobs..." << std::endl;
644  edm::ParameterSet drawJobs = cfg.getParameter<edm::ParameterSet>("drawJobs");
645  vstring drawJobNames = drawJobs.getParameterNamesForType<edm::ParameterSet>();
646  for (vstring::const_iterator drawJobName = drawJobNames.begin(); drawJobName != drawJobNames.end(); ++drawJobName) {
647  edm::ParameterSet drawJob = drawJobs.getParameter<edm::ParameterSet>(*drawJobName);
648 
649  std::map<int, plotDefList> plotDefMap;
650 
651  if (drawJob.existsAs<edm::ParameterSet>("plots")) { // display same monitor element for different processes
653 
654  vstring dqmMonitorElements = plots.getParameter<vstring>("dqmMonitorElements");
655  vstring processes = plots.getParameter<vstring>("processes");
656 
657  std::string drawOptionSet = drawJob.getParameter<std::string>("drawOptionSet");
658  //std::cout << "drawOptionSet = " << drawOptionSet << std::endl;
659 
660  vstring stack = (cfg.exists("stack")) ? drawJob.getParameter<vstring>("stack") : vstring();
661 
662  for (vstring::const_iterator process = processes.begin(); process != processes.end(); ++process) {
663  int index = 0;
664  for (vstring::const_iterator dqmMonitorElement = dqmMonitorElements.begin();
665  dqmMonitorElement != dqmMonitorElements.end();
666  ++dqmMonitorElement) {
667  bool stack_dqmMonitorElement = find_vstring(stack, *process);
668  std::string drawOptionEntry = std::string(drawOptionSet).append(drawOptionSeparator).append(*process);
669  plotDefMap[index].push_back(
670  plotDefEntry(*dqmMonitorElement, drawOptionEntry, "", "", *process, stack_dqmMonitorElement));
671  ++index;
672  }
673  }
674  } else { // display different monitor elements for same process
675  typedef std::vector<edm::ParameterSet> vParameterSet;
676  vParameterSet plots = drawJob.getParameter<vParameterSet>("plots");
677 
678  std::string process = (drawJob.exists("process")) ? drawJob.getParameter<std::string>("process") : "";
679  //std::cout << "process (globally set) = " << process << std::endl;
680 
681  for (vParameterSet::const_iterator plot = plots.begin(); plot != plots.end(); ++plot) {
682  if (process.empty() || plot->exists("process")) {
683  process = plot->getParameter<std::string>("process");
684  //std::cout << "process (locally set) = " << process << std::endl;
685  }
686 
687  std::string drawOptionEntry = plot->getParameter<std::string>("drawOptionEntry");
688  //std::cout << "drawOptionEntry = " << drawOptionEntry << std::endl;
689 
690  std::string legendEntry = "", legendEntryErrorBand = "";
691  if (plot->exists("legendEntry")) {
692  legendEntry = plot->getParameter<std::string>("legendEntry");
693  legendEntryErrorBand = (plot->exists("legendEntryErrorBand"))
694  ? plot->getParameter<std::string>("legendEntryErrorBand")
695  : std::string(legendEntry).append(" Uncertainty");
696  }
697  //std::cout << "legendEntry = " << legendEntry << std::endl;
698  //std::cout << "legendEntryErrorBand = " << legendEntryErrorBand << std::endl;
699 
700  vstring dqmMonitorElements = plot->getParameter<vstring>("dqmMonitorElements");
701  int index = 0;
702  for (vstring::const_iterator dqmMonitorElement = dqmMonitorElements.begin();
703  dqmMonitorElement != dqmMonitorElements.end();
704  ++dqmMonitorElement) {
705  plotDefMap[index].push_back(
706  plotDefEntry(*dqmMonitorElement, drawOptionEntry, legendEntry, legendEntryErrorBand, process, false));
707  ++index;
708  }
709  }
710  }
711 
712  //--- check that number of displayed monitor elements is the same for each plot
713  unsigned numMonitorElements_ref = 0;
714  bool isFirstEntry = true;
715  for (std::map<int, plotDefList>::const_iterator plot = plotDefMap.begin(); plot != plotDefMap.end(); ++plot) {
716  if (isFirstEntry) {
717  numMonitorElements_ref = plot->second.size();
718  isFirstEntry = false;
719  } else {
720  if (plot->second.size() != numMonitorElements_ref) {
721  edm::LogError("TauDQMHistPlotter::TauDQMHistPlotter")
722  << " Numbers of dqmMonitorElements must be the same for all plots"
723  << " --> skipping drawJob = " << (*drawJobName) << " !!";
724  cfgError_ = 1;
725  }
726  }
727  }
728 
729  //--- expand process directories in names of dqmMonitorElements
730  for (std::map<int, plotDefList>::iterator plot = plotDefMap.begin(); plot != plotDefMap.end(); ++plot) {
731  for (plotDefList::iterator entry = plot->second.begin(); entry != plot->second.end(); ++entry) {
732  std::string dqmMonitorElement = entry->dqmMonitorElement_;
733  std::string process = entry->process_;
734 
735  std::map<std::string, cfgEntryProcess>::const_iterator it = processes_.find(process);
736  if (it != processes_.end()) {
737  std::string process_dqmDirectory = it->second.dqmDirectory_;
738 
739  //std::cout << "replacing processDir = " << process_dqmDirectory << " in drawJob = " << (*drawJobName) << std::endl;
740 
741  int errorFlag = 0;
742  std::string dqmMonitorElement_expanded =
743  replace_string(dqmMonitorElement, processDirKeyword, process_dqmDirectory, 0, 1, errorFlag);
744  //std::cout << " dqmMonitorElement_expanded = " << dqmMonitorElement_expanded << std::endl;
745 
746  if (!errorFlag) {
747  entry->dqmMonitorElement_ = dqmMonitorElement_expanded;
748  } else {
749  cfgError_ = 1;
750  }
751  } else {
752  edm::LogError("TauDQMHistPlotter::TauDQMHistPlotter") << " Undefined process = " << process << " !!";
753  cfgError_ = 1;
754  }
755  }
756  }
757 
758  std::string title = (drawJob.exists("title")) ? drawJob.getParameter<std::string>("title") : "";
759 
760  std::string xAxis = drawJob.getParameter<std::string>("xAxis");
761  std::string yAxis = drawJob.getParameter<std::string>("yAxis");
762 
763  std::string legend = drawJob.getParameter<std::string>("legend");
764 
765  vstring labels = (drawJob.exists("labels")) ? drawJob.getParameter<vstring>("labels") : vstring();
766 
767  //--- expand parameters in names of dqmMonitorElements;
768  // create drawJob objects
769  for (std::map<int, plotDefList>::iterator plot = plotDefMap.begin(); plot != plotDefMap.end(); ++plot) {
770  if (drawJob.exists("parameter")) {
771  vstring vparameter = drawJob.getParameter<vstring>("parameter");
772  //std::cout << "replacing parameter = " << format_vstring(vparameter) << " in drawJob = " << (*drawJobName) << std::endl;
773 
774  for (vstring::const_iterator parameter = vparameter.begin(); parameter != vparameter.end(); ++parameter) {
775  plotDefList plot_expanded;
776 
777  for (plotDefList::const_iterator entry = plot->second.begin(); entry != plot->second.end(); ++entry) {
778  std::string dqmMonitorElement = entry->dqmMonitorElement_;
779 
780  int errorFlag = 0;
781  std::string dqmMonitorElement_expanded =
782  replace_string(dqmMonitorElement, parKeyword, *parameter, 1, 1, errorFlag);
783  //std::cout << " dqmMonitorElement_expanded = " << dqmMonitorElement_expanded << std::endl;
784  if (!errorFlag) {
785  plot_expanded.push_back(plotDefEntry(dqmMonitorElement_expanded,
786  entry->drawOptionEntry_,
787  entry->legendEntry_,
788  entry->legendEntryErrorBand_,
789  entry->process_,
790  entry->doStack_));
791  } else {
792  cfgError_ = 1;
793  }
794  }
795 
796  int errorFlag = 0;
797  std::string title_expanded = replace_string(title, parKeyword, *parameter, 0, 1, errorFlag);
798  //std::cout << " title_expanded = " << title_expanded << std::endl;
799  std::string xAxis_expanded = replace_string(xAxis, parKeyword, *parameter, 0, 1, errorFlag);
800  //std::cout << " xAxis_expanded = " << xAxis_expanded << std::endl;
801  std::string yAxis_expanded = replace_string(yAxis, parKeyword, *parameter, 0, 1, errorFlag);
802  //std::cout << " yAxis_expanded = " << yAxis_expanded << std::endl;
803  if (errorFlag)
804  cfgError_ = 1;
805 
806  drawJobs_.push_back(cfgEntryDrawJob(std::string(*drawJobName).append(*parameter),
807  plot_expanded,
808  title_expanded,
809  xAxis_expanded,
810  yAxis_expanded,
811  legend,
812  labels));
813  }
814  } else {
815  drawJobs_.push_back(cfgEntryDrawJob(*drawJobName, plot->second, title, xAxis, yAxis, legend, labels));
816  }
817  }
818  }
819 
820  //--- check that all information neccessary to process drawJob is defined;
821  for (std::list<cfgEntryDrawJob>::const_iterator drawJob = drawJobs_.begin(); drawJob != drawJobs_.end(); ++drawJob) {
822  for (plotDefList::const_iterator plot = drawJob->plots_.begin(); plot != drawJob->plots_.end(); ++plot) {
823  checkCfgDef<cfgEntryDrawOption>(
824  plot->drawOptionEntry_, drawOptionEntries_, cfgError_, "drawOptionEntry", drawJob->name_);
825  checkCfgDef<cfgEntryProcess>(plot->process_, processes_, cfgError_, "process", drawJob->name_);
826  }
827 
828  checkCfgDef<cfgEntryAxisX>(drawJob->xAxis_, xAxes_, cfgError_, "xAxis", drawJob->name_);
829  checkCfgDef<cfgEntryAxisY>(drawJob->yAxis_, yAxes_, cfgError_, "yAxis", drawJob->name_);
830 
831  checkCfgDef<cfgEntryLegend>(drawJob->legend_, legends_, cfgError_, "legend", drawJob->name_);
832 
833  checkCfgDefs<cfgEntryLabel>(drawJob->labels_, labels_, cfgError_, "label", drawJob->name_);
834  }
835 
836  //--- configure canvas size
837  //std::cout << "--> configuring canvas size..." << std::endl;
838  canvasSizeX_ = (cfg.exists("canvasSizeX")) ? cfg.getParameter<int>("canvasSizeX") : defaultCanvasSizeX;
839  canvasSizeY_ = (cfg.exists("canvasSizeY")) ? cfg.getParameter<int>("canvasSizeY") : defaultCanvasSizeY;
840 
841  //--- configure output files
842  //std::cout << "--> configuring postscript output file..." << std::endl;
843 
844  outputFilePath_ = (cfg.exists("outputFilePath")) ? cfg.getParameter<std::string>("outputFilePath") : "";
845  if (outputFilePath_.rbegin() != outputFilePath_.rend()) {
846  if ((*outputFilePath_.rbegin()) == '/')
847  outputFilePath_.erase(outputFilePath_.length() - 1);
848  }
849  //std::cout << " outputFilePath = " << outputFilePath_ << std::endl;
850 
851  outputFileName_ = (cfg.exists("outputFileName")) ? cfg.getParameter<std::string>("outputFileName") : "";
852  //std::cout << " outputFileName = " << outputFileName_ << std::endl;
853 
854  indOutputFileName_ = (cfg.exists("indOutputFileName")) ? cfg.getParameter<std::string>("indOutputFileName") : "";
855  if (!indOutputFileName_.empty() && indOutputFileName_.find('.') == std::string::npos) {
856  edm::LogError("TauDQMHistPlotter") << " Failed to determine type of graphics format from indOutputFileName = "
857  << indOutputFileName_ << " !!";
858  cfgError_ = 1;
859  }
860  //std::cout << " indOutputFileName = " << indOutputFileName_ << std::endl;
861 
862  //--- check that exactly one type of output is specified for the plots
863  // (either separate graphics files displaying one plot each
864  // or postscript file displaying all plots on successive pages;
865  // cannot create both types of output simultaneously,
866  // as TCanvas::Print seems to interfere with TPostScript::NewPage)
867  if (outputFileName_.empty() && indOutputFileName_.empty()) {
868  edm::LogError("TauDQMHistPlotter") << " Either outputFileName or indOutputFileName must be specified !!";
869  cfgError_ = 1;
870  }
871 
872  if (!outputFileName_.empty() && !indOutputFileName_.empty()) {
873  edm::LogError("TauDQMHistPlotter") << " Must not specify outputFileName and indOutputFileName simultaneously !!";
874  cfgError_ = 1;
875  }
876 
877  if (verbosity)
878  std::cout << "done." << std::endl;
879 }
880 
882  // nothing to be done yet...
883 }
884 
886  // nothing to be done yet...
887 }
888 
890  if (verbosity)
891  std::cout << "<TauDQMHistPlotter::endJob>:" << std::endl;
892 
893  //--- check that configuration parameters contain no errors
894  if (cfgError_) {
895  edm::LogError("endJob") << " Error in Configuration ParameterSet --> histograms will NOT be plotted !!";
896  return;
897  }
898 
899  //--- check that DQMStore service is available
900  if (!edm::Service<DQMStore>().isAvailable()) {
901  edm::LogError("endJob") << " Failed to access dqmStore --> histograms will NOT be plotted !!";
902  return;
903  }
904 
906 
907  //--- stop ROOT from keeping references to all hsitograms
908  //TH1::AddDirectory(false);
909 
910  //--- stop ROOT from opening X-window for canvas output
911  // (in order to be able to run in batch mode)
912  gROOT->SetBatch(true);
913 
914  //--- initialize graphical output;
915  // open postscript file
916  TCanvas canvas("TauDQMHistPlotter", "TauDQMHistPlotter", canvasSizeX_, canvasSizeY_);
917  canvas.SetFillColor(10);
918 
919  //--- restrict area in which histograms are drawn to quadratic TPad in the center of the TCanvas,
920  // in order to make space for axis labels...
921  //TPad pad("EWKTauPad", "EWKTauPad", 0.02, 0.15, 0.98, 0.85);
922  //pad.SetFillColor(10);
923  //pad.Draw();
924  //pad.Divide(1,1);
925  //pad.cd(1);
926 
927  TPostScript* ps = nullptr;
928  if (!outputFileName_.empty()) {
930  (!outputFilePath_.empty()) ? std::string(outputFilePath_).append("/").append(outputFileName_) : outputFileName_;
931  ps = new TPostScript(psFileName.data(), 112);
932  }
933 
934  //--- process drawJobs
935  for (std::list<cfgEntryDrawJob>::const_iterator drawJob = drawJobs_.begin(); drawJob != drawJobs_.end(); ++drawJob) {
936  const std::string& drawJobName = drawJob->name_;
937  if (verbosity)
938  std::cout << "--> processing drawJob " << drawJobName << "..." << std::endl;
939 
940  //--- prepare internally used histogram data-structures
941  TH1* stackedHistogram_sum = nullptr;
942  std::list<TH1*> histogramsToDelete;
943  std::list<plotDefEntry*> drawOptionsToDelete;
944 
945  typedef std::pair<TH1*, const plotDefEntry*> histogram_drawOption_pair;
946  std::list<histogram_drawOption_pair> allHistograms;
947 
948  for (plotDefList::const_iterator plot = drawJob->plots_.begin(); plot != drawJob->plots_.end(); ++plot) {
949  std::string dqmMonitorElementName_full =
950  dqmDirectoryName(std::string(dqmRootDirectory)).append(plot->dqmMonitorElement_);
951  if (verbosity)
952  std::cout << " dqmMonitorElementName_full = " << dqmMonitorElementName_full << std::endl;
953  MonitorElement* dqmMonitorElement = dqmStore.get(dqmMonitorElementName_full);
954 
955  TH1* histogram = dqmMonitorElement->getTH1F();
956  if (verbosity)
957  std::cout << "Got Histogram " << std::endl;
958  // TH1* histogram = ( dqmMonitorElement ) ? dynamic_cast<TH1*>(dqmMonitorElement->getTH1()->Clone()) : NULL;
959  //histogramsToDelete.push_back(histogram);
960 
961  if (histogram == nullptr) {
962  edm::LogError("endJob") << " Failed to access dqmMonitorElement = " << dqmMonitorElementName_full << ","
963  << " needed by drawJob = " << drawJobName << " --> histograms will NOT be plotted !!";
964  continue;
965  }
966 
967  if (!histogram->GetSumw2N())
968  histogram->Sumw2();
969 
970  const cfgEntryDrawOption* drawOptionConfig =
971  findCfgDef<cfgEntryDrawOption>(plot->drawOptionEntry_, drawOptionEntries_, "drawOptionEntry", drawJobName);
972  if (drawOptionConfig == nullptr) {
973  edm::LogError("endJob") << " Failed to access information needed by drawJob = " << drawJobName
974  << " --> histograms will NOT be plotted !!";
975  return;
976  }
977 
978  if (drawOptionConfig->drawOption_ == drawOption_eBand) {
979  //--- add histogram displaying central value as solid line
980  TH1* histogram_centralValue = dynamic_cast<TH1*>(histogram->Clone());
981  histogram_centralValue->SetName(std::string(histogram->GetName()).append("_centralValue").data());
982  cfgEntryDrawOption drawOptionConfig_centralValue(*drawOptionConfig);
983  drawOptionConfig_centralValue.fillColor_ = 0;
984  drawOptionConfig_centralValue.fillStyle_ = 0;
985  drawOptionConfig_centralValue.drawOption_ = "hist";
986  drawOptionConfig_centralValue.drawOptionLegend_ = "l";
987  std::string drawOptionName_centralValue = std::string(plot->drawOptionEntry_).append("_centralValue");
988  //--- entries in std::map need to be unique,
989  // so need to check whether drawOptionEntry already exists...
990  if (drawOptionEntries_.find(drawOptionName_centralValue) == drawOptionEntries_.end())
991  drawOptionEntries_.insert(std::pair<std::string, cfgEntryDrawOption>(
992  drawOptionName_centralValue,
993  cfgEntryDrawOption(drawOptionName_centralValue, drawOptionConfig_centralValue)));
994  plotDefEntry* plot_centralValue = new plotDefEntry(*plot);
995  plot_centralValue->drawOptionEntry_ = drawOptionName_centralValue;
996  allHistograms.push_back(histogram_drawOption_pair(histogram_centralValue, plot_centralValue));
997  histogramsToDelete.push_back(histogram_centralValue);
998  drawOptionsToDelete.push_back(plot_centralValue);
999 
1000  //--- add histogram displaying uncertainty as shaded error band
1001  TH1* histogram_ErrorBand = dynamic_cast<TH1*>(histogram->Clone());
1002  histogram_ErrorBand->SetName(std::string(histogram->GetName()).append("_ErrorBand").data());
1003  cfgEntryDrawOption drawOptionConfig_ErrorBand(*drawOptionConfig);
1004  drawOptionConfig_ErrorBand.markerColor_ = drawOptionConfig_ErrorBand.fillColor_;
1005  drawOptionConfig_ErrorBand.markerSize_ = 0.;
1006  drawOptionConfig_ErrorBand.lineColor_ = drawOptionConfig_ErrorBand.fillColor_;
1007  drawOptionConfig_ErrorBand.lineWidth_ = 0;
1008  drawOptionConfig_ErrorBand.drawOption_ = "e2";
1009  drawOptionConfig_ErrorBand.drawOptionLegend_ = "f";
1010  std::string drawOptionName_ErrorBand = std::string(plot->drawOptionEntry_).append("_ErrorBand");
1011  //--- entries in std::map need to be unique,
1012  // so need to check whether drawOptionEntry already exists...
1013  if (drawOptionEntries_.find(drawOptionName_ErrorBand) == drawOptionEntries_.end())
1014  drawOptionEntries_.insert(std::pair<std::string, cfgEntryDrawOption>(
1015  drawOptionName_ErrorBand, cfgEntryDrawOption(drawOptionName_ErrorBand, drawOptionConfig_ErrorBand)));
1016  plotDefEntry* plot_ErrorBand = new plotDefEntry(*plot);
1017  plot_ErrorBand->drawOptionEntry_ = drawOptionName_ErrorBand;
1018  plot_ErrorBand->isErrorBand_ = true;
1019  allHistograms.push_back(histogram_drawOption_pair(histogram_ErrorBand, plot_ErrorBand));
1020  histogramsToDelete.push_back(histogram_ErrorBand);
1021  drawOptionsToDelete.push_back(plot_ErrorBand);
1022  } else if (plot->doStack_) {
1023  TH1* stackedHistogram = dynamic_cast<TH1*>(histogram->Clone());
1024  if (stackedHistogram_sum)
1025  stackedHistogram->Add(stackedHistogram_sum);
1026  stackedHistogram_sum = stackedHistogram;
1027  histogramsToDelete.push_back(stackedHistogram);
1028  allHistograms.push_back(histogram_drawOption_pair(stackedHistogram, &(*plot)));
1029  } else {
1030  allHistograms.push_back(histogram_drawOption_pair(histogram, &(*plot)));
1031  }
1032  }
1033 
1034  //--- determine normalization of y-axis
1035  // (maximum of any of the histograms included in drawJob)
1036  double yAxisNorm = 0.;
1037  for (std::list<histogram_drawOption_pair>::const_iterator it = allHistograms.begin(); it != allHistograms.end();
1038  ++it) {
1039  yAxisNorm = TMath::Max(yAxisNorm, it->first->GetMaximum());
1040  }
1041  //std::cout << " yAxisNorm = " << yAxisNorm << std::endl;
1042 
1043  //--- prepare histograms for drawing
1044  const cfgEntryAxisX* xAxisConfig = findCfgDef<cfgEntryAxisX>(drawJob->xAxis_, xAxes_, "xAxis", drawJobName);
1045  const cfgEntryAxisY* yAxisConfig = findCfgDef<cfgEntryAxisY>(drawJob->yAxis_, yAxes_, "yAxis", drawJobName);
1046  const cfgEntryLegend* legendConfig = findCfgDef<cfgEntryLegend>(drawJob->legend_, legends_, "legend", drawJobName);
1047  if (xAxisConfig == nullptr || yAxisConfig == nullptr || legendConfig == nullptr) {
1048  edm::LogError("endJob") << " Failed to access information needed by drawJob = " << drawJobName
1049  << " --> histograms will NOT be plotted !!";
1050  return;
1051  }
1052 
1053  //--- WARNING: need to call
1054  // TLegend::TLegend(Double_t, Double_t,Double_t, Double_t, const char* = "", Option_t* = "brNDC")
1055  // constructor, as TLegend::TLegend default constructor causes the created TLegend object to behave differently !!
1056  TLegend legend(defaultLegendPosX,
1060  legendConfig->applyTo(&legend);
1061 
1062  std::list<histoDrawEntry> smProcessHistogramList;
1063  std::list<histoDrawEntry> bsmProcessHistogramList;
1064  std::list<histoDrawEntry> smSumHistogramList;
1065  std::list<histoDrawEntry> smSumUncertaintyHistogramList;
1066  std::list<histoDrawEntry> dataHistogramList;
1067 
1068  for (std::list<histogram_drawOption_pair>::const_iterator it = allHistograms.begin(); it != allHistograms.end();
1069  ++it) {
1070  TH1* histogram = it->first;
1071  const plotDefEntry* drawOption = it->second;
1072 
1073  const cfgEntryDrawOption* drawOptionConfig = findCfgDef<cfgEntryDrawOption>(
1074  drawOption->drawOptionEntry_, drawOptionEntries_, "drawOptionEntry", drawJobName);
1075  const cfgEntryProcess* processConfig =
1076  findCfgDef<cfgEntryProcess>(drawOption->process_, processes_, "process", drawJobName);
1077  if (drawOptionConfig == nullptr || processConfig == nullptr) {
1078  edm::LogError("endJob") << " Failed to access information needed by drawJob = " << drawJobName
1079  << " --> histograms will NOT be plotted !!";
1080  return;
1081  }
1082 
1083  if (!drawJob->title_.empty())
1084  histogram->SetTitle(drawJob->title_.data());
1085 
1086  xAxisConfig->applyTo(histogram);
1087  yAxisConfig->applyTo(histogram, yAxisNorm);
1088 
1089  bool yLogScale = (yAxisConfig->yScale_ == yScale_log) ? true : false;
1090  //std::cout << " yLogScale = " << yLogScale << std::endl;
1091  //pad.SetLogy(yLogScale);
1092  canvas.SetLogy(yLogScale);
1093 
1094  drawOptionConfig->applyTo(histogram);
1095  histogram->SetStats(false);
1096 
1097  if (drawOption->isErrorBand_) {
1098  smSumUncertaintyHistogramList.push_back(histoDrawEntry(histogram, drawOptionConfig->drawOption_.data()));
1099  } else {
1100  if (processConfig->type_ == type_smMC) {
1101  smProcessHistogramList.push_back(histoDrawEntry(histogram, drawOptionConfig->drawOption_.data()));
1102  } else if (processConfig->type_ == type_bsmMC) {
1103  bsmProcessHistogramList.push_back(histoDrawEntry(histogram, drawOptionConfig->drawOption_.data()));
1104  } else if (processConfig->type_ == type_smSumMC) {
1105  smSumHistogramList.push_back(histoDrawEntry(histogram, drawOptionConfig->drawOption_.data()));
1106  } else if (processConfig->type_ == type_Data) {
1107  dataHistogramList.push_back(histoDrawEntry(histogram, drawOptionConfig->drawOption_.data()));
1108  }
1109  }
1110 
1111  std::string legendEntry, legendDrawOption;
1112  if (drawOption->isErrorBand_) {
1113  legendEntry = (!drawOption->legendEntryErrorBand_.empty()) ? drawOption->legendEntryErrorBand_
1114  : processConfig->legendEntryErrorBand_;
1115  legendDrawOption = "f";
1116  } else {
1117  legendEntry = (!drawOption->legendEntry_.empty()) ? drawOption->legendEntry_ : processConfig->legendEntry_;
1118  legendDrawOption = drawOptionConfig->drawOptionLegend_;
1119  }
1120 
1121  legend.AddEntry(histogram, legendEntry.data(), legendDrawOption.data());
1122  }
1123 
1124  std::list<TPaveText> labels;
1125  for (vstring::const_iterator labelName = drawJob->labels_.begin(); labelName != drawJob->labels_.end();
1126  ++labelName) {
1127  const cfgEntryLabel* labelConfig = findCfgDef<cfgEntryLabel>(*labelName, labels_, "label", drawJobName);
1128 
1129  TPaveText label;
1130  labelConfig->applyTo(&label);
1131 
1132  labels.push_back(label);
1133  }
1134 
1135  //--- draw histograms
1136  // - in the order:
1137  // 1. uncertainty on sum of all Standard Model processes
1138  // 2. sum of all Standard Model processes
1139  // 3. individual Standard Model processes
1140  // 4. individual beyond the Standard Model processes
1141  // 5. data
1142  bool isFirstHistogram = true;
1143  drawHistograms(smSumUncertaintyHistogramList, isFirstHistogram);
1144  drawHistograms(smSumHistogramList, isFirstHistogram);
1145 
1146  //--- process histograms for individual Standard Model processes
1147  // in reverse order, so that most stacked histogram gets drawn first
1148  for (std::list<histoDrawEntry>::reverse_iterator it = smProcessHistogramList.rbegin();
1149  it != smProcessHistogramList.rend();
1150  ++it) {
1151  std::string drawOption = (isFirstHistogram) ? it->second : std::string(it->second).append("same");
1152  it->first->Draw(drawOption.data());
1153  isFirstHistogram = false;
1154  }
1155 
1156  drawHistograms(bsmProcessHistogramList, isFirstHistogram);
1157  drawHistograms(dataHistogramList, isFirstHistogram);
1158 
1159  legend.Draw();
1160 
1161  for (std::list<TPaveText>::iterator label = labels.begin(); label != labels.end(); ++label) {
1162  label->Draw();
1163  }
1164 
1165  //pad.RedrawAxis();
1166 
1167  canvas.Update();
1168  //pad.Update();
1169 
1170  if (!indOutputFileName_.empty() && toFile_) {
1171  int errorFlag = 0;
1172  std::string modIndOutputFileName = replace_string(indOutputFileName_, plotKeyword, drawJobName, 1, 1, errorFlag);
1173  if (!errorFlag) {
1174  std::string fullFileName = (!outputFilePath_.empty())
1175  ? std::string(outputFilePath_).append("/").append(modIndOutputFileName)
1176  : modIndOutputFileName;
1177  canvas.Print(fullFileName.data());
1178  } else {
1179  edm::LogError("endJob") << " Failed to decode indOutputFileName = " << indOutputFileName_ << " --> skipping !!";
1180  }
1181  }
1182 
1183  if (ps)
1184  ps->NewPage();
1185 
1186  //--- delete temporarily created histogram and drawOption objects
1187  for (std::list<TH1*>::const_iterator histogram = histogramsToDelete.begin(); histogram != histogramsToDelete.end();
1188  ++histogram) {
1189  delete (*histogram);
1190  }
1191 
1192  for (std::list<plotDefEntry*>::const_iterator drawOption = drawOptionsToDelete.begin();
1193  drawOption != drawOptionsToDelete.end();
1194  ++drawOption) {
1195  delete (*drawOption);
1196  }
1197  }
1198 
1199  //--- close postscript file
1200  canvas.Clear();
1201  if (verbosity)
1202  std::cout << "done." << std::endl;
1203  if (ps)
1204  ps->Close();
1205  delete ps;
1206 }
1207 
1209 
const double defaultMaxY_log
const std::string processDirKeyword
const double defaultLabelPosY
int def(FILE *, FILE *, int)
const std::string type_Data
const std::string defaultDrawOption
const double defaultMinY_linear
const double defaultLabelSizeY
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
void applyTo(TPaveText *) const
const std::string yScale_log
std::pair< TH1 *, std::string > histoDrawEntry
cfgEntryLabel(const std::string &, const edm::ParameterSet &)
const double defaultYaxisMaximumScaleFactor_linear
void endRun(const edm::Run &r, const edm::EventSetup &c) override
const int defaultLabelFillColor
bool exists(std::string const &parameterName) const
checks if a parameter exists
const int defaultLineWidth
std::string replace_string(const std::string &src, const std::string &keyword, const std::string &parameter, unsigned minReplacements, unsigned maxReplacements, int &errorFlag)
const int defaultLabelTextAlign
cfgEntryAxisX(const std::string &, const edm::ParameterSet &)
const int defaultFillStyle
bool existsAs(std::string const &parameterName, bool trackiness=true) const
checks if a parameter exists as a given type
Definition: ParameterSet.h:171
Log< level::Error, false > LogError
std::string dqmDirectoryName(const std::string &dqmRootDirectory, const std::string &dqmSubDirectory)
Definition: EwkTauDQM.cc:10
void checkCfgDef(const std::string &cfgEntryName, std::map< std::string, T > &def, int &errorFlag, const std::string &defType, const std::string &drawJobName)
cfgEntryDrawOption(const std::string &, const edm::ParameterSet &)
const double defaultMinY_log
const double defaultLabelSizeX
const double defaultLegendSizeX
const std::string defaultDrawOptionLegend
const double defaultMinX
const int defaultMarkerStyle
char const * label
const double defaultYaxisTitleOffset
const double defaultYaxisMaximumScaleFactor_log
const int defaultLabelTextColor
const std::string type_bsmMC
std::vector< std::string > getParameterNamesForType(bool trackiness=true) const
Definition: ParameterSet.h:179
stack
Definition: svgfig.py:559
void print(TMatrixD &m, const char *label=nullptr, bool mathematicaFormat=false)
Definition: Utilities.cc:47
const std::string defaultLegendOptions
const std::string defaultLegendHeader
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
const double defaultLegendSizeY
const std::string drawOption_eBand
const std::string type_smMC
const T * findCfgDef(const std::string &cfgEntryName, std::map< std::string, T > &def, const std::string &defType, const std::string &drawJobName)
bool find_vstring(const std::vector< std::string > &vs, const std::string &s)
std::map< std::string, cfgEntryLegend > legends_
~TauDQMHistPlotter() override
const double defaultLabelTextSize
const std::string parKeyword
std::vector< std::string > vstring
void checkCfgDefs(const std::vector< std::string > &cfgEntryNames, std::map< std::string, T > &def, int &errorFlag, const std::string &defType, const std::string &drawJobName)
std::string format_vstring(const std::vector< std::string > &vs)
void drawHistograms(const std::list< histoDrawEntry > &histogramList, bool &isFirstHistogram)
const std::string yScale_linear
cfgEntryProcess(const std::string &, const edm::ParameterSet &)
std::string outputFileName_
std::map< std::string, cfgEntryLabel > labels_
std::map< std::string, cfgEntryProcess > processes_
std::map< std::string, cfgEntryAxisX > xAxes_
const std::string type_smSumMC
const int defaultCanvasSizeY
const double defaultLegendPosX
virtual TH1F * getTH1F() const
const int defaultFillColor
cfgEntryAxisY(const std::string &, const edm::ParameterSet &)
std::list< plotDefEntry > plotDefList
std::string outputFilePath_
std::map< std::string, cfgEntryDrawOption > drawOptionEntries_
const int defaultLegendFillColor
const std::string drawOptionSeparator
const std::string plotKeyword
plotDefEntry(const std::string &, const std::string &, const std::string &, const std::string &, const std::string &, bool)
const int defaultLabelBorderSize
const double defaultYaxisTitleSize
const std::string defaultLabelOptions
cfgEntryDrawJob(const std::string &, const plotDefList &, const std::string &, const std::string &, const std::string &, const std::string &, const vstring &)
def canvas(sub, attr)
Definition: svgfig.py:482
std::list< cfgEntryDrawJob > drawJobs_
const int defaultLineStyle
const double defaultXaxisTitleSize
const double defaultMaxY_linear
const int defaultMarkerSize
const std::string dqmRootDirectory
TauDQMHistPlotter(const edm::ParameterSet &)
const int defaultMarkerColor
const int defaultLineColor
const double defaultMaxX
const int defaultLegendBorderSize
const double defaultXaxisTitleOffset
std::map< std::string, cfgEntryAxisY > yAxes_
long double T
const int defaultCanvasSizeX
std::string indOutputFileName_
const std::string defaultYscale
void applyTo(TH1 *, double norm) const
cfgEntryLegend(const std::string &, const edm::ParameterSet &)
const int verbosity
void analyze(const edm::Event &, const edm::EventSetup &) override
const double defaultLegendPosY
Definition: Run.h:45
const double defaultLabelTextAngle
const double defaultLabelPosX