FelixFragment.hh
Go to the documentation of this file.
1 // FelixFragment.hh edited from ToyFragment.hh by Milo Vermeulen and Roland
2 // Sipos (2017) to accept WIB frames.
3 
4 #ifndef artdaq_dune_Overlays_FelixFragment_hh
5 #define artdaq_dune_Overlays_FelixFragment_hh
6 
7 #include "FragmentType.hh"
8 #include "artdaq-core/Data/Fragment.hh"
11 
12 #include <zlib.h>
13 #include <iostream>
14 #include <map>
15 #include <vector>
16 
17 // Implementation of "FelixFragment", an artdaq::FelixFragment overlay
18 // class used for WIB->FELIX frames.
19 //
20 // The intention of this class is to provide an Overlay for a 12-bit ADC
21 // module.
22 
23 namespace dune {
24 // fwd declare FelixFragment
25 class FelixFragmentBase;
26 class FelixFragmentUnordered;
27 class FelixFragmentReordered;
28 class FelixFragmentCompressed;
29 class FelixFragment;
30 } // namespace dune
31 
32 //============================
33 // FELIX fragment base class
34 //============================
36  public:
37  /* Struct to hold FelixFragment Metadata. */
38  struct Metadata {
39  typedef uint32_t data_t;
40 
41  // Old metadata.
42  // data_t num_frames : 16, reordered : 8, compressed : 8;
43  // data_t offset_frames : 16, window_frames : 16;
44 
45  data_t control_word : 12, version : 4, reordered : 8, compressed : 8;
46  data_t num_frames;
47  data_t offset_frames;
48  data_t window_frames;
49 
50  static size_t const size_words = 4ul; /* Units of Metadata::data_t */
51 
52  bool operator==(const Metadata& rhs) {
53  return (control_word == rhs.control_word) && (version == rhs.version) &&
54  (reordered == rhs.reordered) && (compressed == rhs.compressed) &&
55  (num_frames == rhs.num_frames) &&
56  (offset_frames == rhs.offset_frames) &&
57  (window_frames == rhs.window_frames);
58  }
59 
60  bool operator!=(const Metadata& rhs) { return !(*this == rhs); }
61  };
62 
63  struct Old_Metadata {
64  typedef uint32_t data_t;
65  data_t num_frames : 16, reordered : 8, compressed : 8;
66  data_t offset_frames : 16, window_frames : 16;
67 
68  bool operator==(const Metadata& rhs) {
69  return (num_frames == rhs.num_frames) && (reordered == rhs.reordered) &&
70  (compressed == rhs.compressed) &&
71  (offset_frames == rhs.offset_frames) &&
73  }
74 
75  bool operator!=(const Metadata& rhs) { return !(*this == rhs); }
76  };
77 
78  static_assert(sizeof(Metadata) ==
80  "FelixFragment::Metadata size changed");
81 
82  /* Frame field and accessors. */
83  virtual uint8_t sof(const unsigned& frame_ID = 0) const = 0;
84  virtual uint8_t version(const unsigned& frame_ID = 0) const = 0;
85  virtual uint8_t fiber_no(const unsigned& frame_ID = 0) const = 0;
86  virtual uint8_t slot_no(const unsigned& frame_ID = 0) const = 0;
87  virtual uint8_t crate_no(const unsigned& frame_ID = 0) const = 0;
88  virtual uint8_t mm(const unsigned& frame_ID = 0) const = 0;
89  virtual uint8_t oos(const unsigned& frame_ID = 0) const = 0;
90  virtual uint16_t wib_errors(const unsigned& frame_ID = 0) const = 0;
91  virtual uint64_t timestamp(const unsigned& frame_ID = 0) const = 0;
92  virtual uint16_t wib_counter(const unsigned& frame_ID = 0) const = 0;
93 
94  /* Coldata block accessors. */
95  virtual uint8_t s1_error(const unsigned& frame_ID,
96  const uint8_t& block_num) const = 0;
97  virtual uint8_t s2_error(const unsigned& frame_ID,
98  const uint8_t& block_num) const = 0;
99  virtual uint16_t checksum_a(const unsigned& frame_ID,
100  const uint8_t& block_num) const = 0;
101  virtual uint16_t checksum_b(const unsigned& frame_ID,
102  const uint8_t& block_num) const = 0;
103  virtual uint16_t coldata_convert_count(const unsigned& frame_ID,
104  const uint8_t& block_num) const = 0;
105  virtual uint16_t error_register(const unsigned& frame_ID,
106  const uint8_t& block_num) const = 0;
107  virtual uint8_t hdr(const unsigned& frame_ID, const uint8_t& block_num,
108  const uint8_t& hdr_num) const = 0;
109 
110  // Function to return a certain ADC value.
111  virtual adc_t get_ADC(const unsigned& frame_ID,
112  const uint8_t channel_ID) const = 0;
113 
114  // Function to print all timestamps.
115  virtual void print_timestamps() const = 0;
116 
117  virtual void print(const unsigned i) const = 0;
118 
119  virtual void print_frames() const = 0;
120 
121  FelixFragmentBase(const artdaq::Fragment& fragment)
122  : meta_(*(fragment.metadata<Metadata>())),
123  artdaq_Fragment_(fragment.dataBeginBytes()),
124  sizeBytes_(fragment.dataSizeBytes()) {
125  // Check whether the metadata is of the old format.
126  if (meta_.control_word != 0xabc &&
127  !(meta_.num_frames == 6024 && meta_.offset_frames == 500 &&
128  meta_.window_frames == 6000)) {
129  // mf::LogInfo("dune::FelixFragment")
130  // << "Fragment has old metadata format. (Control word "
131  // << (unsigned)meta_.control_word << ")\n";
132  const Old_Metadata* old_meta = fragment.metadata<Old_Metadata>();
133  meta_ = {0,
134  0,
135  old_meta->reordered,
136  old_meta->compressed,
137  old_meta->num_frames,
138  old_meta->offset_frames,
139  old_meta->window_frames};
140  }
141 
142  // Deal with very long fragments that overflow the frame counter.
143  if (fragment.dataSizeBytes() > meta_.num_frames*sizeof(dune::FelixFrame)*3) {
144  // Assume uncompressed data.
145  meta_.reordered = 0;
146  meta_.compressed = 0;
147  meta_.num_frames = fragment.dataSizeBytes()/sizeof(dune::FelixFrame);
148  // Assume the offset is 11 frames at most.
149  meta_.window_frames = fragment.dataSizeBytes()/sizeof(dune::FelixFrame)-12;
150  }
151  // Check whether current metadata makes sense and guess the format
152  // otherwise.
153  else if (meta_.reordered > 1 || meta_.compressed > 1 ||
155  // Assume 6024 frames in a fragment if there is no meaningful metadata.
156  meta_.num_frames = 6024;
157  meta_.offset_frames = 500;
158  meta_.window_frames = 6000;
159  // Try to predict reordered/compressed from fragment size.
160  unsigned sizeBytes = fragment.dataSizeBytes();
161  if (sizeBytes == meta_.num_frames * 464) {
162  meta_.reordered = 0;
163  meta_.compressed = 0;
164  } else if (sizeBytes > meta_.num_frames * 592) {
165  // Assume compression factor > 1.
166  meta_.reordered = 1;
167  meta_.compressed = 0;
168  } else {
169  // Assume reordered if compressed.
170  meta_.reordered = 1;
171  meta_.compressed = 1;
172  }
173  }
174  }
175  virtual ~FelixFragmentBase() {}
176 
177  // The number of words in the current event minus the header.
178  virtual size_t total_words() const = 0;
179  // The number of frames in the current event.
180  virtual size_t total_frames() const = 0;
181  // The number of ADC values describing data beyond the header
182  virtual size_t total_adc_values() const = 0;
183  // Largest ADC value possible
184  virtual size_t adc_range(int daq_adc_bits = 12) {
185  return (1ul << daq_adc_bits);
186  }
187 
188  // Raw data access (const only).
189  const uint8_t* dataBeginBytes() const {
190  return reinterpret_cast<uint8_t const*>(artdaq_Fragment_);
191  }
192  size_t dataSizeBytes() const { return sizeBytes_; }
193 
194  protected:
196  const void* artdaq_Fragment_;
197  size_t sizeBytes_;
198 }; // class dune::FelixFragmentBase
199 
200 //==================================================
201 // FELIX fragment for an array of bare FELIX frames
202 //==================================================
204  public:
205  /* Frame field and accessors. */
206  uint8_t sof(const unsigned& frame_ID = 0) const {
207  return frame_(frame_ID)->sof();
208  }
209  uint8_t version(const unsigned& frame_ID = 0) const {
210  return frame_(frame_ID)->version();
211  }
212  uint8_t fiber_no(const unsigned& frame_ID = 0) const {
213  return frame_(frame_ID)->fiber_no();
214  }
215  uint8_t slot_no(const unsigned& frame_ID = 0) const {
216  return frame_(frame_ID)->slot_no();
217  }
218  uint8_t crate_no(const unsigned& frame_ID = 0) const {
219  return frame_(frame_ID)->crate_no();
220  }
221  uint8_t mm(const unsigned& frame_ID = 0) const {
222  return frame_(frame_ID)->mm();
223  }
224  uint8_t oos(const unsigned& frame_ID = 0) const {
225  return frame_(frame_ID)->oos();
226  }
227  uint16_t wib_errors(const unsigned& frame_ID = 0) const {
228  return frame_(frame_ID)->wib_errors();
229  }
230  uint64_t timestamp(const unsigned& frame_ID = 0) const {
231  return frame_(frame_ID)->timestamp();
232  }
233  uint16_t wib_counter(const unsigned& frame_ID = 0) const {
234  return frame_(frame_ID)->wib_counter();
235  }
236 
237  /* Coldata block accessors. */
238  uint8_t s1_error(const unsigned& frame_ID, const uint8_t& block_num) const {
239  return frame_(frame_ID)->s1_error(block_num);
240  }
241  uint8_t s2_error(const unsigned& frame_ID, const uint8_t& block_num) const {
242  return frame_(frame_ID)->s2_error(block_num);
243  }
244  uint16_t checksum_a(const unsigned& frame_ID,
245  const uint8_t& block_num) const {
246  return frame_(frame_ID)->checksum_a(block_num);
247  }
248  uint16_t checksum_b(const unsigned& frame_ID,
249  const uint8_t& block_num) const {
250  return frame_(frame_ID)->checksum_b(block_num);
251  }
252  uint16_t coldata_convert_count(const unsigned& frame_ID,
253  const uint8_t& block_num) const {
254  return frame_(frame_ID)->coldata_convert_count(block_num);
255  }
256  uint16_t error_register(const unsigned& frame_ID,
257  const uint8_t& block_num) const {
258  return frame_(frame_ID)->error_register(block_num);
259  }
260  uint8_t hdr(const unsigned& frame_ID, const uint8_t& block_num,
261  const uint8_t& hdr_num) const {
262  return frame_(frame_ID)->hdr(block_num, hdr_num);
263  }
264 
265  // Function to return a certain ADC value.
266  adc_t get_ADC(const unsigned& frame_ID, const uint8_t channel_ID) const {
267  return frame_(frame_ID)->channel(channel_ID);
268  }
269 
270  // Function to print all timestamps.
271  void print_timestamps() const {
272  for (unsigned int i = 0; i < total_frames(); i++) {
273  std::cout << std::hex << frame_(i)->timestamp() << '\t' << std::dec << i
274  << std::endl;
275  }
276  }
277 
278  void print(const unsigned i) const { frame_(i)->print(); }
279 
280  void print_frames() const {
281  for (unsigned i = 0; i < total_frames(); i++) {
282  frame_(i)->print();
283  }
284  }
285 
286  // The constructor simply sets its const private member "artdaq_Fragment_"
287  // to refer to the artdaq::Fragment object
288  FelixFragmentUnordered(artdaq::Fragment const& fragment)
289  : FelixFragmentBase(fragment) {}
290 
291  // The number of words in the current event minus the header.
292  size_t total_words() const { return sizeBytes_ / sizeof(word_t); }
293  // The number of frames in the current event.
294  size_t total_frames() const { return meta_.window_frames; }
295  // The number of ADC values describing data beyond the header
296  size_t total_adc_values() const {
298  }
299 
300  protected:
301  // Allow access to individual frames according to the FelixFrame structure.
302  FelixFrame const* frame_(const unsigned& frame_num = 0) const {
303  // WARNING: CUSTOM OFFSET OF EIGHT WORDS FOR DEBUGGING -- backed out as it
304  // was not needed
305  // return reinterpret_cast<dune::FelixFrame const*>(static_cast<uint32_t
306  // const*>(artdaq_Fragment_)+8) + frame_num;
307  return reinterpret_cast<dune::FelixFrame const*>(
308  static_cast<uint32_t const*>(artdaq_Fragment_)) +
309  frame_num;
310  }
311 }; // class dune::FelixFragmentUnordered
312 
313 //=======================================================
314 // FELIX fragment for an array of reordered FELIX frames
315 //=======================================================
317  public:
318  /* Frame field and accessors. */
319  uint8_t sof(const unsigned& frame_ID = 0) const {
320  return head_(frame_ID)->sof;
321  }
322  uint8_t version(const unsigned& frame_ID = 0) const {
323  return head_(frame_ID)->version;
324  }
325  uint8_t fiber_no(const unsigned& frame_ID = 0) const {
326  return head_(frame_ID)->fiber_no;
327  }
328  uint8_t slot_no(const unsigned& frame_ID = 0) const {
329  return head_(frame_ID)->slot_no;
330  }
331  uint8_t crate_no(const unsigned& frame_ID = 0) const {
332  return head_(frame_ID)->crate_no;
333  }
334  uint8_t mm(const unsigned& frame_ID = 0) const { return head_(frame_ID)->mm; }
335  uint8_t oos(const unsigned& frame_ID = 0) const {
336  return head_(frame_ID)->oos;
337  }
338  uint16_t wib_errors(const unsigned& frame_ID = 0) const {
339  return head_(frame_ID)->wib_errors;
340  }
341  uint64_t timestamp(const unsigned& frame_ID = 0) const {
342  uint64_t result = head_(frame_ID)->timestamp();
343  if (header_is_faulty(frame_ID) == false) {
344  // Deduce timestamp from first header,
345  result += frame_ID * 25;
346  }
347  return result;
348  }
349  uint16_t wib_counter(const unsigned& frame_ID = 0) const {
350  return head_(frame_ID)->wib_counter();
351  }
352 
353  /* Coldata block accessors. */
354  uint8_t s1_error(const unsigned& frame_ID, const uint8_t& block_num) const {
355  return blockhead_(frame_ID, block_num)->s1_error;
356  }
357  uint8_t s2_error(const unsigned& frame_ID, const uint8_t& block_num) const {
358  return blockhead_(frame_ID, block_num)->s2_error;
359  }
360  uint16_t checksum_a(const unsigned& frame_ID,
361  const uint8_t& block_num) const {
362  return blockhead_(frame_ID, block_num)->checksum_a();
363  }
364  uint16_t checksum_b(const unsigned& frame_ID,
365  const uint8_t& block_num) const {
366  return blockhead_(frame_ID, block_num)->checksum_b();
367  }
368  uint16_t coldata_convert_count(const unsigned& frame_ID,
369  const uint8_t& block_num) const {
370  uint16_t result = blockhead_(frame_ID, block_num)->coldata_convert_count;
371  if (header_is_faulty(frame_ID) == false) {
372  // Deduce count from first header.
373  result += frame_ID;
374  }
375  return result;
376  }
377  uint16_t error_register(const unsigned& frame_ID,
378  const uint8_t& block_num) const {
379  return blockhead_(frame_ID, block_num)->error_register;
380  }
381  uint8_t hdr(const unsigned& frame_ID, const uint8_t& block_num,
382  const uint8_t& hdr_num) const {
383  return blockhead_(frame_ID, block_num)->hdr(hdr_num);
384  }
385 
386  // Function to return a certain ADC value.
387  adc_t get_ADC(const unsigned& frame_ID, const uint8_t channel_ID) const {
388  return channel_(frame_ID, channel_ID);
389  }
390 
391  // Function to print all timestamps.
392  void print_timestamps() const {
393  // for (unsigned int i = 0; i < total_frames(); i++) {
394  // std::cout << std::hex << frames_()->timestamp(i) << '\t' << std::dec <<
395  // i
396  // << std::endl;
397  // }
398  }
399 
400  void print(const unsigned i) const {
401  std::cout << "Frame " << i
402  << " should be printed here.\n"; /* frames_()->print(i); */
403  }
404 
405  void print_frames() const {
406  // for (unsigned i = 0; i < total_frames(); i++) {
407  // frames_()->print(i);
408  // }
409  }
410 
411  // The constructor simply sets its const private member "artdaq_Fragment_"
412  // to refer to the artdaq::Fragment object
413  FelixFragmentReordered(artdaq::Fragment const& fragment)
414  : FelixFragmentBase(fragment), bad_header_num(meta_.num_frames, 0) {
415  // Go through the bad headers and assign each a number.
416  unsigned int bad_header_count = 1;
417  for (unsigned int i = 0; i < meta_.num_frames; ++i) {
418  if (header_is_faulty(i)) {
419  bad_header_num[i] = bad_header_count++;
420  }
421  // std::cout << bad_header_num[i] << '\n';
422  }
423  }
424 
425  // The number of words in the current event minus the header.
426  size_t total_words() const { return sizeBytes_ / sizeof(word_t); }
427 
428  // The number of frames in the current event.
429  size_t total_frames() const { return meta_.window_frames; }
430 
431  // The number of ADC values describing data beyond the header
432  size_t total_adc_values() const {
434  }
435 
436  protected:
437  // Important positions within the data buffer.
438  const unsigned int adc_start = 0;
439  const unsigned int bitlist_start =
440  adc_start + meta_.num_frames * 256 * sizeof(adc_t);
441  const unsigned int header_start = bitlist_start + (meta_.num_frames + 7) / 8;
442  // Size of WIB header + four COLDATA headers.
443  const unsigned int header_set_size =
444  sizeof(dune::WIBHeader) + 4 * sizeof(dune::ColdataHeader);
445 
446  // Faulty header information.
447  bool header_is_faulty(const unsigned int frame_num) const {
448  const uint8_t* curr_byte = static_cast<uint8_t const*>(artdaq_Fragment_) +
449  bitlist_start + frame_num / 8;
450  return ((*curr_byte) >> (frame_num % 8)) & 1;
451  }
452  // Number of the faulty header (0 if header is good).
453  std::vector<unsigned int> bad_header_num;
454 
455  // Reordered frame format overlaid on the data.
456  dune::WIBHeader const* head_(const unsigned int frame_num) const {
457  if (header_is_faulty(frame_num)) {
458  // Return faulty header.
459  return reinterpret_cast<dune::WIBHeader const*>(
460  static_cast<uint8_t const*>(artdaq_Fragment_) + header_start +
461  bad_header_num[frame_num] * header_set_size);
462  } else {
463  // Return the first header unchanged if requested header is good.
464  return reinterpret_cast<dune::WIBHeader const*>(
465  static_cast<uint8_t const*>(artdaq_Fragment_) + header_start);
466  }
467  }
468 
469  dune::ColdataHeader const* blockhead_(const unsigned int frame_num,
470  const uint8_t block_num) const {
471  if (header_is_faulty(frame_num)) {
472  // Return faulty header.
473  return reinterpret_cast<dune::ColdataHeader const*>(
474  static_cast<uint8_t const*>(artdaq_Fragment_) + header_start +
475  sizeof(dune::WIBHeader) +
476  bad_header_num[frame_num] * header_set_size) +
477  block_num;
478  } else {
479  // Return the first header unchanged if the requested header is good.
480  return reinterpret_cast<dune::ColdataHeader const*>(
481  static_cast<uint8_t const*>(artdaq_Fragment_) + header_start +
482  sizeof(dune::WIBHeader)) +
483  block_num;
484  }
485  }
486 
487  dune::adc_t channel_(const unsigned int frame_num,
488  const uint8_t ch_num) const {
489  return *(reinterpret_cast<dune::adc_t const*>(
490  static_cast<uint8_t const*>(artdaq_Fragment_) + adc_start) +
491  frame_num + ch_num * meta_.num_frames);
492  }
493 }; // class dune::FelixFragmentReordered
494 
495 //=======================================
496 // FELIX fragment for compressed frames.
497 //=======================================
499  private:
500  int decompress_copy(const artdaq::Fragment& src, artdaq::Fragment& dst) {
501  // Determine and reserve new fragment size.
502  long unsigned int uncompSizeBytes;
503  if (meta_.reordered) {
504  uncompSizeBytes = meta_.num_frames * (sizeof(dune::WIBHeader) +
505  4 * sizeof(dune::ColdataHeader) +
506  256 * sizeof(dune::adc_t));
507  // Account for bitfields
508  uncompSizeBytes += (meta_.num_frames + 7) / 8;
509  } else {
510  uncompSizeBytes = meta_.num_frames * sizeof(dune::FelixFrame);
511  }
512  dst.resizeBytes(uncompSizeBytes);
513 
514  int num_bytes = internal_inflate(src.dataBeginBytes(), src.dataSizeBytes(),
515  dst.dataBeginBytes(), dst.dataSizeBytes());
516 
517  return num_bytes;
518  }
519 
520  int internal_inflate(const void* src, uint srcLen, void* dst, uint dstLen) {
521  z_stream strm = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
522  strm.total_in = strm.avail_in = srcLen;
523  strm.total_out = strm.avail_out = dstLen;
524  strm.next_in = (Bytef*)src;
525  strm.next_out = (Bytef*)dst;
526 
527  strm.zalloc = Z_NULL;
528  strm.zfree = Z_NULL;
529  strm.opaque = Z_NULL;
530 
531  unsigned read = 0;
532  unsigned write = 0;
533  int err = 0;
534 
535  while (read < srcLen && write < dstLen) {
536  strm.next_in = (Bytef*)src + read;
537  strm.next_out = (Bytef*)dst + write;
538 
539  unsigned to_read = srcLen - read;
540  unsigned to_write = dstLen - write;
541 
542  if (to_read < 20) {
543  // This cant possibly be a frag
544  break;
545  }
546 
547  strm.total_in = strm.avail_in = to_read;
548  strm.total_out = strm.avail_out = to_write;
549 
550  inflateInit2(&strm, MAX_WBITS | 16);
551  err = inflate(&strm, Z_FINISH);
552  // Just return the source if data error.
553  if (err == Z_DATA_ERROR) {
554  std::cout << "Warning: decompression data error. Returning compressed "
555  "fragment.\n";
556  memcpy(dst, src, srcLen);
557  return srcLen;
558  }
559  inflateEnd(&strm);
560 
561  read += to_read - strm.avail_in;
562  write += to_write - strm.avail_out;
563 
564  if (err < 0) {
565  break;
566  }
567  }
568 
569  return write;
570  }
571 
572  public:
573  FelixFragmentCompressed(const artdaq::Fragment& fragment)
574  : FelixFragmentBase(fragment) {
575  // Decompress.
576  decompress_copy(fragment, uncompfrag_);
577  // std::cout << decompress_copy(fragment, uncompfrag_) << " returned from
578  // decompress_copy\n";
579 
580  // Update metadata.
581  meta_.compressed = 0;
582  uncompfrag_.setMetadata(meta_);
583  if (meta_.reordered) {
584  flxfrag = new FelixFragmentReordered(uncompfrag_);
585  } else {
586  flxfrag = new FelixFragmentUnordered(uncompfrag_);
587  }
588  }
589 
590  ~FelixFragmentCompressed() { delete flxfrag; }
591 
592  /* Frame field and accessors. */
593  uint8_t sof(const unsigned& frame_ID = 0) const {
594  return flxfrag->sof(frame_ID);
595  }
596  uint8_t version(const unsigned& frame_ID = 0) const {
597  return flxfrag->version(frame_ID);
598  }
599  uint8_t fiber_no(const unsigned& frame_ID = 0) const {
600  return flxfrag->fiber_no(frame_ID);
601  }
602  uint8_t slot_no(const unsigned& frame_ID = 0) const {
603  return flxfrag->slot_no(frame_ID);
604  }
605  uint8_t crate_no(const unsigned& frame_ID = 0) const {
606  return flxfrag->crate_no(frame_ID);
607  }
608  uint8_t mm(const unsigned& frame_ID = 0) const {
609  return flxfrag->mm(frame_ID);
610  }
611  uint8_t oos(const unsigned& frame_ID = 0) const {
612  return flxfrag->oos(frame_ID);
613  }
614  uint16_t wib_errors(const unsigned& frame_ID = 0) const {
615  return flxfrag->wib_errors(frame_ID);
616  }
617  uint64_t timestamp(const unsigned& frame_ID = 0) const {
618  return flxfrag->timestamp(frame_ID);
619  }
620  uint16_t wib_counter(const unsigned& frame_ID = 0) const {
621  return flxfrag->wib_counter(frame_ID);
622  }
623 
624  /* Coldata block accessors. */
625  uint8_t s1_error(const unsigned& frame_ID, const uint8_t& block_num) const {
626  return flxfrag->s1_error(frame_ID, block_num);
627  }
628  uint8_t s2_error(const unsigned& frame_ID, const uint8_t& block_num) const {
629  return flxfrag->s2_error(frame_ID, block_num);
630  }
631  uint16_t checksum_a(const unsigned& frame_ID,
632  const uint8_t& block_num) const {
633  return flxfrag->checksum_a(frame_ID, block_num);
634  }
635  uint16_t checksum_b(const unsigned& frame_ID,
636  const uint8_t& block_num) const {
637  return flxfrag->checksum_b(frame_ID, block_num);
638  }
639  uint16_t coldata_convert_count(const unsigned& frame_ID,
640  const uint8_t& block_num) const {
641  return flxfrag->coldata_convert_count(frame_ID, block_num);
642  }
643  uint16_t error_register(const unsigned& frame_ID,
644  const uint8_t& block_num) const {
645  return flxfrag->error_register(frame_ID, block_num);
646  }
647  uint8_t hdr(const unsigned& frame_ID, const uint8_t& block_num,
648  const uint8_t& hdr_num) const {
649  return flxfrag->hdr(frame_ID, block_num, hdr_num);
650  }
651 
652  // Function to return a certain ADC value.
653  adc_t get_ADC(const unsigned& frame_ID, const uint8_t channel_ID) const {
654  return flxfrag->get_ADC(frame_ID, channel_ID);
655  }
656 
657  // Function to print all timestamps.
658  void print_timestamps() const { return flxfrag->print_timestamps(); }
659 
660  void print(const unsigned i) const { return flxfrag->print(i); }
661 
662  void print_frames() const { return flxfrag->print_frames(); }
663 
664  // The number of words in the current event minus the header.
665  size_t total_words() const { return flxfrag->total_words(); }
666  // The number of frames in the current event.
667  size_t total_frames() const { return flxfrag->total_frames(); }
668  // The number of ADC values describing data beyond the header
669  size_t total_adc_values() const { return flxfrag->total_adc_values(); }
670 
671  // Const function to return the uncompressed fragment.
672  const artdaq::Fragment uncompressed_fragment() const { return uncompfrag_; }
673 
674  protected:
675  // Uncompressed data fragment.
676  artdaq::Fragment uncompfrag_;
677  // Member pointer to access uncompressed data.
679 }; // class dune::FelixFragmentCompressed
680 
681 //======================
682 // FELIX fragment class
683 //======================
685  public:
686  FelixFragment(const artdaq::Fragment& fragment)
687  : FelixFragmentBase(fragment) {
688  if (meta_.compressed) {
689  flxfrag = new FelixFragmentCompressed(fragment);
690  } else if (meta_.reordered) {
691  flxfrag = new FelixFragmentReordered(fragment);
692  } else {
693  flxfrag = new FelixFragmentUnordered(fragment);
694  }
695 
696  // Try to set the timestamp offset to the metadata offset.
697  bool shift_good = true;
698  // Is the first requested frame in the data?
699  shift_good &=
700  fragment.timestamp() - meta_.offset_frames * 25 >= flxfrag->timestamp();
701  // Is the data big enough to accommodate the window size?
702  shift_good &= fragment.timestamp() -
704  flxfrag->timestamp() + meta_.num_frames * 25;
705 
706  if (shift_good) {
707  trig_offset = (fragment.timestamp() - flxfrag->timestamp()) / 25 - meta_.offset_frames;
708  } else {
709  mf::LogWarning("dune::FelixFragment")
710  << "Can't find the trigger window in FELIX fragment "
711  << fragment.fragmentID() << ".\nFragment TS: " << fragment.timestamp()
712  << " first frame TS: " << flxfrag->timestamp() << '\n';
713  }
714  }
715 
716  ~FelixFragment() { delete flxfrag; }
717 
718  /* Frame field and accessors. */
719  uint8_t sof(const unsigned& frame_ID = 0) const {
720  return flxfrag->sof(frame_ID + trig_offset);
721  }
722  uint8_t version(const unsigned& frame_ID = 0) const {
723  return flxfrag->version(frame_ID + trig_offset);
724  }
725  uint8_t fiber_no(const unsigned& frame_ID = 0) const {
726  return flxfrag->fiber_no(frame_ID + trig_offset);
727  }
728  uint8_t slot_no(const unsigned& frame_ID = 0) const {
729  return flxfrag->slot_no(frame_ID + trig_offset);
730  }
731  uint8_t crate_no(const unsigned& frame_ID = 0) const {
732  return flxfrag->crate_no(frame_ID + trig_offset);
733  }
734  uint8_t mm(const unsigned& frame_ID = 0) const {
735  return flxfrag->mm(frame_ID + trig_offset);
736  }
737  uint8_t oos(const unsigned& frame_ID = 0) const {
738  return flxfrag->oos(frame_ID + trig_offset);
739  }
740  uint16_t wib_errors(const unsigned& frame_ID = 0) const {
741  return flxfrag->wib_errors(frame_ID + trig_offset);
742  }
743  uint64_t timestamp(const unsigned& frame_ID = 0) const {
744  return flxfrag->timestamp(frame_ID + trig_offset);
745  }
746  uint16_t wib_counter(const unsigned& frame_ID = 0) const {
747  return flxfrag->wib_counter(frame_ID + trig_offset);
748  }
749 
750  /* Coldata block accessors. */
751  uint8_t s1_error(const unsigned& frame_ID, const uint8_t& block_num) const {
752  return flxfrag->s1_error(frame_ID + trig_offset, block_num);
753  }
754  uint8_t s2_error(const unsigned& frame_ID, const uint8_t& block_num) const {
755  return flxfrag->s2_error(frame_ID + trig_offset, block_num);
756  }
757  uint16_t checksum_a(const unsigned& frame_ID,
758  const uint8_t& block_num) const {
759  return flxfrag->checksum_a(frame_ID + trig_offset, block_num);
760  }
761  uint16_t checksum_b(const unsigned& frame_ID,
762  const uint8_t& block_num) const {
763  return flxfrag->checksum_b(frame_ID + trig_offset, block_num);
764  }
765  uint16_t coldata_convert_count(const unsigned& frame_ID,
766  const uint8_t& block_num) const {
767  return flxfrag->coldata_convert_count(frame_ID + trig_offset, block_num);
768  }
769  uint16_t error_register(const unsigned& frame_ID,
770  const uint8_t& block_num) const {
771  return flxfrag->error_register(frame_ID + trig_offset, block_num);
772  }
773  uint8_t hdr(const unsigned& frame_ID, const uint8_t& block_num,
774  const uint8_t& hdr_num) const {
775  return flxfrag->hdr(frame_ID + trig_offset, block_num, hdr_num);
776  }
777 
778  // Functions to return a certain ADC value.
779  adc_t get_ADC(const unsigned& frame_ID, const uint8_t channel_ID) const {
780  return flxfrag->get_ADC(frame_ID + trig_offset, channel_ID);
781  }
782  adc_t get_ADC(const unsigned& frame_ID, const uint8_t block_ID,
783  const uint8_t channel_ID) const {
784  return get_ADC(frame_ID, channel_ID + block_ID * 64);
785  }
786 
787  // Function to return all ADC values for a single channel.
788  adc_v get_ADCs_by_channel(const uint8_t channel_ID) const {
790  for (size_t i = 0; i < total_frames(); i++) {
791  output[i] = get_ADC(i, channel_ID);
792  }
793  return output;
794  }
795  adc_v get_ADCs_by_channel(const uint8_t block_ID,
796  const uint8_t channel_ID) const {
797  return get_ADCs_by_channel(channel_ID + block_ID * 64);
798  }
799 
800  // Function to return all ADC values for all channels in a map.
801  std::map<uint8_t, adc_v> get_all_ADCs() const {
802  std::map<uint8_t, adc_v> output;
803  for (int i = 0; i < 256; i++)
804  output.insert(std::pair<uint8_t, adc_v>(i, get_ADCs_by_channel(i)));
805  return output;
806  }
807 
808  // Function to print all timestamps.
809  void print_timestamps() const { return flxfrag->print_timestamps(); }
810 
811  void print(const unsigned i) const { return flxfrag->print(i); }
812 
813  void print_frames() const { return flxfrag->print_frames(); }
814 
815  // The number of words in the current event minus the header.
816  size_t total_words() const { return flxfrag->total_words(); }
817  // The number of frames in the current event.
818  size_t total_frames() const { return flxfrag->total_frames(); }
819  // The number of ADC values describing data beyond the header
820  size_t total_adc_values() const { return flxfrag->total_adc_values(); }
821 
822  private:
823  size_t trig_offset = 0;
825 }; // class dune::FelixFragment
826 
827 #endif /* artdaq_dune_Overlays_FelixFragment_hh */
adc_t get_ADC(const unsigned &frame_ID, const uint8_t channel_ID) const
virtual uint16_t wib_errors(const unsigned &frame_ID=0) const =0
uint16_t adc_t
Definition: FelixFormat.hh:18
static constexpr size_t num_ch_per_frame
Definition: FelixFormat.hh:298
uint8_t hdr(const unsigned &frame_ID, const uint8_t &block_num, const uint8_t &hdr_num) const
uint8_t s1_error(const unsigned &frame_ID, const uint8_t &block_num) const
uint16_t wib_counter(const unsigned &frame_ID=0) const
virtual uint8_t fiber_no(const unsigned &frame_ID=0) const =0
size_t total_frames() const
FelixFragmentCompressed(const artdaq::Fragment &fragment)
uint8_t hdr(const unsigned &frame_ID, const uint8_t &block_num, const uint8_t &hdr_num) const
uint8_t version(const unsigned &frame_ID=0) const
uint8_t oos(const unsigned &frame_ID=0) const
uint16_t checksum_b(const unsigned &frame_ID, const uint8_t &block_num) const
uint8_t s2_error(const unsigned &frame_ID, const uint8_t &block_num) const
uint64_t timestamp(const unsigned &frame_ID=0) const
static QCString result
uint8_t slot_no(const unsigned &frame_ID=0) const
size_t total_adc_values() const
uint8_t version(const unsigned &frame_ID=0) const
virtual uint8_t mm(const unsigned &frame_ID=0) const =0
uint8_t sof(const unsigned &frame_ID=0) const
FelixFragmentUnordered(artdaq::Fragment const &fragment)
uint32_t word_t
Definition: FelixFormat.hh:17
uint8_t crate_no(const unsigned &frame_ID=0) const
uint64_t timestamp(const unsigned &frame_ID=0) const
uint8_t version(const unsigned &frame_ID=0) const
const void * artdaq_Fragment_
bool header_is_faulty(const unsigned int frame_num) const
virtual uint8_t hdr(const unsigned &frame_ID, const uint8_t &block_num, const uint8_t &hdr_num) const =0
uint8_t s2_error(const unsigned &frame_ID, const uint8_t &block_num) const
uint16_t checksum_b(const unsigned &frame_ID, const uint8_t &block_num) const
virtual uint8_t slot_no(const unsigned &frame_ID=0) const =0
virtual void print_timestamps() const =0
uint8_t sof(const unsigned &frame_ID=0) const
uint8_t crate_no(const unsigned &frame_ID=0) const
uint16_t wib_errors(const unsigned &frame_ID=0) const
uint8_t hdr(const unsigned &frame_ID, const uint8_t &block_num, const uint8_t &hdr_num) const
size_t write(int, const char *, size_t)
Writes count bytes from buf to the filedescriptor fd.
bool operator!=(const Metadata &rhs)
uint16_t checksum_b(const unsigned &frame_ID, const uint8_t &block_num) const
QTextStream & hex(QTextStream &s)
uint16_t error_register(const unsigned &frame_ID, const uint8_t &block_num) const
adc_t get_ADC(const unsigned &frame_ID, const uint8_t block_ID, const uint8_t channel_ID) const
virtual void print(const unsigned i) const =0
const artdaq::Fragment uncompressed_fragment() const
uint16_t checksum_a(const unsigned &frame_ID, const uint8_t &block_num) const
uint8_t mm(const unsigned &frame_ID=0) const
FelixFragmentBase(const artdaq::Fragment &fragment)
std::vector< uint16_t > adc_v
Definition: FelixFormat.hh:19
uint16_t wib_errors(const unsigned &frame_ID=0) const
uint16_t coldata_convert_count(const unsigned &frame_ID, const uint8_t &block_num) const
uint16_t wib_counter(const unsigned &frame_ID=0) const
virtual adc_t get_ADC(const unsigned &frame_ID, const uint8_t channel_ID) const =0
std::vector< unsigned int > bad_header_num
dune::adc_t channel_(const unsigned int frame_num, const uint8_t ch_num) const
uint8_t mm(const unsigned &frame_ID=0) const
uint64_t timestamp(const unsigned &frame_ID=0) const
void print_frames() const
int decompress_copy(const artdaq::Fragment &src, artdaq::Fragment &dst)
adc_t get_ADC(const unsigned &frame_ID, const uint8_t channel_ID) const
uint8_t fiber_no(const unsigned &frame_ID=0) const
virtual uint8_t s1_error(const unsigned &frame_ID, const uint8_t &block_num) const =0
uint16_t checksum_a(const unsigned &frame_ID, const uint8_t &block_num) const
virtual uint16_t coldata_convert_count(const unsigned &frame_ID, const uint8_t &block_num) const =0
uint16_t wib_counter(const unsigned &frame_ID=0) const
virtual uint64_t timestamp(const unsigned &frame_ID=0) const =0
uint8_t oos(const unsigned &frame_ID=0) const
uint8_t sof(const unsigned &frame_ID=0) const
uint8_t version(const unsigned &frame_ID=0) const
dune::ColdataHeader const * blockhead_(const unsigned int frame_num, const uint8_t block_num) const
uint16_t wib_counter(const unsigned &frame_ID=0) const
uint16_t coldata_convert_count(const unsigned &frame_ID, const uint8_t &block_num) const
uint16_t checksum_a(const unsigned &frame_ID, const uint8_t &block_num) const
uint8_t fiber_no(const unsigned &frame_ID=0) const
int internal_inflate(const void *src, uint srcLen, void *dst, uint dstLen)
uint16_t error_register(const unsigned &frame_ID, const uint8_t &block_num) const
uint8_t oos(const unsigned &frame_ID=0) const
uint16_t wib_errors(const unsigned &frame_ID=0) const
uint8_t slot_no(const unsigned &frame_ID=0) const
uint8_t s1_error(const unsigned &frame_ID, const uint8_t &block_num) const
uint16_t checksum_b(const unsigned &frame_ID, const uint8_t &block_num) const
uint8_t slot_no(const unsigned &frame_ID=0) const
void print(const unsigned i) const
uint8_t s1_error(const unsigned &frame_ID, const uint8_t &block_num) const
adc_t get_ADC(const unsigned &frame_ID, const uint8_t channel_ID) const
uint16_t error_register(const unsigned &frame_ID, const uint8_t &block_num) const
bool operator==(const Metadata &rhs)
size_t total_words() const
uint16_t coldata_convert_count(const unsigned &frame_ID, const uint8_t &block_num) const
FelixFrame const * frame_(const unsigned &frame_num=0) const
void err(const char *fmt,...)
Definition: message.cpp:226
virtual size_t total_frames() const =0
virtual uint8_t oos(const unsigned &frame_ID=0) const =0
QTextStream & dec(QTextStream &s)
uint8_t fiber_no(const unsigned &frame_ID=0) const
virtual size_t total_words() const =0
uint8_t s1_error(const unsigned &frame_ID, const uint8_t &block_num) const
uint8_t s2_error(const unsigned &frame_ID, const uint8_t &block_num) const
uint8_t fiber_no(const unsigned &frame_ID=0) const
virtual void print_frames() const =0
adc_v get_ADCs_by_channel(const uint8_t channel_ID) const
size_t total_adc_values() const
void print(const unsigned i) const
uint8_t crate_no(const unsigned &frame_ID=0) const
uint16_t error_register(const unsigned &frame_ID, const uint8_t &block_num) const
const FelixFragmentBase * flxfrag
uint16_t wib_errors(const unsigned &frame_ID=0) const
virtual uint16_t checksum_b(const unsigned &frame_ID, const uint8_t &block_num) const =0
FelixFragmentReordered(artdaq::Fragment const &fragment)
const FelixFragmentBase * flxfrag
virtual size_t adc_range(int daq_adc_bits=12)
void print(const unsigned i) const
uint8_t s2_error(const unsigned &frame_ID, const uint8_t &block_num) const
void print_timestamps() const
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
uint8_t mm(const unsigned &frame_ID=0) const
size_t total_adc_values() const
uint8_t crate_no(const unsigned &frame_ID=0) const
uint8_t slot_no(const unsigned &frame_ID=0) const
virtual uint16_t wib_counter(const unsigned &frame_ID=0) const =0
virtual size_t total_adc_values() const =0
size_t dataSizeBytes() const
virtual uint16_t checksum_a(const unsigned &frame_ID, const uint8_t &block_num) const =0
bool operator==(const Metadata &rhs)
uint8_t hdr(const unsigned &frame_ID, const uint8_t &block_num, const uint8_t &hdr_num) const
int read(int, char *, size_t)
Read bytes from a file descriptor.
dune::WIBHeader const * head_(const unsigned int frame_num) const
uint16_t checksum_a(const unsigned &frame_ID, const uint8_t &block_num) const
uint16_t coldata_convert_count(const unsigned &frame_ID, const uint8_t &block_num) const
bool operator!=(const Metadata &rhs)
adc_v get_ADCs_by_channel(const uint8_t block_ID, const uint8_t channel_ID) const
const uint8_t * dataBeginBytes() const
void print(const unsigned i) const
adc_t get_ADC(const unsigned &frame_ID, const uint8_t channel_ID) const
virtual uint8_t sof(const unsigned &frame_ID=0) const =0
std::map< uint8_t, adc_v > get_all_ADCs() const
unsigned uint
Definition: qglobal.h:351
virtual uint8_t crate_no(const unsigned &frame_ID=0) const =0
virtual uint8_t s2_error(const unsigned &frame_ID, const uint8_t &block_num) const =0
uint8_t oos(const unsigned &frame_ID=0) const
uint8_t sof(const unsigned &frame_ID=0) const
FelixFragment(const artdaq::Fragment &fragment)
QTextStream & endl(QTextStream &s)
virtual uint16_t error_register(const unsigned &frame_ID, const uint8_t &block_num) const =0
uint8_t mm(const unsigned &frame_ID=0) const
uint64_t timestamp(const unsigned &frame_ID=0) const