87template <
typename MapType>
88static std::string map_to_string(
const MapType& m) {
89 std::ostringstream os;
92 for (
const auto& [k, v] : m) {
93 if (!first) os <<
", ";
115static auto generate_events_in_threads(
int nevents,
117 const std::shared_ptr<GOptions>& gopt,
118 const std::shared_ptr<GLogger>& log)
119 -> std::vector<std::shared_ptr<GEventDataCollection>> {
120 std::mutex collectorMtx;
121 std::vector<std::shared_ptr<GEventDataCollection>> collected;
122 collected.reserve(
static_cast<size_t>(nevents));
124 std::atomic<int> next{1};
126 std::vector<jthread_alias> pool;
127 pool.reserve(nthreads);
129 for (
int tid = 0; tid < nthreads; ++tid) {
130 pool.emplace_back([&, tid] {
131 log->info(0,
"worker ", tid,
" started");
134 thread_local std::vector<std::shared_ptr<GEventDataCollection>> localEvents;
138 int evn = next.fetch_add(1, std::memory_order_relaxed);
139 if (evn > nevents)
break;
150 localEvents.emplace_back(edc);
155 std::scoped_lock lk(collectorMtx);
156 for (
auto& evt : localEvents) { collected.emplace_back(evt); }
160 log->info(0,
"worker ", tid,
" processed ", localCount,
" events");
167static void compute_reference_sums(
const std::vector<std::shared_ptr<GEventDataCollection>>& events,
171 for (
const auto& edc : events) {
174 const auto& dcm = edc->getDataCollectionMap();
175 for (
const auto& [sdName, det] : dcm) {
179 for (
const auto& th : det->getTrueInfoData()) {
181 for (
const auto& [k, v] : th->getDoubleVariablesMap()) {
182 truth_ref[sdName][k] += v;
187 for (
const auto& dh : det->getDigitizedData()) {
190 for (
const auto& [k, v] : dh->getIntObservablesMap(0)) {
191 digi_int_ref[sdName][k] +=
static_cast<long long>(v);
193 for (
const auto& [k, v] : dh->getDblObservablesMap(0)) {
194 digi_dbl_ref[sdName][k] += v;
201static auto integrate_into_run(
const std::vector<std::shared_ptr<GEventDataCollection>>& events,
202 const std::shared_ptr<GOptions>& gopt)
203 -> std::shared_ptr<GRunDataCollection> {
204 auto grun_header = std::make_unique<GRunHeader>(gopt, 1);
205 auto run_data = std::make_shared<GRunDataCollection>(gopt, std::move(
grun_header));
207 for (
const auto& edc : events) {
209 run_data->collect_event_data_collection(edc);
215static void validate_run_against_reference(
const std::shared_ptr<GRunDataCollection>& run_data,
219 const std::shared_ptr<GLogger>& log) {
220 log->info(0,
"============================================================");
221 log->info(0,
"RUN SUMMARY (integrated): runID=", run_data->getRunNumber());
222 log->info(0,
"============================================================");
224 const auto& rmap = run_data->getDataCollectionMap();
226 log->info(0,
"Run data map is empty (no detectors integrated).");
230 for (
const auto& [sdName, det] : rmap) {
233 const auto& truthVec = det->getTrueInfoData();
234 const auto& digiVec = det->getDigitizedData();
236 log->info(0,
"Detector <", sdName,
">: integrated truth entries=", truthVec.size(),
237 " integrated digitized entries=", digiVec.size());
240 if (!truthVec.empty() && truthVec.front()) {
241 const auto integrated_truth = truthVec.front()->getDoubleVariablesMap();
242 log->info(0,
" integrated truth doubles: ", map_to_string(integrated_truth));
244 const auto it_ref_det = truth_ref.find(sdName);
245 if (it_ref_det != truth_ref.end()) {
246 for (
const auto& [k, refv] : it_ref_det->second) {
247 const auto itv = integrated_truth.find(k);
248 const double got = (itv == integrated_truth.end()) ? 0.0 : itv->second;
250 log->info(0,
" MISMATCH truth <", sdName,
">::", k,
" got=", got,
" ref=", refv);
255 log->info(0,
" NOTE: no reference truth sums found for detector <", sdName,
">.");
259 log->info(0,
" integrated truth: <none>");
263 if (!digiVec.empty() && digiVec.front()) {
264 const auto ints_non_sro = digiVec.front()->getIntObservablesMap(0);
265 const auto dbls_non_sro = digiVec.front()->getDblObservablesMap(0);
267 log->info(0,
" integrated digi int non-SRO: ", map_to_string(ints_non_sro));
268 log->info(0,
" integrated digi dbl non-SRO: ", map_to_string(dbls_non_sro));
270 const auto ints_sro = digiVec.front()->getIntObservablesMap(1);
271 const auto dbls_sro = digiVec.front()->getDblObservablesMap(1);
272 log->info(0,
" integrated digi int SRO: ", map_to_string(ints_sro));
273 log->info(0,
" integrated digi dbl SRO: ", map_to_string(dbls_sro));
275 const auto it_int_ref_det = digi_int_ref.find(sdName);
276 if (it_int_ref_det != digi_int_ref.end()) {
277 for (
const auto& [k, refv] : it_int_ref_det->second) {
278 const auto itv = ints_non_sro.find(k);
279 const long long got = (itv == ints_non_sro.end()) ? 0LL : static_cast<long long>(itv->second);
281 log->info(0,
" MISMATCH digi-int <", sdName,
">::", k,
" got=", got,
" ref=", refv);
286 log->info(0,
" NOTE: no reference digitized-int sums found for detector <", sdName,
">.");
289 const auto it_dbl_ref_det = digi_dbl_ref.find(sdName);
290 if (it_dbl_ref_det != digi_dbl_ref.end()) {
291 for (
const auto& [k, refv] : it_dbl_ref_det->second) {
292 const auto itv = dbls_non_sro.find(k);
293 const double got = (itv == dbls_non_sro.end()) ? 0.0 : itv->second;
295 log->info(0,
" MISMATCH digi-dbl <", sdName,
">::", k,
" got=", got,
" ref=", refv);
300 log->info(0,
" NOTE: no reference digitized-double sums found for detector <", sdName,
">.");
304 log->info(0,
" integrated digitized: <none>");
309int main(
int argc,
char* argv[]) {
313 constexpr int nevents = 20;
314 constexpr int nthreads = 4;
316 auto events = generate_events_in_threads(nevents, nthreads, gopts, log);
317 log->info(0,
"Generated ", events.size(),
" events.");
322 compute_reference_sums(events, truth_ref, digi_int_ref, digi_dbl_ref);
324 auto runData = integrate_into_run(events, gopts);
325 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)
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.
Defines GRunDataCollection, run-level aggregation of detector data.
constexpr const char * GRUNDATA_LOGGER
std::map< std::string, std::map< std::string, long long > > PerDetectorInts
std::map< std::string, std::map< std::string, double > > PerDetectorDoubles
Type alias for per-detector scalar accumulation maps used in this example.
auto defineOptions() -> GOptions
Aggregated options for run-level data collection.
int main(int argc, char *argv[])