18 #define TRACE_NAME (app_name + "_FragmentWatcher").c_str()
19 #include "artdaq/DAQdata/Globals.hh"
21 #include "art/Framework/Core/EDAnalyzer.h"
22 #include "art/Framework/Core/ModuleMacros.h"
23 #include "art/Framework/Principal/Event.h"
24 #include "art/Framework/Principal/Handle.h"
26 #include "artdaq-core/Data/ContainerFragment.hh"
27 #include "artdaq-core/Data/Fragment.hh"
33 #define TLVL_BAD_FRAGMENTS TLVL_WARNING
34 #define TLVL_EVENT_SUMMARY TLVL_TRACE
35 #define TLVL_EXPECTED_FRAGIDS 5
36 #define TLVL_BASIC_MODE 6
37 #define TLVL_FRACTIONAL_MODE 7
40 class FragmentWatcher;
68 void analyze(art::Event
const& evt)
override;
76 std::bitset<3> mode_bitset_;
77 int metrics_reporting_level_;
79 int events_processed_;
80 std::set<int> expected_fragmentID_list_;
82 int events_with_missing_fragments_;
83 int events_with_empty_fragments_;
85 int events_with_10pct_missing_fragments_;
86 int events_with_10pct_empty_fragments_;
87 int events_with_50pct_missing_fragments_;
88 int events_with_50pct_empty_fragments_;
90 std::map<int, int> missing_fragments_by_fragmentID_;
91 std::map<int, int> empty_fragments_by_fragmentID_;
93 const int BASIC_COUNTS_MODE = 0;
94 const int FRACTIONAL_COUNTS_MODE = 1;
95 const int DETAILED_COUNTS_MODE = 2;
100 , mode_bitset_(std::bitset<3>(pset.get<int>(
"mode_bitmask", 0x1)))
101 , metrics_reporting_level_(pset.get<int>(
"metrics_reporting_level", 1))
102 , events_processed_(0)
103 , expected_fragmentID_list_()
104 , events_with_missing_fragments_(0)
105 , events_with_empty_fragments_(0)
106 , events_with_10pct_missing_fragments_(0)
107 , events_with_10pct_empty_fragments_(0)
108 , events_with_50pct_missing_fragments_(0)
109 , events_with_50pct_empty_fragments_(0)
110 , missing_fragments_by_fragmentID_()
111 , empty_fragments_by_fragmentID_()
124 std::vector<art::Handle<std::vector<artdaq::Fragment> > > fragmentHandles;
125 evt.getManyByType(fragmentHandles);
127 std::set<int> missing_fragmentID_list_this_event(expected_fragmentID_list_);
129 for (
auto const& hndl : fragmentHandles)
131 for (
auto const& fragment : *hndl)
133 int fragID = fragment.fragmentID();
134 TLOG(TLVL_EXPECTED_FRAGIDS) <<
"Inserting fragment ID " << fragID <<
" into the list of expected_fragmentIDs.";
135 expected_fragmentID_list_.insert(fragID);
136 missing_fragmentID_list_this_event.erase(fragID);
141 for (
int const& fragID : missing_fragmentID_list_this_event)
143 if (missing_fragments_by_fragmentID_.count(fragID) == 0)
145 missing_fragments_by_fragmentID_[fragID] = 1;
149 missing_fragments_by_fragmentID_[fragID] += 1;
154 int empty_fragment_count_this_event = 0;
155 std::set<int> empty_fragmentID_list_this_event;
156 for (
auto const& hndl : fragmentHandles)
158 std::string instance_name = hndl.provenance()->productInstanceName();
159 std::size_t found = instance_name.find(
"Empty");
160 if (found != std::string::npos)
162 empty_fragment_count_this_event += hndl->size();
165 for (
auto const& fragment : *hndl)
167 int fragID = fragment.fragmentID();
168 if (empty_fragments_by_fragmentID_.count(fragID) == 0)
170 empty_fragments_by_fragmentID_[fragID] = 1;
174 empty_fragments_by_fragmentID_[fragID] += 1;
176 empty_fragmentID_list_this_event.insert(fragID);
182 if (metricMan !=
nullptr && (mode_bitset_.test(BASIC_COUNTS_MODE) || mode_bitset_.test(FRACTIONAL_COUNTS_MODE)))
184 metricMan->sendMetric(
"EventsProcessed", events_processed_,
"events", metrics_reporting_level_,
185 artdaq::MetricMode::LastPoint);
188 size_t missing_fragment_count_this_event = missing_fragmentID_list_this_event.size();
189 size_t total_fragments_this_event = expected_fragmentID_list_.size() - missing_fragment_count_this_event;
190 TLOG(TLVL_EVENT_SUMMARY) <<
"Event " << evt.event() <<
": this event: total_fragments=" << total_fragments_this_event
191 <<
", missing_fragments=" << missing_fragment_count_this_event <<
", empty_fragments="
192 << empty_fragment_count_this_event <<
" (" << events_processed_ <<
" events processed)";
194 if (missing_fragment_count_this_event > 0)
196 std::ostringstream oss;
197 bool firstLoop =
true;
198 for (
auto const& fragID : missing_fragmentID_list_this_event)
200 if (!firstLoop) { oss <<
", "; }
204 TLOG(TLVL_BAD_FRAGMENTS) <<
"Event " << evt.event() <<
": total_fragments=" << total_fragments_this_event
205 <<
", fragmentIDs for " << missing_fragment_count_this_event <<
" missing_fragments: " << oss.str();
208 if (!empty_fragmentID_list_this_event.empty())
210 std::ostringstream oss;
211 bool firstLoop =
true;
212 for (
auto const& fragID : empty_fragmentID_list_this_event)
214 if (!firstLoop) { oss <<
", "; }
218 TLOG(TLVL_BAD_FRAGMENTS) <<
"Event " << evt.event() <<
": total_fragments=" << total_fragments_this_event
219 <<
", fragmentIDs for " << empty_fragment_count_this_event <<
" empty_fragments: " << oss.str();
223 if (metricMan !=
nullptr && mode_bitset_.test(BASIC_COUNTS_MODE))
225 if (missing_fragment_count_this_event > 0) { ++events_with_missing_fragments_; }
226 if (empty_fragment_count_this_event > 0) { ++events_with_empty_fragments_; }
228 metricMan->sendMetric(
"EventsWithMissingFragments", events_with_missing_fragments_,
"events",
229 metrics_reporting_level_, artdaq::MetricMode::LastPoint);
230 metricMan->sendMetric(
"EventsWithEmptyFragments", events_with_empty_fragments_,
"events",
231 metrics_reporting_level_, artdaq::MetricMode::LastPoint);
233 TLOG(TLVL_BASIC_MODE) <<
"Event " << evt.event() <<
": events_with_missing_fragments=" << events_with_missing_fragments_
234 <<
", events_with_empty_fragments=" << events_with_empty_fragments_;
238 if (metricMan !=
nullptr && mode_bitset_.test(FRACTIONAL_COUNTS_MODE))
240 if (((static_cast<double>(missing_fragment_count_this_event) * 100.0) / static_cast<double>(expected_fragmentID_list_.size())) >= 10.0)
242 ++events_with_10pct_missing_fragments_;
244 if (((static_cast<double>(missing_fragment_count_this_event) * 100.0) /
static_cast<double>(expected_fragmentID_list_.size())) >= 50.0)
246 ++events_with_50pct_missing_fragments_;
249 if (((static_cast<double>(empty_fragment_count_this_event) * 100.0) /
static_cast<double>(expected_fragmentID_list_.size())) >= 10.0)
251 ++events_with_10pct_empty_fragments_;
253 if (((static_cast<double>(empty_fragment_count_this_event) * 100.0) /
static_cast<double>(expected_fragmentID_list_.size())) >= 50.0)
255 ++events_with_50pct_empty_fragments_;
258 metricMan->sendMetric(
"EventsWith10PctMissingFragments", events_with_10pct_missing_fragments_,
"events",
259 metrics_reporting_level_, artdaq::MetricMode::LastPoint);
260 metricMan->sendMetric(
"EventsWith50PctMissingFragments", events_with_50pct_missing_fragments_,
"events",
261 metrics_reporting_level_, artdaq::MetricMode::LastPoint);
263 metricMan->sendMetric(
"EventsWith10PctEmptyFragments", events_with_10pct_empty_fragments_,
"events",
264 metrics_reporting_level_, artdaq::MetricMode::LastPoint);
265 metricMan->sendMetric(
"EventsWith50PctEmptyFragments", events_with_50pct_empty_fragments_,
"events",
266 metrics_reporting_level_, artdaq::MetricMode::LastPoint);
268 TLOG(TLVL_FRACTIONAL_MODE) <<
"Event " << evt.event() <<
": events_with_10pct_missing_fragments=" << events_with_10pct_missing_fragments_
269 <<
", events_with_10pct_empty_fragments=" << events_with_10pct_empty_fragments_;
270 TLOG(TLVL_FRACTIONAL_MODE) <<
"Event " << evt.event() <<
": events_with_50pct_missing_fragments=" << events_with_50pct_missing_fragments_
271 <<
", events_with_50pct_empty_fragments=" << events_with_50pct_empty_fragments_;
275 if (metricMan !=
nullptr && mode_bitset_.test(DETAILED_COUNTS_MODE))
279 if (missing_fragment_count_this_event > 0 || empty_fragment_count_this_event > 0)
281 std::ostringstream oss;
282 oss <<
"<eventbuilder_snapshot app_name=\"" << app_name <<
"\"><events_processed>" << events_processed_
283 <<
"</events_processed>";
284 oss <<
"<missing_fragment_counts>";
285 for (
auto const& mapIter : missing_fragments_by_fragmentID_)
287 oss <<
"<count fragment_id=" << mapIter.first <<
">" << mapIter.second <<
"</count>";
289 oss <<
"</missing_fragment_counts>";
290 oss <<
"<empty_fragment_counts>";
291 for (
auto const& mapIter : empty_fragments_by_fragmentID_)
293 oss <<
"<count fragment_id=" << mapIter.first <<
">" << mapIter.second <<
"</count>";
295 oss <<
"</empty_fragment_counts>";
296 oss <<
"</eventbuilder_snapshot>";
298 metricMan->sendMetric(
"EmptyFragmentSnapshot", oss.str(),
"xml_string",
299 metrics_reporting_level_, artdaq::MetricMode::LastPoint);
304 ==================================================== =
306 event_builder_snapshot : {
307 name:
"EventBuilder5"
308 timestamp :
"20190408T124433"
311 sender_list : [
"felix501",
"felix501",
"ssp101",
"ssp102"]
312 valid_fragment_counts : [105, 105, 102, 104]
313 empty_fragment_counts : [0, 0, 2, 0]
314 missing_fragment_counts : [0, 0, 1, 1]
317 ==================================================== =
319 <event_builder_snapshot name =
"EventBuilder5">
320 < timestamp>20190408T124433< / timestamp>
321 < events_built>105 < / events_built
324 <sender index = 0>felix501< / sender>
325 <sender index = 1>felix502< / sender>
326 <sender index = 2>ssp101< / sender>
327 <sender index = 3>ssp102< / sender>
330 <valid_fragment_counts>
331 < count index = 0>105 < / count >
332 < count index = 1>105 < / count >
333 < count index = 2>102 < / count >
334 < count index = 3>104 < / count >
335 < / valid_fragment_counts>
337 <empty_fragment_counts>
338 < count index = 2>2 < / count >
339 < / empty_fragment_counts>
341 <missing_fragment_counts>
342 < count index = 2>1 < / count >
343 < count index = 3>1 < / count >
344 < / missing_fragment_counts>
345 < / event_builder_snapshot>
347 ==================================================== =
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.