Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 14:33:58

0001 #include "Validation/RecoTau/plugins/DQMHistPlotter.h"
0002 
0003 #include "Validation/RecoTau/plugins/dqmAuxFunctions.h"
0004 
0005 // framework & common header files
0006 #include "FWCore/Framework/interface/Frameworkfwd.h"
0007 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0008 
0009 //DQM services
0010 #include "DQMServices/Core/interface/DQMStore.h"
0011 #include "FWCore/ServiceRegistry/interface/Service.h"
0012 
0013 #include <TCanvas.h>
0014 #include <TPad.h>
0015 #include <TPostScript.h>
0016 #include <TStyle.h>
0017 #include <TROOT.h>
0018 #include <TMath.h>
0019 
0020 #include <iostream>
0021 
0022 //defaults for cfgEntryProcess
0023 const std::string type_smMC = "smMC";
0024 const std::string type_bsmMC = "bsmMC";
0025 const std::string type_smSumMC = "smSumMC";
0026 const std::string type_Data = "Data";
0027 
0028 //defaults for cfgEntryAxisX
0029 const double defaultMinX = -1.;
0030 const double defaultMaxX = -1.;
0031 const double defaultXaxisTitleOffset = 1.0;
0032 const double defaultXaxisTitleSize = 0.05;
0033 
0034 //defaults for cfgEntryAxisY
0035 const double defaultMinY_linear = 0.;
0036 const double defaultMinY_log = 1.e-2;
0037 const double defaultMaxY_linear = -1.;
0038 const double defaultMaxY_log = -1.;
0039 const std::string yScale_linear = "linear";
0040 const std::string yScale_log = "log";
0041 const std::string defaultYscale = yScale_linear;
0042 const double defaultYaxisTitleOffset = 1.0;
0043 const double defaultYaxisTitleSize = 0.05;
0044 const double defaultYaxisMaximumScaleFactor_linear = 1.6;
0045 const double defaultYaxisMaximumScaleFactor_log = 5.e+2;
0046 
0047 // defaults for cfgEntryLegend
0048 const double defaultLegendPosX = 0.50;
0049 const double defaultLegendPosY = 0.55;
0050 const double defaultLegendSizeX = 0.39;
0051 const double defaultLegendSizeY = 0.34;
0052 const std::string defaultLegendHeader = "";
0053 const std::string defaultLegendOptions = "brNDC";
0054 const int defaultLegendBorderSize = 0;
0055 const int defaultLegendFillColor = 0;
0056 
0057 // defaults for cfgEntryLabel
0058 const double defaultLabelPosX = 0.66;
0059 const double defaultLabelPosY = 0.82;
0060 const double defaultLabelSizeX = 0.26;
0061 const double defaultLabelSizeY = 0.10;
0062 const std::string defaultLabelOptions = "brNDC";
0063 const int defaultLabelBorderSize = 0;
0064 const int defaultLabelFillColor = 0;
0065 const int defaultLabelTextColor = 1;
0066 const double defaultLabelTextSize = 0.05;
0067 const int defaultLabelTextAlign = 22;  // horizontally and vertically centered, see documentation of TAttText
0068 const double defaultLabelTextAngle = 0.;
0069 
0070 // defaults for cfgEntryDrawOption
0071 const int defaultMarkerColor = 1;
0072 const int defaultMarkerSize = 1;
0073 const int defaultMarkerStyle = 2;
0074 const int defaultLineColor = 0;
0075 const int defaultLineStyle = 1;
0076 const int defaultLineWidth = 2;
0077 const int defaultFillColor = 0;
0078 const int defaultFillStyle = 1001;
0079 const std::string defaultDrawOption = "";
0080 const std::string defaultDrawOptionLegend = "lpf";
0081 
0082 const std::string drawOption_eBand = "eBand";
0083 
0084 // global defaults
0085 const int defaultCanvasSizeX = 800;
0086 const int defaultCanvasSizeY = 600;
0087 
0088 const std::string drawOptionSeparator = "#.#";
0089 
0090 const int verbosity = 0;
0091 
0092 template <class T>
0093 void checkCfgDef(const std::string& cfgEntryName,
0094                  std::map<std::string, T>& def,
0095                  int& errorFlag,
0096                  const std::string& defType,
0097                  const std::string& drawJobName) {
0098   if (def.find(cfgEntryName) == def.end()) {
0099     edm::LogError("checkCfgDef") << " " << defType << " = " << cfgEntryName
0100                                  << " undefined, needed by drawJob = " << drawJobName << " !!";
0101     errorFlag = 1;
0102   }
0103 }
0104 
0105 template <class T>
0106 void checkCfgDefs(const std::vector<std::string>& cfgEntryNames,
0107                   std::map<std::string, T>& def,
0108                   int& errorFlag,
0109                   const std::string& defType,
0110                   const std::string& drawJobName) {
0111   for (std::vector<std::string>::const_iterator cfgEntryName = cfgEntryNames.begin();
0112        cfgEntryName != cfgEntryNames.end();
0113        ++cfgEntryName) {
0114     checkCfgDef(*cfgEntryName, def, errorFlag, defType, drawJobName);
0115   }
0116 }
0117 
0118 template <class T>
0119 const T* findCfgDef(const std::string& cfgEntryName,
0120                     std::map<std::string, T>& def,
0121                     const std::string& defType,
0122                     const std::string& drawJobName) {
0123   typename std::map<std::string, T>::const_iterator it = def.find(cfgEntryName);
0124   if (it != def.end()) {
0125     return &(it->second);
0126   } else {
0127     edm::LogError("findCfgDef") << " " << defType << " = " << cfgEntryName
0128                                 << " undefined, needed by drawJob = " << drawJobName << " !!";
0129     return nullptr;
0130   }
0131 }
0132 
0133 //
0134 //-----------------------------------------------------------------------------------------------------------------------
0135 //
0136 
0137 typedef std::pair<TH1*, std::string> histoDrawEntry;
0138 
0139 void drawHistograms(const std::list<histoDrawEntry>& histogramList, bool& isFirstHistogram) {
0140   for (std::list<histoDrawEntry>::const_iterator it = histogramList.begin(); it != histogramList.end(); ++it) {
0141     std::string drawOption = (isFirstHistogram) ? it->second : std::string(it->second).append("same");
0142     it->first->Draw(drawOption.data());
0143     isFirstHistogram = false;
0144   }
0145 }
0146 
0147 //
0148 //-----------------------------------------------------------------------------------------------------------------------
0149 //
0150 
0151 bool find_vstring(const std::vector<std::string>& vs, const std::string& s) {
0152   for (std::vector<std::string>::const_iterator it = vs.begin(); it != vs.end(); ++it) {
0153     if ((*it) == s)
0154       return true;
0155   }
0156   return false;
0157 }
0158 
0159 //
0160 //-----------------------------------------------------------------------------------------------------------------------
0161 //
0162 
0163 TauDQMHistPlotter::cfgEntryProcess::cfgEntryProcess(const std::string& name, const edm::ParameterSet& cfg) {
0164   name_ = name;
0165 
0166   dqmDirectory_ = cfg.getParameter<std::string>("dqmDirectory");
0167 
0168   legendEntry_ = cfg.getParameter<std::string>("legendEntry");
0169   legendEntryErrorBand_ = (cfg.exists("legendEntryErrorBand")) ? cfg.getParameter<std::string>("legendEntryErrorBand")
0170                                                                : std::string(legendEntry_).append(" Uncertainty");
0171 
0172   type_ = cfg.getParameter<std::string>("type");
0173 
0174   if (verbosity)
0175     print();
0176 }
0177 
0178 void TauDQMHistPlotter::cfgEntryProcess::print() const {
0179   std::cout << "<TauDQMHistPlotter::cfgEntryProcess::print>:" << std::endl;
0180   std::cout << " name = " << name_ << std::endl;
0181   std::cout << " dqmDirectory = " << dqmDirectory_ << std::endl;
0182   std::cout << " legendEntry = " << legendEntry_ << std::endl;
0183   std::cout << " legendEntryErrorBand = " << legendEntryErrorBand_ << std::endl;
0184   std::cout << " type = " << type_ << std::endl;
0185 }
0186 
0187 //
0188 //-----------------------------------------------------------------------------------------------------------------------
0189 //
0190 
0191 TauDQMHistPlotter::cfgEntryAxisX::cfgEntryAxisX(const std::string& name, const edm::ParameterSet& cfg) {
0192   name_ = name;
0193 
0194   minX_ = (cfg.exists("minX")) ? cfg.getParameter<double>("minX") : defaultMinX;
0195   maxX_ = (cfg.exists("maxX")) ? cfg.getParameter<double>("maxX") : defaultMaxX;
0196   xAxisTitle_ = cfg.getParameter<std::string>("xAxisTitle");
0197   xAxisTitleOffset_ =
0198       (cfg.exists("xAxisTitleOffset")) ? cfg.getParameter<double>("xAxisTitleOffset") : defaultXaxisTitleOffset;
0199   xAxisTitleSize_ = (cfg.exists("xAxisTitleSize")) ? cfg.getParameter<double>("xAxisTitleSize") : defaultXaxisTitleSize;
0200 
0201   if (verbosity)
0202     print();
0203 }
0204 
0205 void TauDQMHistPlotter::cfgEntryAxisX::print() const {
0206   std::cout << "<TauDQMHistPlotter::cfgEntryAxisX::print>:" << std::endl;
0207   std::cout << " name = " << name_ << std::endl;
0208   std::cout << " minX_ = " << minX_ << std::endl;
0209   std::cout << " maxX_ = " << maxX_ << std::endl;
0210   std::cout << " xAxisTitle = " << xAxisTitle_ << std::endl;
0211   std::cout << " xAxisTitleOffset = " << xAxisTitleOffset_ << std::endl;
0212   std::cout << " xAxisTitleSize = " << xAxisTitleSize_ << std::endl;
0213 }
0214 
0215 void TauDQMHistPlotter::cfgEntryAxisX::applyTo(TH1* histogram) const {
0216   if (histogram) {
0217     double xMin = (minX_ != defaultMinX) ? minX_ : histogram->GetXaxis()->GetXmin();
0218     double xMax = (maxX_ != defaultMaxX) ? maxX_ : histogram->GetXaxis()->GetXmax();
0219     histogram->SetAxisRange(xMin, xMax, "X");
0220     histogram->GetXaxis()->SetTitle(xAxisTitle_.data());
0221     histogram->GetXaxis()->SetTitleOffset(xAxisTitleOffset_);
0222     histogram->GetXaxis()->SetTitleSize(xAxisTitleSize_);
0223   }
0224 }
0225 
0226 //
0227 //-----------------------------------------------------------------------------------------------------------------------
0228 //
0229 
0230 TauDQMHistPlotter::cfgEntryAxisY::cfgEntryAxisY(const std::string& name, const edm::ParameterSet& cfg) {
0231   name_ = name;
0232 
0233   minY_linear_ = (cfg.exists("minY_linear")) ? cfg.getParameter<double>("minY_linear") : defaultMinY_linear;
0234   minY_log_ = (cfg.exists("minY_log")) ? cfg.getParameter<double>("minY_log") : defaultMinY_log;
0235   maxY_linear_ = (cfg.exists("maxY_linear")) ? cfg.getParameter<double>("maxY_linear") : defaultMaxY_linear;
0236   maxY_log_ = (cfg.exists("maxY_log")) ? cfg.getParameter<double>("maxY_log") : defaultMaxY_log;
0237   yScale_ = (cfg.exists("yScale")) ? cfg.getParameter<std::string>("yScale") : defaultYscale;
0238   yAxisTitle_ = cfg.getParameter<std::string>("yAxisTitle");
0239   yAxisTitleOffset_ =
0240       (cfg.exists("yAxisTitleOffset")) ? cfg.getParameter<double>("yAxisTitleOffset") : defaultYaxisTitleOffset;
0241   yAxisTitleSize_ = (cfg.exists("yAxisTitleSize")) ? cfg.getParameter<double>("yAxisTitleSize") : defaultYaxisTitleSize;
0242 
0243   if (verbosity)
0244     print();
0245 }
0246 
0247 void TauDQMHistPlotter::cfgEntryAxisY::print() const {
0248   std::cout << "<TauDQMHistPlotter::cfgEntryAxisY::print>:" << std::endl;
0249   std::cout << " name = " << name_ << std::endl;
0250   std::cout << " minY_linear = " << minY_linear_ << std::endl;
0251   std::cout << " minY_log = " << minY_log_ << std::endl;
0252   std::cout << " maxY_linear = " << maxY_linear_ << std::endl;
0253   std::cout << " maxY_log = " << maxY_log_ << std::endl;
0254   std::cout << " yScale = " << yScale_ << std::endl;
0255   std::cout << " yAxisTitle = " << yAxisTitle_ << std::endl;
0256   std::cout << " yAxisTitleOffset = " << yAxisTitleOffset_ << std::endl;
0257   std::cout << " yAxisTitleSize = " << yAxisTitleSize_ << std::endl;
0258 }
0259 
0260 void TauDQMHistPlotter::cfgEntryAxisY::applyTo(TH1* histogram, double norm) const {
0261   if (histogram) {
0262     bool yLogScale = (yScale_ == yScale_log) ? true : false;
0263     double minY = (yLogScale) ? minY_log_ : minY_linear_;
0264     histogram->SetMinimum(minY);
0265     double maxY = (yLogScale) ? maxY_log_ : maxY_linear_;
0266     double defaultMaxY = (yLogScale) ? defaultMaxY_log : defaultMaxY_linear;
0267     if (maxY != defaultMaxY) {
0268       //--- normalize y-axis range using given configuration parameter
0269       histogram->SetMaximum(maxY);
0270     } else {
0271       //--- in case configuration parameter for y-axis range not explicitely given,
0272       //    normalize y-axis range to maximum of any histogram included in drawJob
0273       //    times defaultYaxisMaximumScaleFactor (apply scale factor in order to make space for legend)
0274       double defaultYaxisMaximumScaleFactor =
0275           (yLogScale) ? defaultYaxisMaximumScaleFactor_log : defaultYaxisMaximumScaleFactor_linear;
0276       histogram->SetMaximum(defaultYaxisMaximumScaleFactor * norm);
0277     }
0278     histogram->GetYaxis()->SetTitle(yAxisTitle_.data());
0279     histogram->GetYaxis()->SetTitleOffset(yAxisTitleOffset_);
0280     histogram->GetYaxis()->SetTitleSize(yAxisTitleSize_);
0281   }
0282 }
0283 
0284 //
0285 //-----------------------------------------------------------------------------------------------------------------------
0286 //
0287 
0288 TauDQMHistPlotter::cfgEntryLegend::cfgEntryLegend(const std::string& name, const edm::ParameterSet& cfg) {
0289   name_ = name;
0290 
0291   posX_ = (cfg.exists("posX")) ? cfg.getParameter<double>("posX") : defaultLegendPosX;
0292   posY_ = (cfg.exists("posY")) ? cfg.getParameter<double>("posY") : defaultLegendPosY;
0293   sizeX_ = (cfg.exists("sizeX")) ? cfg.getParameter<double>("sizeX") : defaultLegendSizeX;
0294   sizeY_ = (cfg.exists("sizeY")) ? cfg.getParameter<double>("sizeY") : defaultLegendSizeY;
0295   header_ = (cfg.exists("header")) ? cfg.getParameter<std::string>("header") : defaultLegendHeader;
0296   option_ = (cfg.exists("option")) ? cfg.getParameter<std::string>("option") : defaultLegendOptions;
0297   borderSize_ = (cfg.exists("borderSize")) ? cfg.getParameter<int>("borderSize") : defaultLegendBorderSize;
0298   fillColor_ = (cfg.exists("fillColor")) ? cfg.getParameter<int>("fillColor") : defaultLegendFillColor;
0299 
0300   if (verbosity)
0301     print();
0302 }
0303 
0304 void TauDQMHistPlotter::cfgEntryLegend::print() const {
0305   std::cout << "<TauDQMHistPlotter::cfgEntryLegend::print>:" << std::endl;
0306   std::cout << " name = " << name_ << std::endl;
0307   std::cout << " posX = " << posX_ << std::endl;
0308   std::cout << " posY = " << posY_ << std::endl;
0309   std::cout << " sizeX = " << sizeX_ << std::endl;
0310   std::cout << " sizeY = " << sizeY_ << std::endl;
0311   std::cout << " header = " << header_ << std::endl;
0312   std::cout << " option = " << option_ << std::endl;
0313   std::cout << " borderSize = " << borderSize_ << std::endl;
0314   std::cout << " fillColor = " << fillColor_ << std::endl;
0315 }
0316 
0317 void TauDQMHistPlotter::cfgEntryLegend::applyTo(TLegend* legend) const {
0318   if (legend) {
0319     legend->SetX1(posX_);
0320     legend->SetY1(posY_);
0321     legend->SetX2(posX_ + sizeX_);
0322     legend->SetY2(posY_ + sizeY_);
0323     legend->SetHeader(header_.data());
0324     legend->SetOption(option_.data());
0325     legend->SetBorderSize(borderSize_);
0326     legend->SetFillColor(fillColor_);
0327   }
0328 }
0329 
0330 //
0331 //-----------------------------------------------------------------------------------------------------------------------
0332 //
0333 
0334 TauDQMHistPlotter::cfgEntryLabel::cfgEntryLabel(const std::string& name, const edm::ParameterSet& cfg) {
0335   name_ = name;
0336 
0337   posX_ = (cfg.exists("posX")) ? cfg.getParameter<double>("posX") : defaultLabelPosX;
0338   posY_ = (cfg.exists("posY")) ? cfg.getParameter<double>("posY") : defaultLabelPosY;
0339   sizeX_ = (cfg.exists("sizeX")) ? cfg.getParameter<double>("sizeX") : defaultLabelSizeX;
0340   sizeY_ = (cfg.exists("sizeY")) ? cfg.getParameter<double>("sizeY") : defaultLabelSizeY;
0341   option_ = (cfg.exists("option")) ? cfg.getParameter<std::string>("option") : defaultLabelOptions;
0342   borderSize_ = (cfg.exists("borderSize")) ? cfg.getParameter<int>("borderSize") : defaultLabelBorderSize;
0343   fillColor_ = (cfg.exists("fillColor")) ? cfg.getParameter<int>("fillColor") : defaultLabelFillColor;
0344   textColor_ = (cfg.exists("textColor")) ? cfg.getParameter<int>("textColor") : defaultLabelTextColor;
0345   textSize_ = (cfg.exists("textSize")) ? cfg.getParameter<double>("textSize") : defaultLabelTextSize;
0346   textAlign_ = (cfg.exists("textAlign")) ? cfg.getParameter<int>("textAlign") : defaultLabelTextAlign;
0347   textAngle_ = (cfg.exists("textAngle")) ? cfg.getParameter<double>("textAngle") : defaultLabelTextAngle;
0348   text_ = cfg.getParameter<vstring>("text");
0349 
0350   if (verbosity)
0351     print();
0352 }
0353 
0354 void TauDQMHistPlotter::cfgEntryLabel::print() const {
0355   std::cout << "<TauDQMHistPlotter::cfgEntryLabel::print>:" << std::endl;
0356   std::cout << " name = " << name_ << std::endl;
0357   std::cout << " posX = " << posX_ << std::endl;
0358   std::cout << " posY = " << posY_ << std::endl;
0359   std::cout << " sizeX = " << sizeX_ << std::endl;
0360   std::cout << " sizeY = " << sizeY_ << std::endl;
0361   std::cout << " option = " << option_ << std::endl;
0362   std::cout << " borderSize = " << borderSize_ << std::endl;
0363   std::cout << " fillColor = " << fillColor_ << std::endl;
0364   std::cout << " textColor = " << textColor_ << std::endl;
0365   std::cout << " textSize = " << textSize_ << std::endl;
0366   std::cout << " textAlign = " << textAlign_ << std::endl;
0367   std::cout << " textAngle = " << textAngle_ << std::endl;
0368   std::cout << " text = " << format_vstring(text_) << std::endl;
0369 }
0370 
0371 void TauDQMHistPlotter::cfgEntryLabel::applyTo(TPaveText* label) const {
0372   if (label) {
0373     //--- WARNING: need to call TPaveText::SetX1NDC, **not** TPaveText::SetX1 !!
0374     //             (see documentation of base-class constructor
0375     //               TPave::TPave(Double_t, Double_t,Double_t, Double_t, Int_t, Option_t*)
0376     //              in TPave.cxx for details)
0377     label->SetX1NDC(posX_);
0378     label->SetY1NDC(posY_);
0379     label->SetX2NDC(posX_ + sizeX_);
0380     label->SetY2NDC(posY_ + sizeY_);
0381     label->SetOption(option_.data());
0382     label->SetBorderSize(borderSize_);
0383     label->SetFillColor(fillColor_);
0384     label->SetTextColor(textColor_);
0385     label->SetTextSize(textSize_);
0386     label->SetTextAlign(textAlign_);
0387     label->SetTextAngle(textAngle_);
0388     for (vstring::const_iterator line = text_.begin(); line != text_.end(); ++line) {
0389       label->AddText(line->data());
0390     }
0391   }
0392 }
0393 
0394 //
0395 //-----------------------------------------------------------------------------------------------------------------------
0396 //
0397 
0398 TauDQMHistPlotter::cfgEntryDrawOption::cfgEntryDrawOption(const std::string& name, const edm::ParameterSet& cfg) {
0399   name_ = name;
0400 
0401   markerColor_ = (cfg.exists("markerColor")) ? cfg.getParameter<int>("markerColor") : defaultMarkerColor;
0402   markerSize_ = (cfg.exists("markerSize")) ? cfg.getParameter<double>("markerSize") : defaultMarkerSize;
0403   markerStyle_ = (cfg.exists("markerStyle")) ? cfg.getParameter<int>("markerStyle") : defaultMarkerStyle;
0404 
0405   lineColor_ = (cfg.exists("lineColor")) ? cfg.getParameter<int>("lineColor") : defaultLineColor;
0406   lineStyle_ = (cfg.exists("lineStyle")) ? cfg.getParameter<int>("lineStyle") : defaultLineStyle;
0407   lineWidth_ = (cfg.exists("lineWidth")) ? cfg.getParameter<int>("lineWidth") : defaultLineWidth;
0408 
0409   fillColor_ = (cfg.exists("fillColor")) ? cfg.getParameter<int>("fillColor") : defaultFillColor;
0410   fillStyle_ = (cfg.exists("fillStyle")) ? cfg.getParameter<int>("fillStyle") : defaultFillStyle;
0411 
0412   drawOption_ = (cfg.exists("drawOption")) ? cfg.getParameter<std::string>("drawOption") : defaultDrawOption;
0413   drawOptionLegend_ =
0414       (cfg.exists("drawOptionLegend")) ? cfg.getParameter<std::string>("drawOptionLegend") : defaultDrawOptionLegend;
0415 
0416   if (verbosity)
0417     print();
0418 }
0419 
0420 TauDQMHistPlotter::cfgEntryDrawOption::cfgEntryDrawOption(const std::string& name, const cfgEntryDrawOption& blueprint)
0421     : name_(name),
0422       markerColor_(blueprint.markerColor_),
0423       markerSize_(blueprint.markerSize_),
0424       markerStyle_(blueprint.markerStyle_),
0425       lineColor_(blueprint.lineColor_),
0426       lineStyle_(blueprint.lineStyle_),
0427       lineWidth_(blueprint.lineWidth_),
0428       fillColor_(blueprint.fillColor_),
0429       fillStyle_(blueprint.fillStyle_),
0430       drawOption_(blueprint.drawOption_),
0431       drawOptionLegend_(blueprint.drawOptionLegend_) {
0432   if (verbosity)
0433     print();
0434 }
0435 
0436 void TauDQMHistPlotter::cfgEntryDrawOption::print() const {
0437   std::cout << "<TauDQMHistPlotter::cfgEntryDrawOption::print>:" << std::endl;
0438   std::cout << " name = " << name_ << std::endl;
0439   std::cout << " markerColor = " << markerColor_ << std::endl;
0440   std::cout << " markerSize = " << markerSize_ << std::endl;
0441   std::cout << " markerStyle = " << markerStyle_ << std::endl;
0442   std::cout << " lineColor = " << lineColor_ << std::endl;
0443   std::cout << " lineStyle = " << lineStyle_ << std::endl;
0444   std::cout << " lineWidth = " << lineWidth_ << std::endl;
0445   std::cout << " fillColor = " << fillColor_ << std::endl;
0446   std::cout << " fillStyle = " << fillStyle_ << std::endl;
0447   std::cout << " drawOption = " << drawOption_ << std::endl;
0448   std::cout << " drawOptionLegend = " << drawOptionLegend_ << std::endl;
0449 }
0450 
0451 void TauDQMHistPlotter::cfgEntryDrawOption::applyTo(TH1* histogram) const {
0452   if (histogram) {
0453     histogram->SetMarkerColor(markerColor_);
0454     histogram->SetMarkerSize(markerSize_);
0455     histogram->SetMarkerStyle(markerStyle_);
0456     histogram->SetLineColor(lineColor_);
0457     histogram->SetLineStyle(lineStyle_);
0458     histogram->SetLineWidth(lineWidth_);
0459     histogram->SetFillColor(fillColor_);
0460     histogram->SetFillStyle(fillStyle_);
0461   }
0462 }
0463 
0464 //
0465 //-----------------------------------------------------------------------------------------------------------------------
0466 //
0467 
0468 TauDQMHistPlotter::plotDefEntry::plotDefEntry(const std::string& dqmMonitorElement,
0469                                               const std::string& drawOptionEntry,
0470                                               const std::string& legendEntry,
0471                                               const std::string& legendEntryErrorBand,
0472                                               const std::string& process,
0473                                               bool doStack)
0474     : dqmMonitorElement_(dqmMonitorElement),
0475       drawOptionEntry_(drawOptionEntry),
0476       legendEntry_(legendEntry),
0477       legendEntryErrorBand_(legendEntryErrorBand),
0478       process_(process),
0479       doStack_(doStack),
0480       isErrorBand_(false) {
0481   //if ( verbosity ) print();
0482 }
0483 
0484 TauDQMHistPlotter::plotDefEntry::plotDefEntry(const plotDefEntry& blueprint)
0485     : dqmMonitorElement_(blueprint.dqmMonitorElement_),
0486       drawOptionEntry_(blueprint.drawOptionEntry_),
0487       legendEntry_(blueprint.legendEntry_),
0488       legendEntryErrorBand_(blueprint.legendEntryErrorBand_),
0489       process_(blueprint.process_),
0490       doStack_(blueprint.doStack_),
0491       isErrorBand_(false) {
0492   //if ( verbosity ) print();
0493 }
0494 
0495 void TauDQMHistPlotter::plotDefEntry::print() const {
0496   std::cout << "<TauDQMHistPlotter::plotDefEntry::print>:" << std::endl;
0497   std::cout << " dqmMonitorElement = " << dqmMonitorElement_ << std::endl;
0498   std::cout << " drawOptionEntry = " << drawOptionEntry_ << std::endl;
0499   std::cout << " legendEntry = " << legendEntry_ << std::endl;
0500   std::cout << " legendEntryErrorBand = " << legendEntryErrorBand_ << std::endl;
0501   std::cout << " process = " << process_ << std::endl;
0502   std::cout << " doStack = " << doStack_ << std::endl;
0503 }
0504 
0505 //
0506 //-----------------------------------------------------------------------------------------------------------------------
0507 //
0508 
0509 TauDQMHistPlotter::cfgEntryDrawJob::cfgEntryDrawJob(const std::string& name,
0510                                                     const plotDefList& plotDefList,
0511                                                     const std::string& title,
0512                                                     const std::string& xAxis,
0513                                                     const std::string& yAxis,
0514                                                     const std::string& legend,
0515                                                     const vstring& labels) {
0516   name_ = name;
0517 
0518   for (plotDefList::const_iterator it = plotDefList.begin(); it != plotDefList.end(); ++it) {
0519     plots_.push_back(plotDefEntry(*it));
0520   }
0521 
0522   title_ = title;
0523 
0524   xAxis_ = xAxis;
0525   yAxis_ = yAxis;
0526 
0527   legend_ = legend;
0528 
0529   for (vstring::const_iterator it = labels.begin(); it != labels.end(); ++it) {
0530     labels_.push_back(std::string(*it));
0531   }
0532 
0533   if (verbosity)
0534     print();
0535 }
0536 
0537 void TauDQMHistPlotter::cfgEntryDrawJob::print() const {
0538   std::cout << "<TauDQMHistPlotter::cfgSetDrawJob::print>:" << std::endl;
0539   std::cout << " name = " << name_ << std::endl;
0540   std::cout << "plots = {" << std::endl;
0541   for (plotDefList::const_iterator plot = plots_.begin(); plot != plots_.end(); ++plot) {
0542     plot->print();
0543   }
0544   std::cout << "}" << std::endl;
0545   std::cout << " title = " << title_ << std::endl;
0546   std::cout << " xAxis = " << xAxis_ << std::endl;
0547   std::cout << " yAxis = " << yAxis_ << std::endl;
0548   std::cout << " legend = " << legend_ << std::endl;
0549   std::cout << " labels = " << format_vstring(labels_) << std::endl;
0550 }
0551 
0552 //
0553 //-----------------------------------------------------------------------------------------------------------------------
0554 //
0555 
0556 TauDQMHistPlotter::TauDQMHistPlotter(const edm::ParameterSet& cfg) {
0557   if (verbosity)
0558     std::cout << "<TauDQMHistPlotter::TauDQMHistPlotter>:" << std::endl;
0559 
0560   toFile_ = cfg.getParameter<bool>("PrintToFile");
0561   cfgError_ = 0;
0562 
0563   //--- configure processes
0564   //std::cout << "--> configuring processes..." << std::endl;
0565   edm::ParameterSet cfgParSet_processes = cfg.getParameter<edm::ParameterSet>("processes");
0566   readCfgParameter<cfgEntryProcess>(cfgParSet_processes, processes_);
0567 
0568   //--- check that process types are defined
0569   //std::cout << "--> checking configuration parameters..." << std::endl;
0570 
0571   int numProcesses_Data = 0;
0572   int numProcesses_sumMC = 0;
0573   for (std::map<std::string, cfgEntryProcess>::const_iterator process = processes_.begin(); process != processes_.end();
0574        ++process) {
0575     const std::string& type = process->second.type_;
0576 
0577     if (!((type == type_smMC) || (type == type_bsmMC) || (type == type_smSumMC) || (type == type_Data))) {
0578       edm::LogError("TauDQMHistPlotter") << " Undefined process type = " << type << " !!";
0579       cfgError_ = 1;
0580     }
0581 
0582     if (type == type_smSumMC)
0583       ++numProcesses_sumMC;
0584     if (type == type_Data)
0585       ++numProcesses_Data;
0586   }
0587 
0588   if ((numProcesses_Data > 1) || (numProcesses_sumMC > 1)) {
0589     edm::LogError("TauDQMHistPlotter") << " Cannot have more than one process of types sumMC and Data !!";
0590     cfgError_ = 1;
0591   }
0592 
0593   //--- configure x-axes
0594   //std::cout << "--> configuring x-axes..." << std::endl;
0595   edm::ParameterSet cfgParSet_xAxes = cfg.getParameter<edm::ParameterSet>("xAxes");
0596   readCfgParameter<cfgEntryAxisX>(cfgParSet_xAxes, xAxes_);
0597 
0598   //--- configure y-axes
0599   //std::cout << "--> configuring y-axes..." << std::endl;
0600   edm::ParameterSet cfgParSet_yAxes = cfg.getParameter<edm::ParameterSet>("yAxes");
0601   readCfgParameter<cfgEntryAxisY>(cfgParSet_yAxes, yAxes_);
0602 
0603   //--- configure legends
0604   //std::cout << "--> configuring legends..." << std::endl;
0605   edm::ParameterSet cfgParSet_legends = cfg.getParameter<edm::ParameterSet>("legends");
0606   readCfgParameter<cfgEntryLegend>(cfgParSet_legends, legends_);
0607 
0608   //--- configure labels
0609   //std::cout << "--> configuring labels..." << std::endl;
0610   edm::ParameterSet cfgParSet_labels = cfg.getParameter<edm::ParameterSet>("labels");
0611   readCfgParameter<cfgEntryLabel>(cfgParSet_labels, labels_);
0612 
0613   //--- configure drawOptions
0614   //std::cout << "--> configuring drawOptions..." << std::endl;
0615   if (cfg.exists("drawOptionSets")) {
0616     edm::ParameterSet drawOptionSets = cfg.getParameter<edm::ParameterSet>("drawOptionSets");
0617     vstring drawOptionSetNames = drawOptionSets.getParameterNamesForType<edm::ParameterSet>();
0618     for (vstring::const_iterator drawOptionSetName = drawOptionSetNames.begin();
0619          drawOptionSetName != drawOptionSetNames.end();
0620          ++drawOptionSetName) {
0621       edm::ParameterSet drawOptionSet = drawOptionSets.getParameter<edm::ParameterSet>(*drawOptionSetName);
0622 
0623       vstring drawOptionEntryNames = drawOptionSet.getParameterNamesForType<edm::ParameterSet>();
0624       for (vstring::const_iterator drawOptionEntryName = drawOptionEntryNames.begin();
0625            drawOptionEntryName != drawOptionEntryNames.end();
0626            ++drawOptionEntryName) {
0627         edm::ParameterSet drawOptionEntry = drawOptionSet.getParameter<edm::ParameterSet>(*drawOptionEntryName);
0628 
0629         std::string drawOptionEntryName_full =
0630             std::string(*drawOptionSetName).append(drawOptionSeparator).append(*drawOptionEntryName);
0631         drawOptionEntries_.insert(std::pair<std::string, cfgEntryDrawOption>(
0632             drawOptionEntryName_full, cfgEntryDrawOption(drawOptionEntryName_full, drawOptionEntry)));
0633       }
0634     }
0635   }
0636 
0637   if (cfg.exists("drawOptionEntries")) {
0638     edm::ParameterSet cfgParSet_drawOptionEntries = cfg.getParameter<edm::ParameterSet>("drawOptionEntries");
0639     readCfgParameter<cfgEntryDrawOption>(cfgParSet_drawOptionEntries, drawOptionEntries_);
0640   }
0641 
0642   //--- configure drawJobs
0643   //std::cout << "--> configuring drawJobs..." << std::endl;
0644   edm::ParameterSet drawJobs = cfg.getParameter<edm::ParameterSet>("drawJobs");
0645   vstring drawJobNames = drawJobs.getParameterNamesForType<edm::ParameterSet>();
0646   for (vstring::const_iterator drawJobName = drawJobNames.begin(); drawJobName != drawJobNames.end(); ++drawJobName) {
0647     edm::ParameterSet drawJob = drawJobs.getParameter<edm::ParameterSet>(*drawJobName);
0648 
0649     std::map<int, plotDefList> plotDefMap;
0650 
0651     if (drawJob.existsAs<edm::ParameterSet>("plots")) {  // display same monitor element for different processes
0652       edm::ParameterSet plots = drawJob.getParameter<edm::ParameterSet>("plots");
0653 
0654       vstring dqmMonitorElements = plots.getParameter<vstring>("dqmMonitorElements");
0655       vstring processes = plots.getParameter<vstring>("processes");
0656 
0657       std::string drawOptionSet = drawJob.getParameter<std::string>("drawOptionSet");
0658       //std::cout << "drawOptionSet = " << drawOptionSet << std::endl;
0659 
0660       vstring stack = (cfg.exists("stack")) ? drawJob.getParameter<vstring>("stack") : vstring();
0661 
0662       for (vstring::const_iterator process = processes.begin(); process != processes.end(); ++process) {
0663         int index = 0;
0664         for (vstring::const_iterator dqmMonitorElement = dqmMonitorElements.begin();
0665              dqmMonitorElement != dqmMonitorElements.end();
0666              ++dqmMonitorElement) {
0667           bool stack_dqmMonitorElement = find_vstring(stack, *process);
0668           std::string drawOptionEntry = std::string(drawOptionSet).append(drawOptionSeparator).append(*process);
0669           plotDefMap[index].push_back(
0670               plotDefEntry(*dqmMonitorElement, drawOptionEntry, "", "", *process, stack_dqmMonitorElement));
0671           ++index;
0672         }
0673       }
0674     } else {  // display different monitor elements for same process
0675       typedef std::vector<edm::ParameterSet> vParameterSet;
0676       vParameterSet plots = drawJob.getParameter<vParameterSet>("plots");
0677 
0678       std::string process = (drawJob.exists("process")) ? drawJob.getParameter<std::string>("process") : "";
0679       //std::cout << "process (globally set) = " << process << std::endl;
0680 
0681       for (vParameterSet::const_iterator plot = plots.begin(); plot != plots.end(); ++plot) {
0682         if (process.empty() || plot->exists("process")) {
0683           process = plot->getParameter<std::string>("process");
0684           //std::cout << "process (locally set) = " << process << std::endl;
0685         }
0686 
0687         std::string drawOptionEntry = plot->getParameter<std::string>("drawOptionEntry");
0688         //std::cout << "drawOptionEntry = " << drawOptionEntry << std::endl;
0689 
0690         std::string legendEntry = "", legendEntryErrorBand = "";
0691         if (plot->exists("legendEntry")) {
0692           legendEntry = plot->getParameter<std::string>("legendEntry");
0693           legendEntryErrorBand = (plot->exists("legendEntryErrorBand"))
0694                                      ? plot->getParameter<std::string>("legendEntryErrorBand")
0695                                      : std::string(legendEntry).append(" Uncertainty");
0696         }
0697         //std::cout << "legendEntry = " << legendEntry << std::endl;
0698         //std::cout << "legendEntryErrorBand = " << legendEntryErrorBand << std::endl;
0699 
0700         vstring dqmMonitorElements = plot->getParameter<vstring>("dqmMonitorElements");
0701         int index = 0;
0702         for (vstring::const_iterator dqmMonitorElement = dqmMonitorElements.begin();
0703              dqmMonitorElement != dqmMonitorElements.end();
0704              ++dqmMonitorElement) {
0705           plotDefMap[index].push_back(
0706               plotDefEntry(*dqmMonitorElement, drawOptionEntry, legendEntry, legendEntryErrorBand, process, false));
0707           ++index;
0708         }
0709       }
0710     }
0711 
0712     //--- check that number of displayed monitor elements is the same for each plot
0713     unsigned numMonitorElements_ref = 0;
0714     bool isFirstEntry = true;
0715     for (std::map<int, plotDefList>::const_iterator plot = plotDefMap.begin(); plot != plotDefMap.end(); ++plot) {
0716       if (isFirstEntry) {
0717         numMonitorElements_ref = plot->second.size();
0718         isFirstEntry = false;
0719       } else {
0720         if (plot->second.size() != numMonitorElements_ref) {
0721           edm::LogError("TauDQMHistPlotter::TauDQMHistPlotter")
0722               << " Numbers of dqmMonitorElements must be the same for all plots"
0723               << " --> skipping drawJob = " << (*drawJobName) << " !!";
0724           cfgError_ = 1;
0725         }
0726       }
0727     }
0728 
0729     //--- expand process directories in names of dqmMonitorElements
0730     for (std::map<int, plotDefList>::iterator plot = plotDefMap.begin(); plot != plotDefMap.end(); ++plot) {
0731       for (plotDefList::iterator entry = plot->second.begin(); entry != plot->second.end(); ++entry) {
0732         std::string dqmMonitorElement = entry->dqmMonitorElement_;
0733         std::string process = entry->process_;
0734 
0735         std::map<std::string, cfgEntryProcess>::const_iterator it = processes_.find(process);
0736         if (it != processes_.end()) {
0737           std::string process_dqmDirectory = it->second.dqmDirectory_;
0738 
0739           //std::cout << "replacing processDir = " << process_dqmDirectory << " in drawJob = " << (*drawJobName) << std::endl;
0740 
0741           int errorFlag = 0;
0742           std::string dqmMonitorElement_expanded =
0743               replace_string(dqmMonitorElement, processDirKeyword, process_dqmDirectory, 0, 1, errorFlag);
0744           //std::cout << " dqmMonitorElement_expanded = " << dqmMonitorElement_expanded << std::endl;
0745 
0746           if (!errorFlag) {
0747             entry->dqmMonitorElement_ = dqmMonitorElement_expanded;
0748           } else {
0749             cfgError_ = 1;
0750           }
0751         } else {
0752           edm::LogError("TauDQMHistPlotter::TauDQMHistPlotter") << " Undefined process = " << process << " !!";
0753           cfgError_ = 1;
0754         }
0755       }
0756     }
0757 
0758     std::string title = (drawJob.exists("title")) ? drawJob.getParameter<std::string>("title") : "";
0759 
0760     std::string xAxis = drawJob.getParameter<std::string>("xAxis");
0761     std::string yAxis = drawJob.getParameter<std::string>("yAxis");
0762 
0763     std::string legend = drawJob.getParameter<std::string>("legend");
0764 
0765     vstring labels = (drawJob.exists("labels")) ? drawJob.getParameter<vstring>("labels") : vstring();
0766 
0767     //--- expand parameters in names of dqmMonitorElements;
0768     //    create drawJob objects
0769     for (std::map<int, plotDefList>::iterator plot = plotDefMap.begin(); plot != plotDefMap.end(); ++plot) {
0770       if (drawJob.exists("parameter")) {
0771         vstring vparameter = drawJob.getParameter<vstring>("parameter");
0772         //std::cout << "replacing parameter = " << format_vstring(vparameter) << " in drawJob = " << (*drawJobName) << std::endl;
0773 
0774         for (vstring::const_iterator parameter = vparameter.begin(); parameter != vparameter.end(); ++parameter) {
0775           plotDefList plot_expanded;
0776 
0777           for (plotDefList::const_iterator entry = plot->second.begin(); entry != plot->second.end(); ++entry) {
0778             std::string dqmMonitorElement = entry->dqmMonitorElement_;
0779 
0780             int errorFlag = 0;
0781             std::string dqmMonitorElement_expanded =
0782                 replace_string(dqmMonitorElement, parKeyword, *parameter, 1, 1, errorFlag);
0783             //std::cout << " dqmMonitorElement_expanded = " << dqmMonitorElement_expanded << std::endl;
0784             if (!errorFlag) {
0785               plot_expanded.push_back(plotDefEntry(dqmMonitorElement_expanded,
0786                                                    entry->drawOptionEntry_,
0787                                                    entry->legendEntry_,
0788                                                    entry->legendEntryErrorBand_,
0789                                                    entry->process_,
0790                                                    entry->doStack_));
0791             } else {
0792               cfgError_ = 1;
0793             }
0794           }
0795 
0796           int errorFlag = 0;
0797           std::string title_expanded = replace_string(title, parKeyword, *parameter, 0, 1, errorFlag);
0798           //std::cout << " title_expanded = " << title_expanded << std::endl;
0799           std::string xAxis_expanded = replace_string(xAxis, parKeyword, *parameter, 0, 1, errorFlag);
0800           //std::cout << " xAxis_expanded = " << xAxis_expanded << std::endl;
0801           std::string yAxis_expanded = replace_string(yAxis, parKeyword, *parameter, 0, 1, errorFlag);
0802           //std::cout << " yAxis_expanded = " << yAxis_expanded << std::endl;
0803           if (errorFlag)
0804             cfgError_ = 1;
0805 
0806           drawJobs_.push_back(cfgEntryDrawJob(std::string(*drawJobName).append(*parameter),
0807                                               plot_expanded,
0808                                               title_expanded,
0809                                               xAxis_expanded,
0810                                               yAxis_expanded,
0811                                               legend,
0812                                               labels));
0813         }
0814       } else {
0815         drawJobs_.push_back(cfgEntryDrawJob(*drawJobName, plot->second, title, xAxis, yAxis, legend, labels));
0816       }
0817     }
0818   }
0819 
0820   //--- check that all information neccessary to process drawJob is defined;
0821   for (std::list<cfgEntryDrawJob>::const_iterator drawJob = drawJobs_.begin(); drawJob != drawJobs_.end(); ++drawJob) {
0822     for (plotDefList::const_iterator plot = drawJob->plots_.begin(); plot != drawJob->plots_.end(); ++plot) {
0823       checkCfgDef<cfgEntryDrawOption>(
0824           plot->drawOptionEntry_, drawOptionEntries_, cfgError_, "drawOptionEntry", drawJob->name_);
0825       checkCfgDef<cfgEntryProcess>(plot->process_, processes_, cfgError_, "process", drawJob->name_);
0826     }
0827 
0828     checkCfgDef<cfgEntryAxisX>(drawJob->xAxis_, xAxes_, cfgError_, "xAxis", drawJob->name_);
0829     checkCfgDef<cfgEntryAxisY>(drawJob->yAxis_, yAxes_, cfgError_, "yAxis", drawJob->name_);
0830 
0831     checkCfgDef<cfgEntryLegend>(drawJob->legend_, legends_, cfgError_, "legend", drawJob->name_);
0832 
0833     checkCfgDefs<cfgEntryLabel>(drawJob->labels_, labels_, cfgError_, "label", drawJob->name_);
0834   }
0835 
0836   //--- configure canvas size
0837   //std::cout << "--> configuring canvas size..." << std::endl;
0838   canvasSizeX_ = (cfg.exists("canvasSizeX")) ? cfg.getParameter<int>("canvasSizeX") : defaultCanvasSizeX;
0839   canvasSizeY_ = (cfg.exists("canvasSizeY")) ? cfg.getParameter<int>("canvasSizeY") : defaultCanvasSizeY;
0840 
0841   //--- configure output files
0842   //std::cout << "--> configuring postscript output file..." << std::endl;
0843 
0844   outputFilePath_ = (cfg.exists("outputFilePath")) ? cfg.getParameter<std::string>("outputFilePath") : "";
0845   if (outputFilePath_.rbegin() != outputFilePath_.rend()) {
0846     if ((*outputFilePath_.rbegin()) == '/')
0847       outputFilePath_.erase(outputFilePath_.length() - 1);
0848   }
0849   //std::cout << " outputFilePath = " << outputFilePath_ << std::endl;
0850 
0851   outputFileName_ = (cfg.exists("outputFileName")) ? cfg.getParameter<std::string>("outputFileName") : "";
0852   //std::cout << " outputFileName = " << outputFileName_ << std::endl;
0853 
0854   indOutputFileName_ = (cfg.exists("indOutputFileName")) ? cfg.getParameter<std::string>("indOutputFileName") : "";
0855   if (!indOutputFileName_.empty() && indOutputFileName_.find('.') == std::string::npos) {
0856     edm::LogError("TauDQMHistPlotter") << " Failed to determine type of graphics format from indOutputFileName = "
0857                                        << indOutputFileName_ << " !!";
0858     cfgError_ = 1;
0859   }
0860   //std::cout << " indOutputFileName = " << indOutputFileName_ << std::endl;
0861 
0862   //--- check that exactly one type of output is specified for the plots
0863   //    (either separate graphics files displaying one plot each
0864   //     or postscript file displaying all plots on successive pages;
0865   //     cannot create both types of output simultaneously,
0866   //     as TCanvas::Print seems to interfere with TPostScript::NewPage)
0867   if (outputFileName_.empty() && indOutputFileName_.empty()) {
0868     edm::LogError("TauDQMHistPlotter") << " Either outputFileName or indOutputFileName must be specified !!";
0869     cfgError_ = 1;
0870   }
0871 
0872   if (!outputFileName_.empty() && !indOutputFileName_.empty()) {
0873     edm::LogError("TauDQMHistPlotter") << " Must not specify outputFileName and indOutputFileName simultaneously !!";
0874     cfgError_ = 1;
0875   }
0876 
0877   if (verbosity)
0878     std::cout << "done." << std::endl;
0879 }
0880 
0881 TauDQMHistPlotter::~TauDQMHistPlotter() {
0882   // nothing to be done yet...
0883 }
0884 
0885 void TauDQMHistPlotter::analyze(const edm::Event&, const edm::EventSetup&) {
0886   // nothing to be done yet...
0887 }
0888 
0889 void TauDQMHistPlotter::endRun(const edm::Run& r, const edm::EventSetup& c) {
0890   if (verbosity)
0891     std::cout << "<TauDQMHistPlotter::endJob>:" << std::endl;
0892 
0893   //--- check that configuration parameters contain no errors
0894   if (cfgError_) {
0895     edm::LogError("endJob") << " Error in Configuration ParameterSet --> histograms will NOT be plotted !!";
0896     return;
0897   }
0898 
0899   //--- check that DQMStore service is available
0900   if (!edm::Service<DQMStore>().isAvailable()) {
0901     edm::LogError("endJob") << " Failed to access dqmStore --> histograms will NOT be plotted !!";
0902     return;
0903   }
0904 
0905   DQMStore& dqmStore = (*edm::Service<DQMStore>());
0906 
0907   //--- stop ROOT from keeping references to all hsitograms
0908   //TH1::AddDirectory(false);
0909 
0910   //--- stop ROOT from opening X-window for canvas output
0911   //    (in order to be able to run in batch mode)
0912   gROOT->SetBatch(true);
0913 
0914   //--- initialize graphical output;
0915   //    open postscript file
0916   TCanvas canvas("TauDQMHistPlotter", "TauDQMHistPlotter", canvasSizeX_, canvasSizeY_);
0917   canvas.SetFillColor(10);
0918 
0919   //--- restrict area in which histograms are drawn to quadratic TPad in the center of the TCanvas,
0920   //    in order to make space for axis labels...
0921   //TPad pad("EWKTauPad", "EWKTauPad", 0.02, 0.15, 0.98, 0.85);
0922   //pad.SetFillColor(10);
0923   //pad.Draw();
0924   //pad.Divide(1,1);
0925   //pad.cd(1);
0926 
0927   TPostScript* ps = nullptr;
0928   if (!outputFileName_.empty()) {
0929     std::string psFileName =
0930         (!outputFilePath_.empty()) ? std::string(outputFilePath_).append("/").append(outputFileName_) : outputFileName_;
0931     ps = new TPostScript(psFileName.data(), 112);
0932   }
0933 
0934   //--- process drawJobs
0935   for (std::list<cfgEntryDrawJob>::const_iterator drawJob = drawJobs_.begin(); drawJob != drawJobs_.end(); ++drawJob) {
0936     const std::string& drawJobName = drawJob->name_;
0937     if (verbosity)
0938       std::cout << "--> processing drawJob " << drawJobName << "..." << std::endl;
0939 
0940     //--- prepare internally used histogram data-structures
0941     TH1* stackedHistogram_sum = nullptr;
0942     std::list<TH1*> histogramsToDelete;
0943     std::list<plotDefEntry*> drawOptionsToDelete;
0944 
0945     typedef std::pair<TH1*, const plotDefEntry*> histogram_drawOption_pair;
0946     std::list<histogram_drawOption_pair> allHistograms;
0947 
0948     for (plotDefList::const_iterator plot = drawJob->plots_.begin(); plot != drawJob->plots_.end(); ++plot) {
0949       std::string dqmMonitorElementName_full =
0950           dqmDirectoryName(std::string(dqmRootDirectory)).append(plot->dqmMonitorElement_);
0951       if (verbosity)
0952         std::cout << " dqmMonitorElementName_full = " << dqmMonitorElementName_full << std::endl;
0953       MonitorElement* dqmMonitorElement = dqmStore.get(dqmMonitorElementName_full);
0954 
0955       TH1* histogram = dqmMonitorElement->getTH1F();
0956       if (verbosity)
0957         std::cout << "Got Histogram " << std::endl;
0958       //      TH1* histogram = ( dqmMonitorElement ) ? dynamic_cast<TH1*>(dqmMonitorElement->getTH1()->Clone()) : NULL;
0959       //histogramsToDelete.push_back(histogram);
0960 
0961       if (histogram == nullptr) {
0962         edm::LogError("endJob") << " Failed to access dqmMonitorElement = " << dqmMonitorElementName_full << ","
0963                                 << " needed by drawJob = " << drawJobName << " --> histograms will NOT be plotted !!";
0964         continue;
0965       }
0966 
0967       if (!histogram->GetSumw2N())
0968         histogram->Sumw2();
0969 
0970       const cfgEntryDrawOption* drawOptionConfig =
0971           findCfgDef<cfgEntryDrawOption>(plot->drawOptionEntry_, drawOptionEntries_, "drawOptionEntry", drawJobName);
0972       if (drawOptionConfig == nullptr) {
0973         edm::LogError("endJob") << " Failed to access information needed by drawJob = " << drawJobName
0974                                 << " --> histograms will NOT be plotted !!";
0975         return;
0976       }
0977 
0978       if (drawOptionConfig->drawOption_ == drawOption_eBand) {
0979         //--- add histogram displaying central value as solid line
0980         TH1* histogram_centralValue = dynamic_cast<TH1*>(histogram->Clone());
0981         histogram_centralValue->SetName(std::string(histogram->GetName()).append("_centralValue").data());
0982         cfgEntryDrawOption drawOptionConfig_centralValue(*drawOptionConfig);
0983         drawOptionConfig_centralValue.fillColor_ = 0;
0984         drawOptionConfig_centralValue.fillStyle_ = 0;
0985         drawOptionConfig_centralValue.drawOption_ = "hist";
0986         drawOptionConfig_centralValue.drawOptionLegend_ = "l";
0987         std::string drawOptionName_centralValue = std::string(plot->drawOptionEntry_).append("_centralValue");
0988         //--- entries in std::map need to be unique,
0989         //    so need to check whether drawOptionEntry already exists...
0990         if (drawOptionEntries_.find(drawOptionName_centralValue) == drawOptionEntries_.end())
0991           drawOptionEntries_.insert(std::pair<std::string, cfgEntryDrawOption>(
0992               drawOptionName_centralValue,
0993               cfgEntryDrawOption(drawOptionName_centralValue, drawOptionConfig_centralValue)));
0994         plotDefEntry* plot_centralValue = new plotDefEntry(*plot);
0995         plot_centralValue->drawOptionEntry_ = drawOptionName_centralValue;
0996         allHistograms.push_back(histogram_drawOption_pair(histogram_centralValue, plot_centralValue));
0997         histogramsToDelete.push_back(histogram_centralValue);
0998         drawOptionsToDelete.push_back(plot_centralValue);
0999 
1000         //--- add histogram displaying uncertainty as shaded error band
1001         TH1* histogram_ErrorBand = dynamic_cast<TH1*>(histogram->Clone());
1002         histogram_ErrorBand->SetName(std::string(histogram->GetName()).append("_ErrorBand").data());
1003         cfgEntryDrawOption drawOptionConfig_ErrorBand(*drawOptionConfig);
1004         drawOptionConfig_ErrorBand.markerColor_ = drawOptionConfig_ErrorBand.fillColor_;
1005         drawOptionConfig_ErrorBand.markerSize_ = 0.;
1006         drawOptionConfig_ErrorBand.lineColor_ = drawOptionConfig_ErrorBand.fillColor_;
1007         drawOptionConfig_ErrorBand.lineWidth_ = 0;
1008         drawOptionConfig_ErrorBand.drawOption_ = "e2";
1009         drawOptionConfig_ErrorBand.drawOptionLegend_ = "f";
1010         std::string drawOptionName_ErrorBand = std::string(plot->drawOptionEntry_).append("_ErrorBand");
1011         //--- entries in std::map need to be unique,
1012         //    so need to check whether drawOptionEntry already exists...
1013         if (drawOptionEntries_.find(drawOptionName_ErrorBand) == drawOptionEntries_.end())
1014           drawOptionEntries_.insert(std::pair<std::string, cfgEntryDrawOption>(
1015               drawOptionName_ErrorBand, cfgEntryDrawOption(drawOptionName_ErrorBand, drawOptionConfig_ErrorBand)));
1016         plotDefEntry* plot_ErrorBand = new plotDefEntry(*plot);
1017         plot_ErrorBand->drawOptionEntry_ = drawOptionName_ErrorBand;
1018         plot_ErrorBand->isErrorBand_ = true;
1019         allHistograms.push_back(histogram_drawOption_pair(histogram_ErrorBand, plot_ErrorBand));
1020         histogramsToDelete.push_back(histogram_ErrorBand);
1021         drawOptionsToDelete.push_back(plot_ErrorBand);
1022       } else if (plot->doStack_) {
1023         TH1* stackedHistogram = dynamic_cast<TH1*>(histogram->Clone());
1024         if (stackedHistogram_sum)
1025           stackedHistogram->Add(stackedHistogram_sum);
1026         stackedHistogram_sum = stackedHistogram;
1027         histogramsToDelete.push_back(stackedHistogram);
1028         allHistograms.push_back(histogram_drawOption_pair(stackedHistogram, &(*plot)));
1029       } else {
1030         allHistograms.push_back(histogram_drawOption_pair(histogram, &(*plot)));
1031       }
1032     }
1033 
1034     //--- determine normalization of y-axis
1035     //    (maximum of any of the histograms included in drawJob)
1036     double yAxisNorm = 0.;
1037     for (std::list<histogram_drawOption_pair>::const_iterator it = allHistograms.begin(); it != allHistograms.end();
1038          ++it) {
1039       yAxisNorm = TMath::Max(yAxisNorm, it->first->GetMaximum());
1040     }
1041     //std::cout << " yAxisNorm = " << yAxisNorm << std::endl;
1042 
1043     //--- prepare histograms for drawing
1044     const cfgEntryAxisX* xAxisConfig = findCfgDef<cfgEntryAxisX>(drawJob->xAxis_, xAxes_, "xAxis", drawJobName);
1045     const cfgEntryAxisY* yAxisConfig = findCfgDef<cfgEntryAxisY>(drawJob->yAxis_, yAxes_, "yAxis", drawJobName);
1046     const cfgEntryLegend* legendConfig = findCfgDef<cfgEntryLegend>(drawJob->legend_, legends_, "legend", drawJobName);
1047     if (xAxisConfig == nullptr || yAxisConfig == nullptr || legendConfig == nullptr) {
1048       edm::LogError("endJob") << " Failed to access information needed by drawJob = " << drawJobName
1049                               << " --> histograms will NOT be plotted !!";
1050       return;
1051     }
1052 
1053     //--- WARNING: need to call
1054     //              TLegend::TLegend(Double_t, Double_t,Double_t, Double_t, const char* = "", Option_t* = "brNDC")
1055     //             constructor, as TLegend::TLegend default constructor causes the created TLegend object to behave differently !!
1056     TLegend legend(defaultLegendPosX,
1057                    defaultLegendPosY,
1058                    defaultLegendPosX + defaultLegendSizeX,
1059                    defaultLegendPosY + defaultLegendSizeY);
1060     legendConfig->applyTo(&legend);
1061 
1062     std::list<histoDrawEntry> smProcessHistogramList;
1063     std::list<histoDrawEntry> bsmProcessHistogramList;
1064     std::list<histoDrawEntry> smSumHistogramList;
1065     std::list<histoDrawEntry> smSumUncertaintyHistogramList;
1066     std::list<histoDrawEntry> dataHistogramList;
1067 
1068     for (std::list<histogram_drawOption_pair>::const_iterator it = allHistograms.begin(); it != allHistograms.end();
1069          ++it) {
1070       TH1* histogram = it->first;
1071       const plotDefEntry* drawOption = it->second;
1072 
1073       const cfgEntryDrawOption* drawOptionConfig = findCfgDef<cfgEntryDrawOption>(
1074           drawOption->drawOptionEntry_, drawOptionEntries_, "drawOptionEntry", drawJobName);
1075       const cfgEntryProcess* processConfig =
1076           findCfgDef<cfgEntryProcess>(drawOption->process_, processes_, "process", drawJobName);
1077       if (drawOptionConfig == nullptr || processConfig == nullptr) {
1078         edm::LogError("endJob") << " Failed to access information needed by drawJob = " << drawJobName
1079                                 << " --> histograms will NOT be plotted !!";
1080         return;
1081       }
1082 
1083       if (!drawJob->title_.empty())
1084         histogram->SetTitle(drawJob->title_.data());
1085 
1086       xAxisConfig->applyTo(histogram);
1087       yAxisConfig->applyTo(histogram, yAxisNorm);
1088 
1089       bool yLogScale = (yAxisConfig->yScale_ == yScale_log) ? true : false;
1090       //std::cout << " yLogScale = " << yLogScale << std::endl;
1091       //pad.SetLogy(yLogScale);
1092       canvas.SetLogy(yLogScale);
1093 
1094       drawOptionConfig->applyTo(histogram);
1095       histogram->SetStats(false);
1096 
1097       if (drawOption->isErrorBand_) {
1098         smSumUncertaintyHistogramList.push_back(histoDrawEntry(histogram, drawOptionConfig->drawOption_.data()));
1099       } else {
1100         if (processConfig->type_ == type_smMC) {
1101           smProcessHistogramList.push_back(histoDrawEntry(histogram, drawOptionConfig->drawOption_.data()));
1102         } else if (processConfig->type_ == type_bsmMC) {
1103           bsmProcessHistogramList.push_back(histoDrawEntry(histogram, drawOptionConfig->drawOption_.data()));
1104         } else if (processConfig->type_ == type_smSumMC) {
1105           smSumHistogramList.push_back(histoDrawEntry(histogram, drawOptionConfig->drawOption_.data()));
1106         } else if (processConfig->type_ == type_Data) {
1107           dataHistogramList.push_back(histoDrawEntry(histogram, drawOptionConfig->drawOption_.data()));
1108         }
1109       }
1110 
1111       std::string legendEntry, legendDrawOption;
1112       if (drawOption->isErrorBand_) {
1113         legendEntry = (!drawOption->legendEntryErrorBand_.empty()) ? drawOption->legendEntryErrorBand_
1114                                                                    : processConfig->legendEntryErrorBand_;
1115         legendDrawOption = "f";
1116       } else {
1117         legendEntry = (!drawOption->legendEntry_.empty()) ? drawOption->legendEntry_ : processConfig->legendEntry_;
1118         legendDrawOption = drawOptionConfig->drawOptionLegend_;
1119       }
1120 
1121       legend.AddEntry(histogram, legendEntry.data(), legendDrawOption.data());
1122     }
1123 
1124     std::list<TPaveText> labels;
1125     for (vstring::const_iterator labelName = drawJob->labels_.begin(); labelName != drawJob->labels_.end();
1126          ++labelName) {
1127       const cfgEntryLabel* labelConfig = findCfgDef<cfgEntryLabel>(*labelName, labels_, "label", drawJobName);
1128 
1129       TPaveText label;
1130       labelConfig->applyTo(&label);
1131 
1132       labels.push_back(label);
1133     }
1134 
1135     //--- draw histograms
1136     //   - in the order:
1137     //    1. uncertainty on sum of all Standard Model processes
1138     //    2. sum of all Standard Model processes
1139     //    3. individual Standard Model processes
1140     //    4. individual beyond the Standard Model processes
1141     //    5. data
1142     bool isFirstHistogram = true;
1143     drawHistograms(smSumUncertaintyHistogramList, isFirstHistogram);
1144     drawHistograms(smSumHistogramList, isFirstHistogram);
1145 
1146     //--- process histograms for individual Standard Model processes
1147     //    in reverse order, so that most stacked histogram gets drawn first
1148     for (std::list<histoDrawEntry>::reverse_iterator it = smProcessHistogramList.rbegin();
1149          it != smProcessHistogramList.rend();
1150          ++it) {
1151       std::string drawOption = (isFirstHistogram) ? it->second : std::string(it->second).append("same");
1152       it->first->Draw(drawOption.data());
1153       isFirstHistogram = false;
1154     }
1155 
1156     drawHistograms(bsmProcessHistogramList, isFirstHistogram);
1157     drawHistograms(dataHistogramList, isFirstHistogram);
1158 
1159     legend.Draw();
1160 
1161     for (std::list<TPaveText>::iterator label = labels.begin(); label != labels.end(); ++label) {
1162       label->Draw();
1163     }
1164 
1165     //pad.RedrawAxis();
1166 
1167     canvas.Update();
1168     //pad.Update();
1169 
1170     if (!indOutputFileName_.empty() && toFile_) {
1171       int errorFlag = 0;
1172       std::string modIndOutputFileName = replace_string(indOutputFileName_, plotKeyword, drawJobName, 1, 1, errorFlag);
1173       if (!errorFlag) {
1174         std::string fullFileName = (!outputFilePath_.empty())
1175                                        ? std::string(outputFilePath_).append("/").append(modIndOutputFileName)
1176                                        : modIndOutputFileName;
1177         canvas.Print(fullFileName.data());
1178       } else {
1179         edm::LogError("endJob") << " Failed to decode indOutputFileName = " << indOutputFileName_ << " --> skipping !!";
1180       }
1181     }
1182 
1183     if (ps)
1184       ps->NewPage();
1185 
1186     //--- delete temporarily created histogram and drawOption objects
1187     for (std::list<TH1*>::const_iterator histogram = histogramsToDelete.begin(); histogram != histogramsToDelete.end();
1188          ++histogram) {
1189       delete (*histogram);
1190     }
1191 
1192     for (std::list<plotDefEntry*>::const_iterator drawOption = drawOptionsToDelete.begin();
1193          drawOption != drawOptionsToDelete.end();
1194          ++drawOption) {
1195       delete (*drawOption);
1196     }
1197   }
1198 
1199   //--- close postscript file
1200   canvas.Clear();
1201   if (verbosity)
1202     std::cout << "done." << std::endl;
1203   if (ps)
1204     ps->Close();
1205   delete ps;
1206 }
1207 
1208 #include "FWCore/Framework/interface/MakerMacros.h"
1209 
1210 DEFINE_FWK_MODULE(TauDQMHistPlotter);