File indexing completed on 2023-03-17 10:57:07
0001
0002
0003 #include "CondFormats/HLTObjects/interface/AlCaRecoTriggerBits.h"
0004 #include "CondFormats/DataRecord/interface/AlCaRecoTriggerBitsRcd.h"
0005 #include "DataFormats/L1GlobalTrigger/interface/L1GtLogicParser.h"
0006 #include "DQM/TrackerCommon/interface/TriggerHelper.h"
0007 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0008 #include <string>
0009 #include <vector>
0010
0011
0012 TriggerHelper::TriggerHelper(const edm::ParameterSet &config, edm::ConsumesCollector &iC)
0013 : watchDB_(nullptr),
0014 gtDBKey_(""),
0015 l1DBKey_(""),
0016 hltDBKey_(""),
0017 on_(true),
0018 onDcs_(true),
0019 onGt_(true),
0020 onL1_(true),
0021 onHlt_(true),
0022 configError_("CONFIG_ERROR") {
0023
0024 if (config.exists("andOr")) {
0025 andOr_ = config.getParameter<bool>("andOr");
0026 } else {
0027 on_ = false;
0028 onDcs_ = false;
0029 onGt_ = false;
0030 onL1_ = false;
0031 onHlt_ = false;
0032 }
0033
0034 if (on_) {
0035 if (config.exists("andOrDcs")) {
0036 andOrDcs_ = config.getParameter<bool>("andOrDcs");
0037 dcsInputTag_ = config.getParameter<edm::InputTag>("dcsInputTag");
0038 dcsInputToken_ = iC.mayConsume<DcsStatusCollection>(dcsInputTag_);
0039 dcsRecordInputTag_ = config.getParameter<edm::InputTag>("dcsRecordInputTag");
0040 dcsRecordToken_ = iC.mayConsume<DCSRecord>(dcsRecordInputTag_);
0041 dcsPartitions_ = config.getParameter<std::vector<int>>("dcsPartitions");
0042 errorReplyDcs_ = config.getParameter<bool>("errorReplyDcs");
0043 } else {
0044 onDcs_ = false;
0045 }
0046 if (config.exists("andOrGt")) {
0047 andOrGt_ = config.getParameter<bool>("andOrGt");
0048 gtLogicalExpressions_ = config.getParameter<std::vector<std::string>>("gtStatusBits");
0049 errorReplyGt_ = config.getParameter<bool>("errorReplyGt");
0050 if (config.exists("gtDBKey"))
0051 gtDBKey_ = config.getParameter<std::string>("gtDBKey");
0052 } else {
0053 onGt_ = false;
0054 }
0055 if (config.exists("andOrL1")) {
0056 andOrL1_ = config.getParameter<bool>("andOrL1");
0057 l1LogicalExpressions_ = config.getParameter<std::vector<std::string>>("l1Algorithms");
0058 errorReplyL1_ = config.getParameter<bool>("errorReplyL1");
0059 if (config.exists("l1DBKey"))
0060 l1DBKey_ = config.getParameter<std::string>("l1DBKey");
0061 } else {
0062 onL1_ = false;
0063 }
0064 if (config.exists("andOrHlt")) {
0065 andOrHlt_ = config.getParameter<bool>("andOrHlt");
0066 hltInputTag_ = config.getParameter<edm::InputTag>("hltInputTag");
0067 hltInputToken_ = iC.mayConsume<edm::TriggerResults>(hltInputTag_);
0068 hltLogicalExpressions_ = config.getParameter<std::vector<std::string>>("hltPaths");
0069 errorReplyHlt_ = config.getParameter<bool>("errorReplyHlt");
0070 if (config.exists("hltDBKey"))
0071 hltDBKey_ = config.getParameter<std::string>("hltDBKey");
0072 } else {
0073 onHlt_ = false;
0074 }
0075 if (!onDcs_ && !onGt_ && !onL1_ && !onHlt_)
0076 on_ = false;
0077 else
0078 watchDB_ = new edm::ESWatcher<AlCaRecoTriggerBitsRcd>;
0079 }
0080 }
0081
0082
0083 TriggerHelper::~TriggerHelper() {
0084 if (on_)
0085 delete watchDB_;
0086 }
0087
0088
0089 void TriggerHelper::initRun(const edm::Run &run, const edm::EventSetup &setup) {
0090
0091
0092 if (watchDB_->check(setup)) {
0093 if (onGt_ && !gtDBKey_.empty()) {
0094 const std::vector<std::string> exprs(expressionsFromDB(gtDBKey_, setup));
0095 if (exprs.empty() || exprs.at(0) != configError_)
0096 gtLogicalExpressions_ = exprs;
0097 }
0098 if (onL1_ && !l1DBKey_.empty()) {
0099 const std::vector<std::string> exprs(expressionsFromDB(l1DBKey_, setup));
0100 if (exprs.empty() || exprs.at(0) != configError_)
0101 l1LogicalExpressions_ = exprs;
0102 }
0103 if (onHlt_ && !hltDBKey_.empty()) {
0104 const std::vector<std::string> exprs(expressionsFromDB(hltDBKey_, setup));
0105 if (exprs.empty() || exprs.at(0) != configError_)
0106 hltLogicalExpressions_ = exprs;
0107 }
0108 }
0109
0110 hltConfigInit_ = false;
0111 if (onHlt_) {
0112 if (hltInputTag_.process().empty()) {
0113 edm::LogError("TriggerHelper") << "HLT TriggerResults InputTag \"" << hltInputTag_.encode()
0114 << "\" specifies no process";
0115 } else {
0116 bool hltChanged(false);
0117 if (!hltConfig_.init(run, setup, hltInputTag_.process(), hltChanged)) {
0118 edm::LogError("TriggerHelper") << "HLT config initialization error with process name \""
0119 << hltInputTag_.process() << "\"";
0120 } else if (hltConfig_.size() <= 0) {
0121 edm::LogError("TriggerHelper") << "HLT config size error";
0122 } else
0123 hltConfigInit_ = true;
0124 }
0125 }
0126 }
0127
0128
0129 bool TriggerHelper::accept(const edm::Event &event, const edm::EventSetup &setup) {
0130 if (!on_)
0131 return true;
0132
0133
0134 if (andOr_)
0135 return (acceptDcs(event) || acceptGt(event) || acceptL1(event, setup) || acceptHlt(event));
0136 return (acceptDcs(event) && acceptGt(event) && acceptL1(event, setup) && acceptHlt(event));
0137 }
0138
0139 bool TriggerHelper::acceptDcs(const edm::Event &event) {
0140
0141 if (!onDcs_ || dcsPartitions_.empty())
0142 return (!andOr_);
0143
0144 bool useDCSRecord(false);
0145
0146
0147 edm::Handle<DcsStatusCollection> dcsStatus;
0148 event.getByToken(dcsInputToken_, dcsStatus);
0149
0150 edm::Handle<DCSRecord> dcsRecord;
0151 event.getByToken(dcsRecordToken_, dcsRecord);
0152
0153
0154 if (!dcsStatus.isValid() && !dcsRecord.isValid()) {
0155 edm::LogWarning("TriggerHelper") << "DcsStatusCollection product with InputTag \"" << dcsInputTag_.encode()
0156 << "\" not in event \n"
0157 << "DCSRecord product with InputTag \"" << dcsRecordInputTag_.encode()
0158 << "\" not in event \n"
0159 << " ==> decision: " << errorReplyDcs_;
0160 return errorReplyDcs_;
0161 }
0162 if (dcsStatus.isValid() && (*dcsStatus).empty()) {
0163 if (event.eventAuxiliary().isRealData()) {
0164
0165
0166 if (dcsRecord.isValid()) {
0167 useDCSRecord = true;
0168 } else {
0169 edm::LogWarning("TriggerHelper") << "DCSRecord product with InputTag \"" << dcsRecordInputTag_.encode()
0170 << "\" empty ==> decision: " << errorReplyDcs_;
0171 return errorReplyDcs_;
0172 }
0173 } else {
0174
0175 edm::LogInfo("TriggerHelper") << "DcsStatusCollection product with InputTag \"" << dcsInputTag_.encode()
0176 << "\" empty ==> decision: " << errorReplyDcs_;
0177 return errorReplyDcs_;
0178 }
0179 }
0180
0181
0182 if (andOrDcs_) {
0183 for (std::vector<int>::const_iterator partitionNumber = dcsPartitions_.begin();
0184 partitionNumber != dcsPartitions_.end();
0185 ++partitionNumber) {
0186 if (acceptDcsPartition(dcsStatus, dcsRecord, useDCSRecord, *partitionNumber))
0187 return true;
0188 }
0189 return false;
0190 }
0191 for (std::vector<int>::const_iterator partitionNumber = dcsPartitions_.begin();
0192 partitionNumber != dcsPartitions_.end();
0193 ++partitionNumber) {
0194 if (!acceptDcsPartition(dcsStatus, dcsRecord, useDCSRecord, *partitionNumber))
0195 return false;
0196 }
0197 return true;
0198 }
0199
0200 bool TriggerHelper::acceptDcsPartition(const edm::Handle<DcsStatusCollection> &dcsStatus,
0201 const edm::Handle<DCSRecord> &dcsRecord,
0202 bool useDCSRecord,
0203 int dcsPartition) const {
0204 int theDCSRecordPartition;
0205
0206 switch (dcsPartition) {
0207 case DcsStatus::EBp:
0208 theDCSRecordPartition = DCSRecord::EBp;
0209 break;
0210 case DcsStatus::EBm:
0211 theDCSRecordPartition = DCSRecord::EBm;
0212 break;
0213 case DcsStatus::EEp:
0214 theDCSRecordPartition = DCSRecord::EEp;
0215 break;
0216 case DcsStatus::EEm:
0217 theDCSRecordPartition = DCSRecord::EBm;
0218 break;
0219 case DcsStatus::HBHEa:
0220 theDCSRecordPartition = DCSRecord::HBHEa;
0221 break;
0222 case DcsStatus::HBHEb:
0223 theDCSRecordPartition = DCSRecord::HBHEb;
0224 break;
0225 case DcsStatus::HBHEc:
0226 theDCSRecordPartition = DCSRecord::HBHEc;
0227 break;
0228 case DcsStatus::HF:
0229 theDCSRecordPartition = DCSRecord::HF;
0230 break;
0231 case DcsStatus::HO:
0232 theDCSRecordPartition = DCSRecord::HO;
0233 break;
0234 case DcsStatus::RPC:
0235 theDCSRecordPartition = DCSRecord::RPC;
0236 break;
0237 case DcsStatus::DT0:
0238 theDCSRecordPartition = DCSRecord::DT0;
0239 break;
0240 case DcsStatus::DTp:
0241 theDCSRecordPartition = DCSRecord::DTp;
0242 break;
0243 case DcsStatus::DTm:
0244 theDCSRecordPartition = DCSRecord::DTm;
0245 break;
0246 case DcsStatus::CSCp:
0247 theDCSRecordPartition = DCSRecord::CSCp;
0248 break;
0249 case DcsStatus::CSCm:
0250 theDCSRecordPartition = DCSRecord::CSCm;
0251 break;
0252 case DcsStatus::CASTOR:
0253 theDCSRecordPartition = DCSRecord::CASTOR;
0254 break;
0255 case DcsStatus::TIBTID:
0256 theDCSRecordPartition = DCSRecord::TIBTID;
0257 break;
0258 case DcsStatus::TOB:
0259 theDCSRecordPartition = DCSRecord::TOB;
0260 break;
0261 case DcsStatus::TECp:
0262 theDCSRecordPartition = DCSRecord::TECp;
0263 break;
0264 case DcsStatus::TECm:
0265 theDCSRecordPartition = DCSRecord::TECm;
0266 break;
0267 case DcsStatus::BPIX:
0268 theDCSRecordPartition = DCSRecord::BPIX;
0269 break;
0270 case DcsStatus::FPIX:
0271 theDCSRecordPartition = DCSRecord::FPIX;
0272 break;
0273 case DcsStatus::ESp:
0274 theDCSRecordPartition = DCSRecord::ESp;
0275 break;
0276 case DcsStatus::ESm:
0277 theDCSRecordPartition = DCSRecord::ESm;
0278 break;
0279 default:
0280 edm::LogWarning("TriggerHelper") << "DCS partition number \"" << dcsPartition
0281 << "\" does not exist ==> decision: " << errorReplyDcs_;
0282 return errorReplyDcs_;
0283 }
0284
0285
0286 if (!useDCSRecord) {
0287 return dcsStatus->at(0).ready(dcsPartition);
0288 } else {
0289 LogDebug("TriggerHelper") << "using dcs record, dcsPartition:" << dcsPartition << " " << theDCSRecordPartition
0290 << " " << (*dcsRecord).partitionName(theDCSRecordPartition) << " "
0291 << (*dcsRecord).highVoltageReady(theDCSRecordPartition) << std::endl;
0292 return (*dcsRecord).highVoltageReady(theDCSRecordPartition);
0293 }
0294 }
0295
0296
0297
0298 bool TriggerHelper::acceptGt(const edm::Event &event) {
0299
0300 if (!onGt_ || gtLogicalExpressions_.empty())
0301 return (!andOr_);
0302
0303
0304 edm::Handle<L1GlobalTriggerReadoutRecord> gtReadoutRecord;
0305 event.getByToken(gtInputToken_, gtReadoutRecord);
0306 if (!gtReadoutRecord.isValid()) {
0307
0308
0309 return errorReplyGt_;
0310 }
0311
0312
0313
0314 if (andOrGt_) {
0315 for (std::vector<std::string>::const_iterator gtLogicalExpression = gtLogicalExpressions_.begin();
0316 gtLogicalExpression != gtLogicalExpressions_.end();
0317 ++gtLogicalExpression) {
0318 if (acceptGtLogicalExpression(gtReadoutRecord, *gtLogicalExpression))
0319 return true;
0320 }
0321 return false;
0322 }
0323 for (std::vector<std::string>::const_iterator gtLogicalExpression = gtLogicalExpressions_.begin();
0324 gtLogicalExpression != gtLogicalExpressions_.end();
0325 ++gtLogicalExpression) {
0326 if (!acceptGtLogicalExpression(gtReadoutRecord, *gtLogicalExpression))
0327 return false;
0328 }
0329 return true;
0330 }
0331
0332
0333 bool TriggerHelper::acceptGtLogicalExpression(const edm::Handle<L1GlobalTriggerReadoutRecord> >ReadoutRecord,
0334 std::string gtLogicalExpression) {
0335
0336 if (gtLogicalExpression.empty()) {
0337 edm::LogError("TriggerHelper") << "Empty logical expression ==> decision: " << errorReplyGt_;
0338 return errorReplyGt_;
0339 }
0340
0341
0342 bool negExpr(negate(gtLogicalExpression));
0343 if (negExpr && gtLogicalExpression.empty()) {
0344 edm::LogError("TriggerHelper") << "Empty (negated) logical expression ==> decision: " << errorReplyGt_;
0345 return errorReplyGt_;
0346 }
0347
0348
0349 L1GtLogicParser gtAlgoLogicParser(gtLogicalExpression);
0350
0351 for (size_t iStatusBit = 0; iStatusBit < gtAlgoLogicParser.operandTokenVector().size(); ++iStatusBit) {
0352 const std::string gtStatusBit(gtAlgoLogicParser.operandTokenVector().at(iStatusBit).tokenName);
0353
0354 bool decision;
0355
0356 if (gtStatusBit == "PhysDecl" || gtStatusBit == "PhysicsDeclared") {
0357 decision = (gtReadoutRecord->gtFdlWord().physicsDeclared() == 1);
0358 } else {
0359 edm::LogError("TriggerHelper") << "GT status bit \"" << gtStatusBit
0360 << "\" is not defined ==> decision: " << errorReplyGt_;
0361 decision = errorReplyDcs_;
0362 }
0363 gtAlgoLogicParser.operandTokenVector().at(iStatusBit).tokenResult = decision;
0364 }
0365
0366
0367 const bool gtDecision(gtAlgoLogicParser.expressionResult());
0368 return negExpr ? (!gtDecision) : gtDecision;
0369 }
0370
0371
0372 bool TriggerHelper::acceptL1(const edm::Event &event, const edm::EventSetup &setup) {
0373
0374 if (!onL1_ || l1LogicalExpressions_.empty())
0375 return (!andOr_);
0376
0377
0378 l1Gt_->retrieveL1EventSetup(setup);
0379
0380
0381 if (andOrL1_) {
0382 for (std::vector<std::string>::const_iterator l1LogicalExpression = l1LogicalExpressions_.begin();
0383 l1LogicalExpression != l1LogicalExpressions_.end();
0384 ++l1LogicalExpression) {
0385 if (acceptL1LogicalExpression(event, *l1LogicalExpression))
0386 return true;
0387 }
0388 return false;
0389 }
0390 for (std::vector<std::string>::const_iterator l1LogicalExpression = l1LogicalExpressions_.begin();
0391 l1LogicalExpression != l1LogicalExpressions_.end();
0392 ++l1LogicalExpression) {
0393 if (!acceptL1LogicalExpression(event, *l1LogicalExpression))
0394 return false;
0395 }
0396 return true;
0397 }
0398
0399
0400
0401 bool TriggerHelper::acceptL1LogicalExpression(const edm::Event &event, std::string l1LogicalExpression) {
0402
0403 if (l1LogicalExpression.empty()) {
0404 edm::LogError("TriggerHelper") << "Empty logical expression ==> decision: " << errorReplyL1_;
0405 return errorReplyL1_;
0406 }
0407
0408
0409 bool negExpr(negate(l1LogicalExpression));
0410 if (negExpr && l1LogicalExpression.empty()) {
0411 edm::LogError("TriggerHelper") << "Empty (negated) logical expression ==> decision: " << errorReplyL1_;
0412 return errorReplyL1_;
0413 }
0414
0415
0416 L1GtLogicParser l1AlgoLogicParser(l1LogicalExpression);
0417
0418 for (size_t iAlgorithm = 0; iAlgorithm < l1AlgoLogicParser.operandTokenVector().size(); ++iAlgorithm) {
0419 const std::string l1AlgoName(l1AlgoLogicParser.operandTokenVector().at(iAlgorithm).tokenName);
0420 int error(-1);
0421 const bool decision(l1Gt_->decision(event, l1AlgoName, error));
0422
0423 if (error != 0) {
0424 if (error == 1)
0425 edm::LogError("TriggerHelper") << "L1 algorithm \"" << l1AlgoName
0426 << "\" does not exist in the L1 menu ==> decision: " << errorReplyL1_;
0427 else
0428 edm::LogError("TriggerHelper") << "L1 algorithm \"" << l1AlgoName << "\" received error code " << error
0429 << " from L1GtUtils::decisionBeforeMask ==> decision: " << errorReplyL1_;
0430 l1AlgoLogicParser.operandTokenVector().at(iAlgorithm).tokenResult = errorReplyL1_;
0431 continue;
0432 }
0433
0434 l1AlgoLogicParser.operandTokenVector().at(iAlgorithm).tokenResult = decision;
0435 }
0436
0437
0438 const bool l1Decision(l1AlgoLogicParser.expressionResult());
0439 return negExpr ? (!l1Decision) : l1Decision;
0440 }
0441
0442
0443
0444 bool TriggerHelper::acceptHlt(const edm::Event &event) {
0445
0446 if (!onHlt_ || hltLogicalExpressions_.empty())
0447 return (!andOr_);
0448
0449
0450 if (!hltConfigInit_) {
0451 edm::LogError("TriggerHelper") << "HLT config error ==> decision: " << errorReplyHlt_;
0452 return errorReplyHlt_;
0453 }
0454
0455
0456 edm::Handle<edm::TriggerResults> hltTriggerResults;
0457 event.getByToken(hltInputToken_, hltTriggerResults);
0458 if (!hltTriggerResults.isValid()) {
0459 edm::LogError("TriggerHelper") << "TriggerResults product with InputTag \"" << hltInputTag_.encode()
0460 << "\" not in event ==> decision: " << errorReplyHlt_;
0461 return errorReplyHlt_;
0462 }
0463
0464
0465 if (andOrHlt_) {
0466 for (std::vector<std::string>::const_iterator hltLogicalExpression = hltLogicalExpressions_.begin();
0467 hltLogicalExpression != hltLogicalExpressions_.end();
0468 ++hltLogicalExpression) {
0469 if (acceptHltLogicalExpression(hltTriggerResults, *hltLogicalExpression))
0470 return true;
0471 }
0472 return false;
0473 }
0474 for (std::vector<std::string>::const_iterator hltLogicalExpression = hltLogicalExpressions_.begin();
0475 hltLogicalExpression != hltLogicalExpressions_.end();
0476 ++hltLogicalExpression) {
0477 if (!acceptHltLogicalExpression(hltTriggerResults, *hltLogicalExpression))
0478 return false;
0479 }
0480 return true;
0481 }
0482
0483
0484 bool TriggerHelper::acceptHltLogicalExpression(const edm::Handle<edm::TriggerResults> &hltTriggerResults,
0485 std::string hltLogicalExpression) const {
0486
0487 if (hltLogicalExpression.empty()) {
0488 edm::LogError("TriggerHelper") << "Empty logical expression ==> decision: " << errorReplyHlt_;
0489 return errorReplyHlt_;
0490 }
0491
0492
0493 bool negExpr(negate(hltLogicalExpression));
0494 if (negExpr && hltLogicalExpression.empty()) {
0495 edm::LogError("TriggerHelper") << "Empty (negated) logical expression ==> decision: " << errorReplyHlt_;
0496 return errorReplyHlt_;
0497 }
0498
0499
0500 L1GtLogicParser hltAlgoLogicParser(hltLogicalExpression);
0501
0502 for (size_t iPath = 0; iPath < hltAlgoLogicParser.operandTokenVector().size(); ++iPath) {
0503 const std::string hltPathName(hltAlgoLogicParser.operandTokenVector().at(iPath).tokenName);
0504 const unsigned indexPath(hltConfig_.triggerIndex(hltPathName));
0505
0506 if (indexPath == hltConfig_.size()) {
0507 edm::LogError("TriggerHelper") << "HLT path \"" << hltPathName << "\" is not found in process "
0508 << hltInputTag_.process() << " ==> decision: " << errorReplyHlt_;
0509 hltAlgoLogicParser.operandTokenVector().at(iPath).tokenResult = errorReplyHlt_;
0510 continue;
0511 }
0512 if (hltTriggerResults->error(indexPath)) {
0513 edm::LogError("TriggerHelper") << "HLT path \"" << hltPathName << "\" in error ==> decision: " << errorReplyHlt_;
0514 hltAlgoLogicParser.operandTokenVector().at(iPath).tokenResult = errorReplyHlt_;
0515 continue;
0516 }
0517
0518 const bool decision(hltTriggerResults->accept(indexPath));
0519 hltAlgoLogicParser.operandTokenVector().at(iPath).tokenResult = decision;
0520 }
0521
0522
0523 const bool hltDecision(hltAlgoLogicParser.expressionResult());
0524 return negExpr ? (!hltDecision) : hltDecision;
0525 }
0526
0527
0528 std::vector<std::string> TriggerHelper::expressionsFromDB(const std::string &key, const edm::EventSetup &setup) {
0529 const AlCaRecoTriggerBits *logicalExpressions = &(setup.getData(alcaRecotriggerBitsToken_));
0530 const std::map<std::string, std::string> &expressionMap = logicalExpressions->m_alcarecoToTrig;
0531 std::map<std::string, std::string>::const_iterator listIter = expressionMap.find(key);
0532 if (listIter == expressionMap.end()) {
0533 edm::LogError("TriggerHelper") << "No logical expressions found under key " << key
0534 << " in 'AlCaRecoTriggerBitsRcd'";
0535 return std::vector<std::string>(1, configError_);
0536 }
0537 return logicalExpressions->decompose(listIter->second);
0538 }
0539
0540
0541 bool TriggerHelper::negate(std::string &word) const {
0542 bool negate(false);
0543 if (word.at(0) == '~') {
0544 negate = true;
0545 word.erase(0, 1);
0546 }
0547 return negate;
0548 }