CMS 3D CMS Logo

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