91template <
typename MapType>
92static std::string map_to_string(
const MapType& m) {
93 std::ostringstream os;
96 for (
const auto& [k, v] : m) {
97 if (!first) os <<
", ";
144static auto generate_events_in_threads(
int nevents,
146 const std::shared_ptr<GOptions>& gopt,
147 const std::shared_ptr<GLogger>& log)
148 -> std::vector<std::shared_ptr<GEventDataCollection>> {
149 std::mutex collectorMtx;
150 std::vector<std::shared_ptr<GEventDataCollection>> collected;
151 collected.reserve(
static_cast<size_t>(nevents));
153 std::atomic<int> next{1};
155 std::vector<jthread_alias> pool;
156 pool.reserve(nthreads);
158 for (
int tid = 0; tid < nthreads; ++tid) {
159 pool.emplace_back([&, tid] {
160 log->info(0,
"worker ", tid,
" started");
163 thread_local std::vector<std::shared_ptr<GEventDataCollection>> localEvents;
167 int evn = next.fetch_add(1, std::memory_order_relaxed);
168 if (evn > nevents)
break;
179 localEvents.emplace_back(edc);
184 std::scoped_lock lk(collectorMtx);
185 for (
auto& evt : localEvents) { collected.emplace_back(evt); }
189 log->info(0,
"worker ", tid,
" processed ", localCount,
" events");
214static void compute_reference_sums(
const std::vector<std::shared_ptr<GEventDataCollection>>& events,
218 for (
const auto& edc : events) {
221 const auto& dcm = edc->getDataCollectionMap();
222 for (
const auto& [sdName, det] : dcm) {
226 for (
const auto& th : det->getTrueInfoData()) {
228 for (
const auto& [k, v] : th->getDoubleVariablesMap()) {
229 truth_ref[sdName][k] += v;
234 for (
const auto& dh : det->getDigitizedData()) {
237 for (
const auto& [k, v] : dh->getIntObservablesMap(0)) {
238 digi_int_ref[sdName][k] +=
static_cast<long long>(v);
240 for (
const auto& [k, v] : dh->getDblObservablesMap(0)) {
241 digi_dbl_ref[sdName][k] += v;
259static auto integrate_into_run(
const std::vector<std::shared_ptr<GEventDataCollection>>& events,
260 const std::shared_ptr<GOptions>& gopt)
261 -> std::shared_ptr<GRunDataCollection> {
262 auto grun_header = std::make_unique<GRunHeader>(gopt, 1);
263 auto run_data = std::make_shared<GRunDataCollection>(gopt, std::move(
grun_header));
265 for (
const auto& edc : events) {
267 run_data->collect_event_data_collection(edc);
291static void validate_run_against_reference(
const std::shared_ptr<GRunDataCollection>& run_data,
295 const std::shared_ptr<GLogger>& log) {
296 log->info(0,
"============================================================");
297 log->info(0,
"RUN SUMMARY (integrated): runID=", run_data->getRunNumber());
298 log->info(0,
"============================================================");
300 const auto& rmap = run_data->getDataCollectionMap();
302 log->info(0,
"Run data map is empty (no detectors integrated).");
306 for (
const auto& [sdName, det] : rmap) {
309 const auto& truthVec = det->getTrueInfoData();
310 const auto& digiVec = det->getDigitizedData();
312 log->info(0,
"Detector <", sdName,
">: integrated truth entries=", truthVec.size(),
313 " integrated digitized entries=", digiVec.size());
316 if (!truthVec.empty() && truthVec.front()) {
317 const auto integrated_truth = truthVec.front()->getDoubleVariablesMap();
318 log->info(0,
" integrated truth doubles: ", map_to_string(integrated_truth));
320 const auto it_ref_det = truth_ref.find(sdName);
321 if (it_ref_det != truth_ref.end()) {
322 for (
const auto& [k, refv] : it_ref_det->second) {
323 const auto itv = integrated_truth.find(k);
324 const double got = (itv == integrated_truth.end()) ? 0.0 : itv->second;
326 log->info(0,
" MISMATCH truth <", sdName,
">::", k,
" got=", got,
" ref=", refv);
331 log->info(0,
" NOTE: no reference truth sums found for detector <", sdName,
">.");
335 log->info(0,
" integrated truth: <none>");
339 if (!digiVec.empty() && digiVec.front()) {
340 const auto ints_non_sro = digiVec.front()->getIntObservablesMap(0);
341 const auto dbls_non_sro = digiVec.front()->getDblObservablesMap(0);
343 log->info(0,
" integrated digi int non-SRO: ", map_to_string(ints_non_sro));
344 log->info(0,
" integrated digi dbl non-SRO: ", map_to_string(dbls_non_sro));
346 const auto ints_sro = digiVec.front()->getIntObservablesMap(1);
347 const auto dbls_sro = digiVec.front()->getDblObservablesMap(1);
348 log->info(0,
" integrated digi int SRO: ", map_to_string(ints_sro));
349 log->info(0,
" integrated digi dbl SRO: ", map_to_string(dbls_sro));
351 const auto it_int_ref_det = digi_int_ref.find(sdName);
352 if (it_int_ref_det != digi_int_ref.end()) {
353 for (
const auto& [k, refv] : it_int_ref_det->second) {
354 const auto itv = ints_non_sro.find(k);
355 const long long got = (itv == ints_non_sro.end()) ? 0LL : static_cast<long long>(itv->second);
357 log->info(0,
" MISMATCH digi-int <", sdName,
">::", k,
" got=", got,
" ref=", refv);
362 log->info(0,
" NOTE: no reference digitized-int sums found for detector <", sdName,
">.");
365 const auto it_dbl_ref_det = digi_dbl_ref.find(sdName);
366 if (it_dbl_ref_det != digi_dbl_ref.end()) {
367 for (
const auto& [k, refv] : it_dbl_ref_det->second) {
368 const auto itv = dbls_non_sro.find(k);
369 const double got = (itv == dbls_non_sro.end()) ? 0.0 : itv->second;
371 log->info(0,
" MISMATCH digi-dbl <", sdName,
">::", k,
" got=", got,
" ref=", refv);
376 log->info(0,
" NOTE: no reference digitized-double sums found for detector <", sdName,
">.");
380 log->info(0,
" integrated digitized: <none>");
400int main(
int argc,
char* argv[]) {
404 constexpr int nevents = 20;
405 constexpr int nthreads = 4;
407 auto events = generate_events_in_threads(nevents, nthreads, gopts, log);
408 log->info(0,
"Generated ", events.size(),
" events.");
413 compute_reference_sums(events, truth_ref, digi_int_ref, digi_dbl_ref);
415 auto runData = integrate_into_run(events, gopts);
416 validate_run_against_reference(runData, truth_ref, digi_int_ref, digi_dbl_ref, log);
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.
Defines GRunDataCollection, the run-level aggregation of detector data.
constexpr const char * GRUNDATA_LOGGER
auto defineOptions() -> GOptions
Aggregates the option groups needed by run-level data containers.
std::map< std::string, std::map< std::string, long long > > PerDetectorInts
Per-detector map of integer-like reference sums used by the example.
std::map< std::string, std::map< std::string, double > > PerDetectorDoubles
Per-detector map of floating-point reference sums used by the example.
int main(int argc, char *argv[])