Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:08:59

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 /// To be called from the ED module's c'tor
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   // General switch(es)
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 /// To be called from d'tors by 'delete'
0083 TriggerHelper::~TriggerHelper() {
0084   if (on_)
0085     delete watchDB_;
0086 }
0087 
0088 /// To be called from beginedm::Run() methods
0089 void TriggerHelper::initRun(const edm::Run &run, const edm::EventSetup &setup) {
0090   // FIXME Can this stay safely in the run loop, or does it need to go to the
0091   // event loop? Means: Are the event setups identical?
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 /// To be called from analyze/filter() methods
0129 bool TriggerHelper::accept(const edm::Event &event, const edm::EventSetup &setup) {
0130   if (!on_)
0131     return true;
0132 
0133   // Determine decision
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   // An empty DCS partitions list acts as switch.
0141   if (!onDcs_ || dcsPartitions_.empty())
0142     return (!andOr_);  // logically neutral, depending on base logical connective
0143 
0144   bool useDCSRecord(false);
0145 
0146   // Accessing the DcsStatusCollection
0147   edm::Handle<DcsStatusCollection> dcsStatus;
0148   event.getByToken(dcsInputToken_, dcsStatus);
0149 
0150   edm::Handle<DCSRecord> dcsRecord;
0151   event.getByToken(dcsRecordToken_, dcsRecord);
0152 
0153   // none of the DCS products is valid
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       // this is the Data case for >= Run3, DCSStatus is available (unpacked), but empty
0165       // becasue SCAL is not in data-taking. In this case we fall back to s/w FED 1022
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       // this is the case in which the DCS status is empty, but it's not real data.
0175       edm::LogInfo("TriggerHelper") << "DcsStatusCollection product with InputTag \"" << dcsInputTag_.encode()
0176                                     << "\" empty ==> decision: " << errorReplyDcs_;
0177       return errorReplyDcs_;
0178     }
0179   }
0180 
0181   // Determine decision of DCS partition combination and return
0182   if (andOrDcs_) {  // OR combination
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   // Error checks
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   // Determine decision
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 /// Does this event fulfill the configured GT status logical expression
0297 /// combination?
0298 bool TriggerHelper::acceptGt(const edm::Event &event) {
0299   // An empty GT status bits logical expressions list acts as switch.
0300   if (!onGt_ || gtLogicalExpressions_.empty())
0301     return (!andOr_);  // logically neutral, depending on base logical connective
0302 
0303   // Accessing the L1GlobalTriggerReadoutRecord
0304   edm::Handle<L1GlobalTriggerReadoutRecord> gtReadoutRecord;
0305   event.getByToken(gtInputToken_, gtReadoutRecord);
0306   if (!gtReadoutRecord.isValid()) {
0307     //edm::LogError("TriggerHelper") << "L1GlobalTriggerReadoutRecord product with InputTag \"" << gtInputTag_.encode()
0308     //                               << "\" not in event ==> decision: " << errorReplyGt_;
0309     return errorReplyGt_;
0310   }
0311 
0312   // Determine decision of GT status bits logical expression combination and
0313   // return
0314   if (andOrGt_) {  // OR combination
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 /// Does this event fulfill this particular GT status bits' logical expression?
0333 bool TriggerHelper::acceptGtLogicalExpression(const edm::Handle<L1GlobalTriggerReadoutRecord> &gtReadoutRecord,
0334                                               std::string gtLogicalExpression) {
0335   // Check empty std::strings
0336   if (gtLogicalExpression.empty()) {
0337     edm::LogError("TriggerHelper") << "Empty logical expression ==> decision: " << errorReplyGt_;
0338     return errorReplyGt_;
0339   }
0340 
0341   // Negated paths
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   // Parse logical expression and determine GT status bit decision
0349   L1GtLogicParser gtAlgoLogicParser(gtLogicalExpression);
0350   // Loop over status bits
0351   for (size_t iStatusBit = 0; iStatusBit < gtAlgoLogicParser.operandTokenVector().size(); ++iStatusBit) {
0352     const std::string gtStatusBit(gtAlgoLogicParser.operandTokenVector().at(iStatusBit).tokenName);
0353     // Manipulate status bit decision as stored in the parser
0354     bool decision;
0355     // Hard-coded status bits!!!
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   // Determine decision
0367   const bool gtDecision(gtAlgoLogicParser.expressionResult());
0368   return negExpr ? (!gtDecision) : gtDecision;
0369 }
0370 
0371 /// Was this event accepted by the configured L1 logical expression combination?
0372 bool TriggerHelper::acceptL1(const edm::Event &event, const edm::EventSetup &setup) {
0373   // An empty L1 logical expressions list acts as switch.
0374   if (!onL1_ || l1LogicalExpressions_.empty())
0375     return (!andOr_);  // logically neutral, depending on base logical connective
0376 
0377   // Getting the L1 event setup
0378   l1Gt_->retrieveL1EventSetup(setup);  // FIXME This can possibly go to initRun()
0379 
0380   // Determine decision of L1 logical expression combination and return
0381   if (andOrL1_) {  // OR combination
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 /// Was this event accepted by this particular L1 algorithms' logical
0400 /// expression?
0401 bool TriggerHelper::acceptL1LogicalExpression(const edm::Event &event, std::string l1LogicalExpression) {
0402   // Check empty std::strings
0403   if (l1LogicalExpression.empty()) {
0404     edm::LogError("TriggerHelper") << "Empty logical expression ==> decision: " << errorReplyL1_;
0405     return errorReplyL1_;
0406   }
0407 
0408   // Negated logical expression
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   // Parse logical expression and determine L1 decision
0416   L1GtLogicParser l1AlgoLogicParser(l1LogicalExpression);
0417   // Loop over algorithms
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     // Error checks
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     // Manipulate algo decision as stored in the parser
0434     l1AlgoLogicParser.operandTokenVector().at(iAlgorithm).tokenResult = decision;
0435   }
0436 
0437   // Return decision
0438   const bool l1Decision(l1AlgoLogicParser.expressionResult());
0439   return negExpr ? (!l1Decision) : l1Decision;
0440 }
0441 
0442 /// Was this event accepted by the configured HLT logical expression
0443 /// combination?
0444 bool TriggerHelper::acceptHlt(const edm::Event &event) {
0445   // An empty HLT logical expressions list acts as switch.
0446   if (!onHlt_ || hltLogicalExpressions_.empty())
0447     return (!andOr_);  // logically neutral, depending on base logical connective
0448 
0449   // Checking the HLT configuration,
0450   if (!hltConfigInit_) {
0451     edm::LogError("TriggerHelper") << "HLT config error ==> decision: " << errorReplyHlt_;
0452     return errorReplyHlt_;
0453   }
0454 
0455   // Accessing the TriggerResults
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   // Determine decision of HLT logical expression combination and return
0465   if (andOrHlt_) {  // OR combination
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 /// Was this event accepted by this particular HLT paths' logical expression?
0484 bool TriggerHelper::acceptHltLogicalExpression(const edm::Handle<edm::TriggerResults> &hltTriggerResults,
0485                                                std::string hltLogicalExpression) const {
0486   // Check empty std::strings
0487   if (hltLogicalExpression.empty()) {
0488     edm::LogError("TriggerHelper") << "Empty logical expression ==> decision: " << errorReplyHlt_;
0489     return errorReplyHlt_;
0490   }
0491 
0492   // Negated paths
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   // Parse logical expression and determine HLT decision
0500   L1GtLogicParser hltAlgoLogicParser(hltLogicalExpression);
0501   // Loop over paths
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     // Further error checks
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     // Manipulate algo decision as stored in the parser
0518     const bool decision(hltTriggerResults->accept(indexPath));
0519     hltAlgoLogicParser.operandTokenVector().at(iPath).tokenResult = decision;
0520   }
0521 
0522   // Determine decision
0523   const bool hltDecision(hltAlgoLogicParser.expressionResult());
0524   return negExpr ? (!hltDecision) : hltDecision;
0525 }
0526 
0527 /// Reads and returns logical expressions from DB
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 /// Checks for negated words
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 }