diff --git a/gemc/gstreamer/factories/JSON/event/event.cc b/gemc/gstreamer/factories/JSON/event/event.cc index d0692252..fd5dd4c2 100644 --- a/gemc/gstreamer/factories/JSON/event/event.cc +++ b/gemc/gstreamer/factories/JSON/event/event.cc @@ -29,6 +29,7 @@ bool GstreamerJsonFactory::startEventImpl(const std::shared_ptrgetHeader()->getG4LocalEvn(); @@ -47,24 +48,37 @@ bool GstreamerJsonFactory::endEventImpl(const std::shared_ptrgetG4LocalEvn(); + current_event << "}"; // close the "header" object opened in startEventImpl current_event_has_header = true; return true; diff --git a/gemc/gstreamer/factories/JSON/event/publishDigitized.cc b/gemc/gstreamer/factories/JSON/event/publishDigitized.cc index 578e7a7f..e88c562d 100644 --- a/gemc/gstreamer/factories/JSON/event/publishDigitized.cc +++ b/gemc/gstreamer/factories/JSON/event/publishDigitized.cc @@ -17,80 +17,54 @@ bool GstreamerJsonFactory::publishEventDigitizedDataImpl(const std::string& return false; } - // The current design appends digitized content into a reserved object nested under - // "detectors". This avoids rewriting previously emitted detector JSON. + // Build this detector's digitized array into a standalone entry and buffer it. + // endEventImpl emits all buffered entries together as the "digitized_by_detector" + // object, which keeps the JSON valid regardless of how true-info and digitized + // publish calls interleave across detectors. if (digitizedData.empty()) return true; - static const char* marker = "\"digitized_by_detector\": {"; - const std::string assembled = current_event.str(); - - const bool has_digitized_container = (assembled.find(marker) != std::string::npos); - - if (!has_digitized_container) { - // Ensure the event already has a detectors object before reserving a nested map - // for digitized collections keyed by detector name. - if (!current_event_has_any_detector) { - current_event << ", \"detectors\": {"; - current_event_has_any_detector = true; - } - else { - current_event << ", "; - } - - current_event << "\"digitized_by_detector\": {"; - } - - // If the reserved object already contains one detector entry, append a comma - // before adding the next one. - const std::string updated = current_event.str(); - if (!updated.empty()) { - char last = updated.back(); - if (last != '{') current_event << ", "; - } - - current_event << "\"" << jsonEscape(detectorName) << "\": ["; + std::ostringstream entry; + entry << "\"" << jsonEscape(detectorName) << "\": ["; bool wrote_first_hit = false; for (const auto* hit : digitizedData) { if (!hit) continue; - if (wrote_first_hit) current_event << ", "; + if (wrote_first_hit) entry << ", "; wrote_first_hit = true; - current_event << "{"; + entry << "{"; auto addr = getIdentityString(hit->getIdentity()); - current_event << "\"address\": \"" << jsonEscape(addr) << "\""; + entry << "\"address\": \"" << jsonEscape(addr) << "\""; - current_event << ", \"vars\": {"; + entry << ", \"vars\": {"; bool wrote_first_var = false; // Integer observables: // the argument 0 means "do not include SRO variables". for (const auto& [name, value] : hit->getIntObservablesMap(0)) { - if (wrote_first_var) current_event << ", "; + if (wrote_first_var) entry << ", "; wrote_first_var = true; - current_event << "\"" << jsonEscape(name) << "\": " << value; + entry << "\"" << jsonEscape(name) << "\": " << value; } // Floating-point observables. for (const auto& [name, value] : hit->getDblObservablesMap(0)) { - if (wrote_first_var) current_event << ", "; + if (wrote_first_var) entry << ", "; wrote_first_var = true; - current_event << "\"" << jsonEscape(name) << "\": " << value; + entry << "\"" << jsonEscape(name) << "\": " << value; } - current_event << "}"; - current_event << "}"; + entry << "}"; + entry << "}"; } - current_event << "]"; + entry << "]"; - // Close the temporary digitized_by_detector object immediately so the enclosing - // event remains structurally valid after this call. - current_event << "}"; + current_event_digitized_entries.push_back(entry.str()); return true; } \ No newline at end of file diff --git a/gemc/gstreamer/factories/JSON/gstreamerJSONFactory.h b/gemc/gstreamer/factories/JSON/gstreamerJSONFactory.h index dcc575c4..ce50c047 100644 --- a/gemc/gstreamer/factories/JSON/gstreamerJSONFactory.h +++ b/gemc/gstreamer/factories/JSON/gstreamerJSONFactory.h @@ -185,6 +185,11 @@ class GstreamerJsonFactory : public GStreamer { /// \brief Tracks whether the current event already contains generated-particle banks. bool current_event_has_generated = false; + /// \brief Buffered digitized detector arrays for the current event. endEventImpl emits + /// them together as the "digitized_by_detector" object, which keeps the JSON valid + /// regardless of how true-info and digitized publish calls interleave across detectors. + std::vector current_event_digitized_entries; + /// \brief Tracks whether the plugin is currently assembling a frame object. bool is_building_frame = false;