101template <
typename MapType>
102static std::string map_to_string(
const MapType& m) {
103 std::ostringstream os;
106 for (
const auto& [k, v] : m) {
107 if (!first) os <<
", ";
134static void dump_event(
const std::shared_ptr<GEventDataCollection>& edc,
const std::shared_ptr<GLogger>& log) {
135 log->info(0,
"------------------------------------------------------------");
136 log->info(0,
"Dumping event: local event number = ", edc->getEventNumber());
137 log->info(0,
"------------------------------------------------------------");
139 const auto& dcm = edc->getDataCollectionMap();
141 log->info(0,
"Event contains no detector data.");
145 for (
const auto& [sdName, det] : dcm) {
147 log->info(0,
"Detector <", sdName,
"> has a null GDataCollection pointer (unexpected).");
151 const auto& truthHits = det->getTrueInfoData();
152 const auto& digiHits = det->getDigitizedData();
154 log->info(0,
"Detector <", sdName,
">: truthHits=", truthHits.size(),
" digitizedHits=", digiHits.size());
157 for (
size_t i = 0; i < truthHits.size(); ++i) {
158 const auto& th = truthHits[i];
161 const auto doubles = th->getDoubleVariablesMap();
162 const auto strings = th->getStringVariablesMap();
166 log->info(0,
" [truth hit ", i,
"] id={",idString,
"}");
167 log->info(0,
" doubles: ", map_to_string(doubles));
170 if (!strings.empty()) {
171 log->info(0,
" strings: ", map_to_string(strings));
174 log->info(0,
" strings: {} (none)");
179 for (
size_t i = 0; i < digiHits.size(); ++i) {
180 const auto& dh = digiHits[i];
183 const auto ints_non_sro = dh->getIntObservablesMap(0);
184 const auto ints_sro = dh->getIntObservablesMap(1);
185 const auto dbls_non_sro = dh->getDblObservablesMap(0);
186 const auto dbls_sro_only = dh->getDblObservablesMap(1);
190 log->info(0,
" [digi hit ", i,
"] id={",idString,
"}");
191 log->info(0,
" int non-SRO: ", map_to_string(ints_non_sro));
192 log->info(0,
" int SRO: ", map_to_string(ints_sro));
193 log->info(0,
" dbl non-SRO: ", map_to_string(dbls_non_sro));
194 log->info(0,
" dbl SRO: ", map_to_string(dbls_sro_only));
197 log->info(0,
" timeAtElectronics() = ", dh->getTimeAtElectronics());
217static void validate_event_structure(
const std::shared_ptr<GEventDataCollection>& edc,
218 const std::shared_ptr<GLogger>& log) {
219 const auto& dcm = edc->getDataCollectionMap();
221 log->info(0,
"VALIDATION: event ", edc->getEventNumber(),
" has no detectors (unexpected in this example).");
225 for (
const auto& [sdName, det] : dcm) {
227 log->info(0,
"VALIDATION: detector <", sdName,
"> has null GDataCollection pointer.");
231 const auto& truthHits = det->getTrueInfoData();
232 const auto& digiHits = det->getDigitizedData();
234 for (
size_t i = 0; i < truthHits.size(); ++i) {
235 if (!truthHits[i]) log->info(0,
"VALIDATION: detector <", sdName,
"> truth hit ", i,
" is null.");
237 for (
size_t i = 0; i < digiHits.size(); ++i) {
238 if (!digiHits[i]) log->info(0,
"VALIDATION: detector <", sdName,
"> digitized hit ", i,
" is null.");
242 if (truthHits.size() != digiHits.size()) {
243 log->info(0,
"VALIDATION: detector <", sdName,
"> truthHits(", truthHits.size(),
244 ") != digitizedHits(", digiHits.size(),
") in event ", edc->getEventNumber());
269 const std::shared_ptr<GOptions>& gopt,
270 const std::shared_ptr<GLogger>& log)
271 -> std::vector<std::shared_ptr<GEventDataCollection>> {
272 std::mutex collectorMtx;
273 std::vector<std::shared_ptr<GEventDataCollection>> collected;
274 collected.reserve(
static_cast<size_t>(nevents));
277 std::atomic<int> next{1};
280 std::vector<jthread_alias> pool;
281 pool.reserve(nthreads);
283 for (
int tid = 0; tid < nthreads; ++tid) {
284 pool.emplace_back([&, tid] {
285 log->info(0,
"worker ", tid,
" started");
290 thread_local std::vector<std::shared_ptr<GEventDataCollection>> localEvents;
294 int evn = next.fetch_add(1, std::memory_order_relaxed);
295 if (evn > nevents) {
break; }
310 localEvents.emplace_back(edc);
315 std::scoped_lock lk(collectorMtx);
316 for (
auto& evt : localEvents) { collected.emplace_back(evt); }
320 log->info(0,
"worker ", tid,
" processed ", localCount,
" events");
344int main(
int argc,
char* argv[]) {
352 constexpr int nevents = 5;
353 constexpr int nthreads = 4;
358 for (
const auto& edc : events) {
360 validate_event_structure(edc, log);
361 dump_event(edc, log);
364 log->info(0,
"Generated ", events.size(),
" event containers.");
static std::unique_ptr< GDigitizedData > create(const std::shared_ptr< GOptions > &gopts)
Creates deterministic example data for tests and examples.
static auto create(const std::shared_ptr< GOptions > &gopts) -> std::shared_ptr< GEventDataCollection >
Creates a minimal example event containing one detector entry and one hit pair.
static std::unique_ptr< GTrueInfoData > create(const std::shared_ptr< GOptions > &gopts)
Creates deterministic example data for tests and examples.
Defines GEventDataCollection, the event-level aggregation of detector hit data.
constexpr const char * GEVENTDATA_LOGGER
std::string getIdentityString(std::vector< GIdentifier > gidentity)
auto defineOptions() -> GOptions
Aggregates the option groups needed by event-level data containers.
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[])