LDMX Software
Simulator.cxx
Go to the documentation of this file.
1
8#include "SimCore/Simulator.h"
9
10/*~~~~~~~~~~~~~~~*/
11/* Framework */
12/*~~~~~~~~~~~~~~~*/
13#include "Framework/EventFile.h"
14#include "Framework/Process.h"
16#include "Framework/Version.h" //for LDMX_INSTALL path
17
18/*~~~~~~~~~~~~~*/
19/* SimCore */
20/*~~~~~~~~~~~~~*/
22#include "SimCore/DetectorConstruction.h"
23#include "SimCore/G4Session.h"
25#include "SimCore/Geo/ParserFactory.h"
27#include "SimCore/SensitiveDetector.h"
28#include "SimCore/UserEventInformation.h"
29#include "SimCore/XsecBiasingOperator.h"
30
31/*~~~~~~~~~~~~~~*/
32/* Geant4 */
33/*~~~~~~~~~~~~~~*/
34#include "G4BiasingProcessInterface.hh"
35#include "G4CascadeParameters.hh"
36#include "G4Electron.hh"
37#include "G4GDMLParser.hh"
38#include "G4GeometryManager.hh"
39#include "G4UImanager.hh"
40#include "G4UIsession.hh"
41#include "Randomize.hh"
42
43namespace simcore {
44
45Simulator::Simulator(const std::string& name, framework::Process& process)
46 : simcore::SimulatorBase(name, process) {}
47
51
53 // Get the detector header from the user detector construction
54 DetectorConstruction* detector =
55 dynamic_cast<RunManager*>(RunManager::GetRunManager())
56 ->getDetectorConstruction();
57
58 header.setDetectorName(detector->getDetectorName());
59 header.setDescription(parameters_.getParameter<std::string>("description"));
60 header.setIntParameter(
61 "Included Scoring Planes",
62 !parameters_.getParameter<std::string>("scoringPlanes").empty());
63 header.setIntParameter(
64 "Use Random Seed from Event Header",
65 parameters_.getParameter<bool>("rootPrimaryGenUseSeed"));
66
67 // lambda function for dumping 3-vectors into the run header
68 auto threeVectorDump = [&header](const std::string& name,
69 const std::vector<double>& vec) {
70 header.setFloatParameter(name + " X", vec.at(0));
71 header.setFloatParameter(name + " Y", vec.at(1));
72 header.setFloatParameter(name + " Z", vec.at(2));
73 };
74
75 auto beamSpotSmear{
76 parameters_.getParameter<std::vector<double>>("beamSpotSmear", {})};
77 if (!beamSpotSmear.empty()) {
78 threeVectorDump("Smear Beam Spot [mm]", beamSpotSmear);
79 }
80
81 // lambda function for dumping vectors of strings to the run header
82 auto stringVectorDump = [&header](const std::string& name,
83 const std::vector<std::string>& vec) {
84 int index = 0;
85 for (auto const& val : vec) {
86 header.setStringParameter(name + " " + std::to_string(++index), val);
87 }
88 };
89
90 stringVectorDump("Pre Init Command",
91 parameters_.getParameter<std::vector<std::string>>(
92 "preInitCommands", {}));
93 stringVectorDump("Post Init Command",
94 parameters_.getParameter<std::vector<std::string>>(
95 "postInitCommands", {}));
96
98 [&header](auto bop) { bop->RecordConfig(header); });
99
100 int counter = 0;
101 PrimaryGenerator::Factory::get().apply([&header, &counter](auto gen) {
102 std::string gen_id = "Gen" + std::to_string(counter++);
103 gen->RecordConfig(gen_id, header);
104 });
105
106 // Set a string parameter with the Geant4 SHA-1.
107 if (G4RunManagerKernel::GetRunManagerKernel()) {
108 G4String g4Version{
109 G4RunManagerKernel::GetRunManagerKernel()->GetVersionString()};
110 header.setStringParameter("Geant4 revision", g4Version);
111 } else {
112 ldmx_log(warn) << "Unable to access G4 RunManager Kernel. Will not store "
113 "G4 Version string.";
114 }
115
116 header.setStringParameter("SIM version", LDMXSW_VERSION);
117 header.setStringParameter("SIM revision", GIT_SHA1);
118}
119
120void Simulator::onNewRun(const ldmx::RunHeader& runHeader) {
124 std::vector<int> seeds;
125 seeds.push_back(rseed.getSeed("Simulator[0]"));
126 seeds.push_back(rseed.getSeed("Simulator[1]"));
127 setSeeds(seeds);
128
129 run_ = runHeader.getRunNumber();
130}
131
133 // Generate and process a Geant4 event.
135 // Save the state of the random engine to an output stream. A string
136 // is then extracted and saved to the event header.
137 std::ostringstream stream;
138 G4Random::saveFullState(stream);
139 runManager_->ProcessOneEvent(event.getEventHeader().getEventNumber());
140
141 // If a Geant4 event has been aborted, skip the rest of the processing
142 // sequence. This will immediately force the simulation to move on to
143 // the next event.
144 if (runManager_->GetCurrentEvent()->IsAborted()) {
145 runManager_->TerminateOneEvent(); // clean up event objects
147 [](auto sd) { sd->OnFinishedEvent(); });
148 this->abortEvent(); // get out of processors loop
149 }
150
151 // Terminate the event. This checks if an event is to be stored or
152 // stacked for later.
154
155 // store event-wide information in EventHeader
156 auto& event_header = event.getEventHeader();
157 updateEventHeader(event_header);
158
159 event_header.setStringParameter("eventSeed", stream.str());
160
161 saveTracks(event);
162
163 saveSDHits(event);
164
165 runManager_->TerminateOneEvent();
166
167 return;
168}
169
172 std::cout << "[ Simulator ] : "
173 << "Started " << numEventsBegan_ << " events to produce "
174 << numEventsCompleted_ << " events." << std::endl;
175}
176
177void Simulator::setSeeds(std::vector<int> seeds) {
178 // If no seeds have been specified then return immediately.
179 if (seeds.empty()) {
180 return;
181 }
182
183 // If seeds are specified, make sure that the container has at least
184 // two seeds. If not, throw an exception.
185 if (seeds.size() == 1) {
186 EXCEPTION_RAISE("ConfigurationException",
187 "At least two seeds need to be specified.");
188 }
189
190 // Create the array of seeds and pass them to G4Random. Currently,
191 // only 100 seeds can be specified at a time. If less than 100
192 // seeds are specified, the remaining slots are set to 0.
193
194 constexpr int max_number_of_seeds{100};
195 std::vector<long> seedVec(max_number_of_seeds, 0);
196 for (std::size_t index{0}; index < seeds.size(); ++index) {
197 seedVec[index] = static_cast<long>(seeds[index]);
198 }
199
200 // Pass the array of seeds to the random engine.
201 G4Random::setTheSeeds(seedVec.data());
202}
203
204} // namespace simcore
205
206DECLARE_PRODUCER_NS(simcore, Simulator)
Class which defines basic APrime physics.
#define DECLARE_PRODUCER_NS(NS, CLASS)
Macro which allows the framework to construct a producer given its name during configuration.
Classes which redirect the output of G4cout and G4cerr.
Header file for PrimaryGenerator.
Class which represents the process under execution.
Conditions object for random number seeds.
Run the G4 simulation inside of ldmx-app.
Class which implements the user tracking action.
const T & getCondition(const std::string &condition_name)
Access a conditions object for the current event.
void abortEvent()
Abort the event immediately.
Implements an event buffer system for storing event data.
Definition Event.h:42
ldmx::EventHeader & getEventHeader()
Get the event header.
Definition Event.h:59
Class which represents the process under execution.
Definition Process.h:36
System for consistent seeding of random number generators.
static const std::string CONDITIONS_OBJECT_NAME
Conditions object name.
uint64_t getSeed(const std::string &name) const
Access a given seed by name.
Class encapsulating parameters for configuring a processor.
Definition Parameters.h:29
int getEventNumber() const
Return the event number.
Definition EventHeader.h:78
Run-specific configuration and data stored in its own output TTree alongside the event TTree in the o...
Definition RunHeader.h:57
void setFloatParameter(const std::string &name, float value)
Set a float parameter value.
Definition RunHeader.h:197
void setDetectorName(const std::string &det)
Set the name of the detector that was used in this run.
Definition RunHeader.h:83
void setStringParameter(const std::string &name, std::string value)
Set a string parameter value.
Definition RunHeader.h:222
void setDescription(const std::string &des)
Set the description of this run.
Definition RunHeader.h:100
void setIntParameter(const std::string &name, int value)
Set an int parameter value.
Definition RunHeader.h:172
int getRunNumber() const
Definition RunHeader.h:77
Implements the Geant4 detector construction.
void apply(UnaryFunction f) const
Apply the input UnaryFunction to each entry in the inventory.
Definition Factory.h:283
static Factory & get()
get the factory instance
Definition Factory.h:217
Extension of Geant4 run manager.
Definition RunManager.h:42
std::unique_ptr< RunManager > runManager_
Manager controlling G4 simulation run.
void configure(framework::config::Parameters &parameters) override
Callback for the EventProcessor to configure itself from the given set of parameters.
void onProcessEnd() override
Callback called once processing is complete.
framework::config::Parameters parameters_
The parameters used to configure the simulation.
void configure(framework::config::Parameters &parameters) override
Callback for the processor to configure itself from the given set of parameters.
Definition Simulator.cxx:48
Simulator(const std::string &name, framework::Process &process)
Constructor.
Definition Simulator.cxx:45
void beforeNewRun(ldmx::RunHeader &header) override
Given a non-const reference to the new RunHeader, we can add parameters from the simulation here befo...
Definition Simulator.cxx:52
void setSeeds(std::vector< int > seeds)
Set the seeds to be used by the Geant4 random engine.
void onNewRun(const ldmx::RunHeader &header) override
Before the run starts (but after the conditions are configured) set up the random seeds for this run.
int numEventsBegan_
Number of events started.
Definition Simulator.h:113
virtual void produce(framework::Event &event) override
Run simulation and export results to output event.
int numEventsCompleted_
Number of events completed.
Definition Simulator.h:116
void onProcessEnd() override
Callback called once processing is complete.
int run_
the run number (for accessing the run header in onFileClose
Definition Simulator.h:119