LDMX Software
simcore::Simulator Class Reference

Producer that runs Geant4 simulation inside of ldmx-app. More...

#include <Simulator.h>

Public Member Functions

 Simulator (const std::string &name, framework::Process &process)
 Constructor.
 
virtual ~Simulator ()=default
 Destructor.
 
void configure (framework::config::Parameters &parameters) override
 Callback for the processor to configure itself from the given set of parameters.
 
void beforeNewRun (ldmx::RunHeader &header) override
 Given a non-const reference to the new RunHeader, we can add parameters from the simulation here before the run starts.
 
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.
 
virtual void produce (framework::Event &event) override
 Run simulation and export results to output event.
 
void onProcessEnd () override
 Callback called once processing is complete.
 
- Public Member Functions inherited from simcore::SimulatorBase
 SimulatorBase (const std::string &name, framework::Process &process)
 
void configure (framework::config::Parameters &parameters) override
 Callback for the EventProcessor to configure itself from the given set of parameters.
 
- Public Member Functions inherited from framework::Producer
 Producer (const std::string &name, Process &process)
 Class constructor.
 
virtual void process (Event &event) final
 Processing an event for a Producer is calling produce.
 
- Public Member Functions inherited from framework::EventProcessor
 DECLARE_FACTORY (EventProcessor, EventProcessor *, const std::string &, Process &)
 declare that we have a factory for this class
 
 EventProcessor (const std::string &name, Process &process)
 Class constructor.
 
virtual ~EventProcessor ()=default
 Class destructor.
 
virtual void onFileOpen (EventFile &event_file)
 Callback for the EventProcessor to take any necessary action when a new event input ROOT file is opened.
 
virtual void onFileClose (EventFile &event_file)
 Callback for the EventProcessor to take any necessary action when a event input ROOT file is closed.
 
template<class T >
const T & getCondition (const std::string &condition_name)
 Access a conditions object for the current event.
 
TDirectory * getHistoDirectory ()
 Access/create a directory in the histogram file for this event processor to create histograms and analysis tuples.
 
void setStorageHint (framework::StorageControl::Hint hint)
 Mark the current event as having the given storage control hint from this module_.
 
void setStorageHint (framework::StorageControl::Hint hint, const std::string &purposeString)
 Mark the current event as having the given storage control hint from this module and the given purpose string.
 
int getLogFrequency () const
 Get the current logging frequency from the process.
 
int getRunNumber () const
 Get the run number from the process.
 
std::string getName () const
 Get the processor name.
 
void createHistograms (const std::vector< framework::config::Parameters > &histos)
 Internal function which is used to create histograms passed from the python configuration @parma histos vector of Parameters that configure histograms to create.
 

Private Member Functions

void setSeeds (std::vector< int > seeds)
 Set the seeds to be used by the Geant4 random engine.
 

Private Attributes

int num_events_began_ {0}
 Number of events started.
 
int num_events_completed_ {0}
 Number of events completed.
 
int run_ {-1}
 the run number (for accessing the run header in onFileClose
 

Additional Inherited Members

- Protected Member Functions inherited from simcore::SimulatorBase
void onProcessEnd () override
 Callback called once processing is complete.
 
void onProcessStart () override
 Initialization of simulation.
 
virtual void prepEvent (framework::Event &event)
 prepare a new event before entering into the Geant4 simulation
 
virtual void updateEventHeader (ldmx::EventHeader &eventHeader) const
 
virtual void saveTracks (framework::Event &event)
 
virtual void saveSDHits (framework::Event &event)
 
virtual void savePhotonuclearInteractions (framework::Event &event)
 
- Protected Member Functions inherited from framework::EventProcessor
void abortEvent ()
 Abort the event immediately.
 
- Protected Attributes inherited from simcore::SimulatorBase
ConditionsInterface conditions_intf_
 Conditions interface.
 
G4UImanager * ui_manager_ {nullptr}
 User interface handle.
 
std::unique_ptr< RunManager > run_manager_
 Manager controlling G4 simulation run.
 
std::unique_ptr< LoggedSession > session_handle_
 Handle to the G4Session -> how to deal with G4cout and G4cerr.
 
framework::config::Parameters parameters_
 The parameters used to configure the simulation.
 
std::vector< std::string > pre_init_commands_
 
std::vector< std::string > post_init_commands_
 
- Protected Attributes inherited from framework::EventProcessor
HistogramPool histograms_
 helper object for making and filling histograms
 
NtupleManager & ntuple_ {NtupleManager::getInstance()}
 Manager for any ntuples.
 
logging::logger the_log_
 The logger for this EventProcessor.
 
- Static Protected Attributes inherited from simcore::SimulatorBase
static const std::vector< std::string > INVALID_COMMANDS
 Commands not allowed to be passed from python config file This is because Simulator already runs them.
 

Detailed Description

Producer that runs Geant4 simulation inside of ldmx-app.

Most (if not all) of the heavy lifting is done in the classes in the Sim* modules. This producer is mainly focused on calling appropriate functions at the right time in the processing chain.

Definition at line 62 of file Simulator.h.

Constructor & Destructor Documentation

◆ Simulator()

simcore::Simulator::Simulator ( const std::string & name,
framework::Process & process )

Constructor.

Blank Producer constructor Constructs object that are non-configurable.

Parameters
nameName for this instance of the class.
processThe Process class assocaited with EventProcessor, provided by the Framework.

Definition at line 27 of file Simulator.cxx.

virtual void process(Event &event) final
Processing an event for a Producer is calling produce.

Member Function Documentation

◆ beforeNewRun()

void simcore::Simulator::beforeNewRun ( ldmx::RunHeader & header)
overridevirtual

Given a non-const reference to the new RunHeader, we can add parameters from the simulation here before the run starts.

Parameters
headerof new run

Reimplemented from framework::EventProcessor.

Definition at line 34 of file Simulator.cxx.

34 {
35 // Get the detector header from the user detector construction
36 DetectorConstruction* detector =
37 dynamic_cast<RunManager*>(RunManager::GetRunManager())
38 ->getDetectorConstruction();
39
40 header.setDetectorName(detector->getDetectorName());
41 header.setDescription(parameters_.get<std::string>("description"));
42 header.setIntParameter(
43 "Included Scoring Planes",
44 !parameters_.get<std::string>("scoring_planes").empty());
45 header.setIntParameter("Use Random Seed from Event Header",
46 parameters_.get<bool>("root_primary_gen_use_seed"));
47
48 // lambda function for dumping 3-vectors into the run header
49 auto three_vector_dump = [&header](const std::string& name,
50 const std::vector<double>& vec) {
51 header.setFloatParameter(name + " X", vec.at(0));
52 header.setFloatParameter(name + " Y", vec.at(1));
53 header.setFloatParameter(name + " Z", vec.at(2));
54 };
55
56 auto beam_spot_smear{
57 parameters_.get<std::vector<double>>("beamSpotSmear", {})};
58 if (!beam_spot_smear.empty()) {
59 three_vector_dump("Smear Beam Spot [mm]", beam_spot_smear);
60 }
61
62 // lambda function for dumping vectors of strings to the run header
63 auto string_vector_dump = [&header](const std::string& name,
64 const std::vector<std::string>& vec) {
65 int index = 0;
66 for (auto const& val : vec) {
67 header.setStringParameter(name + " " + std::to_string(++index), val);
68 }
69 };
70
71 string_vector_dump(
72 "Pre Init Command",
73 parameters_.get<std::vector<std::string>>("pre_init_commands", {}));
74 string_vector_dump(
75 "Post Init Command",
76 parameters_.get<std::vector<std::string>>("post_init_commands", {}));
77
78 simcore::XsecBiasingOperator::Factory::get().apply(
79 [&header](auto bop) { bop->RecordConfig(header); });
80
81 int counter = 0;
82 PrimaryGenerator::Factory::get().apply([&header, &counter](auto gen) {
83 std::string gen_id = "Gen" + std::to_string(counter++);
84 gen->RecordConfig(gen_id, header);
85 });
86
87 // Set a string parameter with the Geant4 SHA-1.
88 if (G4RunManagerKernel::GetRunManagerKernel()) {
89 G4String g4_version{
90 G4RunManagerKernel::GetRunManagerKernel()->GetVersionString()};
91 header.setStringParameter("Geant4 revision", g4_version);
92 } else {
93 ldmx_log(warn) << "Unable to access G4 RunManager Kernel. Will not store "
94 "G4 Version string.";
95 }
96
97 header.setStringParameter("SIM version", LDMXSW_VERSION);
98 header.setStringParameter("SIM revision", GIT_SHA1);
99}
const T & get(const std::string &name) const
Retrieve the parameter of the given name.
Definition Parameters.h:75
void setFloatParameter(const std::string &name, float value)
Set a float parameter value.
Definition RunHeader.h:236
void setDetectorName(const std::string &det)
Set the name of the detector that was used in this run.
Definition RunHeader.h:102
void setStringParameter(const std::string &name, std::string value)
Set a string parameter value.
Definition RunHeader.h:261
void setDescription(const std::string &des)
Set the description of this run.
Definition RunHeader.h:119
void setIntParameter(const std::string &name, int value)
Set an int parameter value.
Definition RunHeader.h:211
framework::config::Parameters parameters_
The parameters used to configure the simulation.

References framework::config::Parameters::get(), simcore::DetectorConstruction::getDetectorName(), simcore::SimulatorBase::parameters_, ldmx::RunHeader::setDescription(), ldmx::RunHeader::setDetectorName(), ldmx::RunHeader::setFloatParameter(), ldmx::RunHeader::setIntParameter(), and ldmx::RunHeader::setStringParameter().

◆ configure()

void simcore::Simulator::configure ( framework::config::Parameters & parameters)
overridevirtual

Callback for the processor to configure itself from the given set of parameters.

Parameters
parametersParameterSet for configuration.

Reimplemented from framework::EventProcessor.

Definition at line 30 of file Simulator.cxx.

30 {
31 SimulatorBase::configure(parameters);
32}
void configure(framework::config::Parameters &parameters) override
Callback for the EventProcessor to configure itself from the given set of parameters.

References simcore::SimulatorBase::configure().

◆ onNewRun()

void simcore::Simulator::onNewRun ( const ldmx::RunHeader & header)
overridevirtual

Before the run starts (but after the conditions are configured) set up the random seeds for this run.

Parameters
[in]headerRunHeader for this run, unused

Reimplemented from framework::EventProcessor.

Definition at line 101 of file Simulator.cxx.

101 {
105 std::vector<int> seeds;
106 seeds.push_back(rseed.getSeed("Simulator[0]"));
107 seeds.push_back(rseed.getSeed("Simulator[1]"));
108 setSeeds(seeds);
109
110 run_ = runHeader.getRunNumber();
111}
const T & getCondition(const std::string &condition_name)
Access a conditions object for the current event.
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.
void setSeeds(std::vector< int > seeds)
Set the seeds to be used by the Geant4 random engine.
int run_
the run number (for accessing the run header in onFileClose
Definition Simulator.h:135

References framework::RandomNumberSeedService::CONDITIONS_OBJECT_NAME, framework::EventProcessor::getCondition(), ldmx::RunHeader::getRunNumber(), framework::RandomNumberSeedService::getSeed(), run_, and setSeeds().

◆ onProcessEnd()

void simcore::Simulator::onProcessEnd ( )
overridevirtual

Callback called once processing is complete.

Reimplemented from framework::EventProcessor.

Definition at line 175 of file Simulator.cxx.

175 {
177 // Put this to warn level, just so it's printed out for sure
178 ldmx_log(warn) << "Started " << num_events_began_ << " events to produce "
179 << num_events_completed_ << " events.";
180}
void onProcessEnd() override
Callback called once processing is complete.
int num_events_began_
Number of events started.
Definition Simulator.h:129
int num_events_completed_
Number of events completed.
Definition Simulator.h:132

References num_events_began_, num_events_completed_, and simcore::SimulatorBase::onProcessEnd().

◆ produce()

void simcore::Simulator::produce ( framework::Event & event)
overridevirtual

Run simulation and export results to output event.

Parameters
eventThe event to process.

Implements simcore::SimulatorBase.

Definition at line 113 of file Simulator.cxx.

113 {
114 // Generate and process a Geant4 event.
116 // Save the state of the random engine to an output stream. A string
117 // is then extracted and saved to the event header.
118 std::ostringstream stream;
119 G4Random::saveFullState(stream);
120
122 run_manager_->ProcessOneEvent(event.getEventHeader().getEventNumber());
123
124 // If a Geant4 event has been aborted, skip the rest of the processing
125 // sequence. This will immediately force the simulation to move on to
126 // the next event.
127 if (run_manager_->GetCurrentEvent()->IsAborted()) {
128 run_manager_->TerminateOneEvent(); // clean up event objects
129 SensitiveDetector::Factory::get().apply(
130 [](auto sd) { sd->onFinishedEvent(); });
131 this->abortEvent(); // get out of processors loop
132 }
133
134 // Terminate the event. This checks if an event is to be stored or
135 // stacked for later.
137
138 // store event-wide information in EventHeader
139 auto& event_header = event.getEventHeader();
140 updateEventHeader(event_header);
141
142 event_header.setStringParameter("eventSeed", stream.str());
143
144 auto event_info = static_cast<UserEventInformation*>(
145 run_manager_->GetCurrentEvent()->GetUserInformation());
146
147 auto hepmc3_events = event_info->getHepMC3GenEvents();
148 for (auto& hepmc3ev : hepmc3_events) {
149 hepmc3ev.event_number = event.getEventHeader().getEventNumber();
150 }
151 if (hepmc3_events.size() > 0) event.add("SimHepMC3Events", hepmc3_events);
152
153 saveTracks(event);
154
155 saveSDHits(event);
156
157 savePhotonuclearInteractions(event);
158
159 // Extract and save Bertini cascade histories if any were recorded
160 auto& history_store = bertini::CascadeHistoryStore::getInstance();
161 ldmx_log(debug) << "Checking cascade history store: "
162 << (history_store.empty() ? "empty" : "has histories");
163 if (!history_store.empty()) {
164 auto cascade_histories = history_store.extractHistories();
165 ldmx_log(info) << "Saving " << cascade_histories.size()
166 << " cascade histories to event";
167 event.add("PhotonuclearCascadeHistories", cascade_histories);
168 }
169
170 run_manager_->TerminateOneEvent();
171
172 return;
173}
void abortEvent()
Abort the event immediately.
ldmx::EventHeader & getEventHeader()
Get the event header.
Definition Event.h:57
int getEventNumber() const
Return the event number.
Definition EventHeader.h:78
std::unique_ptr< RunManager > run_manager_
Manager controlling G4 simulation run.
virtual void prepEvent(framework::Event &event)
prepare a new event before entering into the Geant4 simulation

References framework::EventProcessor::abortEvent(), framework::Event::getEventHeader(), ldmx::EventHeader::getEventNumber(), num_events_began_, num_events_completed_, simcore::SimulatorBase::prepEvent(), and simcore::SimulatorBase::run_manager_.

◆ setSeeds()

void simcore::Simulator::setSeeds ( std::vector< int > seeds)
private

Set the seeds to be used by the Geant4 random engine.

Parameters
[in]seedsA vector of seeds to pass to the G4 random engine. The vector must contain at least 2 seeds otherwise an exception is thrown.

Definition at line 182 of file Simulator.cxx.

182 {
183 // If no seeds have been specified then return immediately.
184 if (seeds.empty()) {
185 return;
186 }
187
188 // If seeds are specified, make sure that the container has at least
189 // two seeds. If not, throw an exception.
190 if (seeds.size() == 1) {
191 EXCEPTION_RAISE("ConfigurationException",
192 "At least two seeds need to be specified.");
193 }
194
195 // Create the array of seeds and pass them to G4Random. Currently,
196 // only 100 seeds can be specified at a time. If less than 100
197 // seeds are specified, the remaining slots are set to 0.
198
199 constexpr int max_number_of_seeds{100};
200 std::vector<long> seed_vec(max_number_of_seeds, 0);
201 for (std::size_t index{0}; index < seeds.size(); ++index) {
202 seed_vec[index] = static_cast<long>(seeds[index]);
203 }
204
205 // Pass the array of seeds to the random engine.
206 G4Random::setTheSeeds(seed_vec.data());
207}

Referenced by onNewRun().

Member Data Documentation

◆ num_events_began_

int simcore::Simulator::num_events_began_ {0}
private

Number of events started.

Definition at line 129 of file Simulator.h.

129{0};

Referenced by onProcessEnd(), and produce().

◆ num_events_completed_

int simcore::Simulator::num_events_completed_ {0}
private

Number of events completed.

Definition at line 132 of file Simulator.h.

132{0};

Referenced by onProcessEnd(), and produce().

◆ run_

int simcore::Simulator::run_ {-1}
private

the run number (for accessing the run header in onFileClose

Definition at line 135 of file Simulator.h.

135{-1};

Referenced by onNewRun().


The documentation for this class was generated from the following files: