Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-09 22:33:52

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