Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
oncsSub_idmvtxv3.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file oncsSub_idmvtxv3.cc
1 #include "oncsSub_idmvtxv3.h"
2 
3 // for memset
4 #include <string.h>
5 #include <cassert>
6 
7 using namespace std;
8 
9 // define static references
11 std::unordered_map<uint32_t, oncsSub_idmvtxv3::dumpEntry> oncsSub_idmvtxv3::mSubId2Buffers = {};
12 std::vector< mvtx::PayLoadCont> oncsSub_idmvtxv3::mBuffers = {};
13 std::unordered_map<uint16_t, oncsSub_idmvtxv3::dumpEntry> oncsSub_idmvtxv3::mFeeId2LinkID = {};
14 std::vector< mvtx::GBTLink> oncsSub_idmvtxv3::mGBTLinks = {};
15 
17  : oncsSubevent_w4(data)
18 {
19  m_is_decoded = false;
20  payload = nullptr;
21  payload_position = 0;
22 }
23 
24 //_________________________________________________
26 {
27  if ( m_is_decoded )
28  {
29  return 0;
30  }
31  m_is_decoded = true;
32 
33  feeid_set.clear();
34 
35  for (auto& link : mGBTLinks)
36  {
37  link.clear(false, true); // clear data but not the statistics
38  }
39 
40  short pck_id = getIdentifier();
41 
42  auto& bufref = mSubId2Buffers[pck_id];
43  if ( bufref.entry == -1 )
44  {
45  bufref.entry = mBuffers.size();
46  mBuffers.push_back( {} );
47  }
48  auto& buffer = mBuffers[bufref.entry];
51 
52  buffer.movePtr(payload_position);
53 
54  if ( buffer.isEmpty() )
55  {
56  buffer.clear();
57  }
58  else
59  {
60  buffer.moveUnusedToHead();
61  }
62 
63  for ( auto& link : mGBTLinks )
64  {
65  link.collectROFCableData();
66  }
67 
68  ++mEventId;
69  return 0;
70 }
71 
72 
74 {
75  uint8_t* payload_start = (uint8_t *) &SubeventHdr->data; // here begins the payload
76  unsigned int dlength = getDataLength() - getPadding(); //padding is supposed to be in units of dwords, this assumes dwords
77  dlength *= 4;
78 
80  {
82  COUT
83  << ENDL
84  << "!!!!!!!!!!!!!!!!!!WARNING!!!!!!!!!!!!!!!!!!!! \n"
85  << "DMA packet has incomplete FLX words, only "
86  << dlength << " bytes(" << (dlength / mvtx_utils::FLXWordLength)
87  << " FLX words), will be decoded. \n"
88  << "!!!!!!!!!!!!!!!!!!WARNING!!!!!!!!!!!!!!!!!!!! \n"
89  << ENDL;
90  }
91 
92  buffer.add(payload_start, dlength);
93  payload = buffer.getPtr();
94  payload_position = 0;
95 
96  return;
97 }
98 
99 
101 {
102  mvtx_utils::RdhExt_t rdh = {};
103  size_t dlength = buf.getUnusedSize();
104  do
105  {
106  // Skip FLX padding
107  if ( *(reinterpret_cast<uint16_t*>(&payload[payload_position] + 30)) == 0xFFFF )
108  {
109  while ( (*(reinterpret_cast<uint16_t*>(&payload[payload_position] + 30)) == 0xFFFF) &&\
110  payload_position < dlength)
111  {
113  }
114  }
115  else if ( (dlength - payload_position) >= 2 * mvtx_utils::FLXWordLength ) // at least FLX header and RDH
116  {
117  if ( *(reinterpret_cast<uint16_t*>(&payload[payload_position] + 30)) == 0xAB01 )
118  {
120  const size_t pageSizeInBytes = (rdh.pageSize + 1) * mvtx_utils::FLXWordLength;
121  if ( pageSizeInBytes > (dlength - payload_position) )
122  {
123  break; // skip incomplete felix packet
124  }
125  else
126  {
127  feeid_set.insert(rdh.feeId);
128  auto& lnkref = mFeeId2LinkID[rdh.feeId];
129  if ( lnkref.entry == -1 )
130  {
131  lnkref.entry = mGBTLinks.size();
132  mGBTLinks.emplace_back(rdh.flxId, rdh.feeId);
133  }
134  auto& gbtLink = mGBTLinks[lnkref.entry];
135 
136  if ( (rdh.packetCounter) && (rdh.packetCounter != gbtLink.prev_pck_cnt + 1) )
137  {
138  log_error << "Incorrect pages count " << rdh.packetCounter <<", previous page count was " \
139  << gbtLink.prev_pck_cnt << std::endl;
140  payload_position += pageSizeInBytes;
141  continue;
142  }
143  gbtLink.prev_pck_cnt = rdh.packetCounter;
144 
145  gbtLink.data.add((payload + payload_position), pageSizeInBytes);
146 
147  if ( ! rdh.packetCounter ) // start HB
148  {
149  if ( gbtLink.hbf_found )
150  {
151  log_error << "FLX: " << gbtLink.flxId << ", FeeId: " << gbtLink.feeId \
152  << ". Found new HBF before stop previous HBF. Previous HBF will be ignored." << std::endl;
153  gbtLink.cacheData(gbtLink.hbf_length, true);
154  }
155  gbtLink.hbf_found = true;
156  gbtLink.hbf_length = pageSizeInBytes;
157  }
158  else
159  {
160  gbtLink.hbf_length += pageSizeInBytes;
161  }
162 
163  if ( rdh.stopBit ) // found HB end
164  {
165  if ( ! gbtLink.hbf_found )
166  {
167  log_error << "FLX: " << gbtLink.flxId << ", FeeId: " << gbtLink.feeId \
168  << ". Stopping HBF without start. This block will be ignored." << std::endl;
169  gbtLink.cacheData(gbtLink.hbf_length, true);
170  }
171  gbtLink.hbf_found = false;
172  gbtLink.cacheData(gbtLink.hbf_length, false);
173  }
174  payload_position += pageSizeInBytes;
175  }
176  }
177  else
178  {
179  // skip raw data without a initial FLX header
180  // (YCM)TODO: OK for OM but error otherwise
181  if ( 0 )
182  {
183  std::cout << "Felix header: " << std::hex << "0x" << std::setfill('0') << std::setw(4);
184  std::cout << *(reinterpret_cast<uint16_t*>(&payload[payload_position] + 30)) << std::dec <<std::endl;
185  }
187  }
188  }
189  else
190  {
191  break; // skip incomplete flx_header
192  }
193  } while (payload_position < dlength);
194 
195  return;
196 }
197 
198 
199 int oncsSub_idmvtxv3::iValue(const int n, const char *what)
200 {
201  decode();
202  if ( n == -1 ) // Global Information.
203  {
204  if ( strcmp(what, "NR_LINKS") == 0)
205  {
206  return feeid_set.size();
207  }
208  else
209  {
210  std::cout << "Unknow option " << what << std::endl;
211  return -1;
212  }
213  }
214 
215  unsigned int i = n;
216  if ( strcmp(what, "FEEID") == 0 )
217  {
218  return (i < feeid_set.size()) ? *(next(feeid_set.begin(), i)) : -1;
219  }
220  else
221  {
222  if (mFeeId2LinkID.find(i) == mFeeId2LinkID.cend())
223  {
224  log_error << "FeeId " << i << " was not found in the feeId mapping for this packet" << std::endl;
225  assert(false);
226  }
227  uint32_t lnkId = mFeeId2LinkID[i].entry;
228  if ( strcmp(what, "NR_HBF") == 0 )
229  {
230  if ( mGBTLinks[lnkId].rawData.getNPieces() != mGBTLinks[lnkId].hbf_count)
231  {
232  log_error << "Mismatch size for HBF from hbfData: " << mGBTLinks[lnkId].hbf_count << " and link rawData Pieces: " \
233  << mGBTLinks[lnkId].rawData.getNPieces() << std::endl;
234  assert(false);
235  }
236  return mGBTLinks[lnkId].hbf_count;
237  }
238  else if ( strcmp(what, "NR_PHYS_TRG") == 0 )
239  {
240  return mGBTLinks[lnkId].mL1TrgTime.size();
241  }
242  else if ( strcmp(what, "NR_STROBES") == 0 )
243  {
244  return mGBTLinks[lnkId].mTrgData.size();
245  }
246  else if ( strcmp(what, "NR_HITS") == 0 ) // the number of datasets
247  {
248  return mGBTLinks[lnkId].hit_vector.size();
249  }
250  else
251  {
252  std::cout << "Unknow option " << what << std::endl;
253  return -1;
254  }
255  }
256  return 0;
257 }
258 
259 int oncsSub_idmvtxv3::iValue(const int i_feeid, const int idx, const char *what)
260 {
261  decode();
262  uint32_t feeId = i_feeid;
263  uint32_t index = idx;
264 
265  if (mFeeId2LinkID.find(feeId) == mFeeId2LinkID.cend())
266  {
267  log_error << "FeeId " << feeId << " was not found in the feeId mapping for this packet" << std::endl;
268  assert(false);
269  }
270  uint32_t lnkId = mFeeId2LinkID[feeId].entry;
271 
272  if ( strcmp(what, "L1_IR_BC") == 0 )
273  {
274  return (index < mGBTLinks[lnkId].mL1TrgTime.size()) ? mGBTLinks[lnkId].mL1TrgTime[index].bc : -1;
275  }
276  else if ( strcmp(what, "TRG_IR_BC") == 0 )
277  {
278  return (index < mGBTLinks[lnkId].mTrgData.size()) ? mGBTLinks[lnkId].mTrgData[index].ir.bc : -1;
279  }
280  else if ( strcmp(what, "TRG_NR_HITS") == 0)
281  {
282  return (index < mGBTLinks[lnkId].mTrgData.size()) ? mGBTLinks[lnkId].mTrgData[index].n_hits : -1;
283  }
284  else
285  {
286  std::cout << "Unknow option " << what << std::endl;
287  return -1;
288  }
289  return 0;
290 }
291 
292 int oncsSub_idmvtxv3::iValue(const int i_feeid, const int i_trg, const int i_hit, const char *what)
293 {
294  decode();
295 
296  uint32_t feeId = i_feeid;
297  uint32_t trg = i_trg;
298  uint32_t hit = i_hit;
299 
300  if (mFeeId2LinkID.find(feeId) == mFeeId2LinkID.cend())
301  {
302  log_error << "FeeId " << feeId << "was not found in the feeId mapping for this packet" << std::endl;
303  assert(false);
304  }
305  uint32_t lnkId = mFeeId2LinkID[feeId].entry;
306 
307  uint32_t hit_global_id = mGBTLinks[lnkId].mTrgData[trg].first_hit_pos + hit;
308 
309  if ( strcmp(what, "HIT_CHIP_ID") == 0 )
310  {
311  return ( (hit >= 0) && (hit < mGBTLinks[lnkId].mTrgData[trg].n_hits) ) ? \
312  mGBTLinks[lnkId].hit_vector[hit_global_id]->chip_id : -1;
313  }
314  else if ( strcmp(what, "HIT_BC") == 0 )
315  {
316  return ( (hit >= 0) && (hit < mGBTLinks[lnkId].mTrgData[trg].n_hits) ) ? \
317  mGBTLinks[lnkId].hit_vector[hit_global_id]->bunchcounter : -1;
318  }
319  else if ( strcmp(what, "HIT_ROW") == 0 )
320  {
321  return ( (hit >= 0) && (hit < mGBTLinks[lnkId].mTrgData[trg].n_hits) ) ? \
322  mGBTLinks[lnkId].hit_vector[hit_global_id]->row_pos : -1;
323  }
324  else if ( strcmp(what, "HIT_COL") == 0 )
325  {
326  return ( (hit >= 0) && (hit < mGBTLinks[lnkId].mTrgData[trg].n_hits) ) ? \
327  mGBTLinks[lnkId].hit_vector[hit_global_id]->col_pos : -1;
328  }
329  else
330  {
331  std::cout << "Unknow option " << what << std::endl;
332  return -1;
333  }
334  return 0;
335 }
336 
337 
338 long long int oncsSub_idmvtxv3::lValue(const int i_feeid, const int idx, const char *what)
339 {
340  decode();
341 
342  uint32_t feeId = i_feeid;
343  uint32_t index = idx;
344 
345  if (mFeeId2LinkID.find(feeId) == mFeeId2LinkID.cend())
346  {
347  log_error << "FeeId " << feeId << "was not found in the feeId mapping for this packet" << std::endl;
348  assert(false);
349  }
350  uint32_t lnkId = mFeeId2LinkID[feeId].entry;
351 
352  if ( strcmp(what, "L1_IR_BCO") == 0 )
353  {
354  return (index < mGBTLinks[lnkId].mL1TrgTime.size()) ? mGBTLinks[lnkId].mL1TrgTime[index].orbit : -1;
355  }
356  else if ( strcmp(what, "TRG_IR_BCO") == 0 )
357  {
358  return (index < mGBTLinks[lnkId].mTrgData.size()) ? mGBTLinks[lnkId].mTrgData[index].ir.orbit : -1;
359  }
360  else
361  {
362  std::cout << "Unknow option " << what << std::endl;
363  return -1;
364  }
365 
366  return 0;
367 }
368 
369 
370 //_________________________________________________
372 {
373  identify(os);
374  decode();
375 
376  // Debug HB pooling
377  int num_feeids = iValue(-1, "NR_LINKS");
378  os << "Event: " << mEventId << " Number of feeid: " << num_feeids << std::endl;
379  if (num_feeids > 0)
380  {
381  for ( int i = 0; i < num_feeids; ++i )
382  {
383  auto feeId = iValue(i, "FEEID");
384  auto hbfSize = iValue(feeId, "NR_HBF");
385  os << "Link " << setw(4) << feeId << " has " << hbfSize << " HBs, ";
386  os << iValue(feeId, "NR_STROBES") << " strobes and ";
387  os << iValue(feeId, "NR_PHYS_TRG") << " L1 triggers" << std::endl;
388 
389  for ( int iL1 = 0; iL1 < iValue(feeId, "NR_PHYS_TRG"); ++iL1 )
390  {
391  os << "L1: " << iL1 << std::hex << " BCO: 0x" << lValue(feeId, iL1, "L1_IR_BCO");
392  os << std::dec << " BC: " << iValue(feeId, iL1, "L1_IR_BC") << endl;
393  }
394 
395  os << "Total number of hits: " << iValue(feeId, "NR_HITS") << endl;
396  for ( int i_trg = 0; i_trg < iValue(feeId, "NR_STROBES"); ++i_trg )
397  {
398  os << "-- Strobe: " << i_trg;
399  os << ", BCO: 0x" << std::hex << lValue(feeId, i_trg, "TRG_IR_BCO") << std::dec;
400  os << " BC: " << iValue(feeId, i_trg, "TRG_IR_BC");
401  os << ", has " << iValue(feeId, i_trg, "TRG_NR_HITS") << " hits." << std::endl;
402 
403  if ( iValue(feeId, i_trg, "TRG_NR_HITS") )
404  {
405  os << " hit number chip_id bc row col " << endl;
406  }
407  for ( int i_hit = 0; i_hit < iValue(feeId, i_trg, "TRG_NR_HITS"); ++i_hit )
408  {
409  os << setw(4) << i_hit;
410  os << " " << setw(9) << iValue(feeId, i_trg, i_hit, "HIT_CHIP_ID");
411  os << " " << setw(8) << std::hex << iValue(feeId, i_trg, i_hit, "HIT_BC") << std::dec;
412  os << " " << setw(4) << iValue(feeId, i_trg, i_hit, "HIT_ROW");
413  os << " " << setw(4) << iValue(feeId, i_trg, i_hit, "HIT_COL");
414  os << endl;
415  }
416  }
417  }
418  }
419 
420  return;
421 }
422 
423 //_________________________________________________
425 {
426  for ( auto&& link : mGBTLinks )
427  {
428  link.clear(true, true);
429  }
430  feeid_set.clear();
431 }