00001 #ifndef mu2e_artdaq_Overlays_DetectorFragment_hh
00002 #define mu2e_artdaq_Overlays_DetectorFragment_hh
00003
00004 #include "artdaq-core/Data/Fragment.hh"
00005 #include "cetlib_except/exception.h"
00006
00007 #include <iostream>
00008
00009 #include <ostream>
00010 #include <vector>
00011
00012 #include <bitset>
00013
00014
00015
00016
00017
00018
00019
00020
00021 namespace mu2e {
00022 class DetectorFragment;
00023
00024
00025 std::ostream &operator<<(std::ostream &, DetectorFragment const &);
00026 }
00027
00028 class mu2e::DetectorFragment
00029 {
00030 public:
00031
00032
00033
00034 typedef uint16_t adc_t;
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 struct Metadata
00045 {
00046 typedef uint32_t data_t;
00047
00048
00049 data_t board_serial_number : 16;
00050 data_t num_adc_bits : 8;
00051 data_t unused : 8;
00052
00053 static size_t const size_words = 1ul;
00054 };
00055
00056 static_assert(sizeof(Metadata) == Metadata::size_words * sizeof(Metadata::data_t),
00057 "DetectorFragment::Metadata size changed");
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 struct Header
00075 {
00076 typedef uint32_t data_t;
00077
00078 typedef uint32_t event_size_t;
00079 typedef uint32_t run_number_t;
00080
00081 event_size_t event_size : 28;
00082 event_size_t unused_1 : 4;
00083
00084 run_number_t run_number : 32;
00085
00086 static size_t const size_words = 2ul;
00087 };
00088
00089 static_assert(sizeof(Header) == Header::size_words * sizeof(Header::data_t), "DetectorFragment::Header size changed");
00090
00091
00092
00093
00094 DetectorFragment(artdaq::Fragment const &f)
00095 : current_offset_(0), current_offset_index_(0), artdaq_Fragment_(f) {}
00096
00097 virtual ~DetectorFragment() {}
00098
00099
00100
00101 Header::event_size_t hdr_event_size() const { return header_()->event_size; }
00102 Header::run_number_t hdr_run_number() const { return header_()->run_number; }
00103 static constexpr size_t hdr_size_words() { return Header::size_words; }
00104
00105
00106 size_t total_adc_values() const { return (hdr_event_size() - hdr_size_words()) * adcs_per_word_(); }
00107
00108 size_t total_adc_values_in_data_block() const
00109 {
00110 mu2e::DetectorFragment::adc_t packetCount = convertFromBinary(bitArray(dataBlockBegin()), 127 - 43, 127 - 32);
00111 return 8 * (size_t(packetCount) + 1);
00112 }
00113
00114
00115 adc_t const *dataBegin() const { return (reinterpret_cast<mu2e::DetectorFragment::adc_t const *>(header_() + 1)); }
00116
00117 adc_t const *dataEnd() const { return dataBegin() + total_adc_values(); }
00118
00119
00120
00121 adc_t const *dataBlockBegin() const
00122 {
00123 return (reinterpret_cast<mu2e::DetectorFragment::adc_t const *>(header_() + 1)) + current_offset_;
00124 }
00125
00126
00127 adc_t const *dataBlockEnd() const { return dataBlockBegin() + total_adc_values_in_data_block(); }
00128
00129
00130
00131
00132
00133
00134
00135
00136 adc_t const *findBadADC(int daq_adc_bits) const
00137 {
00138 return std::find_if(dataBegin(), dataEnd(),
00139 [&](mu2e::DetectorFragment::adc_t const adc) -> bool { return (adc >> daq_adc_bits); });
00140 }
00141
00142 bool fastVerify(int daq_adc_bits) const { return (findBadADC(daq_adc_bits) == dataEnd()); };
00143
00144
00145 void checkADCData(int daq_adc_bits) const;
00146
00147
00148 size_t adc_range(int daq_adc_bits) { return (1ul << daq_adc_bits); }
00149
00150 size_t numDataBlocks()
00151 {
00152 size_t data_counter = 0;
00153 size_t numDataBlocks = 0;
00154 size_t totalPacketsRead = 0;
00155 for (mu2e::DetectorFragment::adc_t const *curPos = dataBegin(); curPos != dataEnd(); curPos += 8) {
00156 if (data_counter == 0) {
00157
00158
00159
00160 mu2e::DetectorFragment::adc_t packetType = convertFromBinary(bitArray(curPos), 127 - 24, 127 - 20);
00161 mu2e::DetectorFragment::adc_t packetCount = convertFromBinary(bitArray(curPos), 127 - 43, 127 - 32);
00162
00163 data_counter = packetCount;
00164
00165 if (packetType == 5 || packetType == 0x1 ||
00166 packetType == 0x2) {
00167 numDataBlocks++;
00168 }
00169 else
00170 {
00171
00172
00173
00174
00175
00176
00177
00178 throw cet::exception("Error in DetectorFragment: Non-dataheader packet found in dataheader packet location");
00179 }
00180 }
00181 else
00182 {
00183 data_counter--;
00184 }
00185 totalPacketsRead++;
00186 }
00187
00188 return numDataBlocks;
00189 }
00190
00191 size_t offset() { return current_offset_; }
00192
00193 size_t offsetIndex() { return current_offset_index_; }
00194
00195 bool setDataBlockIndex(size_t theIndex)
00196 {
00197 size_t numDB = numDataBlocks();
00198 if (theIndex < numDB) {
00199 current_offset_index_ = theIndex;
00200 current_offset_ = 0;
00201
00202 size_t blockNum = 0;
00203 mu2e::DetectorFragment::adc_t const *curPos = dataBegin();
00204 bool foundBlock = false;
00205 while (!foundBlock) {
00206 mu2e::DetectorFragment::adc_t packetCount = convertFromBinary(bitArray(curPos), 127 - 43, 127 - 32);
00207 if (blockNum == theIndex) {
00208 foundBlock = true;
00209
00210 }
00211 else
00212 {
00213
00214
00215 curPos += 8 * (size_t(packetCount) + 1);
00216
00217 current_offset_ += 8 * (size_t(packetCount) + 1);
00218
00219 blockNum++;
00220 }
00221 }
00222 }
00223 else
00224 {
00225 return false;
00226 }
00227 return true;
00228 }
00229
00230
00231 adc_t byteCount();
00232 adc_t rocID();
00233 adc_t packetType();
00234 adc_t valid();
00235 adc_t packetCount();
00236 adc_t status();
00237 std::vector<adc_t> timestampVector();
00238 std::vector<adc_t> dataVector();
00239 void printDTCHeader();
00240 virtual void printAll();
00241
00242 protected:
00243
00244
00245
00246
00247
00248 static constexpr size_t adcs_per_word_() { return sizeof(Header::data_t) / sizeof(adc_t); }
00249
00250 static constexpr size_t words_per_frag_word_()
00251 {
00252 return sizeof(artdaq::Fragment::value_type) / sizeof(Header::data_t);
00253 }
00254
00255
00256
00257
00258
00259 Header const *header_() const
00260 {
00261 return reinterpret_cast<DetectorFragment::Header const *>(&*artdaq_Fragment_.dataBegin());
00262 }
00263
00264
00265
00266
00267
00268
00269
00270
00271 std::bitset<128> bitArray(mu2e::DetectorFragment::adc_t const *beginning) const;
00272
00273
00274
00275 void fillBitArray(std::bitset<128> &theArray, adc_t const *beginning);
00276
00277 void printBitArray(std::bitset<128> theArray);
00278
00279
00280
00281
00282 mu2e::DetectorFragment::adc_t convertFromBinary(std::bitset<128> theArray, int minIdx, int maxIdx) const;
00283
00284
00285 size_t current_offset_;
00286 size_t current_offset_index_;
00287
00288
00289
00290
00291 private:
00292 artdaq::Fragment const &artdaq_Fragment_;
00293 };
00294
00295 #endif