Skip to content

Commit fa1cbc3

Browse files
sawenzelclaude
andcommitted
Seed Geant4 through a function installed by the Geant4 configuration
This replaces the just-in-time compiled Geant4 seeding with a function that the Geant4 configuration installs. - The JIT code needed CLHEP/Random/Random.h on ROOT_INCLUDE_PATH, which the alienv module environment does not provide. - g4Config.C links Geant4 and installs the same seeding recipe through VMCSeederService::setGeant4Seeder. https://its.cern.ch/jira/browse/O2-7305 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 931eda3 commit fa1cbc3

3 files changed

Lines changed: 26 additions & 10 deletions

File tree

‎Detectors/Base/include/DetectorsBase/VMCSeederService.h‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,19 @@ class VMCSeederService
4242

4343
typedef std::function<void(TRandom*)> SeederFcn;
4444

45+
/// installs the function that seeds Geant4 from a generator; called by the Geant4 configuration, which links Geant4
46+
static void setGeant4Seeder(SeederFcn fcn) { geant4Seeder() = std::move(fcn); }
47+
4548
private:
4649
VMCSeederService();
50+
static SeederFcn& geant4Seeder()
51+
{
52+
static SeederFcn fcn;
53+
return fcn;
54+
}
4755
void initSeederFunction(TVirtualMC const*);
4856

49-
SeederFcn mSeederFcn; // the just-in-time compiled function talking to the VMC engines
57+
SeederFcn mSeederFcn; // the function talking to the VMC engine
5058
mutable std::atomic<unsigned long long> mSeedCount{0}; // number of setSeed() calls
5159
};
5260

‎Detectors/Base/src/VMCSeederService.cxx‎

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,7 @@
1212
#include "DetectorsBase/VMCSeederService.h"
1313
#include "DetectorsBase/SimRandom.h"
1414
#include "TVirtualMC.h"
15-
#include <fairlogger/Logger.h> // for FairLogger
16-
#include <CommonUtils/ConfigurationMacroHelper.h> // for ROOT JIT helpers
17-
#include <TInterpreter.h>
15+
#include <fairlogger/Logger.h> // for FairLogger
1816
#include <TRandom.h>
1917

2018
using namespace o2::base;
@@ -25,13 +23,11 @@ void VMCSeederService::initSeederFunction(TVirtualMC const* vmc)
2523
// Geant3 doesn't need anything special in our context
2624
mSeederFcn = [](TRandom*) {};
2725
} else if (strcmp(vmc->GetName(), "TGeant4") == 0) {
28-
// Seed the Geant4 engine of the calling thread from the given generator, with the same recipe as
29-
// TG4RunManager::SetRandomSeed (which always reads gRandom). JIT-compiled to avoid linking against Geant4.
30-
if (!gInterpreter->Declare("#include <CLHEP/Random/Random.h>")) {
31-
LOG(fatal) << "CLHEP/Random/Random.h not found on ROOT_INCLUDE_PATH; cannot seed Geant4";
26+
// installed by the Geant4 configuration, so that this library does not link against Geant4
27+
mSeederFcn = geant4Seeder();
28+
if (!mSeederFcn) {
29+
LOG(fatal) << "No Geant4 seeding function installed (VMCSeederService::setGeant4Seeder)";
3230
}
33-
std::string G4func("std::function<void(TRandom*)> G4func() { gSystem->Load(\"libgeant4vmc\"); return [](TRandom* r){ long seeds[10]; seeds[0] = r->GetSeed(); seeds[1] = r->GetSeed(); seeds[2] = 0; CLHEP::HepRandom::setTheSeeds(seeds); };}");
34-
mSeederFcn = o2::conf::JITAndEvalFunction<SeederFcn>(G4func, "G4func()", "std::function<void(TRandom*)>", "VMCSEEDERFUNC123");
3531
} else {
3632
LOG(warn) << "Unknown VMC engine or unimplemented VMC seeding function";
3733
mSeederFcn = [](TRandom*) {};

‎Detectors/gconfig/g4Config.C‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ R__LOAD_LIBRARY(libgeant4vmc)
6868
#include <unistd.h>
6969
#include "SimSetup/G4RunConfiguration.h"
7070
#include "SimSetup/VecGeomNavigation.h"
71+
#include "DetectorsBase/VMCSeederService.h"
72+
#include "CLHEP/Random/Random.h"
73+
#include "TRandom.h"
7174
#endif
7275
#include "commonConfig.C"
7376

@@ -153,6 +156,15 @@ void Config()
153156
TGeant4* geant4 = new TGeant4("TGeant4", "The Geant4 Monte Carlo", runConfiguration);
154157
std::cout << "Geant4 has been created." << std::endl;
155158

159+
// seeds the Geant4 engine of the calling thread from a ROOT generator, as TG4RunManager::SetRandomSeed does from gRandom
160+
o2::base::VMCSeederService::setGeant4Seeder([](TRandom* r) {
161+
long seeds[10];
162+
seeds[0] = r->GetSeed();
163+
seeds[1] = r->GetSeed();
164+
seeds[2] = 0;
165+
CLHEP::HepRandom::setTheSeeds(seeds);
166+
});
167+
156168
if (g4Params.navmode == o2::conf::EG4Nav::kVecGeom) {
157169
o2::simsetup::installVecGeomNavigator();
158170
}

0 commit comments

Comments
 (0)