diff --git a/L1Trigger/L1TGlobal/interface/GlobalBoard.h b/L1Trigger/L1TGlobal/interface/GlobalBoard.h index 894951209f4bd..9dcf37a5fc2b7 100644 --- a/L1Trigger/L1TGlobal/interface/GlobalBoard.h +++ b/L1Trigger/L1TGlobal/interface/GlobalBoard.h @@ -16,9 +16,13 @@ #include #include #include +#include +#include // user include files #include "FWCore/Utilities/interface/typedefs.h" +#include "FWCore/Utilities/interface/Exception.h" + #include "DataFormats/L1TGlobal/interface/GlobalObjectMapRecord.h" #include "L1Trigger/L1TGlobal/interface/AlgorithmEvaluation.h" @@ -37,8 +41,6 @@ #include "DataFormats/L1TGlobal/interface/GlobalExtBlk.h" #include "FWCore/Framework/interface/Event.h" -#include "FWCore/Utilities/interface/InputTag.h" -#include "FWCore/MessageLogger/interface/MessageLogger.h" #include "FWCore/Framework/interface/EventSetup.h" // forward declarations @@ -61,7 +63,7 @@ namespace l1t { public: /// receive data from Global Muon Trigger - void receiveCaloObjectData(edm::Event&, + void receiveCaloObjectData(const edm::Event&, const edm::EDGetTokenT>&, const edm::EDGetTokenT>&, const edm::EDGetTokenT>&, @@ -74,17 +76,17 @@ namespace l1t { const int nrL1Jet, const bool receiveEtSums); - void receiveMuonObjectData(edm::Event&, + void receiveMuonObjectData(const edm::Event&, const edm::EDGetTokenT>&, const bool receiveMu, const int nrL1Mu); - void receiveMuonShowerObjectData(edm::Event&, + void receiveMuonShowerObjectData(const edm::Event&, const edm::EDGetTokenT>&, const bool receiveMuShower, const int nrL1MuShower); - void receiveExternalData(edm::Event&, const edm::EDGetTokenT>&, const bool receiveExt); + void receiveExternalData(const edm::Event&, const edm::EDGetTokenT>&, const bool receiveExt); /// initialize the class (mainly reserve) void init(const int numberPhysTriggers, @@ -97,7 +99,7 @@ namespace l1t { int bxLast); /// run the uGT GTL (Conditions and Algorithms) - void runGTL(edm::Event& iEvent, + void runGTL(const edm::Event& iEvent, const edm::EventSetup& evSetup, const TriggerMenu* m_l1GtMenu, const bool produceL1GtObjectMapRecord, @@ -111,7 +113,7 @@ namespace l1t { const int nrL1Jet); /// run the uGT FDL (Apply Prescales and Veto) - void runFDL(edm::Event& iEvent, + void runFDL(const edm::Event& iEvent, const int iBxInEvent, const int totalBxInEvent, const unsigned int numberPhysTriggers, @@ -165,10 +167,6 @@ namespace l1t { /// pointer to Tau data list inline const BXVector* getCandL1External() const { return m_candL1External; } - //initializer prescale counter using a semi-random value between [1, prescale value] - static const std::vector semirandomNumber(const edm::Event& iEvent, - const std::vector& prescaleFactorsAlgoTrig); - /* Drop individual EtSums for Now /// pointer to ETM data list inline const l1t::EtSum* getCandL1ETM() const @@ -243,15 +241,10 @@ namespace l1t { GlobalAlgBlk m_uGtAlgBlk; - // cache of maps + // cache of maps std::vector m_conditionResultMaps; - /// prescale counters: NumberPhysTriggers counters per bunch cross in event - std::vector> m_prescaleCounterAlgoTrig; - - bool m_firstEv; - bool m_firstEvLumiSegment; - uint m_currentLumi; + unsigned int m_currentLumi; private: /// verbosity level @@ -277,7 +270,41 @@ namespace l1t { // start the PS counter from a random value between [1,PS] instead of PS bool m_semiRandomInitialPSCounters = false; + + // step-size in prescale counter corresponding to 10^p, + // where p is the precision allowed for non-integer prescales; + // since the introduction of L1T fractional prescales, p == 2 + static constexpr size_t m_singlestep = 100; + + // struct to increment the prescale according to fractional prescale logic in firmware + struct PrescaleCounter { + size_t const prescale_count; + size_t trigger_counter; + + PrescaleCounter(double prescale, size_t const initial_counter = 0) + : prescale_count(std::lround(prescale * m_singlestep)), trigger_counter(initial_counter) { + if (prescale_count != 0 and (prescale_count < m_singlestep or prescale < 0)) { + throw cms::Exception("PrescaleCounterConstructor") + << "invalid initialisation of PrescaleCounter: prescale = " << prescale + << ", prescale_count = " << prescale_count << " (< " << m_singlestep << " = m_singlestep)"; + } + } + + // function to increment the prescale counter and return the decision + bool accept(); + }; + + // prescale counters: NumberPhysTriggers counters per bunch cross in event + std::vector> m_prescaleCounterAlgoTrig; + + // create prescale counters, initialising trigger_counter to zero + static std::vector prescaleCounters(std::vector const& prescaleFactorsAlgoTrig); + + // create prescale counters, initialising trigger_counter to a semirandom number between 0 and prescale_count - 1 inclusive + static std::vector prescaleCountersWithSemirandomInitialCounter( + std::vector const& prescaleFactorsAlgoTrig, edm::Event const& iEvent); }; } // namespace l1t -#endif + +#endif \ No newline at end of file diff --git a/L1Trigger/L1TGlobal/src/GlobalBoard.cc b/L1Trigger/L1TGlobal/src/GlobalBoard.cc index bf82d690d8961..4d4d328460e13 100644 --- a/L1Trigger/L1TGlobal/src/GlobalBoard.cc +++ b/L1Trigger/L1TGlobal/src/GlobalBoard.cc @@ -50,15 +50,10 @@ #include "L1Trigger/L1TGlobal/interface/CorrCondition.h" #include "L1Trigger/L1TGlobal/interface/CorrThreeBodyCondition.h" #include "L1Trigger/L1TGlobal/interface/CorrWithOverlapRemovalCondition.h" -#include "FWCore/Utilities/interface/Exception.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" #include "FWCore/MessageLogger/interface/MessageDrop.h" -#include "FWCore/Framework/interface/ESHandle.h" - -// forward declarations - // constructor l1t::GlobalBoard::GlobalBoard() : m_candL1Mu(new BXVector), @@ -68,8 +63,6 @@ l1t::GlobalBoard::GlobalBoard() m_candL1Jet(new BXVector), m_candL1EtSum(new BXVector), m_candL1External(new BXVector), - m_firstEv(true), - m_firstEvLumiSegment(true), m_currentLumi(0), m_isDebugEnabled(edm::isDebugEnabled()) { m_uGtAlgBlk.reset(); @@ -77,6 +70,8 @@ l1t::GlobalBoard::GlobalBoard() m_gtlAlgorithmOR.reset(); m_gtlDecisionWord.reset(); + m_prescaleCounterAlgoTrig.clear(); + // initialize cached IDs m_l1GtMenuCacheID = 0ULL; m_l1CaloGeometryCacheID = 0ULL; @@ -130,12 +125,11 @@ void l1t::GlobalBoard::init(const int numberPhysTriggers, m_uGtAlgBlk.reset(); - LogDebug("L1TGlobal") << "\t Initializing Board with bxFirst = " << m_bxFirst_ << ", bxLast = " << m_bxLast_ - << std::endl; + LogDebug("L1TGlobal") << "\t Initializing Board with bxFirst = " << m_bxFirst_ << ", bxLast = " << m_bxLast_; } // receive data from Calorimeter -void l1t::GlobalBoard::receiveCaloObjectData(edm::Event& iEvent, +void l1t::GlobalBoard::receiveCaloObjectData(const edm::Event& iEvent, const edm::EDGetTokenT>& egInputToken, const edm::EDGetTokenT>& tauInputToken, const edm::EDGetTokenT>& jetInputToken, @@ -148,9 +142,8 @@ void l1t::GlobalBoard::receiveCaloObjectData(edm::Event& iEvent, const int nrL1Jet, const bool receiveEtSums) { if (m_verbosity) { - LogDebug("L1TGlobal") << "\n**** Board receiving Calo Data " - //<< "\n from input tag " << caloInputTag << "\n" - << std::endl; + LogDebug("L1TGlobal") << "\n**** Board receiving Calo Data "; + //<< "\n from input tag " << caloInputTag << "\n" } resetCalo(); @@ -164,8 +157,7 @@ void l1t::GlobalBoard::receiveCaloObjectData(edm::Event& iEvent, if (m_verbosity) { edm::LogWarning("L1TGlobal") << "\nWarning: BXVector with input tag " //<< caloInputTag - << "\nrequested in configuration, but not found in the event.\n" - << std::endl; + << "\nrequested in configuration, but not found in the event.\n"; } } else { // bx in EG data @@ -180,11 +172,10 @@ void l1t::GlobalBoard::receiveCaloObjectData(edm::Event& iEvent, if (nObj < nrL1EG) { (*m_candL1EG).push_back(i, &(*eg)); } else { - edm::LogWarning("L1TGlobal") << " Too many EG (" << nObj << ") for uGT Configuration maxEG =" << nrL1EG - << std::endl; + edm::LogWarning("L1TGlobal") << " Too many EG (" << nObj << ") for uGT Configuration maxEG =" << nrL1EG; } LogDebug("L1TGlobal") << "EG Pt " << eg->hwPt() << " Eta " << eg->hwEta() << " Phi " << eg->hwPhi() - << " Qual " << eg->hwQual() << " Iso " << eg->hwIso() << std::endl; + << " Qual " << eg->hwQual() << " Iso " << eg->hwIso(); nObj++; } //end loop over EG in bx @@ -202,8 +193,7 @@ void l1t::GlobalBoard::receiveCaloObjectData(edm::Event& iEvent, if (m_verbosity) { edm::LogWarning("L1TGlobal") << "\nWarning: BXVector with input tag " //<< caloInputTag - << "\nrequested in configuration, but not found in the event.\n" - << std::endl; + << "\nrequested in configuration, but not found in the event.\n"; } } else { // bx in tau data @@ -218,12 +208,11 @@ void l1t::GlobalBoard::receiveCaloObjectData(edm::Event& iEvent, if (nObj < nrL1Tau) { (*m_candL1Tau).push_back(i, &(*tau)); } else { - LogTrace("L1TGlobal") << " Too many Tau (" << nObj << ") for uGT Configuration maxTau =" << nrL1Tau - << std::endl; + LogTrace("L1TGlobal") << " Too many Tau (" << nObj << ") for uGT Configuration maxTau =" << nrL1Tau; } LogDebug("L1TGlobal") << "tau Pt " << tau->hwPt() << " Eta " << tau->hwEta() << " Phi " << tau->hwPhi() - << " Qual " << tau->hwQual() << " Iso " << tau->hwIso() << std::endl; + << " Qual " << tau->hwQual() << " Iso " << tau->hwIso(); nObj++; } //end loop over tau in bx @@ -241,8 +230,7 @@ void l1t::GlobalBoard::receiveCaloObjectData(edm::Event& iEvent, if (m_verbosity) { edm::LogWarning("L1TGlobal") << "\nWarning: BXVector with input tag " //<< caloInputTag - << "\nrequested in configuration, but not found in the event.\n" - << std::endl; + << "\nrequested in configuration, but not found in the event.\n"; } } else { // bx in jet data @@ -257,12 +245,11 @@ void l1t::GlobalBoard::receiveCaloObjectData(edm::Event& iEvent, if (nObj < nrL1Jet) { (*m_candL1Jet).push_back(i, &(*jet)); } else { - edm::LogWarning("L1TGlobal") << " Too many Jets (" << nObj << ") for uGT Configuration maxJet =" << nrL1Jet - << std::endl; + edm::LogWarning("L1TGlobal") << " Too many Jets (" << nObj << ") for uGT Configuration maxJet =" << nrL1Jet; } LogDebug("L1TGlobal") << "Jet Pt " << jet->hwPt() << " Eta " << jet->hwEta() << " Phi " << jet->hwPhi() - << " Qual " << jet->hwQual() << " Iso " << jet->hwIso() << std::endl; + << " Qual " << jet->hwQual() << " Iso " << jet->hwIso(); nObj++; } //end loop over jet in bx } //end loop over bx @@ -279,8 +266,7 @@ void l1t::GlobalBoard::receiveCaloObjectData(edm::Event& iEvent, if (m_verbosity) { edm::LogWarning("L1TGlobal") << "\nWarning: BXVector with input tag " //<< caloInputTag - << "\nrequested in configuration, but not found in the event.\n" - << std::endl; + << "\nrequested in configuration, but not found in the event.\n"; } } else { for (int i = etSumData->getFirstBX(); i <= etSumData->getLastBX(); ++i) { @@ -297,35 +283,35 @@ void l1t::GlobalBoard::receiveCaloObjectData(edm::Event& iEvent, case l1t::EtSum::EtSumType::kMissingEt: { //(*m_candETM).push_back(i,&(*etsum)); - LogDebug("L1TGlobal") << "ETM: Pt " << etsum->hwPt() << " Phi " << etsum->hwPhi() << std::endl; + LogDebug("L1TGlobal") << "ETM: Pt " << etsum->hwPt() << " Phi " << etsum->hwPhi(); } break; case l1t::EtSum::EtSumType::kMissingHt: { //(*m_candHTM).push_back(i,&(*etsum)); - LogDebug("L1TGlobal") << "HTM: Pt " << etsum->hwPt() << " Phi " << etsum->hwPhi() << std::endl; + LogDebug("L1TGlobal") << "HTM: Pt " << etsum->hwPt() << " Phi " << etsum->hwPhi(); } break; case l1t::EtSum::EtSumType::kTotalEt: { //(*m_candETT).push_back(i,&(*etsum)); - LogDebug("L1TGlobal") << "ETT: Pt " << etsum->hwPt() << std::endl; + LogDebug("L1TGlobal") << "ETT: Pt " << etsum->hwPt(); } break; case l1t::EtSum::EtSumType::kTotalHt: { //(*m_candHTT).push_back(i,&(*etsum)); - LogDebug("L1TGlobal") << "HTT: Pt " << etsum->hwPt() << std::endl; + LogDebug("L1TGlobal") << "HTT: Pt " << etsum->hwPt(); } break; case l1t::EtSum::EtSumType::kTowerCount: { //(*m_candTowerCount).push_back(i,&(*etsum)); - LogDebug("L1TGlobal") << "TowerCount: " << etsum->hwPt() << std::endl; + LogDebug("L1TGlobal") << "TowerCount: " << etsum->hwPt(); } break; default: - LogDebug("L1TGlobal") << "Default encounted " << std::endl; + LogDebug("L1TGlobal") << "Default encounted "; break; } */ @@ -337,14 +323,13 @@ void l1t::GlobalBoard::receiveCaloObjectData(edm::Event& iEvent, } // receive data from Global Muon Trigger -void l1t::GlobalBoard::receiveMuonObjectData(edm::Event& iEvent, +void l1t::GlobalBoard::receiveMuonObjectData(const edm::Event& iEvent, const edm::EDGetTokenT>& muInputToken, const bool receiveMu, const int nrL1Mu) { if (m_verbosity) { - LogDebug("L1TGlobal") << "\n**** GlobalBoard receiving muon data = " - //<< "\n from input tag " << muInputTag << "\n" - << std::endl; + LogDebug("L1TGlobal") << "\n**** GlobalBoard receiving muon data = "; + //<< "\n from input tag " << muInputTag << "\n" } resetMu(); @@ -358,8 +343,7 @@ void l1t::GlobalBoard::receiveMuonObjectData(edm::Event& iEvent, if (m_verbosity) { edm::LogWarning("L1TGlobal") << "\nWarning: BXVector with input tag " //<< muInputTag - << "\nrequested in configuration, but not found in the event.\n" - << std::endl; + << "\nrequested in configuration, but not found in the event.\n"; } } else { // bx in muon data @@ -374,13 +358,11 @@ void l1t::GlobalBoard::receiveMuonObjectData(edm::Event& iEvent, if (nObj < nrL1Mu) { (*m_candL1Mu).push_back(i, &(*mu)); } else { - edm::LogWarning("L1TGlobal") << " Too many Muons (" << nObj << ") for uGT Configuration maxMu =" << nrL1Mu - << std::endl; + edm::LogWarning("L1TGlobal") << " Too many Muons (" << nObj << ") for uGT Configuration maxMu =" << nrL1Mu; } LogDebug("L1TGlobal") << "Muon Pt " << mu->hwPt() << " EtaAtVtx " << mu->hwEtaAtVtx() << " PhiAtVtx " - << mu->hwPhiAtVtx() << " Qual " << mu->hwQual() << " Iso " << mu->hwIso() - << std::endl; + << mu->hwPhiAtVtx() << " Qual " << mu->hwQual() << " Iso " << mu->hwIso(); nObj++; } //end loop over muons in bx } //end loop over bx @@ -391,7 +373,7 @@ void l1t::GlobalBoard::receiveMuonObjectData(edm::Event& iEvent, } // receive muon shower data from Global Muon Trigger -void l1t::GlobalBoard::receiveMuonShowerObjectData(edm::Event& iEvent, +void l1t::GlobalBoard::receiveMuonShowerObjectData(const edm::Event& iEvent, const edm::EDGetTokenT>& muShowerInputToken, const bool receiveMuShower, const int nrL1MuShower) { @@ -403,8 +385,7 @@ void l1t::GlobalBoard::receiveMuonShowerObjectData(edm::Event& iEvent, if (!muonData.isValid()) { if (m_verbosity) { edm::LogWarning("L1TGlobal") << "\nWarning: BXVector with input tag " - << "\nrequested in configuration, but not found in the event.\n" - << std::endl; + << "\nrequested in configuration, but not found in the event.\n"; } } else { //Loop over Muon Showers in this bx @@ -430,7 +411,7 @@ void l1t::GlobalBoard::receiveMuonShowerObjectData(edm::Event& iEvent, (*m_candL1MuShower).push_back(0, &musOutOfTime1); } else { edm::LogWarning("L1TGlobal") << " Too many Muon Showers (" << nObj - << ") for uGT Configuration maxMuShower =" << nrL1MuShower << std::endl; + << ") for uGT Configuration maxMuShower =" << nrL1MuShower; } nObj++; } //end loop over muon showers in bx @@ -439,13 +420,12 @@ void l1t::GlobalBoard::receiveMuonShowerObjectData(edm::Event& iEvent, } // receive data from Global External Conditions -void l1t::GlobalBoard::receiveExternalData(edm::Event& iEvent, +void l1t::GlobalBoard::receiveExternalData(const edm::Event& iEvent, const edm::EDGetTokenT>& extInputToken, const bool receiveExt) { if (m_verbosity) { - LogDebug("L1TGlobal") << "\n**** GlobalBoard receiving external data = " - //<< "\n from input tag " << muInputTag << "\n" - << std::endl; + LogDebug("L1TGlobal") << "\n**** GlobalBoard receiving external data = "; + //<< "\n from input tag " << muInputTag << "\n" } resetExternal(); @@ -459,8 +439,7 @@ void l1t::GlobalBoard::receiveExternalData(edm::Event& iEvent, if (m_verbosity) { edm::LogWarning("L1TGlobal") << "\nWarning: BXVector with input tag " //<< muInputTag - << "\nrequested in configuration, but not found in the event.\n" - << std::endl; + << "\nrequested in configuration, but not found in the event.\n"; } } else { // bx in muon data @@ -481,7 +460,7 @@ void l1t::GlobalBoard::receiveExternalData(edm::Event& iEvent, } // run GTL -void l1t::GlobalBoard::runGTL(edm::Event& iEvent, +void l1t::GlobalBoard::runGTL(const edm::Event&, const edm::EventSetup& evSetup, const TriggerMenu* m_l1GtMenu, const bool produceL1GtObjectMapRecord, @@ -497,7 +476,7 @@ void l1t::GlobalBoard::runGTL(edm::Event& iEvent, const AlgorithmMap& algorithmMap = m_l1GtMenu->gtAlgorithmMap(); const GlobalScales& gtScales = m_l1GtMenu->gtScales(); const std::string scaleSetName = gtScales.getScalesName(); - LogDebug("L1TGlobal") << " L1 Menu Scales -- Set Name: " << scaleSetName << std::endl; + LogDebug("L1TGlobal") << " L1 Menu Scales -- Set Name: " << scaleSetName; // Reset AlgBlk for this bx m_uGtAlgBlk.reset(); @@ -515,7 +494,7 @@ void l1t::GlobalBoard::runGTL(edm::Event& iEvent, const std::vector>& corrEnergySum = m_l1GtMenu->corEnergySumTemplate(); LogDebug("L1TGlobal") << "Size corrMuon " << corrMuon.size() << "\nSize corrCalo " << corrCalo.size() - << "\nSize corrSums " << corrEnergySum.size() << std::endl; + << "\nSize corrSums " << corrEnergySum.size(); // loop over condition maps (one map per condition chip) // then loop over conditions in the map @@ -556,7 +535,7 @@ void l1t::GlobalBoard::runGTL(edm::Event& iEvent, std::ostringstream myCout; muCondition->print(myCout); - LogTrace("L1TGlobal") << myCout.str() << std::endl; + LogTrace("L1TGlobal") << myCout.str(); } //delete muCondition; @@ -574,7 +553,7 @@ void l1t::GlobalBoard::runGTL(edm::Event& iEvent, std::ostringstream myCout; muShowerCondition->print(myCout); - edm::LogWarning("L1TGlobal") << "MuonShowerCondition " << myCout.str() << std::endl; + edm::LogWarning("L1TGlobal") << "MuonShowerCondition " << myCout.str(); } //delete muShowerCondition; @@ -596,7 +575,7 @@ void l1t::GlobalBoard::runGTL(edm::Event& iEvent, std::ostringstream myCout; caloCondition->print(myCout); - LogTrace("L1TGlobal") << myCout.str() << std::endl; + LogTrace("L1TGlobal") << myCout.str(); } // delete caloCondition; @@ -613,7 +592,7 @@ void l1t::GlobalBoard::runGTL(edm::Event& iEvent, std::ostringstream myCout; eSumCondition->print(myCout); - LogTrace("L1TGlobal") << myCout.str() << std::endl; + LogTrace("L1TGlobal") << myCout.str(); } // delete eSumCondition; @@ -631,7 +610,7 @@ void l1t::GlobalBoard::runGTL(edm::Event& iEvent, std::ostringstream myCout; extCondition->print(myCout); - LogTrace("L1TGlobal") << myCout.str() << std::endl; + LogTrace("L1TGlobal") << myCout.str(); } // delete extCondition; @@ -650,8 +629,8 @@ void l1t::GlobalBoard::runGTL(edm::Event& iEvent, // maximum number of objects received for evaluation of l1t::Type1s condition int cond0NrL1Objects = 0; int cond1NrL1Objects = 0; - LogDebug("L1TGlobal") << " cond0NrL1Objects" << cond0NrL1Objects << " cond1NrL1Objects " << cond1NrL1Objects - << std::endl; + LogDebug("L1TGlobal") << " cond0NrL1Objects" << cond0NrL1Objects << " cond1NrL1Objects " + << cond1NrL1Objects; switch (cond0Categ) { case CondMuon: { @@ -695,7 +674,7 @@ void l1t::GlobalBoard::runGTL(edm::Event& iEvent, std::ostringstream myCout; correlationCond->print(myCout); - LogTrace("L1TGlobal") << myCout.str() << std::endl; + LogTrace("L1TGlobal") << myCout.str(); } // delete correlationCond; @@ -721,7 +700,7 @@ void l1t::GlobalBoard::runGTL(edm::Event& iEvent, int cond1NrL1Objects = 0; int cond2NrL1Objects = 0; LogDebug("L1TGlobal") << " cond0NrL1Objects " << cond0NrL1Objects << " cond1NrL1Objects " - << cond1NrL1Objects << " cond2NrL1Objects " << cond2NrL1Objects << std::endl; + << cond1NrL1Objects << " cond2NrL1Objects " << cond2NrL1Objects; if (cond0Categ == CondMuon) { cond0Condition = &((corrMuon[iChip])[cond0Ind]); } else { @@ -750,7 +729,7 @@ void l1t::GlobalBoard::runGTL(edm::Event& iEvent, std::ostringstream myCout; correlationThreeBodyCond->print(myCout); - LogTrace("L1TGlobal") << myCout.str() << std::endl; + LogTrace("L1TGlobal") << myCout.str(); } // delete correlationThreeBodyCond; } break; @@ -775,7 +754,7 @@ void l1t::GlobalBoard::runGTL(edm::Event& iEvent, int cond1NrL1Objects = 0; int cond2NrL1Objects = 0; LogDebug("L1TGlobal") << " cond0NrL1Objects" << cond0NrL1Objects << " cond1NrL1Objects " << cond1NrL1Objects - << " cond2NrL1Objects " << cond2NrL1Objects << std::endl; + << " cond2NrL1Objects " << cond2NrL1Objects; switch (cond0Categ) { case CondMuon: { @@ -835,7 +814,7 @@ void l1t::GlobalBoard::runGTL(edm::Event& iEvent, std::ostringstream myCout; correlationCondWOR->print(myCout); - LogTrace("L1TGlobal") << myCout.str() << std::endl; + LogTrace("L1TGlobal") << myCout.str(); } // delete correlationCondWOR; @@ -868,7 +847,7 @@ void l1t::GlobalBoard::runGTL(edm::Event& iEvent, bool algResult = gtAlg.gtAlgoResult(); LogDebug("L1TGlobal") << " ===> for iBxInEvent = " << iBxInEvent << ":\t algBitName = " << itAlgo->first - << ",\t algBitNumber = " << algBitNumber << ",\t algResult = " << algResult << std::endl; + << ",\t algBitNumber = " << algBitNumber << ",\t algResult = " << algResult; if (algResult) { // m_gtlAlgorithmOR.set(algBitNumber); @@ -881,7 +860,7 @@ void l1t::GlobalBoard::runGTL(edm::Event& iEvent, (itAlgo->second).print(myCout); gtAlg.print(myCout); - LogTrace("L1TGlobal") << myCout.str() << std::endl; + LogTrace("L1TGlobal") << myCout.str(); } // object maps only for BxInEvent = 0 @@ -929,7 +908,7 @@ void l1t::GlobalBoard::runGTL(edm::Event& iEvent, std::ostringstream myCout1; objMap.print(myCout1); - LogTrace("L1TGlobal") << myCout1.str() << std::endl; + LogTrace("L1TGlobal") << myCout1.str(); } objMapVec.push_back(objMap); @@ -955,7 +934,7 @@ void l1t::GlobalBoard::runGTL(edm::Event& iEvent, } // run GTL -void l1t::GlobalBoard::runFDL(edm::Event& iEvent, +void l1t::GlobalBoard::runFDL(const edm::Event& iEvent, const int iBxInEvent, const int totalBxInEvent, const unsigned int numberPhysTriggers, @@ -965,35 +944,21 @@ void l1t::GlobalBoard::runFDL(edm::Event& iEvent, const bool algorithmTriggersUnprescaled, const bool algorithmTriggersUnmasked) { if (m_verbosity) { - LogDebug("L1TGlobal") << "\n**** GlobalBoard apply Final Decision Logic " << std::endl; + LogDebug("L1TGlobal") << "\n**** GlobalBoard apply Final Decision Logic "; } - // prescale counters are reset at the beginning of the luminosity segment - if (m_firstEv) { - // prescale counters: numberPhysTriggers counters per bunch cross + // update and clear prescales at the beginning of the luminosity segment + if (m_prescaleCounterAlgoTrig.empty() or + (m_currentLumi != iEvent.luminosityBlock() and m_resetPSCountersEachLumiSec)) { + m_prescaleCounterAlgoTrig.clear(); m_prescaleCounterAlgoTrig.reserve(totalBxInEvent); - auto const& prescaleCountersAlgoTrig = - m_semiRandomInitialPSCounters ? semirandomNumber(iEvent, prescaleFactorsAlgoTrig) : prescaleFactorsAlgoTrig; - - for (int iBxInEvent = 0; iBxInEvent <= totalBxInEvent; ++iBxInEvent) { + m_semiRandomInitialPSCounters ? prescaleCountersWithSemirandomInitialCounter(prescaleFactorsAlgoTrig, iEvent) + : prescaleCounters(prescaleFactorsAlgoTrig); + for (int iBxInEvent = 0; iBxInEvent < totalBxInEvent; ++iBxInEvent) { m_prescaleCounterAlgoTrig.push_back(prescaleCountersAlgoTrig); } - m_firstEv = false; - m_currentLumi = iEvent.luminosityBlock(); - } - // update and clear prescales at the beginning of the luminosity segment - if (m_firstEvLumiSegment || (m_currentLumi != iEvent.luminosityBlock() && m_resetPSCountersEachLumiSec)) { - m_prescaleCounterAlgoTrig.clear(); - for (int iBxInEvent = 0; iBxInEvent <= totalBxInEvent; ++iBxInEvent) { - if (m_semiRandomInitialPSCounters) { - m_prescaleCounterAlgoTrig.push_back(semirandomNumber(iEvent, prescaleFactorsAlgoTrig)); - } else { - m_prescaleCounterAlgoTrig.push_back(prescaleFactorsAlgoTrig); - } - } - m_firstEvLumiSegment = false; m_currentLumi = iEvent.luminosityBlock(); } @@ -1006,25 +971,22 @@ void l1t::GlobalBoard::runFDL(edm::Event& iEvent, // ------------------------------------------- if (!algorithmTriggersUnprescaled) { // iBxInEvent is ... -2 -1 0 1 2 ... while counters are 0 1 2 3 4 ... - int inBxInEvent = totalBxInEvent / 2 + iBxInEvent; + int const inBxInEvent = totalBxInEvent / 2 + iBxInEvent; bool temp_algPrescaledOr = false; bool alreadyReported = false; for (unsigned int iBit = 0; iBit < numberPhysTriggers; ++iBit) { - bool bitValue = m_uGtAlgBlk.getAlgoDecisionInitial(iBit); + bool const bitValue = m_uGtAlgBlk.getAlgoDecisionInitial(iBit); if (bitValue) { // Make sure algo bit in range, warn otherwise if (iBit < prescaleFactorsAlgoTrig.size()) { if (prescaleFactorsAlgoTrig.at(iBit) != 1) { - (m_prescaleCounterAlgoTrig.at(inBxInEvent).at(iBit))--; - if (m_prescaleCounterAlgoTrig.at(inBxInEvent).at(iBit) == 0) { - // bit already true in algoDecisionWord, just reset counter - m_prescaleCounterAlgoTrig.at(inBxInEvent).at(iBit) = prescaleFactorsAlgoTrig.at(iBit); + bool const triggered = m_prescaleCounterAlgoTrig.at(inBxInEvent).at(iBit).accept(); + if (triggered) { temp_algPrescaledOr = true; } else { // change bit to false in prescaled word and final decision word m_uGtAlgBlk.setAlgoDecisionInterm(iBit, false); - } //if Prescale counter reached zero } //if prescale factor is not 1 (ie. no prescale) else { @@ -1033,8 +995,7 @@ void l1t::GlobalBoard::runFDL(edm::Event& iEvent, } // require bit in range else if (!alreadyReported) { alreadyReported = true; - edm::LogWarning("L1TGlobal") << "\nWarning: algoBit >= prescaleFactorsAlgoTrig.size() in bx " << iBxInEvent - << std::endl; + edm::LogWarning("L1TGlobal") << "\nWarning: algoBit >= prescaleFactorsAlgoTrig.size() in bx " << iBxInEvent; } } //if algo bit is set true } //loop over alg bits @@ -1055,7 +1016,7 @@ void l1t::GlobalBoard::runFDL(edm::Event& iEvent, bool temp_algFinalOr = false; bool alreadyReported = false; for (unsigned int iBit = 0; iBit < numberPhysTriggers; ++iBit) { - bool bitValue = m_uGtAlgBlk.getAlgoDecisionInterm(iBit); + const bool bitValue = m_uGtAlgBlk.getAlgoDecisionInterm(iBit); if (bitValue) { //bool isMasked = ( triggerMaskAlgoTrig.at(iBit) == 0 ); @@ -1064,11 +1025,10 @@ void l1t::GlobalBoard::runFDL(edm::Event& iEvent, isMasked = (triggerMaskAlgoTrig.at(iBit) == 0); else if (!alreadyReported) { alreadyReported = true; - edm::LogWarning("L1TGlobal") << "\nWarning: algoBit >= triggerMaskAlgoTrig.size() in bx " << iBxInEvent - << std::endl; + edm::LogWarning("L1TGlobal") << "\nWarning: algoBit >= triggerMaskAlgoTrig.size() in bx " << iBxInEvent; } - bool passMask = (bitValue && !isMasked); + bool const passMask = (bitValue && !isMasked); if (passMask) temp_algFinalOr = true; @@ -1099,7 +1059,7 @@ void l1t::GlobalBoard::fillAlgRecord(int iBxInEvent, int menuUUID, int firmwareUUID) { if (m_verbosity) { - LogDebug("L1TGlobal") << "\n**** GlobalBoard fill DAQ Records for bx= " << iBxInEvent << std::endl; + LogDebug("L1TGlobal") << "\n**** GlobalBoard fill DAQ Records for bx= " << iBxInEvent; } // Set header information @@ -1160,43 +1120,59 @@ void l1t::GlobalBoard::resetExternal() { // print Global Muon Trigger data received void l1t::GlobalBoard::printGmtData(const int iBxInEvent) const { - LogTrace("L1TGlobal") << "\nl1t::L1GlobalTrigger: uGMT data received for BxInEvent = " << iBxInEvent << std::endl; + LogTrace("L1TGlobal") << "\nl1t::L1GlobalTrigger: uGMT data received for BxInEvent = " << iBxInEvent; int nrL1Mu = m_candL1Mu->size(iBxInEvent); - LogTrace("L1TGlobal") << "Number of GMT muons = " << nrL1Mu << "\n" << std::endl; + LogTrace("L1TGlobal") << "Number of GMT muons = " << nrL1Mu << "\n"; +} - LogTrace("L1TGlobal") << std::endl; +// initialize prescale counters to zero +std::vector l1t::GlobalBoard::prescaleCounters( + std::vector const& prescaleFactorsAlgoTrig) { + std::vector out; + out.reserve(prescaleFactorsAlgoTrig.size()); + for (size_t iAlgo = 0; iAlgo < prescaleFactorsAlgoTrig.size(); ++iAlgo) { + out.emplace_back(prescaleFactorsAlgoTrig[iAlgo]); + } + return out; } -//initializer prescale counter using a semi-random value between [1, prescale value] -const std::vector l1t::GlobalBoard::semirandomNumber(const edm::Event& iEvent, - const std::vector& prescaleFactorsAlgoTrig) { - auto out = prescaleFactorsAlgoTrig; - // pick a random number from a combination of run, lumi, event numbers +// initializer prescale counters using a semi-random value between [0, prescale value * 10 ^ precision - 1] +std::vector l1t::GlobalBoard::prescaleCountersWithSemirandomInitialCounter( + std::vector const& prescaleFactorsAlgoTrig, edm::Event const& iEvent) { + // pick a (semi)random number seeding based on run, lumi, event numbers, + // this leads to different (semi)random numbers for different streams, + // reminder: different streams have different initial event number std::srand(iEvent.id().run()); std::srand(std::rand() + iEvent.id().luminosityBlock()); - // this causes different (semi)random number number for different streams - // reminder: different streams have different initial event number std::srand(std::rand() + iEvent.id().event()); - // very large (semi)random number - double const semirandom = std::rand(); - for (auto& ps : out) { - // if the ps is smaller than 1 (e.g. ps=0, ps=1), it is not changed - // else, replace ps with a semirandom integer in the [1,ps] range - if (ps > 1) { - auto nps = semirandom - floor(semirandom / ps) * ps; - // if nps=0 or a wrong value (<0,>ps) use PS value (standard method) - if (nps > 0 and nps <= ps) - ps = nps; - else { - if (nps != 0) // complain only if nps <0 or nps >PS - edm::LogWarning("L1TGlobal::semirandomNumber") - << "\n The inital prescale counter obtained by L1TGlobal::semirandomNumber is wrong." - << "\n This is probably do to the floating-point precision. Using the PS value." - << "\n semirandom = " << semirandom << "\n PS = " << ps << "\n nps = " << nps - << " <-- it should be in the range [0 , " << ps << "]" << std::endl; - } + int const semirandom = std::rand(); + + std::vector out; + out.reserve(prescaleFactorsAlgoTrig.size()); + + for (size_t iAlgo = 0; iAlgo < prescaleFactorsAlgoTrig.size(); ++iAlgo) { + out.emplace_back(prescaleFactorsAlgoTrig[iAlgo]); + // initialise trigger_counter to a (semi)random integer + // between 0 and prescale_count - 1 (both inclusive) + // (this only changes the behaviour of triggers with PS > 1) + auto& prescaleCounter = out.back(); + if (prescaleCounter.prescale_count > 0) { + prescaleCounter.trigger_counter = semirandom % prescaleCounter.prescale_count; } } + return out; } + +// return decision of PrescalCounter, and update its internal counter +bool l1t::GlobalBoard::PrescaleCounter::accept() { + trigger_counter += m_singlestep; + + if (prescale_count == 0 or trigger_counter < prescale_count) + return false; + + trigger_counter -= prescale_count; + + return true; +} diff --git a/L1Trigger/L1TGlobal/test/BuildFile.xml b/L1Trigger/L1TGlobal/test/BuildFile.xml new file mode 100644 index 0000000000000..fb38828dc924f --- /dev/null +++ b/L1Trigger/L1TGlobal/test/BuildFile.xml @@ -0,0 +1 @@ + diff --git a/L1Trigger/L1TGlobal/test/testL1TGlobalProducer.sh b/L1Trigger/L1TGlobal/test/testL1TGlobalProducer.sh new file mode 100755 index 0000000000000..b9d48f32d0289 --- /dev/null +++ b/L1Trigger/L1TGlobal/test/testL1TGlobalProducer.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +# Pass in name and status +function die { + echo $1: status $2 + echo === Log file === + cat ${3:-/dev/null} + echo === End log file === + exit $2 +} + +# run test job +TESTDIR="${LOCALTOP}"/src/L1Trigger/L1TGlobal/test + +cmsRun "${TESTDIR}"/testL1TGlobalProducer_cfg.py &> log_testL1TGlobalProducer \ + || die "Failure running testL1TGlobalProducer_cfg.py" $? log_testL1TGlobalProducer + +# expected PathSummary of test job +cat <<@EOF > log_testL1TGlobalProducer_expected + Bit Algorithm Name Init PScd Final PS Factor Num Bx Masked +============================================================================================================ + 21 L1_SingleMu22 228 228 228 1 0 + 194 L1_SingleIsoEG32er2p5 244 0 0 0 0 + 286 L1_Mu22er2p1_IsoTau30er2p1 160 133 133 1.2 0 + 318 L1_SingleJet90er2p5 686 103 103 6.65 0 + 428 L1_ETMHF80_HTT60er 155 45 45 3.4 0 + 459 L1_ZeroBias 1000 19 19 50.1 0 + 461 L1_MinimumBiasHF0_AND_BptxAND 983 799 799 1.23 0 + 480 L1_FirstCollisionInOrbit 0 0 0 1 0 + Final OR Count = 866 +@EOF + +# compare to expected output of test job +sed -n '/Init PScd Final PS Factor/,/Final OR Count =/p' log_testL1TGlobalProducer \ + | diff log_testL1TGlobalProducer_expected - \ + || die "differences in expected log report" $? diff --git a/L1Trigger/L1TGlobal/test/testL1TGlobalProducer_cfg.py b/L1Trigger/L1TGlobal/test/testL1TGlobalProducer_cfg.py new file mode 100644 index 0000000000000..721bac9eeb690 --- /dev/null +++ b/L1Trigger/L1TGlobal/test/testL1TGlobalProducer_cfg.py @@ -0,0 +1,149 @@ +import FWCore.ParameterSet.Config as cms + +import FWCore.ParameterSet.VarParsing as vpo +opts = vpo.VarParsing('standard') + +opts.setDefault('maxEvents', 1000) + +opts.register('resetPSCountersEachLumiSec', False, + vpo.VarParsing.multiplicity.singleton, + vpo.VarParsing.varType.bool, + 'reset prescale counters at the start of every luminosity section') + +opts.register('semiRandomInitialPSCounters', False, + vpo.VarParsing.multiplicity.singleton, + vpo.VarParsing.varType.bool, + 'use semi-random initialisation of prescale counters') + +opts.register('prescaleSet', 2, + vpo.VarParsing.multiplicity.singleton, + vpo.VarParsing.varType.int, + 'index of prescale column (starts from zero)') + +opts.parseArguments() + +process = cms.Process('TEST') + +process.options.numberOfThreads = 1 +process.options.numberOfStreams = 0 +process.options.wantSummary = False +process.maxEvents.input = opts.maxEvents + +# Global Tag +from Configuration.AlCa.GlobalTag import GlobalTag +process.load('Configuration.StandardSequences.FrontierConditions_GlobalTag_cff') +process.GlobalTag = GlobalTag(process.GlobalTag, 'auto:phase1_2022_realistic', '') + +# Input source +process.source = cms.Source('PoolSource', + fileNames = cms.untracked.vstring( + '/store/relval/CMSSW_12_5_0/RelValTTbar_14TeV/GEN-SIM-DIGI-RAW/125X_mcRun3_2022_realistic_v3-v2/2580000/ada87bae-44e5-4c2d-84a5-d3286706d4a0.root', + ) +) + +# EventSetup modules +process.GlobalParametersRcdSource = cms.ESSource('EmptyESSource', + recordName = cms.string('L1TGlobalParametersRcd'), + iovIsRunNotTime = cms.bool(True), + firstValid = cms.vuint32(1) +) + +process.GlobalParameters = cms.ESProducer('StableParametersTrivialProducer', + # trigger decision + NumberPhysTriggers = cms.uint32(512), # number of physics trigger algorithms + # trigger objects + NumberL1Muon = cms.uint32(8), # muons + NumberL1EGamma = cms.uint32(12), # e/gamma and isolated e/gamma objects + NumberL1Jet = cms.uint32(12), # jets + NumberL1Tau = cms.uint32(12), # taus + # hardware + NumberChips = cms.uint32(1), # number of maximum chips defined in the xml file + PinsOnChip = cms.uint32(512), # number of pins on the GTL condition chips + # correspondence 'condition chip - GTL algorithm word' in the hardware + # e.g.: chip 2: 0 - 95; chip 1: 96 - 128 (191) + OrderOfChip = cms.vint32(1), +) + +process.L1TUtmTriggerMenuRcdSource = cms.ESSource('EmptyESSource', + recordName = cms.string('L1TUtmTriggerMenuRcd'), + iovIsRunNotTime = cms.bool(True), + firstValid = cms.vuint32(1) +) + +process.L1TriggerMenu = cms.ESProducer('L1TUtmTriggerMenuESProducer', + L1TriggerMenuFile = cms.string('test/L1Menu_L1TGlobalUnitTests_v1_0_0.xml'), +) + +process.L1TGlobalPrescalesVetosFractRcdSource = cms.ESSource('EmptyESSource', + recordName = cms.string('L1TGlobalPrescalesVetosFractRcd'), + iovIsRunNotTime = cms.bool(True), + firstValid = cms.vuint32(1) +) + +process.L1TGlobalPrescalesVetosFract = cms.ESProducer('L1TGlobalPrescalesVetosFractESProducer', + TriggerMenuLuminosity = cms.string('startup'), + Verbosity = cms.int32(0), + AlgoBxMaskDefault = cms.int32(1), + PrescaleXMLFile = cms.string('test/UGT_BASE_RS_PRESCALES_L1MenuL1TGlobalUnitTests_v1_0_0.xml'), + AlgoBxMaskXMLFile = cms.string('test/UGT_BASE_RS_ALGOBX_MASK_L1MenuL1TGlobalUnitTests_v1_0_0.xml'), + FinOrMaskXMLFile = cms.string('test/UGT_BASE_RS_FINOR_MASK_L1MenuL1TGlobalUnitTests_v1_0_0.xml'), + VetoMaskXMLFile = cms.string('test/UGT_BASE_RS_VETO_MASK_L1MenuL1TGlobalUnitTests_v1_0_0.xml'), +) + +# EventData modules +process.simGtExtFakeStage2Digis = cms.EDProducer('L1TExtCondProducer', + bxFirst = cms.int32(-2), + bxLast = cms.int32(2), + setBptxAND = cms.bool(True), + setBptxMinus = cms.bool(True), + setBptxOR = cms.bool(True), + setBptxPlus = cms.bool(True), + tcdsRecordLabel = cms.InputTag('') +) + +process.simGtStage2Digis = cms.EDProducer('L1TGlobalProducer', + AlgoBlkInputTag = cms.InputTag(''), + AlgorithmTriggersUnmasked = cms.bool(False), + AlgorithmTriggersUnprescaled = cms.bool(False), + EGammaInputTag = cms.InputTag('simCaloStage2Digis'), + EtSumInputTag = cms.InputTag('simCaloStage2Digis'), + ExtInputTag = cms.InputTag('simGtExtFakeStage2Digis'), + GetPrescaleColumnFromData = cms.bool(False), + JetInputTag = cms.InputTag('simCaloStage2Digis'), + MuonInputTag = cms.InputTag('simGmtStage2Digis'), + MuonShowerInputTag = cms.InputTag('simGmtShowerDigis'), + TauInputTag = cms.InputTag('simCaloStage2Digis'), + useMuonShowers = cms.bool(True), + RequireMenuToMatchAlgoBlkInput = cms.bool(False), + resetPSCountersEachLumiSec = cms.bool(opts.resetPSCountersEachLumiSec), + semiRandomInitialPSCounters = cms.bool(opts.semiRandomInitialPSCounters), + PrescaleSet = cms.uint32(opts.prescaleSet) +) + +# Task definition +process.l1tTask = cms.Task( process.simGtExtFakeStage2Digis, process.simGtStage2Digis ) + +# Path definition +process.l1tPath = cms.Path( process.l1tTask ) + +# Analyser of L1T-menu results +process.l1tGlobalSummary = cms.EDAnalyzer( 'L1TGlobalSummary', + AlgInputTag = cms.InputTag( 'simGtStage2Digis' ), + ExtInputTag = cms.InputTag( 'simGtStage2Digis' ), + MinBx = cms.int32( 0 ), + MaxBx = cms.int32( 0 ), + DumpTrigResults = cms.bool( False ), + DumpRecord = cms.bool( False ), + DumpTrigSummary = cms.bool( True ), + ReadPrescalesFromFile = cms.bool( False ), + psFileName = cms.string( '' ), + psColumn = cms.int32( 0 ) +) + +# EndPath definition +process.l1tEndPath = cms.EndPath( process.l1tGlobalSummary ) + +# MessageLogger +process.load('FWCore.MessageService.MessageLogger_cfi') +process.MessageLogger.cerr.FwkReport.reportEvery = 100 # only report every 100th event start +process.MessageLogger.L1TGlobalSummary = cms.untracked.PSet()