Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:01:15

0001 //
0002 // $Id: GenericTriggerEventFlag.cc,v 1.13 2012/04/22 15:09:29 vadler Exp $
0003 //
0004 
0005 #include "CommonTools/TriggerUtils/interface/GenericTriggerEventFlag.h"
0006 
0007 #include "DataFormats/L1GlobalTrigger/interface/L1GtLogicParser.h"
0008 
0009 #include <memory>
0010 
0011 #include <vector>
0012 
0013 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0014 #include "FWCore/Utilities/interface/Transition.h"
0015 
0016 // Constants' definitions
0017 static const bool useL1EventSetup(true);
0018 static const bool useL1GtTriggerMenuLite(false);
0019 
0020 GenericTriggerEventFlag::GenericTriggerEventFlag(const edm::ParameterSet& config,
0021                                                  edm::ConsumesCollector& iC,
0022                                                  l1t::UseEventSetupIn use)
0023     : GenericTriggerEventFlag(config, iC, false) {
0024   if (config.exists("andOrL1")) {
0025     if (stage2_) {
0026       l1uGt_ = std::make_unique<l1t::L1TGlobalUtil>(config, iC, use);
0027     }
0028   }
0029 }
0030 
0031 /// To be called from the ED module's c'tor
0032 GenericTriggerEventFlag::GenericTriggerEventFlag(const edm::ParameterSet& config,
0033                                                  edm::ConsumesCollector& iC,
0034                                                  bool stage1Valid)
0035     : watchDB_(),
0036       hltConfigInit_(false),
0037       andOr_(false),
0038       dbLabel_(""),
0039       verbose_(0),
0040       andOrDcs_(false),
0041       errorReplyDcs_(false),
0042       andOrGt_(false),
0043       gtInputTag_(""),
0044       gtEvmInputTag_(""),
0045       gtDBKey_(""),
0046       errorReplyGt_(false),
0047       andOrL1_(false),
0048       stage2_(false),
0049       l1BeforeMask_(true),
0050       l1DBKey_(""),
0051       errorReplyL1_(false),
0052       andOrHlt_(false),
0053       hltDBKey_(""),
0054       errorReplyHlt_(false),
0055       on_(true),
0056       onDcs_(true),
0057       onGt_(true),
0058       onL1_(true),
0059       onHlt_(true),
0060       configError_("CONFIG_ERROR"),
0061       emptyKeyError_("EMPTY_KEY_ERROR") {
0062   // General switch(es)
0063   if (config.exists("andOr")) {
0064     andOr_ = config.getParameter<bool>("andOr");
0065     if (config.exists("verbosityLevel"))
0066       verbose_ = config.getParameter<unsigned>("verbosityLevel");
0067   } else {
0068     on_ = false;
0069     onDcs_ = false;
0070     onGt_ = false;
0071     onL1_ = false;
0072     onHlt_ = false;
0073   }
0074 
0075   if (on_) {
0076     if (config.exists("andOrDcs")) {
0077       andOrDcs_ = config.getParameter<bool>("andOrDcs");
0078       dcsInputTag_ = config.getParameter<edm::InputTag>("dcsInputTag");
0079       dcsInputToken_ = iC.mayConsume<DcsStatusCollection>(dcsInputTag_);
0080       dcsRecordInputTag_ = config.getParameter<edm::InputTag>("dcsRecordInputTag");
0081       dcsRecordToken_ = iC.mayConsume<DCSRecord>(dcsRecordInputTag_);
0082       dcsPartitions_ = config.getParameter<std::vector<int>>("dcsPartitions");
0083       errorReplyDcs_ = config.getParameter<bool>("errorReplyDcs");
0084     } else {
0085       onDcs_ = false;
0086     }
0087     if (config.exists("andOrGt")) {
0088       andOrGt_ = config.getParameter<bool>("andOrGt");
0089       gtInputTag_ = config.getParameter<edm::InputTag>("gtInputTag");
0090       gtInputToken_ = iC.mayConsume<L1GlobalTriggerReadoutRecord>(gtInputTag_);
0091       gtLogicalExpressions_ = config.getParameter<std::vector<std::string>>("gtStatusBits");
0092       errorReplyGt_ = config.getParameter<bool>("errorReplyGt");
0093       if (config.exists("gtEvmInputTag")) {
0094         gtEvmInputTag_ = config.getParameter<edm::InputTag>("gtEvmInputTag");
0095         gtEvmInputToken_ = iC.mayConsume<L1GlobalTriggerEvmReadoutRecord>(gtEvmInputTag_);
0096       }
0097       if (config.exists("gtDBKey"))
0098         gtDBKey_ = config.getParameter<std::string>("gtDBKey");
0099     } else {
0100       onGt_ = false;
0101     }
0102     if (config.exists("andOrL1")) {
0103       andOrL1_ = config.getParameter<bool>("andOrL1");
0104       if (config.exists("stage2"))
0105         stage2_ = config.getParameter<bool>("stage2");
0106       else
0107         stage2_ = false;
0108       l1LogicalExpressionsCache_ = config.getParameter<std::vector<std::string>>("l1Algorithms");
0109       errorReplyL1_ = config.getParameter<bool>("errorReplyL1");
0110       if (config.exists("l1DBKey"))
0111         l1DBKey_ = config.getParameter<std::string>("l1DBKey");
0112       if (config.exists("l1BeforeMask"))
0113         l1BeforeMask_ = config.getParameter<bool>("l1BeforeMask");
0114     } else {
0115       onL1_ = false;
0116     }
0117     if (config.exists("andOrHlt")) {
0118       andOrHlt_ = config.getParameter<bool>("andOrHlt");
0119       hltInputTag_ = config.getParameter<edm::InputTag>("hltInputTag");
0120       hltInputToken_ = iC.mayConsume<edm::TriggerResults>(hltInputTag_);
0121       hltLogicalExpressionsCache_ = config.getParameter<std::vector<std::string>>("hltPaths");
0122       errorReplyHlt_ = config.getParameter<bool>("errorReplyHlt");
0123       if (config.exists("hltDBKey"))
0124         hltDBKey_ = config.getParameter<std::string>("hltDBKey");
0125     } else {
0126       onHlt_ = false;
0127     }
0128     if (!onDcs_ && !onGt_ && !onL1_ && !onHlt_)
0129       on_ = false;
0130     else {
0131       if (config.exists("dbLabel"))
0132         dbLabel_ = config.getParameter<std::string>("dbLabel");
0133       watchDB_ = std::make_unique<edm::ESWatcher<AlCaRecoTriggerBitsRcd>>();
0134     }
0135   }
0136 
0137   if (onL1_ && !stage2_) {
0138     l1GtTriggerMenuToken_ = iC.esConsumes<L1GtTriggerMenu, L1GtTriggerMenuRcd, edm::Transition::BeginRun>();
0139   }
0140   if ((onGt_ && !gtDBKey_.empty()) || (onL1_ && !l1DBKey_.empty()) || (onHlt_ && !hltDBKey_.empty())) {
0141     alCaRecoTriggerBitsToken_ = iC.esConsumes<AlCaRecoTriggerBits, AlCaRecoTriggerBitsRcd, edm::Transition::BeginRun>(
0142         edm::ESInputTag{"", dbLabel_});
0143   }
0144 
0145   //check to see we arent trying to setup legacy / stage-1 from a constructor call
0146   //that does not support it
0147   if (config.exists("andOrL1") && stage2_ == false) {  //stage-1 setup
0148     if (stage1Valid == false)
0149       throw cms::Exception("ConfigError") << " Error when constructing GenericTriggerEventFlag, legacy/stage-1 is "
0150                                              "requested but the constructor called is stage2 only";
0151   }
0152 }
0153 
0154 /// To be called from beginRun() methods
0155 void GenericTriggerEventFlag::initRun(const edm::Run& run, const edm::EventSetup& setup) {
0156   if (watchDB_->check(setup)) {
0157     if (onGt_ && !gtDBKey_.empty()) {
0158       const std::vector<std::string> exprs(expressionsFromDB(gtDBKey_, setup));
0159       if (exprs.empty() || exprs.at(0) != configError_)
0160         gtLogicalExpressions_ = exprs;
0161     }
0162     if (onL1_ && !l1DBKey_.empty()) {
0163       const std::vector<std::string> exprs(expressionsFromDB(l1DBKey_, setup));
0164       if (exprs.empty() || exprs.at(0) != configError_)
0165         l1LogicalExpressionsCache_ = exprs;
0166     }
0167     if (onHlt_ && !hltDBKey_.empty()) {
0168       const std::vector<std::string> exprs(expressionsFromDB(hltDBKey_, setup));
0169       if (exprs.empty() || exprs.at(0) != configError_)
0170         hltLogicalExpressionsCache_ = exprs;
0171     }
0172   }
0173 
0174   // Re-initialise starting valuse before wild-card expansion
0175   l1LogicalExpressions_ = l1LogicalExpressionsCache_;
0176   hltLogicalExpressions_ = hltLogicalExpressionsCache_;
0177 
0178   hltConfigInit_ = false;
0179   if (onHlt_) {
0180     if (hltInputTag_.process().empty()) {
0181       if (verbose_ > 0)
0182         edm::LogError("GenericTriggerEventFlag")
0183             << "HLT TriggerResults InputTag \"" << hltInputTag_.encode() << "\" specifies no process";
0184     } else {
0185       bool hltChanged(false);
0186       if (!hltConfig_.init(run, setup, hltInputTag_.process(), hltChanged)) {
0187         if (verbose_ > 0)
0188           edm::LogError("GenericTriggerEventFlag")
0189               << "HLT config initialization error with process name \"" << hltInputTag_.process() << "\"";
0190       } else if (hltConfig_.size() <= 0) {
0191         if (verbose_ > 0)
0192           edm::LogError("GenericTriggerEventFlag") << "HLT config size error";
0193       } else
0194         hltConfigInit_ = true;
0195     }
0196   }
0197 
0198   // Expand version wild-cards in HLT logical expressions
0199   // L1
0200   if (onL1_) {
0201     // build vector of algo names
0202 
0203     std::vector<std::string> algoNames;
0204 
0205     if (stage2_) {
0206       l1uGt_->retrieveL1Setup(setup);
0207 
0208       const std::vector<std::pair<std::string, double>> prescales = l1uGt_->prescales();
0209       for (const auto& ip : prescales)
0210         algoNames.push_back(ip.first);
0211     } else {
0212       l1Gt_->getL1GtRunCache(run, setup, useL1EventSetup, useL1GtTriggerMenuLite);
0213       L1GtTriggerMenu const& l1GtTriggerMenu = setup.get<L1GtTriggerMenuRcd>().get(l1GtTriggerMenuToken_);
0214 
0215       const AlgorithmMap& l1GtPhys(l1GtTriggerMenu.gtAlgorithmMap());
0216       for (CItAlgo iAlgo = l1GtPhys.begin(); iAlgo != l1GtPhys.end(); ++iAlgo) {
0217         algoNames.push_back(iAlgo->second.algoName());
0218       }
0219       const AlgorithmMap& l1GtTech(l1GtTriggerMenu.gtTechnicalTriggerMap());
0220       for (CItAlgo iAlgo = l1GtTech.begin(); iAlgo != l1GtTech.end(); ++iAlgo) {
0221         algoNames.push_back(iAlgo->second.algoName());
0222       }
0223     }
0224 
0225     for (unsigned iExpr = 0; iExpr < l1LogicalExpressions_.size(); ++iExpr) {
0226       std::string l1LogicalExpression(l1LogicalExpressions_.at(iExpr));
0227       L1GtLogicParser l1AlgoLogicParser(l1LogicalExpression);
0228       // Loop over algorithms
0229       for (size_t iAlgo = 0; iAlgo < l1AlgoLogicParser.operandTokenVector().size(); ++iAlgo) {
0230         const std::string l1AlgoName(l1AlgoLogicParser.operandTokenVector().at(iAlgo).tokenName);
0231         if (l1AlgoName.find('*') != std::string::npos) {
0232           l1LogicalExpression.replace(
0233               l1LogicalExpression.find(l1AlgoName), l1AlgoName.size(), expandLogicalExpression(algoNames, l1AlgoName));
0234         }
0235       }
0236       l1LogicalExpressions_[iExpr] = l1LogicalExpression;
0237     }
0238     std::vector<std::string> tmp = l1LogicalExpressions_;
0239     for (unsigned iExpr = 0; iExpr < tmp.size(); ++iExpr)
0240       if (std::find(algoNames.begin(), algoNames.end(), tmp[iExpr]) == algoNames.end()) {
0241         l1LogicalExpressions_.erase(l1LogicalExpressions_.begin() + iExpr);
0242         if (verbose_ > 1)
0243           edm::LogWarning("GenericTriggerEventFlag")
0244               << "L1 algorithm \"" << tmp[iExpr]
0245               << "\" does not exist in the L1 menu ==> drop it from the list of l1LogicalExpressions";
0246       }
0247   }
0248   // HLT
0249   if (hltConfigInit_) {
0250     for (unsigned iExpr = 0; iExpr < hltLogicalExpressions_.size(); ++iExpr) {
0251       std::string hltLogicalExpression(hltLogicalExpressions_.at(iExpr));
0252       L1GtLogicParser hltAlgoLogicParser(hltLogicalExpression);
0253       // Loop over paths
0254       for (size_t iPath = 0; iPath < hltAlgoLogicParser.operandTokenVector().size(); ++iPath) {
0255         const std::string hltPathName(hltAlgoLogicParser.operandTokenVector().at(iPath).tokenName);
0256         if (hltPathName.find('*') != std::string::npos) {
0257           hltLogicalExpression.replace(hltLogicalExpression.find(hltPathName),
0258                                        hltPathName.size(),
0259                                        expandLogicalExpression(hltConfig_.triggerNames(), hltPathName));
0260         }
0261       }
0262       hltLogicalExpressions_[iExpr] = hltLogicalExpression;
0263     }
0264   }
0265 }
0266 
0267 /// To be called from analyze/filter() methods
0268 bool GenericTriggerEventFlag::accept(const edm::Event& event, const edm::EventSetup& setup) {
0269   if (!on_)
0270     return true;
0271 
0272   // Determine decision
0273   if (andOr_)
0274     return (acceptDcs(event) || acceptGt(event) || acceptL1(event, setup) || acceptHlt(event));
0275   return (acceptDcs(event) && acceptGt(event) && acceptL1(event, setup) && acceptHlt(event));
0276 }
0277 
0278 bool GenericTriggerEventFlag::acceptDcs(const edm::Event& event) {
0279   // An empty DCS partitions list acts as switch.
0280   if (!onDcs_ || dcsPartitions_.empty())
0281     return (!andOr_);  // logically neutral, depending on base logical connective
0282 
0283   bool useDCSRecord(false);
0284 
0285   // Accessing the DcsStatusCollection
0286   edm::Handle<DcsStatusCollection> dcsStatus;
0287   event.getByToken(dcsInputToken_, dcsStatus);
0288 
0289   edm::Handle<DCSRecord> dcsRecord;
0290   event.getByToken(dcsRecordToken_, dcsRecord);
0291 
0292   // none of the DCS products is valid
0293   if (!dcsStatus.isValid() && !dcsRecord.isValid()) {
0294     if (verbose_ > 1)
0295       edm::LogWarning("GenericTriggerEventFlag")
0296           << "DcsStatusCollection product with InputTag \"" << dcsInputTag_.encode() << "\" not in event \n"
0297           << "DCSRecord product with InputTag \"" << dcsRecordInputTag_.encode() << "\" not in event \n"
0298           << " ==> decision: " << errorReplyDcs_;
0299     return errorReplyDcs_;
0300   }
0301   if (dcsStatus.isValid() && (*dcsStatus).empty()) {
0302     if (event.eventAuxiliary().isRealData()) {
0303       // this is the Data case for >= Run3, DCSStatus is available (unpacked), but empty
0304       // becasue SCAL is not in data-taking. In this case we fall back to s/w FED 1022
0305       if (dcsRecord.isValid()) {
0306         useDCSRecord = true;
0307       } else {
0308         if (verbose_ > 1)
0309           edm::LogWarning("GenericTriggerEventFlag")
0310               << "DCSRecord product with InputTag \"" << dcsRecordInputTag_.encode()
0311               << "\" empty ==> decision: " << errorReplyDcs_;
0312         return errorReplyDcs_;
0313       }
0314     } else {
0315       // this is the case in which the DCS status is empty, but it's not real data.
0316       if (verbose_ > 1)
0317         edm::LogWarning("GenericTriggerEventFlag")
0318             << "DcsStatusCollection product with InputTag \"" << dcsInputTag_.encode()
0319             << "\" empty ==> decision: " << errorReplyDcs_;
0320       return errorReplyDcs_;
0321     }
0322   }
0323 
0324   // Determine decision of DCS partition combination and return
0325   if (andOrDcs_) {  // OR combination
0326     for (std::vector<int>::const_iterator partitionNumber = dcsPartitions_.begin();
0327          partitionNumber != dcsPartitions_.end();
0328          ++partitionNumber) {
0329       if (acceptDcsPartition(dcsStatus, dcsRecord, useDCSRecord, *partitionNumber))
0330         return true;
0331     }
0332     return false;
0333   }
0334   for (std::vector<int>::const_iterator partitionNumber = dcsPartitions_.begin();
0335        partitionNumber != dcsPartitions_.end();
0336        ++partitionNumber) {
0337     if (!acceptDcsPartition(dcsStatus, dcsRecord, useDCSRecord, *partitionNumber))
0338       return false;
0339   }
0340   return true;
0341 }
0342 
0343 bool GenericTriggerEventFlag::acceptDcsPartition(const edm::Handle<DcsStatusCollection>& dcsStatus,
0344                                                  const edm::Handle<DCSRecord>& dcsRecord,
0345                                                  bool useDCSRecord,
0346                                                  int dcsPartition) const {
0347   int theDCSRecordPartition;
0348   // Error checks
0349   switch (dcsPartition) {
0350     case DcsStatus::EBp:
0351       theDCSRecordPartition = DCSRecord::EBp;
0352       break;
0353     case DcsStatus::EBm:
0354       theDCSRecordPartition = DCSRecord::EBm;
0355       break;
0356     case DcsStatus::EEp:
0357       theDCSRecordPartition = DCSRecord::EEp;
0358       break;
0359     case DcsStatus::EEm:
0360       theDCSRecordPartition = DCSRecord::EBm;
0361       break;
0362     case DcsStatus::HBHEa:
0363       theDCSRecordPartition = DCSRecord::HBHEa;
0364       break;
0365     case DcsStatus::HBHEb:
0366       theDCSRecordPartition = DCSRecord::HBHEb;
0367       break;
0368     case DcsStatus::HBHEc:
0369       theDCSRecordPartition = DCSRecord::HBHEc;
0370       break;
0371     case DcsStatus::HF:
0372       theDCSRecordPartition = DCSRecord::HF;
0373       break;
0374     case DcsStatus::HO:
0375       theDCSRecordPartition = DCSRecord::HO;
0376       break;
0377     case DcsStatus::RPC:
0378       theDCSRecordPartition = DCSRecord::RPC;
0379       break;
0380     case DcsStatus::DT0:
0381       theDCSRecordPartition = DCSRecord::DT0;
0382       break;
0383     case DcsStatus::DTp:
0384       theDCSRecordPartition = DCSRecord::DTp;
0385       break;
0386     case DcsStatus::DTm:
0387       theDCSRecordPartition = DCSRecord::DTm;
0388       break;
0389     case DcsStatus::CSCp:
0390       theDCSRecordPartition = DCSRecord::CSCp;
0391       break;
0392     case DcsStatus::CSCm:
0393       theDCSRecordPartition = DCSRecord::CSCm;
0394       break;
0395     case DcsStatus::CASTOR:
0396       theDCSRecordPartition = DCSRecord::CASTOR;
0397       break;
0398     case DcsStatus::TIBTID:
0399       theDCSRecordPartition = DCSRecord::TIBTID;
0400       break;
0401     case DcsStatus::TOB:
0402       theDCSRecordPartition = DCSRecord::TOB;
0403       break;
0404     case DcsStatus::TECp:
0405       theDCSRecordPartition = DCSRecord::TECp;
0406       break;
0407     case DcsStatus::TECm:
0408       theDCSRecordPartition = DCSRecord::TECm;
0409       break;
0410     case DcsStatus::BPIX:
0411       theDCSRecordPartition = DCSRecord::BPIX;
0412       break;
0413     case DcsStatus::FPIX:
0414       theDCSRecordPartition = DCSRecord::FPIX;
0415       break;
0416     case DcsStatus::ESp:
0417       theDCSRecordPartition = DCSRecord::ESp;
0418       break;
0419     case DcsStatus::ESm:
0420       theDCSRecordPartition = DCSRecord::ESm;
0421       break;
0422     default:
0423       if (verbose_ > 1)
0424         edm::LogWarning("GenericTriggerEventFlag")
0425             << "DCS partition number \"" << dcsPartition << "\" does not exist ==> decision: " << errorReplyDcs_;
0426       return errorReplyDcs_;
0427   }
0428 
0429   // Determine decision
0430   if (!useDCSRecord) {
0431     return dcsStatus->at(0).ready(dcsPartition);
0432   } else {
0433     if (verbose_ > 2) {
0434       LogDebug("GenericTriggerEventFlag")
0435           << "using dcs record, dcsPartition:" << dcsPartition << " " << theDCSRecordPartition << " "
0436           << (*dcsRecord).partitionName(theDCSRecordPartition) << " "
0437           << (*dcsRecord).highVoltageReady(theDCSRecordPartition) << std::endl;
0438     }
0439     return (*dcsRecord).highVoltageReady(theDCSRecordPartition);
0440   }
0441 }
0442 
0443 /// Does this event fulfill the configured GT status logical expression combination?
0444 bool GenericTriggerEventFlag::acceptGt(const edm::Event& event) {
0445   // An empty GT status bits logical expressions list acts as switch.
0446   if (!onGt_ || gtLogicalExpressions_.empty())
0447     return (!andOr_);  // logically neutral, depending on base logical connective
0448 
0449   // Determine decision of GT status bits logical expression combination and return
0450   if (andOrGt_) {  // OR combination
0451     for (std::vector<std::string>::const_iterator gtLogicalExpression = gtLogicalExpressions_.begin();
0452          gtLogicalExpression != gtLogicalExpressions_.end();
0453          ++gtLogicalExpression) {
0454       if (acceptGtLogicalExpression(event, *gtLogicalExpression))
0455         return true;
0456     }
0457     return false;
0458   }
0459   for (std::vector<std::string>::const_iterator gtLogicalExpression = gtLogicalExpressions_.begin();
0460        gtLogicalExpression != gtLogicalExpressions_.end();
0461        ++gtLogicalExpression) {
0462     if (!acceptGtLogicalExpression(event, *gtLogicalExpression))
0463       return false;
0464   }
0465   return true;
0466 }
0467 
0468 /// Does this event fulfill this particular GT status bits' logical expression?
0469 bool GenericTriggerEventFlag::acceptGtLogicalExpression(const edm::Event& event, std::string gtLogicalExpression) {
0470   // Check empty std::strings
0471   if (gtLogicalExpression.empty()) {
0472     if (verbose_ > 1)
0473       edm::LogWarning("GenericTriggerEventFlag") << "Empty logical expression ==> decision: " << errorReplyGt_;
0474     return errorReplyGt_;
0475   }
0476 
0477   // Negated paths
0478   bool negExpr(negate(gtLogicalExpression));
0479   if (negExpr && gtLogicalExpression.empty()) {
0480     if (verbose_ > 1)
0481       edm::LogWarning("GenericTriggerEventFlag")
0482           << "Empty (negated) logical expression ==> decision: " << errorReplyGt_;
0483     return errorReplyGt_;
0484   }
0485 
0486   // Parse logical expression and determine GT status bit decision
0487   L1GtLogicParser gtAlgoLogicParser(gtLogicalExpression);
0488   // Loop over status bits
0489   for (size_t iStatusBit = 0; iStatusBit < gtAlgoLogicParser.operandTokenVector().size(); ++iStatusBit) {
0490     const std::string gtStatusBit(gtAlgoLogicParser.operandTokenVector().at(iStatusBit).tokenName);
0491     // Manipulate status bit decision as stored in the parser
0492     bool decision(errorReplyDcs_);
0493     // Hard-coded status bits!!!
0494     if (gtStatusBit == "PhysDecl" || gtStatusBit == "PhysicsDeclared") {
0495       edm::Handle<L1GlobalTriggerReadoutRecord> gtReadoutRecord;
0496       event.getByToken(gtInputToken_, gtReadoutRecord);
0497       if (!gtReadoutRecord.isValid()) {
0498         if (verbose_ > 1)
0499           edm::LogWarning("GenericTriggerEventFlag")
0500               << "L1GlobalTriggerReadoutRecord product with InputTag \"" << gtInputTag_.encode()
0501               << "\" not in event ==> decision: " << errorReplyGt_;
0502         gtAlgoLogicParser.operandTokenVector().at(iStatusBit).tokenResult = errorReplyDcs_;
0503         continue;
0504       }
0505       decision = (gtReadoutRecord->gtFdlWord().physicsDeclared() == 1);
0506     } else if (gtStatusBit == "Stable" || gtStatusBit == "StableBeam" || gtStatusBit == "Adjust" ||
0507                gtStatusBit == "Sqeeze" || gtStatusBit == "Flat" || gtStatusBit == "FlatTop" || gtStatusBit == "7TeV" ||
0508                gtStatusBit == "8TeV" || gtStatusBit == "13TeV" || gtStatusBit == "2360GeV" || gtStatusBit == "900GeV") {
0509       edm::Handle<L1GlobalTriggerEvmReadoutRecord> gtEvmReadoutRecord;
0510       event.getByToken(gtEvmInputToken_, gtEvmReadoutRecord);
0511       if (!gtEvmReadoutRecord.isValid()) {
0512         if (verbose_ > 1)
0513           edm::LogWarning("GenericTriggerEventFlag")
0514               << "L1GlobalTriggerEvmReadoutRecord product with InputTag \"" << gtEvmInputTag_.encode()
0515               << "\" not in event ==> decision: " << errorReplyGt_;
0516         gtAlgoLogicParser.operandTokenVector().at(iStatusBit).tokenResult = errorReplyDcs_;
0517         continue;
0518       }
0519       if (gtStatusBit == "Stable" || gtStatusBit == "StableBeam") {
0520         decision = (gtEvmReadoutRecord->gtfeWord().beamMode() == 11);
0521       } else if (gtStatusBit == "Adjust") {
0522         decision = (10 <= gtEvmReadoutRecord->gtfeWord().beamMode() && gtEvmReadoutRecord->gtfeWord().beamMode() <= 11);
0523       } else if (gtStatusBit == "Sqeeze") {
0524         decision = (9 <= gtEvmReadoutRecord->gtfeWord().beamMode() && gtEvmReadoutRecord->gtfeWord().beamMode() <= 11);
0525       } else if (gtStatusBit == "Flat" || gtStatusBit == "FlatTop") {
0526         decision = (8 <= gtEvmReadoutRecord->gtfeWord().beamMode() && gtEvmReadoutRecord->gtfeWord().beamMode() <= 11);
0527       } else if (gtStatusBit == "7TeV") {
0528         decision = (gtEvmReadoutRecord->gtfeWord().beamMomentum() == 3500);
0529       } else if (gtStatusBit == "8TeV") {
0530         decision = (gtEvmReadoutRecord->gtfeWord().beamMomentum() == 4000);
0531       } else if (gtStatusBit == "13TeV") {
0532         decision = (gtEvmReadoutRecord->gtfeWord().beamMomentum() == 6500);
0533       } else if (gtStatusBit == "2360GeV") {
0534         decision = (gtEvmReadoutRecord->gtfeWord().beamMomentum() == 1180);
0535       } else if (gtStatusBit == "900GeV") {
0536         decision = (gtEvmReadoutRecord->gtfeWord().beamMomentum() == 450);
0537       }
0538     } else {
0539       if (verbose_ > 1)
0540         edm::LogWarning("GenericTriggerEventFlag")
0541             << "GT status bit \"" << gtStatusBit << "\" is not defined ==> decision: " << errorReplyGt_;
0542     }
0543     gtAlgoLogicParser.operandTokenVector().at(iStatusBit).tokenResult = decision;
0544   }
0545 
0546   // Determine decision
0547   const bool gtDecision(gtAlgoLogicParser.expressionResult());
0548   return negExpr ? (!gtDecision) : gtDecision;
0549 }
0550 
0551 /// Was this event accepted by the configured L1 logical expression combination?
0552 bool GenericTriggerEventFlag::acceptL1(const edm::Event& event, const edm::EventSetup& setup) {
0553   // An empty L1 logical expressions list acts as switch.
0554   if (!onL1_ || l1LogicalExpressions_.empty())
0555     return (!andOr_);  // logically neutral, depending on base logical connective
0556 
0557   // Determine decision of L1 logical expression combination and return
0558   if (andOrL1_) {  // OR combination
0559     for (std::vector<std::string>::const_iterator l1LogicalExpression = l1LogicalExpressions_.begin();
0560          l1LogicalExpression != l1LogicalExpressions_.end();
0561          ++l1LogicalExpression) {
0562       if (acceptL1LogicalExpression(event, setup, *l1LogicalExpression))
0563         return true;
0564     }
0565     return false;
0566   }
0567   for (std::vector<std::string>::const_iterator l1LogicalExpression = l1LogicalExpressions_.begin();
0568        l1LogicalExpression != l1LogicalExpressions_.end();
0569        ++l1LogicalExpression) {
0570     if (!acceptL1LogicalExpression(event, setup, *l1LogicalExpression))
0571       return false;
0572   }
0573   return true;
0574 }
0575 
0576 /// Was this event accepted by this particular L1 algorithms' logical expression?
0577 bool GenericTriggerEventFlag::acceptL1LogicalExpression(const edm::Event& event,
0578                                                         const edm::EventSetup& setup,
0579                                                         std::string l1LogicalExpression) {
0580   // Getting the L1 event setup
0581   if (stage2_)
0582     l1uGt_->retrieveL1(event, setup);
0583   else
0584     // FIXME This can possibly go to initRun()
0585     l1Gt_->getL1GtRunCache(event, setup, useL1EventSetup, useL1GtTriggerMenuLite);
0586 
0587   // Check empty std::strings
0588   if (l1LogicalExpression.empty()) {
0589     if (verbose_ > 1)
0590       edm::LogWarning("GenericTriggerEventFlag") << "Empty logical expression ==> decision: " << errorReplyL1_;
0591     return errorReplyL1_;
0592   }
0593 
0594   // Negated logical expression
0595   bool negExpr(negate(l1LogicalExpression));
0596   if (negExpr && l1LogicalExpression.empty()) {
0597     if (verbose_ > 1)
0598       edm::LogWarning("GenericTriggerEventFlag")
0599           << "Empty (negated) logical expression ==> decision: " << errorReplyL1_;
0600     return errorReplyL1_;
0601   }
0602 
0603   // Parse logical expression and determine L1 decision
0604   L1GtLogicParser l1AlgoLogicParser(l1LogicalExpression);
0605   // Loop over algorithms
0606   for (size_t iAlgorithm = 0; iAlgorithm < l1AlgoLogicParser.operandTokenVector().size(); ++iAlgorithm) {
0607     const std::string l1AlgoName(l1AlgoLogicParser.operandTokenVector().at(iAlgorithm).tokenName);
0608 
0609     bool decision = false;
0610     bool error = false;
0611     if (stage2_) {
0612       bool errorBOOL = (l1BeforeMask_ ? l1uGt_->getInitialDecisionByName(l1AlgoName, decision)
0613                                       : l1uGt_->getFinalDecisionByName(l1AlgoName, decision));
0614       error = !errorBOOL;
0615     } else {
0616       int errorINT(-1);
0617       //      const bool decision( l1BeforeMask_ ? l1Gt_->decisionBeforeMask( event, l1AlgoName, errorINT ) : l1Gt_->decisionAfterMask( event, l1AlgoName, errorINT ) );
0618       decision = (l1BeforeMask_ ? l1Gt_->decisionBeforeMask(event, l1AlgoName, errorINT)
0619                                 : l1Gt_->decisionAfterMask(event, l1AlgoName, errorINT));
0620       error = (errorINT != 0);
0621       if (errorINT > 1)
0622         if (verbose_ > 1)
0623           edm::LogWarning("GenericTriggerEventFlag")
0624               << "L1 algorithm \"" << l1AlgoName << "\" received error code " << error
0625               << " from L1GtUtils::decisionBeforeMask ==> decision: " << errorReplyL1_;
0626     }
0627 
0628     // Error checks
0629     if (error) {
0630       if (verbose_ > 1)
0631         edm::LogWarning("GenericTriggerEventFlag")
0632             << "L1 algorithm \"" << l1AlgoName << "\" does not exist in the L1 menu ==> decision: " << errorReplyL1_;
0633       l1AlgoLogicParser.operandTokenVector().at(iAlgorithm).tokenResult = errorReplyL1_;
0634       continue;
0635     }
0636     // Manipulate algo decision as stored in the parser
0637     l1AlgoLogicParser.operandTokenVector().at(iAlgorithm).tokenResult = decision;
0638   }
0639 
0640   // Return decision
0641   const bool l1Decision(l1AlgoLogicParser.expressionResult());
0642   return negExpr ? (!l1Decision) : l1Decision;
0643 }
0644 
0645 /// Was this event accepted by the configured HLT logical expression combination?
0646 bool GenericTriggerEventFlag::acceptHlt(const edm::Event& event) {
0647   // An empty HLT logical expressions list acts as switch.
0648   if (!onHlt_ || hltLogicalExpressions_.empty())
0649     return (!andOr_);  // logically neutral, depending on base logical connective
0650 
0651   // Checking the HLT configuration,
0652   if (!hltConfigInit_) {
0653     if (verbose_ > 1)
0654       edm::LogWarning("GenericTriggerEventFlag") << "HLT config error ==> decision: " << errorReplyHlt_;
0655     return errorReplyHlt_;
0656   }
0657 
0658   // Accessing the TriggerResults
0659   edm::Handle<edm::TriggerResults> hltTriggerResults;
0660   event.getByToken(hltInputToken_, hltTriggerResults);
0661   if (!hltTriggerResults.isValid()) {
0662     if (verbose_ > 1)
0663       edm::LogWarning("GenericTriggerEventFlag") << "TriggerResults product with InputTag \"" << hltInputTag_.encode()
0664                                                  << "\" not in event ==> decision: " << errorReplyHlt_;
0665     return errorReplyHlt_;
0666   }
0667   if ((*hltTriggerResults).size() == 0) {
0668     if (verbose_ > 1)
0669       edm::LogWarning("GenericTriggerEventFlag") << "TriggerResults product with InputTag \"" << hltInputTag_.encode()
0670                                                  << "\" empty ==> decision: " << errorReplyHlt_;
0671     return errorReplyDcs_;
0672   }
0673 
0674   // Determine decision of HLT logical expression combination and return
0675   if (andOrHlt_) {  // OR combination
0676     for (std::vector<std::string>::const_iterator hltLogicalExpression = hltLogicalExpressions_.begin();
0677          hltLogicalExpression != hltLogicalExpressions_.end();
0678          ++hltLogicalExpression) {
0679       if (acceptHltLogicalExpression(hltTriggerResults, *hltLogicalExpression))
0680         return true;
0681     }
0682     return false;
0683   }
0684   for (std::vector<std::string>::const_iterator hltLogicalExpression = hltLogicalExpressions_.begin();
0685        hltLogicalExpression != hltLogicalExpressions_.end();
0686        ++hltLogicalExpression) {
0687     if (!acceptHltLogicalExpression(hltTriggerResults, *hltLogicalExpression))
0688       return false;
0689   }
0690   return true;
0691 }
0692 
0693 /// Was this event accepted by this particular HLT paths' logical expression?
0694 bool GenericTriggerEventFlag::acceptHltLogicalExpression(const edm::Handle<edm::TriggerResults>& hltTriggerResults,
0695                                                          std::string hltLogicalExpression) const {
0696   // Check empty std::strings
0697   if (hltLogicalExpression.empty()) {
0698     if (verbose_ > 1)
0699       edm::LogWarning("GenericTriggerEventFlag") << "Empty logical expression ==> decision: " << errorReplyHlt_;
0700     return errorReplyHlt_;
0701   }
0702 
0703   // Negated paths
0704   bool negExpr(negate(hltLogicalExpression));
0705   if (negExpr && hltLogicalExpression.empty()) {
0706     if (verbose_ > 1)
0707       edm::LogWarning("GenericTriggerEventFlag")
0708           << "Empty (negated) logical expression ==> decision: " << errorReplyHlt_;
0709     return errorReplyHlt_;
0710   }
0711 
0712   // Parse logical expression and determine HLT decision
0713   L1GtLogicParser hltAlgoLogicParser(hltLogicalExpression);
0714   // Loop over paths
0715   for (size_t iPath = 0; iPath < hltAlgoLogicParser.operandTokenVector().size(); ++iPath) {
0716     const std::string hltPathName(hltAlgoLogicParser.operandTokenVector().at(iPath).tokenName);
0717     const unsigned indexPath(hltConfig_.triggerIndex(hltPathName));
0718     // Further error checks
0719     if (indexPath == hltConfig_.size()) {
0720       if (verbose_ > 1)
0721         edm::LogWarning("GenericTriggerEventFlag") << "HLT path \"" << hltPathName << "\" is not found in process "
0722                                                    << hltInputTag_.process() << " ==> decision: " << errorReplyHlt_;
0723       hltAlgoLogicParser.operandTokenVector().at(iPath).tokenResult = errorReplyHlt_;
0724       continue;
0725     }
0726     if (hltTriggerResults->error(indexPath)) {
0727       if (verbose_ > 1)
0728         edm::LogWarning("GenericTriggerEventFlag")
0729             << "HLT path \"" << hltPathName << "\" in error ==> decision: " << errorReplyHlt_;
0730       hltAlgoLogicParser.operandTokenVector().at(iPath).tokenResult = errorReplyHlt_;
0731       continue;
0732     }
0733     // Manipulate algo decision as stored in the parser
0734     const bool decision(hltTriggerResults->accept(indexPath));
0735     hltAlgoLogicParser.operandTokenVector().at(iPath).tokenResult = decision;
0736   }
0737 
0738   // Determine decision
0739   const bool hltDecision(hltAlgoLogicParser.expressionResult());
0740   return negExpr ? (!hltDecision) : hltDecision;
0741 }
0742 
0743 /// Expand wild-carded logical expressions, giving version postfixes priority
0744 std::string GenericTriggerEventFlag::expandLogicalExpression(const std::vector<std::string>& targets,
0745                                                              const std::string& expr,
0746                                                              bool useAnd) const {
0747   // Find matching entries in the menu
0748   std::vector<std::string> matched;
0749   const std::string versionWildcard("_v*");
0750   if (expr.substr(expr.size() - versionWildcard.size()) == versionWildcard) {
0751     const std::string exprBase(expr.substr(0, expr.size() - versionWildcard.size()));
0752     matched = hltConfig_.restoreVersion(targets, exprBase);
0753   } else {
0754     matched = hltConfig_.matched(targets, expr);
0755   }
0756 
0757   // Return input, if no match is found
0758   if (matched.empty()) {
0759     if (verbose_ > 1)
0760       edm::LogWarning("GenericTriggerEventFlag") << "Logical expression: \"" << expr << "\" could not be resolved";
0761     return expr;
0762   }
0763 
0764   // Compose logical expression
0765   std::string expanded("(");
0766   for (unsigned iVers = 0; iVers < matched.size(); ++iVers) {
0767     if (iVers > 0)
0768       expanded.append(useAnd ? " AND " : " OR ");
0769     expanded.append(matched.at(iVers));
0770   }
0771   expanded.append(")");
0772   if (verbose_ > 1)
0773     edm::LogInfo("GenericTriggerEventFlag") << "Logical expression: \"" << expr << "\"\n"
0774                                             << "   --> expanded to  \"" << expanded << "\"";
0775 
0776   return expanded;
0777 }
0778 
0779 /// Checks for negated words
0780 bool GenericTriggerEventFlag::negate(std::string& word) const {
0781   bool negate(false);
0782   if (word.at(0) == '~') {
0783     negate = true;
0784     word.erase(0, 1);
0785   }
0786   return negate;
0787 }
0788 
0789 /// Reads and returns logical expressions from DB
0790 std::vector<std::string> GenericTriggerEventFlag::expressionsFromDB(const std::string& key,
0791                                                                     const edm::EventSetup& setup) {
0792   if (key.empty())
0793     return std::vector<std::string>(1, emptyKeyError_);
0794   std::vector<edm::eventsetup::DataKey> labels;
0795   setup.get<AlCaRecoTriggerBitsRcd>().fillRegisteredDataKeys(labels);
0796   std::vector<edm::eventsetup::DataKey>::const_iterator iKey = labels.begin();
0797   while (iKey != labels.end() && iKey->name().value() != dbLabel_)
0798     ++iKey;
0799   if (iKey == labels.end()) {
0800     if (verbose_ > 0)
0801       edm::LogWarning("GenericTriggerEventFlag")
0802           << "Label " << dbLabel_ << " not found in DB for 'AlCaRecoTriggerBitsRcd'";
0803     return std::vector<std::string>(1, configError_);
0804   }
0805   auto const& alCaRecoTriggerBits = setup.getData(alCaRecoTriggerBitsToken_);
0806   const std::map<std::string, std::string>& expressionMap = alCaRecoTriggerBits.m_alcarecoToTrig;
0807   std::map<std::string, std::string>::const_iterator listIter = expressionMap.find(key);
0808   if (listIter == expressionMap.end()) {
0809     if (verbose_ > 0)
0810       edm::LogWarning("GenericTriggerEventFlag")
0811           << "No logical expressions found under key " << key << " in 'AlCaRecoTriggerBitsRcd'";
0812     return std::vector<std::string>(1, configError_);
0813   }
0814   return alCaRecoTriggerBits.decompose(listIter->second);
0815 }
0816 
0817 bool GenericTriggerEventFlag::allHLTPathsAreValid() const {
0818   if (not onHlt_) {
0819     return true;
0820   }
0821 
0822   if (not hltConfigInit_) {
0823     if (verbose_ > 0) {
0824       edm::LogWarning("GenericTriggerEventFlag::allHLTPathsAreValid()")
0825           << "HLTConfigProvider is not initialized, method will return \"false\"";
0826     }
0827 
0828     return false;
0829   }
0830 
0831   for (unsigned iExpr = 0; iExpr < hltLogicalExpressions_.size(); ++iExpr) {
0832     std::string hltLogicalExpression = hltLogicalExpressions_.at(iExpr);
0833 
0834     L1GtLogicParser hltAlgoLogicParser(hltLogicalExpression);
0835 
0836     if (hltAlgoLogicParser.operandTokenVector().empty()) {
0837       return false;
0838     }
0839 
0840     for (size_t iPath = 0; iPath < hltAlgoLogicParser.operandTokenVector().size(); ++iPath) {
0841       const std::string hltPathName(hltAlgoLogicParser.operandTokenVector().at(iPath).tokenName);
0842 
0843       const unsigned indexPath(hltConfig_.triggerIndex(hltPathName));
0844 
0845       if (indexPath == hltConfig_.size()) {
0846         if (verbose_ > 1) {
0847           edm::LogWarning("GenericTriggerEventFlag::allHLTPathsAreValid()")
0848               << "HLT path \"" << hltPathName << "\" is not found in process " << hltInputTag_.process();
0849         }
0850 
0851         return false;
0852       }
0853     }
0854   }
0855 
0856   return true;
0857 }
0858 
0859 void GenericTriggerEventFlag::fillPSetDescription(edm::ParameterSetDescription& desc) {
0860   desc.add<bool>("ReadPrescalesFromFile", false);
0861   desc.add<bool>("andOr", false);
0862   desc.add<bool>("andOrDcs", false);
0863   desc.add<bool>("andOrHlt", false);
0864   desc.add<bool>("andOrL1", false);
0865   desc.add<bool>("errorReplyDcs", false);
0866   desc.add<bool>("errorReplyHlt", false);
0867   desc.add<bool>("errorReplyL1", false);
0868   desc.add<bool>("l1BeforeMask", false);
0869   desc.add<bool>("stage2", false);
0870   desc.add<edm::InputTag>("dcsInputTag", edm::InputTag("scalersRawToDigi"));
0871   desc.add<edm::InputTag>("dcsRecordInputTag", edm::InputTag("onlineMetaDataDigis"));
0872   desc.add<edm::InputTag>("hltInputTag", edm::InputTag("TriggerResults::HLT"));
0873   desc.add<edm::InputTag>("l1tAlgBlkInputTag", edm::InputTag("gtStage2Digis"));
0874   desc.add<edm::InputTag>("l1tExtBlkInputTag", edm::InputTag("gtStage2Digis"));
0875   desc.add<std::string>("dbLabel", "");
0876   desc.add<std::string>("hltDBKey", "");
0877   desc.add<std::vector<int>>("dcsPartitions", {});
0878   desc.add<std::vector<std::string>>("hltPaths", {});
0879   desc.add<std::vector<std::string>>("l1Algorithms", {});
0880   desc.add<unsigned int>("verbosityLevel", 0);
0881 }