$treeview $search $mathjax $extrastylesheet
artdaq_core
v3_06_01
$projectbrief
|
$projectbrief
|
$searchbox |
00001 #ifndef artdaq_core_Data_detail_RawFragmentHeader_hh 00002 #define artdaq_core_Data_detail_RawFragmentHeader_hh 00003 // detail::RawFragmentHeader is an overlay that provides the user's view 00004 // of the data contained within a Fragment. It is intended to be hidden 00005 // from the user of Fragment, as an implementation detail. The interface 00006 // of Fragment is intended to be used to access the data. 00007 00008 //#include <cstddef> 00009 #include <map> 00010 #include "artdaq-core/Data/dictionarycontrol.hh" 00011 #include "artdaq-core/Utilities/TimeUtils.hh" 00012 #include "cetlib_except/exception.h" 00013 00014 extern "C" { 00015 #include <stdint.h> // NOLINT(modernize-deprecated-headers) 00016 } 00017 00018 namespace artdaq { 00019 namespace detail { 00020 struct RawFragmentHeader; 00021 } 00022 } // namespace artdaq 00023 00031 struct artdaq::detail::RawFragmentHeader 00032 { 00039 typedef unsigned long long RawDataType; 00040 00041 #if HIDE_FROM_ROOT 00042 typedef uint16_t version_t; 00043 typedef uint64_t sequence_id_t; 00044 typedef uint8_t type_t; 00045 typedef uint16_t fragment_id_t; 00046 typedef uint8_t metadata_word_count_t; 00047 typedef uint64_t timestamp_t; 00048 00049 // define special values for type_t 00050 static constexpr type_t INVALID_TYPE = 0; 00051 static constexpr type_t FIRST_USER_TYPE = 1; 00052 static constexpr type_t LAST_USER_TYPE = 224; 00053 static constexpr type_t FIRST_SYSTEM_TYPE = 225; 00054 static constexpr type_t LAST_SYSTEM_TYPE = 255; 00055 static constexpr type_t InvalidFragmentType = INVALID_TYPE; 00056 static constexpr type_t EndOfDataFragmentType = FIRST_SYSTEM_TYPE; 00057 static constexpr type_t DataFragmentType = FIRST_SYSTEM_TYPE + 1; 00058 static constexpr type_t InitFragmentType = FIRST_SYSTEM_TYPE + 2; 00059 static constexpr type_t EndOfRunFragmentType = FIRST_SYSTEM_TYPE + 3; 00060 static constexpr type_t EndOfSubrunFragmentType = FIRST_SYSTEM_TYPE + 4; 00061 static constexpr type_t ShutdownFragmentType = FIRST_SYSTEM_TYPE + 5; 00062 static constexpr type_t EmptyFragmentType = FIRST_SYSTEM_TYPE + 6; 00063 static constexpr type_t ContainerFragmentType = FIRST_SYSTEM_TYPE + 7; 00064 static constexpr type_t ErrorFragmentType = FIRST_SYSTEM_TYPE + 8; 00065 00070 static std::map<type_t, std::string> MakeSystemTypeMap() 00071 { 00072 return std::map<type_t, std::string>{ 00073 {type_t(DataFragmentType), "Data"}, 00074 {type_t(EmptyFragmentType), "Empty"}, 00075 {type_t(ErrorFragmentType), "Error"}, 00076 {type_t(InvalidFragmentType), "Invalid"}, 00077 {232, "Container"}}; 00078 } 00079 00084 static std::map<type_t, std::string> MakeVerboseSystemTypeMap() 00085 { 00086 return std::map<type_t, std::string>{ 00087 {type_t(EndOfDataFragmentType), "EndOfData"}, 00088 {type_t(DataFragmentType), "Data"}, 00089 {type_t(InitFragmentType), "Init"}, 00090 {type_t(EndOfRunFragmentType), "EndOfRun"}, 00091 {type_t(EndOfSubrunFragmentType), "EndOfSubrun"}, 00092 {type_t(ShutdownFragmentType), "Shutdown"}, 00093 {type_t(EmptyFragmentType), "Empty"}, 00094 {type_t(ContainerFragmentType), "Container"}}; 00095 } 00096 00102 static std::string SystemTypeToString(type_t type) 00103 { 00104 switch (type) 00105 { 00106 case INVALID_TYPE: 00107 return "INVALID"; 00108 case EndOfDataFragmentType: 00109 return "EndOfData"; 00110 case DataFragmentType: 00111 return "Data"; 00112 case InitFragmentType: 00113 return "Init"; 00114 case EndOfRunFragmentType: 00115 return "EndOfRun"; 00116 case EndOfSubrunFragmentType: 00117 return "EndOfSubrun"; 00118 case ShutdownFragmentType: 00119 return "Shutdown"; 00120 case EmptyFragmentType: 00121 return "Empty"; 00122 case ContainerFragmentType: 00123 return "Container"; 00124 default: 00125 return "Unknown"; 00126 } 00127 } 00128 00129 // Each of the following invalid values is chosen based on the 00130 // size of the bitfield in which the corresponding data are 00131 // encoded; if any of the sizes are changed, the corresponding 00132 // values must be updated. 00133 static const version_t InvalidVersion = 0xFFFF; 00134 static const version_t CurrentVersion = 0x2; 00135 static const sequence_id_t InvalidSequenceID = 0xFFFFFFFFFFFF; 00136 static const fragment_id_t InvalidFragmentID = 0xFFFF; 00137 static const timestamp_t InvalidTimestamp = 0xFFFFFFFFFFFFFFFF; 00138 00139 RawDataType word_count : 32; 00140 RawDataType version : 16; 00141 RawDataType type : 8; 00142 RawDataType metadata_word_count : 8; 00143 00144 RawDataType sequence_id : 48; 00145 RawDataType fragment_id : 16; 00146 00147 RawDataType timestamp : 64; 00148 00149 RawDataType valid : 1; 00150 RawDataType complete : 1; 00151 RawDataType atime_ns : 30; 00152 RawDataType atime_s : 32; 00153 00154 // **************************************************** 00155 // New fields MUST be added to the END of this list!!! 00156 // **************************************************** 00157 00162 static constexpr std::size_t num_words(); 00163 00169 void setUserType(uint8_t utype); 00170 00176 void setSystemType(uint8_t stype); 00177 00181 void touch(); 00186 struct timespec atime() const; 00192 struct timespec getLatency(bool touch); 00193 00194 #endif /* HIDE_FROM_ROOT */ 00195 }; 00196 00197 #if HIDE_FROM_ROOT 00198 inline constexpr std::size_t 00199 artdaq::detail::RawFragmentHeader::num_words() 00200 { 00201 return sizeof(detail::RawFragmentHeader) / sizeof(RawDataType); 00202 } 00203 00204 // Compile-time check that the assumption made in num_words() above is 00205 // actually true. 00206 static_assert((artdaq::detail::RawFragmentHeader::num_words() * 00207 sizeof(artdaq::detail::RawFragmentHeader::RawDataType)) == 00208 sizeof(artdaq::detail::RawFragmentHeader), 00209 "sizeof(RawFragmentHeader) is not an integer " 00210 "multiple of sizeof(RawDataType)!"); 00211 00212 inline void 00213 artdaq::detail::RawFragmentHeader::setUserType(uint8_t utype) 00214 { 00215 if (utype < FIRST_USER_TYPE || utype > LAST_USER_TYPE) 00216 { 00217 throw cet::exception("InvalidValue") // NOLINT(cert-err60-cpp) 00218 << "RawFragmentHeader user types must be in the range of " 00219 << static_cast<int>(FIRST_USER_TYPE) << " to " << static_cast<int>(LAST_USER_TYPE) 00220 << " (bad type is " << static_cast<int>(utype) << ")."; 00221 } 00222 type = utype; 00223 } 00224 00225 inline void 00226 artdaq::detail::RawFragmentHeader::setSystemType(uint8_t stype) 00227 { 00228 if (stype < FIRST_SYSTEM_TYPE /*|| stype > LAST_SYSTEM_TYPE*/) 00229 { 00230 throw cet::exception("InvalidValue") // NOLINT(cert-err60-cpp) 00231 << "RawFragmentHeader system types must be in the range of " 00232 << static_cast<int>(FIRST_USER_TYPE) << " to " << static_cast<int>(LAST_USER_TYPE); 00233 } 00234 type = stype; 00235 } 00236 00237 inline void artdaq::detail::RawFragmentHeader::touch() 00238 { 00239 auto time = artdaq::TimeUtils::get_realtime_clock(); 00240 atime_ns = time.tv_nsec; 00241 atime_s = time.tv_sec; 00242 } 00243 00244 inline struct timespec artdaq::detail::RawFragmentHeader::atime() const 00245 { 00246 struct timespec ts; 00247 ts.tv_nsec = atime_ns; 00248 ts.tv_sec = atime_s; 00249 return ts; 00250 } 00251 00252 inline struct timespec artdaq::detail::RawFragmentHeader::getLatency(bool touch) 00253 { 00254 auto a_time = atime(); 00255 auto time = artdaq::TimeUtils::get_realtime_clock(); 00256 00257 a_time.tv_sec = time.tv_sec - a_time.tv_sec; 00258 00259 if (a_time.tv_nsec > time.tv_nsec) 00260 { 00261 a_time.tv_sec--; 00262 a_time.tv_nsec = 1000000000 + time.tv_nsec - a_time.tv_nsec; 00263 } 00264 else 00265 { 00266 a_time.tv_nsec = time.tv_nsec - a_time.tv_nsec; 00267 } 00268 00269 if (touch) 00270 { 00271 atime_ns = time.tv_nsec; 00272 atime_s = time.tv_sec; 00273 } 00274 return a_time; 00275 } 00276 #endif 00277 00278 #endif /* artdaq_core_Data_detail_RawFragmentHeader_hh */