File indexing completed on 2023-05-26 01:15:34
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 std::unique(keys.begin(), keys.end());
0126 while (!keys.empty() && keys.back() == std::numeric_limits<trigger::size_type>::max()) {
0127 keys.pop_back();
0128 }
0129 }
0130
0131 TrigObjTnPHistColl::FilterSelector::FilterSet::FilterSet(const edm::ParameterSet& config)
0132 : filters_(config.getParameter<std::vector<std::string>>("filters")), isAND_(config.getParameter<bool>("isAND")) {}
0133
0134 TrigObjTnPHistColl::PathSelector::PathSelector(const edm::ParameterSet& config)
0135 : selectionStr_(config.getParameter<std::string>("selectionStr")),
0136 isANDForExpandedPaths_(config.getParameter<bool>("isANDForExpandedPaths")),
0137 verbose_(config.getParameter<int>("verbose")),
0138 isInited_(false) {}
0139
0140 edm::ParameterSetDescription TrigObjTnPHistColl::PathSelector::makePSetDescription() {
0141 edm::ParameterSetDescription desc;
0142 desc.add<std::string>("selectionStr", std::string(""));
0143 desc.add<bool>("isANDForExpandedPaths", false);
0144 desc.add<int>("verbose", 1);
0145 return desc;
0146 }
0147
0148 void TrigObjTnPHistColl::PathSelector::init(const HLTConfigProvider& hltConfig) {
0149 expandedSelStr_ = expandSelectionStr(selectionStr_, hltConfig, isANDForExpandedPaths_, verbose_);
0150 isInited_ = true;
0151 if (verbose_ > 1) {
0152 edm::LogInfo("TrigObjTnPHistColl::PathSelector") << "trigger selection string: \"" << expandedSelStr_ << "\"";
0153 }
0154 }
0155
0156 bool TrigObjTnPHistColl::PathSelector::operator()(const edm::TriggerResults& trigResults,
0157 const edm::TriggerNames& trigNames) const {
0158 if (selectionStr_.empty())
0159 return true;
0160 else if (!isInited_) {
0161 edm::LogError("TrigObjTnPHistColl")
0162 << " error, TrigObjTnPHistColl::PathSelector is not initalised, returning false ";
0163 return false;
0164 } else if (expandedSelStr_.empty()) {
0165
0166 return false;
0167 } else {
0168
0169
0170
0171
0172 std::string selStr = expandedSelStr_;
0173 L1GtLogicParser logicParser(selStr);
0174 for (auto& token : logicParser.operandTokenVector()) {
0175 const std::string& pathName = token.tokenName;
0176 auto pathIndex = trigNames.triggerIndex(pathName);
0177 bool accept = pathIndex < trigNames.size() ? trigResults.accept(pathIndex) : false;
0178 token.tokenResult = accept;
0179 }
0180 return logicParser.expressionResult();
0181 }
0182 }
0183
0184
0185 std::string TrigObjTnPHistColl::PathSelector::expandSelectionStr(const std::string& selStr,
0186 const HLTConfigProvider& hltConfig,
0187 bool isAND,
0188 int verbose) {
0189 std::string expandedSelStr(selStr);
0190
0191 L1GtLogicParser logicParser(expandedSelStr);
0192 for (const auto& token : logicParser.operandTokenVector()) {
0193 const std::string& pathName = token.tokenName;
0194 if (pathName.find('*') != std::string::npos) {
0195 std::string pathPatternExpanded = expandPath(pathName, hltConfig, isAND, verbose);
0196 expandedSelStr.replace(expandedSelStr.find(pathName), pathName.size(), pathPatternExpanded);
0197 }
0198 }
0199 return expandedSelStr;
0200 }
0201
0202
0203
0204 std::string TrigObjTnPHistColl::PathSelector::expandPath(const std::string& pathPattern,
0205 const HLTConfigProvider& hltConfig,
0206 bool isAND,
0207 int verbose) {
0208
0209 const std::vector<std::string>& trigNames = hltConfig.triggerNames();
0210 std::vector<std::string> matched;
0211 const std::string versionWildcard("_v*");
0212 if (pathPattern.substr(pathPattern.size() - versionWildcard.size()) == versionWildcard) {
0213 const std::string pathPatternBase(pathPattern.substr(0, pathPattern.size() - versionWildcard.size()));
0214 matched = hltConfig.restoreVersion(trigNames, pathPatternBase);
0215 } else {
0216 matched = hltConfig.matched(trigNames, pathPattern);
0217 }
0218
0219 if (matched.empty()) {
0220 if (verbose >= 1)
0221 edm::LogWarning("TrigObjTnPHistColl::PathSelector")
0222 << "pattern: \"" << pathPattern
0223 << "\" could not be resolved, please check your triggers are spelt correctly and present in the data you are "
0224 "running over";
0225 return "";
0226 }
0227
0228
0229 std::string expanded("(");
0230 for (unsigned iVers = 0; iVers < matched.size(); ++iVers) {
0231 if (iVers > 0)
0232 expanded.append(isAND ? " AND " : " OR ");
0233 expanded.append(matched.at(iVers));
0234 }
0235 expanded.append(")");
0236 if (verbose > 1) {
0237 edm::LogInfo("TrigObjTnPHistColl::PathSelector") << "Logical expression : \"" << pathPattern << "\"\n"
0238 << " expanded to: \"" << expanded << "\"";
0239 }
0240 return expanded;
0241 }
0242
0243 edm::ParameterSetDescription TrigObjTnPHistColl::FilterSelector::FilterSet::makePSetDescription() {
0244 edm::ParameterSetDescription desc;
0245 desc.add<std::vector<std::string>>("filters", std::vector<std::string>());
0246 desc.add<bool>("isAND", true);
0247 return desc;
0248 }
0249
0250 const trigger::Keys TrigObjTnPHistColl::FilterSelector::FilterSet::getPassingKeys(
0251 const trigger::TriggerEvent& trigEvt) const {
0252 trigger::Keys passingKeys;
0253 bool firstFilter = true;
0254 for (const auto& filterName : filters_) {
0255 const trigger::Keys& trigKeys = getKeys(trigEvt, filterName);
0256 if (firstFilter) {
0257 passingKeys = trigKeys;
0258 firstFilter = false;
0259 } else
0260 mergeTrigKeys(passingKeys, trigKeys, isAND_);
0261 }
0262 cleanTrigKeys(passingKeys);
0263
0264 return passingKeys;
0265 }
0266
0267 TrigObjTnPHistColl::TrigObjVarF::TrigObjVarF(std::string varName) : isAbs_(false) {
0268
0269 auto absPos = varName.rfind("Abs");
0270 if (absPos != std::string::npos && absPos + 3 == varName.size()) {
0271 isAbs_ = true;
0272 varName = varName.erase(absPos);
0273 }
0274 if (varName == "pt")
0275 varFunc_ = &trigger::TriggerObject::pt;
0276 else if (varName == "eta")
0277 varFunc_ = &trigger::TriggerObject::eta;
0278 else if (varName == "phi")
0279 varFunc_ = &trigger::TriggerObject::phi;
0280 else {
0281 std::ostringstream msg;
0282 msg << "var " << varName << " not recognised (use pt or p rather than et or e for speed!) ";
0283 if (isAbs_)
0284 msg << " varName was \"Abs\" suffex cleaned where it tried to remove \"Abs\" at the end of the variable name ";
0285 msg << __FILE__ << "," << __LINE__ << std::endl;
0286 throw cms::Exception("ConfigError") << msg.str();
0287 }
0288 }
0289
0290 TrigObjTnPHistColl::HistFiller::HistFiller(const edm::ParameterSet& config)
0291 : localCuts_(config.getParameter<std::vector<edm::ParameterSet>>("localCuts")),
0292 var_(config.getParameter<std::string>("var")) {}
0293
0294 edm::ParameterSetDescription TrigObjTnPHistColl::HistFiller::makePSetDescription() {
0295 edm::ParameterSetDescription desc;
0296 desc.addVPSet("localCuts", VarRangeCut<trigger::TriggerObject>::makePSetDescription());
0297 desc.add<std::string>("var", "pt");
0298 return desc;
0299 }
0300
0301 void TrigObjTnPHistColl::HistFiller::operator()(const trigger::TriggerObject& probe,
0302 float mass,
0303 dqm::reco::MonitorElement* hist) const {
0304 if (localCuts_(probe))
0305 hist->Fill(var_(probe), mass);
0306 }
0307
0308 TrigObjTnPHistColl::HistDefs::HistDefs(const edm::ParameterSet& config)
0309 : massBins_(convertToFloat(config.getParameter<std::vector<double>>("massBins"))) {
0310 const auto histConfigs = config.getParameter<std::vector<edm::ParameterSet>>("configs");
0311 for (const auto& histConfig : histConfigs) {
0312 histData_.emplace_back(Data(histConfig));
0313 }
0314 }
0315
0316 edm::ParameterSetDescription TrigObjTnPHistColl::HistDefs::makePSetDescription() {
0317 edm::ParameterSetDescription desc;
0318 desc.addVPSet("configs", Data::makePSetDescription(), std::vector<edm::ParameterSet>());
0319 std::vector<double> massBins;
0320 for (float mass = 60; mass <= 120; mass += 1)
0321 massBins.push_back(mass);
0322 desc.add<std::vector<double>>("massBins", massBins);
0323 return desc;
0324 }
0325
0326 std::vector<std::pair<TrigObjTnPHistColl::HistFiller, dqm::reco::MonitorElement*>>
0327 TrigObjTnPHistColl::HistDefs::bookHists(DQMStore::IBooker& iBooker,
0328 const std::string& name,
0329 const std::string& title) const {
0330 std::vector<std::pair<HistFiller, dqm::reco::MonitorElement*>> hists;
0331 hists.reserve(histData_.size());
0332 for (const auto& data : histData_) {
0333 hists.push_back({data.filler(), data.book(iBooker, name, title, massBins_)});
0334 }
0335 return hists;
0336 }
0337
0338 TrigObjTnPHistColl::HistDefs::Data::Data(const edm::ParameterSet& config)
0339 : histFiller_(config.getParameter<edm::ParameterSet>("filler")),
0340 bins_(convertToFloat(config.getParameter<std::vector<double>>("bins"))),
0341 nameSuffex_(config.getParameter<std::string>("nameSuffex")),
0342 titleSuffex_(config.getParameter<std::string>("titleSuffex")) {}
0343
0344 edm::ParameterSetDescription TrigObjTnPHistColl::HistDefs::Data::makePSetDescription() {
0345 edm::ParameterSetDescription desc;
0346 desc.add<edm::ParameterSetDescription>("filler", TrigObjTnPHistColl::HistFiller::makePSetDescription());
0347 desc.add<std::vector<double>>("bins", {-2.5, -1.5, 0, 1.5, 2.5});
0348 desc.add<std::string>("nameSuffex", "_eta");
0349 desc.add<std::string>("titleSuffex", ";#eta;mass [GeV]");
0350 return desc;
0351 }
0352
0353 dqm::reco::MonitorElement* TrigObjTnPHistColl::HistDefs::Data::book(DQMStore::IBooker& iBooker,
0354 const std::string& name,
0355 const std::string& title,
0356 const std::vector<float>& massBins) const {
0357 return iBooker.book2D((name + nameSuffex_).c_str(),
0358 (title + titleSuffex_).c_str(),
0359 bins_.size() - 1,
0360 bins_.data(),
0361 massBins.size() - 1,
0362 massBins.data());
0363 }
0364
0365 void TrigObjTnPHistColl::HistColl::bookHists(DQMStore::IBooker& iBooker,
0366 const std::string& name,
0367 const std::string& title,
0368 const HistDefs& histDefs) {
0369 hists_ = histDefs.bookHists(iBooker, name, title);
0370 }
0371
0372 void TrigObjTnPHistColl::HistColl::fill(const trigger::TriggerObject& probe, float mass) const {
0373 for (auto& hist : hists_) {
0374 hist.first(probe, mass, hist.second);
0375 }
0376 }
0377
0378 void TrigObjTnPHistColl::ProbeData::bookHists(const std::string& tagName,
0379 DQMStore::IBooker& iBooker,
0380 const HistDefs& histDefs) {
0381 hists_.bookHists(iBooker, tagName + "_" + probeFilter_, tagName + "_" + probeFilter_, histDefs);
0382 }
0383
0384 void TrigObjTnPHistColl::ProbeData::fill(const trigger::size_type tagKey,
0385 const trigger::TriggerEvent& trigEvt,
0386 const VarRangeCutColl<trigger::TriggerObject>& probeCuts) const {
0387 auto probeKeys = getKeys(trigEvt, probeFilter_);
0388 for (auto probeKey : probeKeys) {
0389 const trigger::TriggerObject& probe = trigEvt.getObjects()[probeKey];
0390 if (tagKey != probeKey && probeCuts(probe)) {
0391 const trigger::TriggerObject& tag = trigEvt.getObjects()[tagKey];
0392 auto massFunc = [](float pt1, float eta1, float phi1, float pt2, float eta2, float phi2) {
0393 return std::sqrt(2 * pt1 * pt2 * (std::cosh(eta1 - eta2) - std::cos(phi1 - phi2)));
0394 };
0395 float mass = massFunc(tag.pt(), tag.eta(), tag.phi(), probe.pt(), probe.eta(), probe.phi());
0396 hists_.fill(probe, mass);
0397 }
0398 }
0399 }