Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-12-25 01:49:00

0001 #include "DQMOffline/Trigger/interface/HLTTauDQMPath.h"
0002 #include "DQMOffline/Trigger/interface/HLTTauDQMPlotter.h"
0003 
0004 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0005 
0006 #include "HLTrigger/HLTcore/interface/HLTConfigProvider.h"
0007 #include "DataFormats/Common/interface/TriggerResults.h"
0008 #include "DataFormats/HLTReco/interface/TriggerEvent.h"
0009 #include "DataFormats/Math/interface/deltaR.h"
0010 
0011 #include "FWCore/Common/interface/TriggerNames.h"
0012 #include "FWCore/ServiceRegistry/interface/Service.h"
0013 #include "FWCore/Framework/interface/TriggerNamesService.h"
0014 
0015 #include <cstdio>
0016 #include <sstream>
0017 #include <algorithm>
0018 #include <utility>
0019 
0020 namespace {
0021   // Used as a helper only in this file
0022   class HLTPath {
0023   public:
0024     HLTPath(std::string name) : name_(std::move(name)) {}
0025 
0026     using FilterIndex = HLTTauDQMPath::FilterIndex;
0027     typedef std::tuple<typename std::tuple_element<0, FilterIndex>::type,
0028                        typename std::tuple_element<1, FilterIndex>::type,
0029                        typename std::tuple_element<2, FilterIndex>::type,
0030                        bool>
0031         FilterIndexSave;
0032 
0033     constexpr static size_t kName = HLTTauDQMPath::kName;
0034     constexpr static size_t kType = HLTTauDQMPath::kType;
0035     constexpr static size_t kModuleIndex = HLTTauDQMPath::kModuleIndex;
0036     constexpr static size_t kSaveTags = 3;
0037 
0038     std::vector<FilterIndex> interestingFilters(const HLTConfigProvider& HLTCP, bool doRefAnalysis) {
0039       const std::vector<std::string>& moduleLabels = HLTCP.moduleLabels(name_);
0040       std::vector<std::string> leptonTauFilters;
0041       allInterestingFilters_.clear();
0042 
0043       // Ignore all "Selector"s, for ref-analysis keep only those with saveTags=True
0044       // Also record HLT2(Electron|Muon)(PF)?Tau module names
0045       LogTrace("HLTTauDQMOffline") << "Path " << name_
0046                                    << ", list of all filters (preceded by the module index in the path)";
0047       for (auto iLabel = moduleLabels.begin(); iLabel != moduleLabels.end(); ++iLabel) {
0048         if (HLTCP.moduleEDMType(*iLabel) != "EDFilter")
0049           continue;
0050         const std::string type = HLTCP.moduleType(*iLabel);
0051         LogTrace("HLTTauDQMOffline") << "  " << std::distance(moduleLabels.begin(), iLabel) << " " << *iLabel << " "
0052                                      << type << " saveTags " << HLTCP.saveTags(*iLabel);
0053         if (type.find("Selector") != std::string::npos)
0054           continue;
0055         if (type == "HLTTriggerTypeFilter" || type == "HLTBool")
0056           continue;
0057         if (iLabel->find('-') == 0)  // ignore
0058           continue;
0059         if (type == "HLT2PhotonPFTau" || type == "HLT2ElectronPFTau" || type == "HLT2MuonPFTau" ||
0060             type == "HLT2PhotonTau" || type == "HLT2ElectronTau" || type == "HLT2MuonTau")
0061           leptonTauFilters.emplace_back(*iLabel);
0062         //        else if(type.find("Electron") != std::string::npos || type.find("Egamma") != std::string::npos || type.find("Muon") != std::string::npos)
0063         //          continue;
0064         allInterestingFilters_.emplace_back(*iLabel, type, iLabel - moduleLabels.begin(), HLTCP.saveTags(*iLabel));
0065       }
0066 
0067       // Insert the last filters of lepton legs
0068       for (const std::string& leptonTauLabel : leptonTauFilters) {
0069         const edm::ParameterSet& pset = HLTCP.modulePSet(leptonTauLabel);
0070         std::string input1 = pset.getParameter<edm::InputTag>("inputTag1").label();
0071         std::string input2 = pset.getParameter<edm::InputTag>("inputTag2").label();
0072         unsigned idx1 = HLTCP.moduleIndex(name_, input1);
0073         unsigned idx2 = HLTCP.moduleIndex(name_, input2);
0074         std::string type = "dummy";  //HLTCP.moduleType(name_);
0075 
0076         auto func = [&](const FilterIndexSave& a, unsigned idxb) { return std::get<kModuleIndex>(a) < idxb; };
0077 
0078         auto found = std::lower_bound(allInterestingFilters_.begin(), allInterestingFilters_.end(), idx1, func);
0079         if (found == allInterestingFilters_.end() || std::get<kModuleIndex>(*found) != idx1)
0080           allInterestingFilters_.emplace(found, input1, type, idx1, HLTCP.saveTags(input1));
0081         found = std::lower_bound(allInterestingFilters_.begin(), allInterestingFilters_.end(), idx2, func);
0082         if (found == allInterestingFilters_.end() || std::get<kModuleIndex>(*found) != idx2)
0083           allInterestingFilters_.emplace(found, input2, type, idx2, HLTCP.saveTags(input1));
0084       }
0085 
0086       std::vector<FilterIndex> selectedFilters;
0087       // For reference-matched case exclude filters with saveTags=False.
0088       // However, they are needed a bit later to find the position of the
0089       // first L3 tau filter.
0090       for (const auto& item : allInterestingFilters_) {
0091         if (!doRefAnalysis || (doRefAnalysis && std::get<kSaveTags>(item))) {
0092           selectedFilters.emplace_back(std::get<kName>(item), std::get<kType>(item), std::get<kModuleIndex>(item));
0093         }
0094       }
0095 
0096       return selectedFilters;
0097     }
0098 
0099     bool isL3TauProducer(const HLTConfigProvider& HLTCP, const std::string& producerLabel) const {
0100       const std::string type = HLTCP.moduleType(producerLabel);
0101       if (type == "PFRecoTauProducer" || type == "RecoTauPiZeroUnembedder") {
0102         LogDebug("HLTTauDQMOffline") << "Found tau producer " << type << " with label " << producerLabel
0103                                      << " from path " << name_;
0104         return true;
0105       }
0106       return false;
0107     }
0108 
0109     bool isL3ElectronProducer(const HLTConfigProvider& HLTCP, const std::string& producerLabel) const {
0110       const std::string type = HLTCP.moduleType(producerLabel);
0111       if (type == "EgammaHLTPixelMatchElectronProducers") {
0112         LogDebug("HLTTauDQMOffline") << "Found electron producer " << type << " with label " << producerLabel
0113                                      << " from path " << name_;
0114         return true;
0115       }
0116       return false;
0117     }
0118 
0119     bool isL3MuonProducer(const HLTConfigProvider& HLTCP, const std::string& producerLabel) const {
0120       const std::string type = HLTCP.moduleType(producerLabel);
0121       if (type == "L3MuonCandidateProducer" || type == "L3MuonCombinedRelativeIsolationProducer") {
0122         LogDebug("HLTTauDQMOffline") << "Found muon producer " << type << " with label " << producerLabel
0123                                      << " from path " << name_;
0124         return true;
0125       }
0126       return false;
0127     }
0128 
0129     bool isL3TauFilter(const HLTConfigProvider& HLTCP, const std::string& filterLabel) const {
0130       const edm::ParameterSet& pset = HLTCP.modulePSet(filterLabel);
0131       if (pset.exists("inputTag"))
0132         return isL3TauProducer(HLTCP, pset.getParameter<edm::InputTag>("inputTag").label());
0133       if (pset.exists("inputTag1"))
0134         return isL3TauProducer(HLTCP, pset.getParameter<edm::InputTag>("inputTag1").label());
0135       if (pset.exists("inputTag2"))
0136         return isL3TauProducer(HLTCP, pset.getParameter<edm::InputTag>("inputTag2").label());
0137       return false;
0138     }
0139 
0140     bool isL3ElectronFilter(const HLTConfigProvider& HLTCP, const std::string& filterLabel) const {
0141       const edm::ParameterSet& pset = HLTCP.modulePSet(filterLabel);
0142       if (pset.exists("inputTag"))
0143         return isL3ElectronProducer(HLTCP, pset.getParameter<edm::InputTag>("inputTag").label());
0144       if (pset.exists("inputTag1"))
0145         return isL3ElectronProducer(HLTCP, pset.getParameter<edm::InputTag>("inputTag1").label());
0146       if (pset.exists("inputTag2"))
0147         return isL3ElectronProducer(HLTCP, pset.getParameter<edm::InputTag>("inputTag2").label());
0148       return false;
0149     }
0150 
0151     bool isL3MuonFilter(const HLTConfigProvider& HLTCP, const std::string& filterLabel) const {
0152       const edm::ParameterSet& pset = HLTCP.modulePSet(filterLabel);
0153       if (pset.exists("inputTag"))
0154         return isL3MuonProducer(HLTCP, pset.getParameter<edm::InputTag>("inputTag").label());
0155       if (pset.exists("inputTag1"))
0156         return isL3MuonProducer(HLTCP, pset.getParameter<edm::InputTag>("inputTag1").label());
0157       if (pset.exists("inputTag2"))
0158         return isL3MuonProducer(HLTCP, pset.getParameter<edm::InputTag>("inputTag2").label());
0159       return false;
0160     }
0161 
0162     size_t firstL3TauFilterIndex(const HLTConfigProvider& HLTCP) const {
0163       // Loop over filters and check if a filter uses L3 tau producer
0164       // output.
0165       for (const auto& filter : allInterestingFilters_) {
0166         if (isL3TauFilter(HLTCP, std::get<kName>(filter)))
0167           return std::get<kModuleIndex>(filter);
0168       }
0169       return HLTTauDQMPath::kInvalidIndex;
0170     }
0171 
0172     size_t firstL3ElectronFilterIndex(const HLTConfigProvider& HLTCP) const {
0173       // Loop over filters and check if a filter uses L3 tau producer
0174       // output.
0175       for (const auto& filter : allInterestingFilters_) {
0176         if (isL3ElectronFilter(HLTCP, std::get<kName>(filter)))
0177           return std::get<kModuleIndex>(filter);
0178       }
0179       return HLTTauDQMPath::kInvalidIndex;
0180     }
0181 
0182     size_t firstL3MuonFilterIndex(const HLTConfigProvider& HLTCP) const {
0183       // Loop over filters and check if a filter uses L3 tau producer
0184       // output.
0185       for (const auto& filter : allInterestingFilters_) {
0186         if (isL3MuonFilter(HLTCP, std::get<kName>(filter)))
0187           return std::get<kModuleIndex>(filter);
0188       }
0189       return HLTTauDQMPath::kInvalidIndex;
0190     }
0191 
0192     const std::string& name() const { return name_; }
0193 
0194   private:
0195     std::string name_;
0196 
0197     std::vector<FilterIndexSave> allInterestingFilters_;
0198   };
0199 
0200   int getParameterSafe(const HLTConfigProvider& HLTCP,
0201                        const std::string& filterName,
0202                        const std::string& parameterName) {
0203     const edm::ParameterSet& pset = HLTCP.modulePSet(filterName);
0204     if (pset.existsAs<int>(parameterName))
0205       return pset.getParameter<int>(parameterName);
0206     else {
0207       edm::LogWarning("HLTTauDQMOfflineSource") << "No parameter '" << parameterName << "' in configuration of filter "
0208                                                 << filterName << " pset " << pset.dump() << std::endl;
0209       return 0;
0210     }
0211   }
0212 
0213   struct TauLeptonMultiplicity {
0214     TauLeptonMultiplicity() : tau(0), electron(0), muon(0), met(0), level(0) {}
0215     int tau;
0216     int electron;
0217     int muon;
0218     int met;
0219     int level;
0220   };
0221   TauLeptonMultiplicity inferTauLeptonMultiplicity(const HLTConfigProvider& HLTCP,
0222                                                    const std::string& filterName,
0223                                                    const std::string& moduleType,
0224                                                    const std::string& pathName) {
0225     TauLeptonMultiplicity n;
0226     //std::cout << "check menu " << HLTCP.tableName() << std::endl;
0227     if (moduleType == "HLTL1TSeed") {
0228       n.level = 1;
0229       if (filterName.find("Single") != std::string::npos) {
0230         if (filterName.find("Mu") != std::string::npos) {
0231           n.muon = 1;
0232         } else if (filterName.find("EG") != std::string::npos) {
0233           n.electron = 1;
0234         }
0235       } else if (filterName.find("Double") != std::string::npos && filterName.find("Tau") != std::string::npos) {
0236         n.tau = 2;
0237       }
0238       //      else if(filterName.find("Mu") != std::string::npos && filterName.find("Tau") != std::string::npos) {
0239       if (filterName.find("Mu") != std::string::npos) {
0240         n.muon = 1;
0241         //n.tau = 1;
0242       }
0243       if (filterName.find("EG") != std::string::npos && filterName.find("Tau") != std::string::npos) {
0244         n.electron = 1;
0245         //n.tau = 1;
0246       }
0247       if (filterName.find("ETM") != std::string::npos) {
0248         n.met = 1;
0249       }
0250     } else if (moduleType == "HLT1CaloMET") {
0251       n.level = 2;
0252       if (getParameterSafe(HLTCP, filterName, "triggerType") == trigger::TriggerMET) {
0253         n.met = 1;
0254       }
0255     } else if (moduleType == "HLT1CaloJet") {
0256       n.level = 2;
0257       if (getParameterSafe(HLTCP, filterName, "triggerType") == trigger::TriggerTau) {
0258         n.tau = getParameterSafe(HLTCP, filterName, "MinN");
0259       }
0260     } else if (moduleType == "HLT1PFJet") {
0261       n.level = 3;
0262       //const edm::ParameterSet& pset = HLTCP.modulePSet(filterName);
0263       //pset.getParameter<int>("triggerType") == trigger::TriggerTau) {
0264       if (getParameterSafe(HLTCP, filterName, "triggerType") == trigger::TriggerTau) {
0265         //n.tau = pset.getParameter<int>("MinN");
0266         n.tau = getParameterSafe(HLTCP, filterName, "MinN");
0267       }
0268     } else if (moduleType == "HLTCaloJetTag") {
0269       n.level = 2;
0270       //const edm::ParameterSet& pset = HLTCP.modulePSet(filterName);
0271       //if(pset.getParameter<int>("triggerType") == trigger::TriggerTau) {
0272       if (getParameterSafe(HLTCP, filterName, "TriggerType") == trigger::TriggerTau) {
0273         //n.tau = pset.getParameter<int>("MinJets");
0274         n.tau = getParameterSafe(HLTCP, filterName, "MinJets");
0275       }
0276     } else if (moduleType == "HLT1Tau" || moduleType == "HLT1PFTau") {
0277       n.level = 3;
0278       //n.tau = HLTCP.modulePSet(filterName).getParameter<int>("MinN");
0279       n.tau = getParameterSafe(HLTCP, filterName, "MinN");
0280     } else if (moduleType == "HLTPFTauPairDzMatchFilter") {
0281       n.level = 3;
0282       n.tau = 2;
0283     } else if (moduleType == "HLTEgammaGenericFilter") {
0284       n.level = 3;
0285       n.electron = getParameterSafe(HLTCP, filterName, "ncandcut");
0286     } else if (moduleType == "HLTElectronGenericFilter") {
0287       n.level = 3;
0288       //n.electron = HLTCP.modulePSet(filterName).getParameter<int>("ncandcut");
0289       n.electron = getParameterSafe(HLTCP, filterName, "ncandcut");
0290     } else if (moduleType == "HLTMuonL2PreFilter") {
0291       n.level = 2;
0292       //n.muon = HLTCP.modulePSet(filterName).getParameter<int>("MinN");
0293       n.muon = getParameterSafe(HLTCP, filterName, "MinN");
0294     } else if (moduleType == "HLTMuonIsoFilter" || moduleType == "HLTMuonL3PreFilter") {
0295       n.level = 3;
0296       n.muon = getParameterSafe(HLTCP, filterName, "MinN");
0297     } else if (moduleType == "HLTMuonGenericFilter") {
0298       n.level = 3;
0299       n.muon = 1;
0300     } else if (moduleType == "HLT2ElectronTau" || moduleType == "HLT2ElectronPFTau" || moduleType == "HLT2PhotonTau" ||
0301                moduleType == "HLT2PhotonPFTau") {
0302       n.level = 3;
0303       //int num = HLTCP.modulePSet(filterName).getParameter<int>("MinN");
0304       int num = getParameterSafe(HLTCP, filterName, "MinN");
0305       n.tau = num;
0306       n.electron = num;
0307     } else if (moduleType == "HLT2MuonTau" || moduleType == "HLT2MuonPFTau") {
0308       n.level = 3;
0309       //int num = HLTCP.modulePSet(filterName).getParameter<int>("MinN");
0310       int num = getParameterSafe(HLTCP, filterName, "MinN");
0311       n.tau = num;
0312       n.muon = num;
0313     } else if (moduleType == "HLTPrescaler") {  // || moduleType == "HLT1CaloMET") {
0314       // ignore
0315     } else {
0316       edm::LogInfo("HLTTauDQMOfflineSource")
0317           << "HLTTauDQMPath.cc, inferTauLeptonMultiplicity(): module type '" << moduleType
0318           << "' not recognized, filter '" << filterName << "' in path '" << pathName
0319           << "' will be ignored for offline matching." << std::endl;
0320     }
0321     return n;
0322   }
0323 
0324   template <typename T1, typename T2>
0325   bool deltaRmatch(const T1& obj,
0326                    const std::vector<T2>& refColl,
0327                    double dR,
0328                    std::vector<bool>& refMask,
0329                    std::vector<T2>& matchedRefs) {
0330     double minDr = 2 * dR;
0331     size_t found = refColl.size();
0332     //std::cout << "Matching with DR " << dR << ", obj eta " << obj.eta() << " phi " << obj.phi() << std::endl;
0333     for (size_t i = 0; i < refColl.size(); ++i) {
0334       if (!refMask[i])
0335         continue;
0336 
0337       double dr = reco::deltaR(obj, refColl[i]);
0338       //std::cout << "  " << i << " ref eta " << refColl[i].eta() << " phi " << refColl[i].phi() << " dr " << dr << std::endl;
0339       if (dr < minDr) {
0340         minDr = dr;
0341         found = i;
0342       }
0343     }
0344     if (found < refColl.size()) {
0345       matchedRefs.emplace_back(refColl[found]);
0346       refMask[found] = false;
0347       return true;
0348     }
0349     return false;
0350   }
0351 }  // namespace
0352 
0353 HLTTauDQMPath::HLTTauDQMPath(std::string pathName,
0354                              std::string hltProcess,
0355                              bool doRefAnalysis,
0356                              const HLTConfigProvider& HLTCP)
0357     : hltProcess_(std::move(hltProcess)),
0358       doRefAnalysis_(doRefAnalysis),
0359       pathName_(std::move(pathName)),
0360       pathIndex_(HLTCP.triggerIndex(pathName_)),
0361       lastFilterBeforeL2TauIndex_(0),
0362       lastL2TauFilterIndex_(0),
0363       lastFilterBeforeL3TauIndex_(0),
0364       lastL3TauFilterIndex_(0),
0365       lastFilterBeforeL2ElectronIndex_(0),
0366       lastL2ElectronFilterIndex_(0),
0367       lastFilterBeforeL2MuonIndex_(0),
0368       lastL2MuonFilterIndex_(0),
0369       lastFilterBeforeL2METIndex_(0),
0370       lastL2METFilterIndex_(0),
0371       firstFilterBeforeL2METIndex_(0),
0372       firstL2METFilterIndex_(0),
0373 
0374       isFirstL1Seed_(false),
0375       isValid_(false) {
0376 #ifdef EDM_ML_DEBUG
0377   std::stringstream ss;
0378   ss << "HLTTauDQMPath: " << pathName_ << "\n";
0379 #endif
0380   // Get the filters
0381   HLTPath thePath(pathName_);
0382   filterIndices_ = thePath.interestingFilters(HLTCP, doRefAnalysis_);
0383   if (filterIndices_.empty()) {
0384     edm::LogInfo("HLTTauDQMOffline") << "HLTTauDQMPath: " << pathName_ << " no interesting filters found";
0385     return;
0386   }
0387   isFirstL1Seed_ = HLTCP.moduleType(std::get<kName>(filterIndices_[0])) == "HLTL1TSeed";
0388 #ifdef EDM_ML_DEBUG
0389   ss << "  Interesting filters (preceded by the module index in the path)";
0390 #endif
0391   // Set the filter multiplicity counts
0392   filterTauN_.clear();
0393   filterElectronN_.clear();
0394   filterMuonN_.clear();
0395   filterMET_.clear();
0396   filterTauN_.reserve(filterIndices_.size());
0397   filterElectronN_.reserve(filterIndices_.size());
0398   filterMuonN_.reserve(filterIndices_.size());
0399   filterMET_.reserve(filterIndices_.size());
0400   filterLevel_.reserve(filterIndices_.size());
0401 #ifdef EDM_ML_DEBUG
0402   size_t i(0);
0403 #endif
0404   for (auto& filterIndice : filterIndices_) {
0405     const std::string& filterName = std::get<kName>(filterIndice);
0406     const std::string& moduleType = HLTCP.moduleType(filterName);
0407 
0408     TauLeptonMultiplicity n = inferTauLeptonMultiplicity(HLTCP, filterName, moduleType, pathName_);
0409     filterTauN_.push_back(n.tau);
0410     filterElectronN_.push_back(n.electron);
0411     filterMuonN_.push_back(n.muon);
0412     filterMET_.push_back(n.met);
0413     filterLevel_.push_back(n.level);
0414 
0415 #ifdef EDM_ML_DEBUG
0416     ss << "\n    " << i << " " << std::get<kModuleIndex>(filterIndice) << " " << filterName << " " << moduleType
0417        << " ntau " << n.tau << " nele " << n.electron << " nmu " << n.muon;
0418     i++;
0419 #endif
0420   }
0421 #ifdef EDM_ML_DEBUG
0422   LogDebug("HLTTauDQMOffline") << ss.str();
0423 #endif
0424 
0425   // Find the position of tau producer, use filters with taus before
0426   // it for L2 tau efficiency, and filters with taus after it for L3
0427   // tau efficiency. Here we have to take into account that for
0428   // reference-matched case filterIndices_ contains only those filters
0429   // that have saveTags=True, while for searching the first L3 tau
0430   // filter we have to consider all filters
0431   const size_t firstL3TauFilterIndex = thePath.firstL3TauFilterIndex(HLTCP);
0432   if (firstL3TauFilterIndex == kInvalidIndex) {
0433     edm::LogInfo("HLTTauDQMOffline") << "Did not find a filter with L3 tau producer as input in path " << pathName_;
0434   }
0435   const size_t firstL3ElectronFilterIndex = thePath.firstL3ElectronFilterIndex(HLTCP);
0436   if (firstL3ElectronFilterIndex == kInvalidIndex) {
0437     edm::LogInfo("HLTTauDQMOffline") << "Did not find a filter with L3 electron producer as input in path "
0438                                      << pathName_;
0439   }
0440   const size_t firstL3MuonFilterIndex = thePath.firstL3MuonFilterIndex(HLTCP);
0441   if (firstL3MuonFilterIndex == kInvalidIndex) {
0442     edm::LogInfo("HLTTauDQMOffline") << "Did not find a filter with L3 muon producer as input in path " << pathName_;
0443   }
0444 
0445   lastFilterBeforeL2TauIndex_ = 0;
0446   lastL2TauFilterIndex_ = kInvalidIndex;
0447   lastFilterBeforeL3TauIndex_ = 0;
0448   lastL3TauFilterIndex_ = kInvalidIndex;
0449   lastFilterBeforeL2ElectronIndex_ = 0;
0450   lastL2ElectronFilterIndex_ = kInvalidIndex;
0451   lastFilterBeforeL3ElectronIndex_ = 0;
0452   lastL3ElectronFilterIndex_ = kInvalidIndex;
0453   lastFilterBeforeL2MuonIndex_ = 0;
0454   lastL2MuonFilterIndex_ = kInvalidIndex;
0455   lastFilterBeforeL3MuonIndex_ = 0;
0456   lastL3MuonFilterIndex_ = kInvalidIndex;
0457   lastFilterBeforeL2METIndex_ = 0;
0458   lastL2METFilterIndex_ = kInvalidIndex;
0459   firstFilterBeforeL2METIndex_ = 0;
0460   firstL2METFilterIndex_ = kInvalidIndex;
0461   /*
0462   size_t i = 0;
0463   for(; i<filtersSize() && getFilterIndex(i) < firstL3TauFilterIndex; ++i) {
0464     if(lastL2TauFilterIndex_ == kInvalidIndex && getFilterNTaus(i) == 0)
0465       lastFilterBeforeL2TauIndex_ = i;
0466     if(getFilterNTaus(i) > 0 && getFilterNElectrons(i) == 0 && getFilterNMuons(i) == 0)
0467       lastL2TauFilterIndex_ = i;
0468   }
0469   lastFilterBeforeL3TauIndex_ = i-1;
0470   for(; i<filtersSize(); ++i) {
0471     if(lastL3TauFilterIndex_ == kInvalidIndex && getFilterNTaus(i) == 0)
0472       lastFilterBeforeL3TauIndex_ = i;
0473     if(getFilterNTaus(i) > 0 && getFilterNElectrons(i) == 0 && getFilterNMuons(i) == 0)
0474       lastL3TauFilterIndex_ = i;
0475   }
0476 */
0477   for (size_t i = 0; i < filtersSize(); ++i) {
0478     // Tau
0479     if (getFilterLevel(i) == 2 && getFilterNTaus(i) > 0 && getFilterNElectrons(i) == 0 && getFilterNMuons(i) == 0)
0480       lastL2TauFilterIndex_ = i;
0481     if (lastL2TauFilterIndex_ == kInvalidIndex)
0482       lastFilterBeforeL2TauIndex_ = i;
0483 
0484     //    if(lastFilterBeforeL3TauIndex_ < 2 && lastL3TauFilterIndex_ == kInvalidIndex && getFilterNTaus(i) == 0)
0485     //      lastFilterBeforeL3TauIndex_ = i;
0486     if (getFilterLevel(i) == 3 && getFilterNTaus(i) > 0 && getFilterNElectrons(i) == 0 && getFilterNMuons(i) == 0)
0487       lastL3TauFilterIndex_ = i;
0488     if (lastL3TauFilterIndex_ == kInvalidIndex)
0489       lastFilterBeforeL3TauIndex_ = i;
0490 
0491     // Electron
0492     if (lastL2ElectronFilterIndex_ == kInvalidIndex && getFilterNElectrons(i) == 0)
0493       lastFilterBeforeL2ElectronIndex_ = i;
0494     if (getFilterLevel(i) == 2 && getFilterNElectrons(i) > 0 && getFilterNTaus(i) == 0 && getFilterNMuons(i) == 0)
0495       lastL2ElectronFilterIndex_ = i;
0496 
0497     if (getFilterLevel(i) == 3 && getFilterNElectrons(i) > 0 && getFilterNTaus(i) == 0 && getFilterNMuons(i) == 0)
0498       lastL3ElectronFilterIndex_ = i;
0499     if (lastL3ElectronFilterIndex_ == kInvalidIndex)
0500       lastFilterBeforeL3ElectronIndex_ = i;
0501     /*
0502     if(lastL2ElectronFilterIndex_ == kInvalidIndex && getFilterNElectrons(i) == 0)
0503       lastFilterBeforeL2ElectronIndex_ = i;
0504     if(getFilterNElectrons(i) > 0 && getFilterNTaus(i) == 0 && getFilterNMuons(i) == 0)
0505       lastL2ElectronFilterIndex_ = i;
0506     
0507     if(lastFilterBeforeL3ElectronIndex_ == 0 && lastL3ElectronFilterIndex_ == kInvalidIndex && getFilterNElectrons(i) == 0)
0508       lastFilterBeforeL3ElectronIndex_ = i;
0509     if(getFilterNElectrons(i) > 0 && getFilterNTaus(i) == 0 && getFilterNMuons(i) == 0)
0510       lastL3ElectronFilterIndex_ = i;
0511 */
0512     // Muon
0513     if (lastL2MuonFilterIndex_ == kInvalidIndex && getFilterNMuons(i) == 0)
0514       lastFilterBeforeL2MuonIndex_ = i;
0515     if (getFilterLevel(i) == 2 && getFilterNMuons(i) > 0 && getFilterNTaus(i) == 0 && getFilterNElectrons(i) == 0)
0516       lastL2MuonFilterIndex_ = i;
0517 
0518     if (getFilterLevel(i) == 3 && getFilterNMuons(i) > 0 && getFilterNTaus(i) == 0 && getFilterNElectrons(i) == 0)
0519       lastL3MuonFilterIndex_ = i;
0520     if (lastL3MuonFilterIndex_ == kInvalidIndex)
0521       lastFilterBeforeL3MuonIndex_ = i;
0522 
0523     // MET
0524     if (lastL2METFilterIndex_ == kInvalidIndex && getFilterMET(i) == 0)
0525       lastFilterBeforeL2METIndex_ = i;
0526     if (getFilterMET(i) > 0 && getFilterNElectrons(i) == 0 && getFilterNMuons(i) == 0)
0527       lastL2METFilterIndex_ = i;
0528 
0529     if (firstL2METFilterIndex_ == kInvalidIndex && getFilterMET(i) == 0)
0530       firstFilterBeforeL2METIndex_ = i;
0531     if (firstL2METFilterIndex_ == kInvalidIndex && getFilterMET(i) > 0 && getFilterNElectrons(i) == 0 &&
0532         getFilterNMuons(i) == 0)
0533       firstL2METFilterIndex_ = i;
0534   }
0535   //  lastFilterBeforeL3TauIndex_      = firstL3TauFilterIndex - 1;
0536   // lastFilterBeforeL3ElectronIndex_ = firstL3ElectronFilterIndex - 1;
0537   //  lastFilterBeforeL3MuonIndex_     = firstL3MuonFilterIndex - 1;
0538   LogDebug("HLTTauDQMOffline") << "lastFilterBeforeL2 " << lastFilterBeforeL2TauIndex_ << " lastL2TauFilter "
0539                                << lastL2TauFilterIndex_ << " lastFilterBeforeL3 " << lastFilterBeforeL3TauIndex_
0540                                << " lastL3TauFilter " << lastL3TauFilterIndex_;
0541   isValid_ = true;
0542 }
0543 
0544 HLTTauDQMPath::~HLTTauDQMPath() = default;
0545 
0546 bool HLTTauDQMPath::fired(const edm::TriggerResults& triggerResults) const { return triggerResults.accept(pathIndex_); }
0547 
0548 int HLTTauDQMPath::lastPassedFilter(const edm::TriggerResults& triggerResults) const {
0549   if (fired(triggerResults)) {
0550     //std::cout << "Event passed" << std::endl;
0551     return filterIndices_.size() - 1;
0552   }
0553 
0554   unsigned int firstFailedFilter = triggerResults.index(pathIndex_);
0555   int lastPassedFilter = -1;
0556   for (size_t i = 0; i < filterIndices_.size(); ++i) {
0557     if (std::get<kModuleIndex>(filterIndices_[i]) < firstFailedFilter) {
0558       lastPassedFilter = i;
0559     } else {
0560       //std::cout << "Decision-making filter " << firstFailedFilter << " this " << std::get<kModuleIndex>(filterIndices_[i]) << std::endl;
0561       break;
0562     }
0563   }
0564   return lastPassedFilter;
0565 }
0566 
0567 void HLTTauDQMPath::getFilterObjects(const trigger::TriggerEvent& triggerEvent,
0568                                      size_t i,
0569                                      std::vector<Object>& retval) const {
0570   trigger::size_type filterIndex = triggerEvent.filterIndex(edm::InputTag(getFilterName(i), "", hltProcess_));
0571   if (filterIndex != triggerEvent.sizeFilters()) {
0572     const trigger::Keys& keys = triggerEvent.filterKeys(filterIndex);
0573     const trigger::Vids& ids = triggerEvent.filterIds(filterIndex);
0574     const trigger::TriggerObjectCollection& triggerObjects = triggerEvent.getObjects();
0575     for (size_t i = 0; i < keys.size(); ++i) {
0576       const trigger::TriggerObject& object = triggerObjects[keys[i]];
0577       retval.emplace_back(Object{object, ids[i]});
0578     }
0579   }
0580 }
0581 
0582 bool HLTTauDQMPath::offlineMatching(size_t i,
0583                                     const std::vector<Object>& triggerObjects,
0584                                     const HLTTauDQMOfflineObjects& offlineObjects,
0585                                     double dR,
0586                                     std::vector<Object>& matchedTriggerObjects,
0587                                     HLTTauDQMOfflineObjects& matchedOfflineObjects) const {
0588   bool isL1 = (i == 0 && isFirstL1Seed_);
0589   std::vector<bool> offlineMask;
0590   if (filterTauN_[i] > 0) {
0591     int matchedObjects = 0;
0592     offlineMask.resize(offlineObjects.taus.size());
0593     std::fill(offlineMask.begin(), offlineMask.end(), true);
0594     for (const Object& trgObj : triggerObjects) {
0595       //std::cout << "trigger object id " << isL1 << " " << trgObj.id << " " << trigger::TriggerL1Tau << " "<< trigger::TriggerTau << std::endl;
0596       if (!((isL1 && trgObj.id == trigger::TriggerL1Tau) || trgObj.id == trigger::TriggerTau))
0597         continue;
0598       if (deltaRmatch(trgObj.object, offlineObjects.taus, dR, offlineMask, matchedOfflineObjects.taus)) {
0599         ++matchedObjects;
0600         matchedTriggerObjects.emplace_back(trgObj);
0601         //std::cout << "trigger object DR match" << std::endl;
0602       }
0603     }
0604     if (matchedObjects < filterTauN_[i])
0605       return false;
0606   }
0607   if (filterElectronN_[i] > 0) {
0608     int matchedObjects = 0;
0609     offlineMask.resize(offlineObjects.electrons.size());
0610     std::fill(offlineMask.begin(), offlineMask.end(), true);
0611     for (const Object& trgObj : triggerObjects) {
0612       //std::cout << "trigger object id " << trgObj.id << std::endl;
0613       if (!((isL1 && (trgObj.id == trigger::TriggerL1EG)) || trgObj.id == trigger::TriggerElectron ||
0614             trgObj.id == trigger::TriggerPhoton))
0615         continue;
0616       if (deltaRmatch(trgObj.object, offlineObjects.electrons, dR, offlineMask, matchedOfflineObjects.electrons)) {
0617         ++matchedObjects;
0618         matchedTriggerObjects.emplace_back(trgObj);
0619       }
0620     }
0621     if (matchedObjects < filterElectronN_[i])
0622       return false;
0623   }
0624   if (filterMuonN_[i] > 0) {
0625     int matchedObjects = 0;
0626     offlineMask.resize(offlineObjects.muons.size());
0627     std::fill(offlineMask.begin(), offlineMask.end(), true);
0628     for (const Object& trgObj : triggerObjects) {
0629       //std::cout << "trigger object id " << trgObj.id << std::endl;
0630       if (!((isL1 && trgObj.id == trigger::TriggerL1Mu) || trgObj.id == trigger::TriggerMuon))
0631         continue;
0632       if (deltaRmatch(trgObj.object, offlineObjects.muons, dR, offlineMask, matchedOfflineObjects.muons)) {
0633         ++matchedObjects;
0634         matchedTriggerObjects.emplace_back(trgObj);
0635       }
0636     }
0637     if (matchedObjects < filterMuonN_[i])
0638       return false;
0639   }
0640   if (filterMET_[i] > 0) {
0641     int matchedObjects = 0;
0642     offlineMask.resize(offlineObjects.met.size());
0643     std::fill(offlineMask.begin(), offlineMask.end(), true);
0644     for (const Object& trgObj : triggerObjects) {
0645       if (!((isL1 && (trgObj.id == trigger::TriggerL1ETM || trgObj.id == trigger::TriggerL1ETMHF)) ||
0646             trgObj.id == trigger::TriggerMET))
0647         continue;
0648       ++matchedObjects;
0649       matchedTriggerObjects.emplace_back(trgObj);
0650     }
0651     if (matchedObjects < filterMET_[i]) {
0652       return false;
0653     }
0654   }
0655 
0656   // Sort offline objects by pt
0657   std::sort(matchedOfflineObjects.taus.begin(), matchedOfflineObjects.taus.end(), [](const LV& a, const LV& b) {
0658     return a.pt() > b.pt();
0659   });
0660   std::sort(matchedOfflineObjects.electrons.begin(),
0661             matchedOfflineObjects.electrons.end(),
0662             [](const LV& a, const LV& b) { return a.pt() > b.pt(); });
0663   std::sort(matchedOfflineObjects.muons.begin(), matchedOfflineObjects.muons.end(), [](const LV& a, const LV& b) {
0664     return a.pt() > b.pt();
0665   });
0666   matchedOfflineObjects.met = offlineObjects.met;
0667   return true;
0668 }
0669 
0670 bool HLTTauDQMPath::goodOfflineEvent(size_t i, const HLTTauDQMOfflineObjects& offlineObjects) const {
0671   return (static_cast<size_t>(getFilterNTaus(i)) <= offlineObjects.taus.size() &&
0672           static_cast<size_t>(getFilterNElectrons(i)) <= offlineObjects.electrons.size() &&
0673           static_cast<size_t>(getFilterNMuons(i)) <= offlineObjects.muons.size());
0674 }