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