CMS 3D CMS Logo

Classes | Public Member Functions | Private Types | Private Attributes

DQMHistPlotter Class Reference

#include <DQMHistPlotter.h>

Inheritance diagram for DQMHistPlotter:
edm::EDAnalyzer

List of all members.

Classes

struct  cfgEntryAxisX
struct  cfgEntryAxisY
struct  cfgEntryDrawJob
struct  cfgEntryDrawOption
struct  cfgEntryLabel
struct  cfgEntryLegend
struct  cfgEntryProcess
struct  plotDefEntry

Public Member Functions

virtual void analyze (const edm::Event &, const edm::EventSetup &)
 DQMHistPlotter (const edm::ParameterSet &)
virtual void endJob ()
virtual ~DQMHistPlotter ()

Private Types

typedef std::list< plotDefEntryplotDefList
typedef std::vector< std::string > vstring

Private Attributes

int canvasSizeX_
int canvasSizeY_
int cfgError_
std::list< cfgEntryDrawJobdrawJobs_
std::map< std::string,
cfgEntryDrawOption
drawOptionEntries_
std::string indOutputFileName_
std::map< std::string,
cfgEntryLabel
labels_
std::map< std::string,
cfgEntryLegend
legends_
std::string outputFileName_
std::string outputFilePath_
std::map< std::string,
cfgEntryProcess
processes_
std::map< std::string,
cfgEntryAxisX
xAxes_
std::map< std::string,
cfgEntryAxisY
yAxes_

Detailed Description

Definition at line 29 of file DQMHistPlotter.h.


Member Typedef Documentation

typedef std::list<plotDefEntry> DQMHistPlotter::plotDefList [private]

Definition at line 144 of file DQMHistPlotter.h.

typedef std::vector<std::string> DQMHistPlotter::vstring [private]

Definition at line 31 of file DQMHistPlotter.h.


Constructor & Destructor Documentation

DQMHistPlotter::DQMHistPlotter ( const edm::ParameterSet cfg) [explicit]

Definition at line 566 of file DQMHistPlotter.cc.

References canvasSizeX_, canvasSizeY_, cfgError_, gather_cfg::cout, defaultCanvasSizeX, defaultCanvasSizeY, drawJobs_, drawOptionEntries_, drawOptionSeparator, edm::ParameterSet::exists(), edm::ParameterSet::existsAs(), find_vstring(), edm::ParameterSet::getParameter(), edm::ParameterSet::getParameterNamesForType(), getHLTprescales::index, indOutputFileName_, L1TDQM_cfg::labels, labels_, legends_, outputFileName_, outputFilePath_, parKeyword, EcalCondTools::plot(), align_tpl::process, processDirKeyword, processes_, replace_string(), svgfig::stack, indexGen::title, type_bsmMC, type_Data, type_smMC, type_smSumMC, xAxes_, and yAxes_.

{
  std::cout << "<DQMHistPlotter::DQMHistPlotter>:" << std::endl;

  cfgError_ = 0;

//--- configure processes  
  //std::cout << "--> configuring processes..." << std::endl;
  edm::ParameterSet cfgParSet_processes = cfg.getParameter<edm::ParameterSet>("processes");
  readCfgParameter<cfgEntryProcess>(cfgParSet_processes, processes_);
  
//--- check that process types are defined
  //std::cout << "--> checking configuration parameters..." << std::endl;

  int numProcesses_Data = 0;
  int numProcesses_sumMC = 0;
  for ( std::map<std::string, cfgEntryProcess>::const_iterator process = processes_.begin();
        process != processes_.end(); ++process ) {
    const std::string& type = process->second.type_;

    if ( !((type == type_smMC) ||
           (type == type_bsmMC) ||
           (type == type_smSumMC) ||
           (type == type_Data)) ) {
      edm::LogError ("DQMHistPlotter") << " Undefined process type = " << type << " !!";
      cfgError_ = 1;
    }

    if ( type == type_smSumMC ) ++numProcesses_sumMC;
    if ( type == type_Data ) ++numProcesses_Data;
  }

  if ( (numProcesses_Data > 1) || (numProcesses_sumMC > 1) ) {
    edm::LogError ("DQMHistPlotter") << " Cannot have more than one process of types sumMC and Data !!";
    cfgError_ = 1;
  }

//--- configure x-axes  
  //std::cout << "--> configuring x-axes..." << std::endl;
  edm::ParameterSet cfgParSet_xAxes = cfg.getParameter<edm::ParameterSet>("xAxes");
  readCfgParameter<cfgEntryAxisX>(cfgParSet_xAxes, xAxes_);

//--- configure y-axes  
  //std::cout << "--> configuring y-axes..." << std::endl;
  edm::ParameterSet cfgParSet_yAxes = cfg.getParameter<edm::ParameterSet>("yAxes");
  readCfgParameter<cfgEntryAxisY>(cfgParSet_yAxes, yAxes_);

//--- configure legends
  //std::cout << "--> configuring legends..." << std::endl;
  edm::ParameterSet cfgParSet_legends = cfg.getParameter<edm::ParameterSet>("legends");
  readCfgParameter<cfgEntryLegend>(cfgParSet_legends, legends_);

//--- configure labels
  //std::cout << "--> configuring labels..." << std::endl;
  edm::ParameterSet cfgParSet_labels = cfg.getParameter<edm::ParameterSet>("labels");
  readCfgParameter<cfgEntryLabel>(cfgParSet_labels, labels_);

//--- configure drawOptions
  //std::cout << "--> configuring drawOptions..." << std::endl;
  if ( cfg.exists("drawOptionSets") ) {
    edm::ParameterSet drawOptionSets = cfg.getParameter<edm::ParameterSet>("drawOptionSets");
    vstring drawOptionSetNames = drawOptionSets.getParameterNamesForType<edm::ParameterSet>();
    for ( vstring::const_iterator drawOptionSetName = drawOptionSetNames.begin(); 
          drawOptionSetName != drawOptionSetNames.end(); ++drawOptionSetName ) {
      edm::ParameterSet drawOptionSet = drawOptionSets.getParameter<edm::ParameterSet>(*drawOptionSetName);

      vstring drawOptionEntryNames = drawOptionSet.getParameterNamesForType<edm::ParameterSet>();
      for ( vstring::const_iterator drawOptionEntryName = drawOptionEntryNames.begin(); 
            drawOptionEntryName != drawOptionEntryNames.end(); ++drawOptionEntryName ) {
        edm::ParameterSet drawOptionEntry = drawOptionSet.getParameter<edm::ParameterSet>(*drawOptionEntryName);

        std::string drawOptionEntryName_full = std::string(*drawOptionSetName).append(drawOptionSeparator).append(*drawOptionEntryName);
        drawOptionEntries_.insert(std::pair<std::string, cfgEntryDrawOption>
                                  (drawOptionEntryName_full, cfgEntryDrawOption(drawOptionEntryName_full, drawOptionEntry)));
      }
    }
  }

  if ( cfg.exists("drawOptionEntries") ) {
    edm::ParameterSet cfgParSet_drawOptionEntries = cfg.getParameter<edm::ParameterSet>("drawOptionEntries");
    readCfgParameter<cfgEntryDrawOption>(cfgParSet_drawOptionEntries, drawOptionEntries_);
  }

//--- configure drawJobs
  //std::cout << "--> configuring drawJobs..." << std::endl;
  edm::ParameterSet drawJobs = cfg.getParameter<edm::ParameterSet>("drawJobs");
  vstring drawJobNames = drawJobs.getParameterNamesForType<edm::ParameterSet>();
  for ( vstring::const_iterator drawJobName = drawJobNames.begin(); 
        drawJobName != drawJobNames.end(); ++drawJobName ) {
    edm::ParameterSet drawJob = drawJobs.getParameter<edm::ParameterSet>(*drawJobName);

    std::map<int, plotDefList> plotDefMap;

    if ( drawJob.existsAs<edm::ParameterSet>("plots") ) { // display same monitor element for different processes
      edm::ParameterSet plots = drawJob.getParameter<edm::ParameterSet>("plots");

      vstring dqmMonitorElements = plots.getParameter<vstring>("dqmMonitorElements");
      vstring processes = plots.getParameter<vstring>("processes");

      std::string drawOptionSet = drawJob.getParameter<std::string>("drawOptionSet");
      //std::cout << "drawOptionSet = " << drawOptionSet << std::endl;

      vstring stack = ( cfg.exists("stack") ) ? drawJob.getParameter<vstring>("stack") : vstring();

      for ( vstring::const_iterator process = processes.begin();
            process != processes.end(); ++process ) {
        int index = 0;
        for ( vstring::const_iterator dqmMonitorElement = dqmMonitorElements.begin();
              dqmMonitorElement != dqmMonitorElements.end(); ++dqmMonitorElement ) {
          bool stack_dqmMonitorElement = find_vstring(stack, *process);
          std::string drawOptionEntry = std::string(drawOptionSet).append(drawOptionSeparator).append(*process);
          plotDefMap[index].push_back(plotDefEntry(*dqmMonitorElement, drawOptionEntry, "", "", *process, stack_dqmMonitorElement));
          ++index;
        }
      }
    } else { // display different monitor elements for same process
      typedef std::vector<edm::ParameterSet> vParameterSet;
      vParameterSet plots = drawJob.getParameter<vParameterSet>("plots");

      std::string process = ( drawJob.exists("process") ) ? drawJob.getParameter<std::string>("process") : "";
      //std::cout << "process (globally set) = " << process << std::endl;

      for ( vParameterSet::const_iterator plot = plots.begin(); 
            plot != plots.end(); ++plot ) {

        if ( process == "" || plot->exists("process")) {
          process = plot->getParameter<std::string>("process");
          //std::cout << "process (locally set) = " << process << std::endl;
        }

        std::string drawOptionEntry = plot->getParameter<std::string>("drawOptionEntry");
        //std::cout << "drawOptionEntry = " << drawOptionEntry << std::endl;

        std::string legendEntry = "", legendEntryErrorBand = "";
        if ( plot->exists("legendEntry") ) {
          legendEntry = plot->getParameter<std::string>("legendEntry");
          legendEntryErrorBand = ( plot->exists("legendEntryErrorBand") ) ? 
            plot->getParameter<std::string>("legendEntryErrorBand") : std::string(legendEntry).append(" Uncertainty"); 
        }
        //std::cout << "legendEntry = " << legendEntry << std::endl;
        //std::cout << "legendEntryErrorBand = " << legendEntryErrorBand << std::endl;

        vstring dqmMonitorElements = plot->getParameter<vstring>("dqmMonitorElements");
        int index = 0;
        for ( vstring::const_iterator dqmMonitorElement = dqmMonitorElements.begin();
              dqmMonitorElement != dqmMonitorElements.end(); ++dqmMonitorElement ) {
          plotDefMap[index].push_back(plotDefEntry(*dqmMonitorElement, drawOptionEntry, legendEntry, legendEntryErrorBand, process, false));
          ++index;
        }
      }
    }

//--- check that number of displayed monitor elements is the same for each plot
    unsigned numMonitorElements_ref = 0;
    bool isFirstEntry = true;
    for ( std::map<int, plotDefList>::const_iterator plot = plotDefMap.begin(); 
          plot != plotDefMap.end(); ++plot ) {
      if ( isFirstEntry ) {
        numMonitorElements_ref = plot->second.size();
        isFirstEntry = false;
      } else {
        if ( plot->second.size() != numMonitorElements_ref ) {
          edm::LogError ("DQMHistPlotter::DQMHistPlotter") << " Numbers of dqmMonitorElements must be the same for all plots" 
                                                           << " --> skipping drawJob = " << (*drawJobName) << " !!";
          cfgError_ = 1;
        }
      }
    }

//--- expand process directories in names of dqmMonitorElements
    for ( std::map<int, plotDefList>::iterator plot = plotDefMap.begin(); 
          plot != plotDefMap.end(); ++plot ) {
      for ( plotDefList::iterator entry = plot->second.begin();
            entry != plot->second.end(); ++entry ) {
        std::string dqmMonitorElement = entry->dqmMonitorElement_;
        std::string process = entry->process_;

        std::map<std::string, cfgEntryProcess>::const_iterator it = processes_.find(process);
        if ( it != processes_.end() ) {
          std::string process_dqmDirectory = it->second.dqmDirectory_;

          //std::cout << "replacing processDir = " << process_dqmDirectory << " in drawJob = " << (*drawJobName) << std::endl;

          int errorFlag = 0;
          std::string dqmMonitorElement_expanded = replace_string(dqmMonitorElement, processDirKeyword, process_dqmDirectory, 0, 1, errorFlag);
          //std::cout << " dqmMonitorElement_expanded = " << dqmMonitorElement_expanded << std::endl;

          if ( !errorFlag ) {
            entry->dqmMonitorElement_ = dqmMonitorElement_expanded;
          } else {
            cfgError_ = 1;
          }
        } else {
          edm::LogError ("DQMHistPlotter::DQMHistPlotter") << " Undefined process = " << process << " !!";
          cfgError_ = 1;
        }
      }
    }

    std::string title = ( drawJob.exists("title") ) ? drawJob.getParameter<std::string>("title") : ""; 

    std::string xAxis = drawJob.getParameter<std::string>("xAxis"); 
    std::string yAxis = drawJob.getParameter<std::string>("yAxis");
    
    std::string legend = drawJob.getParameter<std::string>("legend");
    
    vstring labels = ( drawJob.exists("labels") ) ? drawJob.getParameter<vstring>("labels") : vstring();

//--- expand parameters in names of dqmMonitorElements;
//    create drawJob objects
    for ( std::map<int, plotDefList>::iterator plot = plotDefMap.begin(); 
          plot != plotDefMap.end(); ++plot ) {
      if ( drawJob.exists("parameter") ) {
        vstring vparameter = drawJob.getParameter<vstring>("parameter");
        //std::cout << "replacing parameter = " << format_vstring(vparameter) << " in drawJob = " << (*drawJobName) << std::endl;

        for ( vstring::const_iterator parameter = vparameter.begin();
              parameter != vparameter.end(); ++parameter ) {

          plotDefList plot_expanded;

          for ( plotDefList::const_iterator entry = plot->second.begin();
                entry != plot->second.end(); ++entry ) {
            std::string dqmMonitorElement = entry->dqmMonitorElement_;
            
            int errorFlag = 0;
            std::string dqmMonitorElement_expanded = replace_string(dqmMonitorElement, parKeyword, *parameter, 1, 1, errorFlag);
            //std::cout << " dqmMonitorElement_expanded = " << dqmMonitorElement_expanded << std::endl;
            if ( !errorFlag ) {
              plot_expanded.push_back(plotDefEntry(dqmMonitorElement_expanded, entry->drawOptionEntry_, 
                                                   entry->legendEntry_, entry->legendEntryErrorBand_, entry->process_, entry->doStack_));
            } else {
              cfgError_ = 1;
            }
          }

          int errorFlag = 0;
          std::string title_expanded = replace_string(title, parKeyword, *parameter, 0, 1, errorFlag);
          //std::cout << " title_expanded = " << title_expanded << std::endl;
          std::string xAxis_expanded = replace_string(xAxis, parKeyword, *parameter, 0, 1, errorFlag);
          //std::cout << " xAxis_expanded = " << xAxis_expanded << std::endl;
          std::string yAxis_expanded = replace_string(yAxis, parKeyword, *parameter, 0, 1, errorFlag);
          //std::cout << " yAxis_expanded = " << yAxis_expanded << std::endl;
          if ( errorFlag ) cfgError_ = 1;

          drawJobs_.push_back(cfgEntryDrawJob(std::string(*drawJobName).append(*parameter),
                                              plot_expanded, title_expanded, xAxis_expanded, yAxis_expanded, legend, labels));
        }
      } else {
        drawJobs_.push_back(cfgEntryDrawJob(*drawJobName, 
                                            plot->second, title, xAxis, yAxis, legend, labels));
      }
    }
  }

//--- check that all information neccessary to process drawJob is defined;
  for ( std::list<cfgEntryDrawJob>::const_iterator drawJob = drawJobs_.begin();
        drawJob != drawJobs_.end(); ++drawJob ) {
    for ( plotDefList::const_iterator plot = drawJob->plots_.begin();
          plot != drawJob->plots_.end(); ++plot ) {
      checkCfgDef<cfgEntryDrawOption>(plot->drawOptionEntry_, drawOptionEntries_, cfgError_, "drawOptionEntry", drawJob->name_);
      checkCfgDef<cfgEntryProcess>(plot->process_, processes_, cfgError_, "process", drawJob->name_);
    }

    checkCfgDef<cfgEntryAxisX>(drawJob->xAxis_, xAxes_, cfgError_, "xAxis", drawJob->name_);
    checkCfgDef<cfgEntryAxisY>(drawJob->yAxis_, yAxes_, cfgError_, "yAxis", drawJob->name_);

    checkCfgDef<cfgEntryLegend>(drawJob->legend_, legends_, cfgError_, "legend", drawJob->name_);

    checkCfgDefs<cfgEntryLabel>(drawJob->labels_, labels_, cfgError_, "label", drawJob->name_);
  }

//--- configure canvas size
  //std::cout << "--> configuring canvas size..." << std::endl;
  canvasSizeX_ = ( cfg.exists("canvasSizeX") ) ? cfg.getParameter<int>("canvasSizeX") : defaultCanvasSizeX;
  canvasSizeY_ = ( cfg.exists("canvasSizeY") ) ? cfg.getParameter<int>("canvasSizeY") : defaultCanvasSizeY;
 
//--- configure output files
  //std::cout << "--> configuring postscript output file..." << std::endl;

  outputFilePath_ = ( cfg.exists("outputFilePath") ) ? cfg.getParameter<std::string>("outputFilePath") : "";
  if ( outputFilePath_.rbegin() != outputFilePath_.rend() ) {
    if ( (*outputFilePath_.rbegin()) == '/' ) outputFilePath_.erase(outputFilePath_.length() - 1);
  }
  //std::cout << " outputFilePath = " << outputFilePath_ << std::endl;

  outputFileName_ = ( cfg.exists("outputFileName") ) ? cfg.getParameter<std::string>("outputFileName") : "";
  //std::cout << " outputFileName = " << outputFileName_ << std::endl;

  indOutputFileName_ = ( cfg.exists("indOutputFileName") ) ? cfg.getParameter<std::string>("indOutputFileName") : "";
  if ( indOutputFileName_ != "" && indOutputFileName_.find('.') == std::string::npos ) {
    edm::LogError ("DQMHistPlotter") << " Failed to determine type of graphics format from indOutputFileName = " << indOutputFileName_ << " !!";
    cfgError_ = 1;
  }
  //std::cout << " indOutputFileName = " << indOutputFileName_ << std::endl;

//--- check that exactly one type of output is specified for the plots
//    (either separate graphics files displaying one plot each 
//     or postscript file displaying all plots on successive pages;
//     cannot create both types of output simultaneously,
//     as TCanvas::Print seems to interfere with TPostScript::NewPage)
  if ( outputFileName_ == "" && indOutputFileName_ == "" ) {
    edm::LogError ("DQMHistPlotter") << " Either outputFileName or indOutputFileName must be specified !!";
    cfgError_ = 1;
  }

  if ( outputFileName_ != "" && indOutputFileName_ != "" ) {
    edm::LogError ("DQMHistPlotter") << " Must not specify outputFileName and indOutputFileName simultaneously !!";
    cfgError_ = 1;
  }

  std::cout << "done." << std::endl;
}
DQMHistPlotter::~DQMHistPlotter ( ) [virtual]

Definition at line 880 of file DQMHistPlotter.cc.

{
// nothing to be done yet...
}

Member Function Documentation

void DQMHistPlotter::analyze ( const edm::Event ,
const edm::EventSetup  
) [virtual]

Implements edm::EDAnalyzer.

Definition at line 885 of file DQMHistPlotter.cc.

{
// nothing to be done yet...
}
void DQMHistPlotter::endJob ( void  ) [virtual]

Reimplemented from edm::EDAnalyzer.

Definition at line 890 of file DQMHistPlotter.cc.

References python::multivaluedict::append(), DQMHistPlotter::cfgEntryLabel::applyTo(), DQMHistPlotter::cfgEntryDrawOption::applyTo(), DQMHistPlotter::cfgEntryAxisX::applyTo(), svgfig::canvas(), canvasSizeX_, canvasSizeY_, cfgError_, gather_cfg::cout, defaultLegendPosX, defaultLegendPosY, defaultLegendSizeX, defaultLegendSizeY, dqmDirectoryName(), dqmRootDirectory, drawHistograms(), drawJobs_, DQMHistPlotter::cfgEntryDrawOption::drawOption_, drawOption_eBand, drawOptionEntries_, DQMHistPlotter::plotDefEntry::drawOptionEntry_, DQMHistPlotter::cfgEntryDrawOption::drawOptionLegend_, DQMHistPlotter::cfgEntryDrawOption::fillColor_, DQMHistPlotter::cfgEntryDrawOption::fillStyle_, DQMStore::get(), MonitorElement::getTH1(), indOutputFileName_, DQMHistPlotter::plotDefEntry::isErrorBand_, label, L1TDQM_cfg::labels, labels_, DQMHistPlotter::plotDefEntry::legendEntry_, DQMHistPlotter::plotDefEntry::legendEntryErrorBand_, legends_, DQMHistPlotter::cfgEntryDrawOption::lineColor_, DQMHistPlotter::cfgEntryDrawOption::lineWidth_, DQMHistPlotter::cfgEntryDrawOption::markerColor_, DQMHistPlotter::cfgEntryDrawOption::markerSize_, siStripFEDMonitor_P5_cff::Max, NULL, outputFileName_, outputFilePath_, EcalCondTools::plot(), plotKeyword, DQMHistPlotter::plotDefEntry::process_, processes_, replace_string(), DQMHistPlotter::cfgEntryAxisY::setNorm(), type_bsmMC, type_Data, type_smMC, type_smSumMC, xAxes_, yAxes_, and yScale_log.

{
  std::cout << "<DQMHistPlotter::endJob>:" << std::endl;

//--- check that configuration parameters contain no errors
  if ( cfgError_ ) {
    edm::LogError ("endJob") << " Error in Configuration ParameterSet --> histograms will NOT be plotted !!";
    return;
  }

//--- check that DQMStore service is available
  if ( !edm::Service<DQMStore>().isAvailable() ) {
    edm::LogError ("endJob") << " Failed to access dqmStore --> histograms will NOT be plotted !!";
    return;
  }

  DQMStore& dqmStore = (*edm::Service<DQMStore>());

//--- stop ROOT from keeping references to all hsitograms
  //TH1::AddDirectory(false);

//--- stop ROOT from opening X-window for canvas output
//    (in order to be able to run in batch mode) 
  gROOT->SetBatch(true);

//--- initialize graphical output;
//    open postscript file
  TCanvas canvas("DQMHistPlotter","DQMHistPlotter", canvasSizeX_, canvasSizeY_);
  canvas.SetFillColor(10);

//--- restrict area in which histograms are drawn to quadratic TPad in the center of the TCanvas,
//    in order to make space for axis labels...
  //TPad pad("EWKTauPad", "EWKTauPad", 0.02, 0.15, 0.98, 0.85);
  //pad.SetFillColor(10);
  //pad.Draw();
  //pad.Divide(1,1);
  //pad.cd(1);

  TPostScript* ps = NULL;
  if ( outputFileName_ != "" ) {
    std::string psFileName = ( outputFilePath_ != "" ) ? std::string(outputFilePath_).append("/").append(outputFileName_) : outputFileName_;
    ps = new TPostScript(psFileName.data(), 112);
  }
    
//--- process drawJobs
  for ( std::list<cfgEntryDrawJob>::const_iterator drawJob = drawJobs_.begin(); 
        drawJob != drawJobs_.end(); ++drawJob ) {
    const std::string& drawJobName = drawJob->name_;
    std::cout << "--> processing drawJob " << drawJobName << "..." << std::endl;

//--- prepare internally used histogram data-structures
    TH1* stackedHistogram_sum = NULL;
    std::list<TH1*> histogramsToDelete;
    std::list<plotDefEntry*> drawOptionsToDelete;

    typedef std::pair<TH1*, const plotDefEntry*> histogram_drawOption_pair;
    std::list<histogram_drawOption_pair> allHistograms;

    for ( plotDefList::const_iterator plot = drawJob->plots_.begin();
          plot != drawJob->plots_.end(); ++plot ) {

      std::string dqmMonitorElementName_full = dqmDirectoryName(std::string(dqmRootDirectory)).append(plot->dqmMonitorElement_);
      //std::cout << " dqmMonitorElementName_full = " << dqmMonitorElementName_full << std::endl;
      MonitorElement* dqmMonitorElement = dqmStore.get(dqmMonitorElementName_full);

      TH1* histogram = ( dqmMonitorElement ) ? dynamic_cast<TH1*>(dqmMonitorElement->getTH1()->Clone()) : NULL;
      histogramsToDelete.push_back(histogram);

      if ( histogram == NULL ) {
        edm::LogError ("endJob") << " Failed to access dqmMonitorElement = " << dqmMonitorElementName_full <<","
                                 << " needed by drawJob = " << drawJobName << " --> histograms will NOT be plotted !!";
        return;
      }

      if ( !histogram->GetSumw2N() ) histogram->Sumw2();

      const cfgEntryDrawOption* drawOptionConfig = 
        findCfgDef<cfgEntryDrawOption>(plot->drawOptionEntry_, drawOptionEntries_, "drawOptionEntry", drawJobName);
      if ( drawOptionConfig == NULL ) {
        edm::LogError ("endJob") << " Failed to access information needed by drawJob = " << drawJobName 
                                 << " --> histograms will NOT be plotted !!";
        return;
      }
      
      if ( drawOptionConfig->drawOption_ == drawOption_eBand ) {
//--- add histogram displaying central value as solid line
        TH1* histogram_centralValue = dynamic_cast<TH1*>(histogram->Clone());
        histogram_centralValue->SetName(std::string(histogram->GetName()).append("_centralValue").data());
        cfgEntryDrawOption drawOptionConfig_centralValue(*drawOptionConfig);
        drawOptionConfig_centralValue.fillColor_ = 0;
        drawOptionConfig_centralValue.fillStyle_ = 0;
        drawOptionConfig_centralValue.drawOption_ = "hist";
        drawOptionConfig_centralValue.drawOptionLegend_ = "l";
        std::string drawOptionName_centralValue = std::string(plot->drawOptionEntry_).append("_centralValue");
//--- entries in std::map need to be unique,
//    so need to check whether drawOptionEntry already exists...
        if ( drawOptionEntries_.find(drawOptionName_centralValue) == drawOptionEntries_.end() ) 
          drawOptionEntries_.insert(std::pair<std::string, cfgEntryDrawOption>
                                    (drawOptionName_centralValue, cfgEntryDrawOption(drawOptionName_centralValue, drawOptionConfig_centralValue)));
        plotDefEntry* plot_centralValue = new plotDefEntry(*plot);
        plot_centralValue->drawOptionEntry_ = drawOptionName_centralValue;
        allHistograms.push_back(histogram_drawOption_pair(histogram_centralValue, plot_centralValue));
        histogramsToDelete.push_back(histogram_centralValue);
        drawOptionsToDelete.push_back(plot_centralValue);

//--- add histogram displaying uncertainty as shaded error band
        TH1* histogram_ErrorBand = dynamic_cast<TH1*>(histogram->Clone());
        histogram_ErrorBand->SetName(std::string(histogram->GetName()).append("_ErrorBand").data());
        cfgEntryDrawOption drawOptionConfig_ErrorBand(*drawOptionConfig);
        drawOptionConfig_ErrorBand.markerColor_ = drawOptionConfig_ErrorBand.fillColor_;
        drawOptionConfig_ErrorBand.markerSize_ = 0.;
        drawOptionConfig_ErrorBand.lineColor_ = drawOptionConfig_ErrorBand.fillColor_;
        drawOptionConfig_ErrorBand.lineWidth_ = 0;
        drawOptionConfig_ErrorBand.drawOption_ = "e2";
        drawOptionConfig_ErrorBand.drawOptionLegend_ = "f";
        std::string drawOptionName_ErrorBand = std::string(plot->drawOptionEntry_).append("_ErrorBand");
//--- entries in std::map need to be unique,
//    so need to check whether drawOptionEntry already exists...
        if ( drawOptionEntries_.find(drawOptionName_ErrorBand) == drawOptionEntries_.end() ) 
          drawOptionEntries_.insert(std::pair<std::string, cfgEntryDrawOption>
                                    (drawOptionName_ErrorBand, cfgEntryDrawOption(drawOptionName_ErrorBand, drawOptionConfig_ErrorBand)));
        plotDefEntry* plot_ErrorBand = new plotDefEntry(*plot);
        plot_ErrorBand->drawOptionEntry_ = drawOptionName_ErrorBand;
        plot_ErrorBand->isErrorBand_ = true;
        allHistograms.push_back(histogram_drawOption_pair(histogram_ErrorBand, plot_ErrorBand));
        histogramsToDelete.push_back(histogram_ErrorBand);
        drawOptionsToDelete.push_back(plot_ErrorBand);
      } else if ( plot->doStack_ ) {
        TH1* stackedHistogram = dynamic_cast<TH1*>(histogram->Clone());
        if ( stackedHistogram_sum ) stackedHistogram->Add(stackedHistogram_sum);
        stackedHistogram_sum = stackedHistogram;
        histogramsToDelete.push_back(stackedHistogram);
        allHistograms.push_back(histogram_drawOption_pair(stackedHistogram, &(*plot)));
      } else {  
        allHistograms.push_back(histogram_drawOption_pair(histogram, &(*plot)));
      }
    }

//--- determine normalization of y-axis
//    (maximum of any of the histograms included in drawJob)
    double yAxisNorm = 0.;
    for ( std::list<histogram_drawOption_pair>::const_iterator it = allHistograms.begin();
          it != allHistograms.end(); ++it ) {
      yAxisNorm = TMath::Max(yAxisNorm, it->first->GetMaximum());
    }
    //std::cout << " yAxisNorm = " << yAxisNorm << std::endl;
    cfgEntryAxisY::setNorm(yAxisNorm);

//--- prepare histograms for drawing
    const cfgEntryAxisX* xAxisConfig = findCfgDef<cfgEntryAxisX>(drawJob->xAxis_, xAxes_, "xAxis", drawJobName);
    const cfgEntryAxisY* yAxisConfig = findCfgDef<cfgEntryAxisY>(drawJob->yAxis_, yAxes_, "yAxis", drawJobName);
    const cfgEntryLegend* legendConfig = findCfgDef<cfgEntryLegend>(drawJob->legend_, legends_, "legend", drawJobName);
    if ( xAxisConfig == NULL || yAxisConfig == NULL || legendConfig == NULL ) {
      edm::LogError ("endJob") << " Failed to access information needed by drawJob = " << drawJobName 
                               << " --> histograms will NOT be plotted !!";
      return;
    }

//--- WARNING: need to call 
//              TLegend::TLegend(Double_t, Double_t,Double_t, Double_t, const char* = "", Option_t* = "brNDC")
//             constructor, as TLegend::TLegend default constructor causes the created TLegend object to behave differently !!
    TLegend legend(defaultLegendPosX, defaultLegendPosY, defaultLegendPosX + defaultLegendSizeX, defaultLegendPosY + defaultLegendSizeY);
    legendConfig->applyTo(&legend);

    std::list<histoDrawEntry> smProcessHistogramList;
    std::list<histoDrawEntry> bsmProcessHistogramList;
    std::list<histoDrawEntry> smSumHistogramList;
    std::list<histoDrawEntry> smSumUncertaintyHistogramList;
    std::list<histoDrawEntry> dataHistogramList;

    for ( std::list<histogram_drawOption_pair>::const_iterator it = allHistograms.begin();
          it != allHistograms.end(); ++it ) {
      TH1* histogram = it->first;
      const plotDefEntry* drawOption = it->second;

      const cfgEntryDrawOption* drawOptionConfig = 
        findCfgDef<cfgEntryDrawOption>(drawOption->drawOptionEntry_, drawOptionEntries_, "drawOptionEntry", drawJobName);
      const cfgEntryProcess* processConfig = findCfgDef<cfgEntryProcess>(drawOption->process_, processes_, "process", drawJobName);
      if ( drawOptionConfig == NULL || processConfig == NULL ) {
        edm::LogError ("endJob") << " Failed to access information needed by drawJob = " << drawJobName 
                                 << " --> histograms will NOT be plotted !!";
        return;
      }
      
      if ( drawJob->title_ != "" ) histogram->SetTitle(drawJob->title_.data());

      xAxisConfig->applyTo(histogram);
      yAxisConfig->applyTo(histogram);

      bool yLogScale = ( yAxisConfig->yScale_ == yScale_log ) ? true : false;
      //std::cout << " yLogScale = " << yLogScale << std::endl; 
      //pad.SetLogy(yLogScale);
      canvas.SetLogy(yLogScale);

      drawOptionConfig->applyTo(histogram);
      histogram->SetStats(false);

      if ( drawOption->isErrorBand_ ) {
        smSumUncertaintyHistogramList.push_back(histoDrawEntry(histogram, drawOptionConfig->drawOption_.data()));
      } else {
        if ( processConfig->type_ == type_smMC ) {
          smProcessHistogramList.push_back(histoDrawEntry(histogram, drawOptionConfig->drawOption_.data()));
        } else if ( processConfig->type_ == type_bsmMC ) {
          bsmProcessHistogramList.push_back(histoDrawEntry(histogram, drawOptionConfig->drawOption_.data()));
        } else if ( processConfig->type_ == type_smSumMC ) {
          smSumHistogramList.push_back(histoDrawEntry(histogram, drawOptionConfig->drawOption_.data()));
        } else if ( processConfig->type_ == type_Data ) {
          dataHistogramList.push_back(histoDrawEntry(histogram, drawOptionConfig->drawOption_.data()));
        } 
      }

      std::string legendEntry, legendDrawOption;
      if ( drawOption->isErrorBand_ ) {
        legendEntry = ( drawOption->legendEntryErrorBand_ != "" ) ? drawOption->legendEntryErrorBand_ : processConfig->legendEntryErrorBand_;
        legendDrawOption = "f";
      } else {
        legendEntry = ( drawOption->legendEntry_ != "" ) ? drawOption->legendEntry_ : processConfig->legendEntry_;
        legendDrawOption = drawOptionConfig->drawOptionLegend_;
      } 

      legend.AddEntry(histogram, legendEntry.data(), legendDrawOption.data());
    }

    std::list<TPaveText> labels;
    for ( vstring::const_iterator labelName = drawJob->labels_.begin();
          labelName != drawJob->labels_.end(); ++labelName ) {
      const cfgEntryLabel* labelConfig = findCfgDef<cfgEntryLabel>(*labelName, labels_, "label", drawJobName);
      
      TPaveText label;
      labelConfig->applyTo(&label);

      labels.push_back(label);
    }

//--- draw histograms 
//   - in the order:
//    1. uncertainty on sum of all Standard Model processes
//    2. sum of all Standard Model processes
//    3. individual Standard Model processes
//    4. individual beyond the Standard Model processes
//    5. data
    bool isFirstHistogram = true;
    drawHistograms(smSumUncertaintyHistogramList, isFirstHistogram);
    drawHistograms(smSumHistogramList, isFirstHistogram);

//--- process histograms for individual Standard Model processes
//    in reverse order, so that most stacked histogram gets drawn first
    for ( std::list<histoDrawEntry>::reverse_iterator it = smProcessHistogramList.rbegin();
          it != smProcessHistogramList.rend(); ++it ) {
      std::string drawOption = ( isFirstHistogram ) ? it->second : std::string(it->second).append("same");
      it->first->Draw(drawOption.data());
      isFirstHistogram = false;
    }
        
    drawHistograms(bsmProcessHistogramList, isFirstHistogram);
    drawHistograms(dataHistogramList, isFirstHistogram);

    legend.Draw();

    for ( std::list<TPaveText>::iterator label = labels.begin();
          label != labels.end(); ++label ) {
      label->Draw();
    }

    //pad.RedrawAxis();
    
    canvas.Update();
    //pad.Update();

    if ( indOutputFileName_ != "" ) {
      int errorFlag = 0;
      std::string modIndOutputFileName = replace_string(indOutputFileName_, plotKeyword, drawJobName, 1, 1, errorFlag);
      if ( !errorFlag ) {
        std::string fullFileName = ( outputFilePath_ != "" ) ? 
          std::string(outputFilePath_).append("/").append(modIndOutputFileName) : modIndOutputFileName;
        canvas.Print(fullFileName.data());
      } else {
        edm::LogError("endJob") << " Failed to decode indOutputFileName = " << indOutputFileName_ << " --> skipping !!";
      }
    }

    if ( ps ) ps->NewPage();

//--- delete temporarily created histogram and drawOption objects
    for ( std::list<TH1*>::const_iterator histogram = histogramsToDelete.begin();
          histogram != histogramsToDelete.end(); ++histogram ) {
      delete (*histogram);
    }

    for ( std::list<plotDefEntry*>::const_iterator drawOption = drawOptionsToDelete.begin();
          drawOption != drawOptionsToDelete.end(); ++drawOption ) {
      delete (*drawOption);
    }
  }

//--- close postscript file
  canvas.Clear();
  std::cout << "done." << std::endl;
  if ( ps ) ps->Close();
  delete ps;
}

Member Data Documentation

Definition at line 173 of file DQMHistPlotter.h.

Referenced by DQMHistPlotter(), and endJob().

Definition at line 174 of file DQMHistPlotter.h.

Referenced by DQMHistPlotter(), and endJob().

Definition at line 178 of file DQMHistPlotter.h.

Referenced by DQMHistPlotter(), and endJob().

Definition at line 172 of file DQMHistPlotter.h.

Referenced by DQMHistPlotter(), and endJob().

std::map<std::string, cfgEntryDrawOption> DQMHistPlotter::drawOptionEntries_ [private]

Definition at line 171 of file DQMHistPlotter.h.

Referenced by DQMHistPlotter(), and endJob().

std::string DQMHistPlotter::indOutputFileName_ [private]

Definition at line 177 of file DQMHistPlotter.h.

Referenced by DQMHistPlotter(), and endJob().

std::map<std::string, cfgEntryLabel> DQMHistPlotter::labels_ [private]
std::map<std::string, cfgEntryLegend> DQMHistPlotter::legends_ [private]

Definition at line 169 of file DQMHistPlotter.h.

Referenced by DQMHistPlotter(), and endJob().

std::string DQMHistPlotter::outputFileName_ [private]

Definition at line 176 of file DQMHistPlotter.h.

Referenced by DQMHistPlotter(), and endJob().

std::string DQMHistPlotter::outputFilePath_ [private]

Definition at line 175 of file DQMHistPlotter.h.

Referenced by DQMHistPlotter(), and endJob().

std::map<std::string, cfgEntryProcess> DQMHistPlotter::processes_ [private]

Definition at line 166 of file DQMHistPlotter.h.

Referenced by DQMHistPlotter(), and endJob().

std::map<std::string, cfgEntryAxisX> DQMHistPlotter::xAxes_ [private]

Definition at line 167 of file DQMHistPlotter.h.

Referenced by DQMHistPlotter(), and endJob().

std::map<std::string, cfgEntryAxisY> DQMHistPlotter::yAxes_ [private]

Definition at line 168 of file DQMHistPlotter.h.

Referenced by DQMHistPlotter(), and endJob().