Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-11-15 23:40:16

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 auto& prescales = l1uGt_->prescales();
0209       algoNames.reserve(prescales.size());
0210       for (const auto& ip : prescales)
0211         algoNames.emplace_back(ip.first);
0212     } else {
0213       l1Gt_->getL1GtRunCache(run, setup, useL1EventSetup, useL1GtTriggerMenuLite);
0214       const auto& l1GtTriggerMenuRcd = setup.get<L1GtTriggerMenuRcd>();
0215       L1GtTriggerMenu const& l1GtTriggerMenu = l1GtTriggerMenuRcd.get(l1GtTriggerMenuToken_);
0216 
0217       const AlgorithmMap& l1GtPhys(l1GtTriggerMenu.gtAlgorithmMap());
0218       for (CItAlgo iAlgo = l1GtPhys.begin(); iAlgo != l1GtPhys.end(); ++iAlgo) {
0219         algoNames.push_back(iAlgo->second.algoName());
0220       }
0221       const AlgorithmMap& l1GtTech(l1GtTriggerMenu.gtTechnicalTriggerMap());
0222       for (CItAlgo iAlgo = l1GtTech.begin(); iAlgo != l1GtTech.end(); ++iAlgo) {
0223         algoNames.push_back(iAlgo->second.algoName());
0224       }
0225     }
0226 
0227     for (unsigned iExpr = 0; iExpr < l1LogicalExpressions_.size(); ++iExpr) {
0228       std::string l1LogicalExpression(l1LogicalExpressions_.at(iExpr));
0229       L1GtLogicParser l1AlgoLogicParser(l1LogicalExpression);
0230       // Loop over algorithms
0231       for (size_t iAlgo = 0; iAlgo < l1AlgoLogicParser.operandTokenVector().size(); ++iAlgo) {
0232         const std::string l1AlgoName(l1AlgoLogicParser.operandTokenVector().at(iAlgo).tokenName);
0233         if (l1AlgoName.find('*') != std::string::npos) {
0234           l1LogicalExpression.replace(
0235               l1LogicalExpression.find(l1AlgoName), l1AlgoName.size(), expandLogicalExpression(algoNames, l1AlgoName));
0236         }
0237       }
0238       l1LogicalExpressions_[iExpr] = l1LogicalExpression;
0239     }
0240     std::vector<std::string> tmp = l1LogicalExpressions_;
0241     for (unsigned iExpr = 0; iExpr < tmp.size(); ++iExpr)
0242       if (std::find(algoNames.begin(), algoNames.end(), tmp[iExpr]) == algoNames.end()) {
0243         l1LogicalExpressions_.erase(l1LogicalExpressions_.begin() + iExpr);
0244         if (verbose_ > 1)
0245           edm::LogWarning("GenericTriggerEventFlag")
0246               << "L1 algorithm \"" << tmp[iExpr]
0247               << "\" does not exist in the L1 menu ==> drop it from the list of l1LogicalExpressions";
0248       }
0249   }
0250   // HLT
0251   if (hltConfigInit_) {
0252     for (unsigned iExpr = 0; iExpr < hltLogicalExpressions_.size(); ++iExpr) {
0253       std::string hltLogicalExpression(hltLogicalExpressions_.at(iExpr));
0254       L1GtLogicParser hltAlgoLogicParser(hltLogicalExpression);
0255       // Loop over paths
0256       for (size_t iPath = 0; iPath < hltAlgoLogicParser.operandTokenVector().size(); ++iPath) {
0257         const std::string hltPathName(hltAlgoLogicParser.operandTokenVector().at(iPath).tokenName);
0258         if (hltPathName.find('*') != std::string::npos) {
0259           hltLogicalExpression.replace(hltLogicalExpression.find(hltPathName),
0260                                        hltPathName.size(),
0261                                        expandLogicalExpression(hltConfig_.triggerNames(), hltPathName));
0262         }
0263       }
0264       hltLogicalExpressions_[iExpr] = hltLogicalExpression;
0265     }
0266   }
0267 }
0268 
0269 /// To be called from analyze/filter() methods
0270 bool GenericTriggerEventFlag::accept(const edm::Event& event, const edm::EventSetup& setup) {
0271   if (!on_)
0272     return true;
0273 
0274   // Determine decision
0275   if (andOr_)
0276     return (acceptDcs(event) || acceptGt(event) || acceptL1(event, setup) || acceptHlt(event));
0277   return (acceptDcs(event) && acceptGt(event) && acceptL1(event, setup) && acceptHlt(event));
0278 }
0279 
0280 bool GenericTriggerEventFlag::acceptDcs(const edm::Event& event) {
0281   // An empty DCS partitions list acts as switch.
0282   if (!onDcs_ || dcsPartitions_.empty())
0283     return (!andOr_);  // logically neutral, depending on base logical connective
0284 
0285   bool useDCSRecord(false);
0286 
0287   // Accessing the DcsStatusCollection
0288   edm::Handle<DcsStatusCollection> dcsStatus;
0289   event.getByToken(dcsInputToken_, dcsStatus);
0290 
0291   edm::Handle<DCSRecord> dcsRecord;
0292   event.getByToken(dcsRecordToken_, dcsRecord);
0293 
0294   // none of the DCS products is valid
0295   if (!dcsStatus.isValid() && !dcsRecord.isValid()) {
0296     if (verbose_ > 1)
0297       edm::LogWarning("GenericTriggerEventFlag")
0298           << "DcsStatusCollection product with InputTag \"" << dcsInputTag_.encode() << "\" not in event \n"
0299           << "DCSRecord product with InputTag \"" << dcsRecordInputTag_.encode() << "\" not in event \n"
0300           << " ==> decision: " << errorReplyDcs_;
0301     return errorReplyDcs_;
0302   }
0303   if (dcsStatus.isValid() && (*dcsStatus).empty()) {
0304     if (event.eventAuxiliary().isRealData()) {
0305       // this is the Data case for >= Run3, DCSStatus is available (unpacked), but empty
0306       // becasue SCAL is not in data-taking. In this case we fall back to s/w FED 1022
0307       if (dcsRecord.isValid()) {
0308         useDCSRecord = true;
0309       } else {
0310         if (verbose_ > 1)
0311           edm::LogWarning("GenericTriggerEventFlag")
0312               << "DCSRecord product with InputTag \"" << dcsRecordInputTag_.encode()
0313               << "\" empty ==> decision: " << errorReplyDcs_;
0314         return errorReplyDcs_;
0315       }
0316     } else {
0317       // this is the case in which the DCS status is empty, but it's not real data.
0318       if (verbose_ > 1)
0319         edm::LogWarning("GenericTriggerEventFlag")
0320             << "DcsStatusCollection product with InputTag \"" << dcsInputTag_.encode()
0321             << "\" empty ==> decision: " << errorReplyDcs_;
0322       return errorReplyDcs_;
0323     }
0324   }
0325 
0326   // Determine decision of DCS partition combination and return
0327   if (andOrDcs_) {  // OR combination
0328     for (std::vector<int>::const_iterator partitionNumber = dcsPartitions_.begin();
0329          partitionNumber != dcsPartitions_.end();
0330          ++partitionNumber) {
0331       if (acceptDcsPartition(dcsStatus, dcsRecord, useDCSRecord, *partitionNumber))
0332         return true;
0333     }
0334     return false;
0335   }
0336   for (std::vector<int>::const_iterator partitionNumber = dcsPartitions_.begin();
0337        partitionNumber != dcsPartitions_.end();
0338        ++partitionNumber) {
0339     if (!acceptDcsPartition(dcsStatus, dcsRecord, useDCSRecord, *partitionNumber))
0340       return false;
0341   }
0342   return true;
0343 }
0344 
0345 bool GenericTriggerEventFlag::acceptDcsPartition(const edm::Handle<DcsStatusCollection>& dcsStatus,
0346                                                  const edm::Handle<DCSRecord>& dcsRecord,
0347                                                  bool useDCSRecord,
0348                                                  int dcsPartition) const {
0349   int theDCSRecordPartition;
0350   // Error checks
0351   switch (dcsPartition) {
0352     case DcsStatus::EBp:
0353       theDCSRecordPartition = DCSRecord::EBp;
0354       break;
0355     case DcsStatus::EBm:
0356       theDCSRecordPartition = DCSRecord::EBm;
0357       break;
0358     case DcsStatus::EEp:
0359       theDCSRecordPartition = DCSRecord::EEp;
0360       break;
0361     case DcsStatus::EEm:
0362       theDCSRecordPartition = DCSRecord::EBm;
0363       break;
0364     case DcsStatus::HBHEa:
0365       theDCSRecordPartition = DCSRecord::HBHEa;
0366       break;
0367     case DcsStatus::HBHEb:
0368       theDCSRecordPartition = DCSRecord::HBHEb;
0369       break;
0370     case DcsStatus::HBHEc:
0371       theDCSRecordPartition = DCSRecord::HBHEc;
0372       break;
0373     case DcsStatus::HF:
0374       theDCSRecordPartition = DCSRecord::HF;
0375       break;
0376     case DcsStatus::HO:
0377       theDCSRecordPartition = DCSRecord::HO;
0378       break;
0379     case DcsStatus::RPC:
0380       theDCSRecordPartition = DCSRecord::RPC;
0381       break;
0382     case DcsStatus::DT0:
0383       theDCSRecordPartition = DCSRecord::DT0;
0384       break;
0385     case DcsStatus::DTp:
0386       theDCSRecordPartition = DCSRecord::DTp;
0387       break;
0388     case DcsStatus::DTm:
0389       theDCSRecordPartition = DCSRecord::DTm;
0390       break;
0391     case DcsStatus::CSCp:
0392       theDCSRecordPartition = DCSRecord::CSCp;
0393       break;
0394     case DcsStatus::CSCm:
0395       theDCSRecordPartition = DCSRecord::CSCm;
0396       break;
0397     case DcsStatus::CASTOR:
0398       theDCSRecordPartition = DCSRecord::CASTOR;
0399       break;
0400     case DcsStatus::TIBTID:
0401       theDCSRecordPartition = DCSRecord::TIBTID;
0402       break;
0403     case DcsStatus::TOB:
0404       theDCSRecordPartition = DCSRecord::TOB;
0405       break;
0406     case DcsStatus::TECp:
0407       theDCSRecordPartition = DCSRecord::TECp;
0408       break;
0409     case DcsStatus::TECm:
0410       theDCSRecordPartition = DCSRecord::TECm;
0411       break;
0412     case DcsStatus::BPIX:
0413       theDCSRecordPartition = DCSRecord::BPIX;
0414       break;
0415     case DcsStatus::FPIX:
0416       theDCSRecordPartition = DCSRecord::FPIX;
0417       break;
0418     case DcsStatus::ESp:
0419       theDCSRecordPartition = DCSRecord::ESp;
0420       break;
0421     case DcsStatus::ESm:
0422       theDCSRecordPartition = DCSRecord::ESm;
0423       break;
0424     default:
0425       if (verbose_ > 1)
0426         edm::LogWarning("GenericTriggerEventFlag")
0427             << "DCS partition number \"" << dcsPartition << "\" does not exist ==> decision: " << errorReplyDcs_;
0428       return errorReplyDcs_;
0429   }
0430 
0431   // Determine decision
0432   if (!useDCSRecord) {
0433     return dcsStatus->at(0).ready(dcsPartition);
0434   } else {
0435     if (verbose_ > 2) {
0436       LogDebug("GenericTriggerEventFlag")
0437           << "using dcs record, dcsPartition:" << dcsPartition << " " << theDCSRecordPartition << " "
0438           << (*dcsRecord).partitionName(theDCSRecordPartition) << " "
0439           << (*dcsRecord).highVoltageReady(theDCSRecordPartition) << std::endl;
0440     }
0441     return (*dcsRecord).highVoltageReady(theDCSRecordPartition);
0442   }
0443 }
0444 
0445 /// Does this event fulfill the configured GT status logical expression combination?
0446 bool GenericTriggerEventFlag::acceptGt(const edm::Event& event) {
0447   // An empty GT status bits logical expressions list acts as switch.
0448   if (!onGt_ || gtLogicalExpressions_.empty())
0449     return (!andOr_);  // logically neutral, depending on base logical connective
0450 
0451   // Determine decision of GT status bits logical expression combination and return
0452   if (andOrGt_) {  // OR combination
0453     for (std::vector<std::string>::const_iterator gtLogicalExpression = gtLogicalExpressions_.begin();
0454          gtLogicalExpression != gtLogicalExpressions_.end();
0455          ++gtLogicalExpression) {
0456       if (acceptGtLogicalExpression(event, *gtLogicalExpression))
0457         return true;
0458     }
0459     return false;
0460   }
0461   for (std::vector<std::string>::const_iterator gtLogicalExpression = gtLogicalExpressions_.begin();
0462        gtLogicalExpression != gtLogicalExpressions_.end();
0463        ++gtLogicalExpression) {
0464     if (!acceptGtLogicalExpression(event, *gtLogicalExpression))
0465       return false;
0466   }
0467   return true;
0468 }
0469 
0470 /// Does this event fulfill this particular GT status bits' logical expression?
0471 bool GenericTriggerEventFlag::acceptGtLogicalExpression(const edm::Event& event, std::string gtLogicalExpression) {
0472   // Check empty std::strings
0473   if (gtLogicalExpression.empty()) {
0474     if (verbose_ > 1)
0475       edm::LogWarning("GenericTriggerEventFlag") << "Empty logical expression ==> decision: " << errorReplyGt_;
0476     return errorReplyGt_;
0477   }
0478 
0479   // Negated paths
0480   bool negExpr(negate(gtLogicalExpression));
0481   if (negExpr && gtLogicalExpression.empty()) {
0482     if (verbose_ > 1)
0483       edm::LogWarning("GenericTriggerEventFlag")
0484           << "Empty (negated) logical expression ==> decision: " << errorReplyGt_;
0485     return errorReplyGt_;
0486   }
0487 
0488   // Parse logical expression and determine GT status bit decision
0489   L1GtLogicParser gtAlgoLogicParser(gtLogicalExpression);
0490   // Loop over status bits
0491   for (size_t iStatusBit = 0; iStatusBit < gtAlgoLogicParser.operandTokenVector().size(); ++iStatusBit) {
0492     const std::string gtStatusBit(gtAlgoLogicParser.operandTokenVector().at(iStatusBit).tokenName);
0493     // Manipulate status bit decision as stored in the parser
0494     bool decision(errorReplyDcs_);
0495     // Hard-coded status bits!!!
0496     if (gtStatusBit == "PhysDecl" || gtStatusBit == "PhysicsDeclared") {
0497       edm::Handle<L1GlobalTriggerReadoutRecord> gtReadoutRecord;
0498       event.getByToken(gtInputToken_, gtReadoutRecord);
0499       if (!gtReadoutRecord.isValid()) {
0500         if (verbose_ > 1)
0501           edm::LogWarning("GenericTriggerEventFlag")
0502               << "L1GlobalTriggerReadoutRecord product with InputTag \"" << gtInputTag_.encode()
0503               << "\" not in event ==> decision: " << errorReplyGt_;
0504         gtAlgoLogicParser.operandTokenVector().at(iStatusBit).tokenResult = errorReplyDcs_;
0505         continue;
0506       }
0507       decision = (gtReadoutRecord->gtFdlWord().physicsDeclared() == 1);
0508     } else if (gtStatusBit == "Stable" || gtStatusBit == "StableBeam" || gtStatusBit == "Adjust" ||
0509                gtStatusBit == "Sqeeze" || gtStatusBit == "Flat" || gtStatusBit == "FlatTop" || gtStatusBit == "7TeV" ||
0510                gtStatusBit == "8TeV" || gtStatusBit == "13TeV" || gtStatusBit == "2360GeV" || gtStatusBit == "900GeV") {
0511       edm::Handle<L1GlobalTriggerEvmReadoutRecord> gtEvmReadoutRecord;
0512       event.getByToken(gtEvmInputToken_, gtEvmReadoutRecord);
0513       if (!gtEvmReadoutRecord.isValid()) {
0514         if (verbose_ > 1)
0515           edm::LogWarning("GenericTriggerEventFlag")
0516               << "L1GlobalTriggerEvmReadoutRecord product with InputTag \"" << gtEvmInputTag_.encode()
0517               << "\" not in event ==> decision: " << errorReplyGt_;
0518         gtAlgoLogicParser.operandTokenVector().at(iStatusBit).tokenResult = errorReplyDcs_;
0519         continue;
0520       }
0521       if (gtStatusBit == "Stable" || gtStatusBit == "StableBeam") {
0522         decision = (gtEvmReadoutRecord->gtfeWord().beamMode() == 11);
0523       } else if (gtStatusBit == "Adjust") {
0524         decision = (10 <= gtEvmReadoutRecord->gtfeWord().beamMode() && gtEvmReadoutRecord->gtfeWord().beamMode() <= 11);
0525       } else if (gtStatusBit == "Sqeeze") {
0526         decision = (9 <= gtEvmReadoutRecord->gtfeWord().beamMode() && gtEvmReadoutRecord->gtfeWord().beamMode() <= 11);
0527       } else if (gtStatusBit == "Flat" || gtStatusBit == "FlatTop") {
0528         decision = (8 <= gtEvmReadoutRecord->gtfeWord().beamMode() && gtEvmReadoutRecord->gtfeWord().beamMode() <= 11);
0529       } else if (gtStatusBit == "7TeV") {
0530         decision = (gtEvmReadoutRecord->gtfeWord().beamMomentum() == 3500);
0531       } else if (gtStatusBit == "8TeV") {
0532         decision = (gtEvmReadoutRecord->gtfeWord().beamMomentum() == 4000);
0533       } else if (gtStatusBit == "13TeV") {
0534         decision = (gtEvmReadoutRecord->gtfeWord().beamMomentum() == 6500);
0535       } else if (gtStatusBit == "2360GeV") {
0536         decision = (gtEvmReadoutRecord->gtfeWord().beamMomentum() == 1180);
0537       } else if (gtStatusBit == "900GeV") {
0538         decision = (gtEvmReadoutRecord->gtfeWord().beamMomentum() == 450);
0539       }
0540     } else {
0541       if (verbose_ > 1)
0542         edm::LogWarning("GenericTriggerEventFlag")
0543             << "GT status bit \"" << gtStatusBit << "\" is not defined ==> decision: " << errorReplyGt_;
0544     }
0545     gtAlgoLogicParser.operandTokenVector().at(iStatusBit).tokenResult = decision;
0546   }
0547 
0548   // Determine decision
0549   const bool gtDecision(gtAlgoLogicParser.expressionResult());
0550   return negExpr ? (!gtDecision) : gtDecision;
0551 }
0552 
0553 /// Was this event accepted by the configured L1 logical expression combination?
0554 bool GenericTriggerEventFlag::acceptL1(const edm::Event& event, const edm::EventSetup& setup) {
0555   // An empty L1 logical expressions list acts as switch.
0556   if (!onL1_ || l1LogicalExpressions_.empty())
0557     return (!andOr_);  // logically neutral, depending on base logical connective
0558 
0559   // Determine decision of L1 logical expression combination and return
0560   if (andOrL1_) {  // OR combination
0561     for (std::vector<std::string>::const_iterator l1LogicalExpression = l1LogicalExpressions_.begin();
0562          l1LogicalExpression != l1LogicalExpressions_.end();
0563          ++l1LogicalExpression) {
0564       if (acceptL1LogicalExpression(event, setup, *l1LogicalExpression))
0565         return true;
0566     }
0567     return false;
0568   }
0569   for (std::vector<std::string>::const_iterator l1LogicalExpression = l1LogicalExpressions_.begin();
0570        l1LogicalExpression != l1LogicalExpressions_.end();
0571        ++l1LogicalExpression) {
0572     if (!acceptL1LogicalExpression(event, setup, *l1LogicalExpression))
0573       return false;
0574   }
0575   return true;
0576 }
0577 
0578 /// Was this event accepted by this particular L1 algorithms' logical expression?
0579 bool GenericTriggerEventFlag::acceptL1LogicalExpression(const edm::Event& event,
0580                                                         const edm::EventSetup& setup,
0581                                                         std::string l1LogicalExpression) {
0582   // Getting the L1 event setup
0583   if (stage2_)
0584     l1uGt_->retrieveL1(event, setup);
0585   else
0586     // FIXME This can possibly go to initRun()
0587     l1Gt_->getL1GtRunCache(event, setup, useL1EventSetup, useL1GtTriggerMenuLite);
0588 
0589   // Check empty std::strings
0590   if (l1LogicalExpression.empty()) {
0591     if (verbose_ > 1)
0592       edm::LogWarning("GenericTriggerEventFlag") << "Empty logical expression ==> decision: " << errorReplyL1_;
0593     return errorReplyL1_;
0594   }
0595 
0596   // Negated logical expression
0597   bool negExpr(negate(l1LogicalExpression));
0598   if (negExpr && l1LogicalExpression.empty()) {
0599     if (verbose_ > 1)
0600       edm::LogWarning("GenericTriggerEventFlag")
0601           << "Empty (negated) logical expression ==> decision: " << errorReplyL1_;
0602     return errorReplyL1_;
0603   }
0604 
0605   // Parse logical expression and determine L1 decision
0606   L1GtLogicParser l1AlgoLogicParser(l1LogicalExpression);
0607   // Loop over algorithms
0608   for (size_t iAlgorithm = 0; iAlgorithm < l1AlgoLogicParser.operandTokenVector().size(); ++iAlgorithm) {
0609     const std::string l1AlgoName(l1AlgoLogicParser.operandTokenVector().at(iAlgorithm).tokenName);
0610 
0611     bool decision = false;
0612     bool error = false;
0613     if (stage2_) {
0614       bool errorBOOL = (l1BeforeMask_ ? l1uGt_->getInitialDecisionByName(l1AlgoName, decision)
0615                                       : l1uGt_->getFinalDecisionByName(l1AlgoName, decision));
0616       error = !errorBOOL;
0617     } else {
0618       int errorINT(-1);
0619       //      const bool decision( l1BeforeMask_ ? l1Gt_->decisionBeforeMask( event, l1AlgoName, errorINT ) : l1Gt_->decisionAfterMask( event, l1AlgoName, errorINT ) );
0620       decision = (l1BeforeMask_ ? l1Gt_->decisionBeforeMask(event, l1AlgoName, errorINT)
0621                                 : l1Gt_->decisionAfterMask(event, l1AlgoName, errorINT));
0622       error = (errorINT != 0);
0623       if (errorINT > 1)
0624         if (verbose_ > 1)
0625           edm::LogWarning("GenericTriggerEventFlag")
0626               << "L1 algorithm \"" << l1AlgoName << "\" received error code " << error
0627               << " from L1GtUtils::decisionBeforeMask ==> decision: " << errorReplyL1_;
0628     }
0629 
0630     // Error checks
0631     if (error) {
0632       if (verbose_ > 1)
0633         edm::LogWarning("GenericTriggerEventFlag")
0634             << "L1 algorithm \"" << l1AlgoName << "\" does not exist in the L1 menu ==> decision: " << errorReplyL1_;
0635       l1AlgoLogicParser.operandTokenVector().at(iAlgorithm).tokenResult = errorReplyL1_;
0636       continue;
0637     }
0638     // Manipulate algo decision as stored in the parser
0639     l1AlgoLogicParser.operandTokenVector().at(iAlgorithm).tokenResult = decision;
0640   }
0641 
0642   // Return decision
0643   const bool l1Decision(l1AlgoLogicParser.expressionResult());
0644   return negExpr ? (!l1Decision) : l1Decision;
0645 }
0646 
0647 /// Was this event accepted by the configured HLT logical expression combination?
0648 bool GenericTriggerEventFlag::acceptHlt(const edm::Event& event) {
0649   // An empty HLT logical expressions list acts as switch.
0650   if (!onHlt_ || hltLogicalExpressions_.empty())
0651     return (!andOr_);  // logically neutral, depending on base logical connective
0652 
0653   // Checking the HLT configuration,
0654   if (!hltConfigInit_) {
0655     if (verbose_ > 1)
0656       edm::LogWarning("GenericTriggerEventFlag") << "HLT config error ==> decision: " << errorReplyHlt_;
0657     return errorReplyHlt_;
0658   }
0659 
0660   // Accessing the TriggerResults
0661   edm::Handle<edm::TriggerResults> hltTriggerResults;
0662   event.getByToken(hltInputToken_, hltTriggerResults);
0663   if (!hltTriggerResults.isValid()) {
0664     if (verbose_ > 1)
0665       edm::LogWarning("GenericTriggerEventFlag") << "TriggerResults product with InputTag \"" << hltInputTag_.encode()
0666                                                  << "\" not in event ==> decision: " << errorReplyHlt_;
0667     return errorReplyHlt_;
0668   }
0669   if ((*hltTriggerResults).size() == 0) {
0670     if (verbose_ > 1)
0671       edm::LogWarning("GenericTriggerEventFlag") << "TriggerResults product with InputTag \"" << hltInputTag_.encode()
0672                                                  << "\" empty ==> decision: " << errorReplyHlt_;
0673     return errorReplyDcs_;
0674   }
0675 
0676   // Determine decision of HLT logical expression combination and return
0677   if (andOrHlt_) {  // OR combination
0678     for (std::vector<std::string>::const_iterator hltLogicalExpression = hltLogicalExpressions_.begin();
0679          hltLogicalExpression != hltLogicalExpressions_.end();
0680          ++hltLogicalExpression) {
0681       if (acceptHltLogicalExpression(hltTriggerResults, *hltLogicalExpression))
0682         return true;
0683     }
0684     return false;
0685   }
0686   for (std::vector<std::string>::const_iterator hltLogicalExpression = hltLogicalExpressions_.begin();
0687        hltLogicalExpression != hltLogicalExpressions_.end();
0688        ++hltLogicalExpression) {
0689     if (!acceptHltLogicalExpression(hltTriggerResults, *hltLogicalExpression))
0690       return false;
0691   }
0692   return true;
0693 }
0694 
0695 /// Was this event accepted by this particular HLT paths' logical expression?
0696 bool GenericTriggerEventFlag::acceptHltLogicalExpression(const edm::Handle<edm::TriggerResults>& hltTriggerResults,
0697                                                          std::string hltLogicalExpression) const {
0698   // Check empty std::strings
0699   if (hltLogicalExpression.empty()) {
0700     if (verbose_ > 1)
0701       edm::LogWarning("GenericTriggerEventFlag") << "Empty logical expression ==> decision: " << errorReplyHlt_;
0702     return errorReplyHlt_;
0703   }
0704 
0705   // Negated paths
0706   bool negExpr(negate(hltLogicalExpression));
0707   if (negExpr && hltLogicalExpression.empty()) {
0708     if (verbose_ > 1)
0709       edm::LogWarning("GenericTriggerEventFlag")
0710           << "Empty (negated) logical expression ==> decision: " << errorReplyHlt_;
0711     return errorReplyHlt_;
0712   }
0713 
0714   // Parse logical expression and determine HLT decision
0715   L1GtLogicParser hltAlgoLogicParser(hltLogicalExpression);
0716   // Loop over paths
0717   for (size_t iPath = 0; iPath < hltAlgoLogicParser.operandTokenVector().size(); ++iPath) {
0718     const std::string hltPathName(hltAlgoLogicParser.operandTokenVector().at(iPath).tokenName);
0719     const unsigned indexPath(hltConfig_.triggerIndex(hltPathName));
0720     // Further error checks
0721     if (indexPath == hltConfig_.size()) {
0722       if (verbose_ > 1)
0723         edm::LogWarning("GenericTriggerEventFlag") << "HLT path \"" << hltPathName << "\" is not found in process "
0724                                                    << hltInputTag_.process() << " ==> decision: " << errorReplyHlt_;
0725       hltAlgoLogicParser.operandTokenVector().at(iPath).tokenResult = errorReplyHlt_;
0726       continue;
0727     }
0728     if (hltTriggerResults->error(indexPath)) {
0729       if (verbose_ > 1)
0730         edm::LogWarning("GenericTriggerEventFlag")
0731             << "HLT path \"" << hltPathName << "\" in error ==> decision: " << errorReplyHlt_;
0732       hltAlgoLogicParser.operandTokenVector().at(iPath).tokenResult = errorReplyHlt_;
0733       continue;
0734     }
0735     // Manipulate algo decision as stored in the parser
0736     const bool decision(hltTriggerResults->accept(indexPath));
0737     hltAlgoLogicParser.operandTokenVector().at(iPath).tokenResult = decision;
0738   }
0739 
0740   // Determine decision
0741   const bool hltDecision(hltAlgoLogicParser.expressionResult());
0742   return negExpr ? (!hltDecision) : hltDecision;
0743 }
0744 
0745 /// Expand wild-carded logical expressions, giving version postfixes priority
0746 std::string GenericTriggerEventFlag::expandLogicalExpression(const std::vector<std::string>& targets,
0747                                                              const std::string& expr,
0748                                                              bool useAnd) const {
0749   // Find matching entries in the menu
0750   std::vector<std::string> matched;
0751   const std::string versionWildcard("_v*");
0752   if (expr.substr(expr.size() - versionWildcard.size()) == versionWildcard) {
0753     const std::string exprBase(expr.substr(0, expr.size() - versionWildcard.size()));
0754     matched = hltConfig_.restoreVersion(targets, exprBase);
0755   } else {
0756     matched = hltConfig_.matched(targets, expr);
0757   }
0758 
0759   // Return input, if no match is found
0760   if (matched.empty()) {
0761     if (verbose_ > 1)
0762       edm::LogWarning("GenericTriggerEventFlag") << "Logical expression: \"" << expr << "\" could not be resolved";
0763     return expr;
0764   }
0765 
0766   // Compose logical expression
0767   std::string expanded("(");
0768   for (unsigned iVers = 0; iVers < matched.size(); ++iVers) {
0769     if (iVers > 0)
0770       expanded.append(useAnd ? " AND " : " OR ");
0771     expanded.append(matched.at(iVers));
0772   }
0773   expanded.append(")");
0774   if (verbose_ > 1)
0775     edm::LogInfo("GenericTriggerEventFlag") << "Logical expression: \"" << expr << "\"\n"
0776                                             << "   --> expanded to  \"" << expanded << "\"";
0777 
0778   return expanded;
0779 }
0780 
0781 /// Checks for negated words
0782 bool GenericTriggerEventFlag::negate(std::string& word) const {
0783   bool negate(false);
0784   if (word.at(0) == '~') {
0785     negate = true;
0786     word.erase(0, 1);
0787   }
0788   return negate;
0789 }
0790 
0791 /// Reads and returns logical expressions from DB
0792 std::vector<std::string> GenericTriggerEventFlag::expressionsFromDB(const std::string& key,
0793                                                                     const edm::EventSetup& setup) {
0794   if (key.empty())
0795     return std::vector<std::string>(1, emptyKeyError_);
0796   std::vector<edm::eventsetup::DataKey> labels;
0797   setup.get<AlCaRecoTriggerBitsRcd>().fillRegisteredDataKeys(labels);
0798   std::vector<edm::eventsetup::DataKey>::const_iterator iKey = labels.begin();
0799   while (iKey != labels.end() && iKey->name().value() != dbLabel_)
0800     ++iKey;
0801   if (iKey == labels.end()) {
0802     if (verbose_ > 0)
0803       edm::LogWarning("GenericTriggerEventFlag")
0804           << "Label " << dbLabel_ << " not found in DB for 'AlCaRecoTriggerBitsRcd'";
0805     return std::vector<std::string>(1, configError_);
0806   }
0807   auto const& alCaRecoTriggerBits = setup.getData(alCaRecoTriggerBitsToken_);
0808   const std::map<std::string, std::string>& expressionMap = alCaRecoTriggerBits.m_alcarecoToTrig;
0809   std::map<std::string, std::string>::const_iterator listIter = expressionMap.find(key);
0810   if (listIter == expressionMap.end()) {
0811     if (verbose_ > 0)
0812       edm::LogWarning("GenericTriggerEventFlag")
0813           << "No logical expressions found under key " << key << " in 'AlCaRecoTriggerBitsRcd'";
0814     return std::vector<std::string>(1, configError_);
0815   }
0816   return alCaRecoTriggerBits.decompose(listIter->second);
0817 }
0818 
0819 bool GenericTriggerEventFlag::allHLTPathsAreValid() const {
0820   if (not onHlt_) {
0821     return true;
0822   }
0823 
0824   if (not hltConfigInit_) {
0825     if (verbose_ > 0) {
0826       edm::LogWarning("GenericTriggerEventFlag::allHLTPathsAreValid()")
0827           << "HLTConfigProvider is not initialized, method will return \"false\"";
0828     }
0829 
0830     return false;
0831   }
0832 
0833   for (unsigned iExpr = 0; iExpr < hltLogicalExpressions_.size(); ++iExpr) {
0834     std::string hltLogicalExpression = hltLogicalExpressions_.at(iExpr);
0835 
0836     L1GtLogicParser hltAlgoLogicParser(hltLogicalExpression);
0837 
0838     if (hltAlgoLogicParser.operandTokenVector().empty()) {
0839       return false;
0840     }
0841 
0842     for (size_t iPath = 0; iPath < hltAlgoLogicParser.operandTokenVector().size(); ++iPath) {
0843       const std::string hltPathName(hltAlgoLogicParser.operandTokenVector().at(iPath).tokenName);
0844 
0845       const unsigned indexPath(hltConfig_.triggerIndex(hltPathName));
0846 
0847       if (indexPath == hltConfig_.size()) {
0848         if (verbose_ > 1) {
0849           edm::LogWarning("GenericTriggerEventFlag::allHLTPathsAreValid()")
0850               << "HLT path \"" << hltPathName << "\" is not found in process " << hltInputTag_.process();
0851         }
0852 
0853         return false;
0854       }
0855     }
0856   }
0857 
0858   return true;
0859 }
0860 
0861 void GenericTriggerEventFlag::fillPSetDescription(edm::ParameterSetDescription& desc) {
0862   desc.add<bool>("ReadPrescalesFromFile", false);
0863   desc.add<bool>("andOr", false);
0864   desc.add<bool>("andOrDcs", false);
0865   desc.add<bool>("andOrHlt", false);
0866   desc.add<bool>("andOrL1", false);
0867   desc.add<bool>("errorReplyDcs", false);
0868   desc.add<bool>("errorReplyHlt", false);
0869   desc.add<bool>("errorReplyL1", false);
0870   desc.add<bool>("l1BeforeMask", false);
0871   desc.add<bool>("stage2", false);
0872   desc.add<edm::InputTag>("dcsInputTag", edm::InputTag("scalersRawToDigi"));
0873   desc.add<edm::InputTag>("dcsRecordInputTag", edm::InputTag("onlineMetaDataDigis"));
0874   desc.add<edm::InputTag>("hltInputTag", edm::InputTag("TriggerResults::HLT"));
0875   desc.add<edm::InputTag>("l1tAlgBlkInputTag", edm::InputTag("gtStage2Digis"));
0876   desc.add<edm::InputTag>("l1tExtBlkInputTag", edm::InputTag("gtStage2Digis"));
0877   desc.add<std::string>("dbLabel", "");
0878   desc.add<std::string>("hltDBKey", "");
0879   desc.add<std::vector<int>>("dcsPartitions", {});
0880   desc.add<std::vector<std::string>>("hltPaths", {});
0881   desc.add<std::vector<std::string>>("l1Algorithms", {});
0882   desc.add<unsigned int>("verbosityLevel", 0);
0883 }