00001 #ifndef mu2e_artdaq_core_Overlays_mu2eFragment_hh
00002 #define mu2e_artdaq_core_Overlays_mu2eFragment_hh
00003
00004 #include "artdaq-core/Data/Fragment.hh"
00005 #include "cetlib_except/exception.h"
00006
00007 #include <ostream>
00008 #include <vector>
00009
00010
00011
00012
00013 #define DATA_BLOCKS_PER_MU2E_FRAGMENT 2500
00014
00015 namespace mu2e {
00016 class mu2eFragment;
00017
00018 static const int BLOCK_COUNT_MAX = DATA_BLOCKS_PER_MU2E_FRAGMENT;
00019
00020
00021 std::ostream &operator<<(std::ostream &, mu2eFragment const &);
00022 }
00023
00024 class mu2e::mu2eFragment {
00025 public:
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 struct Metadata {
00040 typedef uint64_t data_t;
00041
00042 data_t sim_mode : 4;
00043 data_t unused : 4;
00044
00045 data_t board_id : 8;
00046 data_t unused2 : 16;
00047
00048 data_t run_number : 32;
00049
00050 static size_t const size_words = 1ul;
00051 };
00052
00053 static_assert(sizeof(Metadata) == Metadata::size_words * sizeof(Metadata::data_t),
00054 "mu2eFragment::Metadata size changed");
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 struct Header {
00067 typedef uint64_t data_t;
00068 typedef uint64_t count_t;
00069
00070 count_t block_count : 60;
00071 count_t fragment_type : 4;
00072
00073 size_t index[DATA_BLOCKS_PER_MU2E_FRAGMENT];
00074
00075 static size_t constexpr size_words{1ul + (DATA_BLOCKS_PER_MU2E_FRAGMENT * sizeof(size_t)) /
00076 sizeof(uint64_t)};
00077 };
00078
00079 static_assert(sizeof(Header) == sizeof(Header::data_t) * Header::size_words, "mu2eFragment::Header: incorrect size");
00080
00081
00082
00083
00084 mu2eFragment(artdaq::Fragment const &f) : artdaq_Fragment_(f) {}
00085
00086
00087 Header::count_t hdr_block_count() const { return header_()->block_count; }
00088 Header::data_t hdr_fragment_type() const { return (Header::data_t)header_()->fragment_type; }
00089
00090 static constexpr size_t hdr_size_words() { return Header::size_words; }
00091
00092
00093 Header::data_t const *dataBegin() const { return reinterpret_cast<Header::data_t const *>(header_() + 1); }
00094
00095 Header::data_t const *dataEnd() const { return dataAt(hdr_block_count()); }
00096
00097 Header::data_t const *dataAt(const size_t index) const {
00098 if (index == 0) return dataBegin();
00099 auto block = header_()->index[index - 1] / sizeof(Header::data_t);
00100 return reinterpret_cast<Header::data_t const *>(dataBegin() + block);
00101 }
00102
00103 size_t blockSize(const size_t index) const {
00104 auto start = blockOffset(index);
00105 auto end = dataEndBytes();
00106 if (index < hdr_block_count() - 1) {
00107 end = blockOffset(index + 1);
00108 }
00109 return end - start;
00110 }
00111
00112 size_t blockOffset(const size_t index) const {
00113 if (index == 0) {
00114 return 0;
00115 }
00116 return header_()->index[index - 1];
00117 }
00118
00119 size_t dataEndBytes() const { return blockOffset(hdr_block_count()); }
00120
00121 size_t dataSize() const {
00122 return artdaq_Fragment_.dataSize() * sizeof(artdaq::Fragment::value_type) - sizeof(Header) - sizeof(Metadata);
00123 }
00124
00125 protected:
00126 static constexpr size_t words_per_frag_word_() {
00127 return sizeof(artdaq::Fragment::value_type) / sizeof(Header::data_t);
00128 }
00129
00130
00131
00132
00133
00134 Header const *header_() const {
00135 return reinterpret_cast<mu2eFragment::Header const *>(&*artdaq_Fragment_.dataBegin());
00136 }
00137
00138 private:
00139 artdaq::Fragment const &artdaq_Fragment_;
00140 };
00141
00142 #endif