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