From 22b19aadd937a0ac9012bb45309fc6932f5da63d Mon Sep 17 00:00:00 2001 From: Silvio Date: Mon, 28 Mar 2022 17:48:44 +0200 Subject: [PATCH 1/7] make L1 prescale start from a semi-random value --- L1Trigger/L1TGlobal/interface/GlobalBoard.h | 31 +++++++++++++++++++ .../L1TGlobal/plugins/L1TGlobalProducer.cc | 3 ++ .../L1TGlobal/plugins/L1TGlobalProducer.h | 2 ++ L1Trigger/L1TGlobal/src/GlobalBoard.cc | 12 +++++-- 4 files changed, 46 insertions(+), 2 deletions(-) diff --git a/L1Trigger/L1TGlobal/interface/GlobalBoard.h b/L1Trigger/L1TGlobal/interface/GlobalBoard.h index 01d99981ed8ff..2af2d4442e9a1 100644 --- a/L1Trigger/L1TGlobal/interface/GlobalBoard.h +++ b/L1Trigger/L1TGlobal/interface/GlobalBoard.h @@ -14,6 +14,7 @@ // system include files #include +#include #include // user include files @@ -164,6 +165,32 @@ 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) { + std::vector out(prescaleFactorsAlgoTrig.size(), 1.); + //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 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; + assert(out[i] > 0); + assert(out[i] <= ps); + } + } + return out; + } + /* Drop individual EtSums for Now /// pointer to ETM data list inline const l1t::EtSum* getCandL1ETM() const @@ -194,6 +221,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; } @@ -268,6 +296,9 @@ namespace l1t { //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 4fff69df8c94f..ad39825263b4e 100644 --- a/L1Trigger/L1TGlobal/src/GlobalBoard.cc +++ b/L1Trigger/L1TGlobal/src/GlobalBoard.cc @@ -974,7 +974,11 @@ void l1t::GlobalBoard::runFDL(edm::Event& iEvent, m_prescaleCounterAlgoTrig.reserve(numberPhysTriggers * totalBxInEvent); for (int iBxInEvent = 0; iBxInEvent <= totalBxInEvent; ++iBxInEvent) { - m_prescaleCounterAlgoTrig.push_back(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 +988,11 @@ 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(prescaleFactorsAlgoTrig); + if (m_semiRandomInitialPSCounters) { + m_prescaleCounterAlgoTrig.push_back(semirandomNumber(iEvent, prescaleFactorsAlgoTrig)); + } else { + m_prescaleCounterAlgoTrig.push_back(prescaleFactorsAlgoTrig); + } } m_firstEvLumiSegment = false; m_currentLumi = iEvent.luminosityBlock(); From ea3a94b817803b7befec6b342945abca76982ee1 Mon Sep 17 00:00:00 2001 From: Silvio Date: Sun, 1 May 2022 16:01:17 +0200 Subject: [PATCH 2/7] improve readibility, remove asserts --- L1Trigger/L1TGlobal/interface/GlobalBoard.h | 43 ++++++++++++--------- 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/L1Trigger/L1TGlobal/interface/GlobalBoard.h b/L1Trigger/L1TGlobal/interface/GlobalBoard.h index 2af2d4442e9a1..3e4338ff13766 100644 --- a/L1Trigger/L1TGlobal/interface/GlobalBoard.h +++ b/L1Trigger/L1TGlobal/interface/GlobalBoard.h @@ -38,7 +38,7 @@ #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 @@ -168,24 +168,31 @@ namespace l1t { //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) { - std::vector out(prescaleFactorsAlgoTrig.size(), 1.); - //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()); + auto out = prescaleFactorsAlgoTrig; + // pick a random number from a combination of run, lumi, event numbers + std::srand(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 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; - assert(out[i] > 0); - assert(out[i] <= ps); + // 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 || 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." << semirandom + << "\n semirandom = " << semirandom << "\n PS = " << ps << "\n nps = " << nps + << " <-- it should be in the range [0 , " << ps << "]" << std::endl; + } } } return out; From 17833d5590783e072356b1e1edd72526c4fa7921 Mon Sep 17 00:00:00 2001 From: Silvio Date: Sun, 1 May 2022 16:02:31 +0200 Subject: [PATCH 3/7] fix m_prescaleCounterAlgoTrig.reserve, move semirandomNumber outside bx loop --- L1Trigger/L1TGlobal/src/GlobalBoard.cc | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/L1Trigger/L1TGlobal/src/GlobalBoard.cc b/L1Trigger/L1TGlobal/src/GlobalBoard.cc index ad39825263b4e..30be13c8ae9da 100644 --- a/L1Trigger/L1TGlobal/src/GlobalBoard.cc +++ b/L1Trigger/L1TGlobal/src/GlobalBoard.cc @@ -971,14 +971,13 @@ void l1t::GlobalBoard::runFDL(edm::Event& iEvent, // prescale counters are reset at the beginning of the luminosity segment if (m_firstEv) { // prescale counters: numberPhysTriggers counters per bunch cross - m_prescaleCounterAlgoTrig.reserve(numberPhysTriggers * totalBxInEvent); + m_prescaleCounterAlgoTrig.reserve(totalBxInEvent); + + auto const& prescaleCountersAlgoTrig = + m_semiRandomInitialPSCounters ? semirandomNumber(iEvent, prescaleFactorsAlgoTrig) : prescaleFactorsAlgoTrig; for (int iBxInEvent = 0; iBxInEvent <= totalBxInEvent; ++iBxInEvent) { - if (m_semiRandomInitialPSCounters) { - m_prescaleCounterAlgoTrig.push_back(semirandomNumber(iEvent, prescaleFactorsAlgoTrig)); - } else { - m_prescaleCounterAlgoTrig.push_back(prescaleFactorsAlgoTrig); - } + m_prescaleCounterAlgoTrig.push_back(prescaleCountersAlgoTrig); } m_firstEv = false; m_currentLumi = iEvent.luminosityBlock(); From 2c2d2e1f128578673dbe31ccf745bb567c6cdf7e Mon Sep 17 00:00:00 2001 From: Silvio Date: Mon, 2 May 2022 12:26:51 +0200 Subject: [PATCH 4/7] bugfix --- L1Trigger/L1TGlobal/interface/GlobalBoard.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/L1Trigger/L1TGlobal/interface/GlobalBoard.h b/L1Trigger/L1TGlobal/interface/GlobalBoard.h index 3e4338ff13766..2ce48fec195cb 100644 --- a/L1Trigger/L1TGlobal/interface/GlobalBoard.h +++ b/L1Trigger/L1TGlobal/interface/GlobalBoard.h @@ -183,10 +183,10 @@ namespace l1t { 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 || nps <= ps) + if (nps > 0 and nps <= ps) ps = nps; else { - if (nps != 0) // complain only if nps <0 or nps >PS + 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." << semirandom From 599560d3eb655f1ccf592456673cef77cbe5bde8 Mon Sep 17 00:00:00 2001 From: Silvio Date: Mon, 2 May 2022 16:14:58 +0200 Subject: [PATCH 5/7] style fix --- L1Trigger/L1TGlobal/interface/GlobalBoard.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/L1Trigger/L1TGlobal/interface/GlobalBoard.h b/L1Trigger/L1TGlobal/interface/GlobalBoard.h index 2ce48fec195cb..3df1d59b6713e 100644 --- a/L1Trigger/L1TGlobal/interface/GlobalBoard.h +++ b/L1Trigger/L1TGlobal/interface/GlobalBoard.h @@ -186,10 +186,10 @@ namespace l1t { if (nps > 0 and nps <= ps) ps = nps; else { - if (nps != 0) // complain only if nps <0 or nps >PS + 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." << semirandom + << "\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; } From 1d2f9d3c55a25d3f8bb9ad238b34374b782b81d4 Mon Sep 17 00:00:00 2001 From: Silvio Date: Mon, 2 May 2022 18:58:57 +0200 Subject: [PATCH 6/7] move implementation of semirandom function to .cc file --- L1Trigger/L1TGlobal/interface/GlobalBoard.h | 31 +------------------ L1Trigger/L1TGlobal/src/GlobalBoard.cc | 33 +++++++++++++++++++++ 2 files changed, 34 insertions(+), 30 deletions(-) diff --git a/L1Trigger/L1TGlobal/interface/GlobalBoard.h b/L1Trigger/L1TGlobal/interface/GlobalBoard.h index 3df1d59b6713e..894951209f4bd 100644 --- a/L1Trigger/L1TGlobal/interface/GlobalBoard.h +++ b/L1Trigger/L1TGlobal/interface/GlobalBoard.h @@ -167,36 +167,7 @@ namespace l1t { //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) { - auto out = prescaleFactorsAlgoTrig; - // pick a random number from a combination of run, lumi, event numbers - 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; - } - } - } - return out; - } + const std::vector& prescaleFactorsAlgoTrig); /* Drop individual EtSums for Now /// pointer to ETM data list diff --git a/L1Trigger/L1TGlobal/src/GlobalBoard.cc b/L1Trigger/L1TGlobal/src/GlobalBoard.cc index 30be13c8ae9da..d124c8e479d98 100644 --- a/L1Trigger/L1TGlobal/src/GlobalBoard.cc +++ b/L1Trigger/L1TGlobal/src/GlobalBoard.cc @@ -1167,3 +1167,36 @@ void l1t::GlobalBoard::printGmtData(const int iBxInEvent) const { LogTrace("L1TGlobal") << std::endl; } + +//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 + 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; + } + } + } + return out; +} From 6d1821b2fc79ab54eb01eda20ff66e9fee38f196 Mon Sep 17 00:00:00 2001 From: Silvio Date: Mon, 16 May 2022 18:40:50 +0200 Subject: [PATCH 7/7] code checks --- L1Trigger/L1TGlobal/src/GlobalBoard.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/L1Trigger/L1TGlobal/src/GlobalBoard.cc b/L1Trigger/L1TGlobal/src/GlobalBoard.cc index d124c8e479d98..bf82d690d8961 100644 --- a/L1Trigger/L1TGlobal/src/GlobalBoard.cc +++ b/L1Trigger/L1TGlobal/src/GlobalBoard.cc @@ -1170,7 +1170,7 @@ void l1t::GlobalBoard::printGmtData(const int iBxInEvent) const { //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) { + const std::vector& prescaleFactorsAlgoTrig) { auto out = prescaleFactorsAlgoTrig; // pick a random number from a combination of run, lumi, event numbers std::srand(iEvent.id().run());