Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-10-05 02:13:53

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