LDMX Software
Simulator.cxx
Go to the documentation of this file.
1
8#include "SimCore/Simulator.h"
9
10namespace simcore {
11
12Simulator::Simulator(const std::string& name, framework::Process& process)
13 : simcore::SimulatorBase(name, process) {}
14
18
20 // Get the detector header from the user detector construction
21 DetectorConstruction* detector =
22 dynamic_cast<RunManager*>(RunManager::GetRunManager())
23 ->getDetectorConstruction();
24
25 header.setDetectorName(detector->getDetectorName());
26 header.setDescription(parameters_.get<std::string>("description"));
27 header.setIntParameter(
28 "Included Scoring Planes",
29 !parameters_.get<std::string>("scoringPlanes").empty());
30 header.setIntParameter("Use Random Seed from Event Header",
31 parameters_.get<bool>("rootPrimaryGenUseSeed"));
32
33 // lambda function for dumping 3-vectors into the run header
34 auto three_vector_dump = [&header](const std::string& name,
35 const std::vector<double>& vec) {
36 header.setFloatParameter(name + " X", vec.at(0));
37 header.setFloatParameter(name + " Y", vec.at(1));
38 header.setFloatParameter(name + " Z", vec.at(2));
39 };
40
41 auto beam_spot_smear{
42 parameters_.get<std::vector<double>>("beamSpotSmear", {})};
43 if (!beam_spot_smear.empty()) {
44 three_vector_dump("Smear Beam Spot [mm]", beam_spot_smear);
45 }
46
47 // lambda function for dumping vectors of strings to the run header
48 auto string_vector_dump = [&header](const std::string& name,
49 const std::vector<std::string>& vec) {
50 int index = 0;
51 for (auto const& val : vec) {
52 header.setStringParameter(name + " " + std::to_string(++index), val);
53 }
54 };
55
56 string_vector_dump(
57 "Pre Init Command",
58 parameters_.get<std::vector<std::string>>("preInitCommands", {}));
59 string_vector_dump(
60 "Post Init Command",
61 parameters_.get<std::vector<std::string>>("postInitCommands", {}));
62
63 simcore::XsecBiasingOperator::Factory::get().apply(
64 [&header](auto bop) { bop->RecordConfig(header); });
65
66 int counter = 0;
67 PrimaryGenerator::Factory::get().apply([&header, &counter](auto gen) {
68 std::string gen_id = "Gen" + std::to_string(counter++);
69 gen->RecordConfig(gen_id, header);
70 });
71
72 // Set a string parameter with the Geant4 SHA-1.
73 if (G4RunManagerKernel::GetRunManagerKernel()) {
74 G4String g4_version{
75 G4RunManagerKernel::GetRunManagerKernel()->GetVersionString()};
76 header.setStringParameter("Geant4 revision", g4_version);
77 } else {
78 ldmx_log(warn) << "Unable to access G4 RunManager Kernel. Will not store "
79 "G4 Version string.";
80 }
81
82 header.setStringParameter("SIM version", LDMXSW_VERSION);
83 header.setStringParameter("SIM revision", GIT_SHA1);
84}
85
86void Simulator::onNewRun(const ldmx::RunHeader& runHeader) {
90 std::vector<int> seeds;
91 seeds.push_back(rseed.getSeed("Simulator[0]"));
92 seeds.push_back(rseed.getSeed("Simulator[1]"));
93 setSeeds(seeds);
94
95 run_ = runHeader.getRunNumber();
96}
97
99 // Generate and process a Geant4 event.
101 // Save the state of the random engine to an output stream. A string
102 // is then extracted and saved to the event header.
103 std::ostringstream stream;
104 G4Random::saveFullState(stream);
105 run_manager_->ProcessOneEvent(event.getEventHeader().getEventNumber());
106
107 // If a Geant4 event has been aborted, skip the rest of the processing
108 // sequence. This will immediately force the simulation to move on to
109 // the next event.
110 if (run_manager_->GetCurrentEvent()->IsAborted()) {
111 run_manager_->TerminateOneEvent(); // clean up event objects
112 SensitiveDetector::Factory::get().apply(
113 [](auto sd) { sd->onFinishedEvent(); });
114 this->abortEvent(); // get out of processors loop
115 }
116
117 // Terminate the event. This checks if an event is to be stored or
118 // stacked for later.
120
121 // store event-wide information in EventHeader
122 auto& event_header = event.getEventHeader();
123 updateEventHeader(event_header);
124
125 event_header.setStringParameter("eventSeed", stream.str());
126
127 auto event_info = static_cast<UserEventInformation*>(
128 run_manager_->GetCurrentEvent()->GetUserInformation());
129
130 auto hepmc3_events = event_info->getHepMC3GenEvents();
131 for (auto& hepmc3ev : hepmc3_events) {
132 hepmc3ev.event_number = event.getEventHeader().getEventNumber();
133 }
134 if (hepmc3_events.size() > 0) event.add("SimHepMC3Events", hepmc3_events);
135
136 saveTracks(event);
137
138 saveSDHits(event);
139
140 run_manager_->TerminateOneEvent();
141
142 return;
143}
144
147 // Put this to warn level, just so it's printed out for sure
148 ldmx_log(warn) << "Started " << num_events_began_ << " events to produce "
149 << num_events_completed_ << " events.";
150}
151
152void Simulator::setSeeds(std::vector<int> seeds) {
153 // If no seeds have been specified then return immediately.
154 if (seeds.empty()) {
155 return;
156 }
157
158 // If seeds are specified, make sure that the container has at least
159 // two seeds. If not, throw an exception.
160 if (seeds.size() == 1) {
161 EXCEPTION_RAISE("ConfigurationException",
162 "At least two seeds need to be specified.");
163 }
164
165 // Create the array of seeds and pass them to G4Random. Currently,
166 // only 100 seeds can be specified at a time. If less than 100
167 // seeds are specified, the remaining slots are set to 0.
168
169 constexpr int max_number_of_seeds{100};
170 std::vector<long> seed_vec(max_number_of_seeds, 0);
171 for (std::size_t index{0}; index < seeds.size(); ++index) {
172 seed_vec[index] = static_cast<long>(seeds[index]);
173 }
174
175 // Pass the array of seeds to the random engine.
176 G4Random::setTheSeeds(seed_vec.data());
177}
178
179} // namespace simcore
180
#define DECLARE_PRODUCER(CLASS)
Macro which allows the framework to construct a producer given its name during configuration.
Run the G4 simulation inside of ldmx-app.
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
const T & get(const std::string &name) const
Retrieve the parameter of the given name.
Definition Parameters.h:78
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.
Extension of Geant4 run manager.
Definition RunManager.h:42
std::unique_ptr< RunManager > run_manager_
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.
Producer that runs Geant4 simulation inside of ldmx-app.
Definition Simulator.h:87
void configure(framework::config::Parameters &parameters) override
Callback for the processor to configure itself from the given set of parameters.
Definition Simulator.cxx:15
Simulator(const std::string &name, framework::Process &process)
Constructor.
Definition Simulator.cxx:12
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:19
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.
Definition Simulator.cxx:86
virtual void produce(framework::Event &event) override
Run simulation and export results to output event.
Definition Simulator.cxx:98
int num_events_began_
Number of events started.
Definition Simulator.h:154
void onProcessEnd() override
Callback called once processing is complete.
int run_
the run number (for accessing the run header in onFileClose
Definition Simulator.h:160
int num_events_completed_
Number of events completed.
Definition Simulator.h:157
Encapsulates user defined information associated with a Geant4 event.
Dynamically loadable photonuclear models either from SimCore or external libraries implementing this ...