mu2e_artdaq_core  v1_02_00b
 All Classes Functions
mu2eFragmentReader.hh
1 #ifndef mu2e_artdaq_core_Overlays_mu2eFragmentReader_hh
2 #define mu2e_artdaq_core_Overlays_mu2eFragmentReader_hh
3 
5 // mu2eFragmentReader
6 //
7 // Class derived from mu2eFragment which provides additional methods
8 // for accessing data stored in a mu2eFragment
9 //
11 
12 #include "artdaq-core/Data/Fragment.hh"
13 #include "artdaq-core/Data/Fragments.hh"
14 #include "mu2e-artdaq-core/Overlays/mu2eFragment.hh"
15 
16 #include <bitset>
17 
18 #include <iostream>
19 #include "trace.h"
20 
21 namespace mu2e {
22  class mu2eFragmentReader;
23 }
24 
26  public:
27 
28  typedef uint16_t adc_t;
29 
30  mu2eFragmentReader(artdaq::Fragment const & f) : mu2eFragment(f) {};
31 
32  size_t blockIndexBytes(size_t offset) const;
33 
34  size_t blockSizeBytes() const;
35  size_t blockSizeBytes(size_t offset) const;
36  size_t blockEndBytes(size_t offset) const;
37  Header::data_t const * dataAtBytes(size_t offset) const;
38  Header::data_t const * dataAtBlockIndex(size_t offset) const;
39 
40  void printPacketAtByte(size_t offset) const;
41 
42  // DataBlock Header Accessor Methods (by block address)
43  adc_t DBH_ByteCount(adc_t const *pos);
44  bool DBH_Valid(adc_t const *pos);
45  adc_t DBH_ROCID(adc_t const *pos);
46  adc_t DBH_RingID(adc_t const *pos);
47  adc_t DBH_PacketType(adc_t const *pos);
48  adc_t DBH_PacketCount(adc_t const *pos);
49  uint64_t DBH_Timestamp(adc_t const *pos);
50  adc_t DBH_TimestampLow(adc_t const *pos);
51  adc_t DBH_TimestampMedium(adc_t const *pos);
52  adc_t DBH_TimestampHigh(adc_t const *pos);
53  adc_t DBH_Status(adc_t const *pos);
54  adc_t DBH_FormatVersion(adc_t const *pos);
55  adc_t DBH_EVBMode(adc_t const *pos);
56  adc_t DBH_SubsystemID(adc_t const *pos);
57  adc_t DBH_DTCID(adc_t const *pos);
58 
59  // TRK DataBlock Payload Accessor Methods (by block address)
60  adc_t DBT_StrawIndex(adc_t const *pos);
61  uint32_t DBT_TDC0(adc_t const *pos);
62  uint32_t DBT_TDC1(adc_t const *pos);
63  std::vector<adc_t> DBT_Waveform(adc_t const *pos);
64 
65  // CAL DataBlock Payload Accessor Methods (by block address)
66  adc_t DBC_CrystalID(adc_t const *pos);
67  adc_t DBC_apdID(adc_t const *pos);
68  adc_t DBC_Time(adc_t const *pos);
69  adc_t DBC_NumSamples(adc_t const *pos);
70  std::vector<adc_t> DBC_Waveform(adc_t const *pos);
71 
72  protected:
73 
74  // Bit processing helper methods
75  // For now, the focus is on clarity and ease of use, but eventually
76  // these sorts of functions will need to be optimized for efficiency
77 
78  // bitArray populates a 128-bit bitset using the 128 bits beginning
79  // at the position indicated by the provided pointer
80  // std::bitset<128> bitArray(adc_t const * beginning);
81  std::bitset<128> bitArray(adc_t const *beginning) const;
82 
83  // Populates the provided bitset using the 128 bits beginning at the
84  // position indicated by the provided pointer
85  void fillBitArray(std::bitset<128> &theArray, adc_t const * beginning);
86 
87  void printBitArray(std::bitset<128> theArray);
88 
89  // Accepts a 128 bit bitset and converts the bits from minIdx to maxIdx
90  // into a 16-bit adc_t (minIdx and maxIdx should be within 16 bits of
91  // each other as no error-checking is performed at the moment).
92  adc_t convertFromBinary(std::bitset<128> theArray, int minIdx, int maxIdx) const;
93 
94 };
95 
96 // Convert index in number of DataBlocks to index in bytes
97 inline size_t mu2e::mu2eFragmentReader::blockIndexBytes(size_t offset) const {
98  if(hdr_block_count() == 0) { return 0; }
99  else if(offset>=hdr_block_count()) { return -1; }
100  else if(offset==0) { return 0;}
101  return header_()->index[ offset-1 ];
102 }
103 
104 // Return size of all blocks
105 inline size_t mu2e::mu2eFragmentReader::blockSizeBytes() const {
106  return mu2eFragment::dataEndBytes();
107 }
108 
109 // Return size of block at given DataBlock index
110 inline size_t mu2e::mu2eFragmentReader::blockSizeBytes(size_t offset) const {
111  if(hdr_block_count() == 0) { return 0; }
112  else if(offset > hdr_block_count()-1) { return 0; }
113  else if(offset==0) { return header_()->index[ offset ]; }
114  return header_()->index[ offset ] - header_()->index[ offset-1 ];
115 }
116 
117 // Return size of block at given DataBlock index
118 inline size_t mu2e::mu2eFragmentReader::blockEndBytes(size_t offset) const {
119  if(hdr_block_count() == 0) { return 0; }
120  else if(offset > hdr_block_count()-1) { return 0; }
121  return header_()->index[ offset ];
122 }
123 
124 // Return pointer to beginning of DataBlock at given byte index
125 inline mu2e::mu2eFragmentReader::Header::data_t const * mu2e::mu2eFragmentReader::dataAtBytes(size_t offset) const {
126  return dataBegin() + (offset / sizeof(Header::data_t));
127 }
128 
129 // Return pointer to beginning of DataBlock at given DataBlock index
130 inline mu2e::mu2eFragmentReader::Header::data_t const * mu2e::mu2eFragmentReader::dataAtBlockIndex(size_t offset) const {
131  return dataAtBytes(blockIndexBytes(offset));
132 }
133 
134 void mu2e::mu2eFragmentReader::printPacketAtByte(size_t offset) const {
135  std::bitset<128> theArray = bitArray( reinterpret_cast<mu2e::mu2eFragmentReader::adc_t const *>(dataAtBytes(offset)) );
136  std::cout << "\t\t" << "Packet Bits (128): ";
137  for(int i=0; i<128; i++) {
138  std::cout << theArray[i];
139  if(i!=0 && i<128-1 && (i+1)%8==0) {
140  std::cout << " ";
141  }
142  }
143  std::cout << std::endl;
144  return;
145 }
146 
147 std::bitset<128> mu2e::mu2eFragmentReader::bitArray(mu2e::mu2eFragmentReader::adc_t const *beginning) const {
148  // Return 128 bit bitset filled with bits starting at the indicated position in the fragment
149  std::bitset<128> theArray;
150  for(int bitIdx=127, adcIdx = 0; adcIdx<8; adcIdx++) {
151  for(int offset = 0; offset<16; offset++) {
152  if( ( (*((adc_t const *)(beginning+adcIdx))) & (1<<offset) ) != 0) {
153  theArray.set(bitIdx);
154  } else {
155  theArray.reset(bitIdx);
156  }
157  bitIdx--;
158  }
159  }
160  return theArray;
161 }
162 
163 void mu2e::mu2eFragmentReader::fillBitArray(std::bitset<128> &theArray, mu2e::mu2eFragmentReader::adc_t const * beginning) {
164  // Fill bitset using the 128 bits starting at the indicated position in the fragment
165  for(int bitIdx=127, adcIdx = 0; adcIdx<8; adcIdx++) {
166  for(int offset = 0; offset<16; offset++) {
167  if( ( (*((adc_t const *)(beginning+adcIdx))) & (1<<offset) ) != 0) {
168  theArray.set(bitIdx);
169  } else {
170  theArray.reset(bitIdx);
171  }
172  bitIdx--;
173  }
174  }
175 }
176 
177 void mu2e::mu2eFragmentReader::printBitArray(std::bitset<128> theArray) {
178  // Print all 128 bits in the packet
179  std::cout << "\t\t" << "Packet Bits (128): ";
180  for(int i=0; i<128; i++) {
181  std::cout << theArray[i];
182  }
183  std::cout << std::endl;
184 }
185 
186 mu2e::mu2eFragmentReader::adc_t mu2e::mu2eFragmentReader::convertFromBinary(std::bitset<128> theArray, int minIdx, int maxIdx) const {
187  std::bitset<16> retVal;
188  for(int i=minIdx+1; i<=maxIdx; i++) {
189  retVal.set(maxIdx-i,theArray[i]);
190  }
191  return retVal.to_ulong();
192 }
193 
194 
195 
196 
197 
198 
200 // DataBlock Header Accessor Methods (by block address)
202 
203 mu2e::mu2eFragmentReader::adc_t mu2e::mu2eFragmentReader::DBH_ByteCount(adc_t const *pos) {
204  return *(pos+0);
205 }
206 
207 bool mu2e::mu2eFragmentReader::DBH_Valid(adc_t const *pos) {
208  return (*(pos+1) >> 15) & 0x0001;
209 }
210 
211 mu2e::mu2eFragmentReader::adc_t mu2e::mu2eFragmentReader::DBH_ROCID(adc_t const *pos) {
212  return *(pos+1) & 0x000F; // 0x000F = 0b1111
213 }
214 
215 mu2e::mu2eFragmentReader::adc_t mu2e::mu2eFragmentReader::DBH_RingID(adc_t const *pos) {
216  return (*(pos+1) >> 8) & 0x0007; // 0x0007 = 0b0111
217 }
218 
219 mu2e::mu2eFragmentReader::adc_t mu2e::mu2eFragmentReader::DBH_PacketType(adc_t const *pos) {
220  return (*(pos+1) >> 4) & 0x000F; // 0x000F = 0b1111
221 }
222 
223 mu2e::mu2eFragmentReader::adc_t mu2e::mu2eFragmentReader::DBH_PacketCount(adc_t const *pos) {
224  return *(pos+2) & 0x07FF; // 0x07FF = 0b0111 1111 1111
225 }
226 
227 uint64_t mu2e::mu2eFragmentReader::DBH_Timestamp(adc_t const *pos) {
228  return uint64_t(*(pos+3)) + (uint64_t(*(pos+4)) << 16) + (uint64_t(*(pos+5)) << 32);
229 }
230 
231 mu2e::mu2eFragmentReader::adc_t mu2e::mu2eFragmentReader::DBH_TimestampLow(adc_t const *pos) {
232  return *(pos+3);
233 }
234 
235 mu2e::mu2eFragmentReader::adc_t mu2e::mu2eFragmentReader::DBH_TimestampMedium(adc_t const *pos) {
236  return *(pos+4);
237 }
238 
239 mu2e::mu2eFragmentReader::adc_t mu2e::mu2eFragmentReader::DBH_TimestampHigh(adc_t const *pos) {
240  return *(pos+5);
241 }
242 
243 mu2e::mu2eFragmentReader::adc_t mu2e::mu2eFragmentReader::DBH_Status(adc_t const *pos) {
244  return *(pos+6) & 0x00FF; // 0x00FF = 0b1111 1111
245 }
246 
247 mu2e::mu2eFragmentReader::adc_t mu2e::mu2eFragmentReader::DBH_FormatVersion(adc_t const *pos) {
248  return *(pos+6) >> 8;
249 }
250 
251 mu2e::mu2eFragmentReader::adc_t mu2e::mu2eFragmentReader::DBH_EVBMode(adc_t const *pos) {
252  return *(pos+7) >> 8;
253 }
254 
255 mu2e::mu2eFragmentReader::adc_t mu2e::mu2eFragmentReader::DBH_SubsystemID(adc_t const *pos) {
256  return (*(pos+7) >> 6) & 0x0003; //0x0003 = 0b0011
257 }
258 
259 mu2e::mu2eFragmentReader::adc_t mu2e::mu2eFragmentReader::DBH_DTCID(adc_t const *pos) {
260  return *(pos+7) & 0x003F; // 0x003F = 0b0011 1111
261 }
262 
264 // TRK DataBlock Payload Accessor Methods (by block address)
266 mu2e::mu2eFragmentReader::adc_t mu2e::mu2eFragmentReader::DBT_StrawIndex(adc_t const *pos) {
267  return *(pos+8+0);
268 }
269 
270 uint32_t mu2e::mu2eFragmentReader::DBT_TDC0(adc_t const *pos) {
271  return ((uint32_t(*(pos+8+2)) & 0x00FF) << 16) + uint32_t(*(pos+8+1));
272 }
273 
274 uint32_t mu2e::mu2eFragmentReader::DBT_TDC1(adc_t const *pos) {
275  return (uint32_t(*(pos+8+3)) << 8) + uint32_t(*(pos+8+2) >> 8);
276 }
277 
278 std::vector<mu2e::mu2eFragmentReader::adc_t> mu2e::mu2eFragmentReader::DBT_Waveform(adc_t const *pos) {
279  std::vector<adc_t> waveform;
280  for(size_t i=0; i<12; i++) {
281  waveform.push_back(*(pos+8+4+i));
282  }
283  return waveform;
284 }
285 
287 // CAL DataBlock Payload Accessor Methods (by block address)
289 
290 mu2e::mu2eFragmentReader::adc_t mu2e::mu2eFragmentReader::DBC_CrystalID(adc_t const *pos) {
291  return *(pos+8+0) & 0x0FFF; // 0x0FFF = 0b1111 1111 1111
292 }
293 
294 mu2e::mu2eFragmentReader::adc_t mu2e::mu2eFragmentReader::DBC_apdID(adc_t const *pos) {
295  return *(pos+8+0) >> 12;
296 }
297 
298 mu2e::mu2eFragmentReader::adc_t mu2e::mu2eFragmentReader::DBC_Time(adc_t const *pos) {
299  return *(pos+8+1);
300 }
301 
302 mu2e::mu2eFragmentReader::adc_t mu2e::mu2eFragmentReader::DBC_NumSamples(adc_t const *pos) {
303  return *(pos+8+2);
304 }
305 
306 std::vector<mu2e::mu2eFragmentReader::adc_t> mu2e::mu2eFragmentReader::DBC_Waveform(adc_t const *pos) {
307  std::vector<adc_t> waveform;
308  for(size_t i=0; i<DBC_NumSamples(pos); i++) {
309  waveform.push_back(*(pos+8+3+i));
310  }
311  return waveform;
312 }
313 
314 
315 
316 
317 
318 #endif /* mu2e_artdaq_Overlays_mu2eFragmentReader_hh */
319