Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-05 08:09:45

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 2023 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 http://mozilla.org/MPL/2.0/.
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   // Set physics list
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   // Suppress the printing of physics information.
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 }  // namespace ActsExamples