CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_2_9/src/Validation/RecoTau/plugins/DQMHistPlotter.cc

Go to the documentation of this file.
00001 #include "Validation/RecoTau/plugins/DQMHistPlotter.h"
00002 
00003 #include "Validation/RecoTau/plugins/dqmAuxFunctions.h"
00004 
00005 // framework & common header files
00006 #include "FWCore/Framework/interface/Frameworkfwd.h"
00007 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00008 
00009 //DQM services
00010 #include "DQMServices/Core/interface/DQMStore.h"
00011 #include "FWCore/ServiceRegistry/interface/Service.h"
00012 #include "DQMServices/Core/interface/MonitorElement.h"
00013 
00014 #include <TCanvas.h>
00015 #include <TPad.h>
00016 #include <TPostScript.h>
00017 #include <TStyle.h>
00018 #include <TROOT.h>
00019 #include <TMath.h>
00020 
00021 #include <iostream>
00022 
00023 //defaults for cfgEntryProcess
00024 const double defaultScaleFactor = 1.;
00025 const std::string type_smMC = "smMC";
00026 const std::string type_bsmMC = "bsmMC";
00027 const std::string type_smSumMC = "smSumMC";
00028 const std::string type_Data = "Data";
00029 
00030 //defaults for cfgEntryAxisX
00031 const double defaultMinX = -1.;
00032 const double defaultMaxX = -1.;
00033 const double defaultXaxisTitleOffset = 1.0;
00034 const double defaultXaxisTitleSize = 0.05;
00035 
00036 //defaults for cfgEntryAxisY
00037 const double defaultMinY_linear = 0.;
00038 const double defaultMinY_log = 1.e-2;
00039 const double defaultMaxY_linear = -1.;
00040 const double defaultMaxY_log = -1.;
00041 const std::string yScale_linear = "linear";
00042 const std::string yScale_log = "log";
00043 const std::string defaultYscale = yScale_linear;
00044 const double defaultYaxisTitleOffset = 1.0;
00045 const double defaultYaxisTitleSize = 0.05;
00046 const double defaultYaxisMaximumScaleFactor_linear = 1.6;
00047 const double defaultYaxisMaximumScaleFactor_log = 5.e+2;
00048 
00049 double TauDQMHistPlotter::cfgEntryAxisY::yAxisNorm_ = 0.;
00050 
00051 // defaults for cfgEntryLegend
00052 const double defaultLegendPosX = 0.50;
00053 const double defaultLegendPosY = 0.55;
00054 const double defaultLegendSizeX =  0.39;
00055 const double defaultLegendSizeY =  0.34;
00056 const std::string defaultLegendHeader = "";
00057 const std::string defaultLegendOptions = "brNDC";
00058 const int defaultLegendBorderSize = 0;
00059 const int defaultLegendFillColor = 0;
00060 
00061 // defaults for cfgEntryLabel
00062 const double defaultLabelPosX = 0.66;
00063 const double defaultLabelPosY = 0.82;
00064 const double defaultLabelSizeX = 0.26;
00065 const double defaultLabelSizeY = 0.10;
00066 const std::string defaultLabelOptions = "brNDC";
00067 const int defaultLabelBorderSize = 0;
00068 const int defaultLabelFillColor = 0;
00069 const int defaultLabelTextColor = 1;
00070 const double defaultLabelTextSize = 0.05;
00071 const int defaultLabelTextAlign = 22; // horizontally and vertically centered, see documentation of TAttText
00072 const double defaultLabelTextAngle = 0.;
00073 
00074 // defaults for cfgEntryDrawOption
00075 const int defaultMarkerColor = 1;
00076 const int defaultMarkerSize = 1;
00077 const int defaultMarkerStyle = 2;
00078 const int defaultLineColor = 0;
00079 const int defaultLineStyle = 1;
00080 const int defaultLineWidth = 2;
00081 const int defaultFillColor = 0;
00082 const int defaultFillStyle = 1001;
00083 const std::string defaultDrawOption = "";
00084 const std::string defaultDrawOptionLegend = "lpf";
00085 
00086 const std::string drawOption_eBand = "eBand";
00087 
00088 // defaults for cfgEntryDrawJob
00089 const bool defaultDoOverlayPlots = false;
00090 
00091 // global defaults
00092 const int defaultCanvasSizeX = 800;
00093 const int defaultCanvasSizeY = 600;
00094 
00095 const std::string drawOptionSeparator = "#.#";
00096 
00097 const int verbosity = 0;
00098 
00099 template <class T>
00100 void checkCfgDef(const std::string& cfgEntryName, std::map<std::string, T>& def, int& errorFlag,
00101                  const std::string& defType, const std::string& drawJobName)
00102 {
00103   if ( def.find(cfgEntryName) == def.end() ) {
00104     edm::LogError ("checkCfgDef") << " " << defType << " = " << cfgEntryName << " undefined, needed by drawJob = " << drawJobName << " !!";
00105     errorFlag = 1;
00106   }
00107 }
00108 
00109 template <class T>
00110 void checkCfgDefs(const std::vector<std::string>& cfgEntryNames, std::map<std::string, T>& def, int& errorFlag,
00111                   const std::string& defType, const std::string& drawJobName)
00112 {
00113   for ( std::vector<std::string>::const_iterator cfgEntryName = cfgEntryNames.begin();
00114         cfgEntryName != cfgEntryNames.end(); ++cfgEntryName ) {
00115     checkCfgDef(*cfgEntryName, def, errorFlag, defType, drawJobName);
00116   }
00117 }
00118 
00119 template <class T>
00120 const T* findCfgDef(const std::string& cfgEntryName, std::map<std::string, T>& def,
00121                     const std::string& defType, const std::string& drawJobName)
00122 {
00123   typename std::map<std::string, T>::const_iterator it = def.find(cfgEntryName);
00124   if ( it != def.end() ) {
00125     return &(it->second);
00126   } else {
00127     edm::LogError ("findCfgDef") << " " << defType << " = " << cfgEntryName << " undefined, needed by drawJob = " << drawJobName << " !!";
00128     return NULL;
00129   } 
00130 }
00131 
00132 //
00133 //-----------------------------------------------------------------------------------------------------------------------
00134 //
00135 
00136 typedef std::pair<TH1*, std::string> histoDrawEntry;
00137 
00138 void drawHistograms(const std::list<histoDrawEntry>& histogramList, bool& isFirstHistogram)
00139 {
00140   for ( std::list<histoDrawEntry>::const_iterator it = histogramList.begin();
00141         it != histogramList.end(); ++it ) {
00142     std::string drawOption = ( isFirstHistogram ) ? it->second : std::string(it->second).append("same");
00143     it->first->Draw(drawOption.data());
00144     isFirstHistogram = false;
00145   }
00146 }
00147 
00148 //
00149 //-----------------------------------------------------------------------------------------------------------------------
00150 //
00151 
00152 bool find_vstring(const std::vector<std::string>& vs, const std::string& s)
00153 {
00154   for ( std::vector<std::string>::const_iterator it = vs.begin();
00155         it != vs.end(); ++it ) {
00156     if ( (*it) == s ) return true;
00157   }
00158   return false;
00159 }
00160 
00161 //
00162 //-----------------------------------------------------------------------------------------------------------------------
00163 //
00164 
00165 TauDQMHistPlotter::cfgEntryProcess::cfgEntryProcess(const std::string& name, const edm::ParameterSet& cfg)
00166 {
00167   name_ = name;
00168 
00169   dqmDirectory_ = cfg.getParameter<std::string>("dqmDirectory");
00170   
00171   legendEntry_ = cfg.getParameter<std::string>("legendEntry");
00172   legendEntryErrorBand_ = ( cfg.exists("legendEntryErrorBand") ) ? 
00173     cfg.getParameter<std::string>("legendEntryErrorBand") : std::string(legendEntry_).append(" Uncertainty");
00174 
00175   type_ = cfg.getParameter<std::string>("type");
00176   
00177   if ( verbosity ) print();
00178 }
00179 
00180 void TauDQMHistPlotter::cfgEntryProcess::print() const
00181 {
00182   std::cout << "<TauDQMHistPlotter::cfgEntryProcess::print>:" << std::endl;
00183   std::cout << " name = " << name_ << std::endl;
00184   std::cout << " dqmDirectory = " << dqmDirectory_ << std::endl;
00185   std::cout << " legendEntry = " << legendEntry_ << std::endl;
00186   std::cout << " legendEntryErrorBand = " << legendEntryErrorBand_ << std::endl;
00187   std::cout << " type = " << type_ << std::endl;
00188 }
00189 
00190 //
00191 //-----------------------------------------------------------------------------------------------------------------------
00192 //
00193 
00194 TauDQMHistPlotter::cfgEntryAxisX::cfgEntryAxisX(const std::string& name, const edm::ParameterSet& cfg)
00195 {
00196   name_ = name;
00197 
00198   minX_ = ( cfg.exists("minX") ) ? cfg.getParameter<double>("minX") : defaultMinX;
00199   maxX_ = ( cfg.exists("maxX") ) ? cfg.getParameter<double>("maxX") : defaultMaxX;
00200   xAxisTitle_ = cfg.getParameter<std::string>("xAxisTitle");
00201   xAxisTitleOffset_ = ( cfg.exists("xAxisTitleOffset") ) ? cfg.getParameter<double>("xAxisTitleOffset") : defaultXaxisTitleOffset;
00202   xAxisTitleSize_ = ( cfg.exists("xAxisTitleSize") ) ? cfg.getParameter<double>("xAxisTitleSize") : defaultXaxisTitleSize;
00203 
00204   if ( verbosity ) print();
00205 }
00206 
00207 void TauDQMHistPlotter::cfgEntryAxisX::print() const
00208 {
00209   std::cout << "<TauDQMHistPlotter::cfgEntryAxisX::print>:" << std::endl;
00210   std::cout << " name = " << name_ << std::endl;
00211   std::cout << " minX_ = " << minX_ << std::endl;
00212   std::cout << " maxX_ = " << maxX_ << std::endl;
00213   std::cout << " xAxisTitle = " << xAxisTitle_ << std::endl;
00214   std::cout << " xAxisTitleOffset = " << xAxisTitleOffset_ << std::endl;
00215   std::cout << " xAxisTitleSize = " << xAxisTitleSize_ << std::endl;
00216 }
00217 
00218 void TauDQMHistPlotter::cfgEntryAxisX::applyTo(TH1* histogram) const
00219 {
00220   if ( histogram ) {
00221     double xMin = ( minX_ != defaultMinX ) ? minX_ : histogram->GetXaxis()->GetXmin();
00222     double xMax = ( maxX_ != defaultMaxX ) ? maxX_ : histogram->GetXaxis()->GetXmax();
00223     histogram->SetAxisRange(xMin, xMax, "X");
00224     histogram->GetXaxis()->SetTitle(xAxisTitle_.data());
00225     histogram->GetXaxis()->SetTitleOffset(xAxisTitleOffset_);
00226     histogram->GetXaxis()->SetTitleSize(xAxisTitleSize_);
00227   }
00228 }
00229 
00230 //
00231 //-----------------------------------------------------------------------------------------------------------------------
00232 //
00233 
00234 TauDQMHistPlotter::cfgEntryAxisY::cfgEntryAxisY(const std::string& name, const edm::ParameterSet& cfg)
00235 {
00236   name_ = name;
00237 
00238   minY_linear_ = ( cfg.exists("minY_linear") ) ? cfg.getParameter<double>("minY_linear") : defaultMinY_linear;
00239   minY_log_ = ( cfg.exists("minY_log") ) ? cfg.getParameter<double>("minY_log") : defaultMinY_log;
00240   maxY_linear_ = ( cfg.exists("maxY_linear") ) ? cfg.getParameter<double>("maxY_linear") : defaultMaxY_linear;
00241   maxY_log_ = ( cfg.exists("maxY_log") ) ? cfg.getParameter<double>("maxY_log") : defaultMaxY_log;
00242   yScale_ = ( cfg.exists("yScale") ) ? cfg.getParameter<std::string>("yScale") : defaultYscale;
00243   yAxisTitle_ = cfg.getParameter<std::string>("yAxisTitle");
00244   yAxisTitleOffset_ = ( cfg.exists("yAxisTitleOffset") ) ? cfg.getParameter<double>("yAxisTitleOffset") : defaultYaxisTitleOffset;
00245   yAxisTitleSize_ = ( cfg.exists("yAxisTitleSize") ) ? cfg.getParameter<double>("yAxisTitleSize") : defaultYaxisTitleSize;
00246 
00247   if ( verbosity ) print();
00248 }
00249 
00250 void TauDQMHistPlotter::cfgEntryAxisY::print() const
00251 {
00252   std::cout << "<TauDQMHistPlotter::cfgEntryAxisY::print>:" << std::endl;
00253   std::cout << " name = " << name_ << std::endl;
00254   std::cout << " minY_linear = " << minY_linear_ << std::endl;
00255   std::cout << " minY_log = " << minY_log_ << std::endl;
00256   std::cout << " maxY_linear = " << maxY_linear_ << std::endl;
00257   std::cout << " maxY_log = " << maxY_log_ << std::endl;
00258   std::cout << " yScale = " << yScale_ << std::endl;
00259   std::cout << " yAxisTitle = " << yAxisTitle_ << std::endl;
00260   std::cout << " yAxisTitleOffset = " << yAxisTitleOffset_ << std::endl;
00261   std::cout << " yAxisTitleSize = " << yAxisTitleSize_ << std::endl;
00262 }
00263 
00264 void TauDQMHistPlotter::cfgEntryAxisY::applyTo(TH1* histogram) const
00265 {
00266   if ( histogram ) {
00267     bool yLogScale = ( yScale_ == yScale_log ) ? true : false;
00268     double minY = ( yLogScale ) ? minY_log_ : minY_linear_;
00269     histogram->SetMinimum(minY);
00270     double maxY = ( yLogScale ) ? maxY_log_ : maxY_linear_;
00271     double defaultMaxY = ( yLogScale ) ? defaultMaxY_log : defaultMaxY_linear;
00272     if ( maxY != defaultMaxY ) {
00273 //--- normalize y-axis range using given configuration parameter
00274       histogram->SetMaximum(maxY);
00275     } else {
00276 //--- in case configuration parameter for y-axis range not explicitely given,
00277 //    normalize y-axis range to maximum of any histogram included in drawJob
00278 //    times defaultYaxisMaximumScaleFactor (apply scale factor in order to make space for legend)
00279       double defaultYaxisMaximumScaleFactor = ( yLogScale ) ? defaultYaxisMaximumScaleFactor_log : defaultYaxisMaximumScaleFactor_linear;
00280       histogram->SetMaximum(defaultYaxisMaximumScaleFactor*yAxisNorm_);
00281     }
00282     histogram->GetYaxis()->SetTitle(yAxisTitle_.data());
00283     histogram->GetYaxis()->SetTitleOffset(yAxisTitleOffset_);
00284     histogram->GetYaxis()->SetTitleSize(yAxisTitleSize_);
00285   }
00286 }
00287 
00288 //
00289 //-----------------------------------------------------------------------------------------------------------------------
00290 //
00291 
00292 TauDQMHistPlotter::cfgEntryLegend::cfgEntryLegend(const std::string& name, const edm::ParameterSet& cfg)
00293 {
00294   name_ = name;
00295 
00296   posX_ = ( cfg.exists("posX") ) ? cfg.getParameter<double>("posX") : defaultLegendPosX;
00297   posY_ = ( cfg.exists("posY") ) ? cfg.getParameter<double>("posY") : defaultLegendPosY;
00298   sizeX_ = ( cfg.exists("sizeX") ) ? cfg.getParameter<double>("sizeX") : defaultLegendSizeX;
00299   sizeY_ = ( cfg.exists("sizeY") ) ? cfg.getParameter<double>("sizeY") : defaultLegendSizeY;
00300   header_ = ( cfg.exists("header") ) ? cfg.getParameter<std::string>("header") : defaultLegendHeader;
00301   option_ = ( cfg.exists("option") ) ? cfg.getParameter<std::string>("option") : defaultLegendOptions;
00302   borderSize_ = ( cfg.exists("borderSize") ) ? cfg.getParameter<int>("borderSize") : defaultLegendBorderSize;
00303   fillColor_ = ( cfg.exists("fillColor") ) ? cfg.getParameter<int>("fillColor") : defaultLegendFillColor;
00304  
00305   if ( verbosity ) print();
00306 }
00307 
00308 void TauDQMHistPlotter::cfgEntryLegend::print() const
00309 {
00310   std::cout << "<TauDQMHistPlotter::cfgEntryLegend::print>:" << std::endl;
00311   std::cout << " name = " << name_ << std::endl;
00312   std::cout << " posX = " << posX_ << std::endl;
00313   std::cout << " posY = " << posY_ << std::endl;
00314   std::cout << " sizeX = " << sizeX_ << std::endl;
00315   std::cout << " sizeY = " << sizeY_ << std::endl;
00316   std::cout << " header = " << header_ << std::endl;
00317   std::cout << " option = " << option_ << std::endl;
00318   std::cout << " borderSize = " << borderSize_ << std::endl;
00319   std::cout << " fillColor = " << fillColor_ << std::endl;
00320 }
00321 
00322 void TauDQMHistPlotter::cfgEntryLegend::applyTo(TLegend* legend) const
00323 {
00324   if ( legend ) {
00325     legend->SetX1(posX_);
00326     legend->SetY1(posY_);
00327     legend->SetX2(posX_ + sizeX_);
00328     legend->SetY2(posY_ + sizeY_);
00329     legend->SetHeader(header_.data());
00330     legend->SetOption(option_.data());
00331     legend->SetBorderSize(borderSize_);
00332     legend->SetFillColor(fillColor_);
00333   }
00334 }
00335 
00336 //
00337 //-----------------------------------------------------------------------------------------------------------------------
00338 //
00339 
00340 TauDQMHistPlotter::cfgEntryLabel::cfgEntryLabel(const std::string& name, const edm::ParameterSet& cfg)
00341 {
00342   name_ = name;
00343 
00344   posX_ = ( cfg.exists("posX") ) ? cfg.getParameter<double>("posX") : defaultLabelPosX;
00345   posY_ = ( cfg.exists("posY") ) ? cfg.getParameter<double>("posY") : defaultLabelPosY;
00346   sizeX_ = ( cfg.exists("sizeX") ) ? cfg.getParameter<double>("sizeX") : defaultLabelSizeX;
00347   sizeY_ = ( cfg.exists("sizeY") ) ? cfg.getParameter<double>("sizeY") : defaultLabelSizeY;
00348   option_ = ( cfg.exists("option") ) ? cfg.getParameter<std::string>("option") : defaultLabelOptions;
00349   borderSize_ = ( cfg.exists("borderSize") ) ? cfg.getParameter<int>("borderSize") : defaultLabelBorderSize;
00350   fillColor_ = ( cfg.exists("fillColor") ) ? cfg.getParameter<int>("fillColor") : defaultLabelFillColor;
00351   textColor_ = ( cfg.exists("textColor") ) ? cfg.getParameter<int>("textColor") : defaultLabelTextColor;
00352   textSize_ = ( cfg.exists("textSize") ) ? cfg.getParameter<double>("textSize") : defaultLabelTextSize;
00353   textAlign_ = ( cfg.exists("textAlign") ) ? cfg.getParameter<int>("textAlign") : defaultLabelTextAlign;
00354   textAngle_ = ( cfg.exists("textAngle") ) ? cfg.getParameter<double>("textAngle") : defaultLabelTextAngle;
00355   text_ = cfg.getParameter<vstring>("text");
00356  
00357   if ( verbosity ) print();
00358 }
00359 
00360 void TauDQMHistPlotter::cfgEntryLabel::print() const
00361 {
00362   std::cout << "<TauDQMHistPlotter::cfgEntryLabel::print>:" << std::endl;
00363   std::cout << " name = " << name_ << std::endl;
00364   std::cout << " posX = " << posX_ << std::endl;
00365   std::cout << " posY = " << posY_ << std::endl;
00366   std::cout << " sizeX = " << sizeX_ << std::endl;
00367   std::cout << " sizeY = " << sizeY_ << std::endl;
00368   std::cout << " option = " << option_ << std::endl;
00369   std::cout << " borderSize = " << borderSize_ << std::endl;
00370   std::cout << " fillColor = " << fillColor_ << std::endl;
00371   std::cout << " textColor = " << textColor_ << std::endl;
00372   std::cout << " textSize = " << textSize_ << std::endl;
00373   std::cout << " textAlign = " << textAlign_ << std::endl;
00374   std::cout << " textAngle = " << textAngle_ << std::endl;
00375   std::cout << " text = " << format_vstring(text_) << std::endl;
00376 }
00377 
00378 void TauDQMHistPlotter::cfgEntryLabel::applyTo(TPaveText* label) const
00379 {
00380   if ( label ) {
00381 //--- WARNING: need to call TPaveText::SetX1NDC, **not** TPaveText::SetX1 !!
00382 //             (see documentation of base-class constructor
00383 //               TPave::TPave(Double_t, Double_t,Double_t, Double_t, Int_t, Option_t*)
00384 //              in TPave.cxx for details)
00385     label->SetX1NDC(posX_);
00386     label->SetY1NDC(posY_);
00387     label->SetX2NDC(posX_ + sizeX_);
00388     label->SetY2NDC(posY_ + sizeY_);
00389     label->SetOption(option_.data());
00390     label->SetBorderSize(borderSize_);
00391     label->SetFillColor(fillColor_);
00392     label->SetTextColor(textColor_);
00393     label->SetTextSize(textSize_);
00394     label->SetTextAlign(textAlign_);
00395     label->SetTextAngle(textAngle_);
00396     for ( vstring::const_iterator line = text_.begin();
00397           line != text_.end(); ++line ) {
00398       label->AddText(line->data());
00399     }
00400   }
00401 }
00402 
00403 //
00404 //-----------------------------------------------------------------------------------------------------------------------
00405 //
00406 
00407 TauDQMHistPlotter::cfgEntryDrawOption::cfgEntryDrawOption(const std::string& name, const edm::ParameterSet& cfg)
00408 {
00409   name_ = name;
00410 
00411   markerColor_ = ( cfg.exists("markerColor") ) ? cfg.getParameter<int>("markerColor") : defaultMarkerColor;
00412   markerSize_  = ( cfg.exists("markerSize")  ) ? cfg.getParameter<double>("markerSize")  : defaultMarkerSize;
00413   markerStyle_ = ( cfg.exists("markerStyle") ) ? cfg.getParameter<int>("markerStyle") : defaultMarkerStyle;
00414   
00415   lineColor_ = ( cfg.exists("lineColor") ) ? cfg.getParameter<int>("lineColor") : defaultLineColor;
00416   lineStyle_ = ( cfg.exists("lineStyle") ) ? cfg.getParameter<int>("lineStyle") : defaultLineStyle;
00417   lineWidth_ = ( cfg.exists("lineWidth") ) ? cfg.getParameter<int>("lineWidth") : defaultLineWidth;
00418   
00419   fillColor_ = ( cfg.exists("fillColor") ) ? cfg.getParameter<int>("fillColor") : defaultFillColor;
00420   fillStyle_ = ( cfg.exists("fillStyle") ) ? cfg.getParameter<int>("fillStyle") : defaultFillStyle;
00421   
00422   drawOption_ = ( cfg.exists("drawOption") ) ? cfg.getParameter<std::string>("drawOption") : defaultDrawOption;
00423   drawOptionLegend_ = ( cfg.exists("drawOptionLegend") ) ? cfg.getParameter<std::string>("drawOptionLegend") : defaultDrawOptionLegend;
00424   
00425   if ( verbosity ) print();
00426 }
00427 
00428 TauDQMHistPlotter::cfgEntryDrawOption::cfgEntryDrawOption(const std::string& name, const cfgEntryDrawOption& blueprint)
00429   : name_(name),
00430     markerColor_(blueprint.markerColor_), markerSize_(blueprint.markerSize_), markerStyle_(blueprint.markerStyle_),
00431     lineColor_(blueprint.lineColor_), lineStyle_(blueprint.lineStyle_), lineWidth_(blueprint.lineWidth_),
00432     fillColor_(blueprint.fillColor_), fillStyle_(blueprint.fillStyle_),
00433     drawOption_(blueprint.drawOption_), drawOptionLegend_(blueprint.drawOptionLegend_)
00434 {
00435   if ( verbosity ) print();
00436 }
00437 
00438 void TauDQMHistPlotter::cfgEntryDrawOption::print() const
00439 {
00440   std::cout << "<TauDQMHistPlotter::cfgEntryDrawOption::print>:" << std::endl;
00441   std::cout << " name = " << name_ << std::endl;
00442   std::cout << " markerColor = " << markerColor_ << std::endl;
00443   std::cout << " markerSize = " << markerSize_ << std::endl;
00444   std::cout << " markerStyle = " << markerStyle_ << std::endl;
00445   std::cout << " lineColor = " << lineColor_ << std::endl;
00446   std::cout << " lineStyle = " << lineStyle_ << std::endl;
00447   std::cout << " lineWidth = " << lineWidth_ << std::endl;
00448   std::cout << " fillColor = " << fillColor_ << std::endl;
00449   std::cout << " fillStyle = " << fillStyle_ << std::endl;
00450   std::cout << " drawOption = " << drawOption_ << std::endl;
00451   std::cout << " drawOptionLegend = " << drawOptionLegend_ << std::endl;
00452 }
00453 
00454 void TauDQMHistPlotter::cfgEntryDrawOption::applyTo(TH1* histogram) const 
00455 {
00456   if ( histogram ) {
00457     histogram->SetMarkerColor(markerColor_);
00458     histogram->SetMarkerSize(markerSize_);
00459     histogram->SetMarkerStyle(markerStyle_);  
00460     histogram->SetLineColor(lineColor_);
00461     histogram->SetLineStyle(lineStyle_);
00462     histogram->SetLineWidth(lineWidth_);   
00463     histogram->SetFillColor(fillColor_);
00464     histogram->SetFillStyle(fillStyle_);
00465   }
00466 }
00467 
00468 //
00469 //-----------------------------------------------------------------------------------------------------------------------
00470 //
00471 
00472 TauDQMHistPlotter::plotDefEntry::plotDefEntry(const std::string& dqmMonitorElement, 
00473                                            const std::string& drawOptionEntry,
00474                                            const std::string& legendEntry,
00475                                            const std::string& legendEntryErrorBand,
00476                                            const std::string& process,
00477                                            bool doStack)
00478   : dqmMonitorElement_(dqmMonitorElement), 
00479     drawOptionEntry_(drawOptionEntry),
00480     legendEntry_(legendEntry),
00481     legendEntryErrorBand_(legendEntryErrorBand),
00482     process_(process), 
00483     doStack_(doStack),
00484     isErrorBand_(false)
00485 {
00486   //if ( verbosity ) print();
00487 }
00488 
00489 TauDQMHistPlotter::plotDefEntry::plotDefEntry(const plotDefEntry& blueprint)
00490   : dqmMonitorElement_(blueprint.dqmMonitorElement_), 
00491     drawOptionEntry_(blueprint.drawOptionEntry_),
00492     legendEntry_(blueprint.legendEntry_),
00493     legendEntryErrorBand_(blueprint.legendEntryErrorBand_),
00494     process_(blueprint.process_), 
00495     doStack_(blueprint.doStack_),
00496     isErrorBand_(false)
00497 {
00498   //if ( verbosity ) print();
00499 }
00500 
00501 void TauDQMHistPlotter::plotDefEntry::print() const
00502 {
00503   std::cout << "<TauDQMHistPlotter::plotDefEntry::print>:" << std::endl;
00504   std::cout << " dqmMonitorElement = " << dqmMonitorElement_ << std::endl;
00505   std::cout << " drawOptionEntry = " << drawOptionEntry_ << std::endl;
00506   std::cout << " legendEntry = " << legendEntry_ << std::endl;
00507   std::cout << " legendEntryErrorBand = " << legendEntryErrorBand_ << std::endl;
00508   std::cout << " process = " << process_ << std::endl;
00509   std::cout << " doStack = " << doStack_ << std::endl;
00510 }
00511 
00512 //
00513 //-----------------------------------------------------------------------------------------------------------------------
00514 //
00515 
00516 TauDQMHistPlotter::cfgEntryDrawJob::cfgEntryDrawJob(const std::string& name, 
00517                                                  const plotDefList& plotDefList, 
00518                                                  const std::string& title,
00519                                                  const std::string& xAxis, const std::string& yAxis, 
00520                                                  const std::string& legend, 
00521                                                  const vstring& labels)
00522 {
00523   name_ = name;
00524 
00525   for ( plotDefList::const_iterator it = plotDefList.begin();
00526         it != plotDefList.end(); ++it ) {
00527     plots_.push_back(plotDefEntry(*it));
00528   }
00529   
00530   title_ = title;
00531 
00532   xAxis_ = xAxis;
00533   yAxis_ = yAxis;
00534   
00535   legend_ = legend;
00536 
00537   for ( vstring::const_iterator it = labels.begin();
00538         it != labels.end(); ++it ) {
00539     labels_.push_back(std::string(*it));
00540   }
00541 
00542   if ( verbosity ) print();
00543 }
00544 
00545 void TauDQMHistPlotter::cfgEntryDrawJob::print() const
00546 {
00547   std::cout << "<TauDQMHistPlotter::cfgSetDrawJob::print>:" << std::endl;
00548   std::cout << " name = " << name_ << std::endl;
00549   std::cout << "plots = {" << std::endl;
00550   for ( plotDefList::const_iterator plot = plots_.begin();
00551         plot != plots_.end(); ++plot ) {
00552     plot->print();
00553   }
00554   std::cout << "}" << std::endl;
00555   std::cout << " title = " << title_ << std::endl;
00556   std::cout << " xAxis = " << xAxis_ << std::endl;
00557   std::cout << " yAxis = " << yAxis_ << std::endl;
00558   std::cout << " legend = " << legend_ << std::endl;
00559   std::cout << " labels = " << format_vstring(labels_) << std::endl;
00560 }
00561 
00562 //
00563 //-----------------------------------------------------------------------------------------------------------------------
00564 //
00565 
00566 TauDQMHistPlotter::TauDQMHistPlotter(const edm::ParameterSet& cfg)
00567 {
00568   if( verbosity)
00569     std::cout << "<TauDQMHistPlotter::TauDQMHistPlotter>:" << std::endl;
00570 
00571   toFile_ = cfg.getParameter<bool>("PrintToFile");
00572   cfgError_ = 0;
00573 
00574 //--- configure processes  
00575   //std::cout << "--> configuring processes..." << std::endl;
00576   edm::ParameterSet cfgParSet_processes = cfg.getParameter<edm::ParameterSet>("processes");
00577   readCfgParameter<cfgEntryProcess>(cfgParSet_processes, processes_);
00578   
00579 //--- check that process types are defined
00580   //std::cout << "--> checking configuration parameters..." << std::endl;
00581 
00582   int numProcesses_Data = 0;
00583   int numProcesses_sumMC = 0;
00584   for ( std::map<std::string, cfgEntryProcess>::const_iterator process = processes_.begin();
00585         process != processes_.end(); ++process ) {
00586     const std::string& type = process->second.type_;
00587 
00588     if ( !((type == type_smMC) ||
00589            (type == type_bsmMC) ||
00590            (type == type_smSumMC) ||
00591            (type == type_Data)) ) {
00592       edm::LogError ("TauDQMHistPlotter") << " Undefined process type = " << type << " !!";
00593       cfgError_ = 1;
00594     }
00595 
00596     if ( type == type_smSumMC ) ++numProcesses_sumMC;
00597     if ( type == type_Data ) ++numProcesses_Data;
00598   }
00599 
00600   if ( (numProcesses_Data > 1) || (numProcesses_sumMC > 1) ) {
00601     edm::LogError ("TauDQMHistPlotter") << " Cannot have more than one process of types sumMC and Data !!";
00602     cfgError_ = 1;
00603   }
00604 
00605 //--- configure x-axes  
00606   //std::cout << "--> configuring x-axes..." << std::endl;
00607   edm::ParameterSet cfgParSet_xAxes = cfg.getParameter<edm::ParameterSet>("xAxes");
00608   readCfgParameter<cfgEntryAxisX>(cfgParSet_xAxes, xAxes_);
00609 
00610 //--- configure y-axes  
00611   //std::cout << "--> configuring y-axes..." << std::endl;
00612   edm::ParameterSet cfgParSet_yAxes = cfg.getParameter<edm::ParameterSet>("yAxes");
00613   readCfgParameter<cfgEntryAxisY>(cfgParSet_yAxes, yAxes_);
00614 
00615 //--- configure legends
00616   //std::cout << "--> configuring legends..." << std::endl;
00617   edm::ParameterSet cfgParSet_legends = cfg.getParameter<edm::ParameterSet>("legends");
00618   readCfgParameter<cfgEntryLegend>(cfgParSet_legends, legends_);
00619 
00620 //--- configure labels
00621   //std::cout << "--> configuring labels..." << std::endl;
00622   edm::ParameterSet cfgParSet_labels = cfg.getParameter<edm::ParameterSet>("labels");
00623   readCfgParameter<cfgEntryLabel>(cfgParSet_labels, labels_);
00624 
00625 //--- configure drawOptions
00626   //std::cout << "--> configuring drawOptions..." << std::endl;
00627   if ( cfg.exists("drawOptionSets") ) {
00628     edm::ParameterSet drawOptionSets = cfg.getParameter<edm::ParameterSet>("drawOptionSets");
00629     vstring drawOptionSetNames = drawOptionSets.getParameterNamesForType<edm::ParameterSet>();
00630     for ( vstring::const_iterator drawOptionSetName = drawOptionSetNames.begin(); 
00631           drawOptionSetName != drawOptionSetNames.end(); ++drawOptionSetName ) {
00632       edm::ParameterSet drawOptionSet = drawOptionSets.getParameter<edm::ParameterSet>(*drawOptionSetName);
00633 
00634       vstring drawOptionEntryNames = drawOptionSet.getParameterNamesForType<edm::ParameterSet>();
00635       for ( vstring::const_iterator drawOptionEntryName = drawOptionEntryNames.begin(); 
00636             drawOptionEntryName != drawOptionEntryNames.end(); ++drawOptionEntryName ) {
00637         edm::ParameterSet drawOptionEntry = drawOptionSet.getParameter<edm::ParameterSet>(*drawOptionEntryName);
00638 
00639         std::string drawOptionEntryName_full = std::string(*drawOptionSetName).append(drawOptionSeparator).append(*drawOptionEntryName);
00640         drawOptionEntries_.insert(std::pair<std::string, cfgEntryDrawOption>
00641                                   (drawOptionEntryName_full, cfgEntryDrawOption(drawOptionEntryName_full, drawOptionEntry)));
00642       }
00643     }
00644   }
00645 
00646   if ( cfg.exists("drawOptionEntries") ) {
00647     edm::ParameterSet cfgParSet_drawOptionEntries = cfg.getParameter<edm::ParameterSet>("drawOptionEntries");
00648     readCfgParameter<cfgEntryDrawOption>(cfgParSet_drawOptionEntries, drawOptionEntries_);
00649   }
00650 
00651 //--- configure drawJobs
00652   //std::cout << "--> configuring drawJobs..." << std::endl;
00653   edm::ParameterSet drawJobs = cfg.getParameter<edm::ParameterSet>("drawJobs");
00654   vstring drawJobNames = drawJobs.getParameterNamesForType<edm::ParameterSet>();
00655   for ( vstring::const_iterator drawJobName = drawJobNames.begin(); 
00656         drawJobName != drawJobNames.end(); ++drawJobName ) {
00657     edm::ParameterSet drawJob = drawJobs.getParameter<edm::ParameterSet>(*drawJobName);
00658 
00659     std::map<int, plotDefList> plotDefMap;
00660 
00661     if ( drawJob.existsAs<edm::ParameterSet>("plots") ) { // display same monitor element for different processes
00662       edm::ParameterSet plots = drawJob.getParameter<edm::ParameterSet>("plots");
00663 
00664       vstring dqmMonitorElements = plots.getParameter<vstring>("dqmMonitorElements");
00665       vstring processes = plots.getParameter<vstring>("processes");
00666 
00667       std::string drawOptionSet = drawJob.getParameter<std::string>("drawOptionSet");
00668       //std::cout << "drawOptionSet = " << drawOptionSet << std::endl;
00669 
00670       vstring stack = ( cfg.exists("stack") ) ? drawJob.getParameter<vstring>("stack") : vstring();
00671 
00672       for ( vstring::const_iterator process = processes.begin();
00673             process != processes.end(); ++process ) {
00674         int index = 0;
00675         for ( vstring::const_iterator dqmMonitorElement = dqmMonitorElements.begin();
00676               dqmMonitorElement != dqmMonitorElements.end(); ++dqmMonitorElement ) {
00677           bool stack_dqmMonitorElement = find_vstring(stack, *process);
00678           std::string drawOptionEntry = std::string(drawOptionSet).append(drawOptionSeparator).append(*process);
00679           plotDefMap[index].push_back(plotDefEntry(*dqmMonitorElement, drawOptionEntry, "", "", *process, stack_dqmMonitorElement));
00680           ++index;
00681         }
00682       }
00683     } else { // display different monitor elements for same process
00684       typedef std::vector<edm::ParameterSet> vParameterSet;
00685       vParameterSet plots = drawJob.getParameter<vParameterSet>("plots");
00686 
00687       std::string process = ( drawJob.exists("process") ) ? drawJob.getParameter<std::string>("process") : "";
00688       //std::cout << "process (globally set) = " << process << std::endl;
00689 
00690       for ( vParameterSet::const_iterator plot = plots.begin(); 
00691             plot != plots.end(); ++plot ) {
00692 
00693         if ( process == "" || plot->exists("process")) {
00694           process = plot->getParameter<std::string>("process");
00695           //std::cout << "process (locally set) = " << process << std::endl;
00696         }
00697 
00698         std::string drawOptionEntry = plot->getParameter<std::string>("drawOptionEntry");
00699         //std::cout << "drawOptionEntry = " << drawOptionEntry << std::endl;
00700 
00701         std::string legendEntry = "", legendEntryErrorBand = "";
00702         if ( plot->exists("legendEntry") ) {
00703           legendEntry = plot->getParameter<std::string>("legendEntry");
00704           legendEntryErrorBand = ( plot->exists("legendEntryErrorBand") ) ? 
00705             plot->getParameter<std::string>("legendEntryErrorBand") : std::string(legendEntry).append(" Uncertainty"); 
00706         }
00707         //std::cout << "legendEntry = " << legendEntry << std::endl;
00708         //std::cout << "legendEntryErrorBand = " << legendEntryErrorBand << std::endl;
00709 
00710         vstring dqmMonitorElements = plot->getParameter<vstring>("dqmMonitorElements");
00711         int index = 0;
00712         for ( vstring::const_iterator dqmMonitorElement = dqmMonitorElements.begin();
00713               dqmMonitorElement != dqmMonitorElements.end(); ++dqmMonitorElement ) {
00714           plotDefMap[index].push_back(plotDefEntry(*dqmMonitorElement, drawOptionEntry, legendEntry, legendEntryErrorBand, process, false));
00715           ++index;
00716         }
00717       }
00718     }
00719 
00720 //--- check that number of displayed monitor elements is the same for each plot
00721     unsigned numMonitorElements_ref = 0;
00722     bool isFirstEntry = true;
00723     for ( std::map<int, plotDefList>::const_iterator plot = plotDefMap.begin(); 
00724           plot != plotDefMap.end(); ++plot ) {
00725       if ( isFirstEntry ) {
00726         numMonitorElements_ref = plot->second.size();
00727         isFirstEntry = false;
00728       } else {
00729         if ( plot->second.size() != numMonitorElements_ref ) {
00730           edm::LogError ("TauDQMHistPlotter::TauDQMHistPlotter") << " Numbers of dqmMonitorElements must be the same for all plots" 
00731                                                            << " --> skipping drawJob = " << (*drawJobName) << " !!";
00732           cfgError_ = 1;
00733         }
00734       }
00735     }
00736 
00737 //--- expand process directories in names of dqmMonitorElements
00738     for ( std::map<int, plotDefList>::iterator plot = plotDefMap.begin(); 
00739           plot != plotDefMap.end(); ++plot ) {
00740       for ( plotDefList::iterator entry = plot->second.begin();
00741             entry != plot->second.end(); ++entry ) {
00742         std::string dqmMonitorElement = entry->dqmMonitorElement_;
00743         std::string process = entry->process_;
00744 
00745         std::map<std::string, cfgEntryProcess>::const_iterator it = processes_.find(process);
00746         if ( it != processes_.end() ) {
00747           std::string process_dqmDirectory = it->second.dqmDirectory_;
00748 
00749           //std::cout << "replacing processDir = " << process_dqmDirectory << " in drawJob = " << (*drawJobName) << std::endl;
00750 
00751           int errorFlag = 0;
00752           std::string dqmMonitorElement_expanded = replace_string(dqmMonitorElement, processDirKeyword, process_dqmDirectory, 0, 1, errorFlag);
00753           //std::cout << " dqmMonitorElement_expanded = " << dqmMonitorElement_expanded << std::endl;
00754 
00755           if ( !errorFlag ) {
00756             entry->dqmMonitorElement_ = dqmMonitorElement_expanded;
00757           } else {
00758             cfgError_ = 1;
00759           }
00760         } else {
00761           edm::LogError ("TauDQMHistPlotter::TauDQMHistPlotter") << " Undefined process = " << process << " !!";
00762           cfgError_ = 1;
00763         }
00764       }
00765     }
00766 
00767     std::string title = ( drawJob.exists("title") ) ? drawJob.getParameter<std::string>("title") : ""; 
00768 
00769     std::string xAxis = drawJob.getParameter<std::string>("xAxis"); 
00770     std::string yAxis = drawJob.getParameter<std::string>("yAxis");
00771     
00772     std::string legend = drawJob.getParameter<std::string>("legend");
00773     
00774     vstring labels = ( drawJob.exists("labels") ) ? drawJob.getParameter<vstring>("labels") : vstring();
00775 
00776 //--- expand parameters in names of dqmMonitorElements;
00777 //    create drawJob objects
00778     for ( std::map<int, plotDefList>::iterator plot = plotDefMap.begin(); 
00779           plot != plotDefMap.end(); ++plot ) {
00780       if ( drawJob.exists("parameter") ) {
00781         vstring vparameter = drawJob.getParameter<vstring>("parameter");
00782         //std::cout << "replacing parameter = " << format_vstring(vparameter) << " in drawJob = " << (*drawJobName) << std::endl;
00783 
00784         for ( vstring::const_iterator parameter = vparameter.begin();
00785               parameter != vparameter.end(); ++parameter ) {
00786 
00787           plotDefList plot_expanded;
00788 
00789           for ( plotDefList::const_iterator entry = plot->second.begin();
00790                 entry != plot->second.end(); ++entry ) {
00791             std::string dqmMonitorElement = entry->dqmMonitorElement_;
00792             
00793             int errorFlag = 0;
00794             std::string dqmMonitorElement_expanded = replace_string(dqmMonitorElement, parKeyword, *parameter, 1, 1, errorFlag);
00795             //std::cout << " dqmMonitorElement_expanded = " << dqmMonitorElement_expanded << std::endl;
00796             if ( !errorFlag ) {
00797               plot_expanded.push_back(plotDefEntry(dqmMonitorElement_expanded, entry->drawOptionEntry_, 
00798                                                    entry->legendEntry_, entry->legendEntryErrorBand_, entry->process_, entry->doStack_));
00799             } else {
00800               cfgError_ = 1;
00801             }
00802           }
00803 
00804           int errorFlag = 0;
00805           std::string title_expanded = replace_string(title, parKeyword, *parameter, 0, 1, errorFlag);
00806           //std::cout << " title_expanded = " << title_expanded << std::endl;
00807           std::string xAxis_expanded = replace_string(xAxis, parKeyword, *parameter, 0, 1, errorFlag);
00808           //std::cout << " xAxis_expanded = " << xAxis_expanded << std::endl;
00809           std::string yAxis_expanded = replace_string(yAxis, parKeyword, *parameter, 0, 1, errorFlag);
00810           //std::cout << " yAxis_expanded = " << yAxis_expanded << std::endl;
00811           if ( errorFlag ) cfgError_ = 1;
00812 
00813           drawJobs_.push_back(cfgEntryDrawJob(std::string(*drawJobName).append(*parameter),
00814                                               plot_expanded, title_expanded, xAxis_expanded, yAxis_expanded, legend, labels));
00815         }
00816       } else {
00817         drawJobs_.push_back(cfgEntryDrawJob(*drawJobName, 
00818                                             plot->second, title, xAxis, yAxis, legend, labels));
00819       }
00820     }
00821   }
00822 
00823 //--- check that all information neccessary to process drawJob is defined;
00824   for ( std::list<cfgEntryDrawJob>::const_iterator drawJob = drawJobs_.begin();
00825         drawJob != drawJobs_.end(); ++drawJob ) {
00826     for ( plotDefList::const_iterator plot = drawJob->plots_.begin();
00827           plot != drawJob->plots_.end(); ++plot ) {
00828       checkCfgDef<cfgEntryDrawOption>(plot->drawOptionEntry_, drawOptionEntries_, cfgError_, "drawOptionEntry", drawJob->name_);
00829       checkCfgDef<cfgEntryProcess>(plot->process_, processes_, cfgError_, "process", drawJob->name_);
00830     }
00831 
00832     checkCfgDef<cfgEntryAxisX>(drawJob->xAxis_, xAxes_, cfgError_, "xAxis", drawJob->name_);
00833     checkCfgDef<cfgEntryAxisY>(drawJob->yAxis_, yAxes_, cfgError_, "yAxis", drawJob->name_);
00834 
00835     checkCfgDef<cfgEntryLegend>(drawJob->legend_, legends_, cfgError_, "legend", drawJob->name_);
00836 
00837     checkCfgDefs<cfgEntryLabel>(drawJob->labels_, labels_, cfgError_, "label", drawJob->name_);
00838   }
00839 
00840 //--- configure canvas size
00841   //std::cout << "--> configuring canvas size..." << std::endl;
00842   canvasSizeX_ = ( cfg.exists("canvasSizeX") ) ? cfg.getParameter<int>("canvasSizeX") : defaultCanvasSizeX;
00843   canvasSizeY_ = ( cfg.exists("canvasSizeY") ) ? cfg.getParameter<int>("canvasSizeY") : defaultCanvasSizeY;
00844  
00845 //--- configure output files
00846   //std::cout << "--> configuring postscript output file..." << std::endl;
00847 
00848   outputFilePath_ = ( cfg.exists("outputFilePath") ) ? cfg.getParameter<std::string>("outputFilePath") : "";
00849   if ( outputFilePath_.rbegin() != outputFilePath_.rend() ) {
00850     if ( (*outputFilePath_.rbegin()) == '/' ) outputFilePath_.erase(outputFilePath_.length() - 1);
00851   }
00852   //std::cout << " outputFilePath = " << outputFilePath_ << std::endl;
00853 
00854   outputFileName_ = ( cfg.exists("outputFileName") ) ? cfg.getParameter<std::string>("outputFileName") : "";
00855   //std::cout << " outputFileName = " << outputFileName_ << std::endl;
00856 
00857   indOutputFileName_ = ( cfg.exists("indOutputFileName") ) ? cfg.getParameter<std::string>("indOutputFileName") : "";
00858   if ( indOutputFileName_ != "" && indOutputFileName_.find('.') == std::string::npos ) {
00859     edm::LogError ("TauDQMHistPlotter") << " Failed to determine type of graphics format from indOutputFileName = " << indOutputFileName_ << " !!";
00860     cfgError_ = 1;
00861   }
00862   //std::cout << " indOutputFileName = " << indOutputFileName_ << std::endl;
00863 
00864 //--- check that exactly one type of output is specified for the plots
00865 //    (either separate graphics files displaying one plot each 
00866 //     or postscript file displaying all plots on successive pages;
00867 //     cannot create both types of output simultaneously,
00868 //     as TCanvas::Print seems to interfere with TPostScript::NewPage)
00869   if ( outputFileName_ == "" && indOutputFileName_ == "" ) {
00870     edm::LogError ("TauDQMHistPlotter") << " Either outputFileName or indOutputFileName must be specified !!";
00871     cfgError_ = 1;
00872   }
00873 
00874   if ( outputFileName_ != "" && indOutputFileName_ != "" ) {
00875     edm::LogError ("TauDQMHistPlotter") << " Must not specify outputFileName and indOutputFileName simultaneously !!";
00876     cfgError_ = 1;
00877   }
00878 
00879   if( verbosity )
00880     std::cout << "done." << std::endl;
00881 }
00882 
00883 TauDQMHistPlotter::~TauDQMHistPlotter() 
00884 {
00885 // nothing to be done yet...
00886 }
00887 
00888 void TauDQMHistPlotter::analyze(const edm::Event&, const edm::EventSetup&)
00889 {
00890 // nothing to be done yet...
00891 }
00892 
00893 void TauDQMHistPlotter::endRun(const edm::Run& r, const edm::EventSetup& c)
00894 {
00895   if( verbosity )
00896     std::cout << "<TauDQMHistPlotter::endJob>:" << std::endl;
00897 
00898 //--- check that configuration parameters contain no errors
00899   if ( cfgError_ ) {
00900     edm::LogError ("endJob") << " Error in Configuration ParameterSet --> histograms will NOT be plotted !!";
00901     return;
00902   }
00903 
00904 //--- check that DQMStore service is available
00905   if ( !edm::Service<DQMStore>().isAvailable() ) {
00906     edm::LogError ("endJob") << " Failed to access dqmStore --> histograms will NOT be plotted !!";
00907     return;
00908   }
00909 
00910   DQMStore& dqmStore = (*edm::Service<DQMStore>());
00911 
00912 //--- stop ROOT from keeping references to all hsitograms
00913   //TH1::AddDirectory(false);
00914 
00915 //--- stop ROOT from opening X-window for canvas output
00916 //    (in order to be able to run in batch mode) 
00917   gROOT->SetBatch(true);
00918 
00919 //--- initialize graphical output;
00920 //    open postscript file
00921   TCanvas canvas("TauDQMHistPlotter","TauDQMHistPlotter", canvasSizeX_, canvasSizeY_);
00922   canvas.SetFillColor(10);
00923 
00924 //--- restrict area in which histograms are drawn to quadratic TPad in the center of the TCanvas,
00925 //    in order to make space for axis labels...
00926   //TPad pad("EWKTauPad", "EWKTauPad", 0.02, 0.15, 0.98, 0.85);
00927   //pad.SetFillColor(10);
00928   //pad.Draw();
00929   //pad.Divide(1,1);
00930   //pad.cd(1);
00931 
00932   TPostScript* ps = NULL;
00933   if ( outputFileName_ != "" ) {
00934     std::string psFileName = ( outputFilePath_ != "" ) ? std::string(outputFilePath_).append("/").append(outputFileName_) : outputFileName_;
00935     ps = new TPostScript(psFileName.data(), 112);
00936   }
00937     
00938 //--- process drawJobs
00939   for ( std::list<cfgEntryDrawJob>::const_iterator drawJob = drawJobs_.begin(); 
00940         drawJob != drawJobs_.end(); ++drawJob ) {
00941     const std::string& drawJobName = drawJob->name_;
00942     if( verbosity )
00943       std::cout << "--> processing drawJob " << drawJobName << "..." << std::endl;
00944 
00945 //--- prepare internally used histogram data-structures
00946     TH1* stackedHistogram_sum = NULL;
00947     std::list<TH1*> histogramsToDelete;
00948     std::list<plotDefEntry*> drawOptionsToDelete;
00949 
00950     typedef std::pair<TH1*, const plotDefEntry*> histogram_drawOption_pair;
00951     std::list<histogram_drawOption_pair> allHistograms;
00952 
00953     for ( plotDefList::const_iterator plot = drawJob->plots_.begin();
00954           plot != drawJob->plots_.end(); ++plot ) {
00955 
00956       std::string dqmMonitorElementName_full = dqmDirectoryName(std::string(dqmRootDirectory)).append(plot->dqmMonitorElement_);
00957       if( verbosity )
00958         std::cout << " dqmMonitorElementName_full = " << dqmMonitorElementName_full << std::endl;
00959       MonitorElement* dqmMonitorElement = dqmStore.get(dqmMonitorElementName_full);
00960 
00961       TH1* histogram = dqmMonitorElement->getTH1F();
00962       if(verbosity)
00963         std::cout<<"Got Histogram "<<std::endl;
00964       //      TH1* histogram = ( dqmMonitorElement ) ? dynamic_cast<TH1*>(dqmMonitorElement->getTH1()->Clone()) : NULL;
00965       //histogramsToDelete.push_back(histogram);
00966 
00967       if ( histogram == NULL ) {
00968         edm::LogError ("endJob") << " Failed to access dqmMonitorElement = " << dqmMonitorElementName_full <<","
00969                                  << " needed by drawJob = " << drawJobName << " --> histograms will NOT be plotted !!";
00970         continue;
00971       }
00972 
00973       if ( !histogram->GetSumw2N() ) histogram->Sumw2();
00974 
00975       const cfgEntryDrawOption* drawOptionConfig = 
00976         findCfgDef<cfgEntryDrawOption>(plot->drawOptionEntry_, drawOptionEntries_, "drawOptionEntry", drawJobName);
00977       if ( drawOptionConfig == NULL ) {
00978         edm::LogError ("endJob") << " Failed to access information needed by drawJob = " << drawJobName 
00979                                  << " --> histograms will NOT be plotted !!";
00980         return;
00981       }
00982       
00983       if ( drawOptionConfig->drawOption_ == drawOption_eBand ) {
00984 //--- add histogram displaying central value as solid line
00985         TH1* histogram_centralValue = dynamic_cast<TH1*>(histogram->Clone());
00986         histogram_centralValue->SetName(std::string(histogram->GetName()).append("_centralValue").data());
00987         cfgEntryDrawOption drawOptionConfig_centralValue(*drawOptionConfig);
00988         drawOptionConfig_centralValue.fillColor_ = 0;
00989         drawOptionConfig_centralValue.fillStyle_ = 0;
00990         drawOptionConfig_centralValue.drawOption_ = "hist";
00991         drawOptionConfig_centralValue.drawOptionLegend_ = "l";
00992         std::string drawOptionName_centralValue = std::string(plot->drawOptionEntry_).append("_centralValue");
00993 //--- entries in std::map need to be unique,
00994 //    so need to check whether drawOptionEntry already exists...
00995         if ( drawOptionEntries_.find(drawOptionName_centralValue) == drawOptionEntries_.end() ) 
00996           drawOptionEntries_.insert(std::pair<std::string, cfgEntryDrawOption>
00997                                     (drawOptionName_centralValue, cfgEntryDrawOption(drawOptionName_centralValue, drawOptionConfig_centralValue)));
00998         plotDefEntry* plot_centralValue = new plotDefEntry(*plot);
00999         plot_centralValue->drawOptionEntry_ = drawOptionName_centralValue;
01000         allHistograms.push_back(histogram_drawOption_pair(histogram_centralValue, plot_centralValue));
01001         histogramsToDelete.push_back(histogram_centralValue);
01002         drawOptionsToDelete.push_back(plot_centralValue);
01003 
01004 //--- add histogram displaying uncertainty as shaded error band
01005         TH1* histogram_ErrorBand = dynamic_cast<TH1*>(histogram->Clone());
01006         histogram_ErrorBand->SetName(std::string(histogram->GetName()).append("_ErrorBand").data());
01007         cfgEntryDrawOption drawOptionConfig_ErrorBand(*drawOptionConfig);
01008         drawOptionConfig_ErrorBand.markerColor_ = drawOptionConfig_ErrorBand.fillColor_;
01009         drawOptionConfig_ErrorBand.markerSize_ = 0.;
01010         drawOptionConfig_ErrorBand.lineColor_ = drawOptionConfig_ErrorBand.fillColor_;
01011         drawOptionConfig_ErrorBand.lineWidth_ = 0;
01012         drawOptionConfig_ErrorBand.drawOption_ = "e2";
01013         drawOptionConfig_ErrorBand.drawOptionLegend_ = "f";
01014         std::string drawOptionName_ErrorBand = std::string(plot->drawOptionEntry_).append("_ErrorBand");
01015 //--- entries in std::map need to be unique,
01016 //    so need to check whether drawOptionEntry already exists...
01017         if ( drawOptionEntries_.find(drawOptionName_ErrorBand) == drawOptionEntries_.end() ) 
01018           drawOptionEntries_.insert(std::pair<std::string, cfgEntryDrawOption>
01019                                     (drawOptionName_ErrorBand, cfgEntryDrawOption(drawOptionName_ErrorBand, drawOptionConfig_ErrorBand)));
01020         plotDefEntry* plot_ErrorBand = new plotDefEntry(*plot);
01021         plot_ErrorBand->drawOptionEntry_ = drawOptionName_ErrorBand;
01022         plot_ErrorBand->isErrorBand_ = true;
01023         allHistograms.push_back(histogram_drawOption_pair(histogram_ErrorBand, plot_ErrorBand));
01024         histogramsToDelete.push_back(histogram_ErrorBand);
01025         drawOptionsToDelete.push_back(plot_ErrorBand);
01026       } else if ( plot->doStack_ ) {
01027         TH1* stackedHistogram = dynamic_cast<TH1*>(histogram->Clone());
01028         if ( stackedHistogram_sum ) stackedHistogram->Add(stackedHistogram_sum);
01029         stackedHistogram_sum = stackedHistogram;
01030         histogramsToDelete.push_back(stackedHistogram);
01031         allHistograms.push_back(histogram_drawOption_pair(stackedHistogram, &(*plot)));
01032       } else {  
01033         allHistograms.push_back(histogram_drawOption_pair(histogram, &(*plot)));
01034       }
01035     }
01036 
01037 //--- determine normalization of y-axis
01038 //    (maximum of any of the histograms included in drawJob)
01039     double yAxisNorm = 0.;
01040     for ( std::list<histogram_drawOption_pair>::const_iterator it = allHistograms.begin();
01041           it != allHistograms.end(); ++it ) {
01042       yAxisNorm = TMath::Max(yAxisNorm, it->first->GetMaximum());
01043     }
01044     //std::cout << " yAxisNorm = " << yAxisNorm << std::endl;
01045     cfgEntryAxisY::setNorm(yAxisNorm);
01046 
01047 //--- prepare histograms for drawing
01048     const cfgEntryAxisX* xAxisConfig = findCfgDef<cfgEntryAxisX>(drawJob->xAxis_, xAxes_, "xAxis", drawJobName);
01049     const cfgEntryAxisY* yAxisConfig = findCfgDef<cfgEntryAxisY>(drawJob->yAxis_, yAxes_, "yAxis", drawJobName);
01050     const cfgEntryLegend* legendConfig = findCfgDef<cfgEntryLegend>(drawJob->legend_, legends_, "legend", drawJobName);
01051     if ( xAxisConfig == NULL || yAxisConfig == NULL || legendConfig == NULL ) {
01052       edm::LogError ("endJob") << " Failed to access information needed by drawJob = " << drawJobName 
01053                                << " --> histograms will NOT be plotted !!";
01054       return;
01055     }
01056 
01057 //--- WARNING: need to call 
01058 //              TLegend::TLegend(Double_t, Double_t,Double_t, Double_t, const char* = "", Option_t* = "brNDC")
01059 //             constructor, as TLegend::TLegend default constructor causes the created TLegend object to behave differently !!
01060     TLegend legend(defaultLegendPosX, defaultLegendPosY, defaultLegendPosX + defaultLegendSizeX, defaultLegendPosY + defaultLegendSizeY);
01061     legendConfig->applyTo(&legend);
01062 
01063     std::list<histoDrawEntry> smProcessHistogramList;
01064     std::list<histoDrawEntry> bsmProcessHistogramList;
01065     std::list<histoDrawEntry> smSumHistogramList;
01066     std::list<histoDrawEntry> smSumUncertaintyHistogramList;
01067     std::list<histoDrawEntry> dataHistogramList;
01068 
01069     for ( std::list<histogram_drawOption_pair>::const_iterator it = allHistograms.begin();
01070           it != allHistograms.end(); ++it ) {
01071       TH1* histogram = it->first;
01072       const plotDefEntry* drawOption = it->second;
01073 
01074       const cfgEntryDrawOption* drawOptionConfig = 
01075         findCfgDef<cfgEntryDrawOption>(drawOption->drawOptionEntry_, drawOptionEntries_, "drawOptionEntry", drawJobName);
01076       const cfgEntryProcess* processConfig = findCfgDef<cfgEntryProcess>(drawOption->process_, processes_, "process", drawJobName);
01077       if ( drawOptionConfig == NULL || processConfig == NULL ) {
01078         edm::LogError ("endJob") << " Failed to access information needed by drawJob = " << drawJobName 
01079                                  << " --> histograms will NOT be plotted !!";
01080         return;
01081       }
01082       
01083       if ( drawJob->title_ != "" ) histogram->SetTitle(drawJob->title_.data());
01084 
01085       xAxisConfig->applyTo(histogram);
01086       yAxisConfig->applyTo(histogram);
01087 
01088       bool yLogScale = ( yAxisConfig->yScale_ == yScale_log ) ? true : false;
01089       //std::cout << " yLogScale = " << yLogScale << std::endl; 
01090       //pad.SetLogy(yLogScale);
01091       canvas.SetLogy(yLogScale);
01092 
01093       drawOptionConfig->applyTo(histogram);
01094       histogram->SetStats(false);
01095 
01096       if ( drawOption->isErrorBand_ ) {
01097         smSumUncertaintyHistogramList.push_back(histoDrawEntry(histogram, drawOptionConfig->drawOption_.data()));
01098       } else {
01099         if ( processConfig->type_ == type_smMC ) {
01100           smProcessHistogramList.push_back(histoDrawEntry(histogram, drawOptionConfig->drawOption_.data()));
01101         } else if ( processConfig->type_ == type_bsmMC ) {
01102           bsmProcessHistogramList.push_back(histoDrawEntry(histogram, drawOptionConfig->drawOption_.data()));
01103         } else if ( processConfig->type_ == type_smSumMC ) {
01104           smSumHistogramList.push_back(histoDrawEntry(histogram, drawOptionConfig->drawOption_.data()));
01105         } else if ( processConfig->type_ == type_Data ) {
01106           dataHistogramList.push_back(histoDrawEntry(histogram, drawOptionConfig->drawOption_.data()));
01107         } 
01108       }
01109 
01110       std::string legendEntry, legendDrawOption;
01111       if ( drawOption->isErrorBand_ ) {
01112         legendEntry = ( drawOption->legendEntryErrorBand_ != "" ) ? drawOption->legendEntryErrorBand_ : processConfig->legendEntryErrorBand_;
01113         legendDrawOption = "f";
01114       } else {
01115         legendEntry = ( drawOption->legendEntry_ != "" ) ? drawOption->legendEntry_ : processConfig->legendEntry_;
01116         legendDrawOption = drawOptionConfig->drawOptionLegend_;
01117       } 
01118 
01119       legend.AddEntry(histogram, legendEntry.data(), legendDrawOption.data());
01120     }
01121 
01122     std::list<TPaveText> labels;
01123     for ( vstring::const_iterator labelName = drawJob->labels_.begin();
01124           labelName != drawJob->labels_.end(); ++labelName ) {
01125       const cfgEntryLabel* labelConfig = findCfgDef<cfgEntryLabel>(*labelName, labels_, "label", drawJobName);
01126       
01127       TPaveText label;
01128       labelConfig->applyTo(&label);
01129 
01130       labels.push_back(label);
01131     }
01132 
01133 //--- draw histograms 
01134 //   - in the order:
01135 //    1. uncertainty on sum of all Standard Model processes
01136 //    2. sum of all Standard Model processes
01137 //    3. individual Standard Model processes
01138 //    4. individual beyond the Standard Model processes
01139 //    5. data
01140     bool isFirstHistogram = true;
01141     drawHistograms(smSumUncertaintyHistogramList, isFirstHistogram);
01142     drawHistograms(smSumHistogramList, isFirstHistogram);
01143 
01144 //--- process histograms for individual Standard Model processes
01145 //    in reverse order, so that most stacked histogram gets drawn first
01146     for ( std::list<histoDrawEntry>::reverse_iterator it = smProcessHistogramList.rbegin();
01147           it != smProcessHistogramList.rend(); ++it ) {
01148       std::string drawOption = ( isFirstHistogram ) ? it->second : std::string(it->second).append("same");
01149       it->first->Draw(drawOption.data());
01150       isFirstHistogram = false;
01151     }
01152         
01153     drawHistograms(bsmProcessHistogramList, isFirstHistogram);
01154     drawHistograms(dataHistogramList, isFirstHistogram);
01155 
01156     legend.Draw();
01157 
01158     for ( std::list<TPaveText>::iterator label = labels.begin();
01159           label != labels.end(); ++label ) {
01160       label->Draw();
01161     }
01162 
01163     //pad.RedrawAxis();
01164     
01165     canvas.Update();
01166     //pad.Update();
01167 
01168     if ( indOutputFileName_ != "" && toFile_) {
01169       int errorFlag = 0;
01170       std::string modIndOutputFileName = replace_string(indOutputFileName_, plotKeyword, drawJobName, 1, 1, errorFlag);
01171       if ( !errorFlag ) {
01172         std::string fullFileName = ( outputFilePath_ != "" ) ? 
01173           std::string(outputFilePath_).append("/").append(modIndOutputFileName) : modIndOutputFileName;
01174         canvas.Print(fullFileName.data());
01175       } else {
01176         edm::LogError("endJob") << " Failed to decode indOutputFileName = " << indOutputFileName_ << " --> skipping !!";
01177       }
01178     }
01179 
01180     if ( ps ) ps->NewPage();
01181 
01182 //--- delete temporarily created histogram and drawOption objects
01183     for ( std::list<TH1*>::const_iterator histogram = histogramsToDelete.begin();
01184           histogram != histogramsToDelete.end(); ++histogram ) {
01185       delete (*histogram);
01186     }
01187 
01188     for ( std::list<plotDefEntry*>::const_iterator drawOption = drawOptionsToDelete.begin();
01189           drawOption != drawOptionsToDelete.end(); ++drawOption ) {
01190       delete (*drawOption);
01191     }
01192   }
01193 
01194 //--- close postscript file
01195   canvas.Clear();
01196   if(verbosity)
01197     std::cout << "done." << std::endl;
01198   if ( ps ) ps->Close();
01199   delete ps;
01200 }
01201 
01202 #include "FWCore/Framework/interface/MakerMacros.h"
01203 
01204 DEFINE_FWK_MODULE(TauDQMHistPlotter);