Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-10-25 09:55:09

0001 /**
0002  * \class GlobalBoard
0003  *
0004  *
0005  * Description: Global Trigger Logic board, see header file for details.
0006  *
0007  * Implementation:
0008  *    Class responsible for receiving the objects from the different subsystems 
0009  *    and for running the Global Trigger Logic (GTL) and Final Decision Logic (FDL).
0010  *    It is directly called by the L1TGlobalProducer.
0011  *    The emulator considers a single board for all algorithms. 
0012  *
0013  * \author: M. Fierro                    - HEPHY Vienna - ORCA version
0014  * \author: V. M. Ghete                  - HEPHY Vienna - CMSSW version
0015  * \author: V. Rekovic                   - add correlation with overlap removal cases
0016  *                                       - fractional prescales
0017  * \author: E. Fontanesi                 - extended for three-body correlation conditions
0018  *
0019  * \author: E. Fontanesi, E. Yigitbasi, A. Loeliger (original implementation by S. Dildick, 2021)   
0020  *                                       - fix for the muon shower triggers and check on all BXs
0021  * \author: E. Fontanesi                 - added 2Loose HMT for 2023 Run 3
0022  *                                       - added ZDC triggers for 2023 HI data-taking
0023  * $Date$
0024  * $Revision$
0025  *
0026  */
0027 
0028 // this class header
0029 #include "L1Trigger/L1TGlobal/interface/GlobalBoard.h"
0030 
0031 // user include files
0032 #include "DataFormats/L1TGlobal/interface/GlobalObjectMap.h"
0033 #include "L1Trigger/L1TGlobal/interface/TriggerMenu.h"
0034 #include "L1Trigger/L1TGlobal/interface/GlobalAlgorithm.h"
0035 #include "L1Trigger/L1TGlobal/interface/MuonTemplate.h"
0036 #include "L1Trigger/L1TGlobal/interface/MuonShowerTemplate.h"
0037 #include "L1Trigger/L1TGlobal/interface/CaloTemplate.h"
0038 #include "L1Trigger/L1TGlobal/interface/EnergySumTemplate.h"
0039 #include "L1Trigger/L1TGlobal/interface/EnergySumZdcTemplate.h"
0040 #include "L1Trigger/L1TGlobal/interface/AXOL1TLTemplate.h"
0041 #include "L1Trigger/L1TGlobal/interface/ExternalTemplate.h"
0042 #include "L1Trigger/L1TGlobal/interface/CorrelationTemplate.h"
0043 #include "L1Trigger/L1TGlobal/interface/CorrelationThreeBodyTemplate.h"
0044 #include "L1Trigger/L1TGlobal/interface/CorrelationWithOverlapRemovalTemplate.h"
0045 #include "L1Trigger/L1TGlobal/interface/GlobalCondition.h"
0046 #include "L1Trigger/L1TGlobal/interface/CorrCondition.h"
0047 #include "L1Trigger/L1TGlobal/interface/CorrWithOverlapRemovalCondition.h"
0048 #include "L1Trigger/L1TGlobal/interface/ConditionEvaluation.h"
0049 #include "L1Trigger/L1TGlobal/interface/AlgorithmEvaluation.h"
0050 
0051 // Conditions for uGT
0052 #include "L1Trigger/L1TGlobal/interface/MuCondition.h"
0053 #include "L1Trigger/L1TGlobal/interface/MuonShowerCondition.h"
0054 #include "L1Trigger/L1TGlobal/interface/CaloCondition.h"
0055 #include "L1Trigger/L1TGlobal/interface/EnergySumCondition.h"
0056 #include "L1Trigger/L1TGlobal/interface/EnergySumZdcCondition.h"
0057 #include "L1Trigger/L1TGlobal/interface/AXOL1TLCondition.h"
0058 #include "L1Trigger/L1TGlobal/interface/ExternalCondition.h"
0059 #include "L1Trigger/L1TGlobal/interface/CorrCondition.h"
0060 #include "L1Trigger/L1TGlobal/interface/CorrThreeBodyCondition.h"
0061 #include "L1Trigger/L1TGlobal/interface/CorrWithOverlapRemovalCondition.h"
0062 
0063 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0064 #include "FWCore/MessageLogger/interface/MessageDrop.h"
0065 
0066 // Constructor
0067 l1t::GlobalBoard::GlobalBoard()
0068     : m_candL1Mu(new BXVector<const l1t::Muon*>),
0069       m_candL1MuShower(new BXVector<std::shared_ptr<l1t::MuonShower>>),
0070       m_candL1EG(new BXVector<const l1t::L1Candidate*>),
0071       m_candL1Tau(new BXVector<const l1t::L1Candidate*>),
0072       m_candL1Jet(new BXVector<const l1t::L1Candidate*>),
0073       m_candL1EtSum(new BXVector<const l1t::EtSum*>),
0074       m_candL1EtSumZdc(new BXVector<const l1t::EtSum*>),
0075       m_candL1External(new BXVector<const GlobalExtBlk*>),
0076       m_currentLumi(0),
0077       m_isDebugEnabled(edm::isDebugEnabled()) {
0078   m_uGtAlgBlk.reset();
0079 
0080   m_gtlAlgorithmOR.reset();
0081   m_gtlDecisionWord.reset();
0082 
0083   m_prescaleCounterAlgoTrig.clear();
0084 
0085   // Initialize cached IDs
0086   m_l1GtMenuCacheID = 0ULL;
0087   m_l1CaloGeometryCacheID = 0ULL;
0088   m_l1MuTriggerScalesCacheID = 0ULL;
0089 
0090   // Counter for number of events board sees
0091   m_boardEventCount = 0;
0092 
0093   // A single uGT GlobalBoard is taken into account in the emulator
0094   m_uGtBoardNumber = 0;
0095   m_uGtFinalBoard = true;
0096 }
0097 
0098 // Destructor
0099 l1t::GlobalBoard::~GlobalBoard() {
0100   delete m_candL1Mu;
0101   delete m_candL1MuShower;
0102   delete m_candL1EG;
0103   delete m_candL1Tau;
0104   delete m_candL1Jet;
0105   delete m_candL1EtSum;
0106   delete m_candL1EtSumZdc;
0107   delete m_candL1External;
0108 }
0109 
0110 // Operations
0111 void l1t::GlobalBoard::setBxFirst(int bx) { m_bxFirst_ = bx; }
0112 
0113 void l1t::GlobalBoard::setBxLast(int bx) { m_bxLast_ = bx; }
0114 
0115 // temporary class for getting axol1tl version from config to condition class until it can be got from the utm menu
0116 void l1t::GlobalBoard::setAXOL1TLModelVersion(std::string axol1tlModelVersion) {
0117   m_axol1tlModelVersion = axol1tlModelVersion;
0118 }
0119 
0120 void l1t::GlobalBoard::init(const int numberPhysTriggers,
0121                             const int nrL1Mu,
0122                             const int nrL1MuShower,
0123                             const int nrL1EG,
0124                             const int nrL1Tau,
0125                             const int nrL1Jet,
0126                             int bxFirst,
0127                             int bxLast) {
0128   setBxFirst(bxFirst);
0129   setBxLast(bxLast);
0130 
0131   m_candL1Mu->setBXRange(m_bxFirst_, m_bxLast_);
0132   m_candL1MuShower->setBXRange(m_bxFirst_, m_bxLast_);
0133   m_candL1EG->setBXRange(m_bxFirst_, m_bxLast_);
0134   m_candL1Tau->setBXRange(m_bxFirst_, m_bxLast_);
0135   m_candL1Jet->setBXRange(m_bxFirst_, m_bxLast_);
0136   m_candL1EtSum->setBXRange(m_bxFirst_, m_bxLast_);
0137   m_candL1EtSumZdc->setBXRange(m_bxFirst_, m_bxLast_);
0138   m_candL1External->setBXRange(m_bxFirst_, m_bxLast_);
0139 
0140   m_uGtAlgBlk.reset();
0141 
0142   LogDebug("L1TGlobal") << "\t Initializing Board with bxFirst = " << m_bxFirst_ << ", bxLast = " << m_bxLast_;
0143 }
0144 
0145 // receive data from Calorimeter
0146 void l1t::GlobalBoard::receiveCaloObjectData(const edm::Event& iEvent,
0147                                              const edm::EDGetTokenT<BXVector<l1t::EGamma>>& egInputToken,
0148                                              const edm::EDGetTokenT<BXVector<l1t::Tau>>& tauInputToken,
0149                                              const edm::EDGetTokenT<BXVector<l1t::Jet>>& jetInputToken,
0150                                              const edm::EDGetTokenT<BXVector<l1t::EtSum>>& sumInputToken,
0151                                              const edm::EDGetTokenT<BXVector<l1t::EtSum>>& sumZdcInputToken,
0152                                              const bool receiveEG,
0153                                              const int nrL1EG,
0154                                              const bool receiveTau,
0155                                              const int nrL1Tau,
0156                                              const bool receiveJet,
0157                                              const int nrL1Jet,
0158                                              const bool receiveEtSums,
0159                                              const bool receiveEtSumsZdc) {
0160   if (m_verbosity) {
0161     LogDebug("L1TGlobal") << "\n**** Board receiving Calo Data ";
0162   }
0163 
0164   resetCalo();
0165 
0166   // get data from Calorimeter
0167   if (receiveEG) {
0168     edm::Handle<BXVector<l1t::EGamma>> egData;
0169     iEvent.getByToken(egInputToken, egData);
0170 
0171     if (!egData.isValid()) {
0172       if (m_verbosity) {
0173         edm::LogWarning("L1TGlobal") << "\nWarning: Input tag for the BXVector<l1t::EGamma> collection"
0174                                      << "\nrequested in configuration, but not found in the event.\n";
0175       }
0176     } else {
0177       // bx in EG data
0178       for (int i = egData->getFirstBX(); i <= egData->getLastBX(); ++i) {
0179         // Prevent from pushing back bx that is outside of allowed range
0180         if (i < m_bxFirst_ || i > m_bxLast_)
0181           continue;
0182 
0183         //Loop over EG in this bx
0184         int nObj = 0;
0185         for (std::vector<l1t::EGamma>::const_iterator eg = egData->begin(i); eg != egData->end(i); ++eg) {
0186           if (nObj < nrL1EG) {
0187             (*m_candL1EG).push_back(i, &(*eg));
0188           } else {
0189             edm::LogWarning("L1TGlobal") << " Too many EG (" << nObj << ") for uGT Configuration maxEG =" << nrL1EG;
0190           }
0191           LogDebug("L1TGlobal") << "EG  Pt " << eg->hwPt() << " Eta  " << eg->hwEta() << " Phi " << eg->hwPhi()
0192                                 << "  Qual " << eg->hwQual() << "  Iso " << eg->hwIso();
0193 
0194           nObj++;
0195         }  //end loop over EG in bx
0196       }    //end loop over bx
0197     }      //end if over valid EG data
0198   }        //end if ReceiveEG data
0199 
0200   if (receiveTau) {
0201     edm::Handle<BXVector<l1t::Tau>> tauData;
0202     iEvent.getByToken(tauInputToken, tauData);
0203 
0204     if (!tauData.isValid()) {
0205       if (m_verbosity) {
0206         edm::LogWarning("L1TGlobal") << "\nWarning: Input tag for the BXVector<l1t::Tau> collection"
0207                                      << "\nrequested in configuration, but not found in the event.\n";
0208       }
0209     } else {
0210       // bx in tau data
0211       for (int i = tauData->getFirstBX(); i <= tauData->getLastBX(); ++i) {
0212         // Prevent from pushing back bx that is outside of allowed range
0213         if (i < m_bxFirst_ || i > m_bxLast_)
0214           continue;
0215 
0216         //Loop over tau in this bx
0217         int nObj = 0;
0218         for (std::vector<l1t::Tau>::const_iterator tau = tauData->begin(i); tau != tauData->end(i); ++tau) {
0219           if (nObj < nrL1Tau) {
0220             (*m_candL1Tau).push_back(i, &(*tau));
0221           } else {
0222             LogTrace("L1TGlobal") << " Too many Tau (" << nObj << ") for uGT Configuration maxTau =" << nrL1Tau;
0223           }
0224 
0225           LogDebug("L1TGlobal") << "tau  Pt " << tau->hwPt() << " Eta  " << tau->hwEta() << " Phi " << tau->hwPhi()
0226                                 << "  Qual " << tau->hwQual() << "  Iso " << tau->hwIso();
0227           nObj++;
0228 
0229         }  //end loop over tau in bx
0230       }    //end loop over bx
0231     }      //end if over valid tau data
0232   }        //end if ReceiveTau data
0233 
0234   if (receiveJet) {
0235     edm::Handle<BXVector<l1t::Jet>> jetData;
0236     iEvent.getByToken(jetInputToken, jetData);
0237 
0238     if (!jetData.isValid()) {
0239       if (m_verbosity) {
0240         edm::LogWarning("L1TGlobal") << "\nWarning: Input tag for the BXVector<l1t::Jet> collection"
0241                                      << "\nrequested in configuration, but not found in the event.\n";
0242       }
0243     } else {
0244       // bx in jet data
0245       for (int i = jetData->getFirstBX(); i <= jetData->getLastBX(); ++i) {
0246         // Prevent from pushing back bx that is outside of allowed range
0247         if (i < m_bxFirst_ || i > m_bxLast_)
0248           continue;
0249 
0250         //Loop over jet in this bx
0251         int nObj = 0;
0252         for (std::vector<l1t::Jet>::const_iterator jet = jetData->begin(i); jet != jetData->end(i); ++jet) {
0253           if (nObj < nrL1Jet) {
0254             (*m_candL1Jet).push_back(i, &(*jet));
0255           } else {
0256             edm::LogWarning("L1TGlobal") << " Too many Jets (" << nObj << ") for uGT Configuration maxJet =" << nrL1Jet;
0257           }
0258 
0259           LogDebug("L1TGlobal") << "Jet  Pt " << jet->hwPt() << " Eta  " << jet->hwEta() << " Phi " << jet->hwPhi()
0260                                 << "  Qual " << jet->hwQual() << "  Iso " << jet->hwIso();
0261           nObj++;
0262         }  //end loop over jet in bx
0263       }    //end loop over bx
0264     }      //end if over valid jet data
0265   }        //end if ReceiveJet data
0266 
0267   if (receiveEtSums) {
0268     edm::Handle<BXVector<l1t::EtSum>> etSumData;
0269     iEvent.getByToken(sumInputToken, etSumData);
0270 
0271     if (!etSumData.isValid()) {
0272       if (m_verbosity) {
0273         edm::LogWarning("L1TGlobal") << "\nWarning: Input tag for the BXVector<l1t::EtSum> collection"
0274                                      << "\nrequested in configuration, but not found in the event.\n";
0275       }
0276     } else {
0277       for (int i = etSumData->getFirstBX(); i <= etSumData->getLastBX(); ++i) {
0278         // Prevent from pushing back bx that is outside of allowed range
0279         if (i < m_bxFirst_ || i > m_bxLast_)
0280           continue;
0281 
0282         //Loop over EtSum objects in this bx
0283         for (std::vector<l1t::EtSum>::const_iterator etsum = etSumData->begin(i); etsum != etSumData->end(i); ++etsum) {
0284           (*m_candL1EtSum).push_back(i, &(*etsum));
0285 
0286           /*  In case we need to split these out
0287               switch ( etsum->getType() ) {
0288              case l1t::EtSum::EtSumType::kMissingEt:
0289                {
0290              //(*m_candETM).push_back(i,&(*etsum));
0291              LogDebug("L1TGlobal") << "ETM:  Pt " << etsum->hwPt() <<  " Phi " << etsum->hwPhi();
0292                }
0293                break; 
0294              case l1t::EtSum::EtSumType::kMissingHt:
0295                {
0296              //(*m_candHTM).push_back(i,&(*etsum));
0297              LogDebug("L1TGlobal") << "HTM:  Pt " << etsum->hwPt() <<  " Phi " << etsum->hwPhi();
0298                }
0299                break;            
0300              case l1t::EtSum::EtSumType::kTotalEt:
0301                {
0302              //(*m_candETT).push_back(i,&(*etsum));
0303              LogDebug("L1TGlobal") << "ETT:  Pt " << etsum->hwPt();
0304                }
0305                break;            
0306              case l1t::EtSum::EtSumType::kTotalHt:
0307                {
0308              //(*m_candHTT).push_back(i,&(*etsum));
0309              LogDebug("L1TGlobal") << "HTT:  Pt " << etsum->hwPt();
0310                }
0311                break;
0312              case l1t::EtSum::EtSumType::kTowerCount:
0313                {
0314              //(*m_candTowerCount).push_back(i,&(*etsum));
0315              LogDebug("L1TGlobal") << "TowerCount: " << etsum->hwPt();
0316                }
0317                break;
0318              default:
0319                LogDebug("L1TGlobal") << "Default encounted ";
0320                break;
0321           }
0322 */
0323 
0324         }  //end loop over EtSum objects in bx
0325       }    //end loop over Bx
0326     }
0327   }
0328 
0329   if (receiveEtSumsZdc) {
0330     edm::Handle<BXVector<l1t::EtSum>> etSumData;
0331     iEvent.getByToken(sumZdcInputToken, etSumData);
0332 
0333     if (!etSumData.isValid()) {
0334       if (m_verbosity) {
0335         edm::LogWarning("L1TGlobal") << "\nWarning: Input tag for the ZDC Energy Sums collection"
0336                                      << "\nrequested in configuration, but not found in the event.\n";
0337       }
0338     } else {
0339       for (int i = etSumData->getFirstBX(); i <= etSumData->getLastBX(); ++i) {
0340         // Prevent from pushing back bx that is outside of allowed range
0341         if (i < m_bxFirst_ || i > m_bxLast_)
0342           continue;
0343 
0344         for (std::vector<l1t::EtSum>::const_iterator etsum = etSumData->begin(i); etsum != etSumData->end(i); ++etsum) {
0345           (*m_candL1EtSumZdc).push_back(i, &(*etsum));
0346         }
0347       }  //end loop over Bx
0348     }
0349   }
0350 }
0351 
0352 // receive data from Global Muon Trigger
0353 void l1t::GlobalBoard::receiveMuonObjectData(const edm::Event& iEvent,
0354                                              const edm::EDGetTokenT<BXVector<l1t::Muon>>& muInputToken,
0355                                              const bool receiveMu,
0356                                              const int nrL1Mu) {
0357   if (m_verbosity) {
0358     LogDebug("L1TGlobal") << "\n**** GlobalBoard receiving muon data = ";
0359     //<< "\n     from input tag " << muInputTag << "\n"
0360   }
0361 
0362   resetMu();
0363 
0364   // get data from Global Muon Trigger
0365   if (receiveMu) {
0366     edm::Handle<BXVector<l1t::Muon>> muonData;
0367     iEvent.getByToken(muInputToken, muonData);
0368 
0369     if (!muonData.isValid()) {
0370       if (m_verbosity) {
0371         edm::LogWarning("L1TGlobal") << "\nWarning: Input tag for the BXVector<l1t::Muon> collection"
0372                                      << "\nrequested in configuration, but not found in the event.\n";
0373       }
0374     } else {
0375       // bx in muon data
0376       for (int i = muonData->getFirstBX(); i <= muonData->getLastBX(); ++i) {
0377         // Prevent from pushing back bx that is outside of allowed range
0378         if (i < m_bxFirst_ || i > m_bxLast_)
0379           continue;
0380 
0381         //Loop over Muons in this bx
0382         int nObj = 0;
0383         for (std::vector<l1t::Muon>::const_iterator mu = muonData->begin(i); mu != muonData->end(i); ++mu) {
0384           if (nObj < nrL1Mu) {
0385             (*m_candL1Mu).push_back(i, &(*mu));
0386           } else {
0387             edm::LogWarning("L1TGlobal") << " Too many Muons (" << nObj << ") for uGT Configuration maxMu =" << nrL1Mu;
0388           }
0389 
0390           LogDebug("L1TGlobal") << "Muon  Pt " << mu->hwPt() << " EtaAtVtx  " << mu->hwEtaAtVtx() << " PhiAtVtx "
0391                                 << mu->hwPhiAtVtx() << "  Qual " << mu->hwQual() << "  Iso " << mu->hwIso();
0392           nObj++;
0393         }  //end loop over muons in bx
0394       }    //end loop over bx
0395     }      //end if over valid muon data
0396   }        //end if ReceiveMuon data
0397 }
0398 
0399 // receive muon shower data from Global Muon Trigger
0400 void l1t::GlobalBoard::receiveMuonShowerObjectData(const edm::Event& iEvent,
0401                                                    const edm::EDGetTokenT<BXVector<l1t::MuonShower>>& muShowerInputToken,
0402                                                    const bool receiveMuShower,
0403                                                    const int nrL1MuShower) {
0404   // get data from Global Muon Trigger
0405   if (receiveMuShower) {
0406     edm::Handle<BXVector<l1t::MuonShower>> muonData;
0407     iEvent.getByToken(muShowerInputToken, muonData);
0408 
0409     if (!muonData.isValid()) {
0410       if (m_verbosity) {
0411         edm::LogWarning("L1TGlobal") << "\nWarning: Input tag for the BXVector<l1t::MuonShower> collection"
0412                                      << "\nrequested in configuration, but not found in the event.\n";
0413       }
0414     } else {
0415       // Loop over bx in muon data
0416       for (int i = muonData->getFirstBX(); i <= muonData->getLastBX(); ++i) {
0417         // Prevent from pushing back bx that is outside of allowed range
0418         if (i < m_bxFirst_ || i > m_bxLast_)
0419           continue;
0420 
0421         // Loop over Muon Showers in this bx
0422         int nObj = 0;
0423         for (std::vector<l1t::MuonShower>::const_iterator mu = muonData->begin(i); mu != muonData->end(i); ++mu) {
0424           if (nObj < nrL1MuShower) {
0425             /* NOTE: here the single object is split up into 5 separate MuonShower objects 
0426            similarly to the description in the UTM library, where the conditions are four different objects.
0427         */
0428 
0429             std::shared_ptr<l1t::MuonShower> musOneNominalInTime =
0430                 std::make_shared<l1t::MuonShower>(false, false, false, false, false, false);
0431             std::shared_ptr<l1t::MuonShower> musOneTightInTime =
0432                 std::make_shared<l1t::MuonShower>(false, false, false, false, false, false);
0433             std::shared_ptr<l1t::MuonShower> musTwoLooseDiffSectorsInTime =
0434                 std::make_shared<l1t::MuonShower>(false, false, false, false, false, false);
0435             std::shared_ptr<l1t::MuonShower> musOutOfTime0 =
0436                 std::make_shared<l1t::MuonShower>(false, false, false, false, false, false);
0437             std::shared_ptr<l1t::MuonShower> musOutOfTime1 =
0438                 std::make_shared<l1t::MuonShower>(false, false, false, false, false, false);
0439 
0440             musOneNominalInTime->setOneNominalInTime(mu->isOneNominalInTime());
0441             musOneTightInTime->setOneTightInTime(mu->isOneTightInTime());
0442             musTwoLooseDiffSectorsInTime->setTwoLooseDiffSectorsInTime(mu->isTwoLooseDiffSectorsInTime());
0443             musOutOfTime0->setMusOutOfTime0(mu->musOutOfTime0());
0444             musOutOfTime1->setMusOutOfTime1(mu->musOutOfTime1());
0445 
0446             (*m_candL1MuShower).push_back(i, musOneNominalInTime);
0447             (*m_candL1MuShower).push_back(i, musOneTightInTime);
0448             (*m_candL1MuShower).push_back(i, musTwoLooseDiffSectorsInTime);
0449             (*m_candL1MuShower).push_back(i, musOutOfTime0);
0450             (*m_candL1MuShower).push_back(i, musOutOfTime1);
0451 
0452           } else {
0453             edm::LogWarning("L1TGlobal") << " Too many Muon Showers (" << nObj
0454                                          << ") for uGT Configuration maxMuShower =" << nrL1MuShower;
0455           }
0456           nObj++;
0457         }  //end loop over muon showers in bx
0458       }    //end loop over bx
0459     }      //end if over valid muon shower data
0460   }        //end if ReceiveMuonShower data
0461 }
0462 
0463 // receive data from Global External Conditions
0464 void l1t::GlobalBoard::receiveExternalData(const edm::Event& iEvent,
0465                                            const edm::EDGetTokenT<BXVector<GlobalExtBlk>>& extInputToken,
0466                                            const bool receiveExt) {
0467   if (m_verbosity) {
0468     LogDebug("L1TGlobal") << "\n**** GlobalBoard receiving external data = ";
0469     //<< "\n     from input tag " << muInputTag << "\n"
0470   }
0471 
0472   resetExternal();
0473 
0474   // get data from Global Muon Trigger
0475   if (receiveExt) {
0476     edm::Handle<BXVector<GlobalExtBlk>> extData;
0477     iEvent.getByToken(extInputToken, extData);
0478 
0479     if (!extData.isValid()) {
0480       if (m_verbosity) {
0481         edm::LogWarning("L1TGlobal") << "\nWarning: Input tag for the BXVector<GlobalExtBlk> collection"
0482                                      << "\nrequested in configuration, but not found in the event.\n";
0483       }
0484     } else {
0485       // bx in muon data
0486       for (int i = extData->getFirstBX(); i <= extData->getLastBX(); ++i) {
0487         // Prevent from pushing back bx that is outside of allowed range
0488         if (i < m_bxFirst_ || i > m_bxLast_)
0489           continue;
0490 
0491         //Loop over ext in this bx
0492         for (std::vector<GlobalExtBlk>::const_iterator ext = extData->begin(i); ext != extData->end(i); ++ext) {
0493           (*m_candL1External).push_back(i, &(*ext));
0494         }  //end loop over ext in bx
0495       }    //end loop over bx
0496     }      //end if over valid ext data
0497   }        //end if ReceiveExt data
0498 }
0499 
0500 // run GTL
0501 void l1t::GlobalBoard::runGTL(const edm::Event&,
0502                               const edm::EventSetup& evSetup,
0503                               const TriggerMenu* m_l1GtMenu,
0504                               const bool produceL1GtObjectMapRecord,
0505                               const int iBxInEvent,
0506                               std::unique_ptr<GlobalObjectMapRecord>& gtObjectMapRecord,
0507                               const unsigned int numberPhysTriggers,
0508                               const int nrL1Mu,
0509                               const int nrL1MuShower,
0510                               const int nrL1EG,
0511                               const int nrL1Tau,
0512                               const int nrL1Jet) {
0513   const std::vector<ConditionMap>& conditionMap = m_l1GtMenu->gtConditionMap();
0514   const AlgorithmMap& algorithmMap = m_l1GtMenu->gtAlgorithmMap();
0515   const GlobalScales& gtScales = m_l1GtMenu->gtScales();
0516   const std::string scaleSetName = gtScales.getScalesName();
0517   LogDebug("L1TGlobal") << " L1 Menu Scales -- Set Name: " << scaleSetName;
0518 
0519   // Reset AlgBlk for this bx
0520   m_uGtAlgBlk.reset();
0521   m_algInitialOr = false;
0522   m_algPrescaledOr = false;
0523   m_algIntermOr = false;
0524   m_algFinalOr = false;
0525   m_algFinalOrVeto = false;
0526 
0527   const std::vector<std::vector<MuonTemplate>>& corrMuon = m_l1GtMenu->corMuonTemplate();
0528 
0529   const std::vector<std::vector<CaloTemplate>>& corrCalo = m_l1GtMenu->corCaloTemplate();
0530 
0531   const std::vector<std::vector<EnergySumTemplate>>& corrEnergySum = m_l1GtMenu->corEnergySumTemplate();
0532 
0533   LogDebug("L1TGlobal") << "Size corrMuon " << corrMuon.size() << "\nSize corrCalo " << corrCalo.size()
0534                         << "\nSize corrSums " << corrEnergySum.size();
0535 
0536   // -----------------------------------------------------
0537   // Loop over condition maps (one map per condition chip),
0538   // then loop over conditions in the map and
0539   // save the results in temporary maps
0540   // -----------------------------------------------------
0541   // never happens in production but at first event...
0542   if (m_conditionResultMaps.size() != conditionMap.size()) {
0543     m_conditionResultMaps.clear();
0544     m_conditionResultMaps.resize(conditionMap.size());
0545   }
0546 
0547   int iChip = -1;
0548 
0549   for (std::vector<ConditionMap>::const_iterator itCondOnChip = conditionMap.begin();
0550        itCondOnChip != conditionMap.end();
0551        itCondOnChip++) {
0552     iChip++;
0553 
0554     AlgorithmEvaluation::ConditionEvaluationMap& cMapResults = m_conditionResultMaps[iChip];
0555 
0556     for (CItCond itCond = itCondOnChip->begin(); itCond != itCondOnChip->end(); itCond++) {
0557       // evaluate condition
0558       switch ((itCond->second)->condCategory()) {
0559         case CondMuon: {
0560           // BLW Not sure what to do with this for now
0561           const int ifMuEtaNumberBits = 0;
0562 
0563           MuCondition* muCondition = new MuCondition(itCond->second, this, nrL1Mu, ifMuEtaNumberBits);
0564 
0565           muCondition->setVerbosity(m_verbosity);
0566 
0567           muCondition->evaluateConditionStoreResult(iBxInEvent);
0568 
0569           cMapResults[itCond->first] = muCondition;
0570 
0571           if (m_verbosity && m_isDebugEnabled) {
0572             std::ostringstream myCout;
0573             muCondition->print(myCout);
0574 
0575             LogTrace("L1TGlobal") << myCout.str();
0576           }
0577           //delete muCondition;
0578 
0579         } break;
0580         case CondMuonShower: {
0581           MuonShowerCondition* muShowerCondition = new MuonShowerCondition(itCond->second, this, nrL1MuShower);
0582 
0583           muShowerCondition->setVerbosity(m_verbosity);
0584 
0585           muShowerCondition->evaluateConditionStoreResult(iBxInEvent);
0586 
0587           cMapResults[itCond->first] = muShowerCondition;
0588 
0589           if (m_verbosity && m_isDebugEnabled) {
0590             std::ostringstream myCout;
0591             muShowerCondition->print(myCout);
0592 
0593             edm::LogWarning("L1TGlobal") << "MuonShowerCondition " << myCout.str();
0594           }
0595           //delete muShowerCondition;
0596 
0597         } break;
0598         case CondCalo: {
0599           // BLW Not sure w hat to do with this for now
0600           const int ifCaloEtaNumberBits = 0;
0601 
0602           CaloCondition* caloCondition =
0603               new CaloCondition(itCond->second, this, nrL1EG, nrL1Jet, nrL1Tau, ifCaloEtaNumberBits);
0604 
0605           caloCondition->setVerbosity(m_verbosity);
0606 
0607           caloCondition->evaluateConditionStoreResult(iBxInEvent);
0608 
0609           cMapResults[itCond->first] = caloCondition;
0610 
0611           if (m_verbosity && m_isDebugEnabled) {
0612             std::ostringstream myCout;
0613             caloCondition->print(myCout);
0614 
0615             LogTrace("L1TGlobal") << myCout.str();
0616           }
0617           //                    delete caloCondition;
0618 
0619         } break;
0620         case CondEnergySum: {
0621           EnergySumCondition* eSumCondition = new EnergySumCondition(itCond->second, this);
0622 
0623           eSumCondition->setVerbosity(m_verbosity);
0624           eSumCondition->evaluateConditionStoreResult(iBxInEvent);
0625 
0626           cMapResults[itCond->first] = eSumCondition;
0627 
0628           if (m_verbosity && m_isDebugEnabled) {
0629             std::ostringstream myCout;
0630             eSumCondition->print(myCout);
0631 
0632             LogTrace("L1TGlobal") << myCout.str();
0633           }
0634           //                    delete eSumCondition;
0635 
0636         } break;
0637         case CondEnergySumZdc: {
0638           EnergySumZdcCondition* eSumZdcCondition = new EnergySumZdcCondition(itCond->second, this);
0639 
0640           eSumZdcCondition->setVerbosity(m_verbosity);
0641           eSumZdcCondition->evaluateConditionStoreResult(iBxInEvent);
0642 
0643           cMapResults[itCond->first] = eSumZdcCondition;
0644 
0645           if (m_verbosity && m_isDebugEnabled) {
0646             std::ostringstream myCout;
0647             eSumZdcCondition->print(myCout);
0648 
0649             LogTrace("L1TGlobal") << myCout.str();
0650           }
0651           //                    delete eSumZdcCondition;
0652 
0653         } break;
0654         case CondAXOL1TL: {
0655           AXOL1TLCondition* axol1tlCondition = new AXOL1TLCondition(itCond->second, this);
0656 
0657           axol1tlCondition->setVerbosity(m_verbosity);
0658 
0659           axol1tlCondition->setModelVersion(m_axol1tlModelVersion);
0660 
0661           axol1tlCondition->evaluateConditionStoreResult(iBxInEvent);
0662 
0663           cMapResults[itCond->first] = axol1tlCondition;
0664 
0665           if (m_verbosity && m_isDebugEnabled) {
0666             std::ostringstream myCout;
0667             axol1tlCondition->print(myCout);
0668 
0669             edm::LogWarning("L1TGlobal") << "axol1tlCondition " << myCout.str();
0670           }
0671           //delete axol1tlCCondition;
0672 
0673         } break;
0674 
0675         case CondExternal: {
0676           ExternalCondition* extCondition = new ExternalCondition(itCond->second, this);
0677 
0678           extCondition->setVerbosity(m_verbosity);
0679           extCondition->evaluateConditionStoreResult(iBxInEvent);
0680 
0681           cMapResults[itCond->first] = extCondition;
0682 
0683           if (m_verbosity && m_isDebugEnabled) {
0684             std::ostringstream myCout;
0685             extCondition->print(myCout);
0686 
0687             LogTrace("L1TGlobal") << myCout.str();
0688           }
0689           //                    delete extCondition;
0690 
0691         } break;
0692         case CondCorrelation: {
0693           // get first the subconditions
0694           const CorrelationTemplate* corrTemplate = static_cast<const CorrelationTemplate*>(itCond->second);
0695           const GtConditionCategory cond0Categ = corrTemplate->cond0Category();
0696           const GtConditionCategory cond1Categ = corrTemplate->cond1Category();
0697           const int cond0Ind = corrTemplate->cond0Index();
0698           const int cond1Ind = corrTemplate->cond1Index();
0699 
0700           const GlobalCondition* cond0Condition = nullptr;
0701           const GlobalCondition* cond1Condition = nullptr;
0702 
0703           // maximum number of objects received for evaluation of l1t::Type1s condition
0704           int cond0NrL1Objects = 0;
0705           int cond1NrL1Objects = 0;
0706           LogDebug("L1TGlobal") << " cond0NrL1Objects" << cond0NrL1Objects << "  cond1NrL1Objects  "
0707                                 << cond1NrL1Objects;
0708 
0709           switch (cond0Categ) {
0710             case CondMuon: {
0711               cond0Condition = &((corrMuon[iChip])[cond0Ind]);
0712             } break;
0713             case CondCalo: {
0714               cond0Condition = &((corrCalo[iChip])[cond0Ind]);
0715             } break;
0716             case CondEnergySum: {
0717               cond0Condition = &((corrEnergySum[iChip])[cond0Ind]);
0718             } break;
0719             default: {
0720               // do nothing, should not arrive here
0721             } break;
0722           }
0723 
0724           switch (cond1Categ) {
0725             case CondMuon: {
0726               cond1Condition = &((corrMuon[iChip])[cond1Ind]);
0727             } break;
0728             case CondCalo: {
0729               cond1Condition = &((corrCalo[iChip])[cond1Ind]);
0730             } break;
0731             case CondEnergySum: {
0732               cond1Condition = &((corrEnergySum[iChip])[cond1Ind]);
0733             } break;
0734             default: {
0735               // do nothing, should not arrive here
0736             } break;
0737           }
0738 
0739           CorrCondition* correlationCond = new CorrCondition(itCond->second, cond0Condition, cond1Condition, this);
0740 
0741           correlationCond->setVerbosity(m_verbosity);
0742           correlationCond->setScales(&gtScales);
0743           correlationCond->evaluateConditionStoreResult(iBxInEvent);
0744 
0745           cMapResults[itCond->first] = correlationCond;
0746 
0747           if (m_verbosity && m_isDebugEnabled) {
0748             std::ostringstream myCout;
0749             correlationCond->print(myCout);
0750 
0751             LogTrace("L1TGlobal") << myCout.str();
0752           }
0753 
0754           //        delete correlationCond;
0755 
0756         } break;
0757         case CondCorrelationThreeBody: {
0758           // get first the subconditions
0759           const CorrelationThreeBodyTemplate* corrTemplate =
0760               static_cast<const CorrelationThreeBodyTemplate*>(itCond->second);
0761           const GtConditionCategory cond0Categ = corrTemplate->cond0Category();
0762           const GtConditionCategory cond1Categ = corrTemplate->cond1Category();
0763           const GtConditionCategory cond2Categ = corrTemplate->cond2Category();
0764           const int cond0Ind = corrTemplate->cond0Index();
0765           const int cond1Ind = corrTemplate->cond1Index();
0766           const int cond2Ind = corrTemplate->cond2Index();
0767 
0768           const GlobalCondition* cond0Condition = nullptr;
0769           const GlobalCondition* cond1Condition = nullptr;
0770           const GlobalCondition* cond2Condition = nullptr;
0771 
0772           // maximum number of objects received for evaluation of l1t::Type1s condition
0773           int cond0NrL1Objects = 0;
0774           int cond1NrL1Objects = 0;
0775           int cond2NrL1Objects = 0;
0776           LogDebug("L1TGlobal") << "  cond0NrL1Objects  " << cond0NrL1Objects << "  cond1NrL1Objects  "
0777                                 << cond1NrL1Objects << "  cond2NrL1Objects  " << cond2NrL1Objects;
0778           if (cond0Categ == CondMuon) {
0779             cond0Condition = &((corrMuon[iChip])[cond0Ind]);
0780           } else {
0781             LogDebug("L1TGlobal") << "No muon0 to evaluate three-body correlation condition";
0782           }
0783           if (cond1Categ == CondMuon) {
0784             cond1Condition = &((corrMuon[iChip])[cond1Ind]);
0785           } else {
0786             LogDebug("L1TGlobal") << "No muon1 to evaluate three-body correlation condition";
0787           }
0788           if (cond2Categ == CondMuon) {
0789             cond2Condition = &((corrMuon[iChip])[cond2Ind]);
0790           } else {
0791             LogDebug("L1TGlobal") << "No muon2 to evaluate three-body correlation condition";
0792           }
0793 
0794           CorrThreeBodyCondition* correlationThreeBodyCond =
0795               new CorrThreeBodyCondition(itCond->second, cond0Condition, cond1Condition, cond2Condition, this);
0796 
0797           correlationThreeBodyCond->setVerbosity(m_verbosity);
0798           correlationThreeBodyCond->setScales(&gtScales);
0799           correlationThreeBodyCond->evaluateConditionStoreResult(iBxInEvent);
0800           cMapResults[itCond->first] = correlationThreeBodyCond;
0801 
0802           if (m_verbosity && m_isDebugEnabled) {
0803             std::ostringstream myCout;
0804             correlationThreeBodyCond->print(myCout);
0805 
0806             LogTrace("L1TGlobal") << myCout.str();
0807           }
0808           //              delete correlationThreeBodyCond;
0809         } break;
0810 
0811         case CondCorrelationWithOverlapRemoval: {
0812           // get first the subconditions
0813           const CorrelationWithOverlapRemovalTemplate* corrTemplate =
0814               static_cast<const CorrelationWithOverlapRemovalTemplate*>(itCond->second);
0815           const GtConditionCategory cond0Categ = corrTemplate->cond0Category();
0816           const GtConditionCategory cond1Categ = corrTemplate->cond1Category();
0817           const GtConditionCategory cond2Categ = corrTemplate->cond2Category();
0818           const int cond0Ind = corrTemplate->cond0Index();
0819           const int cond1Ind = corrTemplate->cond1Index();
0820           const int cond2Ind = corrTemplate->cond2Index();
0821 
0822           const GlobalCondition* cond0Condition = nullptr;
0823           const GlobalCondition* cond1Condition = nullptr;
0824           const GlobalCondition* cond2Condition = nullptr;
0825 
0826           // maximum number of objects received for evaluation of l1t::Type1s condition
0827           int cond0NrL1Objects = 0;
0828           int cond1NrL1Objects = 0;
0829           int cond2NrL1Objects = 0;
0830           LogDebug("L1TGlobal") << " cond0NrL1Objects" << cond0NrL1Objects << "  cond1NrL1Objects  " << cond1NrL1Objects
0831                                 << " cond2NrL1Objects  " << cond2NrL1Objects;
0832 
0833           switch (cond0Categ) {
0834             case CondMuon: {
0835               cond0Condition = &((corrMuon[iChip])[cond0Ind]);
0836             } break;
0837             case CondCalo: {
0838               cond0Condition = &((corrCalo[iChip])[cond0Ind]);
0839             } break;
0840             case CondEnergySum: {
0841               cond0Condition = &((corrEnergySum[iChip])[cond0Ind]);
0842             } break;
0843             default: {
0844               // do nothing, should not arrive here
0845             } break;
0846           }
0847 
0848           switch (cond1Categ) {
0849             case CondMuon: {
0850               cond1Condition = &((corrMuon[iChip])[cond1Ind]);
0851             } break;
0852             case CondCalo: {
0853               cond1Condition = &((corrCalo[iChip])[cond1Ind]);
0854             } break;
0855             case CondEnergySum: {
0856               cond1Condition = &((corrEnergySum[iChip])[cond1Ind]);
0857             } break;
0858             default: {
0859               // do nothing, should not arrive here
0860             } break;
0861           }
0862 
0863           switch (cond2Categ) {
0864             case CondMuon: {
0865               cond2Condition = &((corrMuon[iChip])[cond2Ind]);
0866             } break;
0867             case CondCalo: {
0868               cond2Condition = &((corrCalo[iChip])[cond2Ind]);
0869             } break;
0870             case CondEnergySum: {
0871               cond2Condition = &((corrEnergySum[iChip])[cond2Ind]);
0872             } break;
0873             default: {
0874               // do nothing, should not arrive here
0875             } break;
0876           }
0877 
0878           CorrWithOverlapRemovalCondition* correlationCondWOR =
0879               new CorrWithOverlapRemovalCondition(itCond->second, cond0Condition, cond1Condition, cond2Condition, this);
0880 
0881           correlationCondWOR->setVerbosity(m_verbosity);
0882           correlationCondWOR->setScales(&gtScales);
0883           correlationCondWOR->evaluateConditionStoreResult(iBxInEvent);
0884 
0885           cMapResults[itCond->first] = correlationCondWOR;
0886 
0887           if (m_verbosity && m_isDebugEnabled) {
0888             std::ostringstream myCout;
0889             correlationCondWOR->print(myCout);
0890 
0891             LogTrace("L1TGlobal") << myCout.str();
0892           }
0893 
0894           //        delete correlationCondWOR;
0895 
0896         } break;
0897         case CondNull: {
0898           // do nothing
0899 
0900         } break;
0901         default: {
0902           // do nothing
0903 
0904         } break;
0905       }
0906     }
0907   }
0908 
0909   // -----------------------
0910   // Loop over algorithm map
0911   // -----------------------
0912   // Empty vector for object maps - filled during loop
0913   std::vector<GlobalObjectMap> objMapVec;
0914   if (produceL1GtObjectMapRecord && (iBxInEvent == 0))
0915     objMapVec.reserve(numberPhysTriggers);
0916 
0917   for (CItAlgo itAlgo = algorithmMap.begin(); itAlgo != algorithmMap.end(); itAlgo++) {
0918     AlgorithmEvaluation gtAlg(itAlgo->second);
0919     gtAlg.evaluateAlgorithm((itAlgo->second).algoChipNumber(), m_conditionResultMaps);
0920 
0921     int algBitNumber = (itAlgo->second).algoBitNumber();
0922     bool algResult = gtAlg.gtAlgoResult();
0923 
0924     LogDebug("L1TGlobal") << " ===> for iBxInEvent = " << iBxInEvent << ":\t algBitName = " << itAlgo->first
0925                           << ",\t algBitNumber = " << algBitNumber << ",\t algResult = " << algResult;
0926 
0927     if (algResult) {
0928       //            m_gtlAlgorithmOR.set(algBitNumber);
0929       m_uGtAlgBlk.setAlgoDecisionInitial(algBitNumber, algResult);
0930       m_algInitialOr = true;
0931     }
0932 
0933     if (m_verbosity && m_isDebugEnabled) {
0934       std::ostringstream myCout;
0935       (itAlgo->second).print(myCout);
0936       gtAlg.print(myCout);
0937 
0938       LogTrace("L1TGlobal") << myCout.str();
0939     }
0940 
0941     // object maps only for BxInEvent = 0
0942     if (produceL1GtObjectMapRecord && (iBxInEvent == 0)) {
0943       std::vector<L1TObjectTypeInCond> otypes;
0944       for (auto iop = gtAlg.operandTokenVector().begin(); iop != gtAlg.operandTokenVector().end(); ++iop) {
0945         //cout << "INFO:  operand name:  " << iop->tokenName << "\n";
0946         int found = 0;
0947         L1TObjectTypeInCond otype;
0948         for (auto imap = conditionMap.begin(); imap != conditionMap.end(); imap++) {
0949           auto match = imap->find(iop->tokenName);
0950 
0951           if (match != imap->end()) {
0952             found = 1;
0953             //cout << "DEBUG: found match for " << iop->tokenName << " at " << match->first << "\n";
0954 
0955             otype = match->second->objectType();
0956 
0957             for (auto itype = otype.begin(); itype != otype.end(); itype++) {
0958               //cout << "type:  " << *itype << "\n";
0959             }
0960           }
0961         }
0962         if (!found) {
0963           edm::LogWarning("L1TGlobal") << "\n Failed to find match for operand token " << iop->tokenName << "\n";
0964         } else {
0965           otypes.push_back(otype);
0966         }
0967       }
0968 
0969       // set object map
0970       GlobalObjectMap objMap;
0971 
0972       objMap.setAlgoName(itAlgo->first);
0973       objMap.setAlgoBitNumber(algBitNumber);
0974       objMap.setAlgoGtlResult(algResult);
0975       objMap.swapOperandTokenVector(gtAlg.operandTokenVector());
0976       objMap.swapCombinationVector(gtAlg.gtAlgoCombinationVector());
0977       // gtAlg is empty now...
0978       objMap.swapObjectTypeVector(otypes);
0979 
0980       if (m_verbosity && m_isDebugEnabled) {
0981         std::ostringstream myCout1;
0982         objMap.print(myCout1);
0983 
0984         LogTrace("L1TGlobal") << myCout1.str();
0985       }
0986 
0987       objMapVec.push_back(objMap);
0988     }
0989   }
0990 
0991   // object maps only for BxInEvent = 0
0992   if (produceL1GtObjectMapRecord && (iBxInEvent == 0)) {
0993     gtObjectMapRecord->swapGtObjectMap(objMapVec);
0994   }
0995 
0996   // loop over condition maps (one map per condition chip)
0997   // then loop over conditions in the map
0998   // delete the conditions created with new, zero pointer, do not clear map, keep the vector as is...
0999   for (std::vector<AlgorithmEvaluation::ConditionEvaluationMap>::iterator itCondOnChip = m_conditionResultMaps.begin();
1000        itCondOnChip != m_conditionResultMaps.end();
1001        itCondOnChip++) {
1002     for (AlgorithmEvaluation::ItEvalMap itCond = itCondOnChip->begin(); itCond != itCondOnChip->end(); itCond++) {
1003       delete itCond->second;
1004       itCond->second = nullptr;
1005     }
1006   }
1007 }
1008 
1009 // -------
1010 // Run GTL
1011 // -------
1012 void l1t::GlobalBoard::runFDL(const edm::Event& iEvent,
1013                               const int iBxInEvent,
1014                               const int totalBxInEvent,
1015                               const unsigned int numberPhysTriggers,
1016                               const std::vector<double>& prescaleFactorsAlgoTrig,
1017                               const std::vector<unsigned int>& triggerMaskAlgoTrig,
1018                               const std::vector<int>& triggerMaskVetoAlgoTrig,
1019                               const bool algorithmTriggersUnprescaled,
1020                               const bool algorithmTriggersUnmasked) {
1021   if (m_verbosity) {
1022     LogDebug("L1TGlobal") << "\n**** GlobalBoard apply Final Decision Logic ";
1023   }
1024 
1025   // update and clear prescales at the beginning of the luminosity segment
1026   if (m_prescaleCounterAlgoTrig.empty() or
1027       (m_currentLumi != iEvent.luminosityBlock() and m_resetPSCountersEachLumiSec)) {
1028     m_prescaleCounterAlgoTrig.clear();
1029     m_prescaleCounterAlgoTrig.reserve(totalBxInEvent);
1030     auto const& prescaleCountersAlgoTrig =
1031         m_semiRandomInitialPSCounters ? prescaleCountersWithSemirandomInitialCounter(prescaleFactorsAlgoTrig, iEvent)
1032                                       : prescaleCounters(prescaleFactorsAlgoTrig);
1033     for (int iBxInEvent = 0; iBxInEvent < totalBxInEvent; ++iBxInEvent) {
1034       m_prescaleCounterAlgoTrig.push_back(prescaleCountersAlgoTrig);
1035     }
1036 
1037     m_currentLumi = iEvent.luminosityBlock();
1038   }
1039 
1040   // Copy Algorithm bits to Prescaled word
1041   // Prescaling and Masking done below if requested.
1042   m_uGtAlgBlk.copyInitialToInterm();
1043 
1044   // -------------------------------------------
1045   //      Apply Prescales or skip if turned off
1046   // -------------------------------------------
1047   if (!algorithmTriggersUnprescaled) {
1048     // iBxInEvent is ... -2 -1 0 1 2 ... while counters are 0 1 2 3 4 ...
1049     int const inBxInEvent = totalBxInEvent / 2 + iBxInEvent;
1050 
1051     bool temp_algPrescaledOr = false;
1052     bool alreadyReported = false;
1053     for (unsigned int iBit = 0; iBit < numberPhysTriggers; ++iBit) {
1054       bool const bitValue = m_uGtAlgBlk.getAlgoDecisionInitial(iBit);
1055       if (bitValue) {
1056         // Make sure algo bit in range, warn otherwise
1057         if (iBit < prescaleFactorsAlgoTrig.size()) {
1058           if (prescaleFactorsAlgoTrig.at(iBit) != 1) {
1059             bool const triggered = m_prescaleCounterAlgoTrig.at(inBxInEvent).at(iBit).accept();
1060             if (triggered) {
1061               temp_algPrescaledOr = true;
1062             } else {
1063               // change bit to false in prescaled word and final decision word
1064               m_uGtAlgBlk.setAlgoDecisionInterm(iBit, false);
1065             }  //if Prescale counter reached zero
1066           }    //if prescale factor is not 1 (ie. no prescale)
1067           else {
1068             temp_algPrescaledOr = true;
1069           }
1070         }  // require bit in range
1071         else if (!alreadyReported) {
1072           alreadyReported = true;
1073           edm::LogWarning("L1TGlobal") << "\nWarning: algoBit >= prescaleFactorsAlgoTrig.size() in bx " << iBxInEvent;
1074         }
1075       }  //if algo bit is set true
1076     }    //loop over alg bits
1077 
1078     m_algPrescaledOr = temp_algPrescaledOr;  //temp
1079 
1080   } else {
1081     // Since not Prescaling just take OR of Initial Work
1082     m_algPrescaledOr = m_algInitialOr;
1083 
1084   }  //if we are going to apply prescales.
1085 
1086   // Copy Algorithm bits fron Prescaled word to Final Word
1087   // Masking done below if requested.
1088   m_uGtAlgBlk.copyIntermToFinal();
1089 
1090   if (!algorithmTriggersUnmasked) {
1091     bool temp_algFinalOr = false;
1092     bool alreadyReported = false;
1093     for (unsigned int iBit = 0; iBit < numberPhysTriggers; ++iBit) {
1094       const bool bitValue = m_uGtAlgBlk.getAlgoDecisionInterm(iBit);
1095 
1096       if (bitValue) {
1097         //bool isMasked = ( triggerMaskAlgoTrig.at(iBit) == 0 );
1098         bool isMasked = false;
1099         if (iBit < triggerMaskAlgoTrig.size())
1100           isMasked = (triggerMaskAlgoTrig.at(iBit) == 0);
1101         else if (!alreadyReported) {
1102           alreadyReported = true;
1103           edm::LogWarning("L1TGlobal") << "\nWarning: algoBit >= triggerMaskAlgoTrig.size() in bx " << iBxInEvent;
1104         }
1105 
1106         bool const passMask = (bitValue && !isMasked);
1107 
1108         if (passMask)
1109           temp_algFinalOr = true;
1110         else
1111           m_uGtAlgBlk.setAlgoDecisionFinal(iBit, false);
1112 
1113         // Check if veto mask is true, if it is, set the event veto flag.
1114         if (triggerMaskVetoAlgoTrig.at(iBit) == 1)
1115           m_algFinalOrVeto = true;
1116       }
1117     }
1118 
1119     m_algIntermOr = temp_algFinalOr;
1120 
1121   } else {
1122     m_algIntermOr = m_algPrescaledOr;
1123 
1124   }  ///if we are masking.
1125 
1126   // --------------------------
1127   // Set FinalOR for this board
1128   // --------------------------
1129   m_algFinalOr = (m_algIntermOr & !m_algFinalOrVeto);
1130 }
1131 
1132 // Fill DAQ Record
1133 void l1t::GlobalBoard::fillAlgRecord(int iBxInEvent,
1134                                      std::unique_ptr<GlobalAlgBlkBxCollection>& uGtAlgRecord,
1135                                      int prescaleSet,
1136                                      int menuUUID,
1137                                      int firmwareUUID) {
1138   if (m_verbosity) {
1139     LogDebug("L1TGlobal") << "\n**** GlobalBoard fill DAQ Records for bx= " << iBxInEvent;
1140   }
1141 
1142   // Set header information
1143   m_uGtAlgBlk.setbxInEventNr((iBxInEvent & 0xF));
1144   m_uGtAlgBlk.setPreScColumn(prescaleSet);
1145   m_uGtAlgBlk.setL1MenuUUID(menuUUID);
1146   m_uGtAlgBlk.setL1FirmwareUUID(firmwareUUID);
1147 
1148   m_uGtAlgBlk.setFinalORVeto(m_algFinalOrVeto);
1149   m_uGtAlgBlk.setFinalORPreVeto(m_algIntermOr);
1150   m_uGtAlgBlk.setFinalOR(m_algFinalOr);
1151 
1152   uGtAlgRecord->push_back(iBxInEvent, m_uGtAlgBlk);
1153 }
1154 
1155 // clear GTL
1156 void l1t::GlobalBoard::reset() {
1157   resetMu();
1158   resetMuonShower();
1159   resetCalo();
1160   resetExternal();
1161 
1162   m_uGtAlgBlk.reset();
1163 
1164   m_gtlDecisionWord.reset();
1165   m_gtlAlgorithmOR.reset();
1166 }
1167 
1168 // clear muon
1169 void l1t::GlobalBoard::resetMu() {
1170   m_candL1Mu->clear();
1171   m_candL1Mu->setBXRange(m_bxFirst_, m_bxLast_);
1172 }
1173 
1174 // clear muon shower
1175 void l1t::GlobalBoard::resetMuonShower() {
1176   m_candL1MuShower->clear();
1177   m_candL1MuShower->setBXRange(m_bxFirst_, m_bxLast_);
1178 }
1179 
1180 // clear calo
1181 void l1t::GlobalBoard::resetCalo() {
1182   m_candL1EG->clear();
1183   m_candL1Tau->clear();
1184   m_candL1Jet->clear();
1185   m_candL1EtSum->clear();
1186   m_candL1EtSumZdc->clear();
1187 
1188   m_candL1EG->setBXRange(m_bxFirst_, m_bxLast_);
1189   m_candL1Tau->setBXRange(m_bxFirst_, m_bxLast_);
1190   m_candL1Jet->setBXRange(m_bxFirst_, m_bxLast_);
1191   m_candL1EtSum->setBXRange(m_bxFirst_, m_bxLast_);
1192   m_candL1EtSumZdc->setBXRange(m_bxFirst_, m_bxLast_);
1193 }
1194 
1195 void l1t::GlobalBoard::resetExternal() {
1196   m_candL1External->clear();
1197   m_candL1External->setBXRange(m_bxFirst_, m_bxLast_);
1198 }
1199 
1200 // print Global Muon Trigger data received
1201 void l1t::GlobalBoard::printGmtData(const int iBxInEvent) const {
1202   LogTrace("L1TGlobal") << "\nl1t::L1GlobalTrigger: uGMT data received for BxInEvent = " << iBxInEvent;
1203 
1204   int nrL1Mu = m_candL1Mu->size(iBxInEvent);
1205   LogTrace("L1TGlobal") << "Number of GMT muons = " << nrL1Mu << "\n";
1206 }
1207 
1208 // initialize prescale counters to zero
1209 std::vector<l1t::GlobalBoard::PrescaleCounter> l1t::GlobalBoard::prescaleCounters(
1210     std::vector<double> const& prescaleFactorsAlgoTrig) {
1211   std::vector<PrescaleCounter> out;
1212   out.reserve(prescaleFactorsAlgoTrig.size());
1213   for (size_t iAlgo = 0; iAlgo < prescaleFactorsAlgoTrig.size(); ++iAlgo) {
1214     out.emplace_back(prescaleFactorsAlgoTrig[iAlgo]);
1215   }
1216   return out;
1217 }
1218 
1219 // initialises prescale counters with a semi-random value in the range [0, prescale*10^precision - 1]
1220 std::vector<l1t::GlobalBoard::PrescaleCounter> l1t::GlobalBoard::prescaleCountersWithSemirandomInitialCounter(
1221     std::vector<double> const& prescaleFactorsAlgoTrig, edm::Event const& iEvent) {
1222   // pick a (semi)random number seeding based on run, lumi, event numbers,
1223   // this leads to different (semi)random numbers for different streams,
1224   // reminder: different streams have different initial event number
1225   std::srand(iEvent.id().run());
1226   std::srand(std::rand() + iEvent.id().luminosityBlock());
1227   std::srand(std::rand() + iEvent.id().event());
1228   int const semirandom = std::rand();
1229 
1230   std::vector<PrescaleCounter> out;
1231   out.reserve(prescaleFactorsAlgoTrig.size());
1232 
1233   for (size_t iAlgo = 0; iAlgo < prescaleFactorsAlgoTrig.size(); ++iAlgo) {
1234     out.emplace_back(prescaleFactorsAlgoTrig[iAlgo]);
1235     // initialise trigger_counter to a (semi)random integer
1236     // between 0 and prescale_count - 1 (both inclusive)
1237     // (this only changes the behaviour of triggers with PS > 1)
1238     auto& prescaleCounter = out.back();
1239     if (prescaleCounter.prescale_count > 0) {
1240       prescaleCounter.trigger_counter = semirandom % prescaleCounter.prescale_count;
1241     }
1242   }
1243 
1244   return out;
1245 }
1246 
1247 // return decision of PrescalCounter, and update its internal counter
1248 bool l1t::GlobalBoard::PrescaleCounter::accept() {
1249   trigger_counter += m_singlestep;
1250 
1251   if (prescale_count == 0 or trigger_counter < prescale_count)
1252     return false;
1253 
1254   trigger_counter -= prescale_count;
1255 
1256   return true;
1257 }