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