Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-03-17 11:11:35

0001 /**
0002  * \class L1GtUtils
0003  *
0004  *
0005  * Description: various methods for L1 GT, to be called in an EDM analyzer, producer or filter.
0006  *
0007  * Implementation:
0008  *    <TODO: enter implementation details>
0009  *
0010  * \author: Vasile Mihai Ghete - HEPHY Vienna
0011  *
0012  *
0013  */
0014 
0015 // this class header
0016 #include "L1Trigger/GlobalTriggerAnalyzer/interface/L1GtUtils.h"
0017 
0018 // system include files
0019 #include <iomanip>
0020 #include <memory>
0021 
0022 // user include files
0023 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerReadoutSetupFwd.h"
0024 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerReadoutRecord.h"
0025 #include "DataFormats/L1GlobalTrigger/interface/L1GlobalTriggerRecord.h"
0026 
0027 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0028 
0029 // constructor(s)
0030 L1GtUtils::L1GtUtils(edm::ConsumesCollector& iC, UseEventSetupIn useEventSetupIn)
0031     :
0032 
0033       m_l1GtStableParCacheID(0ULL),
0034       m_numberAlgorithmTriggers(0),
0035 
0036       m_numberTechnicalTriggers(0),
0037 
0038       m_l1GtPfAlgoCacheID(0ULL),
0039       m_l1GtPfTechCacheID(0ULL),
0040 
0041       m_l1GtTmAlgoCacheID(0ULL),
0042       m_l1GtTmTechCacheID(0ULL),
0043 
0044       m_l1GtTmVetoAlgoCacheID(0ULL),
0045       m_l1GtTmVetoTechCacheID(0ULL),
0046 
0047       m_l1GtMenuCacheID(0ULL),
0048 
0049       m_l1EventSetupValid(false),
0050 
0051       m_l1GtMenuLiteValid(false),
0052 
0053       m_beginRunCache(false),
0054 
0055       m_runIDCache(0),
0056 
0057       m_physicsDaqPartition(0),
0058 
0059       m_retrieveL1EventSetup(false),
0060 
0061       m_retrieveL1GtTriggerMenuLite(false)
0062 
0063 {
0064   if (useEventSetupIn == UseEventSetupIn::Run || useEventSetupIn == UseEventSetupIn::RunAndEvent) {
0065     m_L1GtStableParametersRunToken =
0066         iC.esConsumes<L1GtStableParameters, L1GtStableParametersRcd, edm::Transition::BeginRun>();
0067     m_L1GtPrescaleFactorsAlgoTrigRunToken =
0068         iC.esConsumes<L1GtPrescaleFactors, L1GtPrescaleFactorsAlgoTrigRcd, edm::Transition::BeginRun>();
0069     m_L1GtPrescaleFactorsTechTrigRunToken =
0070         iC.esConsumes<L1GtPrescaleFactors, L1GtPrescaleFactorsTechTrigRcd, edm::Transition::BeginRun>();
0071     m_L1GtTriggerMaskAlgoTrigRunToken =
0072         iC.esConsumes<L1GtTriggerMask, L1GtTriggerMaskAlgoTrigRcd, edm::Transition::BeginRun>();
0073     m_L1GtTriggerMaskTechTrigRunToken =
0074         iC.esConsumes<L1GtTriggerMask, L1GtTriggerMaskTechTrigRcd, edm::Transition::BeginRun>();
0075     m_L1GtTriggerMaskVetoAlgoTrigRunToken =
0076         iC.esConsumes<L1GtTriggerMask, L1GtTriggerMaskVetoAlgoTrigRcd, edm::Transition::BeginRun>();
0077     m_L1GtTriggerMaskVetoTechTrigRunToken =
0078         iC.esConsumes<L1GtTriggerMask, L1GtTriggerMaskVetoTechTrigRcd, edm::Transition::BeginRun>();
0079     m_L1GtTriggerMenuRunToken = iC.esConsumes<L1GtTriggerMenu, L1GtTriggerMenuRcd, edm::Transition::BeginRun>();
0080   }
0081   if (useEventSetupIn == UseEventSetupIn::Event || useEventSetupIn == UseEventSetupIn::RunAndEvent) {
0082     m_L1GtStableParametersEventToken = iC.esConsumes<L1GtStableParameters, L1GtStableParametersRcd>();
0083     m_L1GtPrescaleFactorsAlgoTrigEventToken = iC.esConsumes<L1GtPrescaleFactors, L1GtPrescaleFactorsAlgoTrigRcd>();
0084     m_L1GtPrescaleFactorsTechTrigEventToken = iC.esConsumes<L1GtPrescaleFactors, L1GtPrescaleFactorsTechTrigRcd>();
0085     m_L1GtTriggerMaskAlgoTrigEventToken = iC.esConsumes<L1GtTriggerMask, L1GtTriggerMaskAlgoTrigRcd>();
0086     m_L1GtTriggerMaskTechTrigEventToken = iC.esConsumes<L1GtTriggerMask, L1GtTriggerMaskTechTrigRcd>();
0087     m_L1GtTriggerMaskVetoAlgoTrigEventToken = iC.esConsumes<L1GtTriggerMask, L1GtTriggerMaskVetoAlgoTrigRcd>();
0088     m_L1GtTriggerMaskVetoTechTrigEventToken = iC.esConsumes<L1GtTriggerMask, L1GtTriggerMaskVetoTechTrigRcd>();
0089     m_L1GtTriggerMenuEventToken = iC.esConsumes<L1GtTriggerMenu, L1GtTriggerMenuRcd>();
0090   }
0091 }
0092 
0093 L1GtUtils::L1GtUtils(edm::ParameterSet const& pset,
0094                      edm::ConsumesCollector&& iC,
0095                      bool useL1GtTriggerMenuLite,
0096                      UseEventSetupIn useEventSetupIn)
0097     : L1GtUtils(pset, iC, useL1GtTriggerMenuLite, useEventSetupIn) {}
0098 
0099 L1GtUtils::L1GtUtils(edm::ParameterSet const& pset,
0100                      edm::ConsumesCollector& iC,
0101                      bool useL1GtTriggerMenuLite,
0102                      UseEventSetupIn useEventSetupIn)
0103     : L1GtUtils(iC, useEventSetupIn) {
0104   m_l1GtUtilsHelper = std::make_unique<L1GtUtilsHelper>(pset, iC, useL1GtTriggerMenuLite);
0105 }
0106 
0107 // destructor
0108 L1GtUtils::~L1GtUtils() {
0109   // empty
0110 }
0111 
0112 const std::string L1GtUtils::triggerCategory(const TriggerCategory& trigCategory) const {
0113   switch (trigCategory) {
0114     case AlgorithmTrigger: {
0115       return "Algorithm Trigger";
0116     } break;
0117     case TechnicalTrigger: {
0118       return "Technical Trigger";
0119     }
0120 
0121     break;
0122     default: {
0123       return EmptyString;
0124     } break;
0125   }
0126 }
0127 
0128 void L1GtUtils::retrieveL1EventSetup(const edm::EventSetup& evSetup, bool isRun) {
0129   //
0130   m_retrieveL1EventSetup = true;
0131 
0132   m_l1EventSetupValid = true;
0133   // FIXME test for each record if valid; if not set m_l1EventSetupValid = false;
0134 
0135   // get / update the stable parameters from the EventSetup
0136   // local cache & check on cacheIdentifier
0137 
0138   auto l1GtStableParametersRcd = evSetup.get<L1GtStableParametersRcd>();
0139   unsigned long long l1GtStableParCacheID = l1GtStableParametersRcd.cacheIdentifier();
0140 
0141   if (m_l1GtStableParCacheID != l1GtStableParCacheID) {
0142     if (isRun) {
0143       m_l1GtStablePar = &l1GtStableParametersRcd.get(m_L1GtStableParametersRunToken);
0144     } else {
0145       m_l1GtStablePar = &l1GtStableParametersRcd.get(m_L1GtStableParametersEventToken);
0146     }
0147 
0148     // number of algorithm triggers
0149     m_numberAlgorithmTriggers = m_l1GtStablePar->gtNumberPhysTriggers();
0150 
0151     // number of technical triggers
0152     m_numberTechnicalTriggers = m_l1GtStablePar->gtNumberTechnicalTriggers();
0153 
0154     int maxNumberTrigger = std::max(m_numberAlgorithmTriggers, m_numberTechnicalTriggers);
0155 
0156     m_triggerMaskSet.reserve(maxNumberTrigger);
0157     m_prescaleFactorSet.reserve(maxNumberTrigger);
0158 
0159     //
0160     m_l1GtStableParCacheID = l1GtStableParCacheID;
0161   }
0162 
0163   // get / update the prescale factors from the EventSetup
0164   // local cache & check on cacheIdentifier
0165 
0166   auto l1GtPrescaleFactorsAlgoTrigRcd = evSetup.get<L1GtPrescaleFactorsAlgoTrigRcd>();
0167   unsigned long long l1GtPfAlgoCacheID = l1GtPrescaleFactorsAlgoTrigRcd.cacheIdentifier();
0168 
0169   if (m_l1GtPfAlgoCacheID != l1GtPfAlgoCacheID) {
0170     if (isRun) {
0171       m_l1GtPfAlgo = &l1GtPrescaleFactorsAlgoTrigRcd.get(m_L1GtPrescaleFactorsAlgoTrigRunToken);
0172     } else {
0173       m_l1GtPfAlgo = &l1GtPrescaleFactorsAlgoTrigRcd.get(m_L1GtPrescaleFactorsAlgoTrigEventToken);
0174     }
0175 
0176     m_prescaleFactorsAlgoTrig = &(m_l1GtPfAlgo->gtPrescaleFactors());
0177 
0178     m_l1GtPfAlgoCacheID = l1GtPfAlgoCacheID;
0179   }
0180 
0181   auto l1GtPrescaleFactorsTechTrigRcd = evSetup.get<L1GtPrescaleFactorsTechTrigRcd>();
0182   unsigned long long l1GtPfTechCacheID = l1GtPrescaleFactorsTechTrigRcd.cacheIdentifier();
0183 
0184   if (m_l1GtPfTechCacheID != l1GtPfTechCacheID) {
0185     if (isRun) {
0186       m_l1GtPfTech = &l1GtPrescaleFactorsTechTrigRcd.get(m_L1GtPrescaleFactorsTechTrigRunToken);
0187     } else {
0188       m_l1GtPfTech = &l1GtPrescaleFactorsTechTrigRcd.get(m_L1GtPrescaleFactorsTechTrigEventToken);
0189     }
0190 
0191     m_prescaleFactorsTechTrig = &(m_l1GtPfTech->gtPrescaleFactors());
0192 
0193     m_l1GtPfTechCacheID = l1GtPfTechCacheID;
0194   }
0195 
0196   // get / update the trigger mask from the EventSetup
0197   // local cache & check on cacheIdentifier
0198 
0199   auto l1GtTriggerMaskAlgoTrigRcd = evSetup.get<L1GtTriggerMaskAlgoTrigRcd>();
0200   unsigned long long l1GtTmAlgoCacheID = l1GtTriggerMaskAlgoTrigRcd.cacheIdentifier();
0201 
0202   if (m_l1GtTmAlgoCacheID != l1GtTmAlgoCacheID) {
0203     if (isRun) {
0204       m_l1GtTmAlgo = &l1GtTriggerMaskAlgoTrigRcd.get(m_L1GtTriggerMaskAlgoTrigRunToken);
0205     } else {
0206       m_l1GtTmAlgo = &l1GtTriggerMaskAlgoTrigRcd.get(m_L1GtTriggerMaskAlgoTrigEventToken);
0207     }
0208 
0209     m_triggerMaskAlgoTrig = &(m_l1GtTmAlgo->gtTriggerMask());
0210 
0211     m_l1GtTmAlgoCacheID = l1GtTmAlgoCacheID;
0212   }
0213 
0214   auto l1GtTriggerMaskTechTrigRcd = evSetup.get<L1GtTriggerMaskTechTrigRcd>();
0215   unsigned long long l1GtTmTechCacheID = l1GtTriggerMaskTechTrigRcd.cacheIdentifier();
0216 
0217   if (m_l1GtTmTechCacheID != l1GtTmTechCacheID) {
0218     if (isRun) {
0219       m_l1GtTmTech = &l1GtTriggerMaskTechTrigRcd.get(m_L1GtTriggerMaskTechTrigRunToken);
0220     } else {
0221       m_l1GtTmTech = &l1GtTriggerMaskTechTrigRcd.get(m_L1GtTriggerMaskTechTrigEventToken);
0222     }
0223 
0224     m_triggerMaskTechTrig = &(m_l1GtTmTech->gtTriggerMask());
0225 
0226     m_l1GtTmTechCacheID = l1GtTmTechCacheID;
0227   }
0228 
0229   auto l1GtTriggerMaskVetoAlgoTrigRcd = evSetup.get<L1GtTriggerMaskVetoAlgoTrigRcd>();
0230   unsigned long long l1GtTmVetoAlgoCacheID = l1GtTriggerMaskVetoAlgoTrigRcd.cacheIdentifier();
0231 
0232   if (m_l1GtTmVetoAlgoCacheID != l1GtTmVetoAlgoCacheID) {
0233     if (isRun) {
0234       m_l1GtTmVetoAlgo = &l1GtTriggerMaskVetoAlgoTrigRcd.get(m_L1GtTriggerMaskVetoAlgoTrigRunToken);
0235     } else {
0236       m_l1GtTmVetoAlgo = &l1GtTriggerMaskVetoAlgoTrigRcd.get(m_L1GtTriggerMaskVetoAlgoTrigEventToken);
0237     }
0238 
0239     m_triggerMaskVetoAlgoTrig = &(m_l1GtTmVetoAlgo->gtTriggerMask());
0240 
0241     m_l1GtTmVetoAlgoCacheID = l1GtTmVetoAlgoCacheID;
0242   }
0243 
0244   auto l1GtTriggerMaskVetoTechTrigRcd = evSetup.get<L1GtTriggerMaskVetoTechTrigRcd>();
0245   unsigned long long l1GtTmVetoTechCacheID = l1GtTriggerMaskVetoTechTrigRcd.cacheIdentifier();
0246 
0247   if (m_l1GtTmVetoTechCacheID != l1GtTmVetoTechCacheID) {
0248     if (isRun) {
0249       m_l1GtTmVetoTech = &l1GtTriggerMaskVetoTechTrigRcd.get(m_L1GtTriggerMaskVetoTechTrigRunToken);
0250     } else {
0251       m_l1GtTmVetoTech = &l1GtTriggerMaskVetoTechTrigRcd.get(m_L1GtTriggerMaskVetoTechTrigEventToken);
0252     }
0253 
0254     m_triggerMaskVetoTechTrig = &(m_l1GtTmVetoTech->gtTriggerMask());
0255 
0256     m_l1GtTmVetoTechCacheID = l1GtTmVetoTechCacheID;
0257   }
0258 
0259   // get / update the trigger menu from the EventSetup
0260   // local cache & check on cacheIdentifier
0261 
0262   auto l1GtTriggerMenuRcd = evSetup.get<L1GtTriggerMenuRcd>();
0263   unsigned long long l1GtMenuCacheID = l1GtTriggerMenuRcd.cacheIdentifier();
0264 
0265   if (m_l1GtMenuCacheID != l1GtMenuCacheID) {
0266     if (isRun) {
0267       m_l1GtMenu = &l1GtTriggerMenuRcd.get(m_L1GtTriggerMenuRunToken);
0268     } else {
0269       m_l1GtMenu = &l1GtTriggerMenuRcd.get(m_L1GtTriggerMenuEventToken);
0270     }
0271 
0272     m_algorithmMap = &(m_l1GtMenu->gtAlgorithmMap());
0273     m_algorithmAliasMap = &(m_l1GtMenu->gtAlgorithmAliasMap());
0274 
0275     m_technicalTriggerMap = &(m_l1GtMenu->gtTechnicalTriggerMap());
0276 
0277     m_l1GtMenuCacheID = l1GtMenuCacheID;
0278   }
0279 }
0280 
0281 void L1GtUtils::retrieveL1GtTriggerMenuLite(const edm::Run& iRun) {
0282   m_retrieveL1GtTriggerMenuLite = true;
0283 
0284   // get L1GtTriggerMenuLite
0285   edm::Handle<L1GtTriggerMenuLite> l1GtMenuLite;
0286   if (!m_l1GtUtilsHelper->l1GtTriggerMenuLiteToken().isUninitialized()) {
0287     iRun.getByToken(m_l1GtUtilsHelper->l1GtTriggerMenuLiteToken(), l1GtMenuLite);
0288   }
0289 
0290   if (!l1GtMenuLite.isValid()) {
0291     LogDebug("L1GtUtils") << "\nL1GtTriggerMenuLite with \n  " << m_l1GtUtilsHelper->l1GtTriggerMenuLiteInputTag()
0292                           << "\nrequested, but not found in the run." << std::endl;
0293 
0294     m_l1GtMenuLiteValid = false;
0295   } else {
0296     m_l1GtMenuLite = l1GtMenuLite.product();
0297     m_l1GtMenuLiteValid = true;
0298 
0299     LogDebug("L1GtUtils") << "\nL1GtTriggerMenuLite with \n  " << m_l1GtUtilsHelper->l1GtTriggerMenuLiteInputTag()
0300                           << "\nretrieved for run " << iRun.runAuxiliary().run() << std::endl;
0301 
0302     m_algorithmMapLite = &(m_l1GtMenuLite->gtAlgorithmMap());
0303     m_algorithmAliasMapLite = &(m_l1GtMenuLite->gtAlgorithmAliasMap());
0304     m_technicalTriggerMapLite = &(m_l1GtMenuLite->gtTechnicalTriggerMap());
0305 
0306     m_triggerMaskAlgoTrigLite = &(m_l1GtMenuLite->gtTriggerMaskAlgoTrig());
0307     m_triggerMaskTechTrigLite = &(m_l1GtMenuLite->gtTriggerMaskTechTrig());
0308 
0309     m_prescaleFactorsAlgoTrigLite = &(m_l1GtMenuLite->gtPrescaleFactorsAlgoTrig());
0310     m_prescaleFactorsTechTrigLite = &(m_l1GtMenuLite->gtPrescaleFactorsTechTrig());
0311   }
0312 }
0313 
0314 void L1GtUtils::getL1GtRunCache(const edm::Run& iRun,
0315                                 const edm::EventSetup& evSetup,
0316                                 bool useL1EventSetup,
0317                                 bool useL1GtTriggerMenuLite) {
0318   // first call will turn this to true: the quantities which can be cached in
0319   // beginRun will not be cached then in analyze
0320   m_beginRunCache = true;
0321 
0322   // if requested, retrieve and cache L1 event setup
0323   // keep the caching based on cacheIdentifier() for each record
0324   if (useL1EventSetup) {
0325     bool isRun = true;
0326     retrieveL1EventSetup(evSetup, isRun);
0327   }
0328 
0329   // cached per run
0330 
0331   // if requested, retrieve and cache the L1GtTriggerMenuLite
0332   // L1GtTriggerMenuLite is defined per run and produced in prompt reco by L1Reco
0333   // and put in the Run section
0334   if (useL1GtTriggerMenuLite) {
0335     retrieveL1GtTriggerMenuLite(iRun);
0336   }
0337 }
0338 
0339 void L1GtUtils::getL1GtRunCache(const edm::Event& iEvent,
0340                                 const edm::EventSetup& evSetup,
0341                                 const bool useL1EventSetup,
0342                                 const bool useL1GtTriggerMenuLite) {
0343   // if there was no retrieval and caching in beginRun, do it here
0344   if (!m_beginRunCache) {
0345     // if requested, retrieve and cache L1 event setup
0346     // keep the caching based on cacheIdentifier() for each record
0347     if (useL1EventSetup) {
0348       bool isRun = false;
0349       retrieveL1EventSetup(evSetup, isRun);
0350     }
0351   }
0352 
0353   // cached per run
0354 
0355   const edm::Run& iRun = iEvent.getRun();
0356   edm::RunID runID = iRun.runAuxiliary().id();
0357 
0358   if (runID != m_runIDCache) {
0359     if (!m_beginRunCache) {
0360       // if requested, retrieve and cache the L1GtTriggerMenuLite
0361       // L1GtTriggerMenuLite is defined per run and produced in prompt reco by L1Reco
0362       // and put in the Run section
0363       if (useL1GtTriggerMenuLite) {
0364         retrieveL1GtTriggerMenuLite(iRun);
0365       }
0366     }
0367     m_runIDCache = runID;
0368   }
0369 }
0370 
0371 const bool L1GtUtils::l1AlgoTechTrigBitNumber(const std::string& nameAlgoTechTrig,
0372                                               TriggerCategory& trigCategory,
0373                                               int& bitNumber) const {
0374   trigCategory = AlgorithmTrigger;
0375   bitNumber = -1;
0376 
0377   if (m_retrieveL1GtTriggerMenuLite) {
0378     if (m_l1GtMenuLiteValid) {
0379       // test if the name is an algorithm alias
0380       for (L1GtTriggerMenuLite::CItL1Trig itTrig = m_algorithmAliasMapLite->begin();
0381            itTrig != m_algorithmAliasMapLite->end();
0382            itTrig++) {
0383         if (itTrig->second == nameAlgoTechTrig) {
0384           trigCategory = AlgorithmTrigger;
0385           bitNumber = itTrig->first;
0386 
0387           return true;
0388         }
0389       }
0390 
0391       // test if the name is an algorithm name
0392       for (L1GtTriggerMenuLite::CItL1Trig itTrig = m_algorithmMapLite->begin(); itTrig != m_algorithmMapLite->end();
0393            itTrig++) {
0394         if (itTrig->second == nameAlgoTechTrig) {
0395           trigCategory = AlgorithmTrigger;
0396           bitNumber = itTrig->first;
0397 
0398           return true;
0399         }
0400       }
0401 
0402       // test if the name is a technical trigger
0403       for (L1GtTriggerMenuLite::CItL1Trig itTrig = m_technicalTriggerMapLite->begin();
0404            itTrig != m_technicalTriggerMapLite->end();
0405            itTrig++) {
0406         if (itTrig->second == nameAlgoTechTrig) {
0407           trigCategory = TechnicalTrigger;
0408           bitNumber = itTrig->first;
0409 
0410           return true;
0411         }
0412       }
0413 
0414     } else if (m_retrieveL1EventSetup) {
0415       // test if the name is an algorithm alias
0416       CItAlgo itAlgo = m_algorithmAliasMap->find(nameAlgoTechTrig);
0417       if (itAlgo != m_algorithmAliasMap->end()) {
0418         trigCategory = AlgorithmTrigger;
0419         bitNumber = (itAlgo->second).algoBitNumber();
0420 
0421         return true;
0422       }
0423 
0424       // test if the name is an algorithm name
0425       itAlgo = m_algorithmMap->find(nameAlgoTechTrig);
0426       if (itAlgo != m_algorithmMap->end()) {
0427         trigCategory = AlgorithmTrigger;
0428         bitNumber = (itAlgo->second).algoBitNumber();
0429 
0430         return true;
0431       }
0432 
0433       // test if the name is a technical trigger
0434       itAlgo = m_technicalTriggerMap->find(nameAlgoTechTrig);
0435       if (itAlgo != m_technicalTriggerMap->end()) {
0436         trigCategory = TechnicalTrigger;
0437         bitNumber = (itAlgo->second).algoBitNumber();
0438 
0439         return true;
0440       }
0441 
0442     } else {
0443       // only L1GtTriggerMenuLite requested, but it is not valid
0444       return false;
0445     }
0446   } else if (m_retrieveL1EventSetup) {
0447     // test if the name is an algorithm alias
0448     CItAlgo itAlgo = m_algorithmAliasMap->find(nameAlgoTechTrig);
0449     if (itAlgo != m_algorithmAliasMap->end()) {
0450       trigCategory = AlgorithmTrigger;
0451       bitNumber = (itAlgo->second).algoBitNumber();
0452 
0453       return true;
0454     }
0455 
0456     // test if the name is an algorithm name
0457     itAlgo = m_algorithmMap->find(nameAlgoTechTrig);
0458     if (itAlgo != m_algorithmMap->end()) {
0459       trigCategory = AlgorithmTrigger;
0460       bitNumber = (itAlgo->second).algoBitNumber();
0461 
0462       return true;
0463     }
0464 
0465     // test if the name is a technical trigger
0466     itAlgo = m_technicalTriggerMap->find(nameAlgoTechTrig);
0467     if (itAlgo != m_technicalTriggerMap->end()) {
0468       trigCategory = TechnicalTrigger;
0469       bitNumber = (itAlgo->second).algoBitNumber();
0470 
0471       return true;
0472     }
0473 
0474   } else {
0475     // L1 trigger configuration not retrieved
0476     return false;
0477   }
0478 
0479   // all possibilities already tested, so it should not arrive here
0480   return false;
0481 }
0482 
0483 const bool L1GtUtils::l1TriggerNameFromBit(const int& bitNumber,
0484                                            const TriggerCategory& trigCategory,
0485                                            std::string& aliasL1Trigger,
0486                                            std::string& nameL1Trigger) const {
0487   aliasL1Trigger.clear();
0488   nameL1Trigger.clear();
0489 
0490   if (m_retrieveL1GtTriggerMenuLite) {
0491     if (m_l1GtMenuLiteValid) {
0492       // for an algorithm trigger
0493       if (trigCategory == AlgorithmTrigger) {
0494         bool trigAliasFound = false;
0495         bool trigNameFound = false;
0496 
0497         for (L1GtTriggerMenuLite::CItL1Trig itTrig = m_algorithmAliasMapLite->begin();
0498              itTrig != m_algorithmAliasMapLite->end();
0499              itTrig++) {
0500           if (static_cast<int>(itTrig->first) == bitNumber) {
0501             aliasL1Trigger = itTrig->second;
0502             trigAliasFound = true;
0503             break;
0504           }
0505         }
0506 
0507         for (L1GtTriggerMenuLite::CItL1Trig itTrig = m_algorithmMapLite->begin(); itTrig != m_algorithmMapLite->end();
0508              itTrig++) {
0509           if (static_cast<int>(itTrig->first) == bitNumber) {
0510             nameL1Trigger = itTrig->second;
0511             trigNameFound = true;
0512             break;
0513           }
0514         }
0515 
0516         if (!(trigAliasFound && trigNameFound)) {
0517           return false;
0518         }
0519 
0520         return true;
0521 
0522       } else if (trigCategory == TechnicalTrigger) {
0523         // for a technical trigger
0524 
0525         bool trigNameFound = false;
0526 
0527         for (L1GtTriggerMenuLite::CItL1Trig itTrig = m_technicalTriggerMapLite->begin();
0528              itTrig != m_technicalTriggerMapLite->end();
0529              itTrig++) {
0530           if (static_cast<int>(itTrig->first) == bitNumber) {
0531             nameL1Trigger = itTrig->second;
0532 
0533             // technically, no alias is defined for technical triggers
0534             // users use mainly aliases, so just return the name here
0535             aliasL1Trigger = itTrig->second;
0536 
0537             trigNameFound = true;
0538             break;
0539           }
0540         }
0541 
0542         if (!(trigNameFound)) {
0543           return false;
0544         }
0545 
0546         return true;
0547 
0548       } else {
0549         // non-existing trigger category...
0550         return false;
0551       }
0552 
0553     } else if (m_retrieveL1EventSetup) {
0554       // for an algorithm trigger
0555       if (trigCategory == AlgorithmTrigger) {
0556         bool trigAliasFound = false;
0557 
0558         for (CItAlgo itTrig = m_algorithmAliasMap->begin(); itTrig != m_algorithmAliasMap->end(); itTrig++) {
0559           if ((itTrig->second).algoBitNumber() == bitNumber) {
0560             aliasL1Trigger = itTrig->first;
0561             // get the name here, avoiding a loop on m_algorithmMap
0562             nameL1Trigger = (itTrig->second).algoName();
0563 
0564             trigAliasFound = true;
0565             break;
0566           }
0567         }
0568 
0569         if (!(trigAliasFound)) {
0570           return false;
0571         }
0572 
0573         return true;
0574 
0575       } else if (trigCategory == TechnicalTrigger) {
0576         // for a technical trigger
0577 
0578         bool trigNameFound = false;
0579 
0580         for (CItAlgo itTrig = m_technicalTriggerMap->begin(); itTrig != m_technicalTriggerMap->end(); itTrig++) {
0581           if ((itTrig->second).algoBitNumber() == bitNumber) {
0582             nameL1Trigger = (itTrig->second).algoName();
0583             // technically, no alias is defined for technical triggers
0584             // users use mainly aliases, so just return the name here
0585             aliasL1Trigger = nameL1Trigger;
0586 
0587             trigNameFound = true;
0588             break;
0589           }
0590         }
0591 
0592         if (!(trigNameFound)) {
0593           return false;
0594         }
0595 
0596         return true;
0597 
0598       } else {
0599         // non-existing trigger category...
0600         return false;
0601       }
0602 
0603     } else {
0604       // only L1GtTriggerMenuLite requested, but it is not valid
0605       return false;
0606     }
0607   } else if (m_retrieveL1EventSetup) {
0608     // for an algorithm trigger
0609     if (trigCategory == AlgorithmTrigger) {
0610       bool trigAliasFound = false;
0611 
0612       for (CItAlgo itTrig = m_algorithmAliasMap->begin(); itTrig != m_algorithmAliasMap->end(); itTrig++) {
0613         if ((itTrig->second).algoBitNumber() == bitNumber) {
0614           aliasL1Trigger = itTrig->first;
0615           // get the name here, avoiding a loop on m_algorithmMap
0616           nameL1Trigger = (itTrig->second).algoName();
0617 
0618           trigAliasFound = true;
0619           break;
0620         }
0621       }
0622 
0623       if (!(trigAliasFound)) {
0624         return false;
0625       }
0626 
0627       return true;
0628 
0629     } else if (trigCategory == TechnicalTrigger) {
0630       // for a technical trigger
0631 
0632       bool trigNameFound = false;
0633 
0634       for (CItAlgo itTrig = m_technicalTriggerMap->begin(); itTrig != m_technicalTriggerMap->end(); itTrig++) {
0635         if ((itTrig->second).algoBitNumber() == bitNumber) {
0636           nameL1Trigger = (itTrig->second).algoName();
0637           // technically, no alias is defined for technical triggers
0638           // users use mainly aliases, so just return the name here
0639           aliasL1Trigger = itTrig->first;
0640 
0641           trigNameFound = true;
0642           break;
0643         }
0644       }
0645 
0646       if (!(trigNameFound)) {
0647         return false;
0648       }
0649 
0650       return true;
0651 
0652     } else {
0653       // non-existing trigger category...
0654       return false;
0655     }
0656 
0657   } else {
0658     // L1 trigger configuration not retrieved
0659     return false;
0660   }
0661 
0662   // all possibilities already tested, so it should not arrive here
0663   return false;
0664 }
0665 
0666 const int L1GtUtils::l1Results(const edm::Event& iEvent,
0667                                const std::string& nameAlgoTechTrig,
0668                                bool& decisionBeforeMask,
0669                                bool& decisionAfterMask,
0670                                int& prescaleFactor,
0671                                int& triggerMask) const {
0672   // initial values for returned results
0673   decisionBeforeMask = false;
0674   decisionAfterMask = false;
0675   prescaleFactor = -1;
0676   triggerMask = -1;
0677 
0678   // initialize error code and L1 configuration code
0679   int iError = 0;
0680   int l1ConfCode = 0;
0681 
0682   // check if L1 configuration is available
0683 
0684   if (!availableL1Configuration(iError, l1ConfCode)) {
0685     return iError;
0686   }
0687 
0688   // at this point, a valid L1 configuration is available, so the if/else if/else
0689   // can be simplified
0690 
0691   // if the given name is not an algorithm trigger alias, an algorithm trigger name
0692   // or a technical trigger in the current menu, return with error code 1
0693 
0694   TriggerCategory trigCategory = AlgorithmTrigger;
0695   int bitNumber = -1;
0696 
0697   if (!l1AlgoTechTrigBitNumber(nameAlgoTechTrig, trigCategory, bitNumber)) {
0698     iError = l1ConfCode + 1;
0699 
0700     if (m_retrieveL1GtTriggerMenuLite) {
0701       if (m_l1GtMenuLiteValid) {
0702         LogDebug("L1GtUtils") << "\nAlgorithm/technical trigger \n  " << nameAlgoTechTrig
0703                               << "\not found in the trigger menu \n  " << m_l1GtMenuLite->gtTriggerMenuImplementation()
0704                               << "\nretrieved from L1GtTriggerMenuLite" << std::endl;
0705 
0706       } else {
0707         // fall through: L1 trigger configuration from event setup
0708         LogDebug("L1GtUtils") << "\nAlgorithm/technical trigger \n  " << nameAlgoTechTrig
0709                               << "\not found in the trigger menu \n  " << m_l1GtMenu->gtTriggerMenuImplementation()
0710                               << "\nretrieved from Event Setup" << std::endl;
0711       }
0712 
0713     } else {
0714       // L1 trigger configuration from event setup only
0715       LogDebug("L1GtUtils") << "\nAlgorithm/technical trigger \n  " << nameAlgoTechTrig
0716                             << "\not found in the trigger menu \n  " << m_l1GtMenu->gtTriggerMenuImplementation()
0717                             << "\nretrieved from Event Setup" << std::endl;
0718     }
0719 
0720     return iError;
0721   }
0722 
0723   // check here if a positive bit number was retrieved
0724   // exit in case of negative bit number, before retrieving L1 GT products, saving time
0725 
0726   if (bitNumber < 0) {
0727     iError = l1ConfCode + 2;
0728 
0729     if (m_retrieveL1GtTriggerMenuLite) {
0730       if (m_l1GtMenuLiteValid) {
0731         LogDebug("L1GtUtils") << "\nNegative bit number for " << triggerCategory(trigCategory) << "\n  "
0732                               << nameAlgoTechTrig << "\nfrom menu \n  " << m_l1GtMenuLite->gtTriggerMenuImplementation()
0733                               << "\nretrieved from L1GtTriggerMenuLite" << std::endl;
0734 
0735       } else {
0736         // fall through: L1 trigger configuration from event setup
0737         LogDebug("L1GtUtils") << "\nNegative bit number for " << triggerCategory(trigCategory) << "\n  "
0738                               << nameAlgoTechTrig << "\nfrom menu \n  " << m_l1GtMenu->gtTriggerMenuImplementation()
0739                               << "\nretrieved from Event Setup" << std::endl;
0740       }
0741 
0742     } else {
0743       // L1 trigger configuration from event setup only
0744       LogDebug("L1GtUtils") << "\nNegative bit number for " << triggerCategory(trigCategory) << "\n  "
0745                             << nameAlgoTechTrig << "\nfrom menu \n  " << m_l1GtMenu->gtTriggerMenuImplementation()
0746                             << "\nretrieved from Event Setup" << std::endl;
0747     }
0748 
0749     return iError;
0750   }
0751 
0752   // retrieve L1GlobalTriggerRecord and 1GlobalTriggerReadoutRecord product
0753   // intermediate error code for the records
0754   // the module returns an error code only if both the lite and the readout record are missing
0755 
0756   int iErrorRecord = 0;
0757 
0758   bool validRecord = false;
0759   bool gtReadoutRecordValid = false;
0760 
0761   edm::Handle<L1GlobalTriggerRecord> gtRecord;
0762   if (!m_l1GtUtilsHelper->l1GtRecordToken().isUninitialized()) {
0763     iEvent.getByToken(m_l1GtUtilsHelper->l1GtRecordToken(), gtRecord);
0764   }
0765   if (gtRecord.isValid()) {
0766     validRecord = true;
0767 
0768   } else {
0769     iErrorRecord = 10;
0770     LogDebug("L1GtUtils") << "\nL1GlobalTriggerRecord with \n  " << m_l1GtUtilsHelper->l1GtRecordInputTag()
0771                           << "\nnot found in the event." << std::endl;
0772   }
0773 
0774   edm::Handle<L1GlobalTriggerReadoutRecord> gtReadoutRecord;
0775   if (!m_l1GtUtilsHelper->l1GtReadoutRecordToken().isUninitialized()) {
0776     iEvent.getByToken(m_l1GtUtilsHelper->l1GtReadoutRecordToken(), gtReadoutRecord);
0777   }
0778   if (gtReadoutRecord.isValid()) {
0779     gtReadoutRecordValid = true;
0780     validRecord = true;
0781 
0782   } else {
0783     iErrorRecord = iErrorRecord + 100;
0784     LogDebug("L1GtUtils") << "\nL1GlobalTriggerReadoutRecord with \n  "
0785                           << m_l1GtUtilsHelper->l1GtReadoutRecordInputTag() << "\nnot found in the event." << std::endl;
0786   }
0787 
0788   // get the prescale factor index from
0789   //  L1GlobalTriggerReadoutRecord if valid
0790   //  if not, from L1GlobalTriggerRecord if valid
0791   //  else return an error
0792 
0793   int pfIndexTechTrig = -1;
0794   int pfIndexAlgoTrig = -1;
0795 
0796   if (validRecord) {
0797     if (gtReadoutRecordValid) {
0798       pfIndexTechTrig = (gtReadoutRecord->gtFdlWord()).gtPrescaleFactorIndexTech();
0799       pfIndexAlgoTrig = (gtReadoutRecord->gtFdlWord()).gtPrescaleFactorIndexAlgo();
0800 
0801     } else {
0802       pfIndexTechTrig = static_cast<int>(gtRecord->gtPrescaleFactorIndexTech());
0803       pfIndexAlgoTrig = static_cast<int>(gtRecord->gtPrescaleFactorIndexAlgo());
0804     }
0805 
0806   } else {
0807     LogDebug("L1GtUtils") << "\nError: "
0808                           << "\nNo valid L1GlobalTriggerRecord with \n  " << m_l1GtUtilsHelper->l1GtRecordInputTag()
0809                           << "\nfound in the event."
0810                           << "\nNo valid L1GlobalTriggerReadoutRecord with \n  "
0811                           << m_l1GtUtilsHelper->l1GtReadoutRecordInputTag() << "\nfound in the event." << std::endl;
0812 
0813     iError = l1ConfCode + iErrorRecord;
0814     return iError;
0815   }
0816 
0817   // depending on trigger category (algorithm trigger or technical trigger)
0818   // get the correct quantities
0819 
0820   // number of sets of prescale factors
0821   // index of prescale factor set retrieved from data
0822   // pointer to the actual prescale factor set
0823   // pointer to the set of trigger masks
0824 
0825   size_t pfSetsSize = 0;
0826   int pfIndex = -1;
0827   const std::vector<int>* prescaleFactorsSubset = nullptr;
0828   const std::vector<unsigned int>* triggerMasksSet = nullptr;
0829 
0830   switch (trigCategory) {
0831     case AlgorithmTrigger: {
0832       if (m_retrieveL1GtTriggerMenuLite) {
0833         if (m_l1GtMenuLiteValid) {
0834           pfSetsSize = m_prescaleFactorsAlgoTrigLite->size();
0835           triggerMasksSet = m_triggerMaskAlgoTrigLite;
0836 
0837         } else {
0838           // fall through: L1 trigger configuration from event setup
0839           pfSetsSize = m_prescaleFactorsAlgoTrig->size();
0840           triggerMasksSet = m_triggerMaskAlgoTrig;
0841         }
0842 
0843       } else {
0844         // L1 trigger configuration from event setup only
0845         pfSetsSize = m_prescaleFactorsAlgoTrig->size();
0846         triggerMasksSet = m_triggerMaskAlgoTrig;
0847       }
0848 
0849       pfIndex = pfIndexAlgoTrig;
0850 
0851     } break;
0852     case TechnicalTrigger: {
0853       if (m_retrieveL1GtTriggerMenuLite) {
0854         if (m_l1GtMenuLiteValid) {
0855           pfSetsSize = m_prescaleFactorsTechTrigLite->size();
0856           triggerMasksSet = m_triggerMaskTechTrigLite;
0857 
0858         } else {
0859           // fall through: L1 trigger configuration from event setup
0860           pfSetsSize = m_prescaleFactorsTechTrig->size();
0861           triggerMasksSet = m_triggerMaskTechTrig;
0862         }
0863 
0864       } else {
0865         // L1 trigger configuration from event setup only
0866         pfSetsSize = m_prescaleFactorsTechTrig->size();
0867         triggerMasksSet = m_triggerMaskTechTrig;
0868       }
0869 
0870       pfIndex = pfIndexTechTrig;
0871 
0872     } break;
0873     default: {
0874       // should not be the case
0875       iError = l1ConfCode + iErrorRecord + 3;
0876       return iError;
0877 
0878     } break;
0879   }
0880 
0881   // test prescale factor set index correctness, then retrieve the actual set of prescale factors
0882 
0883   if (pfIndex < 0) {
0884     iError = l1ConfCode + iErrorRecord + 1000;
0885     LogDebug("L1GtUtils") << "\nError: index of prescale factor set retrieved from the data \n"
0886                           << "less than zero."
0887                           << "\n  Value of index retrieved from data = " << pfIndex << std::endl;
0888 
0889     return iError;
0890 
0891   } else if (pfIndex >= (static_cast<int>(pfSetsSize))) {
0892     iError = l1ConfCode + iErrorRecord + 2000;
0893     LogDebug("L1GtUtils") << "\nError: index of prescale factor set retrieved from the data \n"
0894                           << "greater than the size of the vector of prescale factor sets."
0895                           << "\n  Value of index retrieved from data = " << pfIndex
0896                           << "\n  Vector size = " << pfSetsSize << std::endl;
0897 
0898     return iError;
0899 
0900   } else {
0901     switch (trigCategory) {
0902       case AlgorithmTrigger: {
0903         if (m_retrieveL1GtTriggerMenuLite) {
0904           if (m_l1GtMenuLiteValid) {
0905             prescaleFactorsSubset = &((*m_prescaleFactorsAlgoTrigLite).at(pfIndex));
0906 
0907           } else {
0908             // fall through: L1 trigger configuration from event setup
0909             prescaleFactorsSubset = &((*m_prescaleFactorsAlgoTrig).at(pfIndex));
0910           }
0911 
0912         } else {
0913           // L1 trigger configuration from event setup only
0914           prescaleFactorsSubset = &((*m_prescaleFactorsAlgoTrig).at(pfIndex));
0915         }
0916 
0917       } break;
0918       case TechnicalTrigger: {
0919         if (m_retrieveL1GtTriggerMenuLite) {
0920           if (m_l1GtMenuLiteValid) {
0921             prescaleFactorsSubset = &((*m_prescaleFactorsTechTrigLite).at(pfIndex));
0922 
0923           } else {
0924             // fall through: L1 trigger configuration from event setup
0925             prescaleFactorsSubset = &((*m_prescaleFactorsTechTrig).at(pfIndex));
0926           }
0927 
0928         } else {
0929           // L1 trigger configuration from event setup only
0930           prescaleFactorsSubset = &((*m_prescaleFactorsTechTrig).at(pfIndex));
0931         }
0932 
0933       } break;
0934       default: {
0935         // do nothing - it was tested before, with return
0936 
0937       } break;
0938     }
0939   }
0940 
0941   // algorithm result before applying the trigger masks
0942   // the bit number is positive (tested previously)
0943 
0944   switch (trigCategory) {
0945     case AlgorithmTrigger: {
0946       if (gtReadoutRecordValid) {
0947         const DecisionWord& decWord = gtReadoutRecord->decisionWord();
0948         decisionBeforeMask = trigResult(decWord, bitNumber, nameAlgoTechTrig, trigCategory, iError);
0949         if (iError) {
0950           return (iError + l1ConfCode + iErrorRecord);
0951         }
0952 
0953       } else {
0954         const DecisionWord& decWord = gtRecord->decisionWordBeforeMask();
0955         decisionBeforeMask = trigResult(decWord, bitNumber, nameAlgoTechTrig, trigCategory, iError);
0956         if (iError) {
0957           return (iError + l1ConfCode + iErrorRecord);
0958         }
0959       }
0960 
0961     } break;
0962     case TechnicalTrigger: {
0963       if (gtReadoutRecordValid) {
0964         const DecisionWord& decWord = gtReadoutRecord->technicalTriggerWord();
0965         decisionBeforeMask = trigResult(decWord, bitNumber, nameAlgoTechTrig, trigCategory, iError);
0966         if (iError) {
0967           return (iError + l1ConfCode + iErrorRecord);
0968         }
0969 
0970       } else {
0971         const DecisionWord& decWord = gtRecord->technicalTriggerWordBeforeMask();
0972         decisionBeforeMask = trigResult(decWord, bitNumber, nameAlgoTechTrig, trigCategory, iError);
0973         if (iError) {
0974           return (iError + l1ConfCode + iErrorRecord);
0975         }
0976       }
0977 
0978     } break;
0979     default: {
0980       // do nothing - it was tested before, with return
0981 
0982     } break;
0983   }
0984 
0985   // prescale factor
0986   // the bit number is positive (tested previously)
0987 
0988   if (bitNumber < (static_cast<int>(prescaleFactorsSubset->size()))) {
0989     prescaleFactor = (*prescaleFactorsSubset)[bitNumber];
0990   } else {
0991     iError = l1ConfCode + iErrorRecord + 4000;
0992     LogDebug("L1GtUtils") << "\nError: bit number " << bitNumber << " retrieved for " << triggerCategory(trigCategory)
0993                           << "\n  " << nameAlgoTechTrig << "\ngreater than size of actual L1 GT prescale factor set: "
0994                           << prescaleFactorsSubset->size() << "\nError: Inconsistent L1 trigger configuration!"
0995                           << std::endl;
0996 
0997     return iError;
0998   }
0999 
1000   // trigger mask and trigger result after applying the trigger masks
1001 
1002   if (bitNumber < (static_cast<int>((*triggerMasksSet).size()))) {
1003     if (m_retrieveL1GtTriggerMenuLite) {
1004       if (m_l1GtMenuLiteValid) {
1005         triggerMask = (*triggerMasksSet)[bitNumber];
1006 
1007       } else {
1008         // fall through: L1 trigger configuration from event setup
1009         // masks in event setup are for all partitions
1010         triggerMask = ((*triggerMasksSet)[bitNumber]) & (1 << m_physicsDaqPartition);
1011       }
1012 
1013     } else {
1014       // L1 trigger configuration from event setup only
1015       // masks in event setup are for all partitions
1016       triggerMask = ((*triggerMasksSet)[bitNumber]) & (1 << m_physicsDaqPartition);
1017     }
1018 
1019   } else {
1020     iError = l1ConfCode + iErrorRecord + 5000;
1021     LogDebug("L1GtUtils") << "\nError: bit number " << bitNumber << " retrieved for " << triggerCategory(trigCategory)
1022                           << "\n  " << nameAlgoTechTrig
1023                           << "\ngreater than size of L1 GT trigger mask set: " << (*triggerMasksSet).size()
1024                           << "\nError: Inconsistent L1 trigger configuration!" << std::endl;
1025 
1026     return iError;
1027   }
1028 
1029   decisionAfterMask = decisionBeforeMask;
1030 
1031   if (triggerMask) {
1032     decisionAfterMask = false;
1033   }
1034 
1035   return iError;
1036 }
1037 
1038 const bool L1GtUtils::decisionBeforeMask(const edm::Event& iEvent,
1039                                          const std::string& nameAlgoTechTrig,
1040                                          int& errorCode) const {
1041   // initial values
1042   bool decisionBeforeMask = false;
1043   bool decisionAfterMask = false;
1044   int prescaleFactor = -1;
1045   int triggerMask = -1;
1046 
1047   errorCode = l1Results(iEvent, nameAlgoTechTrig, decisionBeforeMask, decisionAfterMask, prescaleFactor, triggerMask);
1048 
1049   return decisionBeforeMask;
1050 }
1051 
1052 const bool L1GtUtils::decisionAfterMask(const edm::Event& iEvent,
1053                                         const std::string& nameAlgoTechTrig,
1054                                         int& errorCode) const {
1055   // initial values
1056   bool decisionBeforeMask = false;
1057   bool decisionAfterMask = false;
1058   int prescaleFactor = -1;
1059   int triggerMask = -1;
1060 
1061   errorCode = l1Results(iEvent, nameAlgoTechTrig, decisionBeforeMask, decisionAfterMask, prescaleFactor, triggerMask);
1062 
1063   return decisionAfterMask;
1064 }
1065 
1066 const bool L1GtUtils::decision(const edm::Event& iEvent, const std::string& nameAlgoTechTrig, int& errorCode) const {
1067   // initial values
1068   bool decisionBeforeMask = false;
1069   bool decisionAfterMask = false;
1070   int prescaleFactor = -1;
1071   int triggerMask = -1;
1072 
1073   errorCode = l1Results(iEvent, nameAlgoTechTrig, decisionBeforeMask, decisionAfterMask, prescaleFactor, triggerMask);
1074 
1075   return decisionAfterMask;
1076 }
1077 
1078 const int L1GtUtils::prescaleFactor(const edm::Event& iEvent,
1079                                     const std::string& nameAlgoTechTrig,
1080                                     int& errorCode) const {
1081   // initial values
1082   bool decisionBeforeMask = false;
1083   bool decisionAfterMask = false;
1084   int prescaleFactor = -1;
1085   int triggerMask = -1;
1086 
1087   errorCode = l1Results(iEvent, nameAlgoTechTrig, decisionBeforeMask, decisionAfterMask, prescaleFactor, triggerMask);
1088 
1089   return prescaleFactor;
1090 }
1091 
1092 const int L1GtUtils::triggerMask(const edm::Event& iEvent, const std::string& nameAlgoTechTrig, int& errorCode) const {
1093   // initial values
1094   bool decisionBeforeMask = false;
1095   bool decisionAfterMask = false;
1096   int prescaleFactor = -1;
1097   int triggerMask = -1;
1098 
1099   errorCode = l1Results(iEvent, nameAlgoTechTrig, decisionBeforeMask, decisionAfterMask, prescaleFactor, triggerMask);
1100 
1101   return triggerMask;
1102 }
1103 
1104 const int L1GtUtils::triggerMask(const std::string& nameAlgoTechTrig, int& errorCode) const {
1105   // initial values for returned results
1106   int triggerMaskValue = -1;
1107 
1108   // initialize error code and L1 configuration code
1109   int iError = 0;
1110   int l1ConfCode = 0;
1111 
1112   // check if L1 configuration is available
1113 
1114   if (!availableL1Configuration(iError, l1ConfCode)) {
1115     errorCode = iError;
1116     return triggerMaskValue;
1117   }
1118 
1119   // at this point, a valid L1 configuration is available, so the if/else if/else
1120   // can be simplified
1121 
1122   // if the given name is not an algorithm trigger alias, an algorithm trigger name
1123   // or a technical trigger in the current menu, return with error code 1
1124 
1125   TriggerCategory trigCategory = AlgorithmTrigger;
1126   int bitNumber = -1;
1127 
1128   if (!l1AlgoTechTrigBitNumber(nameAlgoTechTrig, trigCategory, bitNumber)) {
1129     iError = l1ConfCode + 1;
1130 
1131     if (m_retrieveL1GtTriggerMenuLite) {
1132       if (m_l1GtMenuLiteValid) {
1133         LogDebug("L1GtUtils") << "\nAlgorithm/technical trigger \n  " << nameAlgoTechTrig
1134                               << "\not found in the trigger menu \n  " << m_l1GtMenuLite->gtTriggerMenuImplementation()
1135                               << "\nretrieved from L1GtTriggerMenuLite" << std::endl;
1136 
1137       } else {
1138         // fall through: L1 trigger configuration from event setup
1139         LogDebug("L1GtUtils") << "\nAlgorithm/technical trigger \n  " << nameAlgoTechTrig
1140                               << "\not found in the trigger menu \n  " << m_l1GtMenu->gtTriggerMenuImplementation()
1141                               << "\nretrieved from Event Setup" << std::endl;
1142       }
1143 
1144     } else {
1145       // L1 trigger configuration from event setup only
1146       LogDebug("L1GtUtils") << "\nAlgorithm/technical trigger \n  " << nameAlgoTechTrig
1147                             << "\not found in the trigger menu \n  " << m_l1GtMenu->gtTriggerMenuImplementation()
1148                             << "\nretrieved from Event Setup" << std::endl;
1149     }
1150 
1151     errorCode = iError;
1152     return triggerMaskValue;
1153   }
1154 
1155   // check here if a positive bit number was retrieved
1156   // exit in case of negative bit number, before retrieving L1 GT products, saving time
1157 
1158   if (bitNumber < 0) {
1159     iError = l1ConfCode + 2;
1160 
1161     if (m_retrieveL1GtTriggerMenuLite) {
1162       if (m_l1GtMenuLiteValid) {
1163         LogDebug("L1GtUtils") << "\nNegative bit number for " << triggerCategory(trigCategory) << "\n  "
1164                               << nameAlgoTechTrig << "\nfrom menu \n  " << m_l1GtMenuLite->gtTriggerMenuImplementation()
1165                               << "\nretrieved from L1GtTriggerMenuLite" << std::endl;
1166 
1167       } else {
1168         // fall through: L1 trigger configuration from event setup
1169         LogDebug("L1GtUtils") << "\nNegative bit number for " << triggerCategory(trigCategory) << "\n  "
1170                               << nameAlgoTechTrig << "\nfrom menu \n  " << m_l1GtMenu->gtTriggerMenuImplementation()
1171                               << "\nretrieved from Event Setup" << std::endl;
1172       }
1173 
1174     } else {
1175       // L1 trigger configuration from event setup only
1176       LogDebug("L1GtUtils") << "\nNegative bit number for " << triggerCategory(trigCategory) << "\n  "
1177                             << nameAlgoTechTrig << "\nfrom menu \n  " << m_l1GtMenu->gtTriggerMenuImplementation()
1178                             << "\nretrieved from Event Setup" << std::endl;
1179     }
1180 
1181     errorCode = iError;
1182     return triggerMaskValue;
1183   }
1184 
1185   // depending on trigger category (algorithm trigger or technical trigger)
1186   // get the correct quantities
1187 
1188   // pointer to the set of trigger masks
1189 
1190   const std::vector<unsigned int>* triggerMasksSet = nullptr;
1191 
1192   switch (trigCategory) {
1193     case AlgorithmTrigger: {
1194       if (m_retrieveL1GtTriggerMenuLite) {
1195         if (m_l1GtMenuLiteValid) {
1196           triggerMasksSet = m_triggerMaskAlgoTrigLite;
1197 
1198         } else {
1199           // fall through: L1 trigger configuration from event setup
1200           triggerMasksSet = m_triggerMaskAlgoTrig;
1201         }
1202 
1203       } else {
1204         // L1 trigger configuration from event setup only
1205         triggerMasksSet = m_triggerMaskAlgoTrig;
1206       }
1207 
1208     } break;
1209     case TechnicalTrigger: {
1210       if (m_retrieveL1GtTriggerMenuLite) {
1211         if (m_l1GtMenuLiteValid) {
1212           triggerMasksSet = m_triggerMaskTechTrigLite;
1213 
1214         } else {
1215           // fall through: L1 trigger configuration from event setup
1216           triggerMasksSet = m_triggerMaskTechTrig;
1217         }
1218 
1219       } else {
1220         // L1 trigger configuration from event setup only
1221         triggerMasksSet = m_triggerMaskTechTrig;
1222       }
1223 
1224     } break;
1225     default: {
1226       // should not be the case
1227       iError = l1ConfCode + 3;
1228 
1229       errorCode = iError;
1230       return triggerMaskValue;
1231 
1232     } break;
1233   }
1234 
1235   // trigger mask
1236 
1237   if (bitNumber < (static_cast<int>((*triggerMasksSet).size()))) {
1238     if (m_retrieveL1GtTriggerMenuLite) {
1239       if (m_l1GtMenuLiteValid) {
1240         triggerMaskValue = (*triggerMasksSet)[bitNumber];
1241 
1242       } else {
1243         // fall through: L1 trigger configuration from event setup
1244         // masks in event setup are for all partitions
1245         triggerMaskValue = ((*triggerMasksSet)[bitNumber]) & (1 << m_physicsDaqPartition);
1246       }
1247 
1248     } else {
1249       // L1 trigger configuration from event setup only
1250       // masks in event setup are for all partitions
1251       triggerMaskValue = ((*triggerMasksSet)[bitNumber]) & (1 << m_physicsDaqPartition);
1252     }
1253 
1254   } else {
1255     iError = l1ConfCode + 5000;
1256     LogDebug("L1GtUtils") << "\nError: bit number " << bitNumber << " retrieved for " << triggerCategory(trigCategory)
1257                           << "\n  " << nameAlgoTechTrig
1258                           << "\ngreater than size of L1 GT trigger mask set: " << (*triggerMasksSet).size()
1259                           << "\nError: Inconsistent L1 trigger configuration!" << std::endl;
1260 
1261     errorCode = iError;
1262     return triggerMaskValue;
1263   }
1264 
1265   errorCode = iError;
1266   return triggerMaskValue;
1267 }
1268 
1269 const int L1GtUtils::prescaleFactorSetIndex(const edm::Event& iEvent,
1270                                             const TriggerCategory& trigCategory,
1271                                             int& errorCode) const {
1272   // initialize the index to a negative value
1273   int pfIndex = -1;
1274 
1275   // initialize error code and L1 configuration code
1276   int iError = 0;
1277   int l1ConfCode = 0;
1278 
1279   // check if L1 configuration is available
1280 
1281   if (!availableL1Configuration(iError, l1ConfCode)) {
1282     errorCode = iError;
1283     return pfIndex;
1284   }
1285 
1286   // at this point, a valid L1 configuration is available, so the if/else if/else
1287   // can be simplified
1288 
1289   // retrieve L1GlobalTriggerRecord and 1GlobalTriggerReadoutRecord product
1290   // intermediate error code for the records
1291   // the module returns an error code only if both the lite and the readout record are missing
1292 
1293   int iErrorRecord = 0;
1294 
1295   bool validRecord = false;
1296   bool gtReadoutRecordValid = false;
1297 
1298   edm::Handle<L1GlobalTriggerRecord> gtRecord;
1299   if (!m_l1GtUtilsHelper->l1GtRecordToken().isUninitialized()) {
1300     iEvent.getByToken(m_l1GtUtilsHelper->l1GtRecordToken(), gtRecord);
1301   }
1302   if (gtRecord.isValid()) {
1303     validRecord = true;
1304 
1305   } else {
1306     iErrorRecord = 10;
1307     LogDebug("L1GtUtils") << "\nL1GlobalTriggerRecord with \n  " << m_l1GtUtilsHelper->l1GtRecordInputTag()
1308                           << "\nnot found in the event." << std::endl;
1309   }
1310 
1311   edm::Handle<L1GlobalTriggerReadoutRecord> gtReadoutRecord;
1312   if (!m_l1GtUtilsHelper->l1GtReadoutRecordToken().isUninitialized()) {
1313     iEvent.getByToken(m_l1GtUtilsHelper->l1GtReadoutRecordToken(), gtReadoutRecord);
1314   }
1315   if (gtReadoutRecord.isValid()) {
1316     gtReadoutRecordValid = true;
1317     validRecord = true;
1318 
1319   } else {
1320     iErrorRecord = iErrorRecord + 100;
1321     LogDebug("L1GtUtils") << "\nL1GlobalTriggerReadoutRecord with \n  "
1322                           << m_l1GtUtilsHelper->l1GtReadoutRecordInputTag() << "\nnot found in the event." << std::endl;
1323   }
1324 
1325   // get the prescale factor index from
1326   //  L1GlobalTriggerReadoutRecord if valid
1327   //  if not, from L1GlobalTriggerRecord if valid
1328   //  else return an error
1329 
1330   int pfIndexTechTrig = -1;
1331   int pfIndexAlgoTrig = -1;
1332 
1333   if (validRecord) {
1334     if (gtReadoutRecordValid) {
1335       pfIndexTechTrig = (gtReadoutRecord->gtFdlWord()).gtPrescaleFactorIndexTech();
1336       pfIndexAlgoTrig = (gtReadoutRecord->gtFdlWord()).gtPrescaleFactorIndexAlgo();
1337 
1338     } else {
1339       pfIndexTechTrig = static_cast<int>(gtRecord->gtPrescaleFactorIndexTech());
1340       pfIndexAlgoTrig = static_cast<int>(gtRecord->gtPrescaleFactorIndexAlgo());
1341     }
1342 
1343   } else {
1344     LogDebug("L1GtUtils") << "\nError: "
1345                           << "\nNo valid L1GlobalTriggerRecord with \n  " << m_l1GtUtilsHelper->l1GtRecordInputTag()
1346                           << "\nfound in the event."
1347                           << "\nNo valid L1GlobalTriggerReadoutRecord with \n  "
1348                           << m_l1GtUtilsHelper->l1GtReadoutRecordInputTag() << "\nfound in the event." << std::endl;
1349 
1350     iError = l1ConfCode + iErrorRecord;
1351 
1352     errorCode = iError;
1353     return pfIndex;
1354   }
1355 
1356   // depending on trigger category (algorithm trigger or technical trigger)
1357   // get the correct quantities
1358 
1359   // number of sets of prescale factors
1360   // index of prescale factor set retrieved from data
1361   // pointer to the actual prescale factor set
1362   // pointer to the set of trigger masks
1363 
1364   size_t pfSetsSize = 0;
1365 
1366   switch (trigCategory) {
1367     case AlgorithmTrigger: {
1368       if (m_retrieveL1GtTriggerMenuLite) {
1369         if (m_l1GtMenuLiteValid) {
1370           pfSetsSize = m_prescaleFactorsAlgoTrigLite->size();
1371 
1372         } else {
1373           // fall through: L1 trigger configuration from event setup
1374           pfSetsSize = m_prescaleFactorsAlgoTrig->size();
1375         }
1376 
1377       } else {
1378         // L1 trigger configuration from event setup only
1379         pfSetsSize = m_prescaleFactorsAlgoTrig->size();
1380       }
1381 
1382       pfIndex = pfIndexAlgoTrig;
1383 
1384     } break;
1385     case TechnicalTrigger: {
1386       if (m_retrieveL1GtTriggerMenuLite) {
1387         if (m_l1GtMenuLiteValid) {
1388           pfSetsSize = m_prescaleFactorsTechTrigLite->size();
1389 
1390         } else {
1391           // fall through: L1 trigger configuration from event setup
1392           pfSetsSize = m_prescaleFactorsTechTrig->size();
1393         }
1394 
1395       } else {
1396         // L1 trigger configuration from event setup only
1397         pfSetsSize = m_prescaleFactorsTechTrig->size();
1398       }
1399 
1400       pfIndex = pfIndexTechTrig;
1401 
1402     } break;
1403     default: {
1404       // should not be the case
1405       iError = l1ConfCode + iErrorRecord + 3;
1406       return iError;
1407 
1408     } break;
1409   }
1410 
1411   // test prescale factor set index correctness, then retrieve the actual set of prescale factors
1412 
1413   if (pfIndex < 0) {
1414     iError = l1ConfCode + iErrorRecord + 1000;
1415     LogDebug("L1GtUtils") << "\nError: index of prescale factor set retrieved from the data \n"
1416                           << "less than zero."
1417                           << "\n  Value of index retrieved from data = " << pfIndex << std::endl;
1418 
1419     errorCode = iError;
1420     return pfIndex;
1421 
1422   } else if (pfIndex >= (static_cast<int>(pfSetsSize))) {
1423     iError = l1ConfCode + iErrorRecord + 2000;
1424     LogDebug("L1GtUtils") << "\nError: index of prescale factor set retrieved from the data \n"
1425                           << "greater than the size of the vector of prescale factor sets."
1426                           << "\n  Value of index retrieved from data = " << pfIndex
1427                           << "\n  Vector size = " << pfSetsSize << std::endl;
1428 
1429     errorCode = iError;
1430     return pfIndex;
1431 
1432   } else {
1433     errorCode = iError;
1434     return pfIndex;
1435   }
1436 
1437   errorCode = iError;
1438   return pfIndex;
1439 }
1440 
1441 const std::vector<int>& L1GtUtils::prescaleFactorSet(const edm::Event& iEvent,
1442                                                      const TriggerCategory& trigCategory,
1443                                                      int& errorCode) {
1444   // clear the vector before filling it
1445   m_prescaleFactorSet.clear();
1446 
1447   // initialize error code
1448   int iError = 0;
1449 
1450   const int pfIndex = prescaleFactorSetIndex(iEvent, trigCategory, iError);
1451 
1452   if (iError == 0) {
1453     switch (trigCategory) {
1454       case AlgorithmTrigger: {
1455         if (m_retrieveL1GtTriggerMenuLite) {
1456           if (m_l1GtMenuLiteValid) {
1457             m_prescaleFactorSet = (*m_prescaleFactorsAlgoTrigLite).at(pfIndex);
1458 
1459           } else {
1460             // fall through: L1 trigger configuration from event setup
1461             m_prescaleFactorSet = (*m_prescaleFactorsAlgoTrig).at(pfIndex);
1462           }
1463 
1464         } else {
1465           // L1 trigger configuration from event setup only
1466           m_prescaleFactorSet = (*m_prescaleFactorsAlgoTrig).at(pfIndex);
1467         }
1468 
1469       } break;
1470       case TechnicalTrigger: {
1471         if (m_retrieveL1GtTriggerMenuLite) {
1472           if (m_l1GtMenuLiteValid) {
1473             m_prescaleFactorSet = (*m_prescaleFactorsTechTrigLite).at(pfIndex);
1474 
1475           } else {
1476             // fall through: L1 trigger configuration from event setup
1477             m_prescaleFactorSet = (*m_prescaleFactorsTechTrig).at(pfIndex);
1478           }
1479 
1480         } else {
1481           // L1 trigger configuration from event setup only
1482           m_prescaleFactorSet = (*m_prescaleFactorsTechTrig).at(pfIndex);
1483         }
1484 
1485       } break;
1486       default: {
1487         // do nothing - it was tested before, with return
1488 
1489       } break;
1490     }
1491   }
1492 
1493   errorCode = iError;
1494   return m_prescaleFactorSet;
1495 }
1496 
1497 const std::vector<unsigned int>& L1GtUtils::triggerMaskSet(const TriggerCategory& trigCategory, int& errorCode) {
1498   // clear the vector before filling it
1499   m_triggerMaskSet.clear();
1500 
1501   // initialize error code and L1 configuration code
1502   int iError = 0;
1503   int l1ConfCode = 0;
1504 
1505   // check if L1 configuration is available
1506 
1507   if (!availableL1Configuration(iError, l1ConfCode)) {
1508     errorCode = iError;
1509     return m_triggerMaskSet;
1510   }
1511 
1512   // at this point, a valid L1 configuration is available, so the if/else if/else
1513   // can be simplified
1514 
1515   // depending on trigger category (algorithm trigger or technical trigger)
1516   // get the correct quantities
1517 
1518   // pointer to the set of trigger masks
1519 
1520   switch (trigCategory) {
1521     case AlgorithmTrigger: {
1522       if (m_retrieveL1GtTriggerMenuLite) {
1523         // L1GtTriggerMenuLite has masks for physics partition only
1524         // avoid copy to m_triggerMaskSet, return directly m_triggerMaskAlgoTrigLite
1525         if (m_l1GtMenuLiteValid) {
1526           errorCode = iError;
1527           return (*m_triggerMaskAlgoTrigLite);
1528 
1529         } else {
1530           // fall through: L1 trigger configuration from event setup
1531           for (unsigned i = 0; i < m_triggerMaskAlgoTrig->size(); i++) {
1532             m_triggerMaskSet.push_back(((*m_triggerMaskAlgoTrig)[i]) & (1 << m_physicsDaqPartition));
1533           }
1534         }
1535 
1536       } else {
1537         // L1 trigger configuration from event setup only
1538         for (unsigned i = 0; i < m_triggerMaskAlgoTrig->size(); i++) {
1539           m_triggerMaskSet.push_back(((*m_triggerMaskAlgoTrig)[i]) & (1 << m_physicsDaqPartition));
1540         }
1541       }
1542     } break;
1543     case TechnicalTrigger: {
1544       if (m_retrieveL1GtTriggerMenuLite) {
1545         if (m_l1GtMenuLiteValid) {
1546           errorCode = iError;
1547           return (*m_triggerMaskTechTrigLite);
1548 
1549         } else {
1550           // fall through: L1 trigger configuration from event setup
1551           for (unsigned i = 0; i < m_triggerMaskTechTrig->size(); i++) {
1552             m_triggerMaskSet.push_back(((*m_triggerMaskTechTrig)[i]) & (1 << m_physicsDaqPartition));
1553           }
1554         }
1555 
1556       } else {
1557         // L1 trigger configuration from event setup only
1558         for (unsigned i = 0; i < m_triggerMaskTechTrig->size(); i++) {
1559           m_triggerMaskSet.push_back(((*m_triggerMaskTechTrig)[i]) & (1 << m_physicsDaqPartition));
1560         }
1561       }
1562     } break;
1563     default: {
1564       // should not be the case
1565       iError = l1ConfCode + 3;
1566 
1567       errorCode = iError;
1568       return m_triggerMaskSet;
1569 
1570     } break;
1571   }
1572 
1573   errorCode = iError;
1574   return m_triggerMaskSet;
1575 }
1576 
1577 const std::string& L1GtUtils::l1TriggerMenu() const {
1578   if (m_retrieveL1GtTriggerMenuLite) {
1579     if (m_l1GtMenuLiteValid) {
1580       return m_l1GtMenuLite->gtTriggerMenuName();
1581 
1582     } else if (m_retrieveL1EventSetup) {
1583       return m_l1GtMenu->gtTriggerMenuName();
1584 
1585     } else {
1586       // only L1GtTriggerMenuLite requested, but it is not valid
1587       return EmptyString;
1588     }
1589   } else if (m_retrieveL1EventSetup) {
1590     return m_l1GtMenu->gtTriggerMenuName();
1591 
1592   } else {
1593     // L1 trigger configuration not retrieved
1594     return EmptyString;
1595   }
1596 }
1597 
1598 const std::string& L1GtUtils::l1TriggerMenuImplementation() const {
1599   if (m_retrieveL1GtTriggerMenuLite) {
1600     if (m_l1GtMenuLiteValid) {
1601       return m_l1GtMenuLite->gtTriggerMenuImplementation();
1602 
1603     } else if (m_retrieveL1EventSetup) {
1604       return m_l1GtMenu->gtTriggerMenuImplementation();
1605 
1606     } else {
1607       // only L1GtTriggerMenuLite requested, but it is not valid
1608       return EmptyString;
1609     }
1610   } else if (m_retrieveL1EventSetup) {
1611     return m_l1GtMenu->gtTriggerMenuImplementation();
1612 
1613   } else {
1614     // L1 trigger configuration not retrieved
1615     return EmptyString;
1616   }
1617 }
1618 
1619 const L1GtTriggerMenu* L1GtUtils::ptrL1TriggerMenuEventSetup(int& errorCode) {
1620   // initialize error code and return value
1621   int iError = 0;
1622   int l1ConfCode = 0;
1623 
1624   // check if L1 configuration is available
1625 
1626   if (!availableL1Configuration(iError, l1ConfCode)) {
1627     errorCode = iError;
1628     return nullptr;
1629   }
1630 
1631   if (m_retrieveL1EventSetup) {
1632     errorCode = iError;
1633     return m_l1GtMenu;
1634   } else {
1635     iError = l1ConfCode;
1636 
1637     errorCode = iError;
1638     return nullptr;
1639   }
1640 
1641   errorCode = iError;
1642   return m_l1GtMenu;
1643 }
1644 
1645 const L1GtTriggerMenuLite* L1GtUtils::ptrL1GtTriggerMenuLite(int& errorCode) {
1646   // initialize error code and return value
1647   int iError = 0;
1648   int l1ConfCode = 0;
1649 
1650   // check if L1 configuration is available
1651 
1652   if (!availableL1Configuration(iError, l1ConfCode)) {
1653     errorCode = iError;
1654     return nullptr;
1655   }
1656 
1657   if (m_retrieveL1GtTriggerMenuLite) {
1658     if (m_l1GtMenuLiteValid) {
1659       errorCode = iError;
1660       return m_l1GtMenuLite;
1661 
1662     } else {
1663       iError = l1ConfCode;
1664 
1665       errorCode = iError;
1666       return nullptr;
1667     }
1668   } else {
1669     iError = l1ConfCode;
1670 
1671     errorCode = iError;
1672     return nullptr;
1673   }
1674 
1675   errorCode = iError;
1676   return m_l1GtMenuLite;
1677 }
1678 
1679 const bool L1GtUtils::availableL1Configuration(int& errorCode, int& l1ConfCode) const {
1680   if (m_retrieveL1GtTriggerMenuLite) {
1681     if (!m_retrieveL1EventSetup) {
1682       LogDebug("L1GtUtils") << "\nRetrieve L1 trigger configuration from L1GtTriggerMenuLite only.\n" << std::endl;
1683       l1ConfCode = 0;
1684     } else {
1685       LogDebug("L1GtUtils") << "\nFall through: retrieve L1 trigger configuration from L1GtTriggerMenuLite."
1686                             << "\nIf L1GtTriggerMenuLite not valid, try to retrieve from event setup.\n"
1687                             << std::endl;
1688       l1ConfCode = 100000;
1689     }
1690 
1691     if (m_l1GtMenuLiteValid) {
1692       LogDebug("L1GtUtils") << "\nRetrieve L1 trigger configuration from L1GtTriggerMenuLite, valid product.\n"
1693                             << std::endl;
1694       l1ConfCode = l1ConfCode + 10000;
1695       errorCode = 0;
1696 
1697       return true;
1698 
1699     } else if (m_retrieveL1EventSetup) {
1700       if (m_l1EventSetupValid) {
1701         LogDebug("L1GtUtils") << "\nFall through: retrieve L1 trigger configuration from event setup."
1702                               << "\nFirst option was L1GtTriggerMenuLite - but product is not valid.\n"
1703                               << std::endl;
1704         l1ConfCode = l1ConfCode + 20000;
1705         errorCode = 0;
1706 
1707         return true;
1708 
1709       } else {
1710         LogDebug("L1GtUtils") << "\nFall through: L1GtTriggerMenuLite not valid, event setup not valid.\n" << std::endl;
1711         l1ConfCode = l1ConfCode + L1GtNotValidError;
1712         errorCode = l1ConfCode;
1713 
1714         return false;
1715       }
1716 
1717     } else {
1718       LogDebug("L1GtUtils") << "\nError: L1 trigger configuration requested from L1GtTriggerMenuLite only"
1719                             << "\nbut L1GtTriggerMenuLite is not valid.\n"
1720                             << std::endl;
1721       l1ConfCode = l1ConfCode + L1GtNotValidError;
1722       errorCode = l1ConfCode;
1723 
1724       return false;
1725     }
1726   } else if (m_retrieveL1EventSetup) {
1727     LogDebug("L1GtUtils") << "\nRetrieve L1 trigger configuration from event setup."
1728                           << "\nL1GtTriggerMenuLite product was not requested.\n"
1729                           << std::endl;
1730     l1ConfCode = 200000;
1731 
1732     if (m_l1EventSetupValid) {
1733       LogDebug("L1GtUtils") << "\nRetrieve L1 trigger configuration from event setup only."
1734                             << "\nValid L1 trigger event setup.\n"
1735                             << std::endl;
1736       l1ConfCode = l1ConfCode + 10000;
1737       errorCode = 0;
1738 
1739       return true;
1740 
1741     } else {
1742       LogDebug("L1GtUtils") << "\nRetrieve L1 trigger configuration from event setup only."
1743                             << "\nNo valid L1 trigger event setup.\n"
1744                             << std::endl;
1745       l1ConfCode = l1ConfCode + L1GtNotValidError;
1746       errorCode = l1ConfCode;
1747 
1748       return false;
1749     }
1750 
1751   } else {
1752     LogDebug("L1GtUtils") << "\nError: no L1 trigger configuration requested to be retrieved."
1753                           << "\nMust call before getL1GtRunCache in beginRun and analyze.\n"
1754                           << std::endl;
1755     l1ConfCode = 300000;
1756     errorCode = l1ConfCode;
1757 
1758     return false;
1759   }
1760 }
1761 
1762 // private methods
1763 
1764 const bool L1GtUtils::trigResult(const DecisionWord& decWord,
1765                                  const int bitNumber,
1766                                  const std::string& nameAlgoTechTrig,
1767                                  const TriggerCategory& trigCategory,
1768                                  int& errorCode) const {
1769   bool trigRes = false;
1770   errorCode = 0;
1771 
1772   if (bitNumber < (static_cast<int>(decWord.size()))) {
1773     trigRes = decWord[bitNumber];
1774   } else {
1775     errorCode = 3000;
1776     LogDebug("L1GtUtils") << "\nError: bit number " << bitNumber << " retrieved for " << triggerCategory(trigCategory)
1777                           << "\n  " << nameAlgoTechTrig
1778                           << "\ngreater than size of L1 GT decision word: " << decWord.size()
1779                           << "\nError: Inconsistent L1 trigger configuration!" << std::endl;
1780   }
1781 
1782   return trigRes;
1783 }
1784 
1785 L1GtUtils::LogicalExpressionL1Results::LogicalExpressionL1Results(const std::string& expression, L1GtUtils& l1GtUtils)
1786     :
1787 
1788       m_logicalExpression(expression),
1789 
1790       m_l1GtUtils(l1GtUtils),
1791 
1792       m_l1ConfCode(-1),
1793 
1794       m_validL1Configuration(false),
1795 
1796       m_validLogicalExpression(false),
1797 
1798       m_l1ResultsAlreadyCalled(false),
1799 
1800       m_expL1TriggersSize(0),
1801 
1802       m_expBitsTechTrigger(false) {
1803   initialize();
1804 }
1805 
1806 // destructor
1807 L1GtUtils::LogicalExpressionL1Results::~LogicalExpressionL1Results() {
1808   // empty
1809 }
1810 
1811 bool L1GtUtils::LogicalExpressionL1Results::initialize() {
1812   // get the vector of triggers corresponding to the logical expression
1813   // check also the logical expression - add/remove spaces if needed
1814 
1815   try {
1816     L1GtLogicParser m_l1AlgoLogicParser = L1GtLogicParser(m_logicalExpression);
1817 
1818     // list of L1 triggers from the logical expression
1819     m_expL1Triggers = m_l1AlgoLogicParser.operandTokenVector();
1820     m_expL1TriggersSize = m_expL1Triggers.size();
1821 
1822     m_validLogicalExpression = true;
1823 
1824   } catch (cms::Exception& ex) {
1825     m_validLogicalExpression = false;
1826 
1827     edm::LogWarning("L1GtUtils") << ex;
1828     edm::LogWarning("L1GtUtils") << ex.what();
1829     edm::LogWarning("L1GtUtils") << ex.explainSelf();
1830   }
1831 
1832   // try to convert the string representing each L1 trigger to bit number,
1833   //   to check if the logical expression is constructed from bit numbers
1834   // trade-off: cache it here, irrespective of the expression
1835   //   when the conversion fails (normally for the first seed,
1836   //   if not expression of technical trigger bits), stop and
1837   //   set m_expBitsTechTrigger to false
1838 
1839   m_expBitsTechTrigger = true;
1840 
1841   for (size_t iTrig = 0; iTrig < m_expL1TriggersSize; ++iTrig) {
1842     const std::string& bitString = (m_expL1Triggers[iTrig]).tokenName;
1843     std::istringstream bitStream(bitString);
1844     int bitInt;
1845 
1846     if ((bitStream >> bitInt).fail()) {
1847       m_expBitsTechTrigger = false;
1848 
1849       break;
1850     }
1851 
1852     (m_expL1Triggers[iTrig]).tokenNumber = bitInt;
1853   }
1854 
1855   // resize and fill
1856   m_decisionsBeforeMask.resize(m_expL1TriggersSize);
1857   m_decisionsAfterMask.resize(m_expL1TriggersSize);
1858   m_prescaleFactors.resize(m_expL1TriggersSize);
1859   m_triggerMasks.resize(m_expL1TriggersSize);
1860   m_errorCodes.resize(m_expL1TriggersSize);
1861   m_expTriggerCategory.resize(m_expL1TriggersSize);
1862   m_expTriggerInMenu.resize(m_expL1TriggersSize);
1863 
1864   LogDebug("L1GtUtils") << std::endl;
1865   LogTrace("L1GtUtils") << "\nLogical expression\n  " << m_logicalExpression << "\n has " << m_expL1TriggersSize
1866                         << " L1 triggers" << std::endl;
1867   for (size_t iTrig = 0; iTrig < m_expL1TriggersSize; ++iTrig) {
1868     const std::string& trigNameOrAlias = (m_expL1Triggers[iTrig]).tokenName;
1869     LogTrace("L1GtUtils") << "  " << trigNameOrAlias << std::endl;
1870 
1871     (m_decisionsBeforeMask[iTrig]).first = trigNameOrAlias;
1872     (m_decisionsBeforeMask[iTrig]).second = false;
1873 
1874     (m_decisionsAfterMask[iTrig]).first = trigNameOrAlias;
1875     (m_decisionsAfterMask[iTrig]).second = false;
1876 
1877     (m_prescaleFactors[iTrig]).first = trigNameOrAlias;
1878     (m_prescaleFactors[iTrig]).second = -1;
1879 
1880     (m_triggerMasks[iTrig]).first = trigNameOrAlias;
1881     (m_triggerMasks[iTrig]).second = -1;
1882 
1883     (m_errorCodes[iTrig]).first = trigNameOrAlias;
1884     (m_errorCodes[iTrig]).second = -1;
1885 
1886     m_expTriggerCategory[iTrig] = L1GtUtils::AlgorithmTrigger;
1887 
1888     m_expTriggerInMenu[iTrig] = false;
1889   }
1890   LogTrace("L1GtUtils") << std::endl;
1891 
1892   return true;
1893 }
1894 
1895 const int L1GtUtils::LogicalExpressionL1Results::logicalExpressionRunUpdate(const edm::Run& iRun,
1896                                                                             const edm::EventSetup& evSetup,
1897                                                                             const std::string& logicExpression) {
1898   // initialize error code
1899   int errorCode = 0;
1900 
1901   // logical expression has changed - one must re-initialize all quantities related to the logical expression
1902   // and clear the vectors
1903 
1904   m_logicalExpression = logicExpression;
1905   m_validLogicalExpression = false;
1906 
1907   m_l1ResultsAlreadyCalled = false;
1908 
1909   m_expL1TriggersSize = 0;
1910   m_expBitsTechTrigger = false;
1911 
1912   //
1913   m_decisionsBeforeMask.clear();
1914   m_decisionsAfterMask.clear();
1915   m_prescaleFactors.clear();
1916   m_triggerMasks.clear();
1917   m_errorCodes.clear();
1918   m_expTriggerCategory.clear();
1919   m_expTriggerInMenu.clear();
1920 
1921   initialize();
1922 
1923   //
1924   errorCode = logicalExpressionRunUpdate(iRun, evSetup);
1925 
1926   return errorCode;
1927 }
1928 
1929 const int L1GtUtils::LogicalExpressionL1Results::logicalExpressionRunUpdate(const edm::Run& iRun,
1930                                                                             const edm::EventSetup& evSetup) {
1931   // check first that a valid L1 configuration was retrieved,
1932   // to prevent also calls before the L1 configuration retrieval
1933 
1934   // initialize error code and L1 configuration code
1935   int errorCode = 0;
1936   int l1ConfCode = 0;
1937 
1938   if (!(m_l1GtUtils.availableL1Configuration(errorCode, l1ConfCode))) {
1939     m_validL1Configuration = false;
1940     return errorCode;
1941   } else {
1942     m_validL1Configuration = true;
1943     m_l1ConfCode = l1ConfCode;
1944   }
1945 
1946   // check if the trigger (name of alias) from the logical expression are in the menu,
1947   // if names are used, set tokenNumber to the corresponding bit number
1948   // if technical trigger bits, set tokenName to the corresponding technical trigger name, if
1949   //   a technical trigger exists on that bit
1950   // for each trigger, set also the trigger category
1951 
1952   // initialization
1953   L1GtUtils::TriggerCategory trigCategory = L1GtUtils::AlgorithmTrigger;
1954   int bitNumber = -1;
1955 
1956   for (size_t iTrig = 0; iTrig < m_expL1TriggersSize; ++iTrig) {
1957     trigCategory = L1GtUtils::AlgorithmTrigger;
1958     bitNumber = -1;
1959     const std::string& trigNameOrAlias = (m_expL1Triggers[iTrig]).tokenName;
1960 
1961     if (!m_expBitsTechTrigger) {
1962       const bool triggerInMenu = m_l1GtUtils.l1AlgoTechTrigBitNumber(trigNameOrAlias, trigCategory, bitNumber);
1963 
1964       (m_expL1Triggers[iTrig]).tokenNumber = bitNumber;
1965       m_expTriggerCategory[iTrig] = trigCategory;
1966       m_expTriggerInMenu[iTrig] = triggerInMenu;
1967 
1968     } else {
1969       std::string aliasL1Trigger;
1970       std::string nameL1Trigger;
1971 
1972       trigCategory = L1GtUtils::TechnicalTrigger;
1973       bitNumber = (m_expL1Triggers[iTrig]).tokenNumber;
1974 
1975       const bool triggerInMenu =
1976           m_l1GtUtils.l1TriggerNameFromBit(bitNumber, trigCategory, aliasL1Trigger, nameL1Trigger);
1977 
1978       if (!triggerInMenu) {
1979         aliasL1Trigger = "Technical_trigger_bit_" + (m_expL1Triggers[iTrig]).tokenName + "_empty";
1980       }
1981 
1982       (m_expL1Triggers[iTrig]).tokenName = aliasL1Trigger;
1983       m_expTriggerCategory[iTrig] = trigCategory;
1984       m_expTriggerInMenu[iTrig] = triggerInMenu;
1985 
1986       // put the names of the technical triggers in the returned quantities
1987 
1988       (m_decisionsBeforeMask[iTrig]).first = aliasL1Trigger;
1989       (m_decisionsAfterMask[iTrig]).first = aliasL1Trigger;
1990       (m_prescaleFactors[iTrig]).first = aliasL1Trigger;
1991       (m_triggerMasks[iTrig]).first = aliasL1Trigger;
1992       (m_errorCodes[iTrig]).first = aliasL1Trigger;
1993     }
1994   }
1995 
1996   return errorCode;
1997 }
1998 
1999 const std::vector<std::pair<std::string, bool> >& L1GtUtils::LogicalExpressionL1Results::decisionsBeforeMask() {
2000   // throw an exception if the result is not computed once per event - user usage error
2001   if (!m_l1ResultsAlreadyCalled) {
2002     throw cms::Exception("FailModule")
2003         << "\nUsage error: "
2004         << "\n  Method 'errorCodes' must be called in the event loop before attempting to use this method.\n"
2005         << std::endl;
2006   }
2007 
2008   return m_decisionsBeforeMask;
2009 }
2010 
2011 const std::vector<std::pair<std::string, bool> >& L1GtUtils::LogicalExpressionL1Results::decisionsAfterMask() {
2012   // throw an exception if the result is not computed once per event - user usage error
2013   if (!m_l1ResultsAlreadyCalled) {
2014     throw cms::Exception("FailModule")
2015         << "\nUsage error: "
2016         << "\n  Method 'errorCodes' must be called in the event loop before attempting to use this method.\n"
2017         << std::endl;
2018   }
2019 
2020   return m_decisionsAfterMask;
2021 }
2022 
2023 const std::vector<std::pair<std::string, int> >& L1GtUtils::LogicalExpressionL1Results::prescaleFactors() {
2024   // throw an exception if the result is not computed once per event - user usage error
2025   if (!m_l1ResultsAlreadyCalled) {
2026     throw cms::Exception("FailModule")
2027         << "\nUsage error: "
2028         << "\n  Method 'errorCodes' must be called in the event loop before attempting to use this method.\n"
2029         << std::endl;
2030   }
2031 
2032   return m_prescaleFactors;
2033 }
2034 
2035 const std::vector<std::pair<std::string, int> >& L1GtUtils::LogicalExpressionL1Results::triggerMasks() {
2036   // throw an exception if the result is not computed once per event - user usage error
2037   if (!m_l1ResultsAlreadyCalled) {
2038     throw cms::Exception("FailModule")
2039         << "\nUsage error: "
2040         << "\n  Method 'errorCodes' must be called in the event loop before attempting to use this method.\n"
2041         << std::endl;
2042   }
2043 
2044   return m_triggerMasks;
2045 }
2046 
2047 const std::vector<std::pair<std::string, int> >& L1GtUtils::LogicalExpressionL1Results::errorCodes(
2048     const edm::Event& iEvent) {
2049   m_l1ResultsAlreadyCalled = false;
2050 
2051   // if not a valid L1 configuration, reset all quantities and return
2052   if (!m_validL1Configuration) {
2053     reset(m_decisionsBeforeMask);
2054     reset(m_decisionsAfterMask);
2055     reset(m_prescaleFactors);
2056     reset(m_triggerMasks);
2057     reset(m_errorCodes);
2058 
2059     m_l1ResultsAlreadyCalled = true;
2060     return m_errorCodes;
2061   }
2062 
2063   l1Results(iEvent);
2064 
2065   m_l1ResultsAlreadyCalled = true;
2066 
2067   return m_errorCodes;
2068 }
2069 
2070 void L1GtUtils::LogicalExpressionL1Results::reset(const std::vector<std::pair<std::string, bool> >& _pairVector) const {
2071   std::vector<std::pair<std::string, bool> > pairVector = _pairVector;
2072   for (size_t iTrig = 0; iTrig < m_expL1TriggersSize; ++iTrig) {
2073     (pairVector[iTrig]).second = false;
2074   }
2075 }
2076 
2077 void L1GtUtils::LogicalExpressionL1Results::reset(const std::vector<std::pair<std::string, int> >& _pairVector) const {
2078   std::vector<std::pair<std::string, int> > pairVector = _pairVector;
2079   for (size_t iTrig = 0; iTrig < m_expL1TriggersSize; ++iTrig) {
2080     (pairVector[iTrig]).second = -1;
2081   }
2082 }
2083 
2084 void L1GtUtils::LogicalExpressionL1Results::l1Results(const edm::Event& iEvent) {
2085   // reset the vectors before filling them
2086   reset(m_decisionsBeforeMask);
2087   reset(m_decisionsAfterMask);
2088   reset(m_prescaleFactors);
2089   reset(m_triggerMasks);
2090   reset(m_errorCodes);
2091 
2092   // initialization of actual values for each trigger
2093   bool decisionBeforeMaskValue = false;
2094   bool decisionAfterMaskValue = false;
2095   int prescaleFactorValue = -1;
2096   int triggerMaskValue = -1;
2097   int errorCode = -1;
2098 
2099   LogDebug("L1GtUtils") << std::endl;
2100   LogTrace("L1GtUtils") << "\nLogical expression\n  " << m_logicalExpression << std::endl;
2101 
2102   // for each trigger, if it is in the L1 menu, get the prescale factor and trigger mask
2103 
2104   for (size_t iTrig = 0; iTrig < m_expL1TriggersSize; ++iTrig) {
2105     const std::string& trigNameOrAlias = (m_expL1Triggers[iTrig]).tokenName;
2106 
2107     if (m_expTriggerInMenu[iTrig]) {
2108       errorCode = m_l1GtUtils.l1Results(iEvent,
2109                                         trigNameOrAlias,
2110                                         decisionBeforeMaskValue,
2111                                         decisionAfterMaskValue,
2112                                         prescaleFactorValue,
2113                                         triggerMaskValue);
2114 
2115       if (errorCode != 0) {
2116         // error while retrieving the results
2117         //    for this trigger: set prescale factor to -1, trigger mask to -1
2118 
2119         decisionBeforeMaskValue = false;
2120         decisionAfterMaskValue = false;
2121         prescaleFactorValue = -1;
2122         triggerMaskValue = -1;
2123       }
2124 
2125     } else {
2126       // no trigger name or trigger alias in the menu, no bits:
2127       //    for this trigger: set prescale factor to -1, set the error code
2128 
2129       decisionBeforeMaskValue = false;
2130       decisionAfterMaskValue = false;
2131       prescaleFactorValue = -1;
2132       triggerMaskValue = -1;
2133       errorCode = m_l1ConfCode + 1;
2134     }
2135 
2136     LogTrace("L1GtUtils") << "\n" << trigNameOrAlias << ":" << std::endl;
2137 
2138     (m_decisionsBeforeMask[iTrig]).second = decisionBeforeMaskValue;
2139     LogTrace("L1GtUtils") << "    decision before mask = " << decisionBeforeMaskValue << std::endl;
2140 
2141     (m_decisionsAfterMask[iTrig]).second = decisionAfterMaskValue;
2142     LogTrace("L1GtUtils") << "    decision after mask  = " << decisionAfterMaskValue << std::endl;
2143 
2144     (m_prescaleFactors[iTrig]).second = prescaleFactorValue;
2145     LogTrace("L1GtUtils") << "    prescale factor      = " << prescaleFactorValue << std::endl;
2146 
2147     (m_triggerMasks[iTrig]).second = triggerMaskValue;
2148     LogTrace("L1GtUtils") << "    trigger mask         = " << triggerMaskValue << std::endl;
2149 
2150     (m_errorCodes[iTrig]).second = errorCode;
2151     LogTrace("L1GtUtils") << "    error code           = " << errorCode << std::endl;
2152   }
2153 
2154   LogDebug("L1GtUtils") << std::endl;
2155 }
2156 
2157 const std::string L1GtUtils::EmptyString = "";
2158 const int L1GtUtils::L1GtNotValidError = 99999;