$treeview $search $mathjax $extrastylesheet
artdaq_core
v3_06_01
$projectbrief
|
$projectbrief
|
$searchbox |
00001 #ifndef artdaq_core_Data_detail_RawFragmentHeaderV0_hh 00002 #define artdaq_core_Data_detail_RawFragmentHeaderV0_hh 00003 // detail::RawFragmentHeaderV0 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/detail/RawFragmentHeader.hh" 00011 #include "artdaq-core/Data/dictionarycontrol.hh" 00012 #include "artdaq-core/Utilities/TimeUtils.hh" 00013 #include "cetlib_except/exception.h" 00014 00015 extern "C" { 00016 #include <stdint.h> // NOLINT(modernize-deprecated-headers) 00017 } 00018 00019 namespace artdaq { 00020 namespace detail { 00021 struct RawFragmentHeaderV0; 00022 } 00023 } // namespace artdaq 00024 00033 struct artdaq::detail::RawFragmentHeaderV0 00034 { 00038 typedef uint64_t RawDataType; 00039 00040 #if HIDE_FROM_ROOT 00041 typedef uint16_t version_t; 00042 typedef uint64_t sequence_id_t; 00043 typedef uint8_t type_t; 00044 typedef uint16_t fragment_id_t; 00045 typedef uint8_t metadata_word_count_t; 00046 typedef uint32_t timestamp_t; 00047 00048 // define special values for type_t 00049 static constexpr type_t INVALID_TYPE = 0; 00050 static constexpr type_t FIRST_USER_TYPE = 1; 00051 static constexpr type_t LAST_USER_TYPE = 224; 00052 static constexpr type_t FIRST_SYSTEM_TYPE = 225; 00053 static constexpr type_t LAST_SYSTEM_TYPE = 255; 00054 static constexpr type_t InvalidFragmentType = INVALID_TYPE; 00055 static constexpr type_t EndOfDataFragmentType = FIRST_SYSTEM_TYPE; 00056 static constexpr type_t DataFragmentType = FIRST_SYSTEM_TYPE + 1; 00057 static constexpr type_t InitFragmentType = FIRST_SYSTEM_TYPE + 2; 00058 static constexpr type_t EndOfRunFragmentType = FIRST_SYSTEM_TYPE + 3; 00059 static constexpr type_t EndOfSubrunFragmentType = FIRST_SYSTEM_TYPE + 4; 00060 static constexpr type_t ShutdownFragmentType = FIRST_SYSTEM_TYPE + 5; 00061 static constexpr type_t EmptyFragmentType = FIRST_SYSTEM_TYPE + 6; 00062 static constexpr type_t ContainerFragmentType = FIRST_SYSTEM_TYPE + 7; 00063 00068 static std::map<type_t, std::string> MakeSystemTypeMap() 00069 { 00070 return std::map<type_t, std::string>{ 00071 {226, "Data"}, 00072 {231, "Empty"}, 00073 {232, "Container"}}; 00074 } 00075 00080 static std::map<type_t, std::string> MakeVerboseSystemTypeMap() 00081 { 00082 return std::map<type_t, std::string>{ 00083 {225, "EndOfData"}, 00084 {226, "Data"}, 00085 {227, "Init"}, 00086 {228, "EndOfRun"}, 00087 {229, "EndOfSubrun"}, 00088 {230, "Shutdown"}, 00089 {231, "Empty"}, 00090 {232, "Container"}}; 00091 } 00092 00093 // Each of the following invalid values is chosen based on the 00094 // size of the bitfield in which the corresponding data are 00095 // encoded; if any of the sizes are changed, the corresponding 00096 // values must be updated. 00097 static const version_t InvalidVersion = 0xFFFF; 00098 static const version_t CurrentVersion = 0x0; 00099 static const sequence_id_t InvalidSequenceID = 0xFFFFFFFFFFFF; 00100 static const fragment_id_t InvalidFragmentID = 0xFFFF; 00101 static const timestamp_t InvalidTimestamp = 0xFFFFFFFF; 00102 00103 RawDataType word_count : 32; 00104 RawDataType version : 16; 00105 RawDataType type : 8; 00106 RawDataType metadata_word_count : 8; 00107 00108 RawDataType sequence_id : 48; 00109 RawDataType fragment_id : 16; 00110 RawDataType timestamp : 32; 00111 00112 RawDataType unused1 : 16; 00113 RawDataType unused2 : 16; 00114 00119 constexpr static std::size_t num_words(); 00120 00126 void setUserType(uint8_t utype); 00127 00133 void setSystemType(uint8_t stype); 00134 00145 RawFragmentHeader upgrade() const; 00146 00147 #endif /* HIDE_FROM_ROOT */ 00148 }; 00149 00150 #if HIDE_FROM_ROOT 00151 inline constexpr std::size_t 00152 artdaq::detail::RawFragmentHeaderV0::num_words() 00153 { 00154 return sizeof(detail::RawFragmentHeaderV0) / sizeof(RawDataType); 00155 } 00156 00157 // Compile-time check that the assumption made in num_words() above is 00158 // actually true. 00159 static_assert((artdaq::detail::RawFragmentHeaderV0::num_words() * 00160 sizeof(artdaq::detail::RawFragmentHeaderV0::RawDataType)) == 00161 sizeof(artdaq::detail::RawFragmentHeaderV0), 00162 "sizeof(RawFragmentHeader) is not an integer " 00163 "multiple of sizeof(RawDataType)!"); 00164 00165 inline void 00166 artdaq::detail::RawFragmentHeaderV0::setUserType(uint8_t utype) 00167 { 00168 if (utype < FIRST_USER_TYPE || utype > LAST_USER_TYPE) 00169 { 00170 throw cet::exception("InvalidValue") // NOLINT(cert-err60-cpp) 00171 << "RawFragmentHeader user types must be in the range of " 00172 << static_cast<int>(FIRST_SYSTEM_TYPE) << " to " << static_cast<int>(LAST_SYSTEM_TYPE) 00173 << " (bad type is " << static_cast<int>(utype) << ")."; 00174 } 00175 type = utype; 00176 } 00177 00178 inline void 00179 artdaq::detail::RawFragmentHeaderV0::setSystemType(uint8_t stype) 00180 { 00181 if (stype < FIRST_SYSTEM_TYPE /*|| stype > LAST_SYSTEM_TYPE*/) 00182 { 00183 throw cet::exception("InvalidValue") // NOLINT(cert-err60-cpp) 00184 << "RawFragmentHeader system types must be in the range of " 00185 << static_cast<int>(FIRST_SYSTEM_TYPE) << " to " << static_cast<int>(LAST_SYSTEM_TYPE); 00186 } 00187 type = stype; 00188 } 00189 00190 inline artdaq::detail::RawFragmentHeader 00191 artdaq::detail::RawFragmentHeaderV0::upgrade() const 00192 { 00193 RawFragmentHeader output; 00194 output.word_count = word_count; 00195 output.version = RawFragmentHeader::CurrentVersion; 00196 output.type = type; 00197 output.metadata_word_count = metadata_word_count; 00198 00199 output.sequence_id = sequence_id; 00200 output.fragment_id = fragment_id; 00201 output.timestamp = timestamp; 00202 00203 output.valid = true; 00204 output.complete = true; 00205 00206 // ELF 10/1/19: Due to how many times upgrade() gets called during an analysis process, better to just zero these fields 00207 // auto time = artdaq::TimeUtils::get_realtime_clock(); 00208 // output.atime_ns = time.tv_nsec; 00209 // output.atime_s = time.tv_sec; 00210 output.atime_ns = 0; 00211 output.atime_s = 0; 00212 00213 return output; 00214 } 00215 #endif 00216 00217 #endif /* artdaq_core_Data_detail_RawFragmentHeaderV0_hh */