CMS 3D CMS Logo

Public Member Functions | Private Member Functions | Static Private Member Functions | Private Attributes

EmDQMPostProcessor Class Reference

#include <EmDQMPostProcessor.h>

Inheritance diagram for EmDQMPostProcessor:
edm::EDAnalyzer

List of all members.

Public Member Functions

void analyze (const edm::Event &event, const edm::EventSetup &eventSetup)
TProfile * dividehistos (DQMStore *dqm, const std::string &num, const std::string &denom, const std::string &out, const std::string &label, const std::string &titel="")
 EmDQMPostProcessor (const edm::ParameterSet &pset)
void endRun (edm::Run const &, edm::EventSetup const &)
 ~EmDQMPostProcessor ()

Private Member Functions

TH1F * getHistogram (DQMStore *dqm, const std::string &histoPath)

Static Private Member Functions

static void Efficiency (int passing, int total, double level, double &mode, double &lowerBound, double &upperBound)

Private Attributes

std::string dataSet_
bool noPhiPlots
bool normalizeToReco
std::string subDir_

Detailed Description

Definition at line 9 of file EmDQMPostProcessor.h.


Constructor & Destructor Documentation

EmDQMPostProcessor::EmDQMPostProcessor ( const edm::ParameterSet pset)

Definition at line 18 of file EmDQMPostProcessor.cc.

References dataSet_, edm::ParameterSet::getUntrackedParameter(), noPhiPlots, normalizeToReco, and subDir_.

{
  subDir_  = pset.getUntrackedParameter<std::string>("subDir");

  dataSet_ = pset.getUntrackedParameter<std::string>("dataSet","unknown");

  noPhiPlots = pset.getUntrackedParameter<bool>("noPhiPlots", true);

  normalizeToReco = pset.getUntrackedParameter<bool>("normalizeToReco",false);
}
EmDQMPostProcessor::~EmDQMPostProcessor ( ) [inline]

Definition at line 12 of file EmDQMPostProcessor.h.

{};

Member Function Documentation

void EmDQMPostProcessor::analyze ( const edm::Event event,
const edm::EventSetup eventSetup 
) [inline, virtual]

Implements edm::EDAnalyzer.

Definition at line 14 of file EmDQMPostProcessor.h.

{};
TProfile * EmDQMPostProcessor::dividehistos ( DQMStore dqm,
const std::string &  num,
const std::string &  denom,
const std::string &  out,
const std::string &  label,
const std::string &  titel = "" 
)

Definition at line 307 of file EmDQMPostProcessor.cc.

References DQMStore::bookProfile(), alignCSCRings::e, Efficiency(), getHistogram(), MonitorElement::getTProfile(), i, NULL, dbtoconf::out, and mathSSE::sqrt().

Referenced by endRun().

                                                                                                                                                                                      {
  //std::cout << numName <<std::endl;

  TH1F* num = getHistogram(dqm,numName);

  //std::cout << denomName << std::endl;
  TH1F* denom = getHistogram(dqm, denomName);

  if (num == NULL)
    edm::LogWarning("EmDQMPostProcessor") << "numerator histogram " << numName << " does not exist";

  if (denom == NULL)
    edm::LogWarning("EmDQMPostProcessor") << "denominator histogram " << denomName << " does not exist";

  // Check if histograms actually exist

  if(!num || !denom) return 0;

  // Make sure we are able to book new element
  if (!dqm) return 0;
  
  TProfile* out = dqm->bookProfile(outName,titel,num->GetXaxis()->GetNbins(),num->GetXaxis()->GetXmin(),num->GetXaxis()->GetXmax(),0.,1.2)->getTProfile();
  out->GetXaxis()->SetTitle(label.c_str());
  out->SetYTitle("Efficiency");
  out->SetOption("PE");
  out->SetLineColor(2);
  out->SetLineWidth(2);
  out->SetMarkerStyle(20);
  out->SetMarkerSize(0.8);
  out->SetStats(kFALSE);
  for(int i=1;i<=num->GetNbinsX();i++){
    double e, low, high;
    Efficiency( (int)num->GetBinContent(i), (int)denom->GetBinContent(i), 0.683, e, low, high );
    double err = e-low>high-e ? e-low : high-e;
    //here is the trick to store info in TProfile:
    out->SetBinContent( i, e );
    out->SetBinEntries( i, 1 );
    out->SetBinError( i, sqrt(e*e+err*err) );
  }

  return out;
}
void EmDQMPostProcessor::Efficiency ( int  passing,
int  total,
double  level,
double &  mode,
double &  lowerBound,
double &  upperBound 
) [static, private]

a replacement for the function TGraphAsymmErrors::Efficiency(..) used with earlier versions of ROOT (this functionality has been moved to a separate class TEfficiency)

Definition at line 365 of file EmDQMPostProcessor.cc.

Referenced by dividehistos(), and endRun().

{ 
  // protection (see also TGraphAsymmErrors::Efficiency(..), mimick the old behaviour )
  if (total == 0)
  {
    mode = 0.5;
    lowerBound = 0;
    upperBound = 1;
    return;
  }

  mode = passing / ((double) total);

  // note that the order of the two first arguments ('total' and 'passed') is the opposited
  // with respect to the earlier TGraphAsymmErrors::Efficiency(..) method
  //
  // see https://root.cern.ch/root/html/TEfficiency.html#compare for
  // an illustration of the coverage of the different methods provided by TEfficiency
  
  lowerBound = TEfficiency::Wilson(total, passing, level, false);
  upperBound = TEfficiency::Wilson(total, passing, level, true);
}
void EmDQMPostProcessor::endRun ( edm::Run const &  run,
edm::EventSetup const &  es 
) [virtual]

Reimplemented from edm::EDAnalyzer.

Definition at line 31 of file EmDQMPostProcessor.cc.

References newFWLiteAna::bin, DQMStore::book1D(), DQMStore::bookProfile(), DQMStore::cd(), dataSet_, dir, DQMStore::dirExists(), dividehistos(), Efficiency(), error, align_tpl::filter, reco_skim_cfg_mod::filterName, getHistogram(), DQMStore::getSubdirs(), MonitorElement::getTProfile(), getTProfile(), DQMStore::goUp(), noPhiPlots, normalizeToReco, NULL, cmsCodeRules::cppFunctionSkipper::operator, python::multivaluedict::pop(), DQMStore::pwd(), mathSSE::sqrt(), subDir_, groupFilesInBlocks::temp, pileupDistInMC::total, relativeConstraints::value, and summarizeEdmComparisonLogfiles::varNames.

{
  // setup DQM stor               //
  
  DQMStore * dqm = 0;
  dqm = edm::Service<DQMStore>().operator->();

  if ( ! dqm ) {
    edm::LogInfo("EmDQMPostProcessor") << "Cannot create DQMStore instance\n";
    return;
  }


  //go to the directory to be processed
  if(dqm->dirExists(subDir_)) dqm->cd(subDir_);
  else {
    edm::LogWarning("EmDQMPostProcessor") << "cannot find directory: " << subDir_ << " , skipping";
    return;
  }

  //--------------------
  // with respect to what are (some) efficiencies calculated ?
  std::string shortReferenceName;
  if (normalizeToReco)
    shortReferenceName = "RECO";
  else
    shortReferenceName = "gen";



  //--------------------


  //loop over all triggers/samples//

  // store dataset name (if defined) in output file
  // DQMStore:bookString seems to put a key in the file which is
  // of the form <dataSet>s=....</dataSet> which is not very convenient
  // (it points to a null pointer, one would have to loop over
  // all keys of the corresponding directory in the ROOT file
  // and check whether it is of the desired form and then parse
  // it from this string...).
  //
  // So we store the name of the dataset as the title of a histogram,
  // which is much easier to access...
  // TH1D *dataSetNameHisto = 
  dqm->book1D("DataSetNameHistogram",dataSet_,1,0,1);

  std::vector<std::string> subdirectories = dqm->getSubdirs();
  // Do everything twice: once for mc-matched histos,   //
  // once for unmatched histos                          //

  std::vector<std::string> postfixes;
  postfixes.push_back("");   //unmatched histograms
  postfixes.push_back("_RECO_matched"); // for data
  // we put this on the list even when we're running on 
  // data (where there is no generator information).
  // The first test in the loop will then fail and
  // the iteration is skipped.
  postfixes.push_back("_MC_matched"); 

  std::vector<TProfile *> allElePaths;
  int nEle = 0;
  int nPhoton = 0;

  // find the number of electron and photon paths
  for(std::vector<std::string>::iterator dir = subdirectories.begin() ;dir!= subdirectories.end(); ++dir) {
    if (dir->find("HLT_Ele") != std::string::npos || dir->find("HLT_DoubleEle") != std::string::npos || dir->find("HLT_TripleEle") != std::string::npos) ++nEle;
    else if (dir->find("HLT_Photon") != std::string::npos || dir->find("HLT_DoublePhoton") != std::string::npos) ++nPhoton;
  }

  std::vector<TProfile *> allPhotonPaths;
  for(std::vector<std::string>::iterator postfix=postfixes.begin(); postfix!=postfixes.end();postfix++){
    bool pop = false;
    int elePos = 1;
    int photonPos = 1;

    // computer per-event efficiencies //
    
    std::string histoName = "efficiency_by_step" + *postfix;
    std::string baseName = "total_eff" + *postfix;

    std::string allEleHistoName = "EfficiencyByPath_Ele" + *postfix;
    std::string allEleHistoLabel = "Efficiency_for_each_validated_electron_path" + *postfix;
    allElePaths.push_back(new TProfile(allEleHistoName.c_str(), allEleHistoLabel.c_str(), nEle, 0., (double)nEle, 0., 1.2));
    std::string allPhotonHistoName = "EfficiencyByPath_Photon" + *postfix;
    std::string allPhotonHistoLabel = "Efficiency_for_each_validated_photon_path" + *postfix;
    allPhotonPaths.push_back(new TProfile(allPhotonHistoName.c_str(), allPhotonHistoLabel.c_str(), nPhoton, 0., (double)nPhoton, 0., 1.2));

    for(std::vector<std::string>::iterator dir = subdirectories.begin(); dir!= subdirectories.end(); dir++) {
      dqm->cd(*dir);

      TH1F* basehist = getHistogram(dqm, dqm->pwd() + "/" + baseName);
      if (basehist == NULL)
        {
          //edm::LogWarning("EmDQMPostProcessor") << "histogram " << (dqm->pwd() + "/" + baseName) << " does not exist, skipping postfix '" << *postfix << "'";
          pop = true;
          dqm->goUp();
          continue;
        }
      // at least one histogram with postfix was found
      pop = false;
          
      TProfile* total = dqm->bookProfile(histoName,histoName,basehist->GetXaxis()->GetNbins(),basehist->GetXaxis()->GetXmin(),basehist->GetXaxis()->GetXmax(),0.,1.2)->getTProfile();
      total->GetXaxis()->SetBinLabel(1,basehist->GetXaxis()->GetBinLabel(1));
      
//       std::vector<std::string> mes = dqm->getMEs();
//       for(std::vector<std::string>::iterator me = mes.begin() ;me!= mes.end(); me++ )
//      std::cout <<*me <<std::endl;
//       std::cout <<std::endl;
      
      double value=0;
      double errorh=0,errorl=0,error=0;    
      //compute stepwise total efficiencies 
      for(int bin= total->GetNbinsX()-2 ; bin > 1  ; bin--){
        value=0;
        errorl=0;
        errorh=0;
        error=0;
        if(basehist->GetBinContent(bin-1) != 0){
          Efficiency( (int)basehist->GetBinContent(bin), (int)basehist->GetBinContent(bin-1), 0.683, value, errorl, errorh );
          error = value-errorl>errorh-value ? value-errorl : errorh-value;
        }
        total->SetBinContent( bin, value );
        total->SetBinEntries( bin, 1 );
        total->SetBinError( bin, sqrt(value*value+error*error) );
        total->GetXaxis()->SetBinLabel(bin,basehist->GetXaxis()->GetBinLabel(bin));
      }

      //set first bin to L1 efficiency
      if(basehist->GetBinContent(basehist->GetNbinsX()) !=0 ){
        Efficiency( (int)basehist->GetBinContent(1), (int)basehist->GetBinContent(basehist->GetNbinsX()), 0.683, value, errorl, errorh );
        error= value-errorl>errorh-value ? value-errorl : errorh-value;
      }else{
        value=0;error=0;
      }
      total->SetBinContent(1,value);
      total->SetBinEntries(1, 1 );
      total->SetBinError(1, sqrt(value*value+error*error) );
     
      // total efficiency relative to gen or reco
      if(basehist->GetBinContent(basehist->GetNbinsX()) !=0 ){
        Efficiency( (int)basehist->GetBinContent(basehist->GetNbinsX()-2), (int)basehist->GetBinContent(basehist->GetNbinsX()), 0.683, value, errorl, errorh );
        error= value-errorl>errorh-value ? value-errorl : errorh-value;
      }else{
        value=0;error=0;
      }
      total->SetBinContent(total->GetNbinsX(),value);
      total->SetBinEntries(total->GetNbinsX(),1);
      total->SetBinError(total->GetNbinsX(),sqrt(value*value+error*error));
      total->GetXaxis()->SetBinLabel(total->GetNbinsX(),("total efficiency rel. " + shortReferenceName).c_str());
      
      //total efficiency relative to L1
      if(basehist->GetBinContent(1) !=0 ){
        Efficiency( (int)basehist->GetBinContent(basehist->GetNbinsX()-2), (int)basehist->GetBinContent(1), 0.683, value, errorl, errorh );
        error= value-errorl > errorh-value ? value-errorl : errorh-value;
      }else{
        value=0;error=0;
      }
      total->SetBinContent(total->GetNbinsX()-1,value);
      total->SetBinError(total->GetNbinsX()-1,sqrt(value*value+error*error));
      total->SetBinEntries(total->GetNbinsX()-1,1);
      total->GetXaxis()->SetBinLabel(total->GetNbinsX()-1,"total efficiency rel. L1");

      //----------------------------------------

      // compute per-object efficiencies       //
      //MonitorElement *eff, *num, *denom, *genPlot, *effVsGen, *effL1VsGen;
      std::vector<std::string> varNames; 
      varNames.push_back("et");
      varNames.push_back("eta"); 
      if (!noPhiPlots) varNames.push_back("phi"); 

      std::string filterName;
      std::string filterName2;
      std::string denomName;
      std::string numName;

      // Get the gen-level (or reco, for data) plots
      std::string genName;

      // Get the L1 over gen filter first
      filterName2= total->GetXaxis()->GetBinLabel(1);
        
      //loop over variables (eta/phi/et)
      for(std::vector<std::string>::iterator var = varNames.begin(); var != varNames.end() ; var++){
        
        numName   = dqm->pwd() + "/" + filterName2 + *var + *postfix;

        if (normalizeToReco)
          genName   = dqm->pwd() + "/reco_" + *var ;
        else
          genName   = dqm->pwd() + "/gen_" + *var ;

        // Create the efficiency plot
        if(!dividehistos(dqm,numName,genName,"efficiency_"+filterName2+"_vs_"+*var +*postfix,*var,"eff. of"+filterName2+" vs "+*var +*postfix))
          break;
      } // loop over variables
    
      // get the filter names from the bin-labels of the master-histogram
      for (int filter=1; filter < total->GetNbinsX()-2; filter++) {
        filterName = total->GetXaxis()->GetBinLabel(filter);
        filterName2= total->GetXaxis()->GetBinLabel(filter+1);
        
        //loop over variables (eta/et/phi)
        for(std::vector<std::string>::iterator var = varNames.begin(); var != varNames.end() ; var++){
          numName   = dqm->pwd() + "/" + filterName2 + *var + *postfix;
          denomName = dqm->pwd() + "/" + filterName  + *var + *postfix;

          // Is this the last filter? Book efficiency vs gen (or reco, for data) level
          std::string temp = *postfix;
          if (filter==total->GetNbinsX()-3 && temp.find("matched")!=std::string::npos) {
            if (normalizeToReco)
              genName = dqm->pwd() + "/reco_" + *var;
            else
              genName = dqm->pwd() + "/gen_" + *var;

            if(!dividehistos(dqm,numName,genName,"final_eff_vs_"+*var,*var,"Efficiency Compared to " + shortReferenceName + " vs "+*var))
              break;
          }

          if(!dividehistos(dqm,numName,denomName,"efficiency_"+filterName2+"_vs_"+*var +*postfix,*var,"efficiency_"+filterName2+"_vs_"+*var + *postfix))
            break;

        } // loop over variables
      } // loop over monitoring modules within path

      dqm->goUp();

      // fill overall efficiency histograms
      std::string trigName = dir->substr(dir->rfind("/") + 1);
      trigName = trigName.replace(trigName.rfind("_DQM"),4,"");
      double totCont = total->GetBinContent(total->GetNbinsX());
      double totErr = total->GetBinError(total->GetNbinsX());
      if (trigName.find("HLT_Ele") != std::string::npos || trigName.find("HLT_DoubleEle") != std::string::npos || trigName.find("HLT_TripleEle") != std::string::npos) {
        allElePaths.back()->SetBinContent(elePos, totCont);
        allElePaths.back()->SetBinEntries(elePos, 1);
        allElePaths.back()->SetBinError(elePos, sqrt(totCont * totCont + totErr * totErr));
        allElePaths.back()->GetXaxis()->SetBinLabel(elePos, trigName.c_str());
        ++elePos;
      }
      else if (trigName.find("HLT_Photon") != std::string::npos || trigName.find("HLT_DoublePhoton") != std::string::npos) {
        allPhotonPaths.back()->SetBinContent(photonPos, totCont);
        allPhotonPaths.back()->SetBinEntries(photonPos, 1);
        allPhotonPaths.back()->SetBinError(photonPos, sqrt(totCont * totCont + totErr * totErr));
        allPhotonPaths.back()->GetXaxis()->SetBinLabel(photonPos, trigName.c_str());
        ++photonPos;
      }

    } // loop over dirs
    if (pop) {
      allElePaths.pop_back();
      allPhotonPaths.pop_back();
    } 
    else {
      allElePaths.back()->GetXaxis()->SetLabelSize(0.03);
      allPhotonPaths.back()->GetXaxis()->SetLabelSize(0.03);
      dqm->bookProfile(allEleHistoName, allElePaths.back())->getTProfile();
      dqm->bookProfile(allPhotonHistoName, allPhotonPaths.back())->getTProfile();
    }
  } // loop over postfixes
  
}
TH1F * EmDQMPostProcessor::getHistogram ( DQMStore dqm,
const std::string &  histoPath 
) [private]

convenience method to get a histogram but checks first whether the corresponding MonitorElement is non-null.

Returns:
null if the MonitorElement is null

Definition at line 353 of file EmDQMPostProcessor.cc.

References DQMStore::get(), MonitorElement::getTH1F(), and NULL.

Referenced by dividehistos(), and endRun().

{
  MonitorElement *monElement = dqm->get(histoPath);
  if (monElement != NULL)
    return monElement->getTH1F();
  else
    return NULL;
}

Member Data Documentation

std::string EmDQMPostProcessor::dataSet_ [private]

dataset with which these histograms were produced. This is set by a user parameter in the configuration file.

It is just used for writing it to the DQM output file. Useful to remember with which dataset a histogram file was produced. This code does not do much with this information (apart from copying it to the output file) but it can be used when generating reports.

Definition at line 48 of file EmDQMPostProcessor.h.

Referenced by EmDQMPostProcessor(), and endRun().

read from the configuration: if set to true, efficiencies are calculated with respect to reconstructed objects (instead of generated objects). This is e.g. a useful option when running on data.

Definition at line 28 of file EmDQMPostProcessor.h.

Referenced by EmDQMPostProcessor(), and endRun().

Definition at line 29 of file EmDQMPostProcessor.h.

Referenced by EmDQMPostProcessor(), and endRun().

std::string EmDQMPostProcessor::subDir_ [private]

Definition at line 36 of file EmDQMPostProcessor.h.

Referenced by EmDQMPostProcessor(), and endRun().