New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Semi-random initial value in the L1 trigger prescale counter #37506
Changes from 3 commits
22b19aa
ea3a94b
17833d5
2c2d2e1
599560d
1d2f9d3
6d1821b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -14,6 +14,7 @@ | |||||
|
||||||
// system include files | ||||||
#include <bitset> | ||||||
#include <cassert> | ||||||
#include <vector> | ||||||
|
||||||
// user include files | ||||||
|
@@ -37,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 | ||||||
|
@@ -164,6 +165,39 @@ namespace l1t { | |||||
/// pointer to Tau data list | ||||||
inline const BXVector<const GlobalExtBlk*>* getCandL1External() const { return m_candL1External; } | ||||||
|
||||||
//initializer prescale counter using a semi-random value between [1, prescale value] | ||||||
static const std::vector<double> semirandomNumber(const edm::Event& iEvent, | ||||||
const std::vector<double>& 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 || nps <= ps) | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
No? |
||||||
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; | ||||||
} | ||||||
|
||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe this never happens for the values used by this function, but for The current impl only handles the case of non-fractional prescales, right? Should the randomisation be per algo (meaning, a different In case it helps, I find the impl below a bit more readable (but I didn't test it, and there are likely better ways than using auto out = prescaleFactorsAlgoTrig;
// pick a random number from a combination of run, lumi, event numbers (different number for different threads)
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());
// (semi)random number in [0,1] range
auto const semirandom = std::rand() / double(RAND_MAX);
for (auto& ps : out) {
// if the ps is smaller than 1 (e.g. ps=0, ps=1) or if the prescale is fractional, it is not changed
// else, replace ps with a semirandom integer in the [1,ps] range
if (ps > 1 and ps == std::round(ps)) {
ps = std::round((ps - 1)*semirandom + 1);
}
}
return out; There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It looks like my reply is lost.
|
||||||
/* Drop individual EtSums for Now | ||||||
/// pointer to ETM data list | ||||||
inline const l1t::EtSum* getCandL1ETM() const | ||||||
|
@@ -194,6 +228,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 +303,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 | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -971,10 +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); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @cms-sw/l1-l2 please note this is the only line which should affect the default behavior (semiRandomInitialPSCounters = false) |
||
|
||
auto const& prescaleCountersAlgoTrig = | ||
m_semiRandomInitialPSCounters ? semirandomNumber(iEvent, prescaleFactorsAlgoTrig) : prescaleFactorsAlgoTrig; | ||
|
||
for (int iBxInEvent = 0; iBxInEvent <= totalBxInEvent; ++iBxInEvent) { | ||
m_prescaleCounterAlgoTrig.push_back(prescaleFactorsAlgoTrig); | ||
m_prescaleCounterAlgoTrig.push_back(prescaleCountersAlgoTrig); | ||
} | ||
m_firstEv = false; | ||
m_currentLumi = iEvent.luminosityBlock(); | ||
|
@@ -984,7 +987,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(); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why
static
, rather than just aconst
class member?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wanted to stress that this is a standalone function, that might be used even outside a GlobalBoard object.
I might define it as an external function eg.
l1t::semirandomNumber(...)
, but I don't know in which file I should define this function. I've just learned that I cannot define it asl1t::GlobalBoard::semirandomNumber(...)
because a namespace cannot have the same name of a class.I don't have a strong opinion. What do you suggest?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No strong opinion here, either. :)
I guess
l1t::GlobalBoard::semirandomNumber(..)
is effectively how this function would be called outside this class if using the current implementation. I don't see a good place for this elsewhere in this package, so unless L1T has a better idea, I would leave it here like this (maybe the implementation could be moved to the.cc
file, though).