mu2e_artdaq_core  v1_02_16
 All Classes Functions
CalorimeterFragmentWriter.hh
1 #ifndef mu2e_artdaq_Overlays_CalorimeterFragmentWriter_hh
2 #define mu2e_artdaq_Overlays_CalorimeterFragmentWriter_hh
3 
5 // CalorimeterFragmentWriter
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/CalorimeterFragmentReader.hh"
19 
20 #include <iostream>
21 
22 namespace mu2e {
23 class CalorimeterFragmentWriter;
24 }
25 
27 {
28 public:
29  CalorimeterFragmentWriter(artdaq::Fragment &f);
30 
31  virtual ~CalorimeterFragmentWriter(){};
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  adc_t *dataBlockBegin();
40  adc_t *dataBlockEnd();
41 
42  // We'll need to hide the const version of header in DetectorFragment in
43  // order to be able to perform writes
44 
45  Header *header_()
46  {
47  assert(artdaq_Fragment_.dataSize() >= words_to_frag_words_(Header::size_words));
48  return reinterpret_cast<Header *>(&*artdaq_Fragment_.dataBegin());
49  }
50 
51  void set_hdr_run_number(Header::run_number_t run_number) { header_()->run_number = run_number; }
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::CalorimeterFragmentWriter::CalorimeterFragmentWriter(artdaq::Fragment &f)
74  : CalorimeterFragmentReader(f), artdaq_Fragment_(f)
75 {
76  // DetectorFragment(f), artdaq_Fragment_(f) {
77 
78  // If this assert doesn't hold, then can't call
79  // "words_to_frag_words_" below, translating between the
80  // DetectorFragment's standard data type size and the
81  // artdaq::Fragment's data type size, on the Metadata object
82 
83  assert(sizeof(Metadata::data_t) == sizeof(Header::data_t));
84 
85  if (artdaq_Fragment_.size() !=
86  artdaq::detail::RawFragmentHeader::num_words() + words_to_frag_words_(Metadata::size_words)) {
87  std::cerr << "artdaq_Fragment size: " << artdaq_Fragment_.size() << std::endl;
88  std::cerr << "Expected size: "
89  << artdaq::detail::RawFragmentHeader::num_words() + words_to_frag_words_(Metadata::size_words)
90  << std::endl;
91 
92  throw cet::exception(
93  "CalorimeterFragmentWriter: Raw artdaq::Fragment object size suggests it does not consist of its own header + "
94  "the DetectorFragment::Metadata object");
95  }
96 
97  // Allocate space for the header
98  artdaq_Fragment_.resize(words_to_frag_words_(Header::size_words));
99 }
100 
101 inline mu2e::DetectorFragment::adc_t *mu2e::CalorimeterFragmentWriter::dataBegin()
102 {
103  assert(artdaq_Fragment_.dataSize() > words_to_frag_words_(Header::size_words));
104  return reinterpret_cast<adc_t *>(header_() + 1);
105 }
106 
107 inline mu2e::DetectorFragment::adc_t *mu2e::CalorimeterFragmentWriter::dataEnd()
108 {
109  return dataBegin() + total_adc_values();
110 }
111 
112 inline mu2e::DetectorFragment::adc_t *mu2e::CalorimeterFragmentWriter::dataBlockBegin()
113 {
114  assert(artdaq_Fragment_.dataSize() > words_to_frag_words_(Header::size_words));
115  return (reinterpret_cast<adc_t *>(header_() + 1)) + current_offset_;
116 }
117 
118 inline mu2e::DetectorFragment::adc_t *mu2e::CalorimeterFragmentWriter::dataBlockEnd()
119 {
120  return dataBegin() + total_adc_values_in_data_block();
121 }
122 
123 inline void mu2e::CalorimeterFragmentWriter::resize(size_t nAdcs)
124 {
125  auto es(calc_event_size_words_(nAdcs));
126  artdaq_Fragment_.resize(words_to_frag_words_(es));
127  header_()->event_size = es;
128 }
129 
130 inline size_t mu2e::CalorimeterFragmentWriter::calc_event_size_words_(size_t nAdcs)
131 {
132  return adcs_to_words_(nAdcs) + hdr_size_words();
133 }
134 
135 inline size_t mu2e::CalorimeterFragmentWriter::adcs_to_words_(size_t nAdcs)
136 {
137  auto mod(nAdcs % adcs_per_word_());
138  return (mod == 0) ? nAdcs / adcs_per_word_() : nAdcs / adcs_per_word_() + 1;
139 }
140 
141 inline size_t mu2e::CalorimeterFragmentWriter::words_to_frag_words_(size_t nWords)
142 {
143  size_t mod = nWords % words_per_frag_word_();
144  return mod ? nWords / words_per_frag_word_() + 1 : nWords / words_per_frag_word_();
145 }
146 
147 #endif /* mu2e_artdaq_Overlays_CalorimeterFragmentWriter_hh */