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