Belle II Software  release-08-01-10
PXDUnpackerOTModule.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 
9 #include <pxd/unpacking/PXDRawDataDefinitions.h>
10 #include <pxd/unpacking/PXDRawDataStructs.h>
11 #include <pxd/unpacking/PXDMappingLookup.h>
12 #include <pxd/modules/pxdUnpacking/PXDUnpackerOTModule.h>
13 #include <framework/datastore/DataStore.h>
14 #include <framework/logging/Logger.h>
15 #include <framework/datastore/StoreObjPtr.h>
16 
17 #include <boost/endian/arithmetic.hpp>
18 
19 using namespace std;
20 using namespace Belle2;
21 using namespace Belle2::PXD;
22 using namespace Belle2::PXD::PXDError;
23 
24 //-----------------------------------------------------------------
25 // Register the Module
26 //-----------------------------------------------------------------
27 REG_MODULE(PXDUnpackerOT);
28 
29 //-----------------------------------------------------------------
30 // Implementation
31 //-----------------------------------------------------------------
32 
36 
37 PXDUnpackerOTModule::PXDUnpackerOTModule() :
38  Module(),
39  m_storeRawHits(),
40  m_storeROIs(),
41  m_storeRawAdc()
42 {
43  //Set module properties
44  setDescription("Unpack Raw PXD Hits from ONSEN data stream");
46 
47  addParam("RawPXDsName", m_RawPXDsName, "The name of the StoreArray of RawPXDs to be processed", std::string(""));
48  addParam("PXDRawHitsName", m_PXDRawHitsName, "The name of the StoreArray of generated PXDRawHits", std::string(""));
49  addParam("PXDDAQEvtStatsName", m_PXDDAQEvtStatsName, "The name of the StoreObjPtr of generated PXDDAQEvtStats", std::string(""));
50  addParam("PXDRawAdcsName", m_PXDRawAdcsName, "The name of the StoreArray of generated PXDRawAdcs", std::string(""));
51  addParam("PXDRawROIsName", m_PXDRawROIsName, "The name of the StoreArray of generated PXDRawROIs", std::string(""));
52  addParam("DoNotStore", m_doNotStore, "only unpack and check, but do not store", false);
53 // addParam("CriticalErrorMask", m_criticalErrorMask, "Set error mask which stops processing by returning false by task", 0);
54  // m_criticalErrorMask not longer a aparameter
55  // the constructor default to zero anyway
56 // addParam("SuppressErrorMask", m_suppressErrorMask, "Set mask for errors msgs which are not printed", getSilenceMask());
57  // m_suppressErrorMask not longer a aparameter
58  m_suppressErrorMask = getSilenceMask();
59  addParam("ForceMapping", m_forceMapping, "Force Mapping even if DHH bit is NOT requesting it", false);
60  addParam("ForceNoMapping", m_forceNoMapping, "Force NO Mapping even if DHH bit is requesting it", false);
61  addParam("CheckPaddingCRC", m_checkPaddingCRC, "Check for susp. padding (debug option, many false positive)", false);
62  addParam("MaxDHPFrameDiff", m_maxDHPFrameDiff, "Maximum DHP Frame Nr Difference w/o reporting error", 2u);
63  addParam("FormatBonnDAQ", m_formatBonnDAQ, "ONSEN or BonnDAQ format", false);
64  addParam("Verbose", m_verbose, "Turn on extra verbosity for log-level debug", false);
65  addParam("ContinueOnError", m_continueOnError, "Continue package depacking on error (for debugging)", false);
66 // (
67 // /*EPXDErrFlag::c_DHC_END | EPXDErrFlag::c_DHE_START | EPXDErrFlag::c_DATA_OUTSIDE |*/
68 // EPXDErrFlag::c_FIX_SIZE | EPXDErrFlag::c_DHE_CRC | EPXDErrFlag::c_DHC_UNKNOWN | /*EPXDErrFlag::c_MERGER_CRC |*/
69 // EPXDErrFlag::c_DHP_SIZE | /*EPXDErrFlag::c_DHP_PIX_WO_ROW | EPXDErrFlag::c_DHE_START_END_ID | EPXDErrFlag::c_DHE_START_ID |*/
70 // EPXDErrFlag::c_DHE_START_WO_END | EPXDErrFlag::c_DHP_NOT_CONT
71 // ));
72 
73  // this is not really a parameter, it should be fixed.
74  m_errorSkipPacketMask[c_nrDHE_CRC] = true;
75  m_errorSkipPacketMask[c_nrFIX_SIZE] = true;
76 }
77 
79 {
80  // Required input
81  m_eventMetaData.isRequired();
82  // Optional input
83  m_storeRawPXD.isOptional(m_RawPXDsName);
84 
85  //Register output collections
86  m_storeRawHits.registerInDataStore(m_PXDRawHitsName, DataStore::EStoreFlags::c_ErrorIfAlreadyRegistered);
87  m_storeRawAdc.registerInDataStore(m_PXDRawAdcsName, DataStore::EStoreFlags::c_ErrorIfAlreadyRegistered);
88  m_storeROIs.registerInDataStore(m_PXDRawROIsName, DataStore::EStoreFlags::c_ErrorIfAlreadyRegistered);
89  m_storeDAQEvtStats.registerInDataStore(m_PXDDAQEvtStatsName, DataStore::EStoreFlags::c_ErrorIfAlreadyRegistered);
91 
92  B2DEBUG(29, "ForceMapping: " << m_forceMapping);
93  B2DEBUG(29, "ForceNoMapping: " << m_forceNoMapping);
94  B2DEBUG(29, "CheckPaddingCRC: " << m_checkPaddingCRC);
95  B2DEBUG(29, "MaxDHPFrameDiff: " << m_maxDHPFrameDiff);
96 
97  m_sendunfiltered = 0;
98  m_sendrois = 0;
99  m_notaccepted = 0;
101  for (int i = 0; i < ONSEN_MAX_TYPE_ERR; i++) m_errorCounter[i] = 0;
102 
103 }
104 
106 {
107  int flag = 0;
108  string errstr = "Statistic ( ;";
109  errstr += to_string(m_unpackedEventsCount) + ";";
110  for (int i = 0; i < ONSEN_MAX_TYPE_ERR; i++) { errstr += to_string(m_errorCounter[i]) + ";"; flag |= m_errorCounter[i];}
111  if (flag != 0) {
112  B2RESULT("PXD Unpacker --> Error Statistics (counted once per event!) in Events: " << m_unpackedEventsCount);
113  B2RESULT(errstr + " )");
114  for (int i = 0; i < ONSEN_MAX_TYPE_ERR; i++) {
115  if (m_errorCounter[i]) {
116  B2RESULT(getPXDBitErrorName(i) << ": " << m_errorCounter[i]);
117  }
118  }
119  } else {
120  B2RESULT("PXD Unpacker --> No Error found in Events: " << m_unpackedEventsCount);
121  }
122  B2RESULT("Statistic 2: !Accepted: " << m_notaccepted << " SendROIs: " << m_sendrois << " Unfiltered: " << m_sendunfiltered);
123 }
124 
126 {
127  m_storeDAQEvtStats.create();
128 
129  m_errorMask = 0;
130  m_errorMaskEvent = 0;
131 
132  m_meta_event_nr = m_eventMetaData->getEvent();// used for error output below
133 
134  if (!m_storeRawPXD) {// if no input, nothing to do
135  m_errorMask[c_nrNO_PXD] = true;
136  } else {
137  int nRaws = m_storeRawPXD.getEntries();
138  if (m_verbose) {
139  B2DEBUG(29, "PXD Unpacker --> RawPXD Objects in event: " << LogVar("Objects", nRaws));
140  };
141 
142  m_meta_run_nr = m_eventMetaData->getRun();
143  m_meta_subrun_nr = m_eventMetaData->getSubrun();
144  m_meta_experiment = m_eventMetaData->getExperiment();
145  m_meta_time = m_eventMetaData->getTime();
146  m_meta_ticks = (unsigned int)std::round((m_meta_time % 1000000000ull) * 0.127216); // calculate ticks in 127MHz RF clock
147  m_meta_sec = (unsigned int)(m_meta_time / 1000000000ull) & 0x1FFFF;
148 
149  int inx = 0; // count index for output objects
150  for (auto& it : m_storeRawPXD) {
151  if (m_verbose) {
152  B2DEBUG(29, "PXD Unpacker --> Unpack Objects: ");
153  };
154  unpack_rawpxd(it, inx++);
155  }
156 
157  if (nRaws == 0) m_errorMask[c_nrNO_PXD] = true;
158  }
160  m_storeDAQEvtStats->setErrorMask(m_errorMaskEvent);
161 
163  {
164  for (unsigned int i = 0; i < ONSEN_MAX_TYPE_ERR; i++) {
165  if (m_errorMaskEvent[i]) m_errorCounter[i]++;
166  }
167  }
168 
169  if ((PXDErrorFlags(m_criticalErrorMask) & m_errorMaskEvent) != PXDErrorFlags(0)) B2ERROR("Error in PXD unpacking" <<
170  LogVar("event nr", m_meta_event_nr));
171  setReturnValue(PXDErrorFlags(0) == (PXDErrorFlags(m_criticalErrorMask) & m_errorMaskEvent));
172 }
173 
175 {
176  int Frames_in_event;
177  int fullsize;
178  int datafullsize;
179 
180  m_errorMaskDHE = 0;
181  m_errorMaskDHC = 0;
182  m_errorMaskPacket = 0;
183  PXDDAQPacketStatus& daqpktstat = m_storeDAQEvtStats->newPacket(inx);
184 
185  if (px.size() <= 0 || px.size() > 16 * 1024 * 1024) {
186  if (!(m_suppressErrorMask[c_nrPACKET_SIZE])) {
187  B2WARNING("PXD Unpacker --> invalid packet size" <<
188  LogVar("size [32bit words] $", static_cast < std::ostringstream && >(std::ostringstream() << hex << px.size()).str()));
189  }
190  m_errorMask[c_nrPACKET_SIZE] = true;
191  return;
192  }
193  std::vector<unsigned int> data(px.size());
194  fullsize = px.size() * 4;
195  std::copy_n(px.data(), px.size(), data.begin());
196 
197  if (fullsize < 8) {
198  if (!(m_suppressErrorMask[c_nrPACKET_SIZE])) {
199  B2WARNING("Data is to small to hold a valid Header! Will not unpack anything." << LogVar("size [32bit words] $",
200  static_cast < std::ostringstream && >(std::ostringstream() << hex << fullsize).str()));
201  }
202  m_errorMask[c_nrPACKET_SIZE] = true;
203  return;
204  }
205 
206  if (data[0] != 0xCAFEBABE && data[0] != 0xBEBAFECA) {
207  if (!(m_suppressErrorMask[c_nrMAGIC])) {
208  B2WARNING("Magic invalid: Will not unpack anything. Header corrupted." <<
209  LogVar("Header Magic $", static_cast < std::ostringstream && >(std::ostringstream() << hex << data[0]).str()));
210  }
211  m_errorMask[c_nrMAGIC] = true;
212  return;
213  }
214 
215 
216  Frames_in_event = ((ubig32_t*)data.data())[1];
217  if (Frames_in_event < 0 || Frames_in_event > 256) {
218  if (!(m_suppressErrorMask[c_nrFRAME_NR])) {
219  B2WARNING("Number of Frames invalid: Will not unpack anything. Header corrupted!" << LogVar("Frames in event", Frames_in_event));
220  }
221  m_errorMask[c_nrFRAME_NR] = true;
222  return;
223  }
224  if (Frames_in_event < 3) {
225  if (!(m_suppressErrorMask[c_nrNR_FRAMES_TO_SMALL])) {
226  B2WARNING("Number of Frames too small: It cannot contain anything useful." << LogVar("Frames in event", Frames_in_event));
227  }
228  m_errorMask[c_nrNR_FRAMES_TO_SMALL] = true;
229  }
230 
232  if (m_verbose) {
233  B2DEBUG(29, "PXD Unpacker --> data[0]: <-- Magic $" << hex << data[0]);
234  B2DEBUG(29, "PXD Unpacker --> data[1]: <-- #Frames $" << hex << data[1]);
235  if (data[1] >= 1 && fullsize < 12) B2DEBUG(29, "PXD Unpacker --> data[2]: <-- Frame 1 len $" << hex << data[2]);
236  if (data[1] >= 2 && fullsize < 16) B2DEBUG(29, "PXD Unpacker --> data[3]: <-- Frame 2 len $" << hex << data[3]);
237  if (data[1] >= 3 && fullsize < 20) B2DEBUG(29, "PXD Unpacker --> data[4]: <-- Frame 3 len $" << hex << data[4]);
238  if (data[1] >= 4 && fullsize < 24) B2DEBUG(29, "PXD Unpacker --> data[5]: <-- Frame 4 len $" << hex << data[5]);
239  };
240 
241  unsigned int* tableptr;
242  tableptr = &data[2]; // skip header!!!
243 
244  unsigned int* dataptr;
245  dataptr = &tableptr[Frames_in_event];
246  datafullsize = fullsize - 2 * 4 - Frames_in_event * 4; // Size is fullsize minus header minus table
247 
248  int ll = 0; // Offset in dataptr in bytes
249  for (int j = 0; j < Frames_in_event; j++) {
250  int lo;
251 
252  lo = ((ubig32_t*)tableptr)[j];
253  if (lo <= 0) {
254  if (!(m_suppressErrorMask[c_nrFRAME_SIZE])) {
255  B2WARNING("size of frame invalid");
256  B2DEBUG(29, "size of frame invalid: " << j << "size " << lo << " at byte offset in dataptr " << ll);
257  }
258  m_errorMask[c_nrFRAME_SIZE] = true;
259  return;
260  }
261  if (ll + lo > datafullsize) {
262  if (!(m_suppressErrorMask[c_nrFRAME_SIZE])) {
263  B2WARNING("Frames exceed packet size");
264  B2DEBUG(29, "Frames exceed packet size: " << j << " size " << lo << " at byte offset in dataptr " << ll << " of datafullsize " <<
265  datafullsize << " of fullsize " << fullsize);
266  }
267  m_errorMask[c_nrFRAME_SIZE] = true;
268  return;
269  }
270  if (lo & 0x3) {
271  if (!(m_suppressErrorMask[c_nrFRAME_SIZE])) {
272  B2WARNING("SKIP Frame with Data with not MOD 4 length");
273  B2DEBUG(29, "SKIP Frame with Data with not MOD 4 length " << " ( $" << hex << lo << " ) ");
274  }
275  ll += (lo + 3) & 0xFFFFFFFC;
276  m_errorMask[c_nrFRAME_SIZE] = true;
277  } else {
278  B2DEBUG(29, "unpack DHE(C) frame: " << j << " with size " << lo << " at byte offset in dataptr " << ll);
279  unpack_dhc_frame(ll + (char*)dataptr, lo, j, Frames_in_event, daqpktstat);
280  ll += lo;
281  }
286  m_errorMask = 0;
287 
288  if (!m_continueOnError && (m_errorMaskPacket & PXDErrorFlags(m_errorSkipPacketMask)) != PXDErrorFlags(0)) {
289  // skip full package on error, recovery to next DHC/DHE Start might be possible in some cases
290  // But thats to hard to implement
291  // Remark: PXD data for broken events is removed in next PXDPostChecker module, thus skipping the
292  // unpacking is not strictly necessary here.
293  break;
294  }
295  }
296  daqpktstat.setErrorMask(m_errorMaskPacket);
297 }
298 
299 void PXDUnpackerOTModule::unpack_dhp_raw(void* data, unsigned int frame_len, unsigned int dhe_ID, unsigned dhe_DHPport,
300  VxdID vxd_id)
301 {
302 // unsigned int nr_words = frame_len / 2; // frame_len in bytes (excl. CRC)!!!
303  ubig16_t* dhp_pix = (ubig16_t*)data;
304 
311 
312  // Size: 64*768 + 8 bytes for a full frame readout
313  if (frame_len != 0xC008) {
314  if (!(m_suppressErrorMask[c_nrFIX_SIZE])) B2WARNING("Frame size unsupported for RAW ADC frame! $" <<
315  LogVar("size [bytes] $", static_cast < std::ostringstream && >(std::ostringstream() << hex << frame_len).str())
316  << LogVar("DHE", dhe_ID) << LogVar("DHP", dhe_DHPport));
317  m_errorMask[c_nrFIX_SIZE] = true;
318  return;
319  }
320  unsigned int dhp_header_type = 0;
321 // unsigned int dhp_reserved = 0;
322  unsigned int dhp_dhe_id = 0;
323  unsigned int dhp_dhp_id = 0;
324 
325  dhp_header_type = (dhp_pix[2] & 0xE000) >> 13;
326 // dhp_reserved = (dhp_pix[2] >> 8) & 0x1F;
327  dhp_dhe_id = (dhp_pix[2] & 0x00FC) >> 2;
328  dhp_dhp_id = dhp_pix[2] & 0x0003;
329 
330  if (dhe_ID != dhp_dhe_id) {
331  if (!(m_suppressErrorMask[c_nrDHE_DHP_DHEID])) {
332  B2WARNING("DHE ID in DHE and DHP header differ");
333  B2DEBUG(29, "DHE ID in DHE and DHP header differ $" << hex << dhe_ID << " != $" << dhp_dhe_id);
334  }
335  m_errorMask[c_nrDHE_DHP_DHEID] = true;
336  }
337  if (dhe_DHPport != dhp_dhp_id) {
338  if (!(m_suppressErrorMask[c_nrDHE_DHP_PORT])) {
339  B2WARNING("DHP ID (Chip/Port) in DHE and DHP header differ");
340  B2DEBUG(29, "DHP ID (Chip/Port) in DHE and DHP header differ $" << hex << dhe_DHPport << " != $" << dhp_dhp_id);
341  }
342  m_errorMask[c_nrDHE_DHP_PORT] = true;
343  }
344 
345  if (dhp_header_type != EDHPFrameHeaderDataType::c_RAW) {
346  if (!(m_suppressErrorMask[c_nrHEADERTYPE_INV])) {
347  B2WARNING("Header type invalid for this kind of DHE frame");
348  B2DEBUG(29, "Header type invalid for this kind of DHE frame: $" << hex << dhp_header_type);
349  }
350  m_errorMask[c_nrHEADERTYPE_INV] = true;
351  return;
352  }
353 
355  B2DEBUG(29, "Raw ADC Data");
356  // size checked already above
357  m_storeRawAdc.appendNew(vxd_id, data, frame_len);
358 };
359 
360 void PXDUnpackerOTModule::unpack_fce([[maybe_unused]] unsigned short* data, [[maybe_unused]] unsigned int length,
361  [[maybe_unused]] VxdID vxd_id)
362 {
369 
370  B2WARNING("FCE (Cluster) Packet have not yet been tested with real HW clusters. Dont assume that this code is working!");
371  return;
372 
373  // implement the unpacking here and not as a separate module ... when it is available in HW
374 // ubig16_t* cluster = (ubig16_t*)data;
375 // int nr_words; //words in dhp frame
376 // unsigned int words_in_cluster = 0; //counts 16bit words in cluster
377 // nr_words = length / 2;
378 // ubig16_t sor;
379 // sor = 0x0000;
380 //
381 // for (int i = 2 ; i < nr_words ; i++) {
382 // if (i != 2) { //skip header
383 // if ((((cluster[i] & 0x8000) == 0)
384 // && ((cluster[i] & 0x4000) >> 14) == 1)) { //searches for start of row frame with start of cluster flag = 1 => new cluster
385 // if (!m_doNotStore) m_storeRawCluster.appendNew(&data[i - words_in_cluster], words_in_cluster, vxd_id);
386 // words_in_cluster = 0;
387 // }
388 // }
389 // if ((cluster[i] & 0x8000) == 0) {
390 // sor = cluster[i];
391 // }
392 // words_in_cluster++;
393 //
394 // if ((cluster[nr_words - 1] & 0xFFFF) == (sor &
395 // 0xFFFF)) {//if frame is not 32bit aligned last word will be the last start of row word
396 // cluster[nr_words - 1] = 0x0000;//overwrites the last redundant word with zero to make checking easier in PXDHardwareClusterUnpacker
397 // }
398 //
399 // if (i == nr_words - 1) {
400 // if (!m_doNotStore) m_storeRawCluster.appendNew(&data[i - words_in_cluster + 1], words_in_cluster, vxd_id);
401 // }
402 // }
403 }
404 
405 void PXDUnpackerOTModule::dump_dhp(void* data, unsigned int frame_len)
406 {
407  // called only for debugging purpose, will never be called in normal running
408  unsigned int w = frame_len / 2;
409  ubig16_t* d = (ubig16_t*)data;
410 
411  B2WARNING("HEADER -- $" << hex << d[0] << ",$" << hex << d[1] << ",$" << hex << d[2] << ",$" << hex << d[3] << " -- ");
412 
413  auto dhp_header_type = (d[2] & 0xE000) >> 13;
414  auto dhp_reserved = (d[2] & 0x1F00) >> 8;
415  auto dhp_dhe_id = (d[2] & 0x00FC) >> 2;
416  auto dhp_dhp_id = d[2] & 0x0003;
417 
418  B2WARNING("DHP type | $" << hex << dhp_header_type << " ( " << dec << dhp_header_type << " ) ");
419  B2WARNING("DHP reserved | $" << hex << dhp_reserved << " ( " << dec << dhp_reserved << " ) ");
420  B2WARNING("DHP DHE ID | $" << hex << dhp_dhe_id << " ( " << dec << dhp_dhe_id << " ) ");
421  B2WARNING("DHP DHP ID | $" << hex << dhp_dhp_id << " ( " << dec << dhp_dhp_id << " ) ");
422  for (unsigned int i = 4; i < w; i++) {
423  B2WARNING("DHP DATA $" << hex << d[i]);
424  }
425  B2WARNING("DHP CRC $" << hex << d[w] << ",$" << hex << d[w + 1]);
426 }
427 
428 void PXDUnpackerOTModule::dump_roi(void* data, unsigned int frame_len)
429 {
430  // called only for debugging purpose, will never be called in normal running
431  unsigned int w = frame_len / 4;
432  ubig32_t* d = (ubig32_t*)data;
433 
434  B2WARNING("HEADER -- $" << hex << d[0] << ",$" << hex << d[1] << ",$" << hex << d[2] << ",$" << hex << d[3] << " -- Len $" << hex
435  << frame_len);
436 
437  for (unsigned int i = 0; i < w; i++) {
438  B2WARNING("ROI DATA $" << hex << d[i]);
439  }
440  B2WARNING("ROI CRC $" << hex << d[w]);
441 }
442 
443 void PXDUnpackerOTModule::unpack_dhp(void* data, unsigned int frame_len, unsigned int dhe_first_readout_frame_id_lo,
444  unsigned int dhe_ID, unsigned dhe_DHPport, unsigned dhe_reformat, VxdID vxd_id,
445  PXDDAQPacketStatus& daqpktstat)
446 {
447  unsigned int nr_words = frame_len / 2; // frame_len in bytes (excl. CRC)!!!
448  ubig16_t* dhp_pix = (ubig16_t*)data;
449 
450  unsigned int dhp_readout_frame_lo = 0;
451  unsigned int dhp_header_type = 0;
452  unsigned int dhp_reserved = 0;
453  unsigned int dhp_dhe_id = 0;
454  unsigned int dhp_dhp_id = 0;
455  unsigned int wrap = 0; // workaround to recalc a relative frame number
456  int last_gate = -1; // workaround to recalc a relative frame number
457 
458  // cppcheck-suppress unreadVariable
459  unsigned int dhp_row = 0, dhp_col = 0, dhp_cm = 0;
460 // unsigned int dhp_offset = 0;
461  bool rowflag = false;
462  bool pixelflag = true; // just for first row start
463 
464  if (nr_words < 4) {
465  if (!(m_suppressErrorMask[c_nrDHP_SIZE])) B2WARNING("DHP frame size error (too small)" << LogVar("Nr words", nr_words));
466  m_errorMask[c_nrDHP_SIZE] = true;
467  return;
468  }
469 
470  B2DEBUG(29, "HEADER -- $" << hex << dhp_pix[0] << hex << dhp_pix[1] << hex << dhp_pix[2] << hex << dhp_pix[3] << " -- ");
471 
472  B2DEBUG(29, "DHP Header | $" << hex << dhp_pix[2] << " ( " << dec << dhp_pix[2] << " ) ");
473  dhp_header_type = (dhp_pix[2] & 0xE000) >> 13;
474  dhp_reserved = (dhp_pix[2] & 0x1F00) >> 8;
475  dhp_dhe_id = (dhp_pix[2] & 0x00FC) >> 2;
476  dhp_dhp_id = dhp_pix[2] & 0x0003;
477 
478  B2DEBUG(29, "DHP type | $" << hex << dhp_header_type << " ( " << dec << dhp_header_type << " ) ");
479  B2DEBUG(29, "DHP reserved | $" << hex << dhp_reserved << " ( " << dec << dhp_reserved << " ) ");
480  B2DEBUG(29, "DHP DHE ID | $" << hex << dhp_dhe_id << " ( " << dec << dhp_dhe_id << " ) ");
481  B2DEBUG(29, "DHP DHP ID | $" << hex << dhp_dhp_id << " ( " << dec << dhp_dhp_id << " ) ");
482 
483  if (dhe_ID != dhp_dhe_id) {
484  if (!(m_suppressErrorMask[c_nrDHE_DHP_DHEID])) {
485  B2WARNING("DHE ID in DHE and DHP header differ");
486  B2DEBUG(29, "DHE ID in DHE and DHP header differ $" << hex << dhe_ID << " != $" << dhp_dhe_id);
487  }
488  m_errorMask[c_nrDHE_DHP_DHEID] = true;
489  }
490  if (dhe_DHPport != dhp_dhp_id) {
491  if (!(m_suppressErrorMask[c_nrDHE_DHP_PORT])) {
492  B2WARNING("DHP ID (Chip/Port) in DHE and DHP header differ");
493  B2DEBUG(29, "DHP ID (Chip/Port) in DHE and DHP header differ $" << hex << dhe_DHPport << " != $" << dhp_dhp_id);
494  }
495  m_errorMask[c_nrDHE_DHP_PORT] = true;
496  }
497 
498  if (dhp_header_type != EDHPFrameHeaderDataType::c_ZSD) {
499  if (!(m_suppressErrorMask[c_nrHEADERTYPE_INV])) {
500  B2WARNING("Header type invalid for this kind of DHE frame");
501  B2DEBUG(29, "Header type invalid for this kind of DHE frame: $" << hex << dhp_header_type);
502  }
503  m_errorMask[c_nrHEADERTYPE_INV] = true;
504  return;
505  }
506 
507 // static int offtab[4] = {0, 64, 128, 192};
508 // dhp_offset = offtab[dhp_dhp_id];
509 
510  dhp_readout_frame_lo = dhp_pix[3] & 0xFFFF;
511  B2DEBUG(29, "DHP Frame Nr | $" << hex << dhp_readout_frame_lo << " ( " << dec << dhp_readout_frame_lo << " ) ");
512 
513  /* // TODO removed because data format error is not to be fixed soon
514  if (((dhp_readout_frame_lo - dhe_first_readout_frame_id_lo) & 0x3F) > m_maxDHPFrameDiff) {
515  if(!m_suppressErrorMask&c_DHP_DHE_FRAME_DIFFER ) B2WARNING("DHP Frame Nr differ from DHE Frame Nr by >1 DHE " << dhe_first_readout_frame_id_lo << " != DHP " << (dhp_readout_frame_lo & 0x3F) << " delta "<< ((dhp_readout_frame_lo - dhe_first_readout_frame_id_lo) & 0x3F) );
516  m_errorMask[c_nrDHP_DHE_FRAME_DIFFER] = true;
517  }
518  */
519  /* // TODO removed because data format error is not to be fixed soon
520  if (m_last_dhp_readout_frame_lo[dhp_dhp_id] != -1) {
521  if (((dhp_readout_frame_lo - m_last_dhp_readout_frame_lo[dhp_dhp_id]) & 0xFFFF) > m_maxDHPFrameDiff) {
522  if(!m_suppressErrorMask&c_DHP_NOT_CONT ) B2WARNING("Two DHP Frames per sensor which frame number differ more than one! " << m_last_dhp_readout_frame_lo[dhp_dhp_id] << ", " <<
523  dhp_readout_frame_lo);
524  m_errorMask[c_nrDHP_NOT_CONT] = true;
525  }
526  }
527  */
528 
529  if (daqpktstat.dhc_size() > 0) {
530  if (daqpktstat.dhc_back().dhe_size() > 0) {
531  // only is we have a DHC and DHE object... or back() is undefined
532  // Remark, if we have a broken data (DHE_START/END) structure, we might fill the
533  // previous DHE object ... but then the data is junk anyway
534  daqpktstat.dhc_back().dhe_back().newDHP(dhp_dhp_id, dhp_readout_frame_lo);
535  }
536  }
537 
538  /* // TODO removed because the data is not ordered as expected in current firmware
539  for (auto j = 0; j < 4; j++) {
540  if (m_last_dhp_readout_frame_lo[j] != -1) {
541  if (((dhp_readout_frame_lo - m_last_dhp_readout_frame_lo[j]) & 0xFFFF) > m_maxDHPFrameDiff) {
542  if(!m_suppressErrorMask&c_DHP_DHP_FRAME_DIFFER ) B2WARNING("Two DHP Frames (different DHP) per sensor which frame number differ more than one! " << m_last_dhp_readout_frame_lo[j] <<
543  ", " <<
544  dhp_readout_frame_lo);
545  m_errorMask[c_nrDHP_DHP_FRAME_DIFFER] = true;
546  break;// give msg only once
547  }
548  }
549  }
550  */
551  m_last_dhp_readout_frame_lo[dhp_dhp_id] = dhp_readout_frame_lo;
552 
553 // TODO Please check if this can happen by accident with valid data!
554  if (dhp_pix[2] == dhp_pix[4] && dhp_pix[3] + 1 == dhp_pix[5]) {
555  // We see a second "header" with framenr+1 ...
556  if (!(m_suppressErrorMask[c_nrDHP_DBL_HEADER])) {
557  B2WARNING("DHP data: seems to be double header! skipping.");
558  B2DEBUG(29, "DHP data: seems to be double header! skipping." << LogVar("Length",
559  frame_len));
560  }
561  m_errorMask[c_nrDHP_DBL_HEADER] = true;
562  // dump_dhp(data, frame_len); print out guilty dhp packet
563  return;
564  }
565 
566  // Start with offset 4, thus skipping header words
567  for (unsigned int i = 4; i < nr_words ; i++) {
568 
569  B2DEBUG(29, "-- $" << hex << dhp_pix[i] << " -- " << dec << i);
570  {
571  if (((dhp_pix[i] & 0x8000) >> 15) == 0) {
572  rowflag = true;
573  if (!pixelflag) {
574  if (!(m_suppressErrorMask[c_nrDHP_ROW_WO_PIX])) B2WARNING("DHP Unpacking: Row w/o Pix");
575  m_errorMask[c_nrDHP_ROW_WO_PIX] = true;
576  }
577  pixelflag = false;
578  dhp_row = (dhp_pix[i] & 0xFFC0) >> 5;
579  dhp_cm = dhp_pix[i] & 0x3F;
580  if (last_gate != -1 && (int)dhp_row / 4 < last_gate) {
581  // B2DEBUF(29,"Wrap " << LogVar("last", last_gate) << LogVar("curr", dhp_row / 4) << LogVar("DHE", dhe_ID) << LogVar("DHP", dhp_dhp_id));
582  wrap++; // relies on the order of data before mapping and the fact that OT firmware delivers only one frame
583  }
584  last_gate = dhp_row / 4;
585 
586  if (dhp_cm == 63) { // fifo overflow
587  B2WARNING("DHP data loss (CM=63) in " << LogVar("DHE", dhe_ID) << LogVar("DHP", dhp_dhp_id));
589  m_errorMask[c_nrDHH_MISC_ERROR] = true;
590  }
591  if (daqpktstat.dhc_size() > 0) {
592  if (daqpktstat.dhc_back().dhe_size() > 0) {
593  PXDDAQDHPComMode cm(dhp_dhp_id, dhp_row, dhp_cm);
594  // only is we have a DHC and DHE object... or back() is undefined
595  // Remark, if we have a broken data (DHE_START/END) structure, we might fill the
596  // previous DHE object ... but then the data is junk anyway
597  daqpktstat.dhc_back().dhe_back().addCM(cm);
598  }
599  }
600  B2DEBUG(29, "SetRow: $" << hex << dhp_row << " CM $" << hex << dhp_cm);
601  } else {
602  if (!rowflag) {
603  if (!(m_suppressErrorMask[c_nrDHP_PIX_WO_ROW])) B2WARNING("DHP Unpacking: Pix without Row!!! skip dhp data ");
604  m_errorMask[c_nrDHP_PIX_WO_ROW] = true;
605  // dump_dhp(data, frame_len);// print out faulty dhp frame
606  return;
607  } else {
608  pixelflag = true;
609  dhp_row = (dhp_row & 0xFFE) | ((dhp_pix[i] & 0x4000) >> 14);
610  dhp_col = ((dhp_pix[i] & 0x3F00) >> 8);
611  unsigned int v_cellID, u_cellID;
612  v_cellID = dhp_row;// defaults for no mapping
613  if (dhp_row >= 768) {
614  if (!(m_suppressErrorMask[c_nrROW_OVERFLOW])) B2WARNING("DHP ROW Overflow " << LogVar("Row", dhp_row));
615  m_errorMask[c_nrROW_OVERFLOW] = true;
616  }
617  // we cannot do col overflow check before mapping :-(
618 
619  if ((dhe_reformat == 0 && !m_forceNoMapping) || m_forceMapping) {
620  u_cellID = dhp_col;// defaults for no mapping
621  // data has not been pre-processed by DHH, thus we have to do the mapping ourselves
622  if ((dhe_ID & 0x21) == 0x00 || (dhe_ID & 0x21) == 0x21) {
623  // if IFOB
624  PXDMappingLookup::map_rc_to_uv_IF_OB(v_cellID, u_cellID, dhp_dhp_id, dhe_ID);
625  } else { // else OFIB
626  PXDMappingLookup::map_rc_to_uv_IB_OF(v_cellID, u_cellID, dhp_dhp_id, dhe_ID);
627  }
628  } else {
629  u_cellID = dhp_col + 64 * dhp_dhp_id; // defaults for already mapped
630  }
631  if (u_cellID >= 250) {
632  if (!(m_suppressErrorMask[c_nrCOL_OVERFLOW])) {
633  B2WARNING("DHP COL Overflow (unconnected drain lines)");
634  B2DEBUG(29, "DHP COL Overflow (unconnected drain lines) " << u_cellID << ", reformat " << dhe_reformat << ", dhpcol " << dhp_col <<
635  ", id " << dhp_dhp_id);
636  }
637  m_errorMask[c_nrCOL_OVERFLOW] = true;
638  }
639  auto dhp_adc = dhp_pix[i] & 0xFF;
640  B2DEBUG(29, "SetPix: Row $" << hex << dhp_row << " Col $" << hex << dhp_col << " ADC $" << hex << dhp_adc
641  << " CM $" << hex << dhp_cm);
642 
643  if (dhp_adc == 0) {
644  // if !supress error flag
645  B2WARNING("DHE Event truncation in DHE " << dhe_ID << " DHP " << dhp_dhp_id);
646  // m_errorMask |= c_DHE_EVENT_TRUNC;
647  daqpktstat.dhc_back().dhe_back().dhp_back().setTruncated();
648  } else {
649  // in new firmware, (dhp_readout_frame_lo - dhe_first_readout_frame_id_lo) would always been 0
650  if (!m_doNotStore) m_storeRawHits.appendNew(vxd_id, v_cellID, u_cellID, dhp_adc,
651  (dhp_readout_frame_lo - dhe_first_readout_frame_id_lo + wrap) & 0x3F);
652  }
653  }
654  }
655  }
656  }
657 
658  B2DEBUG(29, "(DHE) DHE_ID $" << hex << dhe_ID << " (DHE) DHP ID $" << hex << dhe_DHPport << " (DHP) DHE_ID $" << hex << dhp_dhe_id
659  << " (DHP) DHP ID $" << hex << dhp_dhp_id);
660  /*for (int i = 0; i < raw_nr_words ; i++) {
661  B2DEBUG(29, "RAW | " << hex << p_pix[i]);
662  printf("raw %08X | ", p_pix[i]);
663  B2DEBUG(29, "row " << hex << ((p_pix[i] >> 20) & 0xFFF) << dec << " ( " << ((p_pix[i] >> 20) & 0xFFF) << " ) " << " col " << hex << ((p_pix[i] >> 8) & 0xFFF)
664  << " ( " << dec << ((p_pix[i] >> 8) & 0xFFF) << " ) " << " adc " << hex << (p_pix[i] & 0xFF) << " ( " << (p_pix[i] & 0xFF) << " ) "
665  );
666  }*/
667 }
668 
669 void PXDUnpackerOTModule::unpack_dhc_frame(void* data, const int len, const int Frame_Number, const int Frames_in_event,
670  PXDDAQPacketStatus& daqpktstat)
671 {
675  static unsigned int eventNrOfOnsenTrgFrame = 0;
676  static int countedBytesInDHC = 0;
677  static bool cancheck_countedBytesInDHC = false;
678  static int countedBytesInDHE = 0;
679  static bool cancheck_countedBytesInDHE = false;
680  static int countedDHEStartFrames = 0;
681  static int countedDHEEndFrames = 0;
682  static int mask_active_dhe = 0;// DHE mask (5 bit)
683  static int nr_active_dhe =
684  0;// TODO just count the active DHEs. Until now, it is not possible to check for the bit mask. we would need the info on which DHE connects to which DHC at which port from gearbox/geometry?
685  static int mask_active_dhp = 0;// DHP active mask, 4 bit, per current DHE
686  static int found_mask_active_dhp = 0;// mask which DHP send data and check on DHE END frame if it matches
687  static int found_good_mask_active_dhp = 0;// mask which DHP send useful data
688  static unsigned int dhe_first_readout_frame_id_lo = 0;
689  // cppcheck-suppress variableScope
690  static unsigned int dhe_first_triggergate = 0;
691  static unsigned int currentDHCID = 0xFFFFFFFF;
692  static unsigned int currentDHEID = 0xFFFFFFFF;
693  static unsigned int currentVxdId = 0;
694  static bool isFakedData_event = false;
695  static bool isUnfiltered_event = false;
696 
697 
698  if (Frame_Number == 0) {
699  // We reset the counters on the first event
700  // we do this before any other check is done
701  eventNrOfOnsenTrgFrame = 0;
702  countedDHEStartFrames = 0;
703  countedDHEEndFrames = 0;
704  countedBytesInDHC = 0;
705  cancheck_countedBytesInDHC = false;
706  countedBytesInDHE = 0;
707  cancheck_countedBytesInDHE = false;
708  currentDHCID = 0xFFFFFFFF;
709  currentDHEID = 0xFFFFFFFF;
710  currentVxdId = 0;
711  isUnfiltered_event = false;
712  isFakedData_event = false;
713  mask_active_dhe = 0;
714  nr_active_dhe = 0;
715  mask_active_dhp = 0;
716  found_mask_active_dhp = 0;
717  found_good_mask_active_dhp = 0;
718  }
719 
721 
722  dhc_frames dhc;
723  dhc.set(data, hw->getFrameType(), len);
724 
725  {
726  // if a fixed size frame has a different length, how can we rely on its content???
727  // AND we could by typecasting access memory beyond end of data (but very unlikely)
728  // for that reason this we have to check before any CRC and stop unpacking the frame
729  int s = dhc.getFixedSize();
730  if (len != s && s != 0) {
731  if (!(m_suppressErrorMask[c_nrFIX_SIZE])) {
732  B2WARNING("Fixed frame type size does not match specs" << LogVar("expected length",
733  len) << LogVar("length in data", s));
734  }
735  m_errorMask[c_nrFIX_SIZE] = true;
736  if (!m_continueOnError) return;
737  }
738  }
739 
740  // What do we do with wrong checksum frames? As we do not know WHAT is wrong, we have to skip them alltogether.
741  // As they might contain HEADER Info, we might better skip the processing of the full package, too.
742  dhc.check_crc(m_errorMask, m_suppressErrorMask[c_nrDHE_CRC]);
743  if (!m_continueOnError && m_errorMask[c_nrDHE_CRC]) {
744  // if CRC is wrong, we cannot rely on the content of the frame, thus skipping is the best option
745  return;
746  }
747 
748  unsigned int eventNrOfThisFrame = dhc.getEventNrLo();
749  int frame_type = dhc.getFrameType();
750 
751  if (Frame_Number == 0) {
752  if (m_formatBonnDAQ) {
753  if (frame_type != EDHCFrameHeaderDataType::c_DHC_START) {
754  if (!(m_suppressErrorMask[c_nrEVENT_STRUCT])) B2WARNING("This looks not like BonnDAQ format.");
755  m_errorMask[c_nrEVENT_STRUCT] = true;
756 // if (!m_continueOnError) return; // requires more testing
757  }
758  } else {
759  if (frame_type == EDHCFrameHeaderDataType::c_DHC_START) {
760  if (!(m_suppressErrorMask[c_nrEVENT_STRUCT]))
761  B2WARNING("This looks like BonnDAQ or old Desy 2013/14 testbeam format. Please use formatBonnDAQ or the pxdUnpackerDesy1314 module.");
762  m_errorMask[c_nrEVENT_STRUCT] = true;
763 // if (!m_continueOnError) return; // requires more testing
764  }
765  }
766  }
767 
768  if (!m_formatBonnDAQ) {
769  if (Frame_Number == 1) {
770  if (frame_type == EDHCFrameHeaderDataType::c_DHC_START) {
771  isFakedData_event = dhc.data_dhc_start_frame->isFakedData();
772  }
773  }
774 
775  // please check if this mask is suitable. At least here we are limited by the 16 bit trigger number in the DHH packet header.
776  // we can use more bits in the DHC and DHE START Frame
777  if ((eventNrOfThisFrame & 0xFFFF) != (m_meta_event_nr & 0xFFFF)) {
778  if (!isFakedData_event) {
779  if (!(m_suppressErrorMask[c_nrMETA_MM])) {
780  B2WARNING("Event Numbers do not match for this frame");
781  B2DEBUG(29, "Event Numbers do not match for this frame" <<
782  LogVar("Event nr in frame $", static_cast < std::ostringstream
783  && >(std::ostringstream() << hex << eventNrOfThisFrame).str()) <<
784  LogVar("Event nr in MetaInfo (bits masked) $",
785  static_cast < std::ostringstream && >(std::ostringstream() << hex << m_meta_event_nr).str()));
786  }
787  m_errorMask[c_nrMETA_MM] = true;
788 // if (!m_continueOnError) return; // requires more testing
789  }
790  }
791 
792  if (Frame_Number > 1 && Frame_Number < Frames_in_event - 1) {
793  if (countedDHEStartFrames != countedDHEEndFrames + 1)
794  if (frame_type != EDHCFrameHeaderDataType::c_ONSEN_ROI && frame_type != EDHCFrameHeaderDataType::c_DHE_START) {
795  if (!(m_suppressErrorMask[c_nrDATA_OUTSIDE])) B2WARNING("Data Frame outside a DHE START/END");
796  m_errorMask[c_nrDATA_OUTSIDE] = true;
797 // if (!m_continueOnError) return; // requires more testing
798  }
799  }
800  }
801 
802  // TODO How do we handle Frames where Error Bit is set in header?
803  // Currently there is no documentation what it actually means... only an error bit is set (below)
804  // the following errors must be "accepted", as all firmware sets it wrong from Ghost frames.
805  if (hw->getErrorFlag()) {
806  if (frame_type != EDHCFrameHeaderDataType::c_GHOST) {
807  // We get ERROR bits in header even if only one module or DHP link is missing... thus
808  // we better filter a bit more ... but how?
809  if (!(m_suppressErrorMask[c_nrHEADER_ERR])) B2WARNING("Error Bit set in DHE Header");
810  m_errorMask[c_nrHEADER_ERR] = true;// TODO this should have some effect ... when does it mean something? documentation missing
811  }
812  } else {
813  if (frame_type == EDHCFrameHeaderDataType::c_GHOST) {
814  m_errorMask[c_nrHEADER_ERR_GHOST] = true;
815  }
816  }
817 
818  switch (frame_type) {
819  case EDHCFrameHeaderDataType::c_DHP_RAW: {
820 
822  if (currentDHEID != dhc.data_direct_readout_frame_raw->getDHEId()) {
823  if (!(m_suppressErrorMask[c_nrDHE_START_ID])) {
824  B2WARNING("DHE ID from DHE Start and this frame do not match");
825  B2DEBUG(29, "DHE ID from DHE Start and this frame do not match" <<
826  LogVar("DHEID in this frame $", static_cast < std::ostringstream
827  && >(std::ostringstream() << hex << dhc.data_direct_readout_frame_raw->getDHEId()).str()) <<
828  LogVar("DHEID expected $", static_cast < std::ostringstream && >(std::ostringstream() << hex << currentDHEID).str()));
829  }
830  m_errorMask[c_nrDHE_START_ID] = true;
831  }
832  dhc.check_crc(m_errorMask, m_suppressErrorMask[c_nrDHE_CRC]);
833  if ((found_mask_active_dhp & (1 << dhc.data_direct_readout_frame->getDHPPort())) != 0) {
834  B2ERROR("Second DHP data packet (MEMDUMP) for " << LogVar("DHE", currentDHEID) << LogVar("DHP",
836  }
837 
838  found_mask_active_dhp |= 1 << dhc.data_direct_readout_frame->getDHPPort();
839 
840  unpack_dhp_raw(data, len - 4,
843  currentVxdId);
844 
845  break;
846  };
847  case EDHCFrameHeaderDataType::c_ONSEN_DHP:
848  // Set the counted size invalid if negativ, needs a large negative value because we are adding up to that
849  cancheck_countedBytesInDHC = false;
850  cancheck_countedBytesInDHE = false;
851  [[fallthrough]];
852  case EDHCFrameHeaderDataType::c_DHP_ZSD: {
853 
855  if (isUnfiltered_event) {
856  if (frame_type == EDHCFrameHeaderDataType::c_ONSEN_DHP) m_errorMask[c_nrSENDALL_TYPE] = true;
857  } else {
858  if (frame_type == EDHCFrameHeaderDataType::c_DHP_ZSD) m_errorMask[c_nrNOTSENDALL_TYPE] = true;
859  }
860 
861  //m_errorMask |= dhc.data_direct_readout_frame->check_error();
862 
863  if (currentDHEID != dhc.data_direct_readout_frame_raw->getDHEId()) {
864  if (!(m_suppressErrorMask[c_nrDHE_START_ID])) {
865  B2WARNING("DHE ID from DHE Start and this frame do not match");
866  B2DEBUG(29, "DHE ID from DHE Start and this frame do not match" <<
867  LogVar("DHEID in this frame $", static_cast < std::ostringstream
868  && >(std::ostringstream() << hex << dhc.data_direct_readout_frame_raw->getDHEId()).str()) <<
869  LogVar("DHEID expected $", static_cast < std::ostringstream && >(std::ostringstream() << hex << currentDHEID).str()));
870  }
871  m_errorMask[c_nrDHE_START_ID] = true;
872  }
873  dhc.check_crc(m_errorMask, m_suppressErrorMask[c_nrDHE_CRC]);
874  if ((found_mask_active_dhp & (1 << dhc.data_direct_readout_frame->getDHPPort())) != 0) {
875  B2ERROR("Second DHP data packet for " << LogVar("DHE", currentDHEID) << LogVar("DHP", dhc.data_direct_readout_frame->getDHPPort()));
876  }
877  found_mask_active_dhp |= 1 << dhc.data_direct_readout_frame->getDHPPort();
878  found_good_mask_active_dhp |= 1 << dhc.data_direct_readout_frame->getDHPPort();// only this frametype has useful data
879  if (m_checkPaddingCRC) dhc.check_padding(m_errorMask); // isUnfiltered_event
880 
881 
882  unpack_dhp(data, len - 4,
883  dhe_first_readout_frame_id_lo,
887  currentVxdId, daqpktstat);
888 
889  break;
890  };
891  case EDHCFrameHeaderDataType::c_ONSEN_FCE:
892  // Set the counted size invalid if negativ, needs a large negative value because we are adding up to that
893  cancheck_countedBytesInDHC = false;
894  cancheck_countedBytesInDHE = false;
895  [[fallthrough]];
896  case EDHCFrameHeaderDataType::c_FCE_RAW: {
897  if (!(m_suppressErrorMask[c_nrUNEXPECTED_FRAME_TYPE])) B2WARNING("Unexpected Frame Type (Clustering FCE)");
898  m_errorMask[c_nrUNEXPECTED_FRAME_TYPE] = true;
899  if (m_verbose) hw->print();
900  if (isUnfiltered_event) {
901  if (frame_type == EDHCFrameHeaderDataType::c_ONSEN_FCE) {
902  // TODO add error message
903  m_errorMask[c_nrSENDALL_TYPE] = true;
904  }
905  } else {
906  if (frame_type == EDHCFrameHeaderDataType::c_FCE_RAW) {
907  // TODO add error message
908  m_errorMask[c_nrNOTSENDALL_TYPE] = true;
909  }
910  }
911 
912  if (currentDHEID != dhc.data_direct_readout_frame_raw->getDHEId()) {
913  if (!(m_suppressErrorMask[c_nrDHE_START_ID])) {
914  B2WARNING("DHE ID from DHE Start and this frame do not match");
915  B2DEBUG(29, "DHE ID from DHE Start and this frame do not match" <<
916  LogVar("DHEID in this frame $", static_cast < std::ostringstream
917  && >(std::ostringstream() << hex << dhc.data_direct_readout_frame_raw->getDHEId()).str()) <<
918  LogVar("DHEID expected $", static_cast < std::ostringstream && >(std::ostringstream() << hex << currentDHEID).str()));
919  }
920  m_errorMask[c_nrDHE_START_ID] = true;
921  }
922  dhc.check_crc(m_errorMask, m_suppressErrorMask[c_nrDHE_CRC]);
923  if ((found_mask_active_dhp & (1 << dhc.data_direct_readout_frame->getDHPPort())) != 0) {
924  B2ERROR("Second DHP data packet (FCE) for " << LogVar("DHE", currentDHEID) << LogVar("DHP",
926  }
927  found_mask_active_dhp |= 1 << dhc.data_direct_readout_frame->getDHPPort();
928 
929  B2DEBUG(29, "UNPACK FCE FRAME with len $" << hex << len);
930  unpack_fce((unsigned short*) data, len - 4, currentVxdId);
931 
932  break;
933  };
934  case EDHCFrameHeaderDataType::c_COMMODE: {
935  // this frame type has up to now not been well defined, we do not expect it until
936  // the firmware supports clustering in hardware
937  if (!(m_suppressErrorMask[c_nrUNEXPECTED_FRAME_TYPE])) B2WARNING("Unexpected Frame Type (COMMODE)");
938  m_errorMask[c_nrUNEXPECTED_FRAME_TYPE] = true;
939 
940  if (m_verbose) hw->print();
941  if (currentDHEID != dhc.data_commode_frame->getDHEId()) {
942  if (!(m_suppressErrorMask[c_nrDHE_START_ID])) {
943  B2WARNING("DHE ID from DHE Start and this frame do not match");
944  B2DEBUG(29, "DHE ID from DHE Start and this frame do not match" <<
945  LogVar("DHEID in this frame $", static_cast < std::ostringstream
946  && >(std::ostringstream() << hex << dhc.data_commode_frame->getDHEId()).str()) <<
947  LogVar("DHEID expected $", static_cast < std::ostringstream && >(std::ostringstream() << hex << currentDHEID).str()));
948  }
949  m_errorMask[c_nrDHE_START_ID] = true;
950  }
951  dhc.check_crc(m_errorMask, m_suppressErrorMask[c_nrDHE_CRC]);
952  break;
953  };
954  case EDHCFrameHeaderDataType::c_DHC_START: {
955  countedBytesInDHC = 0;
956  cancheck_countedBytesInDHC = true;
957  if (isFakedData_event != dhc.data_dhc_start_frame->isFakedData()) {
958  if (!(m_suppressErrorMask[c_nrFAKE_NO_FAKE_DATA])) B2WARNING("DHC START mixed Fake/no Fake event.");
959  m_errorMask[c_nrFAKE_NO_FAKE_DATA] = true;
960  }
961  if (dhc.data_dhc_start_frame->isFakedData()) {
962  if (!(m_suppressErrorMask[c_nrFAKE_NO_DATA_TRIG])) B2WARNING("Faked DHC START Data -> trigger without Data!");
963  m_errorMask[c_nrFAKE_NO_DATA_TRIG] = true;
964  } else {
966  }
967 
968 // eventNrOfOnsenTrgFrame = eventNrOfThisFrame;
969  currentDHEID = 0xFFFFFFFF;
970  currentVxdId = 0;
971  currentDHCID = dhc.data_dhc_start_frame->get_dhc_id();
972  dhc.check_crc(m_errorMask, m_suppressErrorMask[c_nrDHE_CRC]);
973 
974  if (m_formatBonnDAQ) eventNrOfOnsenTrgFrame = eventNrOfThisFrame;
975 
976  if (!isFakedData_event) {
980  if (!(m_suppressErrorMask[c_nrMETA_MM_DHC_ERS])) {
981  B2WARNING("DHC-Meta Experiment number mismatch");
982  B2DEBUG(29, "DHC-Meta Experiment number mismatch" <<
983  LogVar("DHC exp nr",
985  LogVar("META exp nr", m_meta_experiment));
986  }
987  m_errorMask[c_nrMETA_MM_DHC_ERS] = true;
988  }
990  if (!(m_suppressErrorMask[c_nrMETA_MM_DHC_ERS])) {
991  B2WARNING("DHC-Meta Run number mismatch");
992  B2DEBUG(29, "DHC-Meta Run number mismatch" <<
993  LogVar("DHC Run nr",
994  dhc.data_dhc_start_frame->get_run()) <<
995  LogVar("META run nr", m_meta_run_nr));
996  }
997  m_errorMask[c_nrMETA_MM_DHC_ERS] = true;
998  }
1000  if (!(m_suppressErrorMask[c_nrMETA_MM_DHC_ERS])) {
1001  B2WARNING("DHC-Meta Sub-Run number mismatch");
1002  B2DEBUG(29, "DHC-Meta Sub-Run number mismatch" <<
1003  LogVar("DHC subrun nr",
1004  dhc.data_dhc_start_frame->get_subrun()) <<
1005  LogVar("META subrun nr", m_meta_subrun_nr));
1006  }
1007  m_errorMask[c_nrMETA_MM_DHC_ERS] = true;
1008  }
1009  if ((((unsigned int)dhc.data_dhc_start_frame->getEventNrHi() << 16) | dhc.data_dhc_start_frame->getEventNrLo()) !=
1010  (m_meta_event_nr & 0xFFFFFFFF)) {
1011  if (!(m_suppressErrorMask[c_nrMETA_MM_DHC])) {
1012  B2WARNING("DHC-Meta 32 bit event number mismatch");
1013  B2DEBUG(29, "DHC-Meta 32 bit event number mismatch" <<
1014  LogVar("DHC trigger nr", (((unsigned int) dhc.data_dhc_start_frame->getEventNrHi() << 16) |
1016  LogVar("META trigger nr", (unsigned int)(m_meta_event_nr & 0xFFFFFFFF)));
1017  }
1018  m_errorMask[c_nrMETA_MM_DHC] = true;
1019  }
1020  uint32_t trig_ticks = (((unsigned int)dhc.data_dhc_start_frame->time_tag_mid & 0x7FFF) << 12) | ((unsigned int)
1022  uint32_t trig_sec = (dhc.data_dhc_start_frame->time_tag_hi * 2) ;
1023  if (dhc.data_dhc_start_frame->time_tag_mid & 0x8000) trig_sec++;
1024 
1025  if ((trig_ticks - m_meta_ticks) != 0 || (trig_sec - m_meta_sec) != 0) {
1026  m_errorMask[c_nrMETA_MM_DHC_TT] = true;
1027  if (!(m_suppressErrorMask[c_nrMETA_MM_DHC_TT])) {
1028  B2WARNING("DHC-Meta TimeTag mismatch");
1029  B2DEBUG(29, "DHC-Meta TimeTag mismatch" <<
1030  LogVar("Header Time $", static_cast < std::ostringstream && >(std::ostringstream() <<
1031  hex << dhc.data_dhc_start_frame->time_tag_hi << "." <<
1032  dhc.data_dhc_start_frame->time_tag_mid << "." <<
1034  LogVar("Meta Time $", static_cast < std::ostringstream && >(std::ostringstream() << hex << m_meta_time).str()) <<
1035  LogVar("Trigger Type", static_cast < std::ostringstream
1036  && >(std::ostringstream() << hex << (dhc.data_dhc_start_frame->time_tag_lo_and_type & 0xF)).str()) <<
1037  LogVar("Meta seconds: $", static_cast < std::ostringstream && >(std::ostringstream() << hex << m_meta_sec).str()) <<
1038  LogVar("DHC seconds $", static_cast < std::ostringstream && >(std::ostringstream() << hex << trig_sec).str()) <<
1039  LogVar("Seconds difference $", static_cast < std::ostringstream
1040  && >(std::ostringstream() << hex << (trig_sec - m_meta_sec)).str()) <<
1041  LogVar("Meta ticks from 127MHz $", static_cast < std::ostringstream && >(std::ostringstream() << hex << m_meta_ticks).str()) <<
1042  LogVar("DHC ticks from 127MHz $", static_cast < std::ostringstream && >(std::ostringstream() << hex << trig_ticks).str()) <<
1043  LogVar("Tick difference $", static_cast < std::ostringstream
1044  && >(std::ostringstream() << hex << (trig_ticks - m_meta_ticks)).str()));
1045  }
1046  } else {
1047  B2DEBUG(29, "DHC TT: $" << hex << dhc.data_dhc_start_frame->time_tag_hi << "." << dhc.data_dhc_start_frame->time_tag_mid << "." <<
1048  dhc.data_dhc_start_frame->time_tag_lo_and_type << " META " << m_meta_time << " TRG Type " <<
1050  }
1051  }
1052  mask_active_dhe = dhc.data_dhc_start_frame->get_active_dhe_mask();
1053  nr_active_dhe = nr5bits(mask_active_dhe);
1054 
1055  m_errorMaskDHC = m_errorMask; // forget about anything before this frame
1056  daqpktstat.newDHC(currentDHCID, m_errorMask);
1059 
1060  break;
1061  };
1062  case EDHCFrameHeaderDataType::c_DHE_START: {
1063  countedBytesInDHE = 0;
1064  cancheck_countedBytesInDHE = true;
1069  if (m_verbose) dhc.data_dhe_start_frame->print();
1070  dhe_first_readout_frame_id_lo = dhc.data_dhe_start_frame->getStartFrameNr();
1071  dhe_first_triggergate = dhc.data_dhe_start_frame->getTriggerGate();
1072  if (currentDHEID != 0xFFFFFFFF && (currentDHEID & 0xFFFF) >= dhc.data_dhe_start_frame->getDHEId()) {
1073  if (!(m_suppressErrorMask[c_nrDHE_WRONG_ID_SEQ])) {
1074  B2WARNING("DHH IDs are not in expected order");
1075  B2DEBUG(29, "DHH IDs are not in expected order" <<
1076  LogVar("Previous ID", (currentDHEID & 0xFFFF)) <<
1077  LogVar("Current ID", dhc.data_dhe_start_frame->getDHEId()));
1078  }
1079  m_errorMask[c_nrDHE_WRONG_ID_SEQ] = true;
1080  }
1081  currentDHEID = dhc.data_dhe_start_frame->getDHEId();
1082  dhc.check_crc(m_errorMask, m_suppressErrorMask[c_nrDHE_CRC]);
1083 
1084  if (countedDHEStartFrames > countedDHEEndFrames) {
1085  if (!(m_suppressErrorMask[c_nrDHE_START_WO_END])) B2WARNING("DHE_START without DHE_END");
1086  m_errorMask[c_nrDHE_START_WO_END] = true;
1087  }
1088  countedDHEStartFrames++;
1089 
1090  found_mask_active_dhp = 0;
1091  found_good_mask_active_dhp = 0;
1092  mask_active_dhp = dhc.data_dhe_start_frame->getActiveDHPMask();
1093 
1094  if ((((unsigned int)dhc.data_dhe_start_frame->getEventNrHi() << 16) | dhc.data_dhe_start_frame->getEventNrLo()) != (unsigned int)(
1095  m_meta_event_nr & 0xFFFFFFFF)) {
1096  if (!(m_suppressErrorMask[c_nrMETA_MM_DHE])) {
1097  B2WARNING("DHE START trigger mismatch in EVT32b/HI WORD");
1098  B2DEBUG(29, "DHE START trigger mismatch in EVT32b/HI WORD" <<
1099  LogVar("DHE Start trigger nr", (dhc.data_dhe_start_frame->getEventNrHi() << 16) | dhc.data_dhe_start_frame->getEventNrLo()) <<
1100  LogVar("Meta trigger nr", (m_meta_event_nr & 0xFFFFFFFF)));
1101  }
1102  m_errorMask[c_nrMETA_MM_DHE] = true;
1103  }
1104 // B2WARNING("DHE TT: $" << hex << dhc.data_dhe_start_frame->dhe_time_tag_hi << "." << dhc.data_dhe_start_frame->dhe_time_tag_lo <<
1105 // " META " << m_meta_time);
1106 
1107  if (currentDHEID == 0) {
1108  if (!(m_suppressErrorMask[c_nrDHE_ID_INVALID])) B2WARNING("DHE ID is invalid=0 (not initialized)");
1109  m_errorMask[c_nrDHE_ID_INVALID] = true;
1110  }
1111  // calculate the VXDID for DHE and save them for DHP unpacking
1112  {
1119  unsigned short sensor, ladder, layer;
1120  sensor = (currentDHEID & 0x1) + 1;
1121  ladder = (currentDHEID & 0x1E) >> 1; // no +1
1122  layer = ((currentDHEID & 0x20) >> 5) + 1;
1123  currentVxdId = VxdID(layer, ladder, sensor);
1124  if (ladder == 0 || (layer == 1 && ladder > 8) || (layer == 2 && ladder > 12)) {
1125  if (!(m_suppressErrorMask[c_nrDHE_ID_INVALID])) {
1126  B2WARNING("DHE ID is invalid");
1127  B2DEBUG(29, "DHE ID is invalid" <<
1128  LogVar("DHE ID", currentDHEID) <<
1129  LogVar("Layer", layer) <<
1130  LogVar("Ladder", ladder) <<
1131  LogVar("Sensor", sensor));
1132  }
1133  m_errorMask[c_nrDHE_ID_INVALID] = true;
1134  }
1135  }
1136 
1137  m_errorMaskDHE = m_errorMask; // forget about anything before this frame
1138  if (daqpktstat.dhc_size() > 0) {
1139  // if no DHC has been defined yet, do nothing!
1140  daqpktstat.dhc_back().newDHE(currentVxdId, currentDHEID, m_errorMask, dhe_first_triggergate, dhe_first_readout_frame_id_lo);
1141  }
1142  break;
1143  };
1144  case EDHCFrameHeaderDataType::c_GHOST:
1145  if (m_verbose) dhc.data_ghost_frame->print();
1146  if (currentDHEID != dhc.data_ghost_frame->getDHEId()) {
1147  if (!(m_suppressErrorMask[c_nrDHE_START_ID])) {
1148  B2WARNING("DHE ID from DHE Start and this frame do not match");
1149  B2DEBUG(29, "Start ID $" << hex << currentDHEID << " != $" << dhc.data_ghost_frame->getDHEId());
1150  }
1151  m_errorMask[c_nrDHE_START_ID] = true;
1152  }
1154  if ((found_mask_active_dhp & (1 << dhc.data_ghost_frame->getDHPPort())) != 0) {
1155  B2ERROR("Second DHP data packet (GHOST) for " << LogVar("DHE", currentDHEID) << LogVar("DHP", dhc.data_ghost_frame->getDHPPort()));
1156  }
1157  found_mask_active_dhp |= 1 << dhc.data_ghost_frame->getDHPPort();
1158 
1159  dhc.check_crc(m_errorMask, m_suppressErrorMask[c_nrDHE_CRC]);
1160 
1161  break;
1162  case EDHCFrameHeaderDataType::c_DHC_END: {
1163  if (dhc.data_dhc_end_frame->isFakedData() != isFakedData_event) {
1164  if (!(m_suppressErrorMask[c_nrFAKE_NO_FAKE_DATA])) B2WARNING("DHC END mixed Fake/no Fake event.");
1165  m_errorMask[c_nrFAKE_NO_FAKE_DATA] = true;
1166  }
1167  if (dhc.data_dhc_end_frame->isFakedData()) {
1168  if (!(m_suppressErrorMask[c_nrFAKE_NO_DATA_TRIG])) B2WARNING("Faked DHC END Data -> trigger without Data!");
1169  m_errorMask[c_nrFAKE_NO_DATA_TRIG] = true;
1170  } else {
1171  if (m_verbose) dhc.data_dhc_end_frame->print();
1172  }
1173 
1174  if (!isFakedData_event) {
1175  if (dhc.data_dhc_end_frame->get_dhc_id() != currentDHCID) {
1176  if (!(m_suppressErrorMask[c_nrDHC_DHCID_START_END_MM])) {
1177  B2WARNING("DHC ID Mismatch between Start and End");
1178  B2DEBUG(29, "DHC ID Mismatch between Start and End $" << std::hex <<
1179  currentDHCID << "!=$" << dhc.data_dhc_end_frame->get_dhc_id());
1180  }
1181  m_errorMask[c_nrDHC_DHCID_START_END_MM] = true;
1182  }
1183  int w;
1184  w = dhc.data_dhc_end_frame->get_words() * 4;
1185  if (cancheck_countedBytesInDHC) {
1186  if (countedBytesInDHC != w) {
1187  if (!(m_suppressErrorMask[c_nrDHC_WIE])) {
1188  B2WARNING("Number of Words in DHC END does not match");
1189  B2DEBUG(29, "Number of Words in DHC END does not match: WIE $" << hex << countedBytesInDHC << " != DHC END $" << hex << w);
1190  }
1191  m_errorMask[c_nrDHC_WIE] = true;
1192  } else {
1193  if (m_verbose)
1194  B2DEBUG(29, "EVT END: WIE $" << hex << countedBytesInDHC << " == DHC END $" << hex << w);
1195  }
1196  // else ... processed data -> length invalid
1197  }
1198  }
1200  if (dhc.data_dhc_end_frame->getErrorInfo() != 0) {
1201  if (!(m_suppressErrorMask[c_nrDHH_END_ERRORBITS])) B2ERROR("DHC END Error Info set to $" << hex <<
1203  m_errorMask[c_nrDHH_END_ERRORBITS] = true;
1204  }
1205  dhc.check_crc(m_errorMask, m_suppressErrorMask[c_nrDHE_CRC]);
1206  m_errorMaskDHC |= m_errorMask; // do latest updates
1207 
1208  if (daqpktstat.dhc_size() > 0) {
1209  // only is we have a DHC object... or back() is undefined
1210  // Remark, if we have a broken data (DHC_START/END) structure, we might fill the
1211  // previous DHC object ... but then the data is junk anyway
1212  daqpktstat.dhc_back().setErrorMask(m_errorMaskDHC);
1213  //B2DEBUG(98,"** DHC "<<currentDHCID<<" Raw"<<dhc.data_dhc_end_frame->get_words() * 4 <<" Red"<<countedBytesInDHC);
1214  daqpktstat.dhc_back().setCounters(dhc.data_dhc_end_frame->get_words() * 4, countedBytesInDHC);
1216  }
1217  m_errorMaskDHC = 0;
1218  currentDHEID = 0xFFFFFFFF;
1219  currentDHCID = 0xFFFFFFFF;
1220  currentVxdId = 0;
1221  break;
1222  };
1223  case EDHCFrameHeaderDataType::c_DHE_END: {
1224  if (m_verbose) dhc.data_dhe_end_frame->print();
1225  if (currentDHEID != dhc.data_dhe_end_frame->getDHEId()) {
1226  if (!(m_suppressErrorMask[c_nrDHE_START_END_ID])) {
1227  B2WARNING("DHE ID from DHE Start and this frame do not match");
1228  B2DEBUG(29, "DHE ID from DHE Start and this frame do not match $" << hex << currentDHEID << " != $" <<
1229  dhc.data_dhe_end_frame->getDHEId());
1230  }
1231  m_errorMask[c_nrDHE_START_END_ID] = true;
1232  }
1234  if (dhc.data_dhe_end_frame->getErrorInfo() != 0) {
1235  if (!(m_suppressErrorMask[c_nrDHH_END_ERRORBITS])) {
1236  B2ERROR("DHE END Error Info set to $" << hex << dhc.data_dhe_end_frame->getErrorInfo());
1237  }
1238  m_errorMask[c_nrDHH_END_ERRORBITS] = true;
1239  }
1240  dhc.check_crc(m_errorMask, m_suppressErrorMask[c_nrDHE_CRC]);
1241  if (found_mask_active_dhp != mask_active_dhp) {
1242  if (!(m_suppressErrorMask[c_nrDHP_ACTIVE])) {
1243  B2WARNING("DHE_END: DHP active mask differs from found data");
1244  B2DEBUG(29, "DHE_END: DHP active mask differs from found data $" << hex << mask_active_dhp << " != $" << hex <<
1245  found_mask_active_dhp
1246  << " mask of found dhp/ghost frames");
1247  }
1248  m_errorMask[c_nrDHP_ACTIVE] = true;
1249  }
1250  countedDHEEndFrames++;
1251  if (countedDHEStartFrames < countedDHEEndFrames) {
1252  // the other case is checked in Start
1253  if (!(m_suppressErrorMask[c_nrDHE_END_WO_START])) B2WARNING("DHE_END without DHE_START");
1254  m_errorMask[c_nrDHE_END_WO_START] = true;
1255  }
1256  {
1257  int w;
1258  w = dhc.data_dhe_end_frame->get_words() * 2;
1259  if (cancheck_countedBytesInDHE) {
1260  if (countedBytesInDHE != w) {
1261  if (!(m_suppressErrorMask[c_nrDHE_WIE])) {
1262  B2WARNING("Number of Words in DHE END does not match");
1263  B2DEBUG(29, "Number of Words in DHE END does not match: WIE $" << hex << countedBytesInDHE << " != DHE END $" << hex << w);
1264  }
1265  m_errorMask[c_nrDHE_WIE] = true;
1266  } else {
1267  if (m_verbose)
1268  B2DEBUG(29, "EVT END: WIE $" << hex << countedBytesInDHE << " == DHE END $" << hex << w);
1269  }
1270  // else ... processed data -> length invalid
1271  }
1272  }
1273  m_errorMaskDHE |= m_errorMask; // do latest updates
1274 
1275  if (daqpktstat.dhc_size() > 0) {
1276  if (daqpktstat.dhc_back().dhe_size() > 0) {
1277  // only is we have a DHC and DHE object... or back() is undefined
1278  // Remark, if we have a broken data (DHE_START/END) structure, we might fill the
1279  // previous DHE object ... but then the data is junk anyway
1280  daqpktstat.dhc_back().dhe_back().setErrorMask(m_errorMaskDHE);
1281  // B2DEBUG(98,"** DHC "<<currentDHEID<<" Raw "<<dhc.data_dhe_end_frame->get_words() * 2 <<" Red"<<countedBytesInDHE);
1282  daqpktstat.dhc_back().dhe_back().setCounters(dhc.data_dhe_end_frame->get_words() * 2, countedBytesInDHE);
1283  daqpktstat.dhc_back().dhe_back().setDHPFoundMask(found_good_mask_active_dhp);
1285  }
1286  }
1287  m_errorMaskDHE = 0;
1288  currentDHEID |= 0xFF000000;// differenciate from 0xFFFFFFFFF as initial value
1289  currentVxdId = 0;
1290  break;
1291  };
1292  case EDHCFrameHeaderDataType::c_ONSEN_ROI:
1293  if (m_verbose) dhc.data_onsen_roi_frame->print();
1294  dhc.data_onsen_roi_frame->check_error(m_errorMask, len, m_suppressErrorMask[c_nrROI_PACKET_INV_SIZE]);
1296  dhc.check_crc(m_errorMask, m_suppressErrorMask[c_nrDHE_CRC]);
1297  if (!m_doNotStore) {
1298  //dhc.data_onsen_roi_frame->save(m_storeROIs, len, (unsigned int*) data);
1299  // void save(StoreArray<PXDRawROIs>& sa, unsigned int length, unsigned int* data) const
1300  // 4 byte header, ROIS (n*8), 4 byte copy of inner CRC, 4 byte outer CRC
1301  if (len >= dhc.data_onsen_roi_frame->getMinSize()) {
1302  //if ((len - dhc.data_onsen_roi_frame->getMinSize()) % 8 != 0) {
1303  // error checking in check_error() above, this is only for dump-ing
1304  // dump_roi(data, len - 4); // dump ROI payload, minus CRC
1305  //}
1306  unsigned int l;
1307  l = (len - dhc.data_onsen_roi_frame->getMinSize()) / 8;
1308  // Endian swapping is done in Contructor of RawRoi object
1309  m_storeROIs.appendNew(l, &((unsigned int*) data)[1]);
1310  }
1311  }
1312  break;
1313  case EDHCFrameHeaderDataType::c_ONSEN_TRG:
1314  eventNrOfOnsenTrgFrame = eventNrOfThisFrame;
1315  if (dhc.data_onsen_trigger_frame->get_trig_nr1() != (unsigned int)(m_meta_event_nr & 0xFFFFFFFF)) {
1316  if (!(m_suppressErrorMask[c_nrMETA_MM_ONS_HLT])) {
1317  B2WARNING("Trigger Frame HLT Trigger Nr mismatch");
1318  B2DEBUG(29, "Trigger Frame HLT Trigger Nr mismatch: HLT $" <<
1319  dhc.data_onsen_trigger_frame->get_trig_nr1() << " META " << (m_meta_event_nr & 0xFFFFFFFF));
1320  }
1321  m_errorMask[c_nrMETA_MM_ONS_HLT] = true;
1322  }
1326  if (!(m_suppressErrorMask[c_nrMETA_MM_ONS_HLT])) {
1327  B2WARNING("Trigger Frame HLT Exp/Run/Subrun Nr mismatch");
1328  B2DEBUG(29, "Trigger Frame HLT Exp/Run/Subrun Nr mismatch: Exp HLT $" <<
1330  " Run HLT $" << dhc.data_onsen_trigger_frame->get_run1() << " META " << m_meta_run_nr <<
1331  " Subrun HLT $" << dhc.data_onsen_trigger_frame->get_subrun1() << " META " << m_meta_subrun_nr);
1332  }
1333  m_errorMask[c_nrMETA_MM_ONS_HLT] = true;
1334  }
1335 
1337  if (dhc.data_onsen_trigger_frame->get_trig_nr2() != (unsigned int)(m_meta_event_nr & 0xFFFFFFFF)) {
1338  if (!(m_suppressErrorMask[c_nrMETA_MM_ONS_DC])) {
1339  B2WARNING("Trigger Frame DATCON Trigger Nr mismatch");
1340  B2DEBUG(29, "Trigger Frame DATCON Trigger Nr mismatch: DC $" <<
1341  dhc.data_onsen_trigger_frame->get_trig_nr2() << " META " << (m_meta_event_nr & 0xFFFFFFFF));
1342  }
1343  m_errorMask[c_nrMETA_MM_ONS_DC] = true;
1344  }
1348  if (!(m_suppressErrorMask[c_nrMETA_MM_ONS_DC])) {
1349  B2WARNING("Trigger Frame DATCON Exp/Run/Subrun Nr mismatch");
1350  B2DEBUG(29, "Trigger Frame DATCON Exp/Run/Subrun Nr mismatch: Exp DC $" <<
1352  " Run DC $" << dhc.data_onsen_trigger_frame->get_run2() << " META " << m_meta_run_nr <<
1353  " Subrun DC $" << dhc.data_onsen_trigger_frame->get_subrun2() << " META " << m_meta_subrun_nr);
1354  }
1355  m_errorMask[c_nrMETA_MM_ONS_DC] = true;
1356  }
1357  }
1358 
1359 // B2WARNING("TRG TAG HLT: $" << hex << dhc.data_onsen_trigger_frame->get_trig_tag1() << " DATCON $" << dhc.data_onsen_trigger_frame->get_trig_tag2() << " META " << m_meta_time);
1360 
1363  m_suppressErrorMask[c_nrMERGER_TRIGNR]);
1364  dhc.check_crc(m_errorMask, m_suppressErrorMask[c_nrDHE_CRC]);
1365  if (Frame_Number != 0) {
1366  if (!(m_suppressErrorMask[c_nrEVENT_STRUCT])) B2WARNING("ONSEN TRG Frame must be the first one.");
1367  m_errorMask[c_nrEVENT_STRUCT] = true;
1368  }
1369  isUnfiltered_event = dhc.data_onsen_trigger_frame->is_SendUnfiltered();
1370  if (isUnfiltered_event) m_sendunfiltered++;
1373  break;
1374  default:
1375  if (!(m_suppressErrorMask[c_nrDHC_UNKNOWN])) B2WARNING("UNKNOWN DHC frame type");
1376  m_errorMask[c_nrDHC_UNKNOWN] = true;
1377  if (m_verbose) hw->print();
1378  break;
1379  }
1380 
1381  if (eventNrOfThisFrame != eventNrOfOnsenTrgFrame && !isFakedData_event) {
1382  if (!(m_suppressErrorMask[c_nrFRAME_TNR_MM])) {
1383  B2WARNING("Frame TrigNr != ONSEN Trig Nr");
1384  B2DEBUG(29, "Frame TrigNr != ONSEN Trig Nr $" << hex << eventNrOfThisFrame << " != $" << eventNrOfOnsenTrgFrame);
1385  }
1386  m_errorMask[c_nrFRAME_TNR_MM] = true;
1387  }
1388 
1389  if (Frame_Number == 0) {
1391  if (frame_type != EDHCFrameHeaderDataType::c_ONSEN_TRG) {
1392  if (!m_formatBonnDAQ) {
1393  if (!(m_suppressErrorMask[c_nrONSEN_TRG_FIRST])) B2WARNING("First frame is not a ONSEN Trigger frame");
1394  m_errorMask[c_nrONSEN_TRG_FIRST] = true;
1395  }
1396  }
1397  } else { // (Frame_Number != 0 &&
1399  if (frame_type == EDHCFrameHeaderDataType::c_ONSEN_TRG) {
1400  if (!(m_suppressErrorMask[c_nrONSEN_TRG_FIRST])) B2WARNING("More than one ONSEN Trigger frame");
1401  m_errorMask[c_nrONSEN_TRG_FIRST] = true;
1402  }
1403  }
1404 
1405  if (!m_formatBonnDAQ) {
1406  if (Frame_Number == 1) {
1408  if (frame_type != EDHCFrameHeaderDataType::c_DHC_START) {
1409  if (!(m_suppressErrorMask[c_nrDHC_START_SECOND])) B2WARNING("Second frame is not a DHC start of subevent frame");
1410  m_errorMask[c_nrDHC_START_SECOND] = true;
1411  }
1412  } else { // (Frame_Number != 0 &&
1414  if (frame_type == EDHCFrameHeaderDataType::c_DHC_START) {
1415  if (!(m_suppressErrorMask[c_nrDHC_START_SECOND])) B2WARNING("More than one DHC start of subevent frame");
1416  m_errorMask[c_nrDHC_START_SECOND] = true;
1417  }
1418  }
1419  }
1420 
1421  if (Frame_Number == Frames_in_event - 1) {
1423  if (frame_type != EDHCFrameHeaderDataType::c_DHC_END) {
1424  if (!(m_suppressErrorMask[c_nrDHC_END_MISS])) B2WARNING("Last frame is not a DHC end of subevent frame");
1425  m_errorMask[c_nrDHC_END_MISS] = true;
1426  }
1427 
1429  if (countedDHEStartFrames != countedDHEEndFrames || countedDHEStartFrames != nr_active_dhe) {
1430  if (!(m_suppressErrorMask[c_nrDHE_ACTIVE]) || !(m_suppressErrorMask[c_nrDHE_START_WO_END])
1431  || !(m_suppressErrorMask[c_nrDHE_END_WO_START])) {
1432  B2WARNING("The number of DHE Start/End does not match the number of active DHE in DHC Header!");
1433  B2DEBUG(29, "The number of DHE Start/End does not match the number of active DHE in DHC Header! Header: " << nr_active_dhe <<
1434  " Start: " << countedDHEStartFrames << " End: " << countedDHEEndFrames << " Mask: $" << hex << mask_active_dhe << " in Event Nr " <<
1435  eventNrOfThisFrame);
1436  }
1437  if (countedDHEStartFrames == countedDHEEndFrames) m_errorMask[c_nrDHE_ACTIVE] = true;
1438  if (countedDHEStartFrames > countedDHEEndFrames) m_errorMask[c_nrDHE_START_WO_END] = true;
1439  if (countedDHEStartFrames < countedDHEEndFrames) m_errorMask[c_nrDHE_END_WO_START] = true;
1440  }
1441 
1442  } else { // (Frame_Number != Frames_in_event - 1 &&
1444  if (frame_type == EDHCFrameHeaderDataType::c_DHC_END) {
1445  if (!(m_suppressErrorMask[c_nrDHC_END_DBL])) B2WARNING("More than one DHC end of subevent frame");
1446  m_errorMask[c_nrDHC_END_DBL] = true;
1447  }
1448  }
1449 
1450  if (!m_formatBonnDAQ) {
1452  if (Frame_Number == 2 && nr_active_dhe != 0 && frame_type != EDHCFrameHeaderDataType::c_DHE_START) {
1453  if (!(m_suppressErrorMask[c_nrDHE_START_THIRD])) B2WARNING("Third frame is not a DHE start frame");
1454  m_errorMask[c_nrDHE_START_THIRD] = true;
1455  }
1456  }
1457 
1458  if (frame_type != EDHCFrameHeaderDataType::c_ONSEN_ROI && frame_type != EDHCFrameHeaderDataType::c_ONSEN_TRG) {
1459  // actually, they should not be withing Start and End, but better be sure.
1460  countedBytesInDHC += len;
1461  countedBytesInDHE += len;
1462  }
1463  B2DEBUG(29, "DHC/DHE $" << hex << countedBytesInDHC << ", $" << hex << countedBytesInDHE);
1464 }
1465 
1467 {
1469  const int lut[32] = {
1470  0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
1471  1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5
1472  };
1473  return lut[i & 0x1F];
1474 }
1475 
Base class for Modules.
Definition: Module.h:72
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
Definition: Module.cc:208
void setReturnValue(int value)
Sets the return value for this module as integer.
Definition: Module.cc:220
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
Definition: Module.h:80
void setErrorMask(const PXDErrorFlags &mask)
Set Error bit mask This should be the OR of error masks of all sub-objects (DHC, DHE)
PXDDAQDHEStatus & dhe_back()
Returns PXDDAQDHEStatus for last DHE.
void setGatedFlag(bool gm)
set gating info from the DHC END
PXDDAQDHEStatus & newDHE(Args &&... params)
Add new DHE information.
void setGatedHER(bool isher)
set HER/LER gating info from the DHC END
void setEndErrorInfo(uint32_t e)
set errorinfo from the DHC END
size_t dhe_size() const
Returns number of DHEs.
void setCounters(uint32_t raw, uint32_t red)
Set Data counters for reduction calculation.
void setDHPFoundMask(unsigned short dhpmask)
set Mask for found DHPs with valid data
void setErrorMask(const PXDErrorFlags &mask)
Set Error bit mask.
PXDDAQDHPStatus & dhp_back()
Returns PXDDAQDHPStatus for the last DHP.
auto addCM(PXDDAQDHPComMode &daqcm)
Add Common Mode information.
void setEndErrorInfo(uint32_t e)
set erroinfo from the DHE END
PXDDAQDHPStatus & newDHP(Args &&... params)
New DHP information.
void setCounters(uint32_t raw, uint32_t red)
Set Data counters for reduction calculation.
void setTruncated(void)
set Truncation
The PXD DAQ Packet Status class.
void setErrorMask(const PXDErrorFlags &mask)
Set Error bit mask This should be the OR of error masks of all sub-objects (DHC, DHE)
PXDDAQDHCStatus & newDHC(Args &&... params)
Add new DHC information.
size_t dhc_size() const
Returns number of DHCs.
PXDDAQDHCStatus & dhc_back()
Returns PXDDAQDHCStatus for last DHC.
static void map_rc_to_uv_IF_OB(unsigned int &row_u, unsigned int &col_v, const unsigned int dhp_id, const unsigned int dhe_ID)
Maps row/col of inner forward (IF) and outer backward (OB) modules of the PXD to U/V cell.
static void map_rc_to_uv_IB_OF(unsigned int &row_u, unsigned int &col_v, const unsigned int dhp_id, const unsigned int dhe_ID)
Maps row/cols of inner backward (IB) and outer forward (OF) modules of the PXD to U/V cell.
std::string m_PXDRawHitsName
The name of the StoreArray of PXDRawHits to be generated.
void initialize() override final
Initialize the module.
unsigned long m_meta_experiment
Experiment from MetaInfo.
PXDError::PXDErrorFlags m_errorMaskEvent
Error Mask set per packet / event.
StoreObjPtr< PXDDAQStatus > m_storeDAQEvtStats
Output array for DAQ Status.
bool m_doNotStore
Only unpack, but Do Not Store anything to file.
StoreArray< RawPXD > m_storeRawPXD
Input array for PXD Raw.
bool m_forceNoMapping
Force No Mapping even if DHH bit is requesting it.
std::string m_PXDDAQEvtStatsName
The name of the StoreObjPtr of PXDDAQStatus to be generated.
static void dump_roi(void *data, unsigned int frame_len)
dump to a file, helper function for debugging.
PXDError::PXDErrorFlags m_suppressErrorMask
Mask for suppressing selected error messages.
bool m_formatBonnDAQ
flag ONSEN or BonnDAQ format
unsigned int m_errorCounter[PXDError::ONSEN_MAX_TYPE_ERR]
Error counters.
StoreArray< PXDRawROIs > m_storeROIs
Output array for Raw ROIs.
unsigned int m_sendunfiltered
counter for send unfiltered
PXDError::PXDErrorFlags m_errorMaskDHC
Error Mask set per packet / DHC.
PXDError::PXDErrorFlags m_errorMaskPacket
Error Mask set per packet / packet.
std::string m_RawPXDsName
The name of the StoreArray of processed RawPXDs.
void unpack_dhp(void *data, unsigned int len, unsigned int dhe_first_readout_frame_lo, unsigned int dhe_ID, unsigned dhe_DHPport, unsigned dhe_reformat, VxdID vxd_id, PXDDAQPacketStatus &daqpktstat)
Unpack DHP data within one DHE frame.
void terminate() override final
Terminate the module.
StoreObjPtr< EventMetaData > m_eventMetaData
Input ptr for EventMetaData.
int m_last_dhp_readout_frame_lo[4]
some workaround check for continouous frame ids
unsigned long m_meta_subrun_nr
Subrun Number from MetaInfo.
void event() override final
do the unpacking
StoreArray< PXDRawAdc > m_storeRawAdc
Output array for Raw Adcs.
unsigned long m_meta_event_nr
Event Number from MetaInfo.
PXDError::PXDErrorFlags m_errorSkipPacketMask
Mask for error which stop package unpacking directly.
static int nr5bits(int i)
helper function to "count" nr of set bits within lower 5 bits.
void unpack_fce(unsigned short *data, unsigned int length, VxdID vxd_id)
Unpack DHP/FCE data within one DHE frame Not fully implemented as cluster format not 100% fixed.
std::string m_PXDRawAdcsName
The name of the StoreArray of PXDRawAdcs to be generated.
unsigned long m_meta_run_nr
Run Number from MetaInfo.
bool m_continueOnError
flag continue unpacking of frames even after error (for debugging)
unsigned int m_notaccepted
counter for not accepted events...
unsigned int m_meta_sec
Time(Tag) from MetaInfo, seconds (masked to lower bits)
void unpack_dhp_raw(void *data, unsigned int len, unsigned int dhe_ID, unsigned dhe_DHPport, VxdID vxd_id)
Unpack DHP RAW data within one DHE frame (pedestals, etc)
PXDError::PXDErrorFlags m_criticalErrorMask
Critical error mask which defines return value of task.
unsigned int m_sendrois
counter for send debug rois
static void dump_dhp(void *data, unsigned int frame_len)
dump to a file, helper function for debugging.
void unpack_rawpxd(RawPXD &px, int inx)
Unpack one event (several frames) stored in RawPXD object.
unsigned long long int m_meta_time
Time(Tag) from MetaInfo.
unsigned int m_maxDHPFrameDiff
Maximum DHP frame difference until error is reported.
PXDError::PXDErrorFlags m_errorMask
Error Mask set per packet / frame.
unsigned int m_unpackedEventsCount
Event counter.
StoreArray< PXDRawHit > m_storeRawHits
Output array for Raw Hits.
void unpack_dhc_frame(void *data, const int len, const int Frame_Number, const int Frames_in_event, PXDDAQPacketStatus &daqpktstat)
Unpack one frame (within an event).
bool m_forceMapping
Force Mapping even if DHH bit is not requesting it.
unsigned int m_meta_ticks
Time(Tag) from MetaInfo, Ticks of 127MHz.
bool m_verbose
give verbose unpacking information
PXDError::PXDErrorFlags m_errorMaskDHE
Error Mask set per packet / DHE.
std::string m_PXDRawROIsName
The name of the StoreArray of PXDRawROIs to be generated.
DHC frame wrapper class.
const dhc_ghost_frame * data_ghost_frame
data_ghost_frame
unsigned int getEventNrLo(void) const
get event nr lo (from data)
const dhc_end_frame * data_dhc_end_frame
data_dhc_end_frame
unsigned int getFixedSize(void)
get fixed size
int getFrameType(void)
get type of frame
const dhc_dhe_start_frame * data_dhe_start_frame
data_dhe_start_frame
void set(const void *d, unsigned int t)
set data and type (and length to 0)
const dhc_start_frame * data_dhc_start_frame
data_dhc_start_frame
const dhc_direct_readout_frame * data_direct_readout_frame
data_direct_readout_frame
const dhc_dhe_end_frame * data_dhe_end_frame
data_dhe_end_frame
void check_padding(PXDErrorFlags &errormask)
check padding and return it
const dhc_onsen_roi_frame * data_onsen_roi_frame
data_onsen_roi_frame
const dhc_direct_readout_frame_raw * data_direct_readout_frame_raw
data_direct_readout_frame_raw
const dhc_commode_frame * data_commode_frame
data_commode_frame
void check_crc(PXDErrorFlags &errormask, bool ignore_crc_flag=false)
check crc and return it
const dhc_onsen_trigger_frame * data_onsen_trigger_frame
data_onsen_trigger_frame
The Raw PXD class.
Definition: RawPXD.h:27
virtual int * data(void)
get pointer to data
Definition: RawPXD.cc:81
virtual int size() const
get size of buffer in 32 Bit words
Definition: RawPXD.cc:76
Class to uniquely identify a any structure of the PXD and SVD.
Definition: VxdID.h:33
Class to store variables with their name which were sent to the logging service.
void addParam(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition: Module.h:560
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition: Module.h:650
std::tuple< uint8_t, uint16_t, uint8_t > PXDDAQDHPComMode
tuple of Chip ID (2 bit), Row (10 bit), Common Mode (6 bit)
Namespace to encapsulate code needed for simulation and reconstrucion of the PXD.
boost::endian::big_uint32_t ubig32_t
define alias ubig32_t
boost::endian::big_uint16_t ubig16_t
define alias ubig16_t
Abstract base class for different kinds of events.
unsigned int getDHEId(void) const
get DHE Id (from word0)
unsigned int get_words(void) const
get words
unsigned int getDHEId(void) const
get DHE Id
unsigned int getErrorInfo(void) const
get error info
unsigned int getDHEId(void) const
get DHE Id (from word0)
unsigned short getEventNrLo(void) const
get trigger_nr_lo
unsigned short getTriggerGate(void) const
trigger gate (updated to 8 bit, before 10!)
unsigned short getStartFrameNr(void) const
last DHP frame before trigger
unsigned short getEventNrHi(void) const
get trigger_nr_hi
unsigned int getActiveDHPMask(void) const
get Active DHP Mask (from word0)
bool getDataReformattedFlag(void) const
get DataReformattedFlag (from word0)
unsigned short getDHEId(void) const
get DHE Id (from word0)
unsigned short getDHPPort(void) const
get DHP Port (from word0)
void print(void) const
print
unsigned int get_words(void) const
get words
bool isFakedData(void) const
is faked data
unsigned int get_dhc_id(void) const
get dhc id (from word0)
unsigned int getErrorInfo(void) const
get error info
DHC frame header word data struct.
unsigned short getFrameType(void) const
get type of frame
unsigned short getErrorFlag(void) const
get error flag
unsigned short getDHEId(void) const
get DHE Id (from word0)
unsigned short getDHPPort(void) const
get DDHP port (from word0)
unsigned int check_inner_crc(PXDErrorFlags &, unsigned int) const
check inner crc (currently not implemented/needed)
void check_error(PXDErrorFlags &errormask, int length, bool ignore_inv_size_flag=false) const
check error and return error mask
int getMinSize(void) const
4 byte header, ROIS (n*8), 4 byte copy of inner CRC, 4 byte outer CRC
unsigned short get_subrun1(void) const
get subrun1 (from trigtag1)
unsigned int get_trig_nr1(void) const
get trignr1
bool is_SendUnfiltered(void) const
is sendUnfiltered
bool is_SendROIs(void) const
is sendROIs
void check_error(PXDErrorFlags &errormask, bool ignore_datcon_flag=false, bool ignore_hltroi_magic_flag=false, bool ignore_merger_mm_flag=false) const
check error and return error mask
unsigned short get_run2(void) const
get run2 (from trigtag2)
bool is_fake_datcon(void) const
is fake datcon
unsigned short get_experiment1(void) const
get experiment1 (from trigtag1)
unsigned int get_trig_nr2(void) const
get trignr2
unsigned short get_experiment2(void) const
get experiment2
unsigned short get_subrun2(void) const
get subrun2 (from trigtag2)
bool is_Accepted(void) const
is accepted
unsigned short get_run1(void) const
get run1 (from trigtag1)
void print(void) const
print
unsigned short get_gated_isher(void) const
get gated_isher (from word0)
unsigned short get_subrun(void) const
get subrun (from run_subrun)
unsigned short get_run(void) const
get run (from run_subrun)
unsigned short get_dhc_id(void) const
get dhc_id (from word0)
const ubig16_t time_tag_hi
time_tag_hi
const ubig16_t time_tag_mid
time_tag_mid
bool isFakedData(void) const
isFakedData
unsigned short getEventNrLo(void) const
get trigger_nr_lo
unsigned short get_experiment(void) const
get experiment (from exp_run)
unsigned short get_gated_flag(void) const
get gated_flag (from word0)
unsigned short get_active_dhe_mask(void) const
get active_dhe_mask (from word0)
const ubig16_t time_tag_lo_and_type
time_tag_lo_and_type
unsigned short getEventNrHi(void) const
get trigger_nr_hi