Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:11:36

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
0008 
0009 #include "ActsExamples/Geant4/Geant4Manager.hpp"
0010 
0011 #include "ActsExamples/Geant4/MaterialPhysicsList.hpp"
0012 #include "ActsExamples/Geant4/PhysicsListFactory.hpp"
0013 
0014 #include <memory>
0015 #include <stdexcept>
0016 
0017 #include <FTFP_BERT.hh>
0018 #include <FTFP_BERT_ATL.hh>
0019 #include <G4EmParameters.hh>
0020 #include <G4HadronicParameters.hh>
0021 #include <G4HadronicProcessStore.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(std::unique_ptr<G4RunManager> _runManager,
0036                            std::unique_ptr<G4VUserPhysicsList> _physicsList,
0037                            std::string _physicsListName)
0038     : runManager(std::move(_runManager)),
0039       physicsList(_physicsList.release()),
0040       physicsListName(std::move(_physicsListName)) {
0041   if (runManager == nullptr) {
0042     std::invalid_argument("runManager cannot be null");
0043   }
0044   if (physicsList == nullptr) {
0045     std::invalid_argument("physicsList cannot be null");
0046   }
0047 
0048   // Set physics list
0049   runManager->SetUserInitialization(physicsList);
0050 }
0051 
0052 Geant4Handle::~Geant4Handle() = default;
0053 
0054 void Geant4Handle::tweakLogging(int level) const {
0055   Geant4Manager::tweakLogging(*runManager, level);
0056 }
0057 
0058 Geant4Manager& Geant4Manager::instance() {
0059   static Geant4Manager manager;
0060   return manager;
0061 }
0062 
0063 void Geant4Manager::tweakLogging(G4RunManager& runManager, int level) {
0064   runManager.SetVerboseLevel(level);
0065   G4EventManager::GetEventManager()->SetVerboseLevel(level);
0066   G4EventManager::GetEventManager()->GetTrackingManager()->SetVerboseLevel(
0067       level);
0068   G4EventManager::GetEventManager()->GetStackManager()->SetVerboseLevel(level);
0069 
0070   // Suppress the printing of physics information.
0071 #if G4VERSION_NUMBER >= 1100
0072   G4HadronicParameters::Instance()->SetVerboseLevel(0);
0073   G4HadronicProcessStore::Instance()->SetVerbose(0);
0074   G4EmParameters::Instance()->SetIsPrintedFlag(true);
0075 #endif
0076 }
0077 
0078 std::shared_ptr<Geant4Handle> Geant4Manager::currentHandle() const {
0079   return m_handle.lock();
0080 }
0081 
0082 std::shared_ptr<Geant4Handle> Geant4Manager::createHandle(
0083     const std::string& physicsList) {
0084   return createHandle(createPhysicsList(physicsList), physicsList);
0085 }
0086 
0087 std::shared_ptr<Geant4Handle> Geant4Manager::createHandle(
0088     std::unique_ptr<G4VUserPhysicsList> physicsList,
0089     std::string physicsListName) {
0090   if (!m_handle.expired()) {
0091     throw std::runtime_error("creating a second handle is prohibited");
0092   }
0093   if (m_created) {
0094     throw std::runtime_error(
0095         "creating a new handle is prohibited. you have to hold onto the "
0096         "first one.");
0097   }
0098 
0099   auto runManager = std::unique_ptr<G4RunManager>(
0100       G4RunManagerFactory::CreateRunManager(G4RunManagerType::SerialOnly));
0101 
0102   auto handle = std::make_shared<Geant4Handle>(std::move(runManager),
0103                                                std::move(physicsList),
0104                                                std::move(physicsListName));
0105 
0106   m_created = true;
0107   m_handle = handle;
0108   return handle;
0109 }
0110 
0111 void Geant4Manager::registerPhysicsListFactory(
0112     std::string name,
0113     std::shared_ptr<Geant4::PhysicsListFactory> physicsListFactory) {
0114   if (m_physicsListFactories.contains(name)) {
0115     throw std::invalid_argument("name already mapped");
0116   }
0117   m_physicsListFactories.emplace(std::move(name),
0118                                  std::move(physicsListFactory));
0119 }
0120 
0121 std::unique_ptr<G4VUserPhysicsList> Geant4Manager::createPhysicsList(
0122     const std::string& name) const {
0123   auto it = m_physicsListFactories.find(name);
0124   if (it == m_physicsListFactories.end()) {
0125     throw std::invalid_argument("name not mapped");
0126   }
0127   return it->second->factorize();
0128 }
0129 
0130 const std::unordered_map<std::string,
0131                          std::shared_ptr<Geant4::PhysicsListFactory>>&
0132 Geant4Manager::getPhysicsListFactories() const {
0133   return m_physicsListFactories;
0134 }
0135 
0136 Geant4Manager::Geant4Manager() {
0137   registerPhysicsListFactory(
0138       "FTFP_BERT", std::make_shared<Geant4::PhysicsListFactoryFunction>(
0139                        []() { return std::make_unique<FTFP_BERT>(); }));
0140   registerPhysicsListFactory(
0141       "FTFP_BERT_ATL", std::make_shared<Geant4::PhysicsListFactoryFunction>(
0142                            []() { return std::make_unique<FTFP_BERT_ATL>(); }));
0143   registerPhysicsListFactory(
0144       "MaterialPhysicsList",
0145       std::make_shared<Geant4::PhysicsListFactoryFunction>(
0146           []() { return std::make_unique<Geant4::MaterialPhysicsList>(); }));
0147 }
0148 
0149 Geant4Manager::~Geant4Manager() = default;
0150 
0151 }  // namespace ActsExamples