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"
16#include "SimCore/FCPPhysics.h"
18#include "SimCore/G4User/RunAction.h"
19#include "SimCore/G4User/StackingAction.h"
20#include "SimCore/G4User/SteppingAction.h"
23#include "SimCore/GenieElectroNuclearProcess.h" //for process name
25#include "SimCore/ParallelWorld.h"
27
28//------------//
29// Geant4 //
30//------------//
31#include "FTFP_BERT.hh"
32#include "G4GDMLParser.hh"
33#include "G4GenericBiasingPhysics.hh"
34#include "G4ParallelWorldPhysics.hh"
35#include "G4ProcessTable.hh"
36#include "G4VModularPhysicsList.hh"
37
38namespace simcore {
39
42 parameters_ = parameters;
43
44 // Set whether the ROOT primary generator should use the persisted seed.
45 auto root_primary_gen_use_seed{
46 parameters.get<bool>("root_primary_gen_use_seed")};
47
48 // Validate the geometry if specified.
49 setUseRootSeed(root_primary_gen_use_seed);
50}
51
53 auto p_list{physics_list_factory_.GetReferencePhysList("FTFP_BERT")};
54 p_list->SetVerboseLevel(0);
55
56 parallel_world_path_ = parameters_.get<std::string>("scoring_planes");
58 if (is_pw_enabled_) {
59 ldmx_log(debug) << "Parallel worlds physics list has been registered";
60 p_list->RegisterPhysics(new G4ParallelWorldPhysics("ldmxParallelWorld"));
61 }
62
63 p_list->RegisterPhysics(new GammaPhysics{"GammaPhysics", parameters_});
64 p_list->RegisterPhysics(new APrimePhysics(
66 p_list->RegisterPhysics(new KaonPhysics(
67 "KaonPhysics",
68 parameters_.get<framework::config::Parameters>("kaon_parameters")));
69 p_list->RegisterPhysics(new FCPPhysics(
70 "FCPPhysics",
72 p_list->RegisterPhysics(new GenieNuclearPhysics(
74
75 auto biasing_operators{
76 parameters_.get<std::vector<framework::config::Parameters>>(
77 "biasing_operators", {})};
78 if (!biasing_operators.empty()) {
79 ldmx_log(info) << " Biasing enabled with " << biasing_operators.size()
80 << " operator(s)";
81
82 // create all the biasing operators that will be used
83 for (framework::config::Parameters& bop : biasing_operators) {
84 if (not simcore::XsecBiasingOperator::Factory::get().make(
85 bop.get<std::string>("class_name"),
86 bop.get<std::string>("instance_name"), bop)) {
87 EXCEPTION_RAISE("UnableToCreate",
88 "Unable to create a XsecBiasingOperator of type " +
89 bop.get<std::string>("class_name"));
90 }
91 }
92
93 // Instantiate the constructor used when biasing
94 G4GenericBiasingPhysics* biasing_physics = new G4GenericBiasingPhysics();
95
96 // specify which particles are going to be biased
97 // this will put a biasing interface wrapper around *all* processes
98 // associated with these particles
99 simcore::XsecBiasingOperator::Factory::get().apply(
100 [this, biasing_physics](auto bop) {
101 ldmx_log(info) << "Biasing operator '" << bop->GetName()
102 << "' set to bias " << bop->getParticleToBias();
103 biasing_physics->Bias(bop->getParticleToBias());
104 });
105
106 // Register the physics constructor to the physics list:
107 p_list->RegisterPhysics(biasing_physics);
108 }
109
110 this->SetUserInitialization(p_list);
111}
112
114 setupPhysics();
115
116 // The parallel world needs to be registered before the mass world is
117 // constructed i.e. before G4RunManager::Initialize() is called.
118 if (is_pw_enabled_) {
119 ldmx_log(debug) << "Parallel worlds have been enabled";
120
121 auto validate_geometry{parameters_.get<bool>("validate_detector")};
122 G4GDMLParser* pw_parser = new G4GDMLParser();
123 pw_parser->Read(parallel_world_path_, validate_geometry);
124 this->getDetectorConstruction()->RegisterParallelWorld(
125 new ParallelWorld(pw_parser, "ldmxParallelWorld"));
126 }
127
128 // This is where the physics lists are told to construct their particles and
129 // their processes
130 // They are constructed in order, so it is important to register the biasing
131 // physics *after* any other processes that need to be able to be biased
132 G4RunManager::Initialize();
133
134 // create our G4User actions
135 auto primary_action{new PrimaryGeneratorAction(parameters_)};
136 auto run_action{new g4user::RunAction};
137 auto event_action{new g4user::EventAction};
138 auto tracking_action{new g4user::TrackingAction};
139 auto stepping_action{new g4user::SteppingAction};
140 auto stacking_action{new g4user::StackingAction};
141 // ...and register them with G4
142 SetUserAction(primary_action);
143 SetUserAction(run_action);
144 SetUserAction(event_action);
145 SetUserAction(tracking_action);
146 SetUserAction(stepping_action);
147 SetUserAction(stacking_action);
148
149 // Create all user actions and attch them to the corresponding G4 actions
150 auto user_actions{parameters_.get<std::vector<framework::config::Parameters>>(
151 "actions", {})};
152 for (auto& user_action : user_actions) {
153 auto ua = UserAction::Factory::get().make(
154 user_action.get<std::string>("class_name"),
155 user_action.get<std::string>("instance_name"), user_action);
156 if (not ua) {
157 EXCEPTION_RAISE(
158 "UnableToCreate",
159 "Unable to create a UserAction of type " +
160 user_action.get<std::string>("class_name") +
161 ". Did you inherit from simcore::UserAction? "
162 "Do you have DECLARE_ACTION in your implementation (.cxx) file? "
163 "Did you include the fully-specified class name in your python "
164 "configuration class? "
165 "Did you specify the correct library in the python configuration "
166 "class?");
167 }
168 for (auto& type : ua.value()->getTypes()) {
169 if (type == simcore::TYPE::RUN) {
170 run_action->registerAction(ua.value());
171 } else if (type == simcore::TYPE::EVENT) {
172 event_action->registerAction(ua.value());
173 } else if (type == simcore::TYPE::TRACKING) {
174 tracking_action->registerAction(ua.value());
175 } else if (type == simcore::TYPE::STEPPING) {
176 stepping_action->registerAction(ua.value());
177 } else if (type == simcore::TYPE::STACKING) {
178 stacking_action->registerAction(ua.value());
179 } else {
180 EXCEPTION_RAISE("ActionType", "Action type does not exist.");
181 }
182 }
183 }
184}
185
187 // have geant4 do its own thing
188 G4RunManager::TerminateOneEvent();
189
190 // A process may deactivate itself after firing so that it only happens once
191 // per event (dark brem and GENIE electronNuclear both do this). At most one
192 // of them is present in a given run, so find whichever it is, reactivate it
193 // so it can fire again next event, and stop. This covers both cases where the
194 // process is biased and not.
195 G4ProcessManager* pman = G4Electron::Definition()->GetProcessManager();
196 for (int i_proc{0}; i_proc < pman->GetProcessList()->size(); i_proc++) {
197 G4VProcess* p{(*(pman->GetProcessList()))[i_proc]};
198 if (p->GetProcessName().contains(G4DarkBremsstrahlung::PROCESS_NAME) or
199 p->GetProcessName().contains(
201 pman->SetProcessActivation(p, true);
202 break;
203 }
204 }
205}
206
208 return static_cast<DetectorConstruction*>(this->userDetector);
209}
210
211} // namespace simcore
Class which defines basic APrime physics.
Class which implements the Geant4 user event action.
Physics constructor for fractionally charged particle (FCP) processes.
Class used to enhanced the gamma physics list.
G4VDiscreteProcess that uses GENIE to simulate electronuclear interactions as the electron traverses ...
G4VPhysicsConstructor that registers the GENIE electronuclear process with the electron.
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.
Physics constructor for fractionally charged particles.
Definition FCPPhysics.h:32
extra gamma particle physics for simulation and sets up the photonuclear model to use from the config...
static const std::string PROCESS_NAME
Process name — matches the built-in so the bias operator works unchanged.
Physics constructor that replaces the built-in Geant4 electronNuclear process with the GENIE-based Ge...
Allows the configuration of properties of kaons produced in the simulation, in particular setting the...
Definition KaonPhysics.h:32
Implementation of Geant4 primary generator action.
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 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 ...