95template <
typename MapType>
96static std::string map_to_string(
const MapType& m) {
97 std::ostringstream os;
100 for (
const auto& [k, v] : m) {
101 if (!first) os <<
", ";
125static void dump_event(
const std::shared_ptr<GEventDataCollection>& edc,
const std::shared_ptr<GLogger>& log) {
126 log->info(0,
"------------------------------------------------------------");
127 log->info(0,
"Dumping event: local event number = ", edc->getEventNumber());
128 log->info(0,
"------------------------------------------------------------");
130 const auto& dcm = edc->getDataCollectionMap();
132 log->info(0,
"Event contains no detector data.");
136 for (
const auto& [sdName, det] : dcm) {
138 log->info(0,
"Detector <", sdName,
"> has a null GDataCollection pointer (unexpected).");
142 const auto& truthHits = det->getTrueInfoData();
143 const auto& digiHits = det->getDigitizedData();
145 log->info(0,
"Detector <", sdName,
">: truthHits=", truthHits.size(),
" digitizedHits=", digiHits.size());
148 for (
size_t i = 0; i < truthHits.size(); ++i) {
149 const auto& th = truthHits[i];
152 const auto doubles = th->getDoubleVariablesMap();
153 const auto strings = th->getStringVariablesMap();
155 log->info(0,
" [truth hit ", i,
"] id={", th->getIdentityString(),
"}");
156 log->info(0,
" doubles: ", map_to_string(doubles));
159 if (!strings.empty()) {
160 log->info(0,
" strings: ", map_to_string(strings));
163 log->info(0,
" strings: {} (none)");
168 for (
size_t i = 0; i < digiHits.size(); ++i) {
169 const auto& dh = digiHits[i];
172 const auto ints_non_sro = dh->getIntObservablesMap(0);
173 const auto ints_sro = dh->getIntObservablesMap(1);
174 const auto dbls_non_sro = dh->getDblObservablesMap(0);
175 const auto dbls_sro_only = dh->getDblObservablesMap(1);
177 log->info(0,
" [digi hit ", i,
"] id={", dh->getIdentityString(),
"}");
178 log->info(0,
" int non-SRO: ", map_to_string(ints_non_sro));
179 log->info(0,
" int SRO: ", map_to_string(ints_sro));
180 log->info(0,
" dbl non-SRO: ", map_to_string(dbls_non_sro));
181 log->info(0,
" dbl SRO: ", map_to_string(dbls_sro_only));
184 log->info(0,
" timeAtElectronics() = ", dh->getTimeAtElectronics());
203static void validate_event_structure(
const std::shared_ptr<GEventDataCollection>& edc,
204 const std::shared_ptr<GLogger>& log) {
205 const auto& dcm = edc->getDataCollectionMap();
207 log->info(0,
"VALIDATION: event ", edc->getEventNumber(),
" has no detectors (unexpected in this example).");
211 for (
const auto& [sdName, det] : dcm) {
213 log->info(0,
"VALIDATION: detector <", sdName,
"> has null GDataCollection pointer.");
217 const auto& truthHits = det->getTrueInfoData();
218 const auto& digiHits = det->getDigitizedData();
220 for (
size_t i = 0; i < truthHits.size(); ++i) {
221 if (!truthHits[i]) log->info(0,
"VALIDATION: detector <", sdName,
"> truth hit ", i,
" is null.");
223 for (
size_t i = 0; i < digiHits.size(); ++i) {
224 if (!digiHits[i]) log->info(0,
"VALIDATION: detector <", sdName,
"> digitized hit ", i,
" is null.");
230 if (truthHits.size() != digiHits.size()) {
231 log->info(0,
"VALIDATION: detector <", sdName,
"> truthHits(", truthHits.size(),
232 ") != digitizedHits(", digiHits.size(),
") in event ", edc->getEventNumber());
253 const std::shared_ptr<GOptions>& gopt,
254 const std::shared_ptr<GLogger>& log)
255 -> std::vector<std::shared_ptr<GEventDataCollection>> {
256 std::mutex collectorMtx;
257 std::vector<std::shared_ptr<GEventDataCollection>> collected;
258 collected.reserve(
static_cast<size_t>(nevents));
261 std::atomic<int> next{1};
264 std::vector<jthread_alias> pool;
265 pool.reserve(nthreads);
267 for (
int tid = 0; tid < nthreads; ++tid) {
268 pool.emplace_back([&, tid] {
269 log->info(0,
"worker ", tid,
" started");
274 thread_local std::vector<std::shared_ptr<GEventDataCollection>> localEvents;
278 int evn = next.fetch_add(1, std::memory_order_relaxed);
279 if (evn > nevents) {
break; }
294 localEvents.emplace_back(edc);
299 std::scoped_lock lk(collectorMtx);
300 for (
auto& evt : localEvents) { collected.emplace_back(evt); }
304 log->info(0,
"worker ", tid,
" processed ", localCount,
" events");
311int main(
int argc,
char* argv[]) {
319 constexpr int nevents = 5;
320 constexpr int nthreads = 4;
325 for (
const auto& edc : events) {
327 validate_event_structure(edc, log);
328 dump_event(edc, log);
331 log->info(0,
"Generated ", events.size(),
" event containers.");
static std::unique_ptr< GDigitizedData > create(const std::shared_ptr< GOptions > &gopts)
Test/example factory: create a digitized hit with deterministic dummy data.
static auto create(const std::shared_ptr< GOptions > &gopts) -> std::shared_ptr< GEventDataCollection >
Test/example factory: create an event collection with one dummy hit for "ctof".
static std::unique_ptr< GTrueInfoData > create(const std::shared_ptr< GOptions > &gopts)
Test/example factory: create a true-hit object with deterministic dummy data.
Defines GEventDataCollection, event-level aggregation of per-detector hit data.
constexpr const char * GEVENTDATA_LOGGER
auto defineOptions() -> GOptions
Aggregated options for event-level data collection.
auto run_simulation_in_threads(int nevents, int nthreads, const std::shared_ptr< GOptions > &gopt, const std::shared_ptr< GLogger > &log, const std::shared_ptr< const gdynamicdigitization::dRoutinesMap > &dynamicRoutinesMap) -> std::vector< std::unique_ptr< GEventDataCollection > >
int main(int argc, char *argv[])