Skip to content

Commit bfd378c

Browse files
sawenzelalcaliva
authored andcommitted
Pythia8 seeding improvements
This commit improves the seeding of Pythia8 in O2. The seeding... (a) ... is now done as part of the object's Init function automatically. Users are no longer required to provide own seeding logic, which can significantly simplify the setup. By default, Pythia8 will seed against ROOT TRandom::GetSeed, which is itself set to values of the command line option `--seed`, used in the o2-sim ... or o2-sim-dpl-eventgen execetuables (which are the 2 places undertaking event generation). This setup guarantees that ``` o2-sim-dpl-eventgen --generator pythiapp --seed x ``` will result in different event sequences when x changes. (b) Users can simply set the seed via a `setInitialSeed` function on the GeneratorPythia8 object. The function must be called before GeneratorPythia8::Init is executed. So calling it right after the constructor is fine. Example code (e.g., inside user Generator macro) is: ``` auto mygen = new o2::eventgen::GeneratorPythia8(); long seed = atol(getenv(ALIEN_PROC_ID)); if(!mygen->setInitialSeed(seed)) { std::cerr << "seeding failed"; } ``` In result, the commit leads to a simplification of the Pythia8 setup also in GeneratorFactory. (cherry picked from commit 4179712)
1 parent 7d85fff commit bfd378c

File tree

3 files changed

+65
-6
lines changed

3 files changed

+65
-6
lines changed

Generators/include/Generators/GeneratorPythia8.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,12 @@ class GeneratorPythia8 : public Generator
163163

164164
typedef std::function<bool(const Pythia8::Particle&)> UserFilterFcn;
165165

166+
/// A function allowing to set the initial value used in seeding Pythia.
167+
/// The function needs to be called before GeneratorPythia8::Init is invoked.
168+
/// The function value will be true upon success, or false if either Init has already been called or if the see is smaller than 0.
169+
/// For values of seed >= 0, a truncation to the range [0:90000000] will automatically take place via a modulus operation.
170+
bool setInitialSeed(long seed);
171+
166172
protected:
167173
/** copy constructor **/
168174
GeneratorPythia8(const GeneratorPythia8&);
@@ -251,6 +257,9 @@ class GeneratorPythia8 : public Generator
251257
void getNfreeSpec(const Pythia8::Info& info, int& nFreenProj, int& nFreepProj, int& nFreenTarg, int& nFreepTarg);
252258
/** @} */
253259

260+
/// performs seeding of the random state of Pythia (called from Init)
261+
void seedGenerator();
262+
254263
/** Pythia8 **/
255264
Pythia8::Pythia mPythia; //!
256265

@@ -269,6 +278,12 @@ class GeneratorPythia8 : public Generator
269278
void initUserFilterCallback();
270279

271280
bool mApplyPruning = false;
281+
bool mIsInitialized = false; // if Init function has been called
282+
long mInitialRNGSeed = -1; // initial seed for Pythia random number state;
283+
// will be transported to Pythia in the Init function through the Pythia::readString("Random:seed") mechanism.
284+
// Value of -1 means unitialized; 0 will be time-dependent and values >1 <= MAX_SEED concrete reproducible seeding
285+
286+
constexpr static long MAX_SEED = 900000000;
272287

273288
ClassDefOverride(GeneratorPythia8, 1);
274289

Generators/src/GeneratorFactory.cxx

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -69,13 +69,9 @@ void GeneratorFactory::setPrimaryGenerator(o2::conf::SimConfig const& conf, Fair
6969
auto makePythia8Gen = [](std::string& config) {
7070
auto gen = new o2::eventgen::GeneratorPythia8();
7171
if (!config.empty()) {
72-
LOG(info) << "Reading \'Pythia8\' base configuration: " << config << std::endl;
73-
gen->readFile(config);
72+
LOG(info) << "Setting \'Pythia8\' base configuration: " << config << std::endl;
73+
gen->setConfig(config); // assign config; will be executed in Init function
7474
}
75-
auto seed = (gRandom->TRandom::GetSeed() % 900000000);
76-
LOG(info) << "Using random seed from gRandom % 900000000: " << seed;
77-
gen->readString("Random:setSeed on");
78-
gen->readString("Random:seed " + std::to_string(seed));
7975
return gen;
8076
};
8177
#endif

Generators/src/GeneratorPythia8.cxx

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,46 @@ GeneratorPythia8::GeneratorPythia8(const Char_t* name, const Char_t* title) : Ge
7171
mInterfaceName = "pythia8";
7272
}
7373

74+
bool GeneratorPythia8::setInitialSeed(long seed)
75+
{
76+
// check first of all if Init not yet called and seed not <0
77+
if (mIsInitialized) {
78+
return false;
79+
}
80+
if (seed < 0) {
81+
return false;
82+
}
83+
// sets the initial seed and applies the correct Pythia
84+
// range
85+
mInitialRNGSeed = seed % (MAX_SEED + 1);
86+
LOG(info) << "GeneratorPythia8: Setting initial seed to " << mInitialRNGSeed;
87+
return true;
88+
}
89+
90+
/*****************************************************************/
91+
void GeneratorPythia8::seedGenerator()
92+
{
93+
/// Function is seeding the Pythia random numbers.
94+
/// In case a completely different logic is required by users,
95+
/// we could make this function virtual or allow to set/execute
96+
/// a user-given lambda function instead.
97+
98+
/// Note that this function is executed **before** the Pythia8
99+
/// user config file is read. So the config file should either not contain seeding information ... or can be used to override seeding logic.
100+
101+
auto seed = mInitialRNGSeed;
102+
if (seed == -1) {
103+
// Will use the mInitialRNGSeed if it was set.
104+
// Otherwise will seed the generator with the state of
105+
// TRandom::GetSeed. This is the seed that is influenced from
106+
// SimConfig --seed command line options options.
107+
seed = (gRandom->TRandom::GetSeed() % (MAX_SEED + 1));
108+
LOG(info) << "GeneratorPythia8: Using random seed from gRandom % 900000001: " << seed;
109+
}
110+
mPythia.readString("Random:setSeed on");
111+
mPythia.readString("Random:seed " + std::to_string(seed));
112+
}
113+
74114
/*****************************************************************/
75115

76116
Bool_t GeneratorPythia8::Init()
@@ -80,6 +120,12 @@ Bool_t GeneratorPythia8::Init()
80120
/** init base class **/
81121
Generator::Init();
82122

123+
/** Seed the Pythia random number state.
124+
The user may override this seeding by providing separate
125+
Random:setSeed configurations in the configuration file.
126+
**/
127+
seedGenerator();
128+
83129
/** read configuration **/
84130
if (!mConfig.empty()) {
85131
std::stringstream ss(mConfig);
@@ -147,6 +193,8 @@ Bool_t GeneratorPythia8::Init()
147193

148194
initUserFilterCallback();
149195

196+
mIsInitialized = true;
197+
150198
/** success **/
151199
return true;
152200
}

0 commit comments

Comments
 (0)