otsdaq_mu2e  v2_04_02
STIBFragment.hh
1 #ifndef artdaq_ots_Overlays_STIBFragment_hh
2 #define artdaq_ots_Overlays_STIBFragment_hh
3 
4 #include "artdaq-core/Data/Fragment.hh"
5 #include "cetlib/exception.h"
6 
7 #include <ostream>
8 #include <vector>
9 
10 // Implementation of "STIBFragment", an artdaq::Fragment overlay class
11 
12 namespace ots
13 {
14 class STIBFragment;
15 
16 // Let the "<<" operator dump the STIBFragment's data to stdout
17 std::ostream& operator<<(std::ostream&, STIBFragment const&);
18 } // namespace ots
19 
21 {
22  public:
23  // The "Metadata" struct is used to store info primarily related to
24  // the upstream hardware environment from where the fragment came
25 
26  // "data_t" is a typedef of the fundamental unit of data the
27  // metadata structure thinks of itself as consisting of; it can give
28  // its size via the static "size_words" variable (
29  // STIBFragment::Metadata::size_words )
30 
31  struct Metadata
32  {
33  typedef uint64_t data_t;
34 
35  data_t port : 16;
36  data_t address : 32;
37  data_t unused : 16;
38 
39  static size_t const size_words = 1ull; // Units of Metadata::data_t
40  };
41 
42  static_assert(sizeof(Metadata) == Metadata::size_words * sizeof(Metadata::data_t),
43  "STIBFragment::Metadata size changed");
44 
45  // The "Header" struct contains "metadata" specific to the fragment
46  // which is not hardware-related
47 
48  // Header::data_t -- not to be confused with Metadata::data_t ! --
49  // describes the standard size of a data type not just for the
50  // header data, but ALSO the physics data beyond it; the size of the
51  // header in units of Header::data_t is given by "size_words", and
52  // the size of the fragment beyond the header in units of
53  // Header::data_t is given by "event_size"
54 
55  // Notice only the first 28 bits of the first 32-bit unsigned
56  // integer in the Header is used to hold the event_size ; this means
57  // that you can't represent a fragment larger than 2**28 units of
58  // data_t, or 1,073,741,824 bytes
59 
60  struct Header
61  {
62  typedef uint32_t data_t;
63 
64  typedef uint32_t event_size_t;
65  typedef uint64_t counter_t;
66 
67  event_size_t event_size : 28;
68  event_size_t unused : 4;
69 
70  counter_t bunch_counter : 48;
71  counter_t unused2 : 16;
72 
73  counter_t trigger_counter : 40;
74  counter_t trigger_input0 : 4;
75  counter_t trigger_input1 : 4;
76  counter_t unused3 : 16;
77 
78  static size_t const size_words = 6ul; // Units of Header::data_t
79  };
80 
81  static_assert(sizeof(Header) == Header::size_words * sizeof(Header::data_t),
82  "STIBFragment::Header size changed");
83 
84  // The constructor simply sets its const private member "artdaq_Fragment_"
85  // to refer to the artdaq::Fragment object
86 
87  STIBFragment(artdaq::Fragment const& f) : artdaq_Fragment_(f) {}
88 
89  // const getter functions for the data in the header
90 
91  Header::event_size_t hdr_event_size() const { return header_()->event_size; }
92  static constexpr size_t hdr_size_words() { return Header::size_words; }
93 
94  Header::counter_t hdr_bunch_counter() const { return header_()->bunch_counter; }
95  Header::counter_t hdr_trigger_counter() const { return header_()->trigger_counter; }
96  Header::counter_t hdr_trigger_input0() const { return header_()->trigger_input0; }
97  Header::counter_t hdr_trigger_input1() const { return header_()->trigger_input1; }
98 
99  // STIB Data Word Count
100  size_t stib_data_words() const { return hdr_event_size() - hdr_size_words(); }
101 
102  // Start of the STIB data, returned as a pointer
103  uint32_t const* dataBegin() const
104  {
105  return reinterpret_cast<uint32_t const*>(header_() + 1);
106  }
107 
108  // End of the STIB data, returned as a pointer
109  uint32_t const* dataEnd() const { return dataBegin() + stib_data_words(); }
110 
111  protected:
112  // Functions to translate between byte size and the size of
113  // this fragment overlay's concept of a unit of data (i.e.,
114  // Header::data_t).
115 
116  static constexpr size_t bytes_per_word_()
117  {
118  return sizeof(Header::data_t) / sizeof(uint8_t);
119  }
120 
121  // header_() simply takes the address of the start of this overlay's
122  // data (i.e., where the STIBFragment::Header object begins) and
123  // casts it as a pointer to STIBFragment::Header
124 
125  Header const* header_() const
126  {
127  return reinterpret_cast<STIBFragment::Header const*>(
128  artdaq_Fragment_.dataBeginBytes());
129  }
130 
131  private:
132  artdaq::Fragment const& artdaq_Fragment_;
133 };
134 
135 #endif /* artdaq_ots_core_Overlays_STIBFragment_hh */