actions
Loading...
Searching...
No Matches
gRunAction.h
Go to the documentation of this file.
1#pragma once
2
3#include <memory>
4#include <mutex>
5#include <optional>
6#include <stdexcept>
7#include <vector>
8
9// geant4
10#include "G4UserRunAction.hh"
11
12// gemc
13#include <gemc/gbase/gbase.h>
14#include <gemc/ganalysis/gAnalysisAccumulator.h>
15#include <gemc/gdynamicDigitization/gdynamicdigitization.h>
16#include <gemc/gstreamer/gstreamer.h>
17#include <gemc/gstreamer/factories/SRO/gSROFactory.h>
18#include <gemc/gdata/run/gRunDataCollection.h>
20
21
28
29constexpr const char* GRUNACTION_LOGGER = "grunaction";
30
36namespace grunaction {
43} // namespace grunaction
44
45
70class GRunAction : public GBase<GRunAction>, public G4UserRunAction
71{
72public:
81 explicit GRunAction(std::shared_ptr<GOptions> gopts,
82 std::shared_ptr<gdynamicdigitization::dRoutinesMap> digi_map,
83 std::shared_ptr<GAnalysisAccumulator> analysis_accumulator = nullptr,
84 std::shared_ptr<GSROFactory> sro_factory = nullptr);
85
86 ~GRunAction() override = default;
87
88 [[nodiscard]] const std::shared_ptr<GSROFactory>& get_sro_factory() const { return sro_factory; }
89
90 // The run action manages thread-local and process-wide state and is therefore
91 // intentionally non-copyable and non-movable.
92 GRunAction(const GRunAction&) = delete;
93 GRunAction& operator=(const GRunAction&) = delete;
96
105 [[nodiscard]] auto get_digitization_routines_map() const
106 -> std::shared_ptr<gdynamicdigitization::dRoutinesMap> {
107 return digitization_routines_map;
108 }
109
119 [[nodiscard]] auto get_streamer_threads_map() const
120 -> std::shared_ptr<const gstreamer::gstreamersMap> {
121 if (!gstreamer_threads_map) {
122 log->error(
123 gaction::ERR_STREAMERMAP_NOT_EXISTING, "%1 no gstreamer thread map available", FUNCTION_NAME);
124 }
125 return gstreamer_threads_map;
126 }
127
128 [[nodiscard]] bool has_streamer_threads_map() const {
129 return gstreamer_threads_map != nullptr;
130 }
131
133 [[nodiscard]] bool analysis_enabled() const { return analysis_shard != nullptr; }
134
136 void record_analysis_digitized(const std::string& detector, const GDigitizedData& data) {
137 if (analysis_shard != nullptr) {
138 analysis_shard->recordDigitized(requiredAnalysisRunNumber(), detector, data);
139 }
140 }
141
143 void record_analysis_true(const std::string& detector, const GTrueInfoData& data) {
144 if (analysis_shard != nullptr) {
145 analysis_shard->recordTrueInformation(requiredAnalysisRunNumber(), detector, data);
146 }
147 }
148
159 void collect_event_data_collections(const std::string& hcSDName,
160 std::unique_ptr<GDigitizedData> digi_data) {
161 if (run_data == nullptr) {
162 log->error(
164 "%1 run_data is null - cannot collect run-level payload for collection %2", FUNCTION_NAME,
165 hcSDName);
166 }
167
168 run_data->collect_event_data_collections(
169 hcSDName,
170 std::move(digi_data));
171 }
172
180 if (run_data == nullptr) {
181 log->error(
183 "%1 run_data is null - cannot increment processed events.", FUNCTION_NAME);
184 }
185
186 auto& header = run_data->getHeader();
187 if (header == nullptr) {
188 log->error(
190 "%1 run_data header is null - cannot increment processed events.", FUNCTION_NAME);
191 }
192
193 header->increment_events_processed();
194 }
195
203 if (run_data == nullptr) {
204 log->error(
205 gaction::ERR_GRUNACTION_NOT_EXISTING, "%1 run_data is null - cannot increment payload events.",
207 }
208
209 auto& header = run_data->getHeader();
210 if (header == nullptr) {
211 log->error(
213 "%1 run_data header is null - cannot increment payload events.", FUNCTION_NAME);
214 }
215
216 header->increment_events_with_payload();
217 }
218
219private:
220 using CompletedRunData = std::vector<std::unique_ptr<GRunDataCollection>>;
221
228 void stash_worker_run_data();
229
238 [[nodiscard]] CompletedRunData take_completed_worker_run_data();
239
248 G4Run* GenerateRun() override;
249
269 void BeginOfRunAction(const G4Run* run) override;
270
285 void EndOfRunAction(const G4Run* run) override;
286
292 void publish_run_data(const std::shared_ptr<GRunDataCollection>& run_data) const;
293
297 std::shared_ptr<GOptions> goptions;
298
302 std::shared_ptr<gdynamicdigitization::dRoutinesMap> digitization_routines_map;
303
305 std::shared_ptr<GAnalysisAccumulator> analysis_accumulator;
306
308 std::shared_ptr<GSROFactory> sro_factory;
309
311 std::unique_ptr<GAnalysisShard> analysis_shard;
312
314 std::optional<int> analysis_run_number;
315
316 [[nodiscard]] int requiredAnalysisRunNumber() const {
317 if (!analysis_run_number) {
318 throw std::logic_error("Analyzer data recorded before the simulation run number was published");
319 }
320 return *analysis_run_number;
321 }
322
326 std::shared_ptr<const gstreamer::gstreamersMap> gstreamer_threads_map;
327
331 std::shared_ptr<const gstreamer::gstreamersMap> gstreamer_run_map;
332
339 std::unique_ptr<GRunDataCollection> run_data;
340
344 bool need_a_thread_streamer = false;
345
349 bool need_a_run_streamer = false;
350
354 static std::mutex completed_run_data_mutex;
355
362 static CompletedRunData completed_worker_run_data;
363
382 void normalize_run_data(const std::shared_ptr<GRunDataCollection>& run_data) const;
383
384 // coming from digitization routine
385 std::unordered_map<std::string, std::vector<std::string>> to_normalize;
386};
387
388
389// vector of frame data in the run (local thread, merged in GRun::Merge in the global thread)
390// std::vector<GFrameDataCollection*> frameRunData;
391
392//
393// int eventIndex = 0; // added to the absolute event number, increases with each run
394// int lastFrameCreated = 0; // keeping track of the last frame created
395//
396// // determine the frame ID based on event number, eventDuration, frameDuration
397// // TODO: this should be in gdata?
398// int eventFrameIndex(int eventNumber, double timeAtElectronics);
399// bool findFrameID(int fid);
400//
401// // decide whether to write or not to stream the frame based on event number, eventDuration, frameDuration and number of threads
402// // streaming the frame also deletes it from frameRunData
403// // TODO: this should be in gdata?
404// bool shouldWriteFrameID(int eventNumber, long int frameID);
405//
406// // TODO: this should be in gdata?
407// std::vector<int> formPayload(GDigitizedData* digitizedData);
408
409
410// in the constructur we had:
411
412// frameDuration = 64000;
413// eventDuration = gparticle::getEventTimeWidth(goptions);
414
415// stream = gopt->getSwitch("stream");
GBase(const std::shared_ptr< GOptions > &gopt, std::string logger_name="")
std::shared_ptr< GLogger > log
GRunAction & operator=(GRunAction &&)=delete
void record_analysis_digitized(const std::string &detector, const GDigitizedData &data)
Discover digitized variables in one accepted record and add them to this thread's shard.
Definition gRunAction.h:136
void increment_run_events_with_payload()
Increments the number of events that produced run-mode payload.
Definition gRunAction.h:202
GRunAction(std::shared_ptr< GOptions > gopts, std::shared_ptr< gdynamicdigitization::dRoutinesMap > digi_map, std::shared_ptr< GAnalysisAccumulator > analysis_accumulator=nullptr, std::shared_ptr< GSROFactory > sro_factory=nullptr)
Constructs the run action.
Definition gRunAction.cc:16
void increment_run_events_processed()
Increments the number of events processed by the current thread for this run.
Definition gRunAction.h:179
GRunAction(GRunAction &&)=delete
auto get_digitization_routines_map() const -> std::shared_ptr< gdynamicdigitization::dRoutinesMap >
Returns the shared digitization-routine map used by this run action.
Definition gRunAction.h:105
bool has_streamer_threads_map() const
Definition gRunAction.h:128
bool analysis_enabled() const
Return whether this run action has a GUI Analyzer shard.
Definition gRunAction.h:133
void record_analysis_true(const std::string &detector, const GTrueInfoData &data)
Discover true-information variables in one record and add them to this thread's shard.
Definition gRunAction.h:143
GRunAction & operator=(const GRunAction &)=delete
const std::shared_ptr< GSROFactory > & get_sro_factory() const
Definition gRunAction.h:88
GRunAction(const GRunAction &)=delete
void collect_event_data_collections(const std::string &hcSDName, std::unique_ptr< GDigitizedData > digi_data)
Adds one run-mode digitized payload to the current thread run-data collection.
Definition gRunAction.h:159
~GRunAction() override=default
auto get_streamer_threads_map() const -> std::shared_ptr< const gstreamer::gstreamersMap >
Returns the worker-thread streamer map, if it has been instantiated.
Definition gRunAction.h:119
constexpr const char * GRUNACTION_LOGGER
Definition gRunAction.h:29
Defines error codes used by the GEMC actions module.
run
#define FUNCTION_NAME
constexpr int ERR_STREAMERMAP_NOT_EXISTING
constexpr int ERR_GRUNACTION_NOT_EXISTING
Namespace containing helpers related to run-action configuration.
Definition gRunAction.h:36
GOptions defineOptions()
Returns the options associated with the run-action logger scope.
Definition gRunAction.h:42