00001
00012 #include <vector>
00013 #include <string>
00014 #include <iostream>
00015 #include <iomanip>
00016 #include <boost/foreach.hpp>
00017 #include <boost/regex.hpp>
00018 #include <boost/algorithm/string.hpp>
00019
00020 #include "DataFormats/Common/interface/Handle.h"
00021 #include "DataFormats/Common/interface/TriggerResults.h"
00022 #include "FWCore/Utilities/interface/Exception.h"
00023 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00024
00025 #include "HLTrigger/HLTfilters/interface/HLTHighLevel.h"
00026
00027
00028 bool is_glob(const std::string & pattern);
00029
00030 std::string glob2reg(const std::string & pattern);
00031
00032 std::vector< std::vector<std::string>::const_iterator >
00033 matching_triggers(const std::vector<std::string> & triggers, const std::string & pattern);
00034
00035
00036
00037
00038 HLTHighLevel::HLTHighLevel(const edm::ParameterSet& iConfig) :
00039 inputTag_ (iConfig.getParameter<edm::InputTag> ("TriggerResultsTag")),
00040 triggerNames_ (),
00041 andOr_ (iConfig.getParameter<bool> ("andOr")),
00042 throw_ (iConfig.getUntrackedParameter<bool> ("throw", true)),
00043 HLTPatterns_ (iConfig.getParameter<std::vector<std::string> >("HLTPaths")),
00044 HLTPathsByName_(),
00045 HLTPathsByIndex_()
00046 {
00047
00048
00049 }
00050
00051 HLTHighLevel::~HLTHighLevel()
00052 {
00053 }
00054
00055
00056
00057
00058
00059
00060
00061
00062 void HLTHighLevel::init(const edm::TriggerResults & result)
00063 {
00064 unsigned int n;
00065
00066
00067 HLTPathsByName_.clear();
00068 HLTPathsByIndex_.clear();
00069
00070 if (HLTPatterns_.empty()) {
00071
00072 n = result.size();
00073 HLTPathsByName_.resize(n);
00074 HLTPathsByIndex_.resize(n);
00075 for (unsigned int i = 0; i < n; ++i) {
00076 HLTPathsByName_[i] = triggerNames_.triggerName(i);
00077 HLTPathsByIndex_[i] = i;
00078 }
00079 } else {
00080
00081 BOOST_FOREACH(const std::string & pattern, HLTPatterns_) {
00082 if (is_glob(pattern)) {
00083
00084 std::vector< std::vector<std::string>::const_iterator > matches = matching_triggers(triggerNames_.triggerNames(), glob2reg(pattern));
00085 if (matches.empty()) {
00086
00087 LogDebug("") << "requested pattern does not match any HLT paths: " << pattern;
00088 } else {
00089
00090 BOOST_FOREACH(std::vector<std::string>::const_iterator match, matches)
00091 HLTPathsByName_.push_back(*match);
00092 }
00093 } else {
00094
00095 HLTPathsByName_.push_back(pattern);
00096 }
00097 }
00098 n = HLTPathsByName_.size();
00099
00100
00101 HLTPathsByIndex_.resize(n);
00102 for (unsigned int i = 0; i < HLTPathsByName_.size(); i++) {
00103 HLTPathsByIndex_[i] = triggerNames_.triggerIndex(HLTPathsByName_[i]);
00104 if (HLTPathsByIndex_[i] >= result.size()) {
00105
00106 LogDebug("") << "requested HLT path does not exist: " << HLTPathsByName_[i];
00107 HLTPathsByIndex_[i] = (unsigned int) -1;
00108 }
00109 }
00110 }
00111
00112
00113 LogDebug("") << "HLT trigger paths: " + inputTag_.encode()
00114 << " - Number of paths: " << n
00115 << " - andOr mode: " << andOr_
00116 << " - throw mode: " << throw_;
00117
00118 LogTrace("") << "The HLT trigger paths (# index name):";
00119 for (unsigned int i = 0; i < n; ++i)
00120 if (HLTPathsByIndex_[i] == (unsigned int) -1)
00121 LogTrace("") << " n/a " << HLTPathsByName_[i];
00122 else
00123 LogTrace("") << " " << std::setw(4) << HLTPathsByIndex_[i] << " " << HLTPathsByName_[i];
00124
00125 }
00126
00127
00128 bool
00129 HLTHighLevel::filter(edm::Event& iEvent, const edm::EventSetup& iSetup)
00130 {
00131 using namespace std;
00132 using namespace edm;
00133
00134
00135 Handle<TriggerResults> trh;
00136 iEvent.getByLabel(inputTag_, trh);
00137 if (trh.isValid()) {
00138 LogDebug("") << "TriggerResults found, number of HLT paths: " << trh->size();
00139 } else {
00140 LogDebug("") << "TriggerResults product not found - returning result=false!";
00141 return false;
00142 }
00143
00144
00145 bool config_changed = triggerNames_.init(*trh);
00146
00147
00148 if (config_changed)
00149 init(*trh);
00150
00151 unsigned int n = HLTPathsByName_.size();
00152 unsigned int nbad = 0;
00153 unsigned int fired = 0;
00154
00155
00156 for (unsigned int i = 0; i < n; i++)
00157 if (HLTPathsByIndex_[i] == (unsigned int) -1)
00158 ++nbad;
00159 else if (trh->accept(HLTPathsByIndex_[i]))
00160 ++fired;
00161
00162 if ((nbad > 0) and (config_changed or throw_)) {
00163
00164 std::string message;
00165
00166 for (unsigned int i = 0; i < n; i++)
00167 if (HLTPathsByIndex_[i] == (unsigned int) -1)
00168 message += HLTPathsByName_[i] + " ";
00169
00170 if (config_changed) {
00171 LogTrace("")
00172 << " HLTHighLevel [instance: " << *moduleLabel()
00173 << " - path: " << *pathName()
00174 << "] configured with " << nbad
00175 << "/" << n
00176 << " unknown HLT path names: " << message;
00177 }
00178
00179 if (throw_) {
00180 throw cms::Exception("Configuration")
00181 << " HLTHighLevel [instance: " << *moduleLabel()
00182 << " - path: " << *pathName()
00183 << "] configured with " << nbad
00184 << "/" << n
00185 << " unknown HLT path names: " << message;
00186 }
00187 }
00188
00189
00190 const bool accept( (fired > 0) and ( andOr_ or (fired == n-nbad) ) );
00191 LogDebug("") << "Accept = " << std::boolalpha << accept;
00192
00193 return accept;
00194 }
00195
00196
00197
00198
00199 bool is_glob(const std::string & pattern)
00200 {
00201 return (pattern.find_first_of("*?") != pattern.npos);
00202 }
00203
00204 std::string glob2reg(const std::string & pattern)
00205 {
00206 std::string regexp = pattern;
00207 boost::replace_all(regexp, "*", ".*");
00208 boost::replace_all(regexp, "?", ".");
00209 return regexp;
00210 }
00211
00212 std::vector< std::vector<std::string>::const_iterator >
00213 matching_triggers(const std::vector<std::string> & triggers, const std::string & pattern)
00214 {
00215 std::vector< std::vector<std::string>::const_iterator > matches;
00216 boost::regex regexp( glob2reg(pattern) );
00217 for (std::vector<std::string>::const_iterator i = triggers.begin(); i != triggers.end(); ++i)
00218 if (boost::regex_match((*i), regexp))
00219 matches.push_back(i);
00220
00221 return matches;
00222 }