artdaq_core  v1_06_00
 All Classes Namespaces Functions
RawFragmentHeader.hh
1 #ifndef artdaq_core_Data_detail_RawFragmentHeader_hh
2 #define artdaq_core_Data_detail_RawFragmentHeader_hh
3 // detail::RawFragmentHeader is an overlay that provides the user's view
4 // of the data contained within a Fragment. It is intended to be hidden
5 // from the user of Fragment, as an implementation detail. The interface
6 // of Fragment is intended to be used to access the data.
7 
8 #include <cstddef>
9 #include "artdaq-core/Data/dictionarycontrol.hh"
10 #include "cetlib/exception.h"
11 
12 extern "C" {
13 #include <stdint.h>
14 }
15 
16 namespace artdaq {
17  namespace detail {
18  struct RawFragmentHeader;
19  }
20 }
21 
23  typedef unsigned long long RawDataType;
24 
25 #if HIDE_FROM_ROOT
26  typedef uint16_t version_t;
27  typedef uint64_t sequence_id_t;
28  typedef uint8_t type_t;
29  typedef uint16_t fragment_id_t;
30  typedef uint8_t metadata_word_count_t;
31  typedef uint32_t timestamp_t;
32 
33  // define special values for type_t
34  static constexpr type_t INVALID_TYPE = 0;
35  static constexpr type_t FIRST_USER_TYPE = 1;
36  static constexpr type_t LAST_USER_TYPE = 224;
37  static constexpr type_t FIRST_SYSTEM_TYPE = 225;
38  static constexpr type_t LAST_SYSTEM_TYPE = 255;
39  static constexpr type_t InvalidFragmentType = INVALID_TYPE;
40  static constexpr type_t EndOfDataFragmentType = FIRST_SYSTEM_TYPE;
41  static constexpr type_t DataFragmentType = FIRST_SYSTEM_TYPE+1;
42  static constexpr type_t InitFragmentType = FIRST_SYSTEM_TYPE+2;
43  static constexpr type_t EndOfRunFragmentType = FIRST_SYSTEM_TYPE+3;
44  static constexpr type_t EndOfSubrunFragmentType = FIRST_SYSTEM_TYPE+4;
45  static constexpr type_t ShutdownFragmentType = FIRST_SYSTEM_TYPE+5;
46  static constexpr type_t EmptyFragmentType = FIRST_SYSTEM_TYPE+6;
47  static constexpr type_t ContainerFragmentType = FIRST_SYSTEM_TYPE+7;
48 
49  // These system types might actually show up in the data stream...
50  static std::map<type_t, std::string> MakeSystemTypeMap()
51  {
52  return std::map<type_t, std::string> {
53  { 226, "Data" },
54  { 231, "Empty" },
55  { 232, "Container" }
56  };
57  }
58  // All system types
59  static std::map<type_t, std::string> MakeVerboseSystemTypeMap()
60  {
61  return std::map<type_t, std::string> {
62  { 225, "EndOfData" },
63  { 226, "Data" },
64  { 227, "Init" },
65  { 228, "EndOfRun" },
66  { 229, "EndOfSubrun" },
67  { 230,"Shutdown" },
68  { 231, "Empty" },
69  { 232, "Container" }
70  };
71  }
72 
73  // Each of the following invalid values is chosen based on the
74  // size of the bitfield in which the corresponding data are
75  // encoded; if any of the sizes are changed, the corresponding
76  // values must be updated.
77  static const version_t InvalidVersion = 0xFFFF;
78  static const sequence_id_t InvalidSequenceID = 0xFFFFFFFFFFFF;
79  static const fragment_id_t InvalidFragmentID = 0xFFFF;
80  static const timestamp_t InvalidTimestamp = 0xFFFFFFFF;
81 
82  RawDataType word_count : 32; // number of RawDataTypes in this Fragment
83  RawDataType version : 16;
84  RawDataType type : 8;
85  RawDataType metadata_word_count : 8;
86 
87  RawDataType sequence_id : 48;
88  RawDataType fragment_id : 16;
89  RawDataType timestamp : 32;
90 
91  // 27-Feb-2013, KAB - As we discussed recently, we will go ahead
92  // and reserve another longword for future needs. The choice of
93  // four 16-bit values is arbitrary and will most certainly change
94  // once we identify the future needs.
95  RawDataType unused1 : 16;
96  RawDataType unused2 : 16;
97 
98  constexpr static std::size_t num_words();
99 
100  void setUserType(uint8_t utype);
101  void setSystemType(uint8_t stype);
102 
103 #endif /* HIDE_FROM_ROOT */
104 
105 };
106 
107 #if HIDE_FROM_ROOT
108 inline
109 constexpr
110 std::size_t
111 artdaq::detail::RawFragmentHeader::num_words()
112 {
113  return sizeof(detail::RawFragmentHeader) / sizeof(RawDataType);
114 }
115 
116 // Compile-time check that the assumption made in num_words() above is
117 // actually true.
118 static_assert((artdaq::detail::RawFragmentHeader::num_words() *
119  sizeof(artdaq::detail::RawFragmentHeader::RawDataType)) ==
121  "sizeof(RawFragmentHeader) is not an integer "
122  "multiple of sizeof(RawDataType)!");
123 
124 inline
125 void
126 artdaq::detail::RawFragmentHeader::setUserType(uint8_t utype)
127 {
128  if (utype < FIRST_USER_TYPE || utype > LAST_USER_TYPE) {
129  throw cet::exception("InvalidValue")
130  << "RawFragmentHeader user types must be in the range of "
131  << ((int)FIRST_USER_TYPE) << " to " << ((int)LAST_USER_TYPE)
132  << " (bad type is " << ((int)utype) << ").";
133  }
134  type = utype;
135 }
136 
137 inline
138 void
139 artdaq::detail::RawFragmentHeader::setSystemType(uint8_t stype)
140 {
141  if (stype < FIRST_SYSTEM_TYPE /*|| stype > LAST_SYSTEM_TYPE*/) {
142  throw cet::exception("InvalidValue")
143  << "RawFragmentHeader system types must be in the range of "
144  << ((int)FIRST_SYSTEM_TYPE) << " to " << ((int)LAST_SYSTEM_TYPE);
145  }
146  type = stype;
147 }
148 #endif
149 
150 #endif /* artdaq_core_Data_detail_RawFragmentHeader_hh */