40 #include <G4FieldManager.hh>
41 #include <G4RunManager.hh>
42 #include <G4TransportationManager.hh>
43 #include <G4UniformMagField.hh>
44 #include <G4UserEventAction.hh>
45 #include <G4UserLimits.hh>
46 #include <G4UserRunAction.hh>
47 #include <G4UserSteppingAction.hh>
48 #include <G4UserTrackingAction.hh>
49 #include <G4VUserDetectorConstruction.hh>
50 #include <G4VUserPhysicsList.hh>
51 #include <G4Version.hh>
52 #include <Randomize.hh>
58 throw std::invalid_argument(
"Missing input particle collection");
61 throw std::invalid_argument(
"Missing detector construction factory");
64 throw std::invalid_argument(
"Missing random numbers");
83 if (runManager().GetUserDetectorConstruction() !=
nullptr) {
84 delete runManager().GetUserDetectorConstruction();
87 m_detectorConstruction =
88 config().detectorConstructionFactory->factorize().release();
89 runManager().SetUserInitialization(m_detectorConstruction);
90 runManager().InitializeGeometry();
95 return *m_geant4Instance->runManager.get();
100 return *m_eventStore;
105 runManager().Initialize();
113 std::lock_guard<std::mutex> guard(m_geant4Instance->mutex);
126 eventStore().inputParticles = &m_inputParticles;
128 ACTS_DEBUG(
"Sending Geant RunManager the BeamOn() command.");
132 runManager().BeamOn(1);
137 eventStore().particlesInitial.size() ==
138 eventStore().particlesFinal.size(),
139 "initial and final particle collections does not have the same size: "
140 << eventStore().particlesInitial.size() <<
" vs "
141 << eventStore().particlesFinal.size());
144 if (eventStore().particleIdCollisionsInitial > 0 or
145 eventStore().particleIdCollisionsFinal > 0 or
146 eventStore().parentIdNotFound > 0) {
148 "Particle ID collisions detected, don't trust the particle "
151 "- initial states: " << eventStore().particleIdCollisionsInitial);
152 ACTS_WARNING(
"- final states: " << eventStore().particleIdCollisionsFinal);
153 ACTS_WARNING(
"- parent ID not found: " << eventStore().parentIdNotFound);
156 if (eventStore().hits.empty()) {
157 ACTS_DEBUG(
"Step merging: No steps recorded");
159 ACTS_DEBUG(
"Step merging: mean hits per hit: "
160 << static_cast<double>(eventStore().numberGeantSteps) /
161 eventStore().hits.size());
163 "Step merging: max hits per hit: " << eventStore().maxStepsForHit);
169 std::shared_ptr<ActsExamples::Geant4Handle>
171 return m_geant4Instance;
182 throw std::runtime_error(
"inconsistent physics list");
190 if (
runManager().GetUserPrimaryGeneratorAction() !=
nullptr) {
191 delete runManager().GetUserPrimaryGeneratorAction();
197 prCfg,
m_logger->cloneWithSuffix(
"SimParticleTranslation"));
199 runManager().SetUserAction(primaryGeneratorAction);
205 if (
runManager().GetUserTrackingAction() !=
nullptr) {
213 trackingCfg,
m_logger->cloneWithSuffix(
"ParticleTracking"));
220 if (
runManager().GetUserSteppingAction() !=
nullptr) {
225 particleKillCfg.
volume = cfg.killVolume;
226 particleKillCfg.
maxTime = cfg.killAfterTime;
234 stepCfg.
secondary = cfg.recordHitsOfSecondaries;
237 steppingCfg.
actions.push_back(std::make_unique<ParticleKillAction>(
238 particleKillCfg,
m_logger->cloneWithSuffix(
"Killer")));
239 steppingCfg.
actions.push_back(std::make_unique<SensitiveSteppingAction>(
240 stepCfg,
m_logger->cloneWithSuffix(
"SensitiveStepping")));
255 if (cfg.magneticField) {
256 ACTS_INFO(
"Setting ACTS configured field to Geant4.");
268 g4World->GetLogicalVolume()->SetFieldManager(m_fieldManager.get(),
true);
273 if (cfg.trackingGeometry) {
275 "Remapping selected volumes from Geant4 to Acts::Surface::GeometryID");
283 ssmCfg,
m_logger->cloneWithSuffix(
"SensitiveSurfaceMapper"));
286 g4World, Acts::Transform3::Identity(), sCounter);
288 ACTS_INFO(
"Remapping successful for " << sCounter <<
" selected volumes.");
304 m_outputParticlesInitial(
306 eventStore().particlesInitial.end()));
307 m_outputParticlesFinal(
309 eventStore().particlesFinal.end()));
311 #if BOOST_VERSION < 107800
313 for (
const auto& hit : eventStore().hits) {
314 container.insert(hit);
316 m_outputSimHits(ctx,
std::move(container));
319 ctx,
SimHitContainer(eventStore().hits.begin(), eventStore().hits.end()));
328 auto physicsListName =
"MaterialPhysicsList";
334 std::make_unique<MaterialPhysicsList>(
335 m_logger->cloneWithSuffix(
"MaterialPhysicsList")),
338 throw std::runtime_error(
"inconsistent physics list");
346 if (
runManager().GetUserPrimaryGeneratorAction() !=
nullptr) {
347 delete runManager().GetUserPrimaryGeneratorAction();
358 prCfg,
m_logger->cloneWithSuffix(
"SimParticleTranslation"));
360 runManager().SetUserAction(primaryGeneratorAction);
366 if (
runManager().GetUserTrackingAction() !=
nullptr) {
374 trackingCfg,
m_logger->cloneWithSuffix(
"ParticleTracking"));
381 if (
runManager().GetUserSteppingAction() !=
nullptr) {
389 steppingCfg,
m_logger->cloneWithSuffix(
"MaterialSteppingAction"));
406 m_outputMaterialTracks(
407 ctx, decltype(eventStore().materialTracks)(eventStore().materialTracks));