Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-06-11 22:53:47

0001 /** \class HLTHighLevel
0002  *
0003  * See header file for documentation
0004  *
0005  *
0006  *  \author Martin Grunewald
0007  *
0008  */
0009 
0010 #include <vector>
0011 #include <string>
0012 #include <iostream>
0013 #include <iomanip>
0014 
0015 #include "DataFormats/Common/interface/Handle.h"
0016 #include "DataFormats/Common/interface/TriggerResults.h"
0017 #include "DataFormats/Provenance/interface/ModuleDescription.h"
0018 #include "FWCore/Common/interface/TriggerNames.h"
0019 #include "FWCore/Utilities/interface/Exception.h"
0020 #include "FWCore/Utilities/interface/RegexMatch.h"
0021 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0022 #include "FWCore/ServiceRegistry/interface/PathContext.h"
0023 #include "FWCore/ServiceRegistry/interface/PlaceInPathContext.h"
0024 #include "FWCore/ServiceRegistry/interface/ModuleCallingContext.h"
0025 
0026 // needed for trigger bits from EventSetup as in ALCARECO paths
0027 #include "CondFormats/HLTObjects/interface/AlCaRecoTriggerBits.h"
0028 #include "CondFormats/DataRecord/interface/AlCaRecoTriggerBitsRcd.h"
0029 
0030 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0031 #include "HLTHighLevel.h"
0032 
0033 //
0034 // constructors and destructor
0035 //
0036 HLTHighLevel::HLTHighLevel(const edm::ParameterSet& iConfig)
0037     : inputTag_(iConfig.getParameter<edm::InputTag>("TriggerResultsTag")),
0038       inputToken_(consumes<edm::TriggerResults>(inputTag_)),
0039       triggerNamesID_(),
0040       andOr_(iConfig.getParameter<bool>("andOr")),
0041       throw_(iConfig.getParameter<bool>("throw")),
0042       eventSetupPathsKey_(iConfig.getParameter<std::string>("eventSetupPathsKey")),
0043       eventSetupPathsLabel_(iConfig.getParameter<std::string>("eventSetupPathsLabel")),
0044       HLTPatterns_(iConfig.getParameter<std::vector<std::string> >("HLTPaths")),
0045       HLTPathsByName_(),
0046       HLTPathsByIndex_() {
0047   // names and slot numbers are computed during the event loop,
0048   // as they need to access the TriggerNames object via the TriggerResults
0049 
0050   if (!eventSetupPathsKey_.empty()) {
0051     // If paths come from eventsetup, we must watch for IOV changes.
0052     if (!HLTPatterns_.empty()) {
0053       // We do not want double trigger path setting, so throw!
0054       throw cms::Exception("Configuration")
0055           << " HLTHighLevel instance: " << iConfig.getParameter<std::string>("@module_label") << "\n configured with "
0056           << HLTPatterns_.size() << " HLTPaths and\n"
0057           << " eventSetupPathsKey " << eventSetupPathsKey_ << ", choose either of them.";
0058     }
0059     alcaRecotriggerBitsToken_ =
0060         esConsumes<AlCaRecoTriggerBits, AlCaRecoTriggerBitsRcd>(edm::ESInputTag("", eventSetupPathsLabel_));
0061     watchAlCaRecoTriggerBitsRcd_.emplace();
0062   }
0063 }
0064 
0065 //
0066 // member functions
0067 //
0068 
0069 void HLTHighLevel::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0070   edm::ParameterSetDescription desc;
0071   desc.add<edm::InputTag>("TriggerResultsTag", edm::InputTag("TriggerResults", "", "HLT"));
0072   std::vector<std::string> hltPaths(0);
0073   // # provide list of HLT paths (or patterns) you want
0074   desc.add<std::vector<std::string> >("HLTPaths", hltPaths);
0075   // # not empty => use read paths from AlCaRecoTriggerBitsRcd via this key
0076   desc.add<std::string>("eventSetupPathsKey", "");
0077   desc.add<std::string>("eventSetupPathsLabel", "");
0078   // # how to deal with multiple triggers: True (OR) accept if ANY is true, False (AND) accept if ALL are true
0079   desc.add<bool>("andOr", true);
0080   // # throw exception on unknown path names
0081   desc.add<bool>("throw", true);
0082   descriptions.add("hltHighLevel", desc);
0083 }
0084 
0085 // Initialize the internal trigger path representation (names and indices) from the
0086 // patterns specified in the configuration.
0087 // This needs to be called once at startup, whenever the trigger table has changed
0088 // or in case of paths from eventsetup and IOV changed
0089 void HLTHighLevel::init(const edm::TriggerResults& result,
0090                         const edm::Event& event,
0091                         const edm::EventSetup& iSetup,
0092                         const edm::TriggerNames& triggerNames) {
0093   unsigned int n;
0094 
0095   // clean up old data
0096   HLTPathsByName_.clear();
0097   HLTPathsByIndex_.clear();
0098 
0099   // Overwrite paths from EventSetup via AlCaRecoTriggerBitsRcd if configured:
0100   if (!eventSetupPathsKey_.empty()) {
0101     HLTPatterns_ = this->pathsFromSetup(eventSetupPathsKey_, event, iSetup);
0102   }
0103 
0104   if (HLTPatterns_.empty()) {
0105     // for empty input vector, default to all HLT trigger paths
0106     n = result.size();
0107     HLTPathsByName_.resize(n);
0108     HLTPathsByIndex_.resize(n);
0109     for (unsigned int i = 0; i < n; ++i) {
0110       HLTPathsByName_[i] = triggerNames.triggerName(i);
0111       HLTPathsByIndex_[i] = i;
0112     }
0113   } else {
0114     // otherwise, expand wildcards in trigger names...
0115     for (auto const& pattern : HLTPatterns_) {
0116       if (edm::is_glob(pattern)) {
0117         // found a glob pattern, expand it
0118         std::vector<std::vector<std::string>::const_iterator> matches =
0119             edm::regexMatch(triggerNames.triggerNames(), pattern);
0120         if (matches.empty()) {
0121           // pattern does not match any trigger paths
0122           if (throw_)
0123             throw cms::Exception("Configuration")
0124                 << "requested pattern \"" << pattern << "\" does not match any HLT paths";
0125           else
0126             edm::LogInfo("Configuration") << "requested pattern \"" << pattern << "\" does not match any HLT paths";
0127         } else {
0128           // store the matching patterns
0129           for (auto const& match : matches)
0130             HLTPathsByName_.push_back(*match);
0131         }
0132       } else {
0133         // found a trigger name, just copy it
0134         HLTPathsByName_.push_back(pattern);
0135       }
0136     }
0137     n = HLTPathsByName_.size();
0138 
0139     // ...and get hold of trigger indices
0140     bool valid = false;
0141     HLTPathsByIndex_.resize(n);
0142     for (unsigned int i = 0; i < HLTPathsByName_.size(); i++) {
0143       HLTPathsByIndex_[i] = triggerNames.triggerIndex(HLTPathsByName_[i]);
0144       if (HLTPathsByIndex_[i] < result.size()) {
0145         valid = true;
0146       } else {
0147         // trigger path not found
0148         HLTPathsByIndex_[i] = (unsigned int)-1;
0149         if (throw_)
0150           throw cms::Exception("Configuration") << "requested HLT path \"" << HLTPathsByName_[i] << "\" does not exist";
0151         else
0152           edm::LogInfo("Configuration") << "requested HLT path \"" << HLTPathsByName_[i] << "\" does not exist";
0153       }
0154     }
0155 
0156     if (not valid) {
0157       // no point in throwing - if requested, it should have already happened
0158       edm::LogWarning("Configuration")
0159           << "none of the requested paths and pattern match any HLT path - no events will be selected";
0160     }
0161   }
0162 
0163   // report on what is finally used
0164   LogDebug("HLTHighLevel") << "HLT trigger paths: " + inputTag_.encode() << " - Number of paths: " << n
0165                            << " - andOr mode: " << andOr_ << " - throw mode: " << throw_;
0166 
0167   LogTrace("HLTHighLevel") << "The HLT trigger paths (# index name):";
0168   for (unsigned int i = 0; i < n; ++i)
0169     if (HLTPathsByIndex_[i] == (unsigned int)-1)
0170       LogTrace("HLTHighLevel") << "    n/a   " << HLTPathsByName_[i];
0171     else
0172       LogTrace("HLTHighLevel") << "    " << std::setw(4) << HLTPathsByIndex_[i] << "  " << HLTPathsByName_[i];
0173 }
0174 
0175 // ------------ getting paths from EventSetup  ------------
0176 std::vector<std::string> HLTHighLevel::pathsFromSetup(const std::string& key,
0177                                                       const edm::Event& event,
0178                                                       const edm::EventSetup& iSetup) const {
0179   // Get map of strings to concatenated list of names of HLT paths from EventSetup:
0180   const auto& triggerBits = iSetup.getData(alcaRecotriggerBitsToken_);
0181   typedef std::map<std::string, std::string> TriggerMap;
0182   const TriggerMap& triggerMap = triggerBits.m_alcarecoToTrig;
0183 
0184   auto listIter = triggerMap.find(key);
0185   if (listIter == triggerMap.end()) {
0186     throw cms::Exception("Configuration")
0187         << " HLTHighLevel [instance: " << moduleLabel() << " - path: " << pathName(event)
0188         << "]: No triggerList with key " << key << " in AlCaRecoTriggerBitsRcd";
0189   }
0190 
0191   // We must avoid a map<string,vector<string> > in DB for performance reason,
0192   // so the paths are mapped into one string that we have to decompose:
0193   return triggerBits.decompose(listIter->second);
0194 }
0195 
0196 // ------------ method called to produce the data  ------------
0197 bool HLTHighLevel::filter(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0198   using namespace std;
0199   using namespace edm;
0200 
0201   // get hold of TriggerResults Object
0202   Handle<TriggerResults> trh;
0203   iEvent.getByToken(inputToken_, trh);
0204   if (trh.isValid()) {
0205     LogDebug("HLTHighLevel") << "TriggerResults found, number of HLT paths: " << trh->size();
0206   } else {
0207     LogError("HLTHighLevel") << "TriggerResults product " << inputTag_.encode()
0208                              << " not found - returning result=false!";
0209     return false;
0210   }
0211 
0212   // init the TriggerNames with the TriggerResults
0213   const edm::TriggerNames& triggerNames = iEvent.triggerNames(*trh);
0214   bool config_changed = false;
0215   if (triggerNamesID_ != triggerNames.parameterSetID()) {
0216     triggerNamesID_ = triggerNames.parameterSetID();
0217     config_changed = true;
0218   }
0219 
0220   // (re)run the initialization stuff if
0221   // - this is the first event
0222   // - or the HLT table has changed
0223   // - or selected trigger bits come from AlCaRecoTriggerBitsRcd and these changed
0224   if (config_changed or (watchAlCaRecoTriggerBitsRcd_ and watchAlCaRecoTriggerBitsRcd_->check(iSetup))) {
0225     this->init(*trh, iEvent, iSetup, triggerNames);
0226   }
0227   unsigned int n = HLTPathsByName_.size();
0228   unsigned int nbad = 0;
0229   unsigned int fired = 0;
0230 
0231   // count invalid and fired triggers
0232   for (unsigned int i = 0; i < n; i++)
0233     if (HLTPathsByIndex_[i] == (unsigned int)-1)
0234       ++nbad;
0235     else if (trh->accept(HLTPathsByIndex_[i]))
0236       ++fired;
0237 
0238   if ((nbad > 0) and (config_changed or throw_)) {
0239     // only generate the error message if it's actually going to be used
0240     std::string message;
0241 
0242     for (unsigned int i = 0; i < n; i++)
0243       if (HLTPathsByIndex_[i] == (unsigned int)-1)
0244         message += HLTPathsByName_[i] + " ";
0245 
0246     if (config_changed) {
0247       LogTrace("HLTHighLevel") << " HLTHighLevel [instance: " << moduleLabel() << " - path: " << pathName(iEvent)
0248                                << "] configured with " << nbad << "/" << n << " unknown HLT path names: " << message;
0249     }
0250 
0251     if (throw_) {
0252       throw cms::Exception("Configuration")
0253           << " HLTHighLevel [instance: " << moduleLabel() << " - path: " << pathName(iEvent) << "] configured with "
0254           << nbad << "/" << n << " unknown HLT path names: " << message;
0255     }
0256   }
0257 
0258   // Boolean filter result (always at least one trigger)
0259   const bool accept((fired > 0) and (andOr_ or (fired == n - nbad)));
0260   LogDebug("HLTHighLevel") << "Accept = " << std::boolalpha << accept;
0261 
0262   return accept;
0263 }
0264 
0265 std::string const& HLTHighLevel::pathName(const edm::Event& event) const {
0266   return event.moduleCallingContext()->placeInPathContext()->pathContext()->pathName();
0267 }
0268 
0269 std::string const& HLTHighLevel::moduleLabel() const { return moduleDescription().moduleLabel(); }