18 #include "TRACE/tracemf.h"
19 #include "artdaq/DAQdata/Globals.hh"
20 #define TRACE_NAME (app_name + "_FragmentWatcher").c_str()
22 #include "artdaq-core/Data/ContainerFragment.hh"
23 #include "artdaq-core/Data/Fragment.hh"
25 #include "art/Framework/Core/EDAnalyzer.h"
26 #include "art/Framework/Core/ModuleMacros.h"
27 #include "art/Framework/Principal/Event.h"
28 #include "art/Framework/Principal/Handle.h"
34 #define TLVL_BAD_FRAGMENTS TLVL_WARNING
35 #define TLVL_EVENT_SUMMARY TLVL_TRACE
36 #define TLVL_EXPECTED_FRAGIDS 5
37 #define TLVL_BASIC_MODE 6
38 #define TLVL_FRACTIONAL_MODE 7
41 class FragmentWatcher;
69 void analyze(art::Event
const& evt)
override;
77 std::bitset<3> mode_bitset_;
78 int metrics_reporting_level_;
80 int events_processed_;
81 std::set<int> expected_fragmentID_list_;
83 int events_with_missing_fragments_;
84 int events_with_empty_fragments_;
86 int events_with_10pct_missing_fragments_;
87 int events_with_10pct_empty_fragments_;
88 int events_with_50pct_missing_fragments_;
89 int events_with_50pct_empty_fragments_;
91 std::map<int, int> missing_fragments_by_fragmentID_;
92 std::map<int, int> empty_fragments_by_fragmentID_;
94 const int BASIC_COUNTS_MODE = 0;
95 const int FRACTIONAL_COUNTS_MODE = 1;
96 const int DETAILED_COUNTS_MODE = 2;
101 , mode_bitset_(std::bitset<3>(pset.get<int>(
"mode_bitmask", 0x1)))
102 , metrics_reporting_level_(pset.get<int>(
"metrics_reporting_level", 1))
103 , events_processed_(0)
104 , expected_fragmentID_list_()
105 , events_with_missing_fragments_(0)
106 , events_with_empty_fragments_(0)
107 , events_with_10pct_missing_fragments_(0)
108 , events_with_10pct_empty_fragments_(0)
109 , events_with_50pct_missing_fragments_(0)
110 , events_with_50pct_empty_fragments_(0)
111 , missing_fragments_by_fragmentID_()
112 , empty_fragments_by_fragmentID_()
114 auto ids = pset.get<std::vector<int>>(
"fragment_ids", {});
117 expected_fragmentID_list_.insert(
id);
130 std::vector<art::Handle<std::vector<artdaq::Fragment>>> fragmentHandles;
131 fragmentHandles = evt.getMany<std::vector<artdaq::Fragment>>();
133 std::set<int> missing_fragmentID_list_this_event(expected_fragmentID_list_);
135 for (
auto const& hndl : fragmentHandles)
137 for (
auto const& fragment : *hndl)
139 int fragID = fragment.fragmentID();
140 if(!expected_fragmentID_list_.count(fragID)) {
141 TLOG(TLVL_EXPECTED_FRAGIDS) <<
"Inserting fragment ID " << fragID <<
" into the list of expected_fragmentIDs.";
142 expected_fragmentID_list_.insert(fragID);
144 missing_fragmentID_list_this_event.erase(fragID);
149 for (
int const& fragID : missing_fragmentID_list_this_event)
151 if (missing_fragments_by_fragmentID_.count(fragID) == 0)
153 missing_fragments_by_fragmentID_[fragID] = 1;
157 missing_fragments_by_fragmentID_[fragID] += 1;
162 int empty_fragment_count_this_event = 0;
163 std::set<int> empty_fragmentID_list_this_event;
164 for (
auto const& hndl : fragmentHandles)
166 std::string instance_name = hndl.provenance()->productInstanceName();
167 std::size_t found = instance_name.find(
"Empty");
168 if (found != std::string::npos)
170 empty_fragment_count_this_event += hndl->size();
173 for (
auto const& fragment : *hndl)
175 int fragID = fragment.fragmentID();
176 if (empty_fragments_by_fragmentID_.count(fragID) == 0)
178 empty_fragments_by_fragmentID_[fragID] = 1;
182 empty_fragments_by_fragmentID_[fragID] += 1;
184 empty_fragmentID_list_this_event.insert(fragID);
190 if (metricMan !=
nullptr && (mode_bitset_.test(BASIC_COUNTS_MODE) || mode_bitset_.test(FRACTIONAL_COUNTS_MODE)))
192 metricMan->sendMetric(
"EventsProcessed", events_processed_,
"events", metrics_reporting_level_,
193 artdaq::MetricMode::LastPoint);
196 size_t missing_fragment_count_this_event = missing_fragmentID_list_this_event.size();
197 size_t total_fragments_this_event = expected_fragmentID_list_.size() - missing_fragment_count_this_event;
198 TLOG(TLVL_EVENT_SUMMARY) <<
"Event " << evt.event() <<
": this event: total_fragments=" << total_fragments_this_event
199 <<
", missing_fragments=" << missing_fragment_count_this_event <<
", empty_fragments="
200 << empty_fragment_count_this_event <<
" (" << events_processed_ <<
" events processed)";
202 if (missing_fragment_count_this_event > 0)
204 std::ostringstream oss;
205 bool firstLoop =
true;
206 for (
auto const& fragID : missing_fragmentID_list_this_event)
208 if (!firstLoop) { oss <<
", "; }
212 TLOG(TLVL_BAD_FRAGMENTS) <<
"Event " << evt.event() <<
": total_fragments=" << total_fragments_this_event
213 <<
", fragmentIDs for " << missing_fragment_count_this_event <<
" missing_fragments: " << oss.str();
216 if (!empty_fragmentID_list_this_event.empty())
218 std::ostringstream oss;
219 bool firstLoop =
true;
220 for (
auto const& fragID : empty_fragmentID_list_this_event)
222 if (!firstLoop) { oss <<
", "; }
226 TLOG(TLVL_BAD_FRAGMENTS) <<
"Event " << evt.event() <<
": total_fragments=" << total_fragments_this_event
227 <<
", fragmentIDs for " << empty_fragment_count_this_event <<
" empty_fragments: " << oss.str();
231 if (metricMan !=
nullptr && mode_bitset_.test(BASIC_COUNTS_MODE))
233 if (missing_fragment_count_this_event > 0) { ++events_with_missing_fragments_; }
234 if (empty_fragment_count_this_event > 0) { ++events_with_empty_fragments_; }
236 metricMan->sendMetric(
"EventsWithMissingFragments", events_with_missing_fragments_,
"events",
237 metrics_reporting_level_, artdaq::MetricMode::LastPoint);
238 metricMan->sendMetric(
"EventsWithEmptyFragments", events_with_empty_fragments_,
"events",
239 metrics_reporting_level_, artdaq::MetricMode::LastPoint);
241 TLOG(TLVL_BASIC_MODE) <<
"Event " << evt.event() <<
": events_with_missing_fragments=" << events_with_missing_fragments_
242 <<
", events_with_empty_fragments=" << events_with_empty_fragments_;
246 if (metricMan !=
nullptr && mode_bitset_.test(FRACTIONAL_COUNTS_MODE))
248 if (((static_cast<double>(missing_fragment_count_this_event) * 100.0) / static_cast<double>(expected_fragmentID_list_.size())) >= 10.0)
250 ++events_with_10pct_missing_fragments_;
252 if (((static_cast<double>(missing_fragment_count_this_event) * 100.0) /
static_cast<double>(expected_fragmentID_list_.size())) >= 50.0)
254 ++events_with_50pct_missing_fragments_;
257 if (((static_cast<double>(empty_fragment_count_this_event) * 100.0) /
static_cast<double>(expected_fragmentID_list_.size())) >= 10.0)
259 ++events_with_10pct_empty_fragments_;
261 if (((static_cast<double>(empty_fragment_count_this_event) * 100.0) /
static_cast<double>(expected_fragmentID_list_.size())) >= 50.0)
263 ++events_with_50pct_empty_fragments_;
266 metricMan->sendMetric(
"EventsWith10PctMissingFragments", events_with_10pct_missing_fragments_,
"events",
267 metrics_reporting_level_, artdaq::MetricMode::LastPoint);
268 metricMan->sendMetric(
"EventsWith50PctMissingFragments", events_with_50pct_missing_fragments_,
"events",
269 metrics_reporting_level_, artdaq::MetricMode::LastPoint);
271 metricMan->sendMetric(
"EventsWith10PctEmptyFragments", events_with_10pct_empty_fragments_,
"events",
272 metrics_reporting_level_, artdaq::MetricMode::LastPoint);
273 metricMan->sendMetric(
"EventsWith50PctEmptyFragments", events_with_50pct_empty_fragments_,
"events",
274 metrics_reporting_level_, artdaq::MetricMode::LastPoint);
276 TLOG(TLVL_FRACTIONAL_MODE) <<
"Event " << evt.event() <<
": events_with_10pct_missing_fragments=" << events_with_10pct_missing_fragments_
277 <<
", events_with_10pct_empty_fragments=" << events_with_10pct_empty_fragments_;
278 TLOG(TLVL_FRACTIONAL_MODE) <<
"Event " << evt.event() <<
": events_with_50pct_missing_fragments=" << events_with_50pct_missing_fragments_
279 <<
", events_with_50pct_empty_fragments=" << events_with_50pct_empty_fragments_;
283 if (metricMan !=
nullptr && mode_bitset_.test(DETAILED_COUNTS_MODE))
287 if (missing_fragment_count_this_event > 0 || empty_fragment_count_this_event > 0)
289 std::ostringstream oss;
290 oss <<
"<eventbuilder_snapshot app_name=\"" << app_name <<
"\"><events_processed>" << events_processed_
291 <<
"</events_processed>";
292 oss <<
"<missing_fragment_counts>";
293 for (
auto const& mapIter : missing_fragments_by_fragmentID_)
295 oss <<
"<count fragment_id=" << mapIter.first <<
">" << mapIter.second <<
"</count>";
297 oss <<
"</missing_fragment_counts>";
298 oss <<
"<empty_fragment_counts>";
299 for (
auto const& mapIter : empty_fragments_by_fragmentID_)
301 oss <<
"<count fragment_id=" << mapIter.first <<
">" << mapIter.second <<
"</count>";
303 oss <<
"</empty_fragment_counts>";
304 oss <<
"</eventbuilder_snapshot>";
306 metricMan->sendMetric(
"EmptyFragmentSnapshot", oss.str(),
"xml_string",
307 metrics_reporting_level_, artdaq::MetricMode::LastPoint);
312 ==================================================== =
314 event_builder_snapshot : {
315 name:
"EventBuilder5"
316 timestamp :
"20190408T124433"
319 sender_list : [
"felix501",
"felix501",
"ssp101",
"ssp102"]
320 valid_fragment_counts : [105, 105, 102, 104]
321 empty_fragment_counts : [0, 0, 2, 0]
322 missing_fragment_counts : [0, 0, 1, 1]
325 ==================================================== =
327 <event_builder_snapshot name =
"EventBuilder5">
328 < timestamp>20190408T124433< / timestamp>
329 < events_built>105 < / events_built
332 <sender index = 0>felix501< / sender>
333 <sender index = 1>felix502< / sender>
334 <sender index = 2>ssp101< / sender>
335 <sender index = 3>ssp102< / sender>
338 <valid_fragment_counts>
339 < count index = 0>105 < / count >
340 < count index = 1>105 < / count >
341 < count index = 2>102 < / count >
342 < count index = 3>104 < / count >
343 < / valid_fragment_counts>
345 <empty_fragment_counts>
346 < count index = 2>2 < / count >
347 < / empty_fragment_counts>
349 <missing_fragment_counts>
350 < count index = 2>1 < / count >
351 < count index = 3>1 < / count >
352 < / missing_fragment_counts>
353 < / event_builder_snapshot>
355 ==================================================== =
FragmentWatcher(fhicl::ParameterSet const &pset)
FragmentWatcher Constructor.
An art::EDAnalyzer module which checks events for certain error conditions (missing fragments...
void analyze(art::Event const &evt) override
Analyze each event, using the configured mode bitmask.
~FragmentWatcher() override
Virtual Destructor. Shuts down MetricManager if one is present.