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 {
00026 public:
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 struct Metadata
00041 {
00042 typedef uint64_t data_t;
00043
00044 data_t sim_mode : 4;
00045 data_t unused : 4;
00046
00047 data_t board_id : 8;
00048 data_t unused2 : 16;
00049
00050 data_t run_number : 32;
00051
00052 static size_t const size_words = 1ul;
00053 };
00054
00055 static_assert(sizeof(Metadata) == Metadata::size_words * sizeof(Metadata::data_t),
00056 "mu2eFragment::Metadata size changed");
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068 struct Header
00069 {
00070 typedef uint64_t data_t;
00071 typedef uint64_t count_t;
00072
00073 count_t block_count : 60;
00074 count_t fragment_type : 4;
00075
00076 size_t index[DATA_BLOCKS_PER_MU2E_FRAGMENT];
00077
00078 static size_t constexpr size_words{1ul + (DATA_BLOCKS_PER_MU2E_FRAGMENT * sizeof(size_t)) /
00079 sizeof(uint64_t)};
00080 };
00081
00082 static_assert(sizeof(Header) == sizeof(Header::data_t) * Header::size_words, "mu2eFragment::Header: incorrect size");
00083
00084
00085
00086
00087 mu2eFragment(artdaq::Fragment const &f)
00088 : artdaq_Fragment_(f) {}
00089
00090
00091 Header::count_t hdr_block_count() const { return header_()->block_count; }
00092 Header::data_t hdr_fragment_type() const { return (Header::data_t)header_()->fragment_type; }
00093
00094 static constexpr size_t hdr_size_words() { return Header::size_words; }
00095
00096
00097 Header::data_t const *dataBegin() const { return reinterpret_cast<Header::data_t const *>(header_() + 1); }
00098
00099 Header::data_t const *dataEnd() const { return dataAt(hdr_block_count()); }
00100
00101 Header::data_t const *dataAt(const size_t index) const
00102 {
00103 if (index == 0) return dataBegin();
00104 auto block = header_()->index[index - 1] / sizeof(Header::data_t);
00105 return reinterpret_cast<Header::data_t const *>(dataBegin() + block);
00106 }
00107
00108 size_t blockSize(const size_t index) const
00109 {
00110 auto start = blockOffset(index);
00111 auto end = dataEndBytes();
00112 if (index < hdr_block_count() - 1) {
00113 end = blockOffset(index + 1);
00114 }
00115 return end - start;
00116 }
00117
00118 size_t blockOffset(const size_t index) const
00119 {
00120 if (index == 0) {
00121 return 0;
00122 }
00123 return header_()->index[index - 1];
00124 }
00125
00126 size_t dataEndBytes() const { return blockOffset(hdr_block_count()); }
00127
00128 size_t dataSize() const
00129 {
00130 return artdaq_Fragment_.dataSize() * sizeof(artdaq::Fragment::value_type) - sizeof(Header) - sizeof(Metadata);
00131 }
00132
00133 protected:
00134 static constexpr size_t words_per_frag_word_()
00135 {
00136 return sizeof(artdaq::Fragment::value_type) / sizeof(Header::data_t);
00137 }
00138
00139
00140
00141
00142
00143 Header const *header_() const
00144 {
00145 return reinterpret_cast<mu2eFragment::Header const *>(&*artdaq_Fragment_.dataBegin());
00146 }
00147
00148 private:
00149 artdaq::Fragment const &artdaq_Fragment_;
00150 };
00151
00152 #endif