otsdaq_mu2e  v2_04_02
STIBFragmentWriter.hh
1 #ifndef artdaq_ots_Overlays_STIBFragmentWriter_hh
2 #define artdaq_ots_Overlays_STIBFragmentWriter_hh
3 
5 // STIBFragmentWriter
6 //
7 // Class derived from STIBFragment 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 // STIBFragment, 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 "otsdaq-demo/Overlays/STIBFragment.hh"
19 
20 #include <iostream>
21 
22 namespace ots
23 {
24 class STIBFragmentWriter;
25 }
26 
28 {
29  public:
30  STIBFragmentWriter(artdaq::Fragment& f);
31 
32  // These functions form overload sets with const functions from
33  // ots::STIBFragment
34 
35  uint8_t* dataBegin();
36  uint8_t* dataEnd();
37 
38  // We'll need to hide the const version of header in STIBFragment in
39  // order to be able to perform writes
40 
41  Header* header_()
42  {
43  assert(artdaq_Fragment_.dataSizeBytes() >= sizeof(Header));
44  return reinterpret_cast<Header*>(artdaq_Fragment_.dataBeginBytes());
45  }
46 
47  void set_hdr_bunch_counter(Header::counter_t counter)
48  {
49  header_()->bunch_counter = counter;
50  }
51 
52  void set_hdr_trigger_counter(Header::counter_t counter)
53  {
54  header_()->trigger_counter = counter;
55  }
56 
57  void set_hdr_trigger_input0(Header::counter_t input)
58  {
59  header_()->trigger_input0 = input;
60  }
61 
62  void set_hdr_trigger_input1(Header::counter_t input)
63  {
64  header_()->trigger_input1 = input;
65  }
66 
67  void resize(size_t nBytes);
68 
69  private:
70  size_t calc_event_size_words_(size_t nBytes);
71 
72  static size_t bytes_to_words_(size_t nBytes);
73 
74  // Note that this non-const reference hides the const reference in the base
75  // class
76  artdaq::Fragment& artdaq_Fragment_;
77 };
78 
79 // The constructor will expect the artdaq::Fragment object it's been
80 // passed to contain the artdaq::Fragment header + the
81 // STIBFragment::Metadata object, otherwise it throws
82 
83 ots::STIBFragmentWriter::STIBFragmentWriter(artdaq::Fragment& f)
84  : STIBFragment(f), artdaq_Fragment_(f)
85 {
86  if(!f.hasMetadata() || f.dataSizeBytes() > 0)
87  {
88  throw cet::exception(
89  "Error in STIBFragmentWriter: Raw artdaq::Fragment "
90  "object does not appear to consist of (and only of) "
91  "its own header + the STIBFragment::Metadata object");
92  }
93 
94  // Allocate space for the header
95  artdaq_Fragment_.resizeBytes(sizeof(Header));
96 }
97 
98 inline uint8_t* ots::STIBFragmentWriter::dataBegin()
99 {
100  // Make sure there's data past the STIBFragment header
101  assert(artdaq_Fragment_.dataSizeBytes() >=
102  sizeof(Header) + sizeof(artdaq::Fragment::value_type));
103  return reinterpret_cast<uint8_t*>(header_() + 1);
104 }
105 
106 inline uint8_t* ots::STIBFragmentWriter::dataEnd()
107 {
108  return dataBegin() + stib_data_words();
109 }
110 
111 inline void ots::STIBFragmentWriter::resize(size_t nBytes)
112 {
113  artdaq_Fragment_.resizeBytes(sizeof(Header::data_t) * calc_event_size_words_(nBytes));
114  header_()->event_size = calc_event_size_words_(nBytes);
115 }
116 
117 inline size_t ots::STIBFragmentWriter::calc_event_size_words_(size_t nBytes)
118 {
119  return bytes_to_words_(nBytes) + hdr_size_words();
120 }
121 
122 inline size_t ots::STIBFragmentWriter::bytes_to_words_(size_t nBytes)
123 {
124  auto mod(nBytes % bytes_per_word_());
125  return (mod == 0) ? nBytes / bytes_per_word_() : nBytes / bytes_per_word_() + 1;
126 }
127 
128 #endif /* artdaq_demo_Overlays_STIBFragmentWriter_hh */