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