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("ldmx-sw revision", GIT_SHA1);
117}
118
119void Simulator::onNewRun(const ldmx::RunHeader& runHeader) {
121 getCondition<framework::RandomNumberSeedService>(
123 std::vector<int> seeds;
124 seeds.push_back(rseed.getSeed("Simulator[0]"));
125 seeds.push_back(rseed.getSeed("Simulator[1]"));
126 setSeeds(seeds);
127
128 run_ = runHeader.getRunNumber();
129}
130
132 // Generate and process a Geant4 event.
134 // Save the state of the random engine to an output stream. A string
135 // is then extracted and saved to the event header.
136 std::ostringstream stream;
137 G4Random::saveFullState(stream);
138 runManager_->ProcessOneEvent(event.getEventHeader().getEventNumber());
139
140 // If a Geant4 event has been aborted, skip the rest of the processing
141 // sequence. This will immediately force the simulation to move on to
142 // the next event.
143 if (runManager_->GetCurrentEvent()->IsAborted()) {
144 runManager_->TerminateOneEvent(); // clean up event objects
146 [](auto sd) { sd->OnFinishedEvent(); });
147 this->abortEvent(); // get out of processors loop
148 }
149
150 // Terminate the event. This checks if an event is to be stored or
151 // stacked for later.
153
154 // store event-wide information in EventHeader
155 auto& event_header = event.getEventHeader();
156 updateEventHeader(event_header);
157
158 event_header.setStringParameter("eventSeed", stream.str());
159
160 saveTracks(event);
161
162 saveSDHits(event);
163
164 runManager_->TerminateOneEvent();
165
166 return;
167}
168
171 std::cout << "[ Simulator ] : "
172 << "Started " << numEventsBegan_ << " events to produce "
173 << numEventsCompleted_ << " events." << std::endl;
174}
175
176void Simulator::setSeeds(std::vector<int> seeds) {
177 // If no seeds have been specified then return immediately.
178 if (seeds.empty()) {
179 return;
180 }
181
182 // If seeds are specified, make sure that the container has at least
183 // two seeds. If not, throw an exception.
184 if (seeds.size() == 1) {
185 EXCEPTION_RAISE("ConfigurationException",
186 "At least two seeds need to be specified.");
187 }
188
189 // Create the array of seeds and pass them to G4Random. Currently,
190 // only 100 seeds can be specified at a time. If less than 100
191 // seeds are specified, the remaining slots are set to 0.
192
193 constexpr int max_number_of_seeds{100};
194 std::vector<long> seedVec(max_number_of_seeds, 0);
195 for (std::size_t index{0}; index < seeds.size(); ++index) {
196 seedVec[index] = static_cast<long>(seeds[index]);
197 }
198
199 // Pass the array of seeds to the random engine.
200 G4Random::setTheSeeds(seedVec.data());
201}
202
203} // namespace simcore
204
205DECLARE_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.
void abortEvent()
Abort the event immediately.
Implements an event buffer system for storing event data.
Definition Event.h:41
ldmx::EventHeader & getEventHeader()
Get the event header.
Definition Event.h:58
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:27
T getParameter(const std::string &name) const
Retrieve the parameter of the given name.
Definition Parameters.h:89
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:54
void setFloatParameter(const std::string &name, float value)
Set a float parameter value.
Definition RunHeader.h:189
void setDetectorName(const std::string &det)
Set the name of the detector that was used in this run.
Definition RunHeader.h:80
void setStringParameter(const std::string &name, std::string value)
Set a string parameter value.
Definition RunHeader.h:214
void setDescription(const std::string &des)
Set the description of this run.
Definition RunHeader.h:92
void setIntParameter(const std::string &name, int value)
Set an int parameter value.
Definition RunHeader.h:164
int getRunNumber() const
Definition RunHeader.h:74
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:41
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