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