CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_4/src/HLTrigger/HLTfilters/src/HLTHighLevel.cc

Go to the documentation of this file.
00001 
00012 #include <vector>
00013 #include <string>
00014 #include <iostream>
00015 #include <iomanip>
00016 #include <boost/foreach.hpp>
00017 
00018 #include "DataFormats/Common/interface/Handle.h"
00019 #include "DataFormats/Common/interface/TriggerResults.h"
00020 #include "FWCore/Common/interface/TriggerNames.h"
00021 #include "FWCore/Framework/interface/ESHandle.h"
00022 #include "FWCore/Utilities/interface/Exception.h"
00023 #include "FWCore/Utilities/interface/RegexMatch.h"
00024 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00025 
00026 // needed for trigger bits from EventSetup as in ALCARECO paths
00027 #include "CondFormats/HLTObjects/interface/AlCaRecoTriggerBits.h"
00028 #include "CondFormats/DataRecord/interface/AlCaRecoTriggerBitsRcd.h"
00029 
00030 
00031 #include "HLTrigger/HLTfilters/interface/HLTHighLevel.h"
00032 
00033 //
00034 // constructors and destructor
00035 //
00036 HLTHighLevel::HLTHighLevel(const edm::ParameterSet& iConfig) :
00037   inputTag_     (iConfig.getParameter<edm::InputTag> ("TriggerResultsTag")),
00038   triggerNamesID_ (),
00039   andOr_        (iConfig.getParameter<bool> ("andOr")),
00040   throw_        (iConfig.getParameter<bool> ("throw")),
00041   eventSetupPathsKey_(iConfig.getParameter<std::string>("eventSetupPathsKey")),
00042   watchAlCaRecoTriggerBitsRcd_(0),
00043   HLTPatterns_  (iConfig.getParameter<std::vector<std::string> >("HLTPaths")),
00044   HLTPathsByName_(),
00045   HLTPathsByIndex_()
00046 {
00047   // names and slot numbers are computed during the event loop, 
00048   // as they need to access the TriggerNames object via the TriggerResults
00049 
00050   if (eventSetupPathsKey_.size()) {
00051     // If paths come from eventsetup, we must watch for IOV changes.
00052     if (!HLTPatterns_.empty()) {
00053       // We do not want double trigger path setting, so throw!
00054       throw cms::Exception("Configuration")
00055         << " HLTHighLevel instance: "<< iConfig.getParameter<std::string>("@module_label")
00056         << "\n configured with " << HLTPatterns_.size() << " HLTPaths and\n"
00057         << " eventSetupPathsKey " << eventSetupPathsKey_ << ", choose either of them.";
00058     }
00059     watchAlCaRecoTriggerBitsRcd_ = new edm::ESWatcher<AlCaRecoTriggerBitsRcd>;
00060   }
00061 }
00062 
00063 HLTHighLevel::~HLTHighLevel()
00064 {
00065   delete watchAlCaRecoTriggerBitsRcd_; // safe on null pointer...
00066 }
00067 
00068 //
00069 // member functions
00070 //
00071 
00072 // Initialize the internal trigger path representation (names and indices) from the 
00073 // patterns specified in the configuration.
00074 // This needs to be called once at startup, whenever the trigger table has changed
00075 // or in case of paths from eventsetup and IOV changed
00076 void HLTHighLevel::init(const edm::TriggerResults & result,
00077                         const edm::EventSetup& iSetup,
00078                         const edm::TriggerNames & triggerNames )
00079 {
00080   unsigned int n;
00081 
00082   // clean up old data
00083   HLTPathsByName_.clear();
00084   HLTPathsByIndex_.clear();
00085 
00086   // Overwrite paths from EventSetup via AlCaRecoTriggerBitsRcd if configured:
00087   if (eventSetupPathsKey_.size()) {
00088     HLTPatterns_ = this->pathsFromSetup(eventSetupPathsKey_, iSetup);
00089   }
00090 
00091   if (HLTPatterns_.empty()) {
00092     // for empty input vector, default to all HLT trigger paths
00093     n = result.size();
00094     HLTPathsByName_.resize(n);
00095     HLTPathsByIndex_.resize(n);
00096     for (unsigned int i = 0; i < n; ++i) {
00097       HLTPathsByName_[i] = triggerNames.triggerName(i);
00098       HLTPathsByIndex_[i] = i;
00099     }
00100   } else {
00101     // otherwise, expand wildcards in trigger names...
00102     BOOST_FOREACH(const std::string & pattern, HLTPatterns_) {
00103       if (edm::is_glob(pattern)) {
00104         // found a glob pattern, expand it
00105         std::vector< std::vector<std::string>::const_iterator > matches = edm::regexMatch(triggerNames.triggerNames(), pattern);
00106         if (matches.empty()) {
00107           // pattern does not match any trigger paths
00108           if (throw_)
00109             throw cms::Exception("Configuration") << "requested pattern \"" << pattern <<  "\" does not match any HLT paths";
00110           else
00111             edm::LogInfo("Configuration") << "requested pattern \"" << pattern <<  "\" does not match any HLT paths";
00112         } else {
00113           // store the matching patterns
00114           BOOST_FOREACH(std::vector<std::string>::const_iterator match, matches)
00115             HLTPathsByName_.push_back(*match);
00116         }
00117       } else {
00118         // found a trigger name, just copy it
00119         HLTPathsByName_.push_back(pattern);
00120       }
00121     }
00122     n = HLTPathsByName_.size();
00123 
00124     // ...and get hold of trigger indices
00125     bool valid = false;
00126     HLTPathsByIndex_.resize(n);
00127     for (unsigned int i = 0; i < HLTPathsByName_.size(); i++) {
00128       HLTPathsByIndex_[i] = triggerNames.triggerIndex(HLTPathsByName_[i]);
00129       if (HLTPathsByIndex_[i] < result.size()) {
00130         valid = true;
00131       } else {
00132         // trigger path not found
00133         HLTPathsByIndex_[i] = (unsigned int) -1;
00134         if (throw_)
00135           throw cms::Exception("Configuration") << "requested HLT path \"" << HLTPathsByName_[i] << "\" does not exist";
00136         else
00137           edm::LogInfo("Configuration") << "requested HLT path \"" << HLTPathsByName_[i] << "\" does not exist";
00138       }
00139     }
00140     
00141     if (not valid) {
00142       // no point in throwing - if requested, it should have already happened
00143       edm::LogWarning("Configuration") << "none of the requested paths and pattern match any HLT path - no events will be selected";
00144     }
00145     
00146   }
00147 
00148   // report on what is finally used
00149   LogDebug("HLTHighLevel") << "HLT trigger paths: " + inputTag_.encode()
00150     << " - Number of paths: " << n
00151     << " - andOr mode: " << andOr_
00152     << " - throw mode: " << throw_;
00153 
00154   LogTrace("HLTHighLevel") << "The HLT trigger paths (# index name):";
00155   for (unsigned int i = 0; i < n; ++i)
00156     if (HLTPathsByIndex_[i] == (unsigned int) -1)
00157       LogTrace("HLTHighLevel") << "    n/a   " << HLTPathsByName_[i];
00158     else
00159       LogTrace("HLTHighLevel") << "    " << std::setw(4) << HLTPathsByIndex_[i] << "  " << HLTPathsByName_[i];
00160 
00161 }
00162 
00163 // ------------ getting paths from EventSetup  ------------
00164 std::vector<std::string>
00165 HLTHighLevel::pathsFromSetup(const std::string &key, const edm::EventSetup &iSetup) const
00166 {
00167   // Get map of strings to concatenated list of names of HLT paths from EventSetup:
00168   edm::ESHandle<AlCaRecoTriggerBits> triggerBits;
00169   iSetup.get<AlCaRecoTriggerBitsRcd>().get(triggerBits);
00170   typedef std::map<std::string, std::string> TriggerMap;
00171   const TriggerMap &triggerMap = triggerBits->m_alcarecoToTrig;
00172 
00173   TriggerMap::const_iterator listIter = triggerMap.find(key);
00174   if (listIter == triggerMap.end()) {
00175     throw cms::Exception("Configuration")
00176       << " HLTHighLevel [instance: " << moduleLabel() << " - path: " << pathName()
00177       << "]: No triggerList with key " << key << " in AlCaRecoTriggerBitsRcd";
00178   }
00179 
00180   // We must avoid a map<string,vector<string> > in DB for performance reason,
00181   // so the paths are mapped into one string that we have to decompose:
00182   return triggerBits->decompose(listIter->second);
00183 }
00184 
00185 // ------------ method called to produce the data  ------------
00186   bool
00187 HLTHighLevel::filter(edm::Event& iEvent, const edm::EventSetup& iSetup)
00188 {
00189   using namespace std;
00190   using namespace edm;
00191 
00192   // get hold of TriggerResults Object
00193   Handle<TriggerResults> trh;
00194   iEvent.getByLabel(inputTag_, trh);
00195   if (trh.isValid()) {
00196     LogDebug("HLTHighLevel") << "TriggerResults found, number of HLT paths: " << trh->size();
00197   } else {
00198     LogError("HLTHighLevel") << "TriggerResults product " << inputTag_.encode() << " not found - returning result=false!";
00199     return false;
00200   }
00201 
00202   // init the TriggerNames with the TriggerResults
00203   const edm::TriggerNames & triggerNames = iEvent.triggerNames(*trh);
00204   bool config_changed = false;
00205   if (triggerNamesID_ != triggerNames.parameterSetID()) {
00206     triggerNamesID_ = triggerNames.parameterSetID();
00207     config_changed = true;
00208   }
00209 
00210   // (re)run the initialization stuff if 
00211   // - this is the first event 
00212   // - or the HLT table has changed 
00213   // - or selected trigger bits come from AlCaRecoTriggerBitsRcd and these changed
00214   if (config_changed or (watchAlCaRecoTriggerBitsRcd_ and watchAlCaRecoTriggerBitsRcd_->check(iSetup))) {
00215     this->init(*trh, iSetup, triggerNames);  
00216   }
00217   unsigned int n     = HLTPathsByName_.size();
00218   unsigned int nbad  = 0;
00219   unsigned int fired = 0;
00220 
00221   // count invalid and fired triggers
00222   for (unsigned int i = 0; i < n; i++)
00223     if (HLTPathsByIndex_[i] == (unsigned int) -1)
00224       ++nbad;
00225     else if (trh->accept(HLTPathsByIndex_[i]))
00226       ++fired;
00227 
00228   if ((nbad > 0) and (config_changed or throw_)) {
00229     // only generate the error message if it's actually going to be used
00230     std::string message;
00231 
00232     for (unsigned int i = 0; i < n; i++)
00233       if (HLTPathsByIndex_[i] == (unsigned int) -1)
00234         message += HLTPathsByName_[i] + " ";
00235 
00236     if (config_changed) {
00237       LogTrace("HLTHighLevel")
00238         << " HLTHighLevel [instance: " << moduleLabel()
00239         << " - path: " << pathName()
00240         << "] configured with " << nbad
00241         << "/" << n
00242         << " unknown HLT path names: " << message;
00243     }
00244 
00245     if (throw_) {
00246       throw cms::Exception("Configuration")
00247         << " HLTHighLevel [instance: " << moduleLabel()
00248         << " - path: " << pathName()
00249         << "] configured with " << nbad
00250         << "/" << n
00251         << " unknown HLT path names: " << message;
00252     }
00253   }
00254 
00255   // Boolean filter result (always at least one trigger)
00256   const bool accept( (fired > 0) and ( andOr_ or (fired == n-nbad) ) );
00257   LogDebug("HLTHighLevel") << "Accept = " << std::boolalpha << accept;
00258 
00259   return accept;
00260 }
00261 
00262 
00263 std::string const & HLTHighLevel::pathName() const {
00264   return * currentContext()->pathName();
00265 }
00266 
00267 std::string const & HLTHighLevel::moduleLabel() const {
00268   return * currentContext()->moduleLabel();
00269 }