mu2e_artdaq_core  v1_02_24
 All Classes Functions
DetectorFragmentWriter.hh
1 #ifndef mu2e_artdaq_Overlays_DetectorFragmentWriter_hh
2 #define mu2e_artdaq_Overlays_DetectorFragmentWriter_hh
3 
5 // DetectorFragmentWriter
6 //
7 // Class derived from DetectorFragment 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 // DetectorFragment, 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/DetectorFragment.hh"
19 
20 #include <iostream>
21 
22 namespace mu2e {
23 class DetectorFragmentWriter;
24 }
25 
27 {
28 public:
29  DetectorFragmentWriter(artdaq::Fragment &f);
30 
31  virtual ~DetectorFragmentWriter(){};
32 
33  // These functions form overload sets with const functions from
34  // mu2e::DetectorFragment
35 
36  adc_t *dataBegin();
37  adc_t *dataEnd();
38 
39  // We'll need to hide the const version of header in DetectorFragment in
40  // order to be able to perform writes
41 
42  Header *header_()
43  {
44  assert(artdaq_Fragment_.dataSize() >= words_to_frag_words_(Header::size_words));
45  return reinterpret_cast<Header *>(&*artdaq_Fragment_.dataBegin());
46  }
47 
48  void set_hdr_run_number(Header::run_number_t run_number) { header_()->run_number = run_number; }
49 
50  void resize(size_t nAdcs);
51 
52  virtual void printAll(){};
53 
54  void generateOffsetTable(const std::vector<size_t> dataBlockVec);
55 
56 private:
57  size_t calc_event_size_words_(size_t nAdcs);
58 
59  static size_t adcs_to_words_(size_t nAdcs);
60  static size_t words_to_frag_words_(size_t nWords);
61 
62  // Note that this non-const reference hides the const reference in the base class
63  artdaq::Fragment &artdaq_Fragment_;
64 };
65 
66 // The constructor will expect the artdaq::Fragment object it's been
67 // passed to contain the artdaq::Fragment header + the
68 // DetectorFragment::Metadata object, otherwise it throws
69 
70 mu2e::DetectorFragmentWriter::DetectorFragmentWriter(artdaq::Fragment &f)
71  : DetectorFragment(f), artdaq_Fragment_(f)
72 {
73  // If this assert doesn't hold, then can't call
74  // "words_to_frag_words_" below, translating between the
75  // DetectorFragment's standard data type size and the
76  // artdaq::Fragment's data type size, on the Metadata object
77 
78  assert(sizeof(Metadata::data_t) == sizeof(Header::data_t));
79 
80  if (artdaq_Fragment_.size() !=
81  artdaq::detail::RawFragmentHeader::num_words() + words_to_frag_words_(Metadata::size_words)) {
82  std::cerr << "artdaq_Fragment size: " << artdaq_Fragment_.size() << std::endl;
83  std::cerr << "Expected size: "
84  << artdaq::detail::RawFragmentHeader::num_words() + words_to_frag_words_(Metadata::size_words)
85  << std::endl;
86 
87  throw cet::exception(
88  "DetectorFragmentWriter: Raw artdaq::Fragment object size suggests it does not consist of its own header + the "
89  "DetectorFragment::Metadata object");
90  }
91 
92  // Allocate space for the header
93  artdaq_Fragment_.resize(words_to_frag_words_(Header::size_words));
94 }
95 
96 inline mu2e::DetectorFragment::adc_t *mu2e::DetectorFragmentWriter::dataBegin()
97 {
98  assert(artdaq_Fragment_.dataSize() > words_to_frag_words_(Header::size_words));
99  // return reinterpret_cast<adc_t *>(header_() + 1);
100  return (reinterpret_cast<adc_t *>(header_() + 1)) + current_offset_;
101 }
102 
103 inline mu2e::DetectorFragment::adc_t *mu2e::DetectorFragmentWriter::dataEnd()
104 {
105  return dataBegin() + total_adc_values_in_data_block();
106  // return dataBegin() + total_adc_values();
107 }
108 
109 inline void mu2e::DetectorFragmentWriter::resize(size_t nAdcs)
110 {
111  auto es(calc_event_size_words_(nAdcs));
112  artdaq_Fragment_.resize(words_to_frag_words_(es));
113  header_()->event_size = es;
114 }
115 
116 inline size_t mu2e::DetectorFragmentWriter::calc_event_size_words_(size_t nAdcs)
117 {
118  return adcs_to_words_(nAdcs) + hdr_size_words();
119 }
120 
121 inline size_t mu2e::DetectorFragmentWriter::adcs_to_words_(size_t nAdcs)
122 {
123  auto mod(nAdcs % adcs_per_word_());
124  return (mod == 0) ? nAdcs / adcs_per_word_() : nAdcs / adcs_per_word_() + 1;
125 }
126 
127 inline size_t mu2e::DetectorFragmentWriter::words_to_frag_words_(size_t nWords)
128 {
129  size_t mod = nWords % words_per_frag_word_();
130  return mod ? nWords / words_per_frag_word_() + 1 : nWords / words_per_frag_word_();
131 }
132 
133 inline void mu2e::DetectorFragmentWriter::generateOffsetTable(const std::vector<size_t> dataBlockVec)
134 {
135  initializeOffset();
136 
137  // The first entry in the adc_t array after the DetectorFragment::Header
138  // is the number of offsets
139 
140  *(dataBegin()) = (adc_t)dataBlockVec.size();
141  for (size_t cur_index = 0, cur_offset = dataBlockVec.size() + 1; cur_index < dataBlockVec.size(); cur_index++) {
142  // The first offset is always the position of the end of the offset list (dataBlockVec.size()+1)
143  // Include a factor of 8 so that the offsets are in units of 16-bit adc_t values (8 per 128-bit packet)
144  cur_offset += 8 * dataBlockVec[cur_index];
145  *(dataBegin() + 1 + cur_index) = (adc_t)cur_offset;
146  }
147  setDataBlockIndex(0);
148 
149  return;
150 }
151 
152 #endif /* mu2e_artdaq_Overlays_DetectorFragmentWriter_hh */