mu2e_artdaq_core  v1_02_01a
 All Classes Functions
mu2eFragmentWriter.hh
1 #ifndef mu2e_artdaq_core_Overlays_mu2eFragmentWriter_hh
2 #define mu2e_artdaq_core_Overlays_mu2eFragmentWriter_hh
3 
5 // mu2eFragmentWriter
6 //
7 // Class derived from mu2eFragment which allows writes to the data (for
8 // simulation purposes). Note that for this reason it contains
9 // non-const members which hide the const members in its parent class,
10 // mu2eFragment, including its reference to the artdaq::Fragment
11 // object, artdaq_Fragment_, as well as its functions pointing to the
12 // beginning and end of ADC values in the fragment, dataBegin() and
13 // dataEnd()
14 //
16 
17 #include "artdaq-core/Data/Fragment.hh"
18 #include "mu2e-artdaq-core/Overlays/mu2eFragment.hh"
19 
20 #include <iostream>
21 #include "trace.h"
22 
23 namespace mu2e {
24  class mu2eFragmentWriter;
25 }
26 
27 
29 public:
30 
31 
32  mu2eFragmentWriter(artdaq::Fragment & f);
33 
34  // These functions form overload sets with const functions from
35  // mu2e::DTCFragment
36 
37  Header::data_t * dataBegin();
38  Header::data_t * dataAt(size_t index);
39  Header::data_t * dataEnd();
40  Header::data_t * dataAtBytes(size_t offset);
41 
42  // We'll need to hide the const version of header in DTCFragment in
43  // order to be able to perform writes
44 
45  Header * header_() {
46  //TRACE(10, "dataSize(): %lu, Header size: %lu", artdaq_Fragment_.dataSize(), words_to_frag_words_(Header::size_words));
47  assert(artdaq_Fragment_.dataSize() >= words_to_frag_words_(Header::size_words) );
48  return reinterpret_cast<Header *>(&*artdaq_Fragment_.dataBegin());
49  }
50 
51  void set_hdr_fragment_type(Header::data_t type) {
52  header_()->fragment_type = type;
53  }
54 
55  void addSpace(size_t bytes);
56  void endSubEvt(size_t bytes);
57 
58 private:
59  // Note that this non-const reference hides the const reference in the base class
60  artdaq::Fragment & artdaq_Fragment_;
61  static size_t words_to_frag_words_(size_t nWords);
62 };
63 
64 // The constructor will expect the artdaq::Fragment object it's been
65 // passed to contain the artdaq::Fragment header + the
66 // DTCFragment::Metadata object, otherwise it throws
67 
68 mu2e::mu2eFragmentWriter::mu2eFragmentWriter(artdaq::Fragment& f ) :
69  mu2eFragment(f), artdaq_Fragment_(f) {
70 
71  // If this assert doesn't hold, then can't call
72  // "words_to_frag_words_" below, translating between the
73  // DTCFragment's standard data type size and the
74  // artdaq::Fragment's data type size, on the Metadata object
75 
76  TRACE(2, "mu2eFragmentWriter Constructor");
77 
78  assert( sizeof(Metadata::data_t) == sizeof(Header::data_t) );
79 
80 
81  if (artdaq_Fragment_.size() !=
82  artdaq::detail::RawFragmentHeader::num_words() +
83  words_to_frag_words_( Metadata::size_words ))
84  {
85  std::cerr << "artdaq_Fragment size: " << artdaq_Fragment_.size() << std::endl;
86  std::cerr << "Expected size: " << artdaq::detail::RawFragmentHeader::num_words() +
87  words_to_frag_words_( Metadata::size_words) << std::endl;
88 
89  throw cet::exception("mu2eFragmentWriter: Raw artdaq::Fragment object size suggests it does not consist of its own header + the mu2eFragment::Metadata object");
90  }
91 
92  // Allocate space for the header
93  artdaq_Fragment_.resize(words_to_frag_words_( Header::size_words ) );
94  header_()->block_count = 0;
95  memset((void*)&(header_()->index[0]), 0, sizeof(size_t) * mu2e::BLOCK_COUNT_MAX);
96 }
97 
98 
99 inline mu2e::mu2eFragmentWriter::Header::data_t * mu2e::mu2eFragmentWriter::dataBegin() {
100  assert(artdaq_Fragment_.dataSize() >= words_to_frag_words_(Header::size_words));
101  return reinterpret_cast<Header::data_t *>(header_() + 1);
102 }
103 
104 inline mu2e::mu2eFragmentWriter::Header::data_t * mu2e::mu2eFragmentWriter::dataAt(size_t index) {
105  if(index == 0) return dataBegin();
106  auto block = header_()->index[ index - 1 ] / sizeof(Header::data_t);
107  return reinterpret_cast<Header::data_t*>(dataBegin() + block);
108 }
109 
110 inline mu2e::mu2eFragmentWriter::Header::data_t * mu2e::mu2eFragmentWriter::dataEnd() {
111  return dataAt(hdr_block_count());
112 }
113 
114 
115 inline mu2e::mu2eFragmentWriter::Header::data_t * mu2e::mu2eFragmentWriter::dataAtBytes(size_t offset) {
116  return dataBegin() + (offset / sizeof(Header::data_t));
117 }
118 
119 inline size_t mu2e::mu2eFragmentWriter::words_to_frag_words_(size_t nWords) {
120  size_t mod = nWords % words_per_frag_word_();
121  return mod ?
122  nWords / words_per_frag_word_() + 1 :
123  nWords / words_per_frag_word_();
124 }
125 
126 void mu2e::mu2eFragmentWriter::addSpace(size_t bytes) {
127  TRACE(2, "mu2eFragmentWriter::addSpace START bytes=%lu", bytes);
128  auto currSize = sizeof(artdaq::Fragment::value_type) * artdaq_Fragment_.size();
129  TRACE(2, "Resizing fragment: additional bytes requested: %lu, size of fragment: %lu", bytes, currSize );
130  artdaq_Fragment_.resizeBytes( bytes + currSize );
131 }
132 
133 void mu2e::mu2eFragmentWriter::endSubEvt(size_t bytes) {
134  TRACE(2, "mu2eFragmentWriter::endSubEvt START bytes=%lu", bytes);
135  header_()->index[hdr_block_count()] = blockOffset(hdr_block_count()) + bytes;
136  header_()->block_count++;
137  TRACE(2, "endSubEvt END");
138 }
139 
140 #endif /* mu2e_artdaq_core_Overlays_mu2eFragmentWriter_hh */