Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:13:23

0001 #include "DQMOffline/Trigger/interface/EgHLTOfflineSource.h"
0002 
0003 #include "DQMOffline/Trigger/interface/EgHLTEleHLTFilterMon.h"
0004 #include "DQMOffline/Trigger/interface/EgHLTPhoHLTFilterMon.h"
0005 
0006 #include "DQMOffline/Trigger/interface/EgHLTDebugFuncs.h"
0007 #include "DQMOffline/Trigger/interface/EgHLTDQMCut.h"
0008 #include "DQMOffline/Trigger/interface/EgHLTTrigTools.h"
0009 
0010 #include "DQMServices/Core/interface/DQMStore.h"
0011 
0012 #include "FWCore/Framework/interface/Run.h"
0013 #include "HLTrigger/HLTcore/interface/HLTConfigProvider.h"
0014 
0015 #include <boost/algorithm/string.hpp>
0016 
0017 //#include "DQMOffline/Trigger/interface/EgHLTCutCodes.h"
0018 #include "DataFormats/TrackReco/interface/Track.h"
0019 #include "DataFormats/EgammaCandidates/interface/ElectronFwd.h"
0020 #include "DataFormats/HLTReco/interface/TriggerFilterObjectWithRefs.h"
0021 using namespace egHLT;
0022 
0023 EgHLTOfflineSource::EgHLTOfflineSource(const edm::ParameterSet& iConfig) : nrEventsProcessed_(0) {
0024   binData_.setup(iConfig.getParameter<edm::ParameterSet>("binData"));
0025   cutMasks_.setup(iConfig.getParameter<edm::ParameterSet>("cutMasks"));
0026   eleHLTFilterNames_ = iConfig.getParameter<std::vector<std::string> >("eleHLTFilterNames");
0027   eleHLTFilterNames2Leg_ = iConfig.getParameter<std::vector<std::string> >("eleHLTFilterNames2Leg");
0028   phoHLTFilterNames_ = iConfig.getParameter<std::vector<std::string> >("phoHLTFilterNames");
0029   eleTightLooseTrigNames_ = iConfig.getParameter<std::vector<std::string> >("eleTightLooseTrigNames");
0030   diEleTightLooseTrigNames_ = iConfig.getParameter<std::vector<std::string> >("diEleTightLooseTrigNames");
0031   phoTightLooseTrigNames_ = iConfig.getParameter<std::vector<std::string> >("phoTightLooseTrigNames");
0032   diPhoTightLooseTrigNames_ = iConfig.getParameter<std::vector<std::string> >("diPhoTightLooseTrigNames");
0033 
0034   filterInactiveTriggers_ = iConfig.getParameter<bool>("filterInactiveTriggers");
0035   hltTag_ = iConfig.getParameter<std::string>("hltTag");
0036   dohep_ = iConfig.getParameter<bool>("doHEP");
0037 
0038   dirName_ = iConfig.getParameter<std::string>(
0039       "DQMDirName");  //"HLT/EgHLTOfflineSource_" + iConfig.getParameter<std::string>("@module_label");
0040 
0041   subdirName_ = iConfig.getParameter<std::string>("subDQMDirName");
0042 
0043   offEvtHelper_.setup(iConfig, consumesCollector());
0044 }
0045 
0046 EgHLTOfflineSource::~EgHLTOfflineSource() {
0047   // LogDebug("EgHLTOfflineSource") << "destructor called";
0048   for (auto& eleFilterMonHist : eleFilterMonHists_) {
0049     delete eleFilterMonHist;
0050   }
0051   for (auto& phoFilterMonHist : phoFilterMonHists_) {
0052     delete phoFilterMonHist;
0053   }
0054   for (auto& eleMonElem : eleMonElems_) {
0055     delete eleMonElem;
0056   }
0057   for (auto& phoMonElem : phoMonElems_) {
0058     delete phoMonElem;
0059   }
0060 }
0061 
0062 void EgHLTOfflineSource::bookHistograms(DQMStore::IBooker& iBooker, edm::Run const& run, edm::EventSetup const& c) {
0063   iBooker.setCurrentFolder(dirName_);
0064 
0065   //the one monitor element the source fills directly
0066   dqmErrsMonElem_ = iBooker.book1D("dqmErrors", "EgHLTOfflineSource Errors", 101, -0.5, 100.5);
0067   nrEventsProcessedMonElem_ = iBooker.bookInt("nrEventsProcessed");
0068 
0069   //if the HLTConfig changes during the job, the results are "un predictable" but in practice should be fine
0070   //the HLTConfig is used for working out which triggers are active, working out which filternames correspond to paths and L1 seeds
0071   //assuming those dont change for E/g it *should* be fine
0072   HLTConfigProvider hltConfig;
0073   bool changed = false;
0074   hltConfig.init(run, c, hltTag_, changed);
0075   if (filterInactiveTriggers_)
0076     filterTriggers(hltConfig);
0077 
0078   std::vector<std::string> hltFiltersUsed;
0079   getHLTFilterNamesUsed(hltFiltersUsed);
0080   trigCodes.reset(TrigCodes::makeCodes(hltFiltersUsed));
0081 
0082   offEvtHelper_.setupTriggers(hltConfig, hltFiltersUsed, *trigCodes);
0083 
0084   MonElemFuncs monElemFuncs(iBooker, *trigCodes);
0085 
0086   //now book ME's
0087   iBooker.setCurrentFolder(dirName_ + "/" + subdirName_);
0088   //each trigger path with generate object distributions and efficiencies (BUT not trigger efficiencies...)
0089   for (auto const& eleHLTFilterName : eleHLTFilterNames_) {
0090     iBooker.setCurrentFolder(dirName_ + "/" + subdirName_ + "/" + eleHLTFilterName);
0091     addEleTrigPath(monElemFuncs, eleHLTFilterName);
0092   }
0093   for (auto const& phoHLTFilterName : phoHLTFilterNames_) {
0094     iBooker.setCurrentFolder(dirName_ + "/" + subdirName_ + "/" + phoHLTFilterName);
0095     addPhoTrigPath(monElemFuncs, phoHLTFilterName);
0096   }
0097   //efficiencies of one trigger path relative to another
0098   monElemFuncs.initTightLooseTrigHists(eleMonElems_, eleTightLooseTrigNames_, binData_, "gsfEle");
0099   //new EgHLTDQMVarCut<OffEle>(cutMasks_.stdEle,&OffEle::cutCode));
0100   //monElemFuncs.initTightLooseTrigHistsTrigCuts(eleMonElems_,eleTightLooseTrigNames_,binData_);
0101 
0102   monElemFuncs.initTightLooseTrigHists(phoMonElems_, phoTightLooseTrigNames_, binData_, "pho");
0103   //    new EgHLTDQMVarCut<OffPho>(cutMasks_.stdPho,&OffPho::cutCode));
0104   //monElemFuncs.initTightLooseTrigHistsTrigCuts(phoMonElems_,phoTightLooseTrigNames_,binData_);
0105 
0106   //di-object triggers
0107   monElemFuncs.initTightLooseTrigHists(eleMonElems_, diEleTightLooseTrigNames_, binData_, "gsfEle");
0108   //    new EgDiEleCut(cutMasks_.stdEle,&OffEle::cutCode));
0109   monElemFuncs.initTightLooseTrigHists(phoMonElems_, diPhoTightLooseTrigNames_, binData_, "pho");
0110   //                new EgDiPhoCut(cutMasks_.stdPho,&OffPho::cutCode));
0111 
0112   monElemFuncs.initTightLooseDiObjTrigHistsTrigCuts(eleMonElems_, diEleTightLooseTrigNames_, binData_);
0113   monElemFuncs.initTightLooseDiObjTrigHistsTrigCuts(phoMonElems_, diPhoTightLooseTrigNames_, binData_);
0114 
0115   //tag and probe trigger efficiencies
0116   //this is to do measure the trigger efficiency with respect to a fully selected offline electron
0117   //using a tag and probe technique (note: this will be different to the trigger efficiency normally calculated)
0118   bool doTrigTagProbeEff = false;
0119   if (doTrigTagProbeEff && (!dohep_)) {
0120     for (auto const& eleHLTFilterName : eleHLTFilterNames_) {
0121       iBooker.setCurrentFolder(dirName_ + "/" + subdirName_ + "/" + eleHLTFilterName);
0122       monElemFuncs.initTrigTagProbeHist(eleMonElems_, eleHLTFilterName, cutMasks_.trigTPEle, binData_);
0123     }
0124     for (auto const& phoHLTFilterName : phoHLTFilterNames_) {
0125       iBooker.setCurrentFolder(dirName_ + "/" + subdirName_ + "/" + phoHLTFilterName);
0126       monElemFuncs.initTrigTagProbeHist(phoMonElems_, phoHLTFilterName, cutMasks_.trigTPPho, binData_);
0127     }
0128     for (auto& i : eleHLTFilterNames2Leg_) {
0129       iBooker.setCurrentFolder(dirName_ + "/" + subdirName_ + "/" + i.substr(i.find("::") + 2));
0130       //std::cout<<"FilterName: "<<eleHLTFilterNames2Leg_[i]<<std::endl;
0131       //std::cout<<"Folder: "<<eleHLTFilterNames2Leg_[i].substr(eleHLTFilterNames2Leg_[i].find("::")+2)<<std::endl;
0132       monElemFuncs.initTrigTagProbeHist_2Leg(eleMonElems_, i, cutMasks_.trigTPEle, binData_);
0133     }
0134     //tag and probe not yet implimented for photons (attemping to see if it makes sense first)
0135     // monElemFuncs.initTrigTagProbeHists(phoMonElems,phoHLTFilterNames_);
0136   }
0137 
0138   iBooker.setCurrentFolder(dirName_);
0139 }
0140 
0141 void EgHLTOfflineSource::analyze(const edm::Event& iEvent, const edm::EventSetup& iSetup) {
0142   const double weight = 1.;  //we have the ability to weight but its disabled for now - maybe use this for prescales?
0143   nrEventsProcessed_++;
0144   nrEventsProcessedMonElem_->Fill(nrEventsProcessed_);
0145   int errCode = offEvtHelper_.makeOffEvt(iEvent, iSetup, offEvt_, *trigCodes);
0146   if (errCode != 0) {
0147     dqmErrsMonElem_->Fill(errCode);
0148     return;
0149   }
0150 
0151   for (auto& eleFilterMonHist : eleFilterMonHists_) {
0152     eleFilterMonHist->fill(offEvt_, weight);
0153   }
0154   for (auto& phoFilterMonHist : phoFilterMonHists_) {
0155     phoFilterMonHist->fill(offEvt_, weight);
0156   }
0157 
0158   for (auto& eleMonElem : eleMonElems_) {
0159     const std::vector<OffEle>& eles = offEvt_.eles();
0160     for (auto const& ele : eles) {
0161       eleMonElem->fill(ele, offEvt_, weight);
0162     }
0163   }
0164 
0165   for (auto& phoMonElem : phoMonElems_) {
0166     const std::vector<OffPho>& phos = offEvt_.phos();
0167     for (auto const& pho : phos) {
0168       phoMonElem->fill(pho, offEvt_, weight);
0169     }
0170   }
0171 }
0172 
0173 void EgHLTOfflineSource::addEleTrigPath(MonElemFuncs& monElemFuncs, const std::string& name) {
0174   auto* filterMon =
0175       new EleHLTFilterMon(monElemFuncs, name, trigCodes->getCode(name.c_str()), binData_, cutMasks_, dohep_);
0176   eleFilterMonHists_.push_back(filterMon);
0177   std::sort(eleFilterMonHists_.begin(), eleFilterMonHists_.end(), [](auto const& x, auto const& y) { return *x < *y; });
0178   //takes a minor efficiency hit at initalisation to ensure that the vector is always sorted
0179 }
0180 
0181 void EgHLTOfflineSource::addPhoTrigPath(MonElemFuncs& monElemFuncs, const std::string& name) {
0182   PhoHLTFilterMon* filterMon =
0183       new PhoHLTFilterMon(monElemFuncs, name, trigCodes->getCode(name.c_str()), binData_, cutMasks_, dohep_);
0184   phoFilterMonHists_.push_back(filterMon);
0185   std::sort(phoFilterMonHists_.begin(), phoFilterMonHists_.end(), [](auto const& x, auto const& y) { return *x < *y; });
0186   //takes a minor efficiency hit at initalisation to ensure that the vector is always sorted
0187 }
0188 
0189 //this function puts every filter name used in a std::vector
0190 //due to the design, to ensure we get every filter, filters will be inserted multiple times
0191 //eg electron filters will contain photon triggers which are also in the photon filters
0192 //but only want one copy in the vector
0193 //this function is intended to be called once per job so some inefficiency can can be tolerated
0194 //therefore we will use a std::set to ensure that each filtername is only inserted once
0195 //and then convert to a std::vector
0196 void EgHLTOfflineSource::getHLTFilterNamesUsed(std::vector<std::string>& filterNames) const {
0197   std::set<std::string> filterNameSet;
0198   for (auto const& eleHLTFilterName : eleHLTFilterNames_)
0199     filterNameSet.insert(eleHLTFilterName);
0200   for (auto const& phoHLTFilterName : phoHLTFilterNames_)
0201     filterNameSet.insert(phoHLTFilterName);
0202   //here we are little more complicated as entries are of the form "tightTrig:looseTrig"
0203   //so we need to split them first
0204   for (auto const& eleTightLooseTrigName : eleTightLooseTrigNames_) {
0205     std::vector<std::string> trigNames;
0206     boost::split(trigNames, eleTightLooseTrigName, boost::is_any_of(std::string(":")));
0207     if (trigNames.size() != 2)
0208       continue;  //format incorrect
0209     filterNameSet.insert(trigNames[0]);
0210     filterNameSet.insert(trigNames[1]);
0211   }
0212   for (auto const& diEleTightLooseTrigName : diEleTightLooseTrigNames_) {
0213     std::vector<std::string> trigNames;
0214     boost::split(trigNames, diEleTightLooseTrigName, boost::is_any_of(std::string(":")));
0215     if (trigNames.size() != 2)
0216       continue;  //format incorrect
0217     filterNameSet.insert(trigNames[0]);
0218     filterNameSet.insert(trigNames[1]);
0219   }
0220   for (auto const& phoTightLooseTrigName : phoTightLooseTrigNames_) {
0221     std::vector<std::string> trigNames;
0222     boost::split(trigNames, phoTightLooseTrigName, boost::is_any_of(std::string(":")));
0223     if (trigNames.size() != 2)
0224       continue;  //format incorrect
0225     filterNameSet.insert(trigNames[0]);
0226     filterNameSet.insert(trigNames[1]);
0227   }
0228   for (auto const& diPhoTightLooseTrigName : diPhoTightLooseTrigNames_) {
0229     std::vector<std::string> trigNames;
0230     boost::split(trigNames, diPhoTightLooseTrigName, boost::is_any_of(std::string(":")));
0231     if (trigNames.size() != 2)
0232       continue;  //format incorrect
0233     filterNameSet.insert(trigNames[0]);
0234     filterNameSet.insert(trigNames[1]);
0235   }
0236   //right all the triggers are inserted once and only once in the set, convert to vector
0237   //very lazy, create a new vector so can use the constructor and then use swap to transfer
0238   std::vector<std::string>(filterNameSet.begin(), filterNameSet.end()).swap(filterNames);
0239 }
0240 
0241 void EgHLTOfflineSource::filterTriggers(const HLTConfigProvider& hltConfig) {
0242   std::vector<std::string> activeFilters;
0243   std::vector<std::string> activeEleFilters;
0244   std::vector<std::string> activeEle2LegFilters;
0245   std::vector<std::string> activePhoFilters;
0246   std::vector<std::string> activePho2LegFilters;
0247 
0248   trigTools::getActiveFilters(
0249       hltConfig, activeFilters, activeEleFilters, activeEle2LegFilters, activePhoFilters, activePho2LegFilters);
0250 
0251   trigTools::filterInactiveTriggers(eleHLTFilterNames_, activeEleFilters);
0252   trigTools::filterInactiveTriggers(phoHLTFilterNames_, activePhoFilters);
0253   trigTools::filterInactiveTriggers(eleHLTFilterNames2Leg_, activeEle2LegFilters);
0254   trigTools::filterInactiveTightLooseTriggers(eleTightLooseTrigNames_, activeEleFilters);
0255   trigTools::filterInactiveTightLooseTriggers(diEleTightLooseTrigNames_, activeEleFilters);
0256   trigTools::filterInactiveTightLooseTriggers(phoTightLooseTrigNames_, activePhoFilters);
0257   trigTools::filterInactiveTightLooseTriggers(diPhoTightLooseTrigNames_, activePhoFilters);
0258 }