Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-09-24 22:51:29

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/CICADATemplate.h"
0042 #include "L1Trigger/L1TGlobal/interface/ExternalTemplate.h"
0043 #include "L1Trigger/L1TGlobal/interface/CorrelationTemplate.h"
0044 #include "L1Trigger/L1TGlobal/interface/CorrelationThreeBodyTemplate.h"
0045 #include "L1Trigger/L1TGlobal/interface/CorrelationWithOverlapRemovalTemplate.h"
0046 #include "L1Trigger/L1TGlobal/interface/GlobalCondition.h"
0047 #include "L1Trigger/L1TGlobal/interface/CorrCondition.h"
0048 #include "L1Trigger/L1TGlobal/interface/CorrWithOverlapRemovalCondition.h"
0049 #include "L1Trigger/L1TGlobal/interface/ConditionEvaluation.h"
0050 #include "L1Trigger/L1TGlobal/interface/AlgorithmEvaluation.h"
0051 
0052 // Conditions for uGT
0053 #include "L1Trigger/L1TGlobal/interface/MuCondition.h"
0054 #include "L1Trigger/L1TGlobal/interface/MuonShowerCondition.h"
0055 #include "L1Trigger/L1TGlobal/interface/CaloCondition.h"
0056 #include "L1Trigger/L1TGlobal/interface/EnergySumCondition.h"
0057 #include "L1Trigger/L1TGlobal/interface/EnergySumZdcCondition.h"
0058 #include "L1Trigger/L1TGlobal/interface/AXOL1TLCondition.h"
0059 #include "L1Trigger/L1TGlobal/interface/CICADACondition.h"
0060 #include "L1Trigger/L1TGlobal/interface/ExternalCondition.h"
0061 #include "L1Trigger/L1TGlobal/interface/CorrCondition.h"
0062 #include "L1Trigger/L1TGlobal/interface/CorrThreeBodyCondition.h"
0063 #include "L1Trigger/L1TGlobal/interface/CorrWithOverlapRemovalCondition.h"
0064 
0065 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0066 #include "FWCore/MessageLogger/interface/MessageDrop.h"
0067 
0068 // Constructor
0069 l1t::GlobalBoard::GlobalBoard()
0070     : m_candL1Mu(new BXVector<const l1t::Muon*>),
0071       m_candL1MuShower(new BXVector<std::shared_ptr<l1t::MuonShower>>),
0072       m_candL1EG(new BXVector<const l1t::L1Candidate*>),
0073       m_candL1Tau(new BXVector<const l1t::L1Candidate*>),
0074       m_candL1Jet(new BXVector<const l1t::L1Candidate*>),
0075       m_candL1EtSum(new BXVector<const l1t::EtSum*>),
0076       m_candL1EtSumZdc(new BXVector<const l1t::EtSum*>),
0077       m_candL1External(new BXVector<const GlobalExtBlk*>),
0078       m_currentLumi(0),
0079       m_isDebugEnabled(edm::isDebugEnabled()) {
0080   m_uGtAlgBlk.reset();
0081   m_uGtAXOScore.reset();
0082 
0083   m_gtlAlgorithmOR.reset();
0084   m_gtlDecisionWord.reset();
0085 
0086   m_prescaleCounterAlgoTrig.clear();
0087 
0088   // Initialize cached IDs
0089   m_l1GtMenuCacheID = 0ULL;
0090   m_l1CaloGeometryCacheID = 0ULL;
0091   m_l1MuTriggerScalesCacheID = 0ULL;
0092 
0093   // Counter for number of events board sees
0094   m_boardEventCount = 0;
0095 
0096   // A single uGT GlobalBoard is taken into account in the emulator
0097   m_uGtBoardNumber = 0;
0098   m_uGtFinalBoard = true;
0099 }
0100 
0101 // Destructor
0102 l1t::GlobalBoard::~GlobalBoard() {
0103   delete m_candL1Mu;
0104   delete m_candL1MuShower;
0105   delete m_candL1EG;
0106   delete m_candL1Tau;
0107   delete m_candL1Jet;
0108   delete m_candL1EtSum;
0109   delete m_candL1EtSumZdc;
0110   delete m_candL1External;
0111 }
0112 
0113 // Operations
0114 void l1t::GlobalBoard::setBxFirst(int bx) { m_bxFirst_ = bx; }
0115 
0116 void l1t::GlobalBoard::setBxLast(int bx) { m_bxLast_ = bx; }
0117 
0118 void l1t::GlobalBoard::init(const int numberPhysTriggers,
0119                             const int nrL1Mu,
0120                             const int nrL1MuShower,
0121                             const int nrL1EG,
0122                             const int nrL1Tau,
0123                             const int nrL1Jet,
0124                             int bxFirst,
0125                             int bxLast) {
0126   setBxFirst(bxFirst);
0127   setBxLast(bxLast);
0128 
0129   m_candL1Mu->setBXRange(m_bxFirst_, m_bxLast_);
0130   m_candL1MuShower->setBXRange(m_bxFirst_, m_bxLast_);
0131   m_candL1EG->setBXRange(m_bxFirst_, m_bxLast_);
0132   m_candL1Tau->setBXRange(m_bxFirst_, m_bxLast_);
0133   m_candL1Jet->setBXRange(m_bxFirst_, m_bxLast_);
0134   m_candL1EtSum->setBXRange(m_bxFirst_, m_bxLast_);
0135   m_candL1EtSumZdc->setBXRange(m_bxFirst_, m_bxLast_);
0136   m_candL1External->setBXRange(m_bxFirst_, m_bxLast_);
0137 
0138   m_uGtAlgBlk.reset();
0139 
0140   LogDebug("L1TGlobal") << "\t Initializing Board with bxFirst = " << m_bxFirst_ << ", bxLast = " << m_bxLast_;
0141 }
0142 
0143 // receive data from Calorimeter
0144 void l1t::GlobalBoard::receiveCaloObjectData(const edm::Event& iEvent,
0145                                              const edm::EDGetTokenT<BXVector<l1t::EGamma>>& egInputToken,
0146                                              const edm::EDGetTokenT<BXVector<l1t::Tau>>& tauInputToken,
0147                                              const edm::EDGetTokenT<BXVector<l1t::Jet>>& jetInputToken,
0148                                              const edm::EDGetTokenT<BXVector<l1t::EtSum>>& sumInputToken,
0149                                              const edm::EDGetTokenT<BXVector<l1t::EtSum>>& sumZdcInputToken,
0150                                              const edm::EDGetTokenT<BXVector<float>>& CICADAInputToken,
0151                                              const bool receiveEG,
0152                                              const int nrL1EG,
0153                                              const bool receiveTau,
0154                                              const int nrL1Tau,
0155                                              const bool receiveJet,
0156                                              const int nrL1Jet,
0157                                              const bool receiveEtSums,
0158                                              const bool receiveEtSumsZdc,
0159                                              const bool receiveCICADA) {
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   if (receiveCICADA) {
0351     edm::Handle<BXVector<float>> cicadaScoreHandle;
0352     iEvent.getByToken(CICADAInputToken, cicadaScoreHandle);
0353     if (not cicadaScoreHandle.isValid()) {
0354       if (m_verbosity) {
0355         edm::LogWarning("L1Tglobal") << "\nWarning: Input tag for the CICADA score"
0356                                      << "\nrequested in configuration, but not found in the event.\n"
0357                                      << "\nSetting score to 0.0";
0358       }
0359       setCICADAScore(0.0);
0360     } else if (cicadaScoreHandle->isEmpty(0)) {
0361       if (m_verbosity) {
0362         edm::LogWarning("L1Tglobal")
0363             << "\nWarning: CICADA score had a valid input tag, but an empty BX collection"
0364             << "\nThe CICADA score will be filled with 0.0 to prevent any failure of uGT emulation";
0365       }
0366       setCICADAScore(0.0);
0367     } else {
0368       setCICADAScore(cicadaScoreHandle->at(
0369           0,
0370           0));  //CICADA emulation will only provide a central BX, and one value. Unpacking may have more values, but that can't be guaranteed.
0371     }
0372   }
0373 }
0374 
0375 // receive data from Global Muon Trigger
0376 void l1t::GlobalBoard::receiveMuonObjectData(const edm::Event& iEvent,
0377                                              const edm::EDGetTokenT<BXVector<l1t::Muon>>& muInputToken,
0378                                              const bool receiveMu,
0379                                              const int nrL1Mu,
0380                                              const std::vector<l1t::Muon>* muonVec_bxm2,
0381                                              const std::vector<l1t::Muon>* muonVec_bxm1) {
0382   if (m_verbosity) {
0383     LogDebug("L1TGlobal") << "\n**** GlobalBoard receiving muon data = ";
0384     //<< "\n     from input tag " << muInputTag << "\n"
0385   }
0386 
0387   resetMu();
0388 
0389   // get data from Global Muon Trigger
0390   if (receiveMu) {
0391     edm::Handle<BXVector<l1t::Muon>> muonData;
0392     iEvent.getByToken(muInputToken, muonData);
0393 
0394     if (!muonData.isValid()) {
0395       if (m_verbosity) {
0396         edm::LogWarning("L1TGlobal") << "\nWarning: Input tag for the BXVector<l1t::Muon> collection"
0397                                      << "\nrequested in configuration, but not found in the event.\n";
0398       }
0399     } else {
0400       // bx in muon data
0401       for (int i = muonData->getFirstBX(); i <= muonData->getLastBX(); ++i) {
0402         // Prevent from pushing back bx that is outside of allowed range
0403         if (i < m_bxFirst_ || i > m_bxLast_)
0404           continue;
0405 
0406         //Loop over Muons in this bx
0407         int nObj = 0;
0408         if (i == -2) {
0409           for (std::vector<l1t::Muon>::const_iterator mu = muonVec_bxm2->begin(); mu != muonVec_bxm2->end(); ++mu) {
0410             if (nObj < nrL1Mu) {
0411               (*m_candL1Mu).push_back(i, &(*mu));
0412             } else {
0413               edm::LogWarning("L1TGlobal")
0414                   << " Too many Muons (" << nObj << ") for uGT Configuration maxMu =" << nrL1Mu;
0415             }
0416 
0417             LogDebug("L1TGlobal") << "Muon  Pt " << mu->hwPt() << " EtaAtVtx  " << mu->hwEtaAtVtx() << " PhiAtVtx "
0418                                   << mu->hwPhiAtVtx() << "  Qual " << mu->hwQual() << "  Iso " << mu->hwIso();
0419             nObj++;
0420           }
0421         } else if (i == -1) {
0422           for (std::vector<l1t::Muon>::const_iterator mu = muonVec_bxm1->begin(); mu != muonVec_bxm1->end(); ++mu) {
0423             if (nObj < nrL1Mu) {
0424               (*m_candL1Mu).push_back(i, &(*mu));
0425             } else {
0426               edm::LogWarning("L1TGlobal")
0427                   << " Too many Muons (" << nObj << ") for uGT Configuration maxMu =" << nrL1Mu;
0428             }
0429 
0430             LogDebug("L1TGlobal") << "Muon  Pt " << mu->hwPt() << " EtaAtVtx  " << mu->hwEtaAtVtx() << " PhiAtVtx "
0431                                   << mu->hwPhiAtVtx() << "  Qual " << mu->hwQual() << "  Iso " << mu->hwIso();
0432             nObj++;
0433           }
0434         } else {
0435           for (std::vector<l1t::Muon>::const_iterator mu = muonData->begin(i); mu != muonData->end(i); ++mu) {
0436             if (nObj < nrL1Mu) {
0437               (*m_candL1Mu).push_back(i, &(*mu));
0438             } else {
0439               edm::LogWarning("L1TGlobal")
0440                   << " Too many Muons (" << nObj << ") for uGT Configuration maxMu =" << nrL1Mu;
0441             }
0442 
0443             LogDebug("L1TGlobal") << "Muon  Pt " << mu->hwPt() << " EtaAtVtx  " << mu->hwEtaAtVtx() << " PhiAtVtx "
0444                                   << mu->hwPhiAtVtx() << "  Qual " << mu->hwQual() << "  Iso " << mu->hwIso();
0445             nObj++;
0446           }
0447         }  //end loop over muons in bx
0448       }  //end loop over bx
0449     }  //end if over valid muon data
0450   }  //end if ReceiveMuon data
0451 }
0452 
0453 // receive muon shower data from Global Muon Trigger
0454 void l1t::GlobalBoard::receiveMuonShowerObjectData(const edm::Event& iEvent,
0455                                                    const edm::EDGetTokenT<BXVector<l1t::MuonShower>>& muShowerInputToken,
0456                                                    const bool receiveMuShower,
0457                                                    const int nrL1MuShower) {
0458   // get data from Global Muon Trigger
0459   if (receiveMuShower) {
0460     edm::Handle<BXVector<l1t::MuonShower>> muonData;
0461     iEvent.getByToken(muShowerInputToken, muonData);
0462 
0463     if (!muonData.isValid()) {
0464       if (m_verbosity) {
0465         edm::LogWarning("L1TGlobal") << "\nWarning: Input tag for the BXVector<l1t::MuonShower> collection"
0466                                      << "\nrequested in configuration, but not found in the event.\n";
0467       }
0468     } else {
0469       // Loop over bx in muon data
0470       for (int i = muonData->getFirstBX(); i <= muonData->getLastBX(); ++i) {
0471         // Prevent from pushing back bx that is outside of allowed range
0472         if (i < m_bxFirst_ || i > m_bxLast_)
0473           continue;
0474 
0475         // Loop over Muon Showers in this bx
0476         int nObj = 0;
0477         for (std::vector<l1t::MuonShower>::const_iterator mu = muonData->begin(i); mu != muonData->end(i); ++mu) {
0478           if (nObj < nrL1MuShower) {
0479             /* NOTE: here the single object is split up into 5 separate MuonShower objects 
0480            similarly to the description in the UTM library, where the conditions are four different objects.
0481         */
0482 
0483             std::shared_ptr<l1t::MuonShower> musOneNominalInTime =
0484                 std::make_shared<l1t::MuonShower>(false, false, false, false, false, false);
0485             std::shared_ptr<l1t::MuonShower> musOneTightInTime =
0486                 std::make_shared<l1t::MuonShower>(false, false, false, false, false, false);
0487             std::shared_ptr<l1t::MuonShower> musTwoLooseDiffSectorsInTime =
0488                 std::make_shared<l1t::MuonShower>(false, false, false, false, false, false);
0489             std::shared_ptr<l1t::MuonShower> musOutOfTime0 =
0490                 std::make_shared<l1t::MuonShower>(false, false, false, false, false, false);
0491             std::shared_ptr<l1t::MuonShower> musOutOfTime1 =
0492                 std::make_shared<l1t::MuonShower>(false, false, false, false, false, false);
0493 
0494             musOneNominalInTime->setOneNominalInTime(mu->isOneNominalInTime());
0495             musOneTightInTime->setOneTightInTime(mu->isOneTightInTime());
0496             musTwoLooseDiffSectorsInTime->setTwoLooseDiffSectorsInTime(mu->isTwoLooseDiffSectorsInTime());
0497             musOutOfTime0->setMusOutOfTime0(mu->musOutOfTime0());
0498             musOutOfTime1->setMusOutOfTime1(mu->musOutOfTime1());
0499 
0500             (*m_candL1MuShower).push_back(i, musOneNominalInTime);
0501             (*m_candL1MuShower).push_back(i, musOneTightInTime);
0502             (*m_candL1MuShower).push_back(i, musTwoLooseDiffSectorsInTime);
0503             (*m_candL1MuShower).push_back(i, musOutOfTime0);
0504             (*m_candL1MuShower).push_back(i, musOutOfTime1);
0505 
0506           } else {
0507             edm::LogWarning("L1TGlobal") << " Too many Muon Showers (" << nObj
0508                                          << ") for uGT Configuration maxMuShower =" << nrL1MuShower;
0509           }
0510           nObj++;
0511         }  //end loop over muon showers in bx
0512       }  //end loop over bx
0513     }  //end if over valid muon shower data
0514   }  //end if ReceiveMuonShower data
0515 }
0516 
0517 // receive data from Global External Conditions
0518 void l1t::GlobalBoard::receiveExternalData(const edm::Event& iEvent,
0519                                            const edm::EDGetTokenT<BXVector<GlobalExtBlk>>& extInputToken,
0520                                            const bool receiveExt) {
0521   if (m_verbosity) {
0522     LogDebug("L1TGlobal") << "\n**** GlobalBoard receiving external data = ";
0523     //<< "\n     from input tag " << muInputTag << "\n"
0524   }
0525 
0526   resetExternal();
0527 
0528   // get data from Global Muon Trigger
0529   if (receiveExt) {
0530     edm::Handle<BXVector<GlobalExtBlk>> extData;
0531     iEvent.getByToken(extInputToken, extData);
0532 
0533     if (!extData.isValid()) {
0534       if (m_verbosity) {
0535         edm::LogWarning("L1TGlobal") << "\nWarning: Input tag for the BXVector<GlobalExtBlk> collection"
0536                                      << "\nrequested in configuration, but not found in the event.\n";
0537       }
0538     } else {
0539       // bx in muon data
0540       for (int i = extData->getFirstBX(); i <= extData->getLastBX(); ++i) {
0541         // Prevent from pushing back bx that is outside of allowed range
0542         if (i < m_bxFirst_ || i > m_bxLast_)
0543           continue;
0544 
0545         //Loop over ext in this bx
0546         for (std::vector<GlobalExtBlk>::const_iterator ext = extData->begin(i); ext != extData->end(i); ++ext) {
0547           (*m_candL1External).push_back(i, &(*ext));
0548         }  //end loop over ext in bx
0549       }  //end loop over bx
0550     }  //end if over valid ext data
0551   }  //end if ReceiveExt data
0552 }
0553 
0554 // fill axo score value per bx in event
0555 void l1t::GlobalBoard::fillAXOScore(int iBxInEvent, std::unique_ptr<AXOL1TLScoreBxCollection>& AxoScoreRecord) {
0556   m_uGtAXOScore.reset();
0557   m_uGtAXOScore.setbxInEventNr((iBxInEvent & 0xF));
0558 
0559   //save stored condition score if Bx is zero, else set to 0
0560   float scorevalue = 0.0;
0561   if (iBxInEvent == 0) {
0562     scorevalue = m_storedAXOScore;
0563   }
0564 
0565   //set dataformat value
0566   m_uGtAXOScore.setAXOScore(scorevalue);
0567   AxoScoreRecord->push_back(iBxInEvent, m_uGtAXOScore);
0568 }
0569 
0570 // run GTL
0571 void l1t::GlobalBoard::runGTL(const edm::Event&,
0572                               const edm::EventSetup& evSetup,
0573                               const TriggerMenu* m_l1GtMenu,
0574                               const bool produceL1GtObjectMapRecord,
0575                               const int iBxInEvent,
0576                               std::unique_ptr<GlobalObjectMapRecord>& gtObjectMapRecord,
0577                               const unsigned int numberPhysTriggers,
0578                               const int nrL1Mu,
0579                               const int nrL1MuShower,
0580                               const int nrL1EG,
0581                               const int nrL1Tau,
0582                               const int nrL1Jet) {
0583   const std::vector<ConditionMap>& conditionMap = m_l1GtMenu->gtConditionMap();
0584   const AlgorithmMap& algorithmMap = m_l1GtMenu->gtAlgorithmMap();
0585   const GlobalScales& gtScales = m_l1GtMenu->gtScales();
0586   const std::string scaleSetName = gtScales.getScalesName();
0587   LogDebug("L1TGlobal") << " L1 Menu Scales -- Set Name: " << scaleSetName;
0588 
0589   // Reset AlgBlk for this bx
0590   m_uGtAlgBlk.reset();
0591   m_algInitialOr = false;
0592   m_algPrescaledOr = false;
0593   m_algIntermOr = false;
0594   m_algFinalOr = false;
0595   m_algFinalOrVeto = false;
0596 
0597   const std::vector<std::vector<MuonTemplate>>& corrMuon = m_l1GtMenu->corMuonTemplate();
0598 
0599   const std::vector<std::vector<CaloTemplate>>& corrCalo = m_l1GtMenu->corCaloTemplate();
0600 
0601   const std::vector<std::vector<EnergySumTemplate>>& corrEnergySum = m_l1GtMenu->corEnergySumTemplate();
0602 
0603   LogDebug("L1TGlobal") << "Size corrMuon " << corrMuon.size() << "\nSize corrCalo " << corrCalo.size()
0604                         << "\nSize corrSums " << corrEnergySum.size();
0605 
0606   // -----------------------------------------------------
0607   // Loop over condition maps (one map per condition chip),
0608   // then loop over conditions in the map and
0609   // save the results in temporary maps
0610   // -----------------------------------------------------
0611   // never happens in production but at first event...
0612   if (m_conditionResultMaps.size() != conditionMap.size()) {
0613     m_conditionResultMaps.clear();
0614     m_conditionResultMaps.resize(conditionMap.size());
0615   }
0616 
0617   int iChip = -1;
0618 
0619   for (std::vector<ConditionMap>::const_iterator itCondOnChip = conditionMap.begin();
0620        itCondOnChip != conditionMap.end();
0621        itCondOnChip++) {
0622     iChip++;
0623 
0624     AlgorithmEvaluation::ConditionEvaluationMap& cMapResults = m_conditionResultMaps[iChip];
0625 
0626     for (CItCond itCond = itCondOnChip->begin(); itCond != itCondOnChip->end(); itCond++) {
0627       // evaluate condition
0628       switch ((itCond->second)->condCategory()) {
0629         case CondMuon: {
0630           // BLW Not sure what to do with this for now
0631           const int ifMuEtaNumberBits = 0;
0632 
0633           MuCondition* muCondition = new MuCondition(itCond->second, this, nrL1Mu, ifMuEtaNumberBits);
0634 
0635           muCondition->setVerbosity(m_verbosity);
0636 
0637           muCondition->evaluateConditionStoreResult(iBxInEvent);
0638 
0639           cMapResults[itCond->first] = muCondition;
0640 
0641           if (m_verbosity && m_isDebugEnabled) {
0642             std::ostringstream myCout;
0643             muCondition->print(myCout);
0644 
0645             LogTrace("L1TGlobal") << myCout.str();
0646           }
0647           //delete muCondition;
0648 
0649         } break;
0650         case CondMuonShower: {
0651           MuonShowerCondition* muShowerCondition = new MuonShowerCondition(itCond->second, this, nrL1MuShower);
0652 
0653           muShowerCondition->setVerbosity(m_verbosity);
0654 
0655           muShowerCondition->evaluateConditionStoreResult(iBxInEvent);
0656 
0657           cMapResults[itCond->first] = muShowerCondition;
0658 
0659           if (m_verbosity && m_isDebugEnabled) {
0660             std::ostringstream myCout;
0661             muShowerCondition->print(myCout);
0662 
0663             edm::LogWarning("L1TGlobal") << "MuonShowerCondition " << myCout.str();
0664           }
0665           //delete muShowerCondition;
0666 
0667         } break;
0668         case CondCalo: {
0669           // BLW Not sure w hat to do with this for now
0670           const int ifCaloEtaNumberBits = 0;
0671 
0672           CaloCondition* caloCondition =
0673               new CaloCondition(itCond->second, this, nrL1EG, nrL1Jet, nrL1Tau, ifCaloEtaNumberBits);
0674 
0675           caloCondition->setVerbosity(m_verbosity);
0676 
0677           caloCondition->evaluateConditionStoreResult(iBxInEvent);
0678 
0679           cMapResults[itCond->first] = caloCondition;
0680 
0681           if (m_verbosity && m_isDebugEnabled) {
0682             std::ostringstream myCout;
0683             caloCondition->print(myCout);
0684 
0685             LogTrace("L1TGlobal") << myCout.str();
0686           }
0687           //                    delete caloCondition;
0688 
0689         } break;
0690         case CondEnergySum: {
0691           EnergySumCondition* eSumCondition = new EnergySumCondition(itCond->second, this);
0692 
0693           eSumCondition->setVerbosity(m_verbosity);
0694           eSumCondition->evaluateConditionStoreResult(iBxInEvent);
0695 
0696           cMapResults[itCond->first] = eSumCondition;
0697 
0698           if (m_verbosity && m_isDebugEnabled) {
0699             std::ostringstream myCout;
0700             eSumCondition->print(myCout);
0701 
0702             LogTrace("L1TGlobal") << myCout.str();
0703           }
0704           //                    delete eSumCondition;
0705 
0706         } break;
0707         case CondEnergySumZdc: {
0708           EnergySumZdcCondition* eSumZdcCondition = new EnergySumZdcCondition(itCond->second, this);
0709 
0710           eSumZdcCondition->setVerbosity(m_verbosity);
0711           eSumZdcCondition->evaluateConditionStoreResult(iBxInEvent);
0712 
0713           cMapResults[itCond->first] = eSumZdcCondition;
0714 
0715           if (m_verbosity && m_isDebugEnabled) {
0716             std::ostringstream myCout;
0717             eSumZdcCondition->print(myCout);
0718 
0719             LogTrace("L1TGlobal") << myCout.str();
0720           }
0721           //                    delete eSumZdcCondition;
0722 
0723         } break;
0724         case CondAXOL1TL: {
0725           AXOL1TLCondition* axol1tlCondition = new AXOL1TLCondition(itCond->second, this);
0726 
0727           axol1tlCondition->setVerbosity(m_verbosity);
0728 
0729           axol1tlCondition->evaluateConditionStoreResult(iBxInEvent);
0730 
0731           cMapResults[itCond->first] = axol1tlCondition;
0732 
0733           //for optional software-only saving of axol1tl score
0734           //m_storedAXOScore < 0.0 ensures only sets once per condition if score not default of -999
0735           if (m_saveAXOScore && m_storedAXOScore < 0.0) {
0736             m_storedAXOScore = axol1tlCondition->getScore();
0737           }
0738 
0739           if (m_verbosity && m_isDebugEnabled) {
0740             std::ostringstream myCout;
0741             axol1tlCondition->print(myCout);
0742 
0743             edm::LogWarning("L1TGlobal") << "axol1tlCondition " << myCout.str();
0744           }
0745           //delete axol1tlCCondition;
0746 
0747         } break;
0748         case CondCICADA: {
0749           CICADACondition* cicadaCondition = new CICADACondition(itCond->second, this);
0750 
0751           cicadaCondition->setVerbosity(m_verbosity);
0752           cicadaCondition->evaluateConditionStoreResult(iBxInEvent);
0753 
0754           cMapResults[itCond->first] = cicadaCondition;
0755 
0756           if (m_verbosity && m_isDebugEnabled) {
0757             std::ostringstream myCout;
0758             cicadaCondition->print(myCout);
0759 
0760             edm::LogWarning("L1TGlobal") << "cicadaCondition " << myCout.str();
0761           }
0762         } break;
0763 
0764         case CondExternal: {
0765           ExternalCondition* extCondition = new ExternalCondition(itCond->second, this);
0766 
0767           extCondition->setVerbosity(m_verbosity);
0768           extCondition->evaluateConditionStoreResult(iBxInEvent);
0769 
0770           cMapResults[itCond->first] = extCondition;
0771 
0772           if (m_verbosity && m_isDebugEnabled) {
0773             std::ostringstream myCout;
0774             extCondition->print(myCout);
0775 
0776             LogTrace("L1TGlobal") << myCout.str();
0777           }
0778           //                    delete extCondition;
0779 
0780         } break;
0781         case CondCorrelation: {
0782           // get first the subconditions
0783           const CorrelationTemplate* corrTemplate = static_cast<const CorrelationTemplate*>(itCond->second);
0784           const GtConditionCategory cond0Categ = corrTemplate->cond0Category();
0785           const GtConditionCategory cond1Categ = corrTemplate->cond1Category();
0786           const int cond0Ind = corrTemplate->cond0Index();
0787           const int cond1Ind = corrTemplate->cond1Index();
0788 
0789           const GlobalCondition* cond0Condition = nullptr;
0790           const GlobalCondition* cond1Condition = nullptr;
0791 
0792           // maximum number of objects received for evaluation of l1t::Type1s condition
0793           int cond0NrL1Objects = 0;
0794           int cond1NrL1Objects = 0;
0795           LogDebug("L1TGlobal") << " cond0NrL1Objects" << cond0NrL1Objects << "  cond1NrL1Objects  "
0796                                 << cond1NrL1Objects;
0797 
0798           switch (cond0Categ) {
0799             case CondMuon: {
0800               cond0Condition = &((corrMuon[iChip])[cond0Ind]);
0801             } break;
0802             case CondCalo: {
0803               cond0Condition = &((corrCalo[iChip])[cond0Ind]);
0804             } break;
0805             case CondEnergySum: {
0806               cond0Condition = &((corrEnergySum[iChip])[cond0Ind]);
0807             } break;
0808             default: {
0809               // do nothing, should not arrive here
0810             } break;
0811           }
0812 
0813           switch (cond1Categ) {
0814             case CondMuon: {
0815               cond1Condition = &((corrMuon[iChip])[cond1Ind]);
0816             } break;
0817             case CondCalo: {
0818               cond1Condition = &((corrCalo[iChip])[cond1Ind]);
0819             } break;
0820             case CondEnergySum: {
0821               cond1Condition = &((corrEnergySum[iChip])[cond1Ind]);
0822             } break;
0823             default: {
0824               // do nothing, should not arrive here
0825             } break;
0826           }
0827 
0828           CorrCondition* correlationCond = new CorrCondition(itCond->second, cond0Condition, cond1Condition, this);
0829 
0830           correlationCond->setVerbosity(m_verbosity);
0831           correlationCond->setScales(&gtScales);
0832           correlationCond->evaluateConditionStoreResult(iBxInEvent);
0833 
0834           cMapResults[itCond->first] = correlationCond;
0835 
0836           if (m_verbosity && m_isDebugEnabled) {
0837             std::ostringstream myCout;
0838             correlationCond->print(myCout);
0839 
0840             LogTrace("L1TGlobal") << myCout.str();
0841           }
0842 
0843           //        delete correlationCond;
0844 
0845         } break;
0846         case CondCorrelationThreeBody: {
0847           // get first the subconditions
0848           const CorrelationThreeBodyTemplate* corrTemplate =
0849               static_cast<const CorrelationThreeBodyTemplate*>(itCond->second);
0850           const GtConditionCategory cond0Categ = corrTemplate->cond0Category();
0851           const GtConditionCategory cond1Categ = corrTemplate->cond1Category();
0852           const GtConditionCategory cond2Categ = corrTemplate->cond2Category();
0853           const int cond0Ind = corrTemplate->cond0Index();
0854           const int cond1Ind = corrTemplate->cond1Index();
0855           const int cond2Ind = corrTemplate->cond2Index();
0856 
0857           const GlobalCondition* cond0Condition = nullptr;
0858           const GlobalCondition* cond1Condition = nullptr;
0859           const GlobalCondition* cond2Condition = nullptr;
0860 
0861           // maximum number of objects received for evaluation of l1t::Type1s condition
0862           int cond0NrL1Objects = 0;
0863           int cond1NrL1Objects = 0;
0864           int cond2NrL1Objects = 0;
0865           LogDebug("L1TGlobal") << "  cond0NrL1Objects  " << cond0NrL1Objects << "  cond1NrL1Objects  "
0866                                 << cond1NrL1Objects << "  cond2NrL1Objects  " << cond2NrL1Objects;
0867           if (cond0Categ == CondMuon) {
0868             cond0Condition = &((corrMuon[iChip])[cond0Ind]);
0869           } else {
0870             LogDebug("L1TGlobal") << "No muon0 to evaluate three-body correlation condition";
0871           }
0872           if (cond1Categ == CondMuon) {
0873             cond1Condition = &((corrMuon[iChip])[cond1Ind]);
0874           } else {
0875             LogDebug("L1TGlobal") << "No muon1 to evaluate three-body correlation condition";
0876           }
0877           if (cond2Categ == CondMuon) {
0878             cond2Condition = &((corrMuon[iChip])[cond2Ind]);
0879           } else {
0880             LogDebug("L1TGlobal") << "No muon2 to evaluate three-body correlation condition";
0881           }
0882 
0883           CorrThreeBodyCondition* correlationThreeBodyCond =
0884               new CorrThreeBodyCondition(itCond->second, cond0Condition, cond1Condition, cond2Condition, this);
0885 
0886           correlationThreeBodyCond->setVerbosity(m_verbosity);
0887           correlationThreeBodyCond->setScales(&gtScales);
0888           correlationThreeBodyCond->evaluateConditionStoreResult(iBxInEvent);
0889           cMapResults[itCond->first] = correlationThreeBodyCond;
0890 
0891           if (m_verbosity && m_isDebugEnabled) {
0892             std::ostringstream myCout;
0893             correlationThreeBodyCond->print(myCout);
0894 
0895             LogTrace("L1TGlobal") << myCout.str();
0896           }
0897           //              delete correlationThreeBodyCond;
0898         } break;
0899 
0900         case CondCorrelationWithOverlapRemoval: {
0901           // get first the subconditions
0902           const CorrelationWithOverlapRemovalTemplate* corrTemplate =
0903               static_cast<const CorrelationWithOverlapRemovalTemplate*>(itCond->second);
0904           const GtConditionCategory cond0Categ = corrTemplate->cond0Category();
0905           const GtConditionCategory cond1Categ = corrTemplate->cond1Category();
0906           const GtConditionCategory cond2Categ = corrTemplate->cond2Category();
0907           const int cond0Ind = corrTemplate->cond0Index();
0908           const int cond1Ind = corrTemplate->cond1Index();
0909           const int cond2Ind = corrTemplate->cond2Index();
0910 
0911           const GlobalCondition* cond0Condition = nullptr;
0912           const GlobalCondition* cond1Condition = nullptr;
0913           const GlobalCondition* cond2Condition = nullptr;
0914 
0915           // maximum number of objects received for evaluation of l1t::Type1s condition
0916           int cond0NrL1Objects = 0;
0917           int cond1NrL1Objects = 0;
0918           int cond2NrL1Objects = 0;
0919           LogDebug("L1TGlobal") << " cond0NrL1Objects" << cond0NrL1Objects << "  cond1NrL1Objects  " << cond1NrL1Objects
0920                                 << " cond2NrL1Objects  " << cond2NrL1Objects;
0921 
0922           switch (cond0Categ) {
0923             case CondMuon: {
0924               cond0Condition = &((corrMuon[iChip])[cond0Ind]);
0925             } break;
0926             case CondCalo: {
0927               cond0Condition = &((corrCalo[iChip])[cond0Ind]);
0928             } break;
0929             case CondEnergySum: {
0930               cond0Condition = &((corrEnergySum[iChip])[cond0Ind]);
0931             } break;
0932             default: {
0933               // do nothing, should not arrive here
0934             } break;
0935           }
0936 
0937           switch (cond1Categ) {
0938             case CondMuon: {
0939               cond1Condition = &((corrMuon[iChip])[cond1Ind]);
0940             } break;
0941             case CondCalo: {
0942               cond1Condition = &((corrCalo[iChip])[cond1Ind]);
0943             } break;
0944             case CondEnergySum: {
0945               cond1Condition = &((corrEnergySum[iChip])[cond1Ind]);
0946             } break;
0947             default: {
0948               // do nothing, should not arrive here
0949             } break;
0950           }
0951 
0952           switch (cond2Categ) {
0953             case CondMuon: {
0954               cond2Condition = &((corrMuon[iChip])[cond2Ind]);
0955             } break;
0956             case CondCalo: {
0957               cond2Condition = &((corrCalo[iChip])[cond2Ind]);
0958             } break;
0959             case CondEnergySum: {
0960               cond2Condition = &((corrEnergySum[iChip])[cond2Ind]);
0961             } break;
0962             default: {
0963               // do nothing, should not arrive here
0964             } break;
0965           }
0966 
0967           CorrWithOverlapRemovalCondition* correlationCondWOR =
0968               new CorrWithOverlapRemovalCondition(itCond->second, cond0Condition, cond1Condition, cond2Condition, this);
0969 
0970           correlationCondWOR->setVerbosity(m_verbosity);
0971           correlationCondWOR->setScales(&gtScales);
0972           correlationCondWOR->evaluateConditionStoreResult(iBxInEvent);
0973 
0974           cMapResults[itCond->first] = correlationCondWOR;
0975 
0976           if (m_verbosity && m_isDebugEnabled) {
0977             std::ostringstream myCout;
0978             correlationCondWOR->print(myCout);
0979 
0980             LogTrace("L1TGlobal") << myCout.str();
0981           }
0982 
0983           //        delete correlationCondWOR;
0984 
0985         } break;
0986         case CondNull: {
0987           // do nothing
0988 
0989         } break;
0990         default: {
0991           // do nothing
0992 
0993         } break;
0994       }
0995     }
0996   }
0997 
0998   // -----------------------
0999   // Loop over algorithm map
1000   // -----------------------
1001   // Empty vector for object maps - filled during loop
1002   std::vector<GlobalObjectMap> objMapVec;
1003   if (produceL1GtObjectMapRecord && (iBxInEvent == 0))
1004     objMapVec.reserve(numberPhysTriggers);
1005 
1006   for (CItAlgo itAlgo = algorithmMap.begin(); itAlgo != algorithmMap.end(); itAlgo++) {
1007     AlgorithmEvaluation gtAlg(itAlgo->second);
1008     gtAlg.evaluateAlgorithm((itAlgo->second).algoChipNumber(), m_conditionResultMaps);
1009 
1010     int algBitNumber = (itAlgo->second).algoBitNumber();
1011     bool algResult = gtAlg.gtAlgoResult();
1012 
1013     LogDebug("L1TGlobal") << " ===> for iBxInEvent = " << iBxInEvent << ":\t algBitName = " << itAlgo->first
1014                           << ",\t algBitNumber = " << algBitNumber << ",\t algResult = " << algResult;
1015 
1016     if (algResult) {
1017       //            m_gtlAlgorithmOR.set(algBitNumber);
1018       m_uGtAlgBlk.setAlgoDecisionInitial(algBitNumber, algResult);
1019       m_algInitialOr = true;
1020     }
1021 
1022     if (m_verbosity && m_isDebugEnabled) {
1023       std::ostringstream myCout;
1024       (itAlgo->second).print(myCout);
1025       gtAlg.print(myCout);
1026 
1027       LogTrace("L1TGlobal") << myCout.str();
1028     }
1029 
1030     // object maps only for BxInEvent = 0
1031     if (produceL1GtObjectMapRecord && (iBxInEvent == 0)) {
1032       std::vector<L1TObjectTypeInCond> otypes;
1033       for (auto iop = gtAlg.operandTokenVector().begin(); iop != gtAlg.operandTokenVector().end(); ++iop) {
1034         //cout << "INFO:  operand name:  " << iop->tokenName << "\n";
1035         int found = 0;
1036         L1TObjectTypeInCond otype;
1037         for (auto imap = conditionMap.begin(); imap != conditionMap.end(); imap++) {
1038           auto match = imap->find(iop->tokenName);
1039 
1040           if (match != imap->end()) {
1041             found = 1;
1042             //cout << "DEBUG: found match for " << iop->tokenName << " at " << match->first << "\n";
1043 
1044             otype = match->second->objectType();
1045 
1046             for (auto itype = otype.begin(); itype != otype.end(); itype++) {
1047               //cout << "type:  " << *itype << "\n";
1048             }
1049           }
1050         }
1051         if (!found) {
1052           edm::LogWarning("L1TGlobal") << "\n Failed to find match for operand token " << iop->tokenName << "\n";
1053         } else {
1054           otypes.push_back(otype);
1055         }
1056       }
1057 
1058       // set object map
1059       GlobalObjectMap objMap;
1060 
1061       objMap.setAlgoName(itAlgo->first);
1062       objMap.setAlgoBitNumber(algBitNumber);
1063       objMap.setAlgoGtlResult(algResult);
1064       objMap.swapOperandTokenVector(gtAlg.operandTokenVector());
1065       objMap.swapCombinationVector(gtAlg.gtAlgoCombinationVector());
1066       // gtAlg is empty now...
1067       objMap.swapObjectTypeVector(otypes);
1068 
1069       if (m_verbosity && m_isDebugEnabled) {
1070         std::ostringstream myCout1;
1071         objMap.print(myCout1);
1072 
1073         LogTrace("L1TGlobal") << myCout1.str();
1074       }
1075 
1076       objMapVec.push_back(objMap);
1077     }
1078   }
1079 
1080   // object maps only for BxInEvent = 0
1081   if (produceL1GtObjectMapRecord && (iBxInEvent == 0)) {
1082     gtObjectMapRecord->swapGtObjectMap(objMapVec);
1083   }
1084 
1085   // loop over condition maps (one map per condition chip)
1086   // then loop over conditions in the map
1087   // delete the conditions created with new, zero pointer, do not clear map, keep the vector as is...
1088   for (std::vector<AlgorithmEvaluation::ConditionEvaluationMap>::iterator itCondOnChip = m_conditionResultMaps.begin();
1089        itCondOnChip != m_conditionResultMaps.end();
1090        itCondOnChip++) {
1091     for (AlgorithmEvaluation::ItEvalMap itCond = itCondOnChip->begin(); itCond != itCondOnChip->end(); itCond++) {
1092       delete itCond->second;
1093       itCond->second = nullptr;
1094     }
1095   }
1096 }
1097 
1098 // -------
1099 // Run GTL
1100 // -------
1101 void l1t::GlobalBoard::runFDL(const edm::Event& iEvent,
1102                               const int iBxInEvent,
1103                               const int totalBxInEvent,
1104                               const unsigned int numberPhysTriggers,
1105                               const std::vector<double>& prescaleFactorsAlgoTrig,
1106                               const std::vector<unsigned int>& triggerMaskAlgoTrig,
1107                               const std::vector<int>& triggerMaskVetoAlgoTrig,
1108                               const bool algorithmTriggersUnprescaled,
1109                               const bool algorithmTriggersUnmasked) {
1110   if (m_verbosity) {
1111     LogDebug("L1TGlobal") << "\n**** GlobalBoard apply Final Decision Logic ";
1112   }
1113 
1114   // update and clear prescales at the beginning of the luminosity segment
1115   if (m_prescaleCounterAlgoTrig.empty() or
1116       (m_currentLumi != iEvent.luminosityBlock() and m_resetPSCountersEachLumiSec)) {
1117     m_prescaleCounterAlgoTrig.clear();
1118     m_prescaleCounterAlgoTrig.reserve(totalBxInEvent);
1119     auto const& prescaleCountersAlgoTrig =
1120         m_semiRandomInitialPSCounters ? prescaleCountersWithSemirandomInitialCounter(prescaleFactorsAlgoTrig, iEvent)
1121                                       : prescaleCounters(prescaleFactorsAlgoTrig);
1122     for (int iBxInEvent = 0; iBxInEvent < totalBxInEvent; ++iBxInEvent) {
1123       m_prescaleCounterAlgoTrig.push_back(prescaleCountersAlgoTrig);
1124     }
1125 
1126     m_currentLumi = iEvent.luminosityBlock();
1127   }
1128 
1129   // Copy Algorithm bits to Prescaled word
1130   // Prescaling and Masking done below if requested.
1131   m_uGtAlgBlk.copyInitialToInterm();
1132 
1133   // -------------------------------------------
1134   //      Apply Prescales or skip if turned off
1135   // -------------------------------------------
1136   if (!algorithmTriggersUnprescaled) {
1137     // iBxInEvent is ... -2 -1 0 1 2 ... while counters are 0 1 2 3 4 ...
1138     int const inBxInEvent = totalBxInEvent / 2 + iBxInEvent;
1139 
1140     bool temp_algPrescaledOr = false;
1141     bool alreadyReported = false;
1142     for (unsigned int iBit = 0; iBit < numberPhysTriggers; ++iBit) {
1143       bool const bitValue = m_uGtAlgBlk.getAlgoDecisionInitial(iBit);
1144       if (bitValue) {
1145         // Make sure algo bit in range, warn otherwise
1146         if (iBit < prescaleFactorsAlgoTrig.size()) {
1147           if (prescaleFactorsAlgoTrig.at(iBit) != 1) {
1148             bool const triggered = m_prescaleCounterAlgoTrig.at(inBxInEvent).at(iBit).accept();
1149             if (triggered) {
1150               temp_algPrescaledOr = true;
1151             } else {
1152               // change bit to false in prescaled word and final decision word
1153               m_uGtAlgBlk.setAlgoDecisionInterm(iBit, false);
1154             }  //if Prescale counter reached zero
1155           }  //if prescale factor is not 1 (ie. no prescale)
1156           else {
1157             temp_algPrescaledOr = true;
1158           }
1159         }  // require bit in range
1160         else if (!alreadyReported) {
1161           alreadyReported = true;
1162           edm::LogWarning("L1TGlobal") << "\nWarning: algoBit >= prescaleFactorsAlgoTrig.size() in bx " << iBxInEvent;
1163         }
1164       }  //if algo bit is set true
1165     }  //loop over alg bits
1166 
1167     m_algPrescaledOr = temp_algPrescaledOr;  //temp
1168 
1169   } else {
1170     // Since not Prescaling just take OR of Initial Work
1171     m_algPrescaledOr = m_algInitialOr;
1172 
1173   }  //if we are going to apply prescales.
1174 
1175   // Copy Algorithm bits fron Prescaled word to Final Word
1176   // Masking done below if requested.
1177   m_uGtAlgBlk.copyIntermToFinal();
1178 
1179   if (!algorithmTriggersUnmasked) {
1180     bool temp_algFinalOr = false;
1181     bool alreadyReported = false;
1182     for (unsigned int iBit = 0; iBit < numberPhysTriggers; ++iBit) {
1183       const bool bitValue = m_uGtAlgBlk.getAlgoDecisionInterm(iBit);
1184 
1185       if (bitValue) {
1186         //bool isMasked = ( triggerMaskAlgoTrig.at(iBit) == 0 );
1187         bool isMasked = false;
1188         if (iBit < triggerMaskAlgoTrig.size())
1189           isMasked = (triggerMaskAlgoTrig.at(iBit) == 0);
1190         else if (!alreadyReported) {
1191           alreadyReported = true;
1192           edm::LogWarning("L1TGlobal") << "\nWarning: algoBit >= triggerMaskAlgoTrig.size() in bx " << iBxInEvent;
1193         }
1194 
1195         bool const passMask = (bitValue && !isMasked);
1196 
1197         if (passMask)
1198           temp_algFinalOr = true;
1199         else
1200           m_uGtAlgBlk.setAlgoDecisionFinal(iBit, false);
1201 
1202         // Check if veto mask is true, if it is, set the event veto flag.
1203         if (triggerMaskVetoAlgoTrig.at(iBit) == 1)
1204           m_algFinalOrVeto = true;
1205       }
1206     }
1207 
1208     m_algIntermOr = temp_algFinalOr;
1209 
1210   } else {
1211     m_algIntermOr = m_algPrescaledOr;
1212 
1213   }  ///if we are masking.
1214 
1215   // --------------------------
1216   // Set FinalOR for this board
1217   // --------------------------
1218   m_algFinalOr = (m_algIntermOr & !m_algFinalOrVeto);
1219 }
1220 
1221 // Fill DAQ Record
1222 void l1t::GlobalBoard::fillAlgRecord(int iBxInEvent,
1223                                      std::unique_ptr<GlobalAlgBlkBxCollection>& uGtAlgRecord,
1224                                      int prescaleSet,
1225                                      int menuUUID,
1226                                      int firmwareUUID) {
1227   if (m_verbosity) {
1228     LogDebug("L1TGlobal") << "\n**** GlobalBoard fill DAQ Records for bx= " << iBxInEvent;
1229   }
1230 
1231   // Set header information
1232   m_uGtAlgBlk.setbxInEventNr((iBxInEvent & 0xF));
1233   m_uGtAlgBlk.setPreScColumn(prescaleSet);
1234   m_uGtAlgBlk.setL1MenuUUID(menuUUID);
1235   m_uGtAlgBlk.setL1FirmwareUUID(firmwareUUID);
1236 
1237   m_uGtAlgBlk.setFinalORVeto(m_algFinalOrVeto);
1238   m_uGtAlgBlk.setFinalORPreVeto(m_algIntermOr);
1239   m_uGtAlgBlk.setFinalOR(m_algFinalOr);
1240 
1241   uGtAlgRecord->push_back(iBxInEvent, m_uGtAlgBlk);
1242 }
1243 
1244 // clear GTL
1245 void l1t::GlobalBoard::reset() {
1246   resetMu();
1247   resetMuonShower();
1248   resetCalo();
1249   resetExternal();
1250 
1251   m_uGtAlgBlk.reset();
1252 
1253   //reset AXO score
1254   m_storedAXOScore = -999.0;
1255   m_uGtAXOScore.reset();
1256 
1257   m_gtlDecisionWord.reset();
1258   m_gtlAlgorithmOR.reset();
1259 }
1260 
1261 // clear muon
1262 void l1t::GlobalBoard::resetMu() {
1263   m_candL1Mu->clear();
1264   m_candL1Mu->setBXRange(m_bxFirst_, m_bxLast_);
1265 }
1266 
1267 // clear muon shower
1268 void l1t::GlobalBoard::resetMuonShower() {
1269   m_candL1MuShower->clear();
1270   m_candL1MuShower->setBXRange(m_bxFirst_, m_bxLast_);
1271 }
1272 
1273 // clear calo
1274 void l1t::GlobalBoard::resetCalo() {
1275   m_candL1EG->clear();
1276   m_candL1Tau->clear();
1277   m_candL1Jet->clear();
1278   m_candL1EtSum->clear();
1279   m_candL1EtSumZdc->clear();
1280   m_cicadaScore = 0.0;
1281 
1282   m_candL1EG->setBXRange(m_bxFirst_, m_bxLast_);
1283   m_candL1Tau->setBXRange(m_bxFirst_, m_bxLast_);
1284   m_candL1Jet->setBXRange(m_bxFirst_, m_bxLast_);
1285   m_candL1EtSum->setBXRange(m_bxFirst_, m_bxLast_);
1286   m_candL1EtSumZdc->setBXRange(m_bxFirst_, m_bxLast_);
1287 }
1288 
1289 void l1t::GlobalBoard::resetExternal() {
1290   m_candL1External->clear();
1291   m_candL1External->setBXRange(m_bxFirst_, m_bxLast_);
1292 }
1293 
1294 // print Global Muon Trigger data received
1295 void l1t::GlobalBoard::printGmtData(const int iBxInEvent) const {
1296   LogTrace("L1TGlobal") << "\nl1t::L1GlobalTrigger: uGMT data received for BxInEvent = " << iBxInEvent;
1297 
1298   int nrL1Mu = m_candL1Mu->size(iBxInEvent);
1299   LogTrace("L1TGlobal") << "Number of GMT muons = " << nrL1Mu << "\n";
1300 }
1301 
1302 // initialize prescale counters to zero
1303 std::vector<l1t::GlobalBoard::PrescaleCounter> l1t::GlobalBoard::prescaleCounters(
1304     std::vector<double> const& prescaleFactorsAlgoTrig) {
1305   std::vector<PrescaleCounter> out;
1306   out.reserve(prescaleFactorsAlgoTrig.size());
1307   for (size_t iAlgo = 0; iAlgo < prescaleFactorsAlgoTrig.size(); ++iAlgo) {
1308     out.emplace_back(prescaleFactorsAlgoTrig[iAlgo]);
1309   }
1310   return out;
1311 }
1312 
1313 // initialises prescale counters with a semi-random value in the range [0, prescale*10^precision - 1]
1314 std::vector<l1t::GlobalBoard::PrescaleCounter> l1t::GlobalBoard::prescaleCountersWithSemirandomInitialCounter(
1315     std::vector<double> const& prescaleFactorsAlgoTrig, edm::Event const& iEvent) {
1316   // pick a (semi)random number seeding based on run, lumi, event numbers,
1317   // this leads to different (semi)random numbers for different streams,
1318   // reminder: different streams have different initial event number
1319   std::srand(iEvent.id().run());
1320   std::srand(std::rand() + iEvent.id().luminosityBlock());
1321   std::srand(std::rand() + iEvent.id().event());
1322   int const semirandom = std::rand();
1323 
1324   std::vector<PrescaleCounter> out;
1325   out.reserve(prescaleFactorsAlgoTrig.size());
1326 
1327   for (size_t iAlgo = 0; iAlgo < prescaleFactorsAlgoTrig.size(); ++iAlgo) {
1328     out.emplace_back(prescaleFactorsAlgoTrig[iAlgo]);
1329     // initialise trigger_counter to a (semi)random integer
1330     // between 0 and prescale_count - 1 (both inclusive)
1331     // (this only changes the behaviour of triggers with PS > 1)
1332     auto& prescaleCounter = out.back();
1333     if (prescaleCounter.prescale_count > 0) {
1334       prescaleCounter.trigger_counter = semirandom % prescaleCounter.prescale_count;
1335     }
1336   }
1337 
1338   return out;
1339 }
1340 
1341 // return decision of PrescalCounter, and update its internal counter
1342 bool l1t::GlobalBoard::PrescaleCounter::accept() {
1343   trigger_counter += m_singlestep;
1344 
1345   if (prescale_count == 0 or trigger_counter < prescale_count)
1346     return false;
1347 
1348   trigger_counter -= prescale_count;
1349 
1350   return true;
1351 }