diff --git a/L1Trigger/L1TGlobal/interface/GlobalBoard.h b/L1Trigger/L1TGlobal/interface/GlobalBoard.h index 4bb167f4f76ff..a353ab300f466 100644 --- a/L1Trigger/L1TGlobal/interface/GlobalBoard.h +++ b/L1Trigger/L1TGlobal/interface/GlobalBoard.h @@ -169,24 +169,22 @@ namespace l1t { static const std::vector semirandomNumber(const edm::Event& iEvent, const std::vector& prescaleFactorsAlgoTrig) { std::vector out(prescaleFactorsAlgoTrig.size(), 1.); - //pick a random number from a combination of run and lumi numbers (same number for different threads) - //Option A) multi-thread reproducible -/* std::srand(0);*/ -/* std::srand(std::rand()+iEvent.id().run());*/ -/* std::srand(std::rand()+iEvent.id().luminosityBlock());*/ -/* const double semirandom = std::rand(); */*/ - //Option B) multi-thread non-reproducible - const double semirandom = iEvent.id().event() + iEvent.id().run() + iEvent.id().luminosityBlock(); + //pick a random number from a combination of run, lumi, event numbers (different number for different threads) + std::srand(0); + std::srand(std::rand()+iEvent.id().run()); + std::srand(std::rand()+iEvent.id().luminosityBlock()); + //this causes different semirandomNumber number for different threads + std::srand(std::rand()+iEvent.id().event()); //reminder: different threads have different initial event number + const double semirandom = std::rand(); for ( size_t i = 0; i< prescaleFactorsAlgoTrig.size(); i++) { const double ps = prescaleFactorsAlgoTrig.at(i); - if (ps==0 || ps==1) { //do not touch ps = 0 or 1 + if (ps==0 || ps==1) { //do not touch ps = 0 and ps = 1 out[i] = ps; } else { //replace ps with a semirandom number between [1,ps] out[i] = semirandom - floor(semirandom/ps)*ps; if(out[i]==0) out[i] = ps; - //std::cout<< out[i] <<"\t" << ps <<"\t" << semirandom << std::endl; assert(out[i]>0); assert(out[i]<=ps); } @@ -224,6 +222,7 @@ namespace l1t { void setBxLast(int bx); void setResetPSCountersEachLumiSec(bool val) { m_resetPSCountersEachLumiSec = val; } + void setSemiRandomInitialPSCounters(bool val) { m_semiRandomInitialPSCounters = val; } public: inline void setVerbosity(const int verbosity) { m_verbosity = verbosity; } @@ -295,9 +294,12 @@ namespace l1t { // Information about board int m_uGtBoardNumber; bool m_uGtFinalBoard; - + //whether we reset the prescales each lumi or not bool m_resetPSCountersEachLumiSec = true; + + // start the PS counter from a random value between [1,PS] instead of PS + bool m_semiRandomInitialPSCounters = false; }; } // namespace l1t diff --git a/L1Trigger/L1TGlobal/plugins/L1TGlobalProducer.cc b/L1Trigger/L1TGlobal/plugins/L1TGlobalProducer.cc index 1fa464f17fed5..1550439d427b5 100644 --- a/L1Trigger/L1TGlobal/plugins/L1TGlobalProducer.cc +++ b/L1Trigger/L1TGlobal/plugins/L1TGlobalProducer.cc @@ -69,6 +69,7 @@ void L1TGlobalProducer::fillDescriptions(edm::ConfigurationDescriptions& descrip // switch for muon showers in Run-3 desc.add("useMuonShowers", false); desc.add("resetPSCountersEachLumiSec", true); + desc.add("semiRandomInitialPSCounters", false); // These parameters have well defined default values and are not currently // part of the L1T/HLT interface. They can be cleaned up or updated at will: desc.add("ProduceL1GtDaqRecord", true); @@ -116,6 +117,7 @@ L1TGlobalProducer::L1TGlobalProducer(const edm::ParameterSet& parSet) m_requireMenuToMatchAlgoBlkInput(parSet.getParameter("RequireMenuToMatchAlgoBlkInput")), m_algoblkInputTag(parSet.getParameter("AlgoBlkInputTag")), m_resetPSCountersEachLumiSec(parSet.getParameter("resetPSCountersEachLumiSec")), + m_semiRandomInitialPSCounters(parSet.getParameter("semiRandomInitialPSCounters")), m_useMuonShowers(parSet.getParameter("useMuonShowers")) { m_egInputToken = consumes>(m_egInputTag); m_tauInputToken = consumes>(m_tauInputTag); @@ -197,6 +199,7 @@ L1TGlobalProducer::L1TGlobalProducer(const edm::ParameterSet& parSet) m_uGtBrd = std::make_unique(); m_uGtBrd->setVerbosity(m_verbosity); m_uGtBrd->setResetPSCountersEachLumiSec(m_resetPSCountersEachLumiSec); + m_uGtBrd->setSemiRandomInitialPSCounters(m_semiRandomInitialPSCounters); // initialize cached IDs diff --git a/L1Trigger/L1TGlobal/plugins/L1TGlobalProducer.h b/L1Trigger/L1TGlobal/plugins/L1TGlobalProducer.h index 80d2c20c66813..22e0f4af1bc6b 100644 --- a/L1Trigger/L1TGlobal/plugins/L1TGlobalProducer.h +++ b/L1Trigger/L1TGlobal/plugins/L1TGlobalProducer.h @@ -188,6 +188,8 @@ class L1TGlobalProducer : public edm::stream::EDProducer<> { //disables reseting the prescale counters each lumisection (needed for offline) bool m_resetPSCountersEachLumiSec; + // start the PS counter from a random value between [1,PS] instead of PS + bool m_semiRandomInitialPSCounters; // switch to load muon showers in the global board bool m_useMuonShowers; }; diff --git a/L1Trigger/L1TGlobal/src/GlobalBoard.cc b/L1Trigger/L1TGlobal/src/GlobalBoard.cc index ec3339b54ae83..a2d78222143c8 100644 --- a/L1Trigger/L1TGlobal/src/GlobalBoard.cc +++ b/L1Trigger/L1TGlobal/src/GlobalBoard.cc @@ -973,8 +973,14 @@ void l1t::GlobalBoard::runFDL(edm::Event& iEvent, // prescale counters: numberPhysTriggers counters per bunch cross m_prescaleCounterAlgoTrig.reserve(numberPhysTriggers * totalBxInEvent); + for (int iBxInEvent = 0; iBxInEvent <= totalBxInEvent; ++iBxInEvent) { - m_prescaleCounterAlgoTrig.push_back(semirandomNumber(iEvent, prescaleFactorsAlgoTrig)); + if (m_semiRandomInitialPSCounters){ + m_prescaleCounterAlgoTrig.push_back(semirandomNumber(iEvent, prescaleFactorsAlgoTrig)); + } + else{ + m_prescaleCounterAlgoTrig.push_back(prescaleFactorsAlgoTrig); + } } m_firstEv = false; m_currentLumi = iEvent.luminosityBlock(); @@ -984,7 +990,12 @@ void l1t::GlobalBoard::runFDL(edm::Event& iEvent, if (m_firstEvLumiSegment || (m_currentLumi != iEvent.luminosityBlock() && m_resetPSCountersEachLumiSec)) { m_prescaleCounterAlgoTrig.clear(); for (int iBxInEvent = 0; iBxInEvent <= totalBxInEvent; ++iBxInEvent) { - m_prescaleCounterAlgoTrig.push_back(semirandomNumber(iEvent, prescaleFactorsAlgoTrig)); + if (m_semiRandomInitialPSCounters){ + m_prescaleCounterAlgoTrig.push_back(semirandomNumber(iEvent, prescaleFactorsAlgoTrig)); + } + else{ + m_prescaleCounterAlgoTrig.push_back(prescaleFactorsAlgoTrig); + } } m_firstEvLumiSegment = false; m_currentLumi = iEvent.luminosityBlock();