File indexing completed on 2024-04-06 12:04:59
0001 #include <oneapi/tbb/concurrent_unordered_map.h>
0002 #include <boost/algorithm/string.hpp>
0003
0004 #include "DataFormats/Common/interface/TriggerResults.h"
0005 #include "DataFormats/PatCandidates/interface/TriggerObjectStandAlone.h"
0006 #include "DataFormats/Math/interface/libminifloat.h"
0007 #include "DataFormats/Provenance/interface/ProcessConfiguration.h"
0008 #include "DataFormats/Provenance/interface/ProcessHistory.h"
0009 #include "FWCore/Common/interface/TriggerNames.h"
0010 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0011 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0012 #include "FWCore/Utilities/interface/path_configuration.h"
0013 #include "FWCore/Utilities/interface/thread_safety_macros.h"
0014
0015 using namespace pat;
0016
0017
0018
0019 const char TriggerObjectStandAlone::wildcard_;
0020
0021
0022
0023
0024 TriggerObjectStandAlone::TriggerObjectStandAlone() : TriggerObject() {
0025 filterLabels_.clear();
0026 filterLabelIndices_.clear();
0027 pathNames_.clear();
0028 pathLastFilterAccepted_.clear();
0029 pathL3FilterAccepted_.clear();
0030 }
0031
0032
0033 TriggerObjectStandAlone::TriggerObjectStandAlone(const TriggerObject &trigObj) : TriggerObject(trigObj) {
0034 filterLabels_.clear();
0035 filterLabelIndices_.clear();
0036 pathNames_.clear();
0037 pathLastFilterAccepted_.clear();
0038 pathL3FilterAccepted_.clear();
0039 }
0040
0041
0042 TriggerObjectStandAlone::TriggerObjectStandAlone(const trigger::TriggerObject &trigObj) : TriggerObject(trigObj) {
0043 filterLabels_.clear();
0044 filterLabelIndices_.clear();
0045 pathNames_.clear();
0046 pathLastFilterAccepted_.clear();
0047 pathL3FilterAccepted_.clear();
0048 }
0049
0050
0051 TriggerObjectStandAlone::TriggerObjectStandAlone(const reco::LeafCandidate &leafCand) : TriggerObject(leafCand) {
0052 filterLabels_.clear();
0053 filterLabelIndices_.clear();
0054 pathNames_.clear();
0055 pathLastFilterAccepted_.clear();
0056 pathL3FilterAccepted_.clear();
0057 }
0058
0059
0060 TriggerObjectStandAlone::TriggerObjectStandAlone(const reco::Particle::LorentzVector &vec, int id)
0061 : TriggerObject(vec, id) {
0062 filterLabels_.clear();
0063 filterLabelIndices_.clear();
0064 pathNames_.clear();
0065 pathLastFilterAccepted_.clear();
0066 pathL3FilterAccepted_.clear();
0067 }
0068 TriggerObjectStandAlone::TriggerObjectStandAlone(const reco::Particle::PolarLorentzVector &vec, int id)
0069 : TriggerObject(vec, id) {
0070 filterLabels_.clear();
0071 filterLabelIndices_.clear();
0072 pathNames_.clear();
0073 pathLastFilterAccepted_.clear();
0074 pathL3FilterAccepted_.clear();
0075 }
0076
0077
0078
0079
0080 bool TriggerObjectStandAlone::hasAnyName(const std::string &name, const std::vector<std::string> &nameVec) const {
0081
0082
0083 if (nameVec.empty())
0084 return false;
0085
0086 if (name.find_first_not_of(wildcard_) == std::string::npos)
0087 return true;
0088
0089 std::vector<std::string> namePartsVec;
0090 boost::split(namePartsVec, name, boost::is_any_of(std::string(1, wildcard_)), boost::token_compress_on);
0091
0092 for (std::vector<std::string>::const_iterator iVec = nameVec.begin(); iVec != nameVec.end(); ++iVec) {
0093
0094 bool failed(false);
0095
0096 size_type index(0);
0097
0098 for (std::vector<std::string>::const_iterator iName = namePartsVec.begin(); iName != namePartsVec.end(); ++iName) {
0099
0100
0101
0102 if (iName->length() == 0)
0103 continue;
0104
0105
0106 index = iVec->find(*iName, index);
0107
0108
0109
0110 if (index == std::string::npos || (iName == namePartsVec.begin() && index > 0)) {
0111 failed = true;
0112 break;
0113 }
0114
0115 index += iName->length();
0116 }
0117
0118 if (index < iVec->length() && namePartsVec.back().length() != 0)
0119 failed = true;
0120
0121 if (!failed)
0122 return true;
0123 }
0124
0125 return false;
0126 }
0127
0128
0129 void TriggerObjectStandAlone::addPathOrAlgorithm(const std::string &name,
0130 bool pathLastFilterAccepted,
0131 bool pathL3FilterAccepted) {
0132 checkIfPathsAreUnpacked();
0133
0134
0135 if (!hasPathOrAlgorithm(name, false, false)) {
0136
0137 pathNames_.push_back(name);
0138
0139 pathLastFilterAccepted_.push_back(pathLastFilterAccepted);
0140 pathL3FilterAccepted_.push_back(pathL3FilterAccepted);
0141
0142 } else if (pathLastFilterAccepted || pathL3FilterAccepted) {
0143
0144 unsigned index(0);
0145 while (index < pathNames_.size()) {
0146 if (pathNames_.at(index) == name)
0147 break;
0148 ++index;
0149 }
0150
0151 if (index < pathNames_.size()) {
0152 pathLastFilterAccepted_.at(index) = pathLastFilterAccepted_.at(index) || pathLastFilterAccepted;
0153 pathL3FilterAccepted_.at(index) = pathL3FilterAccepted_.at(index) || pathL3FilterAccepted;
0154 }
0155 }
0156 }
0157
0158
0159 std::vector<std::string> TriggerObjectStandAlone::pathsOrAlgorithms(bool pathLastFilterAccepted,
0160 bool pathL3FilterAccepted) const {
0161 checkIfPathsAreUnpacked();
0162
0163
0164 if (!hasLastFilter())
0165 pathLastFilterAccepted = false;
0166 if (!hasL3Filter())
0167 pathL3FilterAccepted = false;
0168
0169 if (!pathLastFilterAccepted && !pathL3FilterAccepted)
0170 return pathNames_;
0171
0172 std::vector<std::string> paths;
0173
0174 for (unsigned iPath = 0; iPath < pathNames_.size(); ++iPath) {
0175 if ((!pathLastFilterAccepted || pathLastFilterAccepted_.at(iPath)) &&
0176 (!pathL3FilterAccepted || pathL3FilterAccepted_.at(iPath)))
0177 paths.push_back(pathNames_.at(iPath));
0178 }
0179
0180 return paths;
0181 }
0182
0183
0184 bool TriggerObjectStandAlone::hasFilterOrCondition(const std::string &name) const {
0185 checkIfFiltersAreUnpacked();
0186
0187
0188 if (name.find(wildcard_) != std::string::npos)
0189 return hasAnyName(name, filterLabels_);
0190
0191 return (std::find(filterLabels_.begin(), filterLabels_.end(), name) != filterLabels_.end());
0192 }
0193
0194
0195 bool TriggerObjectStandAlone::hasPathOrAlgorithm(const std::string &name,
0196 bool pathLastFilterAccepted,
0197 bool pathL3FilterAccepted) const {
0198 checkIfPathsAreUnpacked();
0199
0200
0201 if (name.find(wildcard_) != std::string::npos)
0202 return hasAnyName(name, pathsOrAlgorithms(pathLastFilterAccepted, pathL3FilterAccepted));
0203
0204 if (!hasLastFilter())
0205 pathLastFilterAccepted = false;
0206 if (!hasL3Filter())
0207 pathL3FilterAccepted = false;
0208
0209 std::vector<std::string>::const_iterator match(std::find(pathNames_.begin(), pathNames_.end(), name));
0210
0211 if (match == pathNames_.end())
0212 return false;
0213 if (!pathLastFilterAccepted && !pathL3FilterAccepted)
0214 return true;
0215 bool foundLastFilter(pathLastFilterAccepted ? pathLastFilterAccepted_.at(match - pathNames_.begin()) : true);
0216 bool foundL3Filter(pathL3FilterAccepted ? pathL3FilterAccepted_.at(match - pathNames_.begin()) : true);
0217
0218 return (foundLastFilter && foundL3Filter);
0219 }
0220
0221
0222
0223
0224 TriggerObject TriggerObjectStandAlone::triggerObject() {
0225
0226 TriggerObject theObj(p4(), pdgId());
0227
0228 theObj.setCollection(collection());
0229 for (size_t i = 0; i < triggerObjectTypes().size(); ++i)
0230 theObj.addTriggerObjectType(triggerObjectTypes().at(i));
0231
0232 return theObj;
0233 }
0234
0235
0236 bool TriggerObjectStandAlone::hasCollection(const std::string &collName) const {
0237
0238 if (collName.find(wildcard_) != std::string::npos) {
0239
0240 if (hasAnyName(collName, std::vector<std::string>(1, collection())))
0241 return true;
0242
0243 const edm::InputTag collectionTag(collection());
0244 const edm::InputTag collTag(collName);
0245
0246 if (collTag.process().empty()) {
0247
0248 if ((collTag.instance().empty() && collectionTag.instance().empty()) ||
0249 hasAnyName(collTag.instance(), std::vector<std::string>(1, collectionTag.instance()))) {
0250
0251 return hasAnyName(collTag.label(), std::vector<std::string>(1, collectionTag.label()));
0252 }
0253 }
0254 return false;
0255 }
0256
0257 return TriggerObject::hasCollection(collName);
0258 }
0259
0260 bool TriggerObjectStandAlone::checkIfPathsAreUnpacked(bool throwIfPacked) const {
0261 bool unpacked = (!pathNames_.empty() || pathIndices_.empty());
0262 if (!unpacked && throwIfPacked)
0263 throw cms::Exception("RuntimeError",
0264 "This TriggerObjectStandAlone object has packed trigger path names. Before accessing path "
0265 "names you must call unpackPathNames with an edm::TriggerNames object. You can get the latter "
0266 "from the edm::Event or fwlite::Event and the TriggerResults\n");
0267 return unpacked;
0268 }
0269 bool TriggerObjectStandAlone::checkIfFiltersAreUnpacked(bool throwIfPacked) const {
0270 bool unpacked = filterLabelIndices_.empty();
0271 if (!unpacked && throwIfPacked)
0272 throw cms::Exception("RuntimeError",
0273 "This TriggerObjectStandAlone object has packed trigger filter labels. Before accessing path "
0274 "names you must call unpackFilterLabels with an edm::EventBase object. Both the edm::Event or "
0275 "fwlite::Event are derived from edm::EventBase and can be passed\n");
0276 return unpacked;
0277 }
0278
0279 void TriggerObjectStandAlone::packPathNames(const edm::TriggerNames &names) {
0280 if (!pathIndices_.empty()) {
0281 if (!pathNames_.empty()) {
0282 throw cms::Exception("RuntimeError", "Error, trying to pack a partially packed TriggerObjectStandAlone");
0283 } else {
0284 return;
0285 }
0286 }
0287 bool ok = true;
0288 unsigned int n = pathNames_.size(), end = names.size();
0289 std::vector<uint16_t> indices(n);
0290 for (unsigned int i = 0; i < n; ++i) {
0291 uint16_t id = names.triggerIndex(pathNames_[i]);
0292 if (id >= end) {
0293 static std::atomic<int> _warn(0);
0294 if (++_warn < 5)
0295 edm::LogWarning("TriggerObjectStandAlone::packPathNames()")
0296 << "Warning: can't resolve '" << pathNames_[i] << "' to a path index" << std::endl;
0297 ok = false;
0298 break;
0299 } else {
0300 indices[i] = id;
0301 }
0302 }
0303 if (ok) {
0304 pathIndices_.swap(indices);
0305 pathNames_.clear();
0306 }
0307 }
0308
0309 void TriggerObjectStandAlone::unpackPathNames(const edm::TriggerNames &names) {
0310 if (!pathNames_.empty()) {
0311 if (!pathIndices_.empty()) {
0312 throw cms::Exception("RuntimeError", "Error, trying to unpack a partially unpacked TriggerObjectStandAlone");
0313 } else {
0314 return;
0315 }
0316 }
0317 unsigned int n = pathIndices_.size(), end = names.size();
0318 std::vector<std::string> paths(n);
0319 for (unsigned int i = 0; i < n; ++i) {
0320 if (pathIndices_[i] >= end)
0321 throw cms::Exception("RuntimeError", "Error, path index out of bounds");
0322 paths[i] = names.triggerName(pathIndices_[i]);
0323 }
0324 pathIndices_.clear();
0325 pathNames_.swap(paths);
0326 }
0327
0328 void TriggerObjectStandAlone::packFilterLabels(const std::vector<std::string> &names) {
0329 if (!filterLabelIndices_.empty()) {
0330 throw cms::Exception("RuntimeError",
0331 "Error, trying to pack filter labels for an already packed TriggerObjectStandAlone");
0332 }
0333 std::vector<std::string> unmatched;
0334 std::vector<uint16_t> indices;
0335 indices.reserve(filterLabels_.size());
0336
0337 auto nStart = names.begin(), nEnd = names.end();
0338 for (unsigned int i = 0, n = filterLabels_.size(); i < n; ++i) {
0339 auto match = std::lower_bound(nStart, nEnd, filterLabels_[i]);
0340 if (match != nEnd && *match == filterLabels_[i]) {
0341 indices.push_back(match - nStart);
0342 } else {
0343 static std::atomic<int> _warn(0);
0344 if (++_warn < 5)
0345 edm::LogWarning("TriggerObjectStandAlone::packFilterLabels()")
0346 << "Warning: can't resolve '" << filterLabels_[i] << "' to a label index. idx: " << i << std::endl;
0347 unmatched.push_back(std::move(filterLabels_[i]));
0348 }
0349 }
0350 std::sort(indices.begin(), indices.end());
0351 filterLabelIndices_.swap(indices);
0352 filterLabels_.swap(unmatched);
0353 }
0354
0355 void TriggerObjectStandAlone::unpackNamesAndLabels(const edm::EventBase &event, const edm::TriggerResults &res) {
0356 unpackPathNames(event.triggerNames(res));
0357 unpackFilterLabels(event, res);
0358 }
0359
0360 void TriggerObjectStandAlone::unpackFilterLabels(const edm::EventBase &event, const edm::TriggerResults &res) {
0361 unpackFilterLabels(*allLabels(psetId_, event, res));
0362 }
0363
0364 void TriggerObjectStandAlone::unpackFilterLabels(const std::vector<std::string> &labels) {
0365 if (filterLabelIndices_.empty())
0366 return;
0367
0368 std::vector<std::string> mylabels(filterLabels_);
0369 for (unsigned int i = 0, n = filterLabelIndices_.size(), m = labels.size(); i < n; ++i) {
0370 if (filterLabelIndices_[i] >= m)
0371 throw cms::Exception("RuntimeError", "Error, filter label index out of bounds");
0372 mylabels.push_back(labels[filterLabelIndices_[i]]);
0373 }
0374 filterLabelIndices_.clear();
0375 filterLabels_.swap(mylabels);
0376 }
0377 void TriggerObjectStandAlone::packFilterLabels(const edm::EventBase &event, const edm::TriggerResults &res) {
0378 packFilterLabels(*allLabels(psetId_, event, res));
0379 }
0380
0381 void TriggerObjectStandAlone::packP4() {
0382 setP4(reco::Particle::PolarLorentzVector(MiniFloatConverter::reduceMantissaToNbitsRounding<14>(pt()),
0383 MiniFloatConverter::reduceMantissaToNbitsRounding<11>(eta()),
0384 MiniFloatConverter::reduceMantissaToNbits<11>(phi()),
0385 MiniFloatConverter::reduceMantissaToNbitsRounding<8>(mass())));
0386 }
0387
0388 namespace {
0389 struct key_hash {
0390 std::size_t operator()(edm::ParameterSetID const &iKey) const { return iKey.smallHash(); }
0391 };
0392 typedef tbb::concurrent_unordered_map<edm::ParameterSetID, std::vector<std::string>, key_hash> AllLabelsMap;
0393 CMS_THREAD_SAFE AllLabelsMap allLabelsMap;
0394 }
0395
0396 std::vector<std::string> const *TriggerObjectStandAlone::allLabels(edm::ParameterSetID const &psetid,
0397 const edm::EventBase &event,
0398 const edm::TriggerResults &res) const {
0399
0400
0401 AllLabelsMap::const_iterator iter = allLabelsMap.find(psetid);
0402 if (iter != allLabelsMap.end()) {
0403 return &iter->second;
0404 }
0405
0406 const auto &triggerNames = event.triggerNames(res);
0407 edm::ParameterSet const *pset = nullptr;
0408
0409 if (nullptr != (pset = event.parameterSet(psetid))) {
0410 using namespace std;
0411 using namespace edm;
0412 using namespace trigger;
0413
0414 const unsigned int n(triggerNames.size());
0415 std::set<std::string> saveTags;
0416 for (unsigned int i = 0; i != n; ++i) {
0417 if (pset->existsAs<vector<string>>(triggerNames.triggerName(i), true)) {
0418 auto const &modules = pset->getParameter<vector<string>>(triggerNames.triggerName(i));
0419 for (auto const &module : modules) {
0420 auto const moduleStrip = edm::path_configuration::removeSchedulingTokensFromModuleLabel(module);
0421 if (pset->exists(moduleStrip)) {
0422 const auto &modulePSet = pset->getParameterSet(moduleStrip);
0423 if (modulePSet.existsAs<bool>("saveTags", true) and modulePSet.getParameter<bool>("saveTags")) {
0424 saveTags.insert(moduleStrip);
0425 }
0426 }
0427 }
0428 }
0429 }
0430 std::vector<std::string> allModules(saveTags.begin(), saveTags.end());
0431 std::pair<AllLabelsMap::iterator, bool> ret =
0432 allLabelsMap.insert(std::pair<edm::ParameterSetID, std::vector<std::string>>(psetid, allModules));
0433 return &(ret.first->second);
0434 }
0435 return nullptr;
0436 }