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