File indexing completed on 2025-08-05 08:09:45
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "ActsExamples/Geant4/Geant4Manager.hpp"
0010
0011 #include "ActsExamples/Geant4/PhysicsListFactory.hpp"
0012
0013 #include <memory>
0014 #include <stdexcept>
0015
0016 #include <FTFP_BERT.hh>
0017 #include <FTFP_BERT_ATL.hh>
0018 #include <G4EmParameters.hh>
0019 #include <G4HadronicParameters.hh>
0020 #include <G4HadronicProcessStore.hh>
0021 #include <G4Profiler.hh>
0022 #include <G4RunManager.hh>
0023 #include <G4RunManagerFactory.hh>
0024 #include <G4UserEventAction.hh>
0025 #include <G4UserRunAction.hh>
0026 #include <G4UserSteppingAction.hh>
0027 #include <G4UserTrackingAction.hh>
0028 #include <G4VUserDetectorConstruction.hh>
0029 #include <G4VUserPhysicsList.hh>
0030 #include <G4VUserPrimaryGeneratorAction.hh>
0031 #include <G4Version.hh>
0032
0033 namespace ActsExamples {
0034
0035 Geant4Handle::Geant4Handle(int _logLevel,
0036 std::unique_ptr<G4RunManager> _runManager,
0037 std::unique_ptr<G4VUserPhysicsList> _physicsList,
0038 std::string _physicsListName)
0039 : logLevel(_logLevel),
0040 runManager(std::move(_runManager)),
0041 physicsList(_physicsList.release()),
0042 physicsListName(std::move(_physicsListName)) {
0043 if (runManager == nullptr) {
0044 std::invalid_argument("runManager cannot be null");
0045 }
0046 if (physicsList == nullptr) {
0047 std::invalid_argument("physicsList cannot be null");
0048 }
0049
0050
0051 runManager->SetUserInitialization(physicsList);
0052 }
0053
0054 Geant4Handle::~Geant4Handle() = default;
0055
0056 void Geant4Handle::tweakLogging(int level) const {
0057 Geant4Manager::tweakLogging(*runManager, level);
0058 }
0059
0060 Geant4Manager& Geant4Manager::instance() {
0061 static Geant4Manager manager;
0062 return manager;
0063 }
0064
0065 void Geant4Manager::tweakLogging(G4RunManager& runManager, int level) {
0066 runManager.SetVerboseLevel(level);
0067 G4EventManager::GetEventManager()->SetVerboseLevel(level);
0068 G4EventManager::GetEventManager()->GetTrackingManager()->SetVerboseLevel(
0069 level);
0070 G4EventManager::GetEventManager()->GetStackManager()->SetVerboseLevel(level);
0071
0072
0073 #if G4VERSION_NUMBER >= 1100
0074 G4HadronicParameters::Instance()->SetVerboseLevel(0);
0075 G4HadronicProcessStore::Instance()->SetVerbose(0);
0076 G4EmParameters::Instance()->SetIsPrintedFlag(true);
0077 #endif
0078 }
0079
0080 std::shared_ptr<Geant4Handle> Geant4Manager::currentHandle() const {
0081 return m_handle.lock();
0082 }
0083
0084 std::shared_ptr<Geant4Handle> Geant4Manager::createHandle(
0085 int logLevel, const std::string& physicsList) {
0086 return createHandle(logLevel, createPhysicsList(physicsList), physicsList);
0087 }
0088
0089 std::shared_ptr<Geant4Handle> Geant4Manager::createHandle(
0090 int logLevel, std::unique_ptr<G4VUserPhysicsList> physicsList,
0091 std::string physicsListName) {
0092 if (!m_handle.expired()) {
0093 throw std::runtime_error("creating a second handle is prohibited");
0094 }
0095 if (m_created) {
0096 throw std::runtime_error(
0097 "creating a new handle is prohibited. you have to hold onto the "
0098 "first one.");
0099 }
0100
0101 auto runManager = std::unique_ptr<G4RunManager>(
0102 G4RunManagerFactory::CreateRunManager(G4RunManagerType::SerialOnly));
0103
0104 auto handle = std::make_shared<Geant4Handle>(logLevel, std::move(runManager),
0105 std::move(physicsList),
0106 std::move(physicsListName));
0107
0108 m_created = true;
0109 m_handle = handle;
0110 return handle;
0111 }
0112
0113 void Geant4Manager::registerPhysicsListFactory(
0114 std::string name, std::shared_ptr<PhysicsListFactory> physicsListFactory) {
0115 if (m_physicsListFactories.find(name) != m_physicsListFactories.end()) {
0116 throw std::invalid_argument("name already mapped");
0117 }
0118 m_physicsListFactories.emplace(std::move(name),
0119 std::move(physicsListFactory));
0120 }
0121
0122 std::unique_ptr<G4VUserPhysicsList> Geant4Manager::createPhysicsList(
0123 const std::string& name) const {
0124 auto it = m_physicsListFactories.find(name);
0125 if (it == m_physicsListFactories.end()) {
0126 throw std::invalid_argument("name not mapped");
0127 }
0128 return it->second->factorize();
0129 }
0130
0131 const std::unordered_map<std::string, std::shared_ptr<PhysicsListFactory>>&
0132 Geant4Manager::getPhysicsListFactories() const {
0133 return m_physicsListFactories;
0134 }
0135
0136 Geant4Manager::Geant4Manager() {
0137 registerPhysicsListFactory(
0138 "FTFP_BERT", std::make_shared<PhysicsListFactoryFunction>(
0139 []() { return std::make_unique<FTFP_BERT>(); }));
0140 registerPhysicsListFactory(
0141 "FTFP_BERT_ATL", std::make_shared<PhysicsListFactoryFunction>(
0142 []() { return std::make_unique<FTFP_BERT_ATL>(); }));
0143 }
0144
0145 Geant4Manager::~Geant4Manager() = default;
0146
0147 }