File indexing completed on 2025-02-20 03:45:23
0001 #include "TrigObjTnPHistColl.h"
0002
0003 #include "FWCore/Common/interface/TriggerNames.h"
0004 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0005
0006 namespace {
0007 std::vector<float> convertToFloat(const std::vector<double>& vecD) {
0008 return std::vector<float>(vecD.begin(), vecD.end());
0009 }
0010 }
0011
0012 TrigObjTnPHistColl::TrigObjTnPHistColl(const edm::ParameterSet& config)
0013 : tagCuts_(config.getParameter<std::vector<edm::ParameterSet>>("tagCuts")),
0014 probeCuts_(config.getParameter<std::vector<edm::ParameterSet>>("probeCuts")),
0015 tagFilters_(config.getParameter<edm::ParameterSet>("tagFilters")),
0016 collName_(config.getParameter<std::string>("collName")),
0017 folderName_(config.getParameter<std::string>("folderName")),
0018 histDefs_(config.getParameter<edm::ParameterSet>("histDefs")),
0019 evtTrigSel_(config.getParameter<edm::ParameterSet>("evtTrigSel"))
0020
0021 {
0022 auto probeFilters = config.getParameter<std::vector<std::string>>("probeFilters");
0023 for (auto& probeFilter : probeFilters) {
0024 probeHists_.emplace_back(ProbeData(std::move(probeFilter)));
0025 }
0026 }
0027
0028 edm::ParameterSetDescription TrigObjTnPHistColl::makePSetDescription() {
0029 edm::ParameterSetDescription desc;
0030 desc.addVPSet(
0031 "tagCuts", VarRangeCut<trigger::TriggerObject>::makePSetDescription(), std::vector<edm::ParameterSet>());
0032 desc.addVPSet(
0033 "probeCuts", VarRangeCut<trigger::TriggerObject>::makePSetDescription(), std::vector<edm::ParameterSet>());
0034 desc.add<edm::ParameterSetDescription>("tagFilters", FilterSelector::makePSetDescription());
0035 desc.add<std::string>("collName", "stdTag");
0036 desc.add<std::string>("folderName", "HLT/EGM/TrigObjTnP");
0037 desc.add<edm::ParameterSetDescription>("histDefs", HistDefs::makePSetDescription());
0038 desc.add<std::vector<std::string>>("probeFilters", std::vector<std::string>());
0039 desc.add<edm::ParameterSetDescription>("evtTrigSel", PathSelector::makePSetDescription());
0040 return desc;
0041 }
0042
0043 void TrigObjTnPHistColl::bookHists(DQMStore::IBooker& iBooker) {
0044 iBooker.setCurrentFolder(folderName_);
0045 for (auto& probe : probeHists_) {
0046 probe.bookHists(collName_, iBooker, histDefs_);
0047 }
0048 }
0049
0050 void TrigObjTnPHistColl::fill(const trigger::TriggerEvent& trigEvt,
0051 const edm::TriggerResults& trigResults,
0052 const edm::TriggerNames& trigNames) const {
0053 if (evtTrigSel_(trigResults, trigNames) == false)
0054 return;
0055
0056 auto tagTrigKeys = tagFilters_.getPassingKeys(trigEvt);
0057 for (auto& tagKey : tagTrigKeys) {
0058 const trigger::TriggerObject& tagObj = trigEvt.getObjects()[tagKey];
0059 if (tagCuts_(tagObj)) {
0060 for (auto& probeColl : probeHists_)
0061 probeColl.fill(tagKey, trigEvt, probeCuts_);
0062 }
0063 }
0064 }
0065
0066
0067
0068
0069 const trigger::Keys TrigObjTnPHistColl::getKeys(const trigger::TriggerEvent& trigEvt, const std::string& filterName) {
0070 edm::InputTag filterTag(filterName, "", trigEvt.usedProcessName());
0071 trigger::size_type filterIndex = trigEvt.filterIndex(filterTag);
0072 if (filterIndex < trigEvt.sizeFilters())
0073 return trigEvt.filterKeys(filterIndex);
0074 else
0075 return trigger::Keys();
0076 }
0077
0078 TrigObjTnPHistColl::FilterSelector::FilterSelector(const edm::ParameterSet& config)
0079 : isAND_(config.getParameter<bool>("isAND")) {
0080 auto filterSetConfigs = config.getParameter<std::vector<edm::ParameterSet>>("filterSets");
0081 for (auto& filterSetConfig : filterSetConfigs)
0082 filterSets_.emplace_back(FilterSet(filterSetConfig));
0083 }
0084
0085 edm::ParameterSetDescription TrigObjTnPHistColl::FilterSelector::makePSetDescription() {
0086 edm::ParameterSetDescription desc;
0087 desc.addVPSet("filterSets", FilterSet::makePSetDescription(), std::vector<edm::ParameterSet>());
0088 desc.add<bool>("isAND", false);
0089 return desc;
0090 }
0091
0092 const trigger::Keys TrigObjTnPHistColl::FilterSelector::getPassingKeys(const trigger::TriggerEvent& trigEvt) const {
0093 trigger::Keys passingKeys;
0094 bool isFirstFilterSet = true;
0095 for (const auto& filterSet : filterSets_) {
0096 auto keysOfFilterSet = filterSet.getPassingKeys(trigEvt);
0097 if (isFirstFilterSet)
0098 passingKeys = keysOfFilterSet;
0099 else
0100 mergeTrigKeys(passingKeys, keysOfFilterSet, isAND_);
0101 isFirstFilterSet = false;
0102 }
0103 cleanTrigKeys(passingKeys);
0104 return passingKeys;
0105 }
0106
0107 void TrigObjTnPHistColl::FilterSelector::mergeTrigKeys(trigger::Keys& keys,
0108 const trigger::Keys& keysToMerge,
0109 bool isAND) {
0110 if (isAND) {
0111 for (auto& key : keys) {
0112 if (std::count(keysToMerge.begin(), keysToMerge.end(), key) == 0) {
0113 key = std::numeric_limits<trigger::size_type>::max();
0114 }
0115 }
0116 } else {
0117 for (const auto key : keysToMerge) {
0118 keys.push_back(key);
0119 }
0120 }
0121 }
0122
0123 void TrigObjTnPHistColl::FilterSelector::cleanTrigKeys(trigger::Keys& keys) {
0124 std::sort(keys.begin(), keys.end());
0125 auto last = std::unique(keys.begin(), keys.end());
0126 keys.erase(last, keys.end());
0127 while (!keys.empty() && keys.back() == std::numeric_limits<trigger::size_type>::max()) {
0128 keys.pop_back();
0129 }
0130 }
0131
0132 TrigObjTnPHistColl::FilterSelector::FilterSet::FilterSet(const edm::ParameterSet& config)
0133 : filters_(config.getParameter<std::vector<std::string>>("filters")), isAND_(config.getParameter<bool>("isAND")) {}
0134
0135 TrigObjTnPHistColl::PathSelector::PathSelector(const edm::ParameterSet& config)
0136 : selectionStr_(config.getParameter<std::string>("selectionStr")),
0137 isANDForExpandedPaths_(config.getParameter<bool>("isANDForExpandedPaths")),
0138 verbose_(config.getParameter<int>("verbose")),
0139 isInited_(false) {}
0140
0141 edm::ParameterSetDescription TrigObjTnPHistColl::PathSelector::makePSetDescription() {
0142 edm::ParameterSetDescription desc;
0143 desc.add<std::string>("selectionStr", std::string(""));
0144 desc.add<bool>("isANDForExpandedPaths", false);
0145 desc.add<int>("verbose", 1);
0146 return desc;
0147 }
0148
0149 void TrigObjTnPHistColl::PathSelector::init(const HLTConfigProvider& hltConfig) {
0150 expandedSelStr_ = expandSelectionStr(selectionStr_, hltConfig, isANDForExpandedPaths_, verbose_);
0151 isInited_ = true;
0152 if (verbose_ > 1) {
0153 edm::LogInfo("TrigObjTnPHistColl::PathSelector") << "trigger selection string: \"" << expandedSelStr_ << "\"";
0154 }
0155 }
0156
0157 bool TrigObjTnPHistColl::PathSelector::operator()(const edm::TriggerResults& trigResults,
0158 const edm::TriggerNames& trigNames) const {
0159 if (selectionStr_.empty())
0160 return true;
0161 else if (!isInited_) {
0162 edm::LogError("TrigObjTnPHistColl")
0163 << " error, TrigObjTnPHistColl::PathSelector is not initalised, returning false ";
0164 return false;
0165 } else if (expandedSelStr_.empty()) {
0166
0167 return false;
0168 } else {
0169
0170
0171
0172
0173 std::string selStr = expandedSelStr_;
0174 L1GtLogicParser logicParser(selStr);
0175 for (auto& token : logicParser.operandTokenVector()) {
0176 const std::string& pathName = token.tokenName;
0177 auto pathIndex = trigNames.triggerIndex(pathName);
0178 bool accept = pathIndex < trigNames.size() ? trigResults.accept(pathIndex) : false;
0179 token.tokenResult = accept;
0180 }
0181 return logicParser.expressionResult();
0182 }
0183 }
0184
0185
0186 std::string TrigObjTnPHistColl::PathSelector::expandSelectionStr(const std::string& selStr,
0187 const HLTConfigProvider& hltConfig,
0188 bool isAND,
0189 int verbose) {
0190 std::string expandedSelStr(selStr);
0191
0192 L1GtLogicParser logicParser(expandedSelStr);
0193 for (const auto& token : logicParser.operandTokenVector()) {
0194 const std::string& pathName = token.tokenName;
0195 if (pathName.find('*') != std::string::npos) {
0196 std::string pathPatternExpanded = expandPath(pathName, hltConfig, isAND, verbose);
0197 expandedSelStr.replace(expandedSelStr.find(pathName), pathName.size(), pathPatternExpanded);
0198 }
0199 }
0200 return expandedSelStr;
0201 }
0202
0203
0204
0205 std::string TrigObjTnPHistColl::PathSelector::expandPath(const std::string& pathPattern,
0206 const HLTConfigProvider& hltConfig,
0207 bool isAND,
0208 int verbose) {
0209
0210 const std::vector<std::string>& trigNames = hltConfig.triggerNames();
0211 std::vector<std::string> matched;
0212 const std::string versionWildcard("_v*");
0213 if (pathPattern.substr(pathPattern.size() - versionWildcard.size()) == versionWildcard) {
0214 const std::string pathPatternBase(pathPattern.substr(0, pathPattern.size() - versionWildcard.size()));
0215 matched = hltConfig.restoreVersion(trigNames, pathPatternBase);
0216 } else {
0217 matched = hltConfig.matched(trigNames, pathPattern);
0218 }
0219
0220 if (matched.empty()) {
0221 if (verbose >= 1)
0222 edm::LogWarning("TrigObjTnPHistColl::PathSelector")
0223 << "pattern: \"" << pathPattern
0224 << "\" could not be resolved, please check your triggers are spelt correctly and present in the data you are "
0225 "running over";
0226 return "";
0227 }
0228
0229
0230 std::string expanded("(");
0231 for (unsigned iVers = 0; iVers < matched.size(); ++iVers) {
0232 if (iVers > 0)
0233 expanded.append(isAND ? " AND " : " OR ");
0234 expanded.append(matched.at(iVers));
0235 }
0236 expanded.append(")");
0237 if (verbose > 1) {
0238 edm::LogInfo("TrigObjTnPHistColl::PathSelector") << "Logical expression : \"" << pathPattern << "\"\n"
0239 << " expanded to: \"" << expanded << "\"";
0240 }
0241 return expanded;
0242 }
0243
0244 edm::ParameterSetDescription TrigObjTnPHistColl::FilterSelector::FilterSet::makePSetDescription() {
0245 edm::ParameterSetDescription desc;
0246 desc.add<std::vector<std::string>>("filters", std::vector<std::string>());
0247 desc.add<bool>("isAND", true);
0248 return desc;
0249 }
0250
0251 const trigger::Keys TrigObjTnPHistColl::FilterSelector::FilterSet::getPassingKeys(
0252 const trigger::TriggerEvent& trigEvt) const {
0253 trigger::Keys passingKeys;
0254 bool firstFilter = true;
0255 for (const auto& filterName : filters_) {
0256 const trigger::Keys& trigKeys = getKeys(trigEvt, filterName);
0257 if (firstFilter) {
0258 passingKeys = trigKeys;
0259 firstFilter = false;
0260 } else
0261 mergeTrigKeys(passingKeys, trigKeys, isAND_);
0262 }
0263 cleanTrigKeys(passingKeys);
0264
0265 return passingKeys;
0266 }
0267
0268 TrigObjTnPHistColl::TrigObjVarF::TrigObjVarF(std::string varName) : isAbs_(false) {
0269
0270 auto absPos = varName.rfind("Abs");
0271 if (absPos != std::string::npos && absPos + 3 == varName.size()) {
0272 isAbs_ = true;
0273 varName = varName.erase(absPos);
0274 }
0275 if (varName == "pt")
0276 varFunc_ = &trigger::TriggerObject::pt;
0277 else if (varName == "eta")
0278 varFunc_ = &trigger::TriggerObject::eta;
0279 else if (varName == "phi")
0280 varFunc_ = &trigger::TriggerObject::phi;
0281 else {
0282 std::ostringstream msg;
0283 msg << "var " << varName << " not recognised (use pt or p rather than et or e for speed!) ";
0284 if (isAbs_)
0285 msg << " varName was \"Abs\" suffex cleaned where it tried to remove \"Abs\" at the end of the variable name ";
0286 msg << __FILE__ << "," << __LINE__ << std::endl;
0287 throw cms::Exception("ConfigError") << msg.str();
0288 }
0289 }
0290
0291 TrigObjTnPHistColl::HistFiller::HistFiller(const edm::ParameterSet& config)
0292 : localCuts_(config.getParameter<std::vector<edm::ParameterSet>>("localCuts")),
0293 var_(config.getParameter<std::string>("var")) {}
0294
0295 edm::ParameterSetDescription TrigObjTnPHistColl::HistFiller::makePSetDescription() {
0296 edm::ParameterSetDescription desc;
0297 desc.addVPSet("localCuts", VarRangeCut<trigger::TriggerObject>::makePSetDescription());
0298 desc.add<std::string>("var", "pt");
0299 return desc;
0300 }
0301
0302 void TrigObjTnPHistColl::HistFiller::operator()(const trigger::TriggerObject& probe,
0303 float mass,
0304 dqm::reco::MonitorElement* hist) const {
0305 if (localCuts_(probe))
0306 hist->Fill(var_(probe), mass);
0307 }
0308
0309 TrigObjTnPHistColl::HistDefs::HistDefs(const edm::ParameterSet& config)
0310 : massBins_(convertToFloat(config.getParameter<std::vector<double>>("massBins"))) {
0311 const auto histConfigs = config.getParameter<std::vector<edm::ParameterSet>>("configs");
0312 for (const auto& histConfig : histConfigs) {
0313 histData_.emplace_back(Data(histConfig));
0314 }
0315 }
0316
0317 edm::ParameterSetDescription TrigObjTnPHistColl::HistDefs::makePSetDescription() {
0318 edm::ParameterSetDescription desc;
0319 desc.addVPSet("configs", Data::makePSetDescription(), std::vector<edm::ParameterSet>());
0320 std::vector<double> massBins;
0321 for (float mass = 60; mass <= 120; mass += 1)
0322 massBins.push_back(mass);
0323 desc.add<std::vector<double>>("massBins", massBins);
0324 return desc;
0325 }
0326
0327 std::vector<std::pair<TrigObjTnPHistColl::HistFiller, dqm::reco::MonitorElement*>>
0328 TrigObjTnPHistColl::HistDefs::bookHists(DQMStore::IBooker& iBooker,
0329 const std::string& name,
0330 const std::string& title) const {
0331 std::vector<std::pair<HistFiller, dqm::reco::MonitorElement*>> hists;
0332 hists.reserve(histData_.size());
0333 for (const auto& data : histData_) {
0334 hists.push_back({data.filler(), data.book(iBooker, name, title, massBins_)});
0335 }
0336 return hists;
0337 }
0338
0339 TrigObjTnPHistColl::HistDefs::Data::Data(const edm::ParameterSet& config)
0340 : histFiller_(config.getParameter<edm::ParameterSet>("filler")),
0341 bins_(convertToFloat(config.getParameter<std::vector<double>>("bins"))),
0342 nameSuffex_(config.getParameter<std::string>("nameSuffex")),
0343 titleSuffex_(config.getParameter<std::string>("titleSuffex")) {}
0344
0345 edm::ParameterSetDescription TrigObjTnPHistColl::HistDefs::Data::makePSetDescription() {
0346 edm::ParameterSetDescription desc;
0347 desc.add<edm::ParameterSetDescription>("filler", TrigObjTnPHistColl::HistFiller::makePSetDescription());
0348 desc.add<std::vector<double>>("bins", {-2.5, -1.5, 0, 1.5, 2.5});
0349 desc.add<std::string>("nameSuffex", "_eta");
0350 desc.add<std::string>("titleSuffex", ";#eta;mass [GeV]");
0351 return desc;
0352 }
0353
0354 dqm::reco::MonitorElement* TrigObjTnPHistColl::HistDefs::Data::book(DQMStore::IBooker& iBooker,
0355 const std::string& name,
0356 const std::string& title,
0357 const std::vector<float>& massBins) const {
0358 return iBooker.book2D((name + nameSuffex_).c_str(),
0359 (title + titleSuffex_).c_str(),
0360 bins_.size() - 1,
0361 bins_.data(),
0362 massBins.size() - 1,
0363 massBins.data());
0364 }
0365
0366 void TrigObjTnPHistColl::HistColl::bookHists(DQMStore::IBooker& iBooker,
0367 const std::string& name,
0368 const std::string& title,
0369 const HistDefs& histDefs) {
0370 hists_ = histDefs.bookHists(iBooker, name, title);
0371 }
0372
0373 void TrigObjTnPHistColl::HistColl::fill(const trigger::TriggerObject& probe, float mass) const {
0374 for (auto& hist : hists_) {
0375 hist.first(probe, mass, hist.second);
0376 }
0377 }
0378
0379 void TrigObjTnPHistColl::ProbeData::bookHists(const std::string& tagName,
0380 DQMStore::IBooker& iBooker,
0381 const HistDefs& histDefs) {
0382 hists_.bookHists(iBooker, tagName + "_" + probeFilter_, tagName + "_" + probeFilter_, histDefs);
0383 }
0384
0385 void TrigObjTnPHistColl::ProbeData::fill(const trigger::size_type tagKey,
0386 const trigger::TriggerEvent& trigEvt,
0387 const VarRangeCutColl<trigger::TriggerObject>& probeCuts) const {
0388 auto probeKeys = getKeys(trigEvt, probeFilter_);
0389 for (auto probeKey : probeKeys) {
0390 const trigger::TriggerObject& probe = trigEvt.getObjects()[probeKey];
0391 if (tagKey != probeKey && probeCuts(probe)) {
0392 const trigger::TriggerObject& tag = trigEvt.getObjects()[tagKey];
0393 auto massFunc = [](float pt1, float eta1, float phi1, float pt2, float eta2, float phi2) {
0394 return std::sqrt(2 * pt1 * pt2 * (std::cosh(eta1 - eta2) - std::cos(phi1 - phi2)));
0395 };
0396 float mass = massFunc(tag.pt(), tag.eta(), tag.phi(), probe.pt(), probe.eta(), probe.phi());
0397 hists_.fill(probe, mass);
0398 }
0399 }
0400 }