LDMX Software
RunManager.cxx
Go to the documentation of this file.
1
8
9//-------------//
10// ldmx-sw //
11//-------------//
12#include "G4DarkBreM/G4DarkBremsstrahlung.h" //for process name
14#include "SimCore/BiasOperators/XsecBiasingOperator.h"
15#include "SimCore/DetectorConstruction.h"
18#include "SimCore/G4User/RunAction.h"
19#include "SimCore/G4User/StackingAction.h"
20#include "SimCore/G4User/SteppingAction.h"
23#include "SimCore/ParallelWorld.h"
24
25//------------//
26// Geant4 //
27//------------//
28#include "FTFP_BERT.hh"
29#include "G4GDMLParser.hh"
30#include "G4GenericBiasingPhysics.hh"
31#include "G4ParallelWorldPhysics.hh"
32#include "G4ProcessTable.hh"
33#include "G4VModularPhysicsList.hh"
34
35namespace simcore {
36
39 parameters_ = parameters;
40
41 // Set whether the ROOT primary generator should use the persisted seed.
42 auto root_primary_gen_use_seed{parameters.get<bool>("rootPrimaryGenUseSeed")};
43
44 // Validate the geometry if specified.
45 setUseRootSeed(root_primary_gen_use_seed);
46}
47
49 auto p_list{physics_list_factory_.GetReferencePhysList("FTFP_BERT")};
50 p_list->SetVerboseLevel(0);
51
52 parallel_world_path_ = parameters_.get<std::string>("scoringPlanes");
54 if (is_pw_enabled_) {
55 ldmx_log(debug) << "Parallel worlds physics list has been registered";
56 p_list->RegisterPhysics(new G4ParallelWorldPhysics("ldmxParallelWorld"));
57 }
58
59 p_list->RegisterPhysics(new GammaPhysics{"GammaPhysics", parameters_});
60 p_list->RegisterPhysics(new APrimePhysics(
62 p_list->RegisterPhysics(new KaonPhysics(
63 "KaonPhysics",
64 parameters_.get<framework::config::Parameters>("kaon_parameters")));
65
66 auto biasing_operators{
67 parameters_.get<std::vector<framework::config::Parameters>>(
68 "biasing_operators", {})};
69 if (!biasing_operators.empty()) {
70 ldmx_log(info) << " Biasing enabled with " << biasing_operators.size()
71 << " operator(s)";
72
73 // create all the biasing operators that will be used
74 for (framework::config::Parameters& bop : biasing_operators) {
75 if (not simcore::XsecBiasingOperator::Factory::get().make(
76 bop.get<std::string>("class_name"),
77 bop.get<std::string>("instance_name"), bop)) {
78 EXCEPTION_RAISE("UnableToCreate",
79 "Unable to create a XsecBiasingOperator of type " +
80 bop.get<std::string>("class_name"));
81 }
82 }
83
84 // Instantiate the constructor used when biasing
85 G4GenericBiasingPhysics* biasing_physics = new G4GenericBiasingPhysics();
86
87 // specify which particles are going to be biased
88 // this will put a biasing interface wrapper around *all* processes
89 // associated with these particles
90 simcore::XsecBiasingOperator::Factory::get().apply(
91 [this, biasing_physics](auto bop) {
92 ldmx_log(info) << "Biasing operator '" << bop->GetName()
93 << "' set to bias " << bop->getParticleToBias();
94 biasing_physics->Bias(bop->getParticleToBias());
95 });
96
97 // Register the physics constructor to the physics list:
98 p_list->RegisterPhysics(biasing_physics);
99 }
100
101 this->SetUserInitialization(p_list);
102}
103
105 setupPhysics();
106
107 // The parallel world needs to be registered before the mass world is
108 // constructed i.e. before G4RunManager::Initialize() is called.
109 if (is_pw_enabled_) {
110 ldmx_log(debug) << "Parallel worlds have been enabled";
111
112 auto validate_geometry{parameters_.get<bool>("validate_detector")};
113 G4GDMLParser* pw_parser = new G4GDMLParser();
114 pw_parser->Read(parallel_world_path_, validate_geometry);
115 this->getDetectorConstruction()->RegisterParallelWorld(
116 new ParallelWorld(pw_parser, "ldmxParallelWorld"));
117 }
118
119 // This is where the physics lists are told to construct their particles and
120 // their processes
121 // They are constructed in order, so it is important to register the biasing
122 // physics *after* any other processes that need to be able to be biased
123 G4RunManager::Initialize();
124
125 // create our G4User actions
126 auto primary_action{new g4user::PrimaryGeneratorAction(parameters_)};
127 auto run_action{new g4user::RunAction};
128 auto event_action{new g4user::EventAction};
129 auto tracking_action{new g4user::TrackingAction};
130 auto stepping_action{new g4user::SteppingAction};
131 auto stacking_action{new g4user::StackingAction};
132 // ...and register them with G4
133 SetUserAction(primary_action);
134 SetUserAction(run_action);
135 SetUserAction(event_action);
136 SetUserAction(tracking_action);
137 SetUserAction(stepping_action);
138 SetUserAction(stacking_action);
139
140 // Create all user actions and attch them to the corresponding G4 actions
141 auto user_actions{parameters_.get<std::vector<framework::config::Parameters>>(
142 "actions", {})};
143 for (auto& user_action : user_actions) {
144 auto ua = UserAction::Factory::get().make(
145 user_action.get<std::string>("class_name"),
146 user_action.get<std::string>("instance_name"), user_action);
147 if (not ua) {
148 EXCEPTION_RAISE(
149 "UnableToCreate",
150 "Unable to create a UserAction of type " +
151 user_action.get<std::string>("class_name") +
152 ". Did you inherit from simcore::UserAction? "
153 "Do you have DECLARE_ACTION in your implementation (.cxx) file? "
154 "Did you include the fully-specified class name in your python "
155 "configuration class? "
156 "Did you specify the correct library in the python configuration "
157 "class?");
158 }
159 for (auto& type : ua.value()->getTypes()) {
160 if (type == simcore::TYPE::RUN) {
161 run_action->registerAction(ua.value());
162 } else if (type == simcore::TYPE::EVENT) {
163 event_action->registerAction(ua.value());
164 } else if (type == simcore::TYPE::TRACKING) {
165 tracking_action->registerAction(ua.value());
166 } else if (type == simcore::TYPE::STEPPING) {
167 stepping_action->registerAction(ua.value());
168 } else if (type == simcore::TYPE::STACKING) {
169 stacking_action->registerAction(ua.value());
170 } else {
171 EXCEPTION_RAISE("ActionType", "Action type does not exist.");
172 }
173 }
174 }
175}
176
178 // have geant4 do its own thing
179 G4RunManager::TerminateOneEvent();
180
181 // go through the processes attached to the electron and
182 // reactivate any process that contains the G4DarkBremmstrahlung name
183 // this covers both cases where the process is biased and not
184 static auto reactivate_dark_brem = [](G4ProcessManager* pman) {
185 for (int i_proc{0}; i_proc < pman->GetProcessList()->size(); i_proc++) {
186 G4VProcess* p{(*(pman->GetProcessList()))[i_proc]};
187 if (p->GetProcessName().contains(G4DarkBremsstrahlung::PROCESS_NAME)) {
188 pman->SetProcessActivation(p, true);
189 break;
190 }
191 }
192 };
193
194 reactivate_dark_brem(G4Electron::Definition()->GetProcessManager());
195 ldmx_log(debug) << "Reset the dark brem process (if it was activated)";
196}
197
199 return static_cast<DetectorConstruction*>(this->userDetector);
200}
201
202} // namespace simcore
Class which defines basic APrime physics.
Class which implements the Geant4 user event action.
Class used to enhanced the gamma physics list.
Class implementing the Geant4 primary generator action.
Class providing a Geant4 run manager implementation.
Class which implements the user tracking action.
Class encapsulating parameters for configuring a processor.
Definition Parameters.h:29
const T & get(const std::string &name) const
Retrieve the parameter of the given name.
Definition Parameters.h:78
Defines basic APrime physics.
Handle to the conditions system, provided at construction to classes which require it.
Implements the Geant4 detector construction.
extra gamma particle physics for simulation and sets up the photonuclear model to use from the config...
Allows the configuration of properties of kaons produced in the simulation, in particular setting the...
Definition KaonPhysics.h:32
std::string parallel_world_path_
Path to GDML description of parallel world.
Definition RunManager.h:105
framework::config::Parameters parameters_
The set of parameters used to configure the RunManager.
Definition RunManager.h:91
void TerminateOneEvent()
Called at the end of each event.
void setupPhysics()
Initialize physics.
void setUseRootSeed(bool useIt=true)
Tell RunManager to use the seed from the root file.
Definition RunManager.h:82
bool is_pw_enabled_
Flag indicating whether a parallel world should be registered.
Definition RunManager.h:102
void Initialize()
Perform application initialization.
DetectorConstruction * getDetectorConstruction()
Get the user detector construction cast to a specific type.
G4PhysListFactory physics_list_factory_
Factory class for instantiating the physics list.
Definition RunManager.h:96
RunManager(framework::config::Parameters &parameters, ConditionsInterface &)
Class constructor.
Implementation of user event action hook.
Definition EventAction.h:44
Implementation of Geant4 primary generator action.
Implementation of user run action hook.
Definition RunAction.h:34
Class implementing a user stacking action.
Implements the Geant4 user stepping action.
Implementation of user tracking action.
Dynamically loadable photonuclear models either from SimCore or external libraries implementing this ...