Classes | Public Member Functions | Private Member Functions | Private Attributes | List of all members
dune::FelixIntegrityTest Class Reference
Inheritance diagram for dune::FelixIntegrityTest:
art::EDAnalyzer art::detail::Analyzer art::detail::LegacyModule art::Observer art::ModuleBase

Classes

struct  ErrorMetrics
 

Public Member Functions

 FelixIntegrityTest (fhicl::ParameterSet const &p)
 
 FelixIntegrityTest (FelixIntegrityTest const &)=delete
 
 FelixIntegrityTest (FelixIntegrityTest &&)=delete
 
FelixIntegrityTestoperator= (FelixIntegrityTest const &)=delete
 
FelixIntegrityTestoperator= (FelixIntegrityTest &&)=delete
 
void analyze (const art::Event &evt) override
 
void beginJob () override
 
void endJob () override
 
- Public Member Functions inherited from art::EDAnalyzer
 EDAnalyzer (fhicl::ParameterSet const &pset)
 
template<typename Config >
 EDAnalyzer (Table< Config > const &config)
 
std::string workerType () const
 
- Public Member Functions inherited from art::detail::Analyzer
virtual ~Analyzer () noexcept
 
 Analyzer (fhicl::ParameterSet const &pset)
 
template<typename Config >
 Analyzer (Table< Config > const &config)
 
void doBeginJob (SharedResources const &resources)
 
void doEndJob ()
 
void doRespondToOpenInputFile (FileBlock const &fb)
 
void doRespondToCloseInputFile (FileBlock const &fb)
 
void doRespondToOpenOutputFiles (FileBlock const &fb)
 
void doRespondToCloseOutputFiles (FileBlock const &fb)
 
bool doBeginRun (RunPrincipal &rp, ModuleContext const &mc)
 
bool doEndRun (RunPrincipal &rp, ModuleContext const &mc)
 
bool doBeginSubRun (SubRunPrincipal &srp, ModuleContext const &mc)
 
bool doEndSubRun (SubRunPrincipal &srp, ModuleContext const &mc)
 
bool doEvent (EventPrincipal &ep, ModuleContext const &mc, std::atomic< std::size_t > &counts_run, std::atomic< std::size_t > &counts_passed, std::atomic< std::size_t > &counts_failed)
 
- Public Member Functions inherited from art::Observer
 ~Observer () noexcept
 
 Observer (Observer const &)=delete
 
 Observer (Observer &&)=delete
 
Observeroperator= (Observer const &)=delete
 
Observeroperator= (Observer &&)=delete
 
void registerProducts (ProductDescriptions &, ModuleDescription const &)
 
void fillDescriptions (ModuleDescription const &)
 
fhicl::ParameterSetID selectorConfig () const
 
- Public Member Functions inherited from art::ModuleBase
virtual ~ModuleBase () noexcept
 
 ModuleBase ()
 
ModuleDescription const & moduleDescription () const
 
void setModuleDescription (ModuleDescription const &)
 
std::array< std::vector< ProductInfo >, NumBranchTypes > const & getConsumables () const
 
void sortConsumables (std::string const &current_process_name)
 
template<typename T , BranchType BT>
ViewToken< T > consumesView (InputTag const &tag)
 
template<typename T , BranchType BT>
ViewToken< T > mayConsumeView (InputTag const &tag)
 

Private Member Functions

ErrorMetrics _process (const artdaq::Fragment &frag)
 

Private Attributes

std::string _input_label
 
bool _expect_container_fragments
 
dune::FelixFragmentBase::Metadata run_meta = {0xcba}
 
const uint64_t timestamp_increase = 25
 
const uint16_t convert_count_increase = 1
 
std::vector< ErrorMetricstest_results
 
unsigned n_good_frags = 0
 
unsigned n_bad_frags = 0
 

Additional Inherited Members

- Public Types inherited from art::EDAnalyzer
using WorkerType = WorkerT< EDAnalyzer >
 
using ModuleType = EDAnalyzer
 
- Protected Member Functions inherited from art::Observer
std::string const & processName () const
 
bool wantAllEvents () const noexcept
 
bool wantEvent (ScheduleID id, Event const &e) const
 
Handle< TriggerResultsgetTriggerResults (Event const &e) const
 
 Observer (fhicl::ParameterSet const &config)
 
 Observer (std::vector< std::string > const &select_paths, std::vector< std::string > const &reject_paths, fhicl::ParameterSet const &config)
 
- Protected Member Functions inherited from art::ModuleBase
ConsumesCollectorconsumesCollector ()
 
template<typename T , BranchType = InEvent>
ProductToken< T > consumes (InputTag const &)
 
template<typename Element , BranchType = InEvent>
ViewToken< Element > consumesView (InputTag const &)
 
template<typename T , BranchType = InEvent>
void consumesMany ()
 
template<typename T , BranchType = InEvent>
ProductToken< T > mayConsume (InputTag const &)
 
template<typename Element , BranchType = InEvent>
ViewToken< Element > mayConsumeView (InputTag const &)
 
template<typename T , BranchType = InEvent>
void mayConsumeMany ()
 

Detailed Description

Definition at line 35 of file FelixIntegrityTest_module.cc.

Constructor & Destructor Documentation

dune::FelixIntegrityTest::FelixIntegrityTest ( fhicl::ParameterSet const &  p)
explicit

Definition at line 111 of file FelixIntegrityTest_module.cc.

112  : EDAnalyzer(pset),
113  _input_label(pset.get<std::string>("RawDataLabel")),
114  _expect_container_fragments(pset.get<bool>("ExpectContainerFragments", true)) {}
std::string string
Definition: nybbler.cc:12
EDAnalyzer(fhicl::ParameterSet const &pset)
Definition: EDAnalyzer.h:25
dune::FelixIntegrityTest::FelixIntegrityTest ( FelixIntegrityTest const &  )
delete
dune::FelixIntegrityTest::FelixIntegrityTest ( FelixIntegrityTest &&  )
delete

Member Function Documentation

dune::FelixIntegrityTest::ErrorMetrics dune::FelixIntegrityTest::_process ( const artdaq::Fragment &  frag)
private

Definition at line 240 of file FelixIntegrityTest_module.cc.

241 {
242  // Load overlay class
243  dune::FelixFragment flxfrag(frag);
244 
245  std::cout
246  << "-------------------- Testing fragment -------------------" << '\n'
247  << "SequenceID: " << frag.sequenceID()
248  << " fragmentID: " << frag.fragmentID()
249  << " fragmentType: " << (unsigned)frag.type()
250  << " Timestamp: " << frag.timestamp()
251  << " Crate number: " << (int)flxfrag.crate_no()
252  << " Slot number: " << (int)flxfrag.slot_no()
253  << " Fiber number: " << (int)flxfrag.fiber_no() << "\n\n";
254 
255  // Metadata tests
257  bool meta_failed = false;
258  // Record the first metadata, compare otherwise
259  if(run_meta.control_word == 0xcba) {
260  run_meta = *meta;
261  } else {
262  meta_failed |= meta->control_word != run_meta.control_word
263  || meta->version != run_meta.version
264  || meta->reordered != run_meta.reordered
265  || meta->compressed != run_meta.compressed
266  || meta->num_frames != run_meta.num_frames
269  if(meta_failed) {
270  std::cout
271  << "Metadata error." << '\n'
272  << " This fragment's metadata: " << '\n'
273  << " Control word: " << meta->control_word
274  << " Version: " << meta->version
275  << " Reordered: " << meta->reordered
276  << " Compressed: " << meta->compressed
277  << " Number of frames: " << meta->num_frames
278  << " Offset frames: " << meta->offset_frames
279  << " Window frames: " << meta->window_frames << '\n'
280  << " Expected metadata: " << '\n'
281  << " Control word: " << run_meta.control_word
282  << " Version: " << run_meta.version
283  << " Reordered: " << run_meta.reordered
284  << " Compressed: " << run_meta.compressed
285  << " Number of frames: " << run_meta.num_frames
286  << " Offset frames: " << run_meta.offset_frames
287  << " Window frames: " << run_meta.window_frames << "\n\n";
288  } else {
289  std::cout
290  << "Metadata test successful." << "\n\n";
291  }
292  }
293 
294  // Timestamp tests
295  bool timestamp_failed = false;
296  // Compare to metadata: first frame must be within 25 counts of the fragment timestamp
297  if(frag.timestamp() - meta->offset_frames*timestamp_increase - flxfrag.timestamp(0) >= timestamp_increase) {
298  timestamp_failed = true;
299  std::cout
300  << "First timestamp matching error." << '\n'
301  << " This fragment's timestamp: " << frag.timestamp()
302  << " First frame's timestamp: " << flxfrag.timestamp(0)
303  << " Expected offset (-24 or less): " << meta->offset_frames*timestamp_increase
304  << " Offset: " << frag.timestamp() - flxfrag.timestamp(0) << "\n\n";
305  }
306  // Make sure the correct number of frames is contained when compared to the metadata
307  if(flxfrag.total_frames() != meta->window_frames) {
308  timestamp_failed = true;
309  std::cout
310  << "Trigger window error." << '\n'
311  << " This fragment's expected number of frames: " << meta->window_frames
312  << " Number of frames available: " << flxfrag.timestamp(0) << "\n\n";
313  }
314  // Go through all timestamps and check their increase
315  for(unsigned fi = 1; fi < flxfrag.total_frames(); ++fi) {
316  if(flxfrag.timestamp(fi) - flxfrag.timestamp(fi-1) != timestamp_increase) {
317  timestamp_failed = true;
318  std::cout
319  << "Timestamp increase error." << '\n'
320  << " Timestamp of frame " << fi - 1 << ": " << flxfrag.timestamp(fi-1)
321  << " Timestamp of frame " << fi << ": " << flxfrag.timestamp(fi)
322  << " Difference: " << flxfrag.timestamp(fi) - flxfrag.timestamp(fi-1) << "\n\n";
323  break;
324  }
325  }
326  if(!timestamp_failed) {
327  std::cout
328  << "Timestamp test successful." << "\n\n";
329  }
330 
331  // Convert count test
332  bool convert_count_failed = false;
333  // Check the increase of all convert counts between frames
334  for(unsigned fi = 1; fi < flxfrag.total_frames(); ++fi) {
335  // The first two counts and last two counts need to be identical
336  for(int bi = 0; bi < 2; ++bi) {
337  if(flxfrag.coldata_convert_count(fi, 2*bi) != flxfrag.coldata_convert_count(fi, 2*bi + 1)
338  || (flxfrag.coldata_convert_count(fi, bi) - flxfrag.coldata_convert_count(fi - 1, bi)
340  && flxfrag.coldata_convert_count(fi, bi) - flxfrag.coldata_convert_count(fi - 1, bi)
341  != convert_count_increase - (1<<16))) {
342  convert_count_failed = true;
343  std::cout
344  << "COLDATA convert count increase error in frame " << fi << ".\n"
345  << " Count 1 of frame " << fi - 1 << ": " << flxfrag.coldata_convert_count(fi-1, 0)
346  << " Count 2 of frame " << fi - 1 << ": " << flxfrag.coldata_convert_count(fi-1, 1)
347  << " Count 3 of frame " << fi - 1 << ": " << flxfrag.coldata_convert_count(fi-1, 2)
348  << " Count 4 of frame " << fi - 1 << ": " << flxfrag.coldata_convert_count(fi-1, 3) << '\n'
349  << " Count 1 of frame " << fi << ": " << flxfrag.coldata_convert_count(fi, 0)
350  << " Count 2 of frame " << fi << ": " << flxfrag.coldata_convert_count(fi, 1)
351  << " Count 3 of frame " << fi << ": " << flxfrag.coldata_convert_count(fi, 2)
352  << " Count 4 of frame " << fi << ": " << flxfrag.coldata_convert_count(fi, 3) << '\n'
353  << " Difference: "
354  << flxfrag.coldata_convert_count(fi, 0) - flxfrag.coldata_convert_count(fi-1, 0) << "\n\n";
355  break;
356  }
357  }
358  if(convert_count_failed) break;
359  }
360  if(!convert_count_failed) {
361  std::cout
362  << "COLDATA convert count test successful." << "\n\n";
363  }
364 
365  // Frame error fields test
366  bool error_field_failed = false;
367  // Check all error fields in all frames without distinction for now
368  // // TODO: Look into what errors are relevant!
369  // for(unsigned fi = 0; fi < 0/*flxfrag.total_frames()*/; ++fi) {
370  // error_field_failed |= flxfrag.mm(fi) || flxfrag.oos(fi) || flxfrag.wib_errors(fi);
371  // for(unsigned bi = 0; bi < 4; ++bi) {
372  // error_field_failed |= flxfrag.s1_error(fi, bi) || flxfrag.s2_error(fi, bi)
373  // || flxfrag.error_register(fi, bi);
374  // }
375  //
376  // if(error_field_failed) {
377  // std::cout
378  // << "One or more error fields set in frame " << fi << ".\n"
379  // << " Mismatch: " << (int)flxfrag.mm(fi)
380  // << " Out of sync: " << (int)flxfrag.oos(fi)
381  // << " WIB errors: " << (int)flxfrag.wib_errors(fi) << '\n';
382  // for(unsigned bi = 0; bi < 4; ++bi) {
383  // std::cout
384  // << " Block " << bi+1 << ":\n"
385  // << " Stream 1 error: " << (int)flxfrag.s1_error(fi, bi)
386  // << " Stream 2 error: " << (int)flxfrag.s2_error(fi, bi)
387  // << " Error register: " << (int)flxfrag.error_register(fi, bi) << '\n';
388  // }
389  // std::cout << '\n';
390  // break;
391  // }
392  // }
393 
394  //Output error metrics
395  ErrorMetrics outem;
396  outem.sequenceID = frag.sequenceID();
397  outem.fragmentID = frag.fragmentID();
398  outem.type = frag.type();
399  outem.timestamp = frag.timestamp();
400  outem.crate_no = flxfrag.crate_no();
401  outem.slot_no = flxfrag.slot_no();
402  outem.fiber_no = flxfrag.fiber_no();
403  outem.meta = *meta;
404  outem.meta_err = meta_failed;
405  outem.timestamp_err = timestamp_failed;
406  outem.convert_count_err = convert_count_failed;
407  outem.error_fields_set = error_field_failed;
408 
409  outem.bad = timestamp_failed || convert_count_failed || error_field_failed;
410 
411  return outem;
412 }
dune::FelixFragmentBase::Metadata run_meta
void dune::FelixIntegrityTest::analyze ( const art::Event evt)
override

Definition at line 119 of file FelixIntegrityTest_module.cc.

119  {
120  std::cout << "-------------------- FELIX Integrity Test -------------------";
121 
123  art::InputTag itag1(_input_label, "ContainerFELIX");
124  auto cont_frags = evt.getHandle<artdaq::Fragments>(itag1);
125  art::EventNumber_t eventNumber = evt.event();
126  // Check if there is Timing data in this event
127  // Don't crash code if not present, just don't save anything
128  try { cont_frags->size(); }
129  catch(std::exception const&) {
130  std::cout << "WARNING: Container FELIX data not found in event " << eventNumber << std::endl;
131  return;
132  }
133  //Check that the data is valid
134  if (!cont_frags){
135  MF_LOG_ERROR("FelixIntegrityTest")
136  << "Run: " << evt.run()
137  << ", SubRun: " << evt.subRun()
138  << ", Event: " << evt.event()
139  << " Container Fragment data invalid";
140  }
141 
142  for (auto const& cont : *cont_frags)
143  {
144  artdaq::ContainerFragment cont_frag(cont);
145  for (size_t ii = 0; ii < cont_frag.block_count(); ++ii)
146  {
147  const ErrorMetrics this_err = _process(*cont_frag[ii]);
148  test_results.push_back(this_err);
149  this_err.bad? ++n_bad_frags : ++n_good_frags;
150  }
151  }
152  }
153  else
154  {
155  art::InputTag itag2(_input_label, "FELIX");
156  auto frags = evt.getHandle<artdaq::Fragments>(itag2);
157  // Check if there is Timing data in this event
158  // Don't crash code if not present, just don't save anything
159  art::EventNumber_t eventNumber = evt.event();
160  try { frags->size(); }
161  catch(std::exception const&) {
162  std::cout << "WARNING: Raw FELIX data not found in event " << eventNumber << std::endl;
163  return;
164  }
165 
166  //Check that the data is valid
167  if (!frags){
168  MF_LOG_ERROR("FelixIntegrityTest")
169  << "Run: " << evt.run()
170  << ", SubRun: " << evt.subRun()
171  << ", Event: " << evt.event()
172  << " Fragment data invalid";
173  }
174 
175  for(auto const& frag: *frags)
176  {
177  const ErrorMetrics this_err = _process(frag);
178  test_results.push_back(this_err);
179  this_err.bad? ++n_bad_frags : ++n_good_frags;
180  }
181  }
182 }
EventNumber_t event() const
Definition: DataViewImpl.cc:85
Handle< PROD > getHandle(SelectorBase const &) const
Definition: DataViewImpl.h:382
std::vector< ErrorMetrics > test_results
#define MF_LOG_ERROR(category)
SubRunNumber_t subRun() const
Definition: DataViewImpl.cc:78
RunNumber_t run() const
Definition: DataViewImpl.cc:71
IDNumber_t< Level::Event > EventNumber_t
Definition: IDNumber.h:118
std::vector< Fragment > Fragments
Definition: HDF5Utils.h:57
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
QTextStream & endl(QTextStream &s)
ErrorMetrics _process(const artdaq::Fragment &frag)
void dune::FelixIntegrityTest::beginJob ( )
overridevirtual

Reimplemented from art::EDAnalyzer.

Definition at line 116 of file FelixIntegrityTest_module.cc.

116  {
117 }
void dune::FelixIntegrityTest::endJob ( )
overridevirtual

Reimplemented from art::EDAnalyzer.

Definition at line 184 of file FelixIntegrityTest_module.cc.

184  {
185  const unsigned long n_frags = n_bad_frags + n_good_frags;
186  std::cout
187  << "\nProcessed " << n_bad_frags+n_good_frags
188  << " FELIX Fragments.\nFound " << n_good_frags
189  << " good fragments. Success rate: "
190  << (double)n_good_frags/n_frags << "/1.\n\n";
191 
192  // Create structs for easier looping.
193  struct Location {
194  uint64_t crate_no, slot_no, fiber_no;
195  bool operator<(const Location& b) const {
196  if(crate_no == b.crate_no && slot_no == b.slot_no) {
197  return fiber_no < b.fiber_no;
198  } else if(crate_no == b.crate_no) {
199  return slot_no < b.slot_no;
200  }
201  return crate_no < b.crate_no;
202  }
203  };
204  struct Errors {
205  unsigned long meta_err, timestamp_err, convert_count_err, error_fields_set;
206  void operator+=(const Errors& other) {
207  meta_err += other.meta_err;
208  timestamp_err += other.timestamp_err;
209  convert_count_err += other.convert_count_err;
210  error_fields_set += other.error_fields_set;
211  }
212  };
213  // Loop over collected error metrics to find their origin
214  std::map<Location, Errors> errMap;
215  for(const ErrorMetrics& errm : test_results) {
216  Location loc = {errm.crate_no, errm.slot_no, errm.fiber_no};
217  Errors err = {(unsigned long)errm.meta_err, (unsigned long)errm.timestamp_err,
218  (unsigned long)errm.convert_count_err, (unsigned long)errm.error_fields_set};
219  errMap[loc] += err;
220  }
221  // Print the error rate in a nice table
222  std::cout << "Error rates\n";
223  std::cout << "Crate:Slot:Fiber | Metadata error | Timestamp error | Convert count error | Error fields set\n"
224  << "--------------------------------------------------------------------------------------------\n";
225  for(const std::pair<Location, Errors>& p : errMap) {
226  std::cout << std::left << std::setw(16) << std::to_string(p.first.crate_no) + ":" + std::to_string(p.first.slot_no) + ":" + std::to_string(p.first.fiber_no) << " | ";
227  if(p.second.meta_err) std::cout << std::setw(14) << (double)p.second.meta_err/n_frags << " | ";
228  else std::cout << std::setw(14) << " " << " | ";
229  if(p.second.timestamp_err) std::cout << std::setw(15) << (double)p.second.timestamp_err/n_frags << " | ";
230  else std::cout << std::setw(15) << " " << " | ";
231  if(p.second.convert_count_err) std::cout << std::setw(19) << (double)p.second.convert_count_err/n_frags << " | ";
232  else std::cout << std::setw(19) << " " << " | ";
233  if(p.second.error_fields_set) std::cout << std::setw(16) << (double)p.second.error_fields_set/n_frags;
234  else std::cout << std::setw(16) << " ";
235 
236  std::cout << '\n';
237  }
238 }
DoubleProduct & operator+=(DoubleProduct &left, DoubleProduct const &right)
Definition: ToyProducts.h:103
std::vector< ErrorMetrics > test_results
bool operator<(ProductInfo const &a, ProductInfo const &b)
Definition: ProductInfo.cc:51
p
Definition: test.py:223
void err(const char *fmt,...)
Definition: message.cpp:226
Q_EXPORT QTSManip setw(int w)
Definition: qtextstream.h:331
static bool * b
Definition: config.cpp:1043
std::string to_string(ModuleType const mt)
Definition: ModuleType.h:34
FelixIntegrityTest& dune::FelixIntegrityTest::operator= ( FelixIntegrityTest const &  )
delete
FelixIntegrityTest& dune::FelixIntegrityTest::operator= ( FelixIntegrityTest &&  )
delete

Member Data Documentation

bool dune::FelixIntegrityTest::_expect_container_fragments
private

Definition at line 95 of file FelixIntegrityTest_module.cc.

std::string dune::FelixIntegrityTest::_input_label
private

Definition at line 94 of file FelixIntegrityTest_module.cc.

const uint16_t dune::FelixIntegrityTest::convert_count_increase = 1
private

Definition at line 104 of file FelixIntegrityTest_module.cc.

unsigned dune::FelixIntegrityTest::n_bad_frags = 0
private

Definition at line 107 of file FelixIntegrityTest_module.cc.

unsigned dune::FelixIntegrityTest::n_good_frags = 0
private

Definition at line 106 of file FelixIntegrityTest_module.cc.

dune::FelixFragmentBase::Metadata dune::FelixIntegrityTest::run_meta = {0xcba}
private

Definition at line 98 of file FelixIntegrityTest_module.cc.

std::vector<ErrorMetrics> dune::FelixIntegrityTest::test_results
private

Definition at line 105 of file FelixIntegrityTest_module.cc.

const uint64_t dune::FelixIntegrityTest::timestamp_increase = 25
private

Definition at line 101 of file FelixIntegrityTest_module.cc.


The documentation for this class was generated from the following file: