mu2e_artdaq_core  v1_02_10
 All Classes Functions
DTCFragmentWriter.hh
1 #ifndef mu2e_artdaq_core_Overlays_DTCFragmentWriter_hh
2 #define mu2e_artdaq_core_Overlays_DTCFragmentWriter_hh
3 
5 // DTCFragmentWriter
6 //
7 // Class derived from DTCFragment 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 // DTCFragment, 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/DTCFragment.hh"
19 
20 #include <iostream>
21 
22 namespace mu2e {
23  class DTCFragmentWriter;
24 }
25 
26 
28 public:
29 
30 
31  DTCFragmentWriter(artdaq::Fragment & f);
32 
33  // These functions form overload sets with const functions from
34  // mu2e::DTCFragment
35 
36  packet_t * dataBegin();
37  packet_t * dataEnd();
38 
39  // We'll need to hide the const version of header in DTCFragment in
40  // order to be able to perform writes
41 
42  Header * header_() {
43  assert(artdaq_Fragment_.dataSize() >= words_to_frag_words_(Header::size_words ));
44  return reinterpret_cast<Header *>(&*artdaq_Fragment_.dataBegin());
45  }
46 
47  void set_hdr_timestamp(Header::timestamp_t timestamp) {
48  header_()->timestamp = timestamp;
49  }
50 
51  void resize(size_t nPackets);
52 
53  size_t size() { return artdaq_Fragment_.size(); }
54 
55 private:
56  size_t calc_event_size_words_(size_t nPackets);
57 
58  static size_t packets_to_words_(size_t nPackets);
59  static size_t words_to_frag_words_(size_t nWords);
60 
61  // Note that this non-const reference hides the const reference in the base class
62  artdaq::Fragment & artdaq_Fragment_;
63 };
64 
65 // The constructor will expect the artdaq::Fragment object it's been
66 // passed to contain the artdaq::Fragment header + the
67 // DTCFragment::Metadata object, otherwise it throws
68 
69 mu2e::DTCFragmentWriter::DTCFragmentWriter(artdaq::Fragment& f ) :
70  DTCFragment(f), artdaq_Fragment_(f) {
71 
72  // If this assert doesn't hold, then can't call
73  // "words_to_frag_words_" below, translating between the
74  // DTCFragment's standard data type size and the
75  // artdaq::Fragment's data type size, on the Metadata object
76 
77  assert( sizeof(Metadata::data_t) == sizeof(Header::data_t) );
78 
79 
80  if (artdaq_Fragment_.size() !=
81  artdaq::detail::RawFragmentHeader::num_words() +
82  words_to_frag_words_( Metadata::size_words ))
83  {
84  std::cerr << "artdaq_Fragment size: " << artdaq_Fragment_.size() << std::endl;
85  std::cerr << "Expected size: " << artdaq::detail::RawFragmentHeader::num_words() +
86  words_to_frag_words_( Metadata::size_words) << std::endl;
87 
88  throw cet::exception("DTCFragmentWriter: Raw artdaq::Fragment object size suggests it does not consist of its own header + the DTCFragment::Metadata object");
89  }
90 
91  // Allocate space for the header
92  artdaq_Fragment_.resize( words_to_frag_words_(Header::size_words) );
93 }
94 
95 
96 inline mu2e::packet_t * mu2e::DTCFragmentWriter::dataBegin() {
97  assert(artdaq_Fragment_.dataSize() > words_to_frag_words_(Header::size_words));
98  return reinterpret_cast<packet_t *>(header_() + 1);
99 }
100 
101 inline mu2e::packet_t * mu2e::DTCFragmentWriter::dataEnd() {
102  return dataBegin() + hdr_packet_count();
103 }
104 
105 
106 inline void mu2e::DTCFragmentWriter::resize(size_t nPackets) {
107  auto es(calc_event_size_words_(nPackets));
108  artdaq_Fragment_.resize(words_to_frag_words_(es));
109  header_()->event_size = nPackets;
110 }
111 
112 inline size_t mu2e::DTCFragmentWriter::calc_event_size_words_(size_t nPackets) {
113  return packets_to_words_(nPackets) + hdr_size_words();
114 }
115 
116 inline size_t mu2e::DTCFragmentWriter::packets_to_words_(size_t nPackets) {
117  return nPackets * words_per_packet_();
118 }
119 
120 inline size_t mu2e::DTCFragmentWriter::words_to_frag_words_(size_t nWords) {
121  size_t mod = nWords % words_per_frag_word_();
122  return mod ?
123  nWords / words_per_frag_word_() + 1 :
124  nWords / words_per_frag_word_();
125 }
126 
127 #endif /* mu2e_artdaq_core_Overlays_DTCFragmentWriter_hh */