Belle II Software  release-08-01-10
PXDUnpackerModule.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/PXDUnpackerModule.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(PXDUnpacker);
28 
29 //-----------------------------------------------------------------
30 // Implementation
31 //-----------------------------------------------------------------
32 
36 
37 PXDUnpackerModule::PXDUnpackerModule() :
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  // MaxDHPFrameDiff is only useful for old firmware
63  addParam("MaxDHPFrameDiff", m_maxDHPFrameDiff, "Maximum DHP Frame Nr Difference w/o reporting error", 2u);
64  addParam("FormatBonnDAQ", m_formatBonnDAQ, "ONSEN or BonnDAQ format", false);
65  addParam("Verbose", m_verbose, "Turn on extra verbosity for log-level debug", false);
66  addParam("ContinueOnError", m_continueOnError, "Continue package depacking on error (for debugging)", false);
67  addParam("overrideFirmwareVersion", m_overrideFirmwareVersion, "Overwrite Firmware Version from DB with this value", 0);
68 // (
69 // /*EPXDErrFlag::c_DHC_END | EPXDErrFlag::c_DHE_START | EPXDErrFlag::c_DATA_OUTSIDE |*/
70 // EPXDErrFlag::c_FIX_SIZE | EPXDErrFlag::c_DHE_CRC | EPXDErrFlag::c_DHC_UNKNOWN | /*EPXDErrFlag::c_MERGER_CRC |*/
71 // EPXDErrFlag::c_DHP_SIZE | /*EPXDErrFlag::c_DHP_PIX_WO_ROW | EPXDErrFlag::c_DHE_START_END_ID | EPXDErrFlag::c_DHE_START_ID |*/
72 // EPXDErrFlag::c_DHE_START_WO_END | EPXDErrFlag::c_DHP_NOT_CONT
73 // ));
74 
75  // this is not really a parameter, it should be fixed.
76  m_errorSkipPacketMask[c_nrDHE_CRC] = true;
77  m_errorSkipPacketMask[c_nrFIX_SIZE] = true;
78 }
79 
81 {
82  // Required input
83  m_eventMetaData.isRequired();
84  // Optional input
85  m_storeRawPXD.isOptional(m_RawPXDsName);
86 
87  //Register output collections
88  m_storeRawHits.registerInDataStore(m_PXDRawHitsName, DataStore::EStoreFlags::c_ErrorIfAlreadyRegistered);
89  m_storeRawAdc.registerInDataStore(m_PXDRawAdcsName, DataStore::EStoreFlags::c_ErrorIfAlreadyRegistered);
90  m_storeROIs.registerInDataStore(m_PXDRawROIsName, DataStore::EStoreFlags::c_ErrorIfAlreadyRegistered);
91  m_storeDAQEvtStats.registerInDataStore(m_PXDDAQEvtStatsName, DataStore::EStoreFlags::c_ErrorIfAlreadyRegistered);
93 
94  B2DEBUG(29, "ForceMapping: " << m_forceMapping);
95  B2DEBUG(29, "ForceNoMapping: " << m_forceNoMapping);
96  B2DEBUG(29, "CheckPaddingCRC: " << m_checkPaddingCRC);
97  B2DEBUG(29, "MaxDHPFrameDiff: " << m_maxDHPFrameDiff);
98 
99  m_sendunfiltered = 0;
100  m_sendrois = 0;
101  m_notaccepted = 0;
103  for (int i = 0; i < ONSEN_MAX_TYPE_ERR; i++) m_errorCounter[i] = 0;
104 
105 }
106 
108 {
109  if (m_overrideFirmwareVersion == 0) {
110  if (m_firmwareFromDB.isValid()) m_firmware = (*m_firmwareFromDB).getDHHFirmwareVersion();
111  else B2FATAL("Cannot get PXD Firmware version from db");
112  } else {
114  }
115 }
116 
118 {
119  int flag = 0;
120  string errstr = "Statistic ( ;";
121  errstr += to_string(m_unpackedEventsCount) + ";";
122  for (int i = 0; i < ONSEN_MAX_TYPE_ERR; i++) { errstr += to_string(m_errorCounter[i]) + ";"; flag |= m_errorCounter[i];}
123  if (flag != 0) {
124  B2RESULT("PXD Unpacker --> Error Statistics (counted once per event!) in Events: " << m_unpackedEventsCount);
125  B2RESULT(errstr + " )");
126  for (int i = 0; i < ONSEN_MAX_TYPE_ERR; i++) {
127  if (m_errorCounter[i]) {
128  B2RESULT(getPXDBitErrorName(i) << ": " << m_errorCounter[i]);
129  }
130  }
131  } else {
132  B2RESULT("PXD Unpacker --> No Error found in Events: " << m_unpackedEventsCount);
133  }
134  B2RESULT("Statistic 2: !Accepted: " << m_notaccepted << " SendROIs: " << m_sendrois << " Unfiltered: " << m_sendunfiltered);
135 }
136 
138 {
139  m_storeDAQEvtStats.create();
140 
141  m_errorMask = 0;
142  m_errorMaskEvent = 0;
143 
144  m_meta_event_nr = m_eventMetaData->getEvent();// used for error output below
145 
146  if (!m_storeRawPXD) {// if no input, nothing to do
147  m_errorMask[c_nrNO_PXD] = true;
148  } else {
149  int nRaws = m_storeRawPXD.getEntries();
150  if (m_verbose) {
151  B2DEBUG(29, "PXD Unpacker --> RawPXD Objects in event: " << LogVar("Objects", nRaws));
152  };
153 
154  m_meta_run_nr = m_eventMetaData->getRun();
155  m_meta_subrun_nr = m_eventMetaData->getSubrun();
156  m_meta_experiment = m_eventMetaData->getExperiment();
157  m_meta_time = m_eventMetaData->getTime();
158  m_meta_ticks = (unsigned int)std::round((m_meta_time % 1000000000ull) * 0.127216); // calculate ticks in 127MHz RF clock
159  m_meta_sec = (unsigned int)(m_meta_time / 1000000000ull) & 0x1FFFF;
160 
161  int inx = 0; // count index for output objects
162  for (auto& it : m_storeRawPXD) {
163  if (m_verbose) {
164  B2DEBUG(29, "PXD Unpacker --> Unpack Objects: ");
165  };
166  unpack_rawpxd(it, inx++);
167  }
168 
169  if (nRaws == 0) m_errorMask[c_nrNO_PXD] = true;
170  }
172  m_storeDAQEvtStats->setErrorMask(m_errorMaskEvent);
173 
175  {
176  for (unsigned int i = 0; i < ONSEN_MAX_TYPE_ERR; i++) {
177  if (m_errorMaskEvent[i]) m_errorCounter[i]++;
178  }
179  }
180 
181  if ((PXDErrorFlags(m_criticalErrorMask) & m_errorMaskEvent) != PXDErrorFlags(0)) B2ERROR("Error in PXD unpacking" <<
182  LogVar("event nr", m_meta_event_nr));
183  setReturnValue(PXDErrorFlags(0) == (PXDErrorFlags(m_criticalErrorMask) & m_errorMaskEvent));
184 }
185 
187 {
188  int Frames_in_event;
189  int fullsize;
190  int datafullsize;
191 
192  m_errorMaskDHE = 0;
193  m_errorMaskDHC = 0;
194  m_errorMaskPacket = 0;
195  PXDDAQPacketStatus& daqpktstat = m_storeDAQEvtStats->newPacket(inx);
196 
197  if (px.size() <= 0 || px.size() > 16 * 1024 * 1024) {
198  if (!(m_suppressErrorMask[c_nrPACKET_SIZE])) {
199  B2WARNING("PXD Unpacker --> invalid packet size" <<
200  LogVar("size [32bit words] $", static_cast < std::ostringstream && >(std::ostringstream() << hex << px.size()).str()));
201  }
202  m_errorMask[c_nrPACKET_SIZE] = true;
203  return;
204  }
205  std::vector<unsigned int> data(px.size());
206  fullsize = px.size() * 4;
207  std::copy_n(px.data(), px.size(), data.begin());
208 
209  if (fullsize < 8) {
210  if (!(m_suppressErrorMask[c_nrPACKET_SIZE])) {
211  B2WARNING("Data is to small to hold a valid Header! Will not unpack anything." << LogVar("size [32bit words] $",
212  static_cast < std::ostringstream && >(std::ostringstream() << hex << fullsize).str()));
213  }
214  m_errorMask[c_nrPACKET_SIZE] = true;
215  return;
216  }
217 
218  if (data[0] != 0xCAFEBABE && data[0] != 0xBEBAFECA) {
219  if (!(m_suppressErrorMask[c_nrMAGIC])) {
220  B2WARNING("Magic invalid: Will not unpack anything. Header corrupted." <<
221  LogVar("Header Magic $", static_cast < std::ostringstream && >(std::ostringstream() << hex << data[0]).str()));
222  }
223  m_errorMask[c_nrMAGIC] = true;
224  return;
225  }
226 
227 
228  Frames_in_event = ((ubig32_t*)data.data())[1];
229  if (Frames_in_event < 0 || Frames_in_event > 256) {
230  if (!(m_suppressErrorMask[c_nrFRAME_NR])) {
231  B2WARNING("Number of Frames invalid: Will not unpack anything. Header corrupted!" << LogVar("Frames in event", Frames_in_event));
232  }
233  m_errorMask[c_nrFRAME_NR] = true;
234  return;
235  }
236  if (Frames_in_event < 3) {
237  if (!(m_suppressErrorMask[c_nrNR_FRAMES_TO_SMALL])) {
238  B2WARNING("Number of Frames too small: It cannot contain anything useful." << LogVar("Frames in event", Frames_in_event));
239  }
240  m_errorMask[c_nrNR_FRAMES_TO_SMALL] = true;
241  }
242 
244  if (m_verbose) {
245  B2DEBUG(29, "PXD Unpacker --> data[0]: <-- Magic $" << hex << data[0]);
246  B2DEBUG(29, "PXD Unpacker --> data[1]: <-- #Frames $" << hex << data[1]);
247  if (data[1] >= 1 && fullsize < 12) B2DEBUG(29, "PXD Unpacker --> data[2]: <-- Frame 1 len $" << hex << data[2]);
248  if (data[1] >= 2 && fullsize < 16) B2DEBUG(29, "PXD Unpacker --> data[3]: <-- Frame 2 len $" << hex << data[3]);
249  if (data[1] >= 3 && fullsize < 20) B2DEBUG(29, "PXD Unpacker --> data[4]: <-- Frame 3 len $" << hex << data[4]);
250  if (data[1] >= 4 && fullsize < 24) B2DEBUG(29, "PXD Unpacker --> data[5]: <-- Frame 4 len $" << hex << data[5]);
251  };
252 
253  unsigned int* tableptr;
254  tableptr = &data[2]; // skip header!!!
255 
256  unsigned int* dataptr;
257  dataptr = &tableptr[Frames_in_event];
258  datafullsize = fullsize - 2 * 4 - Frames_in_event * 4; // Size is fullsize minus header minus table
259 
260  int ll = 0; // Offset in dataptr in bytes
261  for (int j = 0; j < Frames_in_event; j++) {
262  int lo;
263 
264  lo = ((ubig32_t*)tableptr)[j];
265  if (lo <= 0) {
266  if (!(m_suppressErrorMask[c_nrFRAME_SIZE])) {
267  B2WARNING("size of frame invalid");
268  B2DEBUG(29, "size of frame invalid: " << j << "size " << lo << " at byte offset in dataptr " << ll);
269  }
270  m_errorMask[c_nrFRAME_SIZE] = true;
271  return;
272  }
273  if (ll + lo > datafullsize) {
274  if (!(m_suppressErrorMask[c_nrFRAME_SIZE])) {
275  B2WARNING("Frames exceed packet size");
276  B2DEBUG(29, "Frames exceed packet size: " << j << " size " << lo << " at byte offset in dataptr " << ll << " of datafullsize " <<
277  datafullsize << " of fullsize " << fullsize);
278  }
279  m_errorMask[c_nrFRAME_SIZE] = true;
280  return;
281  }
282  if (lo & 0x3) {
283  if (!(m_suppressErrorMask[c_nrFRAME_SIZE])) {
284  B2WARNING("SKIP Frame with Data with not MOD 4 length");
285  B2DEBUG(29, "SKIP Frame with Data with not MOD 4 length " << " ( $" << hex << lo << " ) ");
286  }
287  ll += (lo + 3) & 0xFFFFFFFC;
288  m_errorMask[c_nrFRAME_SIZE] = true;
289  } else {
290  B2DEBUG(29, "unpack DHE(C) frame: " << j << " with size " << lo << " at byte offset in dataptr " << ll);
291  if (m_firmware > 0 && m_firmware < 10) {
293  unpack_dhc_frame_v01(ll + (char*)dataptr, lo, j, Frames_in_event, daqpktstat);
294  } else if (m_firmware >= 10) {
296  unpack_dhc_frame_v10(ll + (char*)dataptr, lo, j, Frames_in_event, daqpktstat);
297  } else {
298  B2FATAL("Firmware Version not supported " << m_firmware);
299  }
300  ll += lo;
301  }
306  m_errorMask = 0;
307 
308  if (!m_continueOnError && (m_errorMaskPacket & PXDErrorFlags(m_errorSkipPacketMask)) != PXDErrorFlags(0)) {
309  // skip full package on error, recovery to next DHC/DHE Start might be possible in some cases
310  // But thats to hard to implement
311  // Remark: PXD data for broken events is removed in next PXDPostChecker module, thus skipping the
312  // unpacking is not strictly necessary here.
313  break;
314  }
315  }
316  daqpktstat.setErrorMask(m_errorMaskPacket);
317 }
318 
319 void PXDUnpackerModule::unpack_dhp_raw(void* data, unsigned int frame_len, unsigned int dhe_ID, unsigned dhe_DHPport,
320  VxdID vxd_id)
321 {
322 // unsigned int nr_words = frame_len / 2; // frame_len in bytes (excl. CRC)!!!
323  ubig16_t* dhp_pix = (ubig16_t*)data;
324 
331 
332  // Size: 64*768 + 8 bytes for a full frame readout
333  if (frame_len != 0xC008) {
334  if (!(m_suppressErrorMask[c_nrFIX_SIZE])) B2WARNING("Frame size unsupported for RAW ADC frame! $" <<
335  LogVar("size [bytes] $", static_cast < std::ostringstream && >(std::ostringstream() << hex << frame_len).str())
336  << LogVar("DHE", dhe_ID) << LogVar("DHP", dhe_DHPport));
337  m_errorMask[c_nrFIX_SIZE] = true;
338  return;
339  }
340  unsigned int dhp_header_type = 0;
341 // unsigned int dhp_reserved = 0;
342  unsigned int dhp_dhe_id = 0;
343  unsigned int dhp_dhp_id = 0;
344 
345  dhp_header_type = (dhp_pix[2] & 0xE000) >> 13;
346 // dhp_reserved = (dhp_pix[2] >> 8) & 0x1F;
347  dhp_dhe_id = (dhp_pix[2] & 0x00FC) >> 2;
348  dhp_dhp_id = dhp_pix[2] & 0x0003;
349 
350  if (dhe_ID != dhp_dhe_id) {
351  if (!(m_suppressErrorMask[c_nrDHE_DHP_DHEID])) {
352  B2WARNING("DHE ID in DHE and DHP header differ");
353  B2DEBUG(29, "DHE ID in DHE and DHP header differ $" << hex << dhe_ID << " != $" << dhp_dhe_id);
354  }
355  m_errorMask[c_nrDHE_DHP_DHEID] = true;
356  }
357  if (dhe_DHPport != dhp_dhp_id) {
358  if (!(m_suppressErrorMask[c_nrDHE_DHP_PORT])) {
359  B2WARNING("DHP ID (Chip/Port) in DHE and DHP header differ");
360  B2DEBUG(29, "DHP ID (Chip/Port) in DHE and DHP header differ $" << hex << dhe_DHPport << " != $" << dhp_dhp_id);
361  }
362  m_errorMask[c_nrDHE_DHP_PORT] = true;
363  }
364 
365  if (dhp_header_type != EDHPFrameHeaderDataType::c_RAW) {
366  if (!(m_suppressErrorMask[c_nrHEADERTYPE_INV])) {
367  B2WARNING("Header type invalid for this kind of DHE frame");
368  B2DEBUG(29, "Header type invalid for this kind of DHE frame: $" << hex << dhp_header_type);
369  }
370  m_errorMask[c_nrHEADERTYPE_INV] = true;
371  return;
372  }
373 
375  B2DEBUG(29, "Raw ADC Data");
376  // size checked already above
377  m_storeRawAdc.appendNew(vxd_id, data, frame_len);
378 };
379 
380 void PXDUnpackerModule::unpack_fce([[maybe_unused]] unsigned short* data, [[maybe_unused]] unsigned int length,
381  [[maybe_unused]] VxdID vxd_id)
382 {
389 
390  B2WARNING("FCE (Cluster) Packet have not yet been tested with real HW clusters. Dont assume that this code is working!");
391  return;
392 
393  // implement the unpacking here and not as a separate module ... when it is available in HW
394 // ubig16_t* cluster = (ubig16_t*)data;
395 // int nr_words; //words in dhp frame
396 // unsigned int words_in_cluster = 0; //counts 16bit words in cluster
397 // nr_words = length / 2;
398 // ubig16_t sor;
399 // sor = 0x0000;
400 //
401 // for (int i = 2 ; i < nr_words ; i++) {
402 // if (i != 2) { //skip header
403 // if ((((cluster[i] & 0x8000) == 0)
404 // && ((cluster[i] & 0x4000) >> 14) == 1)) { //searches for start of row frame with start of cluster flag = 1 => new cluster
405 // if (!m_doNotStore) m_storeRawCluster.appendNew(&data[i - words_in_cluster], words_in_cluster, vxd_id);
406 // words_in_cluster = 0;
407 // }
408 // }
409 // if ((cluster[i] & 0x8000) == 0) {
410 // sor = cluster[i];
411 // }
412 // words_in_cluster++;
413 //
414 // if ((cluster[nr_words - 1] & 0xFFFF) == (sor &
415 // 0xFFFF)) {//if frame is not 32bit aligned last word will be the last start of row word
416 // cluster[nr_words - 1] = 0x0000;//overwrites the last redundant word with zero to make checking easier in PXDHardwareClusterUnpacker
417 // }
418 //
419 // if (i == nr_words - 1) {
420 // if (!m_doNotStore) m_storeRawCluster.appendNew(&data[i - words_in_cluster + 1], words_in_cluster, vxd_id);
421 // }
422 // }
423 }
424 
425 void PXDUnpackerModule::dump_dhp(void* data, unsigned int frame_len)
426 {
427  // called only for debugging purpose, will never be called in normal running
428  unsigned int w = frame_len / 2;
429  ubig16_t* d = (ubig16_t*)data;
430 
431  B2WARNING("HEADER -- $" << hex << d[0] << ",$" << hex << d[1] << ",$" << hex << d[2] << ",$" << hex << d[3] << " -- ");
432 
433  auto dhp_header_type = (d[2] & 0xE000) >> 13;
434  auto dhp_reserved = (d[2] & 0x1F00) >> 8;
435  auto dhp_dhe_id = (d[2] & 0x00FC) >> 2;
436  auto dhp_dhp_id = d[2] & 0x0003;
437 
438  B2WARNING("DHP type | $" << hex << dhp_header_type << " ( " << dec << dhp_header_type << " ) ");
439  B2WARNING("DHP reserved | $" << hex << dhp_reserved << " ( " << dec << dhp_reserved << " ) ");
440  B2WARNING("DHP DHE ID | $" << hex << dhp_dhe_id << " ( " << dec << dhp_dhe_id << " ) ");
441  B2WARNING("DHP DHP ID | $" << hex << dhp_dhp_id << " ( " << dec << dhp_dhp_id << " ) ");
442  for (unsigned int i = 4; i < w; i++) {
443  B2WARNING("DHP DATA $" << hex << d[i]);
444  }
445  B2WARNING("DHP CRC $" << hex << d[w] << ",$" << hex << d[w + 1]);
446 }
447 
448 void PXDUnpackerModule::dump_roi(void* data, unsigned int frame_len)
449 {
450  // called only for debugging purpose, will never be called in normal running
451  unsigned int w = frame_len / 4;
452  ubig32_t* d = (ubig32_t*)data;
453 
454  B2WARNING("HEADER -- $" << hex << d[0] << ",$" << hex << d[1] << ",$" << hex << d[2] << ",$" << hex << d[3] << " -- Len $" << hex
455  << frame_len);
456 
457  for (unsigned int i = 0; i < w; i++) {
458  B2WARNING("ROI DATA $" << hex << d[i]);
459  }
460  B2WARNING("ROI CRC $" << hex << d[w]);
461 }
462 
463 void PXDUnpackerModule::unpack_dhp_v01(void* data, unsigned int frame_len, unsigned int dhe_first_readout_frame_id_lo,
464  unsigned int dhe_ID, unsigned dhe_DHPport, unsigned dhe_reformat, VxdID vxd_id,
465  PXDDAQPacketStatus& daqpktstat)
466 {
467  unsigned int nr_words = frame_len / 2; // frame_len in bytes (excl. CRC)!!!
468  ubig16_t* dhp_pix = (ubig16_t*)data;
469 
470  unsigned int dhp_readout_frame_lo = 0;
471  unsigned int dhp_header_type = 0;
472  unsigned int dhp_reserved = 0;
473  unsigned int dhp_dhe_id = 0;
474  unsigned int dhp_dhp_id = 0;
475 
476  // cppcheck-suppress unreadVariable
477  unsigned int dhp_row = 0, dhp_col = 0, dhp_cm = 0;
478 // unsigned int dhp_offset = 0;
479  bool rowflag = false;
480  bool pixelflag = true; // just for first row start
481 
482  if (nr_words < 4) {
483  if (!(m_suppressErrorMask[c_nrDHP_SIZE])) B2WARNING("DHP frame size error (too small)" << LogVar("Nr words", nr_words));
484  m_errorMask[c_nrDHP_SIZE] = true;
485  return;
486  }
487 
488  B2DEBUG(29, "HEADER -- $" << hex << dhp_pix[0] << hex << dhp_pix[1] << hex << dhp_pix[2] << hex << dhp_pix[3] << " -- ");
489 
490  B2DEBUG(29, "DHP Header | $" << hex << dhp_pix[2] << " ( " << dec << dhp_pix[2] << " ) ");
491  dhp_header_type = (dhp_pix[2] & 0xE000) >> 13;
492  dhp_reserved = (dhp_pix[2] & 0x1F00) >> 8;
493  dhp_dhe_id = (dhp_pix[2] & 0x00FC) >> 2;
494  dhp_dhp_id = dhp_pix[2] & 0x0003;
495 
496  B2DEBUG(29, "DHP type | $" << hex << dhp_header_type << " ( " << dec << dhp_header_type << " ) ");
497  B2DEBUG(29, "DHP reserved | $" << hex << dhp_reserved << " ( " << dec << dhp_reserved << " ) ");
498  B2DEBUG(29, "DHP DHE ID | $" << hex << dhp_dhe_id << " ( " << dec << dhp_dhe_id << " ) ");
499  B2DEBUG(29, "DHP DHP ID | $" << hex << dhp_dhp_id << " ( " << dec << dhp_dhp_id << " ) ");
500 
501  if (dhe_ID != dhp_dhe_id) {
502  if (!(m_suppressErrorMask[c_nrDHE_DHP_DHEID])) {
503  B2WARNING("DHE ID in DHE and DHP header differ");
504  B2DEBUG(29, "DHE ID in DHE and DHP header differ $" << hex << dhe_ID << " != $" << dhp_dhe_id);
505  }
506  m_errorMask[c_nrDHE_DHP_DHEID] = true;
507  }
508  if (dhe_DHPport != dhp_dhp_id) {
509  if (!(m_suppressErrorMask[c_nrDHE_DHP_PORT])) {
510  B2WARNING("DHP ID (Chip/Port) in DHE and DHP header differ");
511  B2DEBUG(29, "DHP ID (Chip/Port) in DHE and DHP header differ $" << hex << dhe_DHPport << " != $" << dhp_dhp_id);
512  }
513  m_errorMask[c_nrDHE_DHP_PORT] = true;
514  }
515 
516  if (dhp_header_type != EDHPFrameHeaderDataType::c_ZSD) {
517  if (!(m_suppressErrorMask[c_nrHEADERTYPE_INV])) {
518  B2WARNING("Header type invalid for this kind of DHE frame");
519  B2DEBUG(29, "Header type invalid for this kind of DHE frame: $" << hex << dhp_header_type);
520  }
521  m_errorMask[c_nrHEADERTYPE_INV] = true;
522  return;
523  }
524 
525 // static int offtab[4] = {0, 64, 128, 192};
526 // dhp_offset = offtab[dhp_dhp_id];
527 
528  dhp_readout_frame_lo = dhp_pix[3] & 0xFFFF;
529  B2DEBUG(29, "DHP Frame Nr | $" << hex << dhp_readout_frame_lo << " ( " << dec << dhp_readout_frame_lo << " ) ");
530 
531  /* // TODO removed because data format error is not to be fixed soon
532  if (((dhp_readout_frame_lo - dhe_first_readout_frame_id_lo) & 0x3F) > m_maxDHPFrameDiff) {
533  if (!m_suppressErrorMask[c_nrDHP_DHE_FRAME_DIFFER]) B2WARNING("DHP Frame Nr differ from DHE Frame Nr by >1 DHE " <<
534  dhe_first_readout_frame_id_lo << " != DHP " << (dhp_readout_frame_lo & 0x3F) << " delta " << ((
535  dhp_readout_frame_lo - dhe_first_readout_frame_id_lo) & 0x3F));
536  m_errorMask[c_nrDHP_DHE_FRAME_DIFFER] = true;
537  }
538  */
539  /* // TODO removed because data format error is not to be fixed soon
540  if (m_last_dhp_readout_frame_lo[dhp_dhp_id] != -1) {
541  if (((dhp_readout_frame_lo - m_last_dhp_readout_frame_lo[dhp_dhp_id]) & 0xFFFF) > m_maxDHPFrameDiff) {
542  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] << ", " <<
543  dhp_readout_frame_lo);
544  m_errorMask[c_nrDHP_NOT_CONT] = true;
545  }
546  }
547  */
548 
549  if (daqpktstat.dhc_size() > 0) {
550  if (daqpktstat.dhc_back().dhe_size() > 0) {
551  // only is we have a DHC and DHE object... or back() is undefined
552  // Remark, if we have a broken data (DHE_START/END) structure, we might fill the
553  // previous DHE object ... but then the data is junk anyway
554  daqpktstat.dhc_back().dhe_back().newDHP(dhp_dhp_id, dhp_readout_frame_lo);
555  }
556  }
557 
558  /* // TODO removed because the data is not ordered as expected in current firmware
559  for (auto j = 0; j < 4; j++) {
560  if (m_last_dhp_readout_frame_lo[j] != -1) {
561  if (((dhp_readout_frame_lo - m_last_dhp_readout_frame_lo[j]) & 0xFFFF) > m_maxDHPFrameDiff) {
562  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] <<
563  ", " <<
564  dhp_readout_frame_lo);
565  m_errorMask[c_nrDHP_DHP_FRAME_DIFFER] = true;
566  break;// give msg only once
567  }
568  }
569  }
570  */
571  m_last_dhp_readout_frame_lo[dhp_dhp_id] = dhp_readout_frame_lo;
572 
573 // TODO Please check if this can happen by accident with valid data!
574  if (dhp_pix[2] == dhp_pix[4] && dhp_pix[3] + 1 == dhp_pix[5]) {
575  // We see a second "header" with framenr+1 ...
576  if (!(m_suppressErrorMask[c_nrDHP_DBL_HEADER])) {
577  B2WARNING("DHP data: seems to be double header! skipping.");
578  B2DEBUG(29, "DHP data: seems to be double header! skipping." << LogVar("Length",
579  frame_len));
580  }
581  m_errorMask[c_nrDHP_DBL_HEADER] = true;
582  // dump_dhp(data, frame_len); print out guilty dhp packet
583  return;
584  }
585 
586  // Start with offset 4, thus skipping header words
587  for (unsigned int i = 4; i < nr_words ; i++) {
588 
589  B2DEBUG(29, "-- $" << hex << dhp_pix[i] << " -- " << dec << i);
590  {
591  if (((dhp_pix[i] & 0x8000) >> 15) == 0) {
592  rowflag = true;
593  if (!pixelflag) {
594  if (!(m_suppressErrorMask[c_nrDHP_ROW_WO_PIX])) B2WARNING("DHP Unpacking: Row w/o Pix");
595  m_errorMask[c_nrDHP_ROW_WO_PIX] = true;
596  }
597  pixelflag = false;
598  dhp_row = (dhp_pix[i] & 0xFFC0) >> 5;
599  dhp_cm = dhp_pix[i] & 0x3F;
600  if (dhp_cm == 63) { // fifo overflow
601  B2WARNING("DHP data loss (CM=63) in " << LogVar("DHE", dhe_ID) << LogVar("DHP", dhp_dhp_id));
603  m_errorMask[c_nrDHH_MISC_ERROR] = true;
604  }
605  if (daqpktstat.dhc_size() > 0) {
606  if (daqpktstat.dhc_back().dhe_size() > 0) {
607  PXDDAQDHPComMode cm(dhp_dhp_id, dhp_row, dhp_cm);
608  // only is we have a DHC and DHE object... or back() is undefined
609  // Remark, if we have a broken data (DHE_START/END) structure, we might fill the
610  // previous DHE object ... but then the data is junk anyway
611  daqpktstat.dhc_back().dhe_back().addCM(cm);
612  }
613  }
614  B2DEBUG(29, "SetRow: $" << hex << dhp_row << " CM $" << hex << dhp_cm);
615  } else {
616  if (!rowflag) {
617  if (!(m_suppressErrorMask[c_nrDHP_PIX_WO_ROW])) B2WARNING("DHP Unpacking: Pix without Row!!! skip dhp data ");
618  m_errorMask[c_nrDHP_PIX_WO_ROW] = true;
619  // dump_dhp(data, frame_len);// print out faulty dhp frame
620  return;
621  } else {
622  pixelflag = true;
623  dhp_row = (dhp_row & 0xFFE) | ((dhp_pix[i] & 0x4000) >> 14);
624  dhp_col = ((dhp_pix[i] & 0x3F00) >> 8);
625  unsigned int v_cellID, u_cellID;
626  v_cellID = dhp_row;// defaults for no mapping
627  if (dhp_row >= 768) {
628  if (!(m_suppressErrorMask [c_nrROW_OVERFLOW])) B2WARNING("DHP ROW Overflow " << LogVar("Row", dhp_row));
629  m_errorMask[c_nrROW_OVERFLOW] = true;
630  }
631  // we cannot do col overflow check before mapping :-(
632 
633  if ((dhe_reformat == 0 && !m_forceNoMapping) || m_forceMapping) {
634  u_cellID = dhp_col;// defaults for no mapping
635  // data has not been pre-processed by DHH, thus we have to do the mapping ourselves
636  if ((dhe_ID & 0x21) == 0x00 || (dhe_ID & 0x21) == 0x21) {
637  // if IFOB
638  PXDMappingLookup::map_rc_to_uv_IF_OB(v_cellID, u_cellID, dhp_dhp_id, dhe_ID);
639  } else { // else OFIB
640  PXDMappingLookup::map_rc_to_uv_IB_OF(v_cellID, u_cellID, dhp_dhp_id, dhe_ID);
641  }
642  } else {
643  u_cellID = dhp_col + 64 * dhp_dhp_id; // defaults for already mapped
644  }
645  if (u_cellID >= 250) {
646  if (!(m_suppressErrorMask[c_nrCOL_OVERFLOW])) {
647  B2WARNING("DHP COL Overflow (unconnected drain lines)");
648  B2DEBUG(29, "DHP COL Overflow (unconnected drain lines) " << u_cellID << ", reformat " << dhe_reformat << ", dhpcol " << dhp_col <<
649  ", id " << dhp_dhp_id);
650  }
651  m_errorMask[c_nrCOL_OVERFLOW] = true;
652  }
653  auto dhp_adc = dhp_pix[i] & 0xFF;
654  B2DEBUG(29, "SetPix: Row $" << hex << dhp_row << " Col $" << hex << dhp_col << " ADC $" << hex << dhp_adc
655  << " CM $" << hex << dhp_cm);
656 
657  /*if (m_verbose) {
658  B2DEBUG(29, "raw | " << hex << d[i]);
659  B2DEBUG(29, "row " << hex << ((d[i] >> 20) & 0xFFF) << "(" << ((d[i] >> 20) & 0xFFF) << ")" << " col " << "(" << hex << ((d[i] >> 8) & 0xFFF) << ((d[i] >> 8) & 0xFFF)
660  << " adc " << "(" << hex << (d[i] & 0xFF) << (d[i] & 0xFF) << ")");
661  B2DEBUG(29, "dhe_ID " << dhe_ID);
662  B2DEBUG(29, "start-Frame-Nr " << dec << dhe_first_readout_frame_id_lo);
663  };*/
664 
665  if (!m_doNotStore) m_storeRawHits.appendNew(vxd_id, v_cellID, u_cellID, dhp_adc,
666  (dhp_readout_frame_lo - dhe_first_readout_frame_id_lo) & 0x3F);
667  }
668  }
669  }
670  }
671 
672  B2DEBUG(29, "(DHE) DHE_ID $" << hex << dhe_ID << " (DHE) DHP ID $" << hex << dhe_DHPport << " (DHP) DHE_ID $" << hex << dhp_dhe_id
673  << " (DHP) DHP ID $" << hex << dhp_dhp_id);
674  /*for (int i = 0; i < raw_nr_words ; i++) {
675  B2DEBUG(29, "RAW | " << hex << p_pix[i]);
676  printf("raw %08X | ", p_pix[i]);
677  B2DEBUG(29, "row " << hex << ((p_pix[i] >> 20) & 0xFFF) << dec << " ( " << ((p_pix[i] >> 20) & 0xFFF) << " ) " << " col " << hex << ((p_pix[i] >> 8) & 0xFFF)
678  << " ( " << dec << ((p_pix[i] >> 8) & 0xFFF) << " ) " << " adc " << hex << (p_pix[i] & 0xFF) << " ( " << (p_pix[i] & 0xFF) << " ) "
679  );
680  }*/
681 }
682 
683 void PXDUnpackerModule::unpack_dhp_v10(void* data, unsigned int frame_len, unsigned int dhe_first_readout_frame_id_lo,
684  unsigned int dhe_ID, unsigned dhe_DHPport, unsigned dhe_reformat, VxdID vxd_id,
685  PXDDAQPacketStatus& daqpktstat)
686 {
687  unsigned int nr_words = frame_len / 2; // frame_len in bytes (excl. CRC)!!!
688  ubig16_t* dhp_pix = (ubig16_t*)data;
689 
690  unsigned int dhp_readout_frame_lo = 0;
691  unsigned int dhp_header_type = 0;
692  unsigned int dhp_reserved = 0;
693  unsigned int dhp_dhe_id = 0;
694  unsigned int dhp_dhp_id = 0;
695  unsigned int wrap = 0; // workaround to recalc a relative frame number
696  int last_gate = -1; // workaround to recalc a relative frame number
697 
698  // cppcheck-suppress unreadVariable
699  unsigned int dhp_row = 0, dhp_col = 0, dhp_cm = 0;
700 // unsigned int dhp_offset = 0;
701  bool rowflag = false;
702  bool pixelflag = true; // just for first row start
703 
704  if (nr_words < 4) {
705  if (!(m_suppressErrorMask[c_nrDHP_SIZE])) B2WARNING("DHP frame size error (too small)" << LogVar("Nr words", nr_words));
706  m_errorMask[c_nrDHP_SIZE] = true;
707  return;
708  }
709 
710  B2DEBUG(29, "HEADER -- $" << hex << dhp_pix[0] << hex << dhp_pix[1] << hex << dhp_pix[2] << hex << dhp_pix[3] << " -- ");
711 
712  B2DEBUG(29, "DHP Header | $" << hex << dhp_pix[2] << " ( " << dec << dhp_pix[2] << " ) ");
713  dhp_header_type = (dhp_pix[2] & 0xE000) >> 13;
714  dhp_reserved = (dhp_pix[2] & 0x1F00) >> 8;
715  dhp_dhe_id = (dhp_pix[2] & 0x00FC) >> 2;
716  dhp_dhp_id = dhp_pix[2] & 0x0003;
717 
718  B2DEBUG(29, "DHP type | $" << hex << dhp_header_type << " ( " << dec << dhp_header_type << " ) ");
719  B2DEBUG(29, "DHP reserved | $" << hex << dhp_reserved << " ( " << dec << dhp_reserved << " ) ");
720  B2DEBUG(29, "DHP DHE ID | $" << hex << dhp_dhe_id << " ( " << dec << dhp_dhe_id << " ) ");
721  B2DEBUG(29, "DHP DHP ID | $" << hex << dhp_dhp_id << " ( " << dec << dhp_dhp_id << " ) ");
722 
723  if (dhe_ID != dhp_dhe_id) {
724  if (!(m_suppressErrorMask[c_nrDHE_DHP_DHEID])) {
725  B2WARNING("DHE ID in DHE and DHP header differ");
726  B2DEBUG(29, "DHE ID in DHE and DHP header differ $" << hex << dhe_ID << " != $" << dhp_dhe_id);
727  }
728  m_errorMask[c_nrDHE_DHP_DHEID] = true;
729  }
730  if (dhe_DHPport != dhp_dhp_id) {
731  if (!(m_suppressErrorMask[c_nrDHE_DHP_PORT])) {
732  B2WARNING("DHP ID (Chip/Port) in DHE and DHP header differ");
733  B2DEBUG(29, "DHP ID (Chip/Port) in DHE and DHP header differ $" << hex << dhe_DHPport << " != $" << dhp_dhp_id);
734  }
735  m_errorMask[c_nrDHE_DHP_PORT] = true;
736  }
737 
738  if (dhp_header_type != EDHPFrameHeaderDataType::c_ZSD) {
739  if (!(m_suppressErrorMask[c_nrHEADERTYPE_INV])) {
740  B2WARNING("Header type invalid for this kind of DHE frame");
741  B2DEBUG(29, "Header type invalid for this kind of DHE frame: $" << hex << dhp_header_type);
742  }
743  m_errorMask[c_nrHEADERTYPE_INV] = true;
744  return;
745  }
746 
747 // static int offtab[4] = {0, 64, 128, 192};
748 // dhp_offset = offtab[dhp_dhp_id];
749 
750  dhp_readout_frame_lo = dhp_pix[3] & 0xFFFF;
751  B2DEBUG(29, "DHP Frame Nr | $" << hex << dhp_readout_frame_lo << " ( " << dec << dhp_readout_frame_lo << " ) ");
752 
753  /* // TODO removed because data format error is not to be fixed soon
754  if (((dhp_readout_frame_lo - dhe_first_readout_frame_id_lo) & 0x3F) > m_maxDHPFrameDiff) {
755  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) );
756  m_errorMask[c_nrDHP_DHE_FRAME_DIFFER] = true;
757  }
758  */
759  /* // TODO removed because data format error is not to be fixed soon
760  if (m_last_dhp_readout_frame_lo[dhp_dhp_id] != -1) {
761  if (((dhp_readout_frame_lo - m_last_dhp_readout_frame_lo[dhp_dhp_id]) & 0xFFFF) > m_maxDHPFrameDiff) {
762  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] << ", " <<
763  dhp_readout_frame_lo);
764  m_errorMask[c_nrDHP_NOT_CONT] = true;
765  }
766  }
767  */
768 
769  if (daqpktstat.dhc_size() > 0) {
770  if (daqpktstat.dhc_back().dhe_size() > 0) {
771  // only is we have a DHC and DHE object... or back() is undefined
772  // Remark, if we have a broken data (DHE_START/END) structure, we might fill the
773  // previous DHE object ... but then the data is junk anyway
774  daqpktstat.dhc_back().dhe_back().newDHP(dhp_dhp_id, dhp_readout_frame_lo);
775  }
776  }
777 
778  /* // TODO removed because the data is not ordered as expected in current firmware
779  for (auto j = 0; j < 4; j++) {
780  if (m_last_dhp_readout_frame_lo[j] != -1) {
781  if (((dhp_readout_frame_lo - m_last_dhp_readout_frame_lo[j]) & 0xFFFF) > m_maxDHPFrameDiff) {
782  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] <<
783  ", " <<
784  dhp_readout_frame_lo);
785  m_errorMask[c_nrDHP_DHP_FRAME_DIFFER] = true;
786  break;// give msg only once
787  }
788  }
789  }
790  */
791  m_last_dhp_readout_frame_lo[dhp_dhp_id] = dhp_readout_frame_lo;
792 
793 // TODO Please check if this can happen by accident with valid data!
794  if (dhp_pix[2] == dhp_pix[4] && dhp_pix[3] + 1 == dhp_pix[5]) {
795  // We see a second "header" with framenr+1 ...
796  if (!(m_suppressErrorMask[c_nrDHP_DBL_HEADER])) {
797  B2WARNING("DHP data: seems to be double header! skipping.");
798  B2DEBUG(29, "DHP data: seems to be double header! skipping." << LogVar("Length",
799  frame_len));
800  }
801  m_errorMask[c_nrDHP_DBL_HEADER] = true;
802  // dump_dhp(data, frame_len); print out guilty dhp packet
803  return;
804  }
805 
806  // Start with offset 4, thus skipping header words
807  for (unsigned int i = 4; i < nr_words ; i++) {
808 
809  B2DEBUG(29, "-- $" << hex << dhp_pix[i] << " -- " << dec << i);
810  {
811  if (((dhp_pix[i] & 0x8000) >> 15) == 0) {
812  rowflag = true;
813  if (!pixelflag) {
814  if (!(m_suppressErrorMask[c_nrDHP_ROW_WO_PIX])) B2WARNING("DHP Unpacking: Row w/o Pix");
815  m_errorMask[c_nrDHP_ROW_WO_PIX] = true;
816  }
817  pixelflag = false;
818  dhp_row = (dhp_pix[i] & 0xFFC0) >> 5;
819  dhp_cm = dhp_pix[i] & 0x3F;
820  if (last_gate != -1 && (int)dhp_row / 4 < last_gate) {
821  // B2DEBUF(29,"Wrap " << LogVar("last", last_gate) << LogVar("curr", dhp_row / 4) << LogVar("DHE", dhe_ID) << LogVar("DHP", dhp_dhp_id));
822  wrap++; // relies on the order of data before mapping and the fact that OT firmware delivers only one frame
823  }
824  last_gate = dhp_row / 4;
825 
826  if (dhp_cm == 63) { // fifo overflow
827  B2WARNING("DHP data loss (CM=63) in " << LogVar("DHE", dhe_ID) << LogVar("DHP", dhp_dhp_id));
829  m_errorMask[c_nrDHH_MISC_ERROR] = true;
830  }
831  if (daqpktstat.dhc_size() > 0) {
832  if (daqpktstat.dhc_back().dhe_size() > 0) {
833  PXDDAQDHPComMode cm(dhp_dhp_id, dhp_row, dhp_cm);
834  // only is we have a DHC and DHE object... or back() is undefined
835  // Remark, if we have a broken data (DHE_START/END) structure, we might fill the
836  // previous DHE object ... but then the data is junk anyway
837  daqpktstat.dhc_back().dhe_back().addCM(cm);
838  }
839  }
840  B2DEBUG(29, "SetRow: $" << hex << dhp_row << " CM $" << hex << dhp_cm);
841  } else {
842  if (!rowflag) {
843  if (!(m_suppressErrorMask[c_nrDHP_PIX_WO_ROW])) B2WARNING("DHP Unpacking: Pix without Row!!! skip dhp data ");
844  m_errorMask[c_nrDHP_PIX_WO_ROW] = true;
845  // dump_dhp(data, frame_len);// print out faulty dhp frame
846  return;
847  } else {
848  pixelflag = true;
849  dhp_row = (dhp_row & 0xFFE) | ((dhp_pix[i] & 0x4000) >> 14);
850  dhp_col = ((dhp_pix[i] & 0x3F00) >> 8);
851  unsigned int v_cellID, u_cellID;
852  v_cellID = dhp_row;// defaults for no mapping
853  if (dhp_row >= 768) {
854  if (!(m_suppressErrorMask[c_nrROW_OVERFLOW])) B2WARNING("DHP ROW Overflow " << LogVar("Row", dhp_row));
855  m_errorMask[c_nrROW_OVERFLOW] = true;
856  }
857  // we cannot do col overflow check before mapping :-(
858 
859  if ((dhe_reformat == 0 && !m_forceNoMapping) || m_forceMapping) {
860  u_cellID = dhp_col;// defaults for no mapping
861  // data has not been pre-processed by DHH, thus we have to do the mapping ourselves
862  if ((dhe_ID & 0x21) == 0x00 || (dhe_ID & 0x21) == 0x21) {
863  // if IFOB
864  PXDMappingLookup::map_rc_to_uv_IF_OB(v_cellID, u_cellID, dhp_dhp_id, dhe_ID);
865  } else { // else OFIB
866  PXDMappingLookup::map_rc_to_uv_IB_OF(v_cellID, u_cellID, dhp_dhp_id, dhe_ID);
867  }
868  } else {
869  u_cellID = dhp_col + 64 * dhp_dhp_id; // defaults for already mapped
870  }
871  if (u_cellID >= 250) {
872  if (!(m_suppressErrorMask[c_nrCOL_OVERFLOW])) {
873  B2WARNING("DHP COL Overflow (unconnected drain lines)");
874  B2DEBUG(29, "DHP COL Overflow (unconnected drain lines) " << u_cellID << ", reformat " << dhe_reformat << ", dhpcol " << dhp_col <<
875  ", id " << dhp_dhp_id);
876  }
877  m_errorMask[c_nrCOL_OVERFLOW] = true;
878  }
879  auto dhp_adc = dhp_pix[i] & 0xFF;
880  B2DEBUG(29, "SetPix: Row $" << hex << dhp_row << " Col $" << hex << dhp_col << " ADC $" << hex << dhp_adc
881  << " CM $" << hex << dhp_cm);
882 
883  /*if (m_verbose) {
884  B2DEBUG(29, "raw | " << hex << d[i]);
885  B2DEBUG(29, "row " << hex << ((d[i] >> 20) & 0xFFF) << "(" << ((d[i] >> 20) & 0xFFF) << ")" << " col " << "(" << hex << ((d[i] >> 8) & 0xFFF) << ((d[i] >> 8) & 0xFFF)
886  << " adc " << "(" << hex << (d[i] & 0xFF) << (d[i] & 0xFF) << ")");
887  B2DEBUG(29, "dhe_ID " << dhe_ID);
888  B2DEBUG(29, "start-Frame-Nr " << dec << dhe_first_readout_frame_id_lo);
889  };*/
890 
891  // in new firmware, (dhp_readout_frame_lo - dhe_first_readout_frame_id_lo) would always been 0
892  if (!m_doNotStore) m_storeRawHits.appendNew(vxd_id, v_cellID, u_cellID, dhp_adc,
893  (dhp_readout_frame_lo - dhe_first_readout_frame_id_lo + wrap) & 0x3F);
894  }
895  }
896  }
897  }
898 
899  B2DEBUG(29, "(DHE) DHE_ID $" << hex << dhe_ID << " (DHE) DHP ID $" << hex << dhe_DHPport << " (DHP) DHE_ID $" << hex << dhp_dhe_id
900  << " (DHP) DHP ID $" << hex << dhp_dhp_id);
901  /*for (int i = 0; i < raw_nr_words ; i++) {
902  B2DEBUG(29, "RAW | " << hex << p_pix[i]);
903  printf("raw %08X | ", p_pix[i]);
904  B2DEBUG(29, "row " << hex << ((p_pix[i] >> 20) & 0xFFF) << dec << " ( " << ((p_pix[i] >> 20) & 0xFFF) << " ) " << " col " << hex << ((p_pix[i] >> 8) & 0xFFF)
905  << " ( " << dec << ((p_pix[i] >> 8) & 0xFFF) << " ) " << " adc " << hex << (p_pix[i] & 0xFF) << " ( " << (p_pix[i] & 0xFF) << " ) "
906  );
907  }*/
908 }
909 
910 
911 void PXDUnpackerModule::unpack_dhc_frame_v01(void* data, const int len, const int Frame_Number, const int Frames_in_event,
912  PXDDAQPacketStatus& daqpktstat)
913 {
917  static unsigned int eventNrOfOnsenTrgFrame = 0;
918  static int countedBytesInDHC = 0;
919  static bool cancheck_countedBytesInDHC = false;
920  static int countedBytesInDHE = 0;
921  static bool cancheck_countedBytesInDHE = false;
922  static int countedDHEStartFrames = 0;
923  static int countedDHEEndFrames = 0;
924  static int mask_active_dhe = 0;// DHE mask (5 bit)
925  static int nr_active_dhe =
926  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?
927  static int mask_active_dhp = 0;// DHP active mask, 4 bit, per current DHE
928  static int found_mask_active_dhp = 0;// mask which DHP send data and check on DHE END frame if it matches
929  static unsigned int dhe_first_readout_frame_id_lo = 0;
930  // cppcheck-suppress variableScope
931  static unsigned int dhe_first_triggergate = 0;
932  static unsigned int currentDHCID = 0xFFFFFFFF;
933  static unsigned int currentDHEID = 0xFFFFFFFF;
934  static unsigned int currentVxdId = 0;
935  static bool isFakedData_event = false;
936  static bool isUnfiltered_event = false;
937 
938 
939  if (Frame_Number == 0) {
940  // We reset the counters on the first event
941  // we do this before any other check is done
942  eventNrOfOnsenTrgFrame = 0;
943  countedDHEStartFrames = 0;
944  countedDHEEndFrames = 0;
945  countedBytesInDHC = 0;
946  cancheck_countedBytesInDHC = false;
947  countedBytesInDHE = 0;
948  cancheck_countedBytesInDHE = false;
949  currentDHCID = 0xFFFFFFFF;
950  currentDHEID = 0xFFFFFFFF;
951  currentVxdId = 0;
952  isUnfiltered_event = false;
953  isFakedData_event = false;
954  mask_active_dhe = 0;
955  nr_active_dhe = 0;
956  mask_active_dhp = 0;
957  found_mask_active_dhp = 0;
958  }
959 
961 
962  dhc_frames dhc;
963  dhc.set(data, hw->getFrameType(), len);
964 
965  {
966  // if a fixed size frame has a different length, how can we rely on its content???
967  // AND we could by typecasting access memory beyond end of data (but very unlikely)
968  // for that reason this we have to check before any CRC and stop unpacking the frame
969  int s = dhc.getFixedSize();
970  if (len != s && s != 0) {
971  if (!(m_suppressErrorMask[c_nrFIX_SIZE])) {
972  B2WARNING("Fixed frame type size does not match specs" << LogVar("expected length",
973  len) << LogVar("length in data", s));
974  }
975  m_errorMask[c_nrFIX_SIZE] = true;
976  if (!m_continueOnError) return;
977  }
978  }
979 
980  // What do we do with wrong checksum frames? As we do not know WHAT is wrong, we have to skip them alltogether.
981  // As they might contain HEADER Info, we might better skip the processing of the full package, too.
982  dhc.check_crc(m_errorMask, m_suppressErrorMask[c_nrDHE_CRC]);
983  if (!m_continueOnError && m_errorMask[c_nrDHE_CRC]) {
984  // if CRC is wrong, we cannot rely on the content of the frame, thus skipping is the best option
985  return;
986  }
987 
988  unsigned int eventNrOfThisFrame = dhc.getEventNrLo();
989  int frame_type = dhc.getFrameType();
990 
991  if (Frame_Number == 0) {
992  if (m_formatBonnDAQ) {
993  if (frame_type != EDHCFrameHeaderDataType::c_DHC_START) {
994  if (!(m_suppressErrorMask[c_nrEVENT_STRUCT])) B2WARNING("This looks not like BonnDAQ format.");
995  m_errorMask[c_nrEVENT_STRUCT] = true;
996 // if (!m_continueOnError) return; // requires more testing
997  }
998  } else {
999  if (frame_type == EDHCFrameHeaderDataType::c_DHC_START) {
1000  if (!(m_suppressErrorMask[c_nrEVENT_STRUCT]))
1001  B2WARNING("This looks like BonnDAQ or old Desy 2013/14 testbeam format. Please use formatBonnDAQ or the pxdUnpackerDesy1314 module.");
1002  m_errorMask[c_nrEVENT_STRUCT] = true;
1003 // if (!m_continueOnError) return; // requires more testing
1004  }
1005  }
1006  }
1007 
1008  if (!m_formatBonnDAQ) {
1009  if (Frame_Number == 1) {
1010  if (frame_type == EDHCFrameHeaderDataType::c_DHC_START) {
1011  isFakedData_event = dhc.data_dhc_start_frame->isFakedData();
1012  }
1013  }
1014 
1015  // please check if this mask is suitable. At least here we are limited by the 16 bit trigger number in the DHH packet header.
1016  // we can use more bits in the DHC and DHE START Frame
1017  if ((eventNrOfThisFrame & 0xFFFF) != (m_meta_event_nr & 0xFFFF)) {
1018  if (!isFakedData_event) {
1019  if (!(m_suppressErrorMask[c_nrMETA_MM])) {
1020  B2WARNING("Event Numbers do not match for this frame");
1021  B2DEBUG(29, "Event Numbers do not match for this frame" <<
1022  LogVar("Event nr in frame $", static_cast < std::ostringstream
1023  && >(std::ostringstream() << hex << eventNrOfThisFrame).str()) <<
1024  LogVar("Event nr in MetaInfo (bits masked) $",
1025  static_cast < std::ostringstream && >(std::ostringstream() << hex << m_meta_event_nr).str()));
1026  }
1027  m_errorMask[c_nrMETA_MM] = true;
1028 // if (!m_continueOnError) return; // requires more testing
1029  }
1030  }
1031 
1032  if (Frame_Number > 1 && Frame_Number < Frames_in_event - 1) {
1033  if (countedDHEStartFrames != countedDHEEndFrames + 1)
1034  if (frame_type != EDHCFrameHeaderDataType::c_ONSEN_ROI && frame_type != EDHCFrameHeaderDataType::c_DHE_START) {
1035  if (!(m_suppressErrorMask[c_nrDATA_OUTSIDE])) B2WARNING("Data Frame outside a DHE START/END");
1036  m_errorMask[c_nrDATA_OUTSIDE] = true;
1037 // if (!m_continueOnError) return; // requires more testing
1038  }
1039  }
1040  }
1041 
1042  // TODO How do we handle Frames where Error Bit is set in header?
1043  // Currently there is no documentation what it actually means... ony an error bit is set (below)
1044  // the following errors must be "accepted", as all firmware sets it wrong fro Ghost frames.
1045  if (hw->getErrorFlag()) {
1046  if (frame_type != EDHCFrameHeaderDataType::c_GHOST) {
1047  m_errorMask[c_nrHEADER_ERR] = true;// TODO this should have some effect ... when does it mean something? documentation missing
1048  }
1049  } else {
1050  if (frame_type == EDHCFrameHeaderDataType::c_GHOST) {
1051  m_errorMask[c_nrHEADER_ERR_GHOST] = true;
1052  }
1053  }
1054 
1055  switch (frame_type) {
1056  case EDHCFrameHeaderDataType::c_DHP_RAW: {
1057 
1059  if (currentDHEID != dhc.data_direct_readout_frame_raw->getDHEId()) {
1060  if (!(m_suppressErrorMask[c_nrDHE_START_ID])) {
1061  B2WARNING("DHE ID from DHE Start and this frame do not match");
1062  B2DEBUG(29, "DHE ID from DHE Start and this frame do not match" <<
1063  LogVar("DHEID in this frame $", static_cast < std::ostringstream
1064  && >(std::ostringstream() << hex << dhc.data_direct_readout_frame_raw->getDHEId()).str()) <<
1065  LogVar("DHEID expected $", static_cast < std::ostringstream && >(std::ostringstream() << hex << currentDHEID).str()));
1066  }
1067  m_errorMask[c_nrDHE_START_ID] = true;
1068  }
1069  dhc.check_crc(m_errorMask, m_suppressErrorMask[c_nrDHE_CRC]);
1070  found_mask_active_dhp |= 1 << dhc.data_direct_readout_frame->getDHPPort();
1071 
1072  unpack_dhp_raw(data, len - 4,
1075  currentVxdId);
1076 
1077  break;
1078  };
1079  case EDHCFrameHeaderDataType::c_ONSEN_DHP:
1080  // Set the counted size invalid if negativ, needs a large negative value because we are adding up to that
1081  cancheck_countedBytesInDHC = false;
1082  cancheck_countedBytesInDHE = false;
1083  [[fallthrough]];
1084  case EDHCFrameHeaderDataType::c_DHP_ZSD: {
1085 
1087  if (isUnfiltered_event) {
1088  if (frame_type == EDHCFrameHeaderDataType::c_ONSEN_DHP) m_errorMask[c_nrSENDALL_TYPE] = true;
1089  } else {
1090  if (frame_type == EDHCFrameHeaderDataType::c_DHP_ZSD) m_errorMask[c_nrNOTSENDALL_TYPE] = true;
1091  }
1092 
1093  // dhc.data_direct_readout_frame->check_error(m_errorMask);
1094 
1095  if (currentDHEID != dhc.data_direct_readout_frame_raw->getDHEId()) {
1096  if (!(m_suppressErrorMask[c_nrDHE_START_ID])) {
1097  B2WARNING("DHE ID from DHE Start and this frame do not match");
1098  B2DEBUG(29, "DHE ID from DHE Start and this frame do not match" <<
1099  LogVar("DHEID in this frame $", static_cast < std::ostringstream
1100  && >(std::ostringstream() << hex << dhc.data_direct_readout_frame_raw->getDHEId()).str()) <<
1101  LogVar("DHEID expected $", static_cast < std::ostringstream && >(std::ostringstream() << hex << currentDHEID).str()));
1102  }
1103  m_errorMask[c_nrDHE_START_ID] = true;
1104  }
1105  dhc.check_crc(m_errorMask, m_suppressErrorMask[c_nrDHE_CRC]);
1106  found_mask_active_dhp |= 1 << dhc.data_direct_readout_frame->getDHPPort();
1107  if (m_checkPaddingCRC) dhc.check_padding(m_errorMask); // isUnfiltered_event
1108 
1109 
1110  unpack_dhp_v01(data, len - 4,
1111  dhe_first_readout_frame_id_lo,
1115  currentVxdId, daqpktstat);
1116 
1117  break;
1118  };
1119  case EDHCFrameHeaderDataType::c_ONSEN_FCE:
1120  // Set the counted size invalid if negativ, needs a large negative value because we are adding up to that
1121  cancheck_countedBytesInDHC = false;
1122  cancheck_countedBytesInDHE = false;
1123  [[fallthrough]];
1124  case EDHCFrameHeaderDataType::c_FCE_RAW: {
1125  if (!(m_suppressErrorMask[c_nrUNEXPECTED_FRAME_TYPE])) B2WARNING("Unexpected Frame Type (Clustering FCE)");
1126  m_errorMask[c_nrUNEXPECTED_FRAME_TYPE] = true;
1127  if (m_verbose) hw->print();
1128  if (isUnfiltered_event) {
1129  if (frame_type == EDHCFrameHeaderDataType::c_ONSEN_FCE) {
1130  // TODO add error message
1131  m_errorMask[c_nrSENDALL_TYPE] = true;
1132  }
1133  } else {
1134  if (frame_type == EDHCFrameHeaderDataType::c_FCE_RAW) {
1135  // TODO add error message
1136  m_errorMask[c_nrNOTSENDALL_TYPE] = true;
1137  }
1138  }
1139 
1140  if (currentDHEID != dhc.data_direct_readout_frame_raw->getDHEId()) {
1141  if (!(m_suppressErrorMask[c_nrDHE_START_ID])) {
1142  B2WARNING("DHE ID from DHE Start and this frame do not match");
1143  B2DEBUG(29, "DHE ID from DHE Start and this frame do not match" <<
1144  LogVar("DHEID in this frame $", static_cast < std::ostringstream
1145  && >(std::ostringstream() << hex << dhc.data_direct_readout_frame_raw->getDHEId()).str()) <<
1146  LogVar("DHEID expected $", static_cast < std::ostringstream && >(std::ostringstream() << hex << currentDHEID).str()));
1147  }
1148  m_errorMask[c_nrDHE_START_ID] = true;
1149  }
1150  dhc.check_crc(m_errorMask, m_suppressErrorMask[c_nrDHE_CRC]);
1151  found_mask_active_dhp |= 1 << dhc.data_direct_readout_frame->getDHPPort();
1152 
1153  B2DEBUG(29, "UNPACK FCE FRAME with len $" << hex << len);
1154  unpack_fce((unsigned short*) data, len - 4, currentVxdId);
1155 
1156  break;
1157  };
1158  case EDHCFrameHeaderDataType::c_COMMODE: {
1159 
1160  if (!(m_suppressErrorMask[c_nrUNEXPECTED_FRAME_TYPE])) B2WARNING("Unexpected Frame Type (COMMODE)");
1161  m_errorMask[c_nrUNEXPECTED_FRAME_TYPE] = true;
1162 
1163  if (m_verbose) hw->print();
1164  if (currentDHEID != dhc.data_commode_frame->getDHEId()) {
1165  if (!(m_suppressErrorMask[c_nrDHE_START_ID])) {
1166  B2WARNING("DHE ID from DHE Start and this frame do not match");
1167  B2DEBUG(29, "DHE ID from DHE Start and this frame do not match" <<
1168  LogVar("DHEID in this frame $", static_cast < std::ostringstream
1169  && >(std::ostringstream() << hex << dhc.data_commode_frame->getDHEId()).str()) <<
1170  LogVar("DHEID expected $", static_cast < std::ostringstream && >(std::ostringstream() << hex << currentDHEID).str()));
1171  }
1172  m_errorMask[c_nrDHE_START_ID] = true;
1173  }
1174  dhc.check_crc(m_errorMask, m_suppressErrorMask[c_nrDHE_CRC]);
1175  break;
1176  };
1177  case EDHCFrameHeaderDataType::c_DHC_START: {
1178  countedBytesInDHC = 0;
1179  cancheck_countedBytesInDHC = true;
1180  if (isFakedData_event != dhc.data_dhc_start_frame->isFakedData()) {
1181  if (!(m_suppressErrorMask[c_nrFAKE_NO_FAKE_DATA])) B2WARNING("DHC START mixed Fake/no Fake event.");
1182  m_errorMask[c_nrFAKE_NO_FAKE_DATA] = true;
1183  }
1184  if (dhc.data_dhc_start_frame->isFakedData()) {
1185  if (!(m_suppressErrorMask[c_nrFAKE_NO_DATA_TRIG])) B2WARNING("Faked DHC START Data -> trigger without Data!");
1186  m_errorMask[c_nrFAKE_NO_DATA_TRIG] = true;
1187  } else {
1188  if (m_verbose) dhc.data_dhc_start_frame->print();
1189  }
1190 
1191 // eventNrOfOnsenTrgFrame = eventNrOfThisFrame;
1192  currentDHEID = 0xFFFFFFFF;
1193  currentVxdId = 0;
1194  currentDHCID = dhc.data_dhc_start_frame->get_dhc_id();
1195  dhc.check_crc(m_errorMask, m_suppressErrorMask[c_nrDHE_CRC]);
1196 
1197  if (m_formatBonnDAQ) eventNrOfOnsenTrgFrame = eventNrOfThisFrame;
1198 
1199  if (!isFakedData_event) {
1203  if (!(m_suppressErrorMask[c_nrMETA_MM_DHC_ERS])) {
1204  B2WARNING("DHC-Meta Experiment number mismatch");
1205  B2DEBUG(29, "DHC-Meta Experiment number mismatch" <<
1206  LogVar("DHC exp nr",
1208  LogVar("META exp nr", m_meta_experiment));
1209  }
1210  m_errorMask[c_nrMETA_MM_DHC_ERS] = true;
1211  }
1212  if (dhc.data_dhc_start_frame->get_run() != m_meta_run_nr) {
1213  if (!(m_suppressErrorMask[c_nrMETA_MM_DHC_ERS])) {
1214  B2WARNING("DHC-Meta Run number mismatch");
1215  B2DEBUG(29, "DHC-Meta Run number mismatch" <<
1216  LogVar("DHC Run nr",
1217  dhc.data_dhc_start_frame->get_run()) <<
1218  LogVar("META run nr", m_meta_run_nr));
1219  }
1220  m_errorMask[c_nrMETA_MM_DHC_ERS] = true;
1221  }
1223  if (!(m_suppressErrorMask[c_nrMETA_MM_DHC_ERS])) {
1224  B2WARNING("DHC-Meta Sub-Run number mismatch");
1225  B2DEBUG(29, "DHC-Meta Sub-Run number mismatch" <<
1226  LogVar("DHC subrun nr",
1227  dhc.data_dhc_start_frame->get_subrun()) <<
1228  LogVar("META subrun nr", m_meta_subrun_nr));
1229  }
1230  m_errorMask[c_nrMETA_MM_DHC_ERS] = true;
1231  }
1232  if ((((unsigned int)dhc.data_dhc_start_frame->getEventNrHi() << 16) | dhc.data_dhc_start_frame->getEventNrLo()) !=
1233  (m_meta_event_nr & 0xFFFFFFFF)) {
1234  if (!(m_suppressErrorMask[c_nrMETA_MM_DHC])) {
1235  B2WARNING("DHC-Meta 32 bit event number mismatch");
1236  B2DEBUG(29, "DHC-Meta 32 bit event number mismatch" <<
1237  LogVar("DHC trigger nr", (((unsigned int) dhc.data_dhc_start_frame->getEventNrHi() << 16) |
1239  LogVar("META trigger nr", (unsigned int)(m_meta_event_nr & 0xFFFFFFFF)));
1240  }
1241  m_errorMask[c_nrMETA_MM_DHC] = true;
1242  }
1243  uint32_t trig_ticks = (((unsigned int)dhc.data_dhc_start_frame->time_tag_mid & 0x7FFF) << 12) | ((unsigned int)
1245  uint32_t trig_sec = (dhc.data_dhc_start_frame->time_tag_hi * 2) ;
1246  if (dhc.data_dhc_start_frame->time_tag_mid & 0x8000) trig_sec++;
1247 
1248  if ((trig_ticks - m_meta_ticks) != 0 || (trig_sec - m_meta_sec) != 0) {
1249  m_errorMask[c_nrMETA_MM_DHC_TT] = true;
1250  if (!(m_suppressErrorMask[c_nrMETA_MM_DHC_TT])) {
1251  B2WARNING("DHC-Meta TimeTag mismatch");
1252  B2DEBUG(29, "DHC-Meta TimeTag mismatch" <<
1253  LogVar("Header Time $", static_cast < std::ostringstream && >(std::ostringstream() <<
1254  hex << dhc.data_dhc_start_frame->time_tag_hi << "." <<
1255  dhc.data_dhc_start_frame->time_tag_mid << "." <<
1257  LogVar("Meta Time $", static_cast < std::ostringstream && >(std::ostringstream() << hex << m_meta_time).str()) <<
1258  LogVar("Trigger Type", static_cast < std::ostringstream
1259  && >(std::ostringstream() << hex << (dhc.data_dhc_start_frame->time_tag_lo_and_type & 0xF)).str()) <<
1260  LogVar("Meta seconds: $", static_cast < std::ostringstream && >(std::ostringstream() << hex << m_meta_sec).str()) <<
1261  LogVar("DHC seconds $", static_cast < std::ostringstream && >(std::ostringstream() << hex << trig_sec).str()) <<
1262  LogVar("Seconds difference $", static_cast < std::ostringstream
1263  && >(std::ostringstream() << hex << (trig_sec - m_meta_sec)).str()) <<
1264  LogVar("Meta ticks from 127MHz $", static_cast < std::ostringstream && >(std::ostringstream() << hex << m_meta_ticks).str()) <<
1265  LogVar("DHC ticks from 127MHz $", static_cast < std::ostringstream && >(std::ostringstream() << hex << trig_ticks).str()) <<
1266  LogVar("Tick difference $", static_cast < std::ostringstream
1267  && >(std::ostringstream() << hex << (trig_ticks - m_meta_ticks)).str()));
1268  }
1269  } else {
1270  B2DEBUG(29, "DHC TT: $" << hex << dhc.data_dhc_start_frame->time_tag_hi << "." << dhc.data_dhc_start_frame->time_tag_mid << "." <<
1271  dhc.data_dhc_start_frame->time_tag_lo_and_type << " META " << m_meta_time << " TRG Type " <<
1273  }
1274  }
1275  mask_active_dhe = dhc.data_dhc_start_frame->get_active_dhe_mask();
1276  nr_active_dhe = nr5bits(mask_active_dhe);
1277 
1278  m_errorMaskDHC = m_errorMask; // forget about anything before this frame
1279  daqpktstat.newDHC(currentDHCID, m_errorMask);
1282 
1283  break;
1284  };
1285  case EDHCFrameHeaderDataType::c_DHE_START: {
1286  countedBytesInDHE = 0;
1287  cancheck_countedBytesInDHE = true;
1292  if (m_verbose) dhc.data_dhe_start_frame->print();
1293  dhe_first_readout_frame_id_lo = dhc.data_dhe_start_frame->getStartFrameNr();
1294  dhe_first_triggergate = dhc.data_dhe_start_frame->getTriggerGate();
1295  if (currentDHEID != 0xFFFFFFFF && (currentDHEID & 0xFFFF) >= dhc.data_dhe_start_frame->getDHEId()) {
1296  if (!(m_suppressErrorMask[c_nrDHE_WRONG_ID_SEQ])) {
1297  B2WARNING("DHH IDs are not in expected order");
1298  B2DEBUG(29, "DHH IDs are not in expected order" <<
1299  LogVar("Previous ID", (currentDHEID & 0xFFFF)) <<
1300  LogVar("Current ID", dhc.data_dhe_start_frame->getDHEId()));
1301  }
1302  m_errorMask[c_nrDHE_WRONG_ID_SEQ] = true;
1303  }
1304  currentDHEID = dhc.data_dhe_start_frame->getDHEId();
1305  dhc.check_crc(m_errorMask, m_suppressErrorMask[c_nrDHE_CRC]);
1306 
1307  if (countedDHEStartFrames > countedDHEEndFrames) {
1308  if (!(m_suppressErrorMask[c_nrDHE_START_WO_END])) B2WARNING("DHE_START without DHE_END");
1309  m_errorMask[c_nrDHE_START_WO_END] = true;
1310  }
1311  countedDHEStartFrames++;
1312 
1313  found_mask_active_dhp = 0;
1314  mask_active_dhp = dhc.data_dhe_start_frame->getActiveDHPMask();
1315 
1316  if ((((unsigned int)dhc.data_dhe_start_frame->getEventNrHi() << 16) | dhc.data_dhe_start_frame->getEventNrLo()) != (unsigned int)(
1317  m_meta_event_nr & 0xFFFFFFFF)) {
1318  if (!(m_suppressErrorMask[c_nrMETA_MM_DHE])) {
1319  B2WARNING("DHE START trigger mismatch in EVT32b/HI WORD");
1320  B2DEBUG(29, "DHE START trigger mismatch in EVT32b/HI WORD" <<
1321  LogVar("DHE Start trigger nr", (dhc.data_dhe_start_frame->getEventNrHi() << 16) | dhc.data_dhe_start_frame->getEventNrLo()) <<
1322  LogVar("Meta trigger nr", (m_meta_event_nr & 0xFFFFFFFF)));
1323  }
1324  m_errorMask[c_nrMETA_MM_DHE] = true;
1325  }
1326 // B2WARNING("DHE TT: $" << hex << dhc.data_dhe_start_frame->dhe_time_tag_hi << "." << dhc.data_dhe_start_frame->dhe_time_tag_lo <<
1327 // " META " << m_meta_time);
1328 
1329  if (currentDHEID == 0) {
1330  if (!(m_suppressErrorMask[c_nrDHE_ID_INVALID])) B2WARNING("DHE ID is invalid=0 (not initialized)");
1331  m_errorMask[c_nrDHE_ID_INVALID] = true;
1332  }
1333  // calculate the VXDID for DHE and save them for DHP unpacking
1334  {
1341  unsigned short sensor, ladder, layer;
1342  sensor = (currentDHEID & 0x1) + 1;
1343  ladder = (currentDHEID & 0x1E) >> 1; // no +1
1344  layer = ((currentDHEID & 0x20) >> 5) + 1;
1345  currentVxdId = VxdID(layer, ladder, sensor);
1346  if (ladder == 0 || (layer == 1 && ladder > 8) || (layer == 2 && ladder > 12)) {
1347  if (!(m_suppressErrorMask[c_nrDHE_ID_INVALID])) {
1348  B2WARNING("DHE ID is invalid");
1349  B2DEBUG(29, "DHE ID is invalid" <<
1350  LogVar("DHE ID", currentDHEID) <<
1351  LogVar("Layer", layer) <<
1352  LogVar("Ladder", ladder) <<
1353  LogVar("Sensor", sensor));
1354  }
1355  m_errorMask[c_nrDHE_ID_INVALID] = true;
1356  }
1357  }
1358 
1359  m_errorMaskDHE = m_errorMask; // forget about anything before this frame
1360  if (daqpktstat.dhc_size() > 0) {
1361  // if no DHC has been defined yet, do nothing!
1362  daqpktstat.dhc_back().newDHE(currentVxdId, currentDHEID, m_errorMask, dhe_first_triggergate, dhe_first_readout_frame_id_lo);
1363  }
1364  break;
1365  };
1366  case EDHCFrameHeaderDataType::c_GHOST:
1367  if (m_verbose) dhc.data_ghost_frame->print();
1368  if (currentDHEID != dhc.data_ghost_frame->getDHEId()) {
1369  if (!(m_suppressErrorMask[c_nrDHE_START_ID])) {
1370  B2WARNING("DHE ID from DHE Start and this frame do not match");
1371  B2DEBUG(29, "Start ID $" << hex << currentDHEID << " != $" << dhc.data_ghost_frame->getDHEId());
1372  }
1373  m_errorMask[c_nrDHE_START_ID] = true;
1374  }
1376  found_mask_active_dhp |= 1 << dhc.data_ghost_frame->getDHPPort();
1377 
1378  //found_mask_active_dhp = mask_active_dhp;/// TODO Workaround for DESY TB 2016 doesnt work
1379 
1380  dhc.check_crc(m_errorMask, m_suppressErrorMask[c_nrDHE_CRC]);
1381 
1382  break;
1383  case EDHCFrameHeaderDataType::c_DHC_END: {
1384  if (dhc.data_dhc_end_frame->isFakedData() != isFakedData_event) {
1385  if (!(m_suppressErrorMask[c_nrFAKE_NO_FAKE_DATA])) B2WARNING("DHC END mixed Fake/no Fake event.");
1386  m_errorMask[c_nrFAKE_NO_FAKE_DATA] = true;
1387  }
1388  if (dhc.data_dhc_end_frame->isFakedData()) {
1389  if (!(m_suppressErrorMask[c_nrFAKE_NO_DATA_TRIG])) B2WARNING("Faked DHC END Data -> trigger without Data!");
1390  m_errorMask[c_nrFAKE_NO_DATA_TRIG] = true;
1391  } else {
1392  if (m_verbose) dhc.data_dhc_end_frame->print();
1393  }
1394 
1395  if (!isFakedData_event) {
1396  if (dhc.data_dhc_end_frame->get_dhc_id() != currentDHCID) {
1397  if (!(m_suppressErrorMask[c_nrDHC_DHCID_START_END_MM])) {
1398  B2WARNING("DHC ID Mismatch between Start and End");
1399  B2DEBUG(29, "DHC ID Mismatch between Start and End $" << std::hex <<
1400  currentDHCID << "!=$" << dhc.data_dhc_end_frame->get_dhc_id());
1401  }
1402  m_errorMask[c_nrDHC_DHCID_START_END_MM] = true;
1403  }
1404  int w;
1405  w = dhc.data_dhc_end_frame->get_words() * 4;
1406  if (cancheck_countedBytesInDHC) {
1407  if (countedBytesInDHC != w) {
1408  if (!(m_suppressErrorMask[c_nrDHC_WIE])) {
1409  B2WARNING("Number of Words in DHC END does not match");
1410  B2DEBUG(29, "Number of Words in DHC END does not match: WIE $" << hex << countedBytesInDHC << " != DHC END $" << hex << w);
1411  }
1412  m_errorMask[c_nrDHC_WIE] = true;
1413  } else {
1414  if (m_verbose)
1415  B2DEBUG(29, "EVT END: WIE $" << hex << countedBytesInDHC << " == DHC END $" << hex << w);
1416  }
1417  // else ... processed data -> length invalid
1418  }
1419  }
1421  if (dhc.data_dhc_end_frame->getErrorInfo() != 0) {
1422  if (!(m_suppressErrorMask[c_nrDHH_END_ERRORBITS])) B2ERROR("DHC END Error Info set to $" << hex <<
1424  m_errorMask[c_nrDHH_END_ERRORBITS] = true;
1425  }
1426  dhc.check_crc(m_errorMask, m_suppressErrorMask[c_nrDHE_CRC]);
1427  m_errorMaskDHC |= m_errorMask; // do latest updates
1428 
1429  if (daqpktstat.dhc_size() > 0) {
1430  // only is we have a DHC object... or back() is undefined
1431  // Remark, if we have a broken data (DHC_START/END) structure, we might fill the
1432  // previous DHC object ... but then the data is junk anyway
1433  daqpktstat.dhc_back().setErrorMask(m_errorMaskDHC);
1434  //B2DEBUG(98,"** DHC "<<currentDHCID<<" Raw"<<dhc.data_dhc_end_frame->get_words() * 4 <<" Red"<<countedBytesInDHC);
1435  daqpktstat.dhc_back().setCounters(dhc.data_dhc_end_frame->get_words() * 4, countedBytesInDHC);
1437  }
1438  m_errorMaskDHC = 0;
1439  currentDHEID = 0xFFFFFFFF;
1440  currentDHCID = 0xFFFFFFFF;
1441  currentVxdId = 0;
1442  break;
1443  };
1444  case EDHCFrameHeaderDataType::c_DHE_END: {
1445  if (m_verbose) dhc.data_dhe_end_frame->print();
1446  if (currentDHEID != dhc.data_dhe_end_frame->getDHEId()) {
1447  if (!(m_suppressErrorMask[c_nrDHE_START_END_ID])) {
1448  B2WARNING("DHE ID from DHE Start and this frame do not match");
1449  B2DEBUG(29, "DHE ID from DHE Start and this frame do not match $" << hex << currentDHEID << " != $" <<
1450  dhc.data_dhe_end_frame->getDHEId());
1451  }
1452  m_errorMask[c_nrDHE_START_END_ID] = true;
1453  }
1455  if (dhc.data_dhe_end_frame->getErrorInfo() != 0) {
1456  if (!(m_suppressErrorMask[c_nrDHH_END_ERRORBITS])) B2ERROR("DHE END Error Info set to $" << hex <<
1458  m_errorMask[c_nrDHH_END_ERRORBITS] = true;
1459  }
1460  dhc.check_crc(m_errorMask, m_suppressErrorMask[c_nrDHE_CRC]);
1461  if (found_mask_active_dhp != mask_active_dhp) {
1462  if (!(m_suppressErrorMask[c_nrDHP_ACTIVE])) {
1463  B2WARNING("DHE_END: DHP active mask differs from found data");
1464  B2DEBUG(29, "DHE_END: DHP active mask differs from found data $" << hex << mask_active_dhp << " != $" << hex <<
1465  found_mask_active_dhp
1466  << " mask of found dhp/ghost frames");
1467  }
1468  m_errorMask[c_nrDHP_ACTIVE] = true;
1469  }
1470  countedDHEEndFrames++;
1471  if (countedDHEStartFrames < countedDHEEndFrames) {
1472  // the other case is checked in Start
1473  if (!(m_suppressErrorMask[c_nrDHE_END_WO_START])) B2WARNING("DHE_END without DHE_START");
1474  m_errorMask[c_nrDHE_END_WO_START] = true;
1475  }
1476  {
1477  int w;
1478  w = dhc.data_dhe_end_frame->get_words() * 2;
1479  if (cancheck_countedBytesInDHE) {
1480  if (countedBytesInDHE != w) {
1481  if (!(m_suppressErrorMask[c_nrDHE_WIE])) {
1482  B2WARNING("Number of Words in DHE END does not match");
1483  B2DEBUG(29, "Number of Words in DHE END does not match: WIE $" << hex << countedBytesInDHE << " != DHE END $" << hex << w);
1484  }
1485  m_errorMask[c_nrDHE_WIE] = true;
1486  } else {
1487  if (m_verbose)
1488  B2DEBUG(29, "EVT END: WIE $" << hex << countedBytesInDHE << " == DHE END $" << hex << w);
1489  }
1490  // else ... processed data -> length invalid
1491  }
1492  }
1493  m_errorMaskDHE |= m_errorMask; // do latest updates
1494 
1495  if (daqpktstat.dhc_size() > 0) {
1496  if (daqpktstat.dhc_back().dhe_size() > 0) {
1497  // only is we have a DHC and DHE object... or back() is undefined
1498  // Remark, if we have a broken data (DHE_START/END) structure, we might fill the
1499  // previous DHE object ... but then the data is junk anyway
1500  daqpktstat.dhc_back().dhe_back().setErrorMask(m_errorMaskDHE);
1501  // B2DEBUG(98,"** DHC "<<currentDHEID<<" Raw "<<dhc.data_dhe_end_frame->get_words() * 2 <<" Red"<<countedBytesInDHE);
1502  daqpktstat.dhc_back().dhe_back().setCounters(dhc.data_dhe_end_frame->get_words() * 2, countedBytesInDHE);
1504  }
1505  }
1506  m_errorMaskDHE = 0;
1507  currentDHEID |= 0xFF000000;// differenciate from 0xFFFFFFFFF as initial value
1508  currentVxdId = 0;
1509  break;
1510  };
1511  case EDHCFrameHeaderDataType::c_ONSEN_ROI:
1512  if (m_verbose) dhc.data_onsen_roi_frame->print();
1513  dhc.data_onsen_roi_frame->check_error(m_errorMask, len, m_suppressErrorMask[c_nrROI_PACKET_INV_SIZE]);
1515  dhc.check_crc(m_errorMask, m_suppressErrorMask[c_nrDHE_CRC]);
1516  if (!m_doNotStore) {
1517  //dhc.data_onsen_roi_frame->save(m_storeROIs, len, (unsigned int*) data);
1518  // void save(StoreArray<PXDRawROIs>& sa, unsigned int length, unsigned int* data) const
1519  // 4 byte header, ROIS (n*8), 4 byte copy of inner CRC, 4 byte outer CRC
1520  if (len >= dhc.data_onsen_roi_frame->getMinSize()) {
1521  //if ((len - dhc.data_onsen_roi_frame->getMinSize()) % 8 != 0) {
1522  // error checking in check_error() above, this is only for dump-ing
1523  // dump_roi(data, len - 4); // dump ROI payload, minus CRC
1524  //}
1525  unsigned int l;
1526  l = (len - dhc.data_onsen_roi_frame->getMinSize()) / 8;
1527  // Endian swapping is done in Contructor of RawRoi object
1528  m_storeROIs.appendNew(l, &((unsigned int*) data)[1]);
1529  }
1530  }
1531  break;
1532  case EDHCFrameHeaderDataType::c_ONSEN_TRG:
1533  eventNrOfOnsenTrgFrame = eventNrOfThisFrame;
1534  if (dhc.data_onsen_trigger_frame->get_trig_nr1() != (unsigned int)(m_meta_event_nr & 0xFFFFFFFF)) {
1535  if (!(m_suppressErrorMask[c_nrMETA_MM_ONS_HLT])) {
1536  B2WARNING("Trigger Frame HLT Trigger Nr mismatch");
1537  B2DEBUG(29, "Trigger Frame HLT Trigger Nr mismatch: HLT $" <<
1538  dhc.data_onsen_trigger_frame->get_trig_nr1() << " META " << (m_meta_event_nr & 0xFFFFFFFF));
1539  }
1540  m_errorMask[c_nrMETA_MM_ONS_HLT] = true;
1541  }
1545  if (!(m_suppressErrorMask[c_nrMETA_MM_ONS_HLT])) {
1546  B2WARNING("Trigger Frame HLT Exp/Run/Subrun Nr mismatch");
1547  B2DEBUG(29, "Trigger Frame HLT Exp/Run/Subrun Nr mismatch: Exp HLT $" <<
1549  " Run HLT $" << dhc.data_onsen_trigger_frame->get_run1() << " META " << m_meta_run_nr <<
1550  " Subrun HLT $" << dhc.data_onsen_trigger_frame->get_subrun1() << " META " << m_meta_subrun_nr);
1551  }
1552  m_errorMask[c_nrMETA_MM_ONS_HLT] = true;
1553  }
1554 
1556  if (dhc.data_onsen_trigger_frame->get_trig_nr2() != (unsigned int)(m_meta_event_nr & 0xFFFFFFFF)) {
1557  if (!(m_suppressErrorMask[c_nrMETA_MM_ONS_DC])) {
1558  B2WARNING("Trigger Frame DATCON Trigger Nr mismatch");
1559  B2DEBUG(29, "Trigger Frame DATCON Trigger Nr mismatch: DC $" <<
1560  dhc.data_onsen_trigger_frame->get_trig_nr2() << " META " << (m_meta_event_nr & 0xFFFFFFFF));
1561  }
1562  m_errorMask[c_nrMETA_MM_ONS_DC] = true;
1563  }
1567  if (!(m_suppressErrorMask[c_nrMETA_MM_ONS_DC])) {
1568  B2WARNING("Trigger Frame DATCON Exp/Run/Subrun Nr mismatch");
1569  B2DEBUG(29, "Trigger Frame DATCON Exp/Run/Subrun Nr mismatch: Exp DC $" <<
1571  " Run DC $" << dhc.data_onsen_trigger_frame->get_run2() << " META " << m_meta_run_nr <<
1572  " Subrun DC $" << dhc.data_onsen_trigger_frame->get_subrun2() << " META " << m_meta_subrun_nr);
1573  }
1574  m_errorMask[c_nrMETA_MM_ONS_DC] = true;
1575  }
1576  }
1577 
1578 // 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);
1579 
1582  m_suppressErrorMask[c_nrMERGER_TRIGNR]);
1583  dhc.check_crc(m_errorMask, m_suppressErrorMask[c_nrDHE_CRC]);
1584  if (Frame_Number != 0) {
1585  if (!(m_suppressErrorMask[c_nrEVENT_STRUCT])) B2WARNING("ONSEN TRG Frame must be the first one.");
1586  m_errorMask[c_nrEVENT_STRUCT] = true;
1587  }
1588  isUnfiltered_event = dhc.data_onsen_trigger_frame->is_SendUnfiltered();
1589  if (isUnfiltered_event) m_sendunfiltered++;
1592  break;
1593  default:
1594  if (!(m_suppressErrorMask[c_nrDHC_UNKNOWN])) B2WARNING("UNKNOWN DHC frame type");
1595  m_errorMask[c_nrDHC_UNKNOWN] = true;
1596  if (m_verbose) hw->print();
1597  break;
1598  }
1599 
1600  if (eventNrOfThisFrame != eventNrOfOnsenTrgFrame && !isFakedData_event) {
1601  if (!(m_suppressErrorMask[c_nrFRAME_TNR_MM])) {
1602  B2WARNING("Frame TrigNr != ONSEN Trig Nr");
1603  B2DEBUG(29, "Frame TrigNr != ONSEN Trig Nr $" << hex << eventNrOfThisFrame << " != $" << eventNrOfOnsenTrgFrame);
1604  }
1605  m_errorMask[c_nrFRAME_TNR_MM] = true;
1606  }
1607 
1608  if (Frame_Number == 0) {
1610  if (frame_type != EDHCFrameHeaderDataType::c_ONSEN_TRG) {
1611  if (!m_formatBonnDAQ) {
1612  if (!(m_suppressErrorMask[c_nrONSEN_TRG_FIRST])) B2WARNING("First frame is not a ONSEN Trigger frame");
1613  m_errorMask[c_nrONSEN_TRG_FIRST] = true;
1614  }
1615  }
1616  } else { // (Frame_Number != 0 &&
1618  if (frame_type == EDHCFrameHeaderDataType::c_ONSEN_TRG) {
1619  if (!(m_suppressErrorMask[c_nrONSEN_TRG_FIRST])) B2WARNING("More than one ONSEN Trigger frame");
1620  m_errorMask[c_nrONSEN_TRG_FIRST] = true;
1621  }
1622  }
1623 
1624  if (!m_formatBonnDAQ) {
1625  if (Frame_Number == 1) {
1627  if (frame_type != EDHCFrameHeaderDataType::c_DHC_START) {
1628  if (!(m_suppressErrorMask[c_nrDHC_START_SECOND])) B2WARNING("Second frame is not a DHC start of subevent frame");
1629  m_errorMask[c_nrDHC_START_SECOND] = true;
1630  }
1631  } else { // (Frame_Number != 0 &&
1633  if (frame_type == EDHCFrameHeaderDataType::c_DHC_START) {
1634  if (!(m_suppressErrorMask[c_nrDHC_START_SECOND])) B2WARNING("More than one DHC start of subevent frame");
1635  m_errorMask[c_nrDHC_START_SECOND] = true;
1636  }
1637  }
1638  }
1639 
1640  if (Frame_Number == Frames_in_event - 1) {
1642  if (frame_type != EDHCFrameHeaderDataType::c_DHC_END) {
1643  if (!(m_suppressErrorMask[c_nrDHC_END_MISS])) B2WARNING("Last frame is not a DHC end of subevent frame");
1644  m_errorMask[c_nrDHC_END_MISS] = true;
1645  }
1646 
1648  if (countedDHEStartFrames != countedDHEEndFrames || countedDHEStartFrames != nr_active_dhe) {
1649  if (!(m_suppressErrorMask[c_nrDHE_ACTIVE]) || !(m_suppressErrorMask[c_nrDHE_START_WO_END])
1650  || !(m_suppressErrorMask[c_nrDHE_END_WO_START])) {
1651  B2WARNING("The number of DHE Start/End does not match the number of active DHE in DHC Header!");
1652  B2DEBUG(29, "The number of DHE Start/End does not match the number of active DHE in DHC Header! Header: " << nr_active_dhe <<
1653  " Start: " << countedDHEStartFrames << " End: " << countedDHEEndFrames << " Mask: $" << hex << mask_active_dhe << " in Event Nr " <<
1654  eventNrOfThisFrame);
1655  }
1656  if (countedDHEStartFrames == countedDHEEndFrames) m_errorMask[c_nrDHE_ACTIVE] = true;
1657  if (countedDHEStartFrames > countedDHEEndFrames) m_errorMask[c_nrDHE_START_WO_END] = true;
1658  if (countedDHEStartFrames < countedDHEEndFrames) m_errorMask[c_nrDHE_END_WO_START] = true;
1659  }
1660 
1661  } else { // (Frame_Number != Frames_in_event - 1 &&
1663  if (frame_type == EDHCFrameHeaderDataType::c_DHC_END) {
1664  if (!(m_suppressErrorMask[c_nrDHC_END_DBL])) B2WARNING("More than one DHC end of subevent frame");
1665  m_errorMask[c_nrDHC_END_DBL] = true;
1666  }
1667  }
1668 
1669  if (!m_formatBonnDAQ) {
1671  if (Frame_Number == 2 && nr_active_dhe != 0 && frame_type != EDHCFrameHeaderDataType::c_DHE_START) {
1672  if (!(m_suppressErrorMask[c_nrDHE_START_THIRD])) B2WARNING("Third frame is not a DHE start frame");
1673  m_errorMask[c_nrDHE_START_THIRD] = true;
1674  }
1675  }
1676 
1677  if (frame_type != EDHCFrameHeaderDataType::c_ONSEN_ROI && frame_type != EDHCFrameHeaderDataType::c_ONSEN_TRG) {
1678  // actually, they should not be withing Start and End, but better be sure.
1679  countedBytesInDHC += len;
1680  countedBytesInDHE += len;
1681  }
1682  B2DEBUG(29, "DHC/DHE $" << hex << countedBytesInDHC << ", $" << hex << countedBytesInDHE);
1683 }
1684 
1685 
1686 void PXDUnpackerModule::unpack_dhc_frame_v10(void* data, const int len, const int Frame_Number, const int Frames_in_event,
1687  PXDDAQPacketStatus& daqpktstat)
1688 {
1692  static unsigned int eventNrOfOnsenTrgFrame = 0;
1693  static int countedBytesInDHC = 0;
1694  static bool cancheck_countedBytesInDHC = false;
1695  static int countedBytesInDHE = 0;
1696  static bool cancheck_countedBytesInDHE = false;
1697  static int countedDHEStartFrames = 0;
1698  static int countedDHEEndFrames = 0;
1699  static int mask_active_dhe = 0;// DHE mask (5 bit)
1700  static int nr_active_dhe =
1701  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?
1702  static int mask_active_dhp = 0;// DHP active mask, 4 bit, per current DHE
1703  static int found_mask_active_dhp = 0;// mask which DHP send data and check on DHE END frame if it matches
1704  static int found_good_mask_active_dhp = 0;// mask which DHP send useful data
1705  static unsigned int dhe_first_readout_frame_id_lo = 0;
1706  // cppcheck-suppress variableScope
1707  static unsigned int dhe_first_triggergate = 0;
1708  static unsigned int currentDHCID = 0xFFFFFFFF;
1709  static unsigned int currentDHEID = 0xFFFFFFFF;
1710  static unsigned int currentVxdId = 0;
1711  static bool isFakedData_event = false;
1712  static bool isUnfiltered_event = false;
1713 
1714 
1715  if (Frame_Number == 0) {
1716  // We reset the counters on the first event
1717  // we do this before any other check is done
1718  eventNrOfOnsenTrgFrame = 0;
1719  countedDHEStartFrames = 0;
1720  countedDHEEndFrames = 0;
1721  countedBytesInDHC = 0;
1722  cancheck_countedBytesInDHC = false;
1723  countedBytesInDHE = 0;
1724  cancheck_countedBytesInDHE = false;
1725  currentDHCID = 0xFFFFFFFF;
1726  currentDHEID = 0xFFFFFFFF;
1727  currentVxdId = 0;
1728  isUnfiltered_event = false;
1729  isFakedData_event = false;
1730  mask_active_dhe = 0;
1731  nr_active_dhe = 0;
1732  mask_active_dhp = 0;
1733  found_mask_active_dhp = 0;
1734  found_good_mask_active_dhp = 0;
1735  }
1736 
1738 
1739  dhc_frames dhc;
1740  dhc.set(data, hw->getFrameType(), len);
1741 
1742  {
1743  // if a fixed size frame has a different length, how can we rely on its content???
1744  // AND we could by typecasting access memory beyond end of data (but very unlikely)
1745  // for that reason this we have to check before any CRC and stop unpacking the frame
1746  int s = dhc.getFixedSize();
1747  if (len != s && s != 0) {
1748  if (!(m_suppressErrorMask[c_nrFIX_SIZE])) {
1749  B2WARNING("Fixed frame type size does not match specs" << LogVar("expected length",
1750  len) << LogVar("length in data", s));
1751  }
1752  m_errorMask[c_nrFIX_SIZE] = true;
1753  if (!m_continueOnError) return;
1754  }
1755  }
1756 
1757  // What do we do with wrong checksum frames? As we do not know WHAT is wrong, we have to skip them alltogether.
1758  // As they might contain HEADER Info, we might better skip the processing of the full package, too.
1759  dhc.check_crc(m_errorMask, m_suppressErrorMask[c_nrDHE_CRC]);
1760  if (!m_continueOnError && m_errorMask[c_nrDHE_CRC]) {
1761  // if CRC is wrong, we cannot rely on the content of the frame, thus skipping is the best option
1762  return;
1763  }
1764 
1765  unsigned int eventNrOfThisFrame = dhc.getEventNrLo();
1766  int frame_type = dhc.getFrameType();
1767 
1768  if (Frame_Number == 0) {
1769  if (m_formatBonnDAQ) {
1770  if (frame_type != EDHCFrameHeaderDataType::c_DHC_START) {
1771  if (!(m_suppressErrorMask[c_nrEVENT_STRUCT])) B2WARNING("This looks not like BonnDAQ format.");
1772  m_errorMask[c_nrEVENT_STRUCT] = true;
1773 // if (!m_continueOnError) return; // requires more testing
1774  }
1775  } else {
1776  if (frame_type == EDHCFrameHeaderDataType::c_DHC_START) {
1777  if (!(m_suppressErrorMask[c_nrEVENT_STRUCT]))
1778  B2WARNING("This looks like BonnDAQ or old Desy 2013/14 testbeam format. Please use formatBonnDAQ or the pxdUnpackerDesy1314 module.");
1779  m_errorMask[c_nrEVENT_STRUCT] = true;
1780 // if (!m_continueOnError) return; // requires more testing
1781  }
1782  }
1783  }
1784 
1785  if (!m_formatBonnDAQ) {
1786  if (Frame_Number == 1) {
1787  if (frame_type == EDHCFrameHeaderDataType::c_DHC_START) {
1788  isFakedData_event = dhc.data_dhc_start_frame->isFakedData();
1789  }
1790  }
1791 
1792  // please check if this mask is suitable. At least here we are limited by the 16 bit trigger number in the DHH packet header.
1793  // we can use more bits in the DHC and DHE START Frame
1794  if ((eventNrOfThisFrame & 0xFFFF) != (m_meta_event_nr & 0xFFFF)) {
1795  if (!isFakedData_event) {
1796  if (!(m_suppressErrorMask[c_nrMETA_MM])) {
1797  B2WARNING("Event Numbers do not match for this frame");
1798  B2DEBUG(29, "Event Numbers do not match for this frame" <<
1799  LogVar("Event nr in frame $", static_cast < std::ostringstream
1800  && >(std::ostringstream() << hex << eventNrOfThisFrame).str()) <<
1801  LogVar("Event nr in MetaInfo (bits masked) $",
1802  static_cast < std::ostringstream && >(std::ostringstream() << hex << m_meta_event_nr).str()));
1803  }
1804  m_errorMask[c_nrMETA_MM] = true;
1805 // if (!m_continueOnError) return; // requires more testing
1806  }
1807  }
1808 
1809  if (Frame_Number > 1 && Frame_Number < Frames_in_event - 1) {
1810  if (countedDHEStartFrames != countedDHEEndFrames + 1)
1811  if (frame_type != EDHCFrameHeaderDataType::c_ONSEN_ROI && frame_type != EDHCFrameHeaderDataType::c_DHE_START) {
1812  if (!(m_suppressErrorMask[c_nrDATA_OUTSIDE])) B2WARNING("Data Frame outside a DHE START/END");
1813  m_errorMask[c_nrDATA_OUTSIDE] = true;
1814 // if (!m_continueOnError) return; // requires more testing
1815  }
1816  }
1817  }
1818 
1819  // TODO How do we handle Frames where Error Bit is set in header?
1820  // Currently there is no documentation what it actually means... only an error bit is set (below)
1821  // the following errors must be "accepted", as all firmware sets it wrong from Ghost frames.
1822  if (hw->getErrorFlag()) {
1823  if (frame_type != EDHCFrameHeaderDataType::c_GHOST) {
1824  // We get ERROR bits in header even if only one module or DHP link is missing... thus
1825  // we better filter a bit more ... but how?
1826  if (!(m_suppressErrorMask[c_nrHEADER_ERR])) B2WARNING("Error Bit set in DHE Header");
1827  m_errorMask[c_nrHEADER_ERR] = true;// TODO this should have some effect ... when does it mean something? documentation missing
1828  }
1829  } else {
1830  if (frame_type == EDHCFrameHeaderDataType::c_GHOST) {
1831  m_errorMask[c_nrHEADER_ERR_GHOST] = true;
1832  }
1833  }
1834 
1835  switch (frame_type) {
1836  case EDHCFrameHeaderDataType::c_DHP_RAW: {
1837 
1839  if (currentDHEID != dhc.data_direct_readout_frame_raw->getDHEId()) {
1840  if (!(m_suppressErrorMask[c_nrDHE_START_ID])) {
1841  B2WARNING("DHE ID from DHE Start and this frame do not match");
1842  B2DEBUG(29, "DHE ID from DHE Start and this frame do not match" <<
1843  LogVar("DHEID in this frame $", static_cast < std::ostringstream
1844  && >(std::ostringstream() << hex << dhc.data_direct_readout_frame_raw->getDHEId()).str()) <<
1845  LogVar("DHEID expected $", static_cast < std::ostringstream && >(std::ostringstream() << hex << currentDHEID).str()));
1846  }
1847  m_errorMask[c_nrDHE_START_ID] = true;
1848  }
1849  dhc.check_crc(m_errorMask, m_suppressErrorMask[c_nrDHE_CRC]);
1850  if ((found_mask_active_dhp & (1 << dhc.data_direct_readout_frame->getDHPPort())) != 0) {
1851  B2ERROR("Second DHP data packet (MEMDUMP) for " << LogVar("DHE", currentDHEID) << LogVar("DHP",
1853  }
1854 
1855  found_mask_active_dhp |= 1 << dhc.data_direct_readout_frame->getDHPPort();
1856 
1857  unpack_dhp_raw(data, len - 4,
1860  currentVxdId);
1861 
1862  break;
1863  };
1864  case EDHCFrameHeaderDataType::c_ONSEN_DHP:
1865  // Set the counted size invalid if negativ, needs a large negative value because we are adding up to that
1866  cancheck_countedBytesInDHC = false;
1867  cancheck_countedBytesInDHE = false;
1868  [[fallthrough]];
1869  case EDHCFrameHeaderDataType::c_DHP_ZSD: {
1870 
1872  if (isUnfiltered_event) {
1873  if (frame_type == EDHCFrameHeaderDataType::c_ONSEN_DHP) m_errorMask[c_nrSENDALL_TYPE] = true;
1874  } else {
1875  if (frame_type == EDHCFrameHeaderDataType::c_DHP_ZSD) m_errorMask[c_nrNOTSENDALL_TYPE] = true;
1876  }
1877 
1878  // dhc.data_direct_readout_frame->check_error(m_errorMask);
1879 
1880  if (currentDHEID != dhc.data_direct_readout_frame_raw->getDHEId()) {
1881  if (!(m_suppressErrorMask[c_nrDHE_START_ID])) {
1882  B2WARNING("DHE ID from DHE Start and this frame do not match");
1883  B2DEBUG(29, "DHE ID from DHE Start and this frame do not match" <<
1884  LogVar("DHEID in this frame $", static_cast < std::ostringstream
1885  && >(std::ostringstream() << hex << dhc.data_direct_readout_frame_raw->getDHEId()).str()) <<
1886  LogVar("DHEID expected $", static_cast < std::ostringstream && >(std::ostringstream() << hex << currentDHEID).str()));
1887  }
1888  m_errorMask[c_nrDHE_START_ID] = true;
1889  }
1890  dhc.check_crc(m_errorMask, m_suppressErrorMask[c_nrDHE_CRC]);
1891  if ((found_mask_active_dhp & (1 << dhc.data_direct_readout_frame->getDHPPort())) != 0) {
1892  B2ERROR("Second DHP data packet for " << LogVar("DHE", currentDHEID) << LogVar("DHP", dhc.data_direct_readout_frame->getDHPPort()));
1893  }
1894  found_mask_active_dhp |= 1 << dhc.data_direct_readout_frame->getDHPPort();
1895  found_good_mask_active_dhp |= 1 << dhc.data_direct_readout_frame->getDHPPort();// only this frametype has useful data
1896  if (m_checkPaddingCRC) dhc.check_padding(m_errorMask); // isUnfiltered_event
1897 
1898 
1899  unpack_dhp_v10(data, len - 4,
1900  dhe_first_readout_frame_id_lo,
1904  currentVxdId, daqpktstat);
1905 
1906  break;
1907  };
1908  case EDHCFrameHeaderDataType::c_ONSEN_FCE:
1909  // Set the counted size invalid if negativ, needs a large negative value because we are adding up to that
1910  cancheck_countedBytesInDHC = false;
1911  cancheck_countedBytesInDHE = false;
1912  [[fallthrough]];
1913  case EDHCFrameHeaderDataType::c_FCE_RAW: {
1914  if (!(m_suppressErrorMask[c_nrUNEXPECTED_FRAME_TYPE])) B2WARNING("Unexpected Frame Type (Clustering FCE)");
1915  m_errorMask[c_nrUNEXPECTED_FRAME_TYPE] = true;
1916  if (m_verbose) hw->print();
1917  if (isUnfiltered_event) {
1918  if (frame_type == EDHCFrameHeaderDataType::c_ONSEN_FCE) {
1919  // TODO add error message
1920  m_errorMask[c_nrSENDALL_TYPE] = true;
1921  }
1922  } else {
1923  if (frame_type == EDHCFrameHeaderDataType::c_FCE_RAW) {
1924  // TODO add error message
1925  m_errorMask[c_nrNOTSENDALL_TYPE] = true;
1926  }
1927  }
1928 
1929  if (currentDHEID != dhc.data_direct_readout_frame_raw->getDHEId()) {
1930  if (!(m_suppressErrorMask[c_nrDHE_START_ID])) {
1931  B2WARNING("DHE ID from DHE Start and this frame do not match");
1932  B2DEBUG(29, "DHE ID from DHE Start and this frame do not match" <<
1933  LogVar("DHEID in this frame $", static_cast < std::ostringstream
1934  && >(std::ostringstream() << hex << dhc.data_direct_readout_frame_raw->getDHEId()).str()) <<
1935  LogVar("DHEID expected $", static_cast < std::ostringstream && >(std::ostringstream() << hex << currentDHEID).str()));
1936  }
1937  m_errorMask[c_nrDHE_START_ID] = true;
1938  }
1939  dhc.check_crc(m_errorMask, m_suppressErrorMask[c_nrDHE_CRC]);
1940  if ((found_mask_active_dhp & (1 << dhc.data_direct_readout_frame->getDHPPort())) != 0) {
1941  B2ERROR("Second DHP data packet (FCE) for " << LogVar("DHE", currentDHEID) << LogVar("DHP",
1943  }
1944  found_mask_active_dhp |= 1 << dhc.data_direct_readout_frame->getDHPPort();
1945 
1946  B2DEBUG(29, "UNPACK FCE FRAME with len $" << hex << len);
1947  unpack_fce((unsigned short*) data, len - 4, currentVxdId);
1948 
1949  break;
1950  };
1951  case EDHCFrameHeaderDataType::c_COMMODE: {
1952  // this frame type has up to now not been well defined, we do not expect it until
1953  // the firmware supports clustering in hardware
1954  if (!(m_suppressErrorMask[c_nrUNEXPECTED_FRAME_TYPE])) B2WARNING("Unexpected Frame Type (COMMODE)");
1955  m_errorMask[c_nrUNEXPECTED_FRAME_TYPE] = true;
1956 
1957  if (m_verbose) hw->print();
1958  if (currentDHEID != dhc.data_commode_frame->getDHEId()) {
1959  if (!(m_suppressErrorMask[c_nrDHE_START_ID])) {
1960  B2WARNING("DHE ID from DHE Start and this frame do not match");
1961  B2DEBUG(29, "DHE ID from DHE Start and this frame do not match" <<
1962  LogVar("DHEID in this frame $", static_cast < std::ostringstream
1963  && >(std::ostringstream() << hex << dhc.data_commode_frame->getDHEId()).str()) <<
1964  LogVar("DHEID expected $", static_cast < std::ostringstream && >(std::ostringstream() << hex << currentDHEID).str()));
1965  }
1966  m_errorMask[c_nrDHE_START_ID] = true;
1967  }
1968  dhc.check_crc(m_errorMask, m_suppressErrorMask[c_nrDHE_CRC]);
1969  break;
1970  };
1971  case EDHCFrameHeaderDataType::c_DHC_START: {
1972  countedBytesInDHC = 0;
1973  cancheck_countedBytesInDHC = true;
1974  if (isFakedData_event != dhc.data_dhc_start_frame->isFakedData()) {
1975  if (!(m_suppressErrorMask[c_nrFAKE_NO_FAKE_DATA])) B2WARNING("DHC START mixed Fake/no Fake event.");
1976  m_errorMask[c_nrFAKE_NO_FAKE_DATA] = true;
1977  }
1978  if (dhc.data_dhc_start_frame->isFakedData()) {
1979  if (!(m_suppressErrorMask[c_nrFAKE_NO_DATA_TRIG])) B2WARNING("Faked DHC START Data -> trigger without Data!");
1980  m_errorMask[c_nrFAKE_NO_DATA_TRIG] = true;
1981  } else {
1982  if (m_verbose) dhc.data_dhc_start_frame->print();
1983  }
1984 
1985 // eventNrOfOnsenTrgFrame = eventNrOfThisFrame;
1986  currentDHEID = 0xFFFFFFFF;
1987  currentVxdId = 0;
1988  currentDHCID = dhc.data_dhc_start_frame->get_dhc_id();
1989  dhc.check_crc(m_errorMask, m_suppressErrorMask[c_nrDHE_CRC]);
1990 
1991  if (m_formatBonnDAQ) eventNrOfOnsenTrgFrame = eventNrOfThisFrame;
1992 
1993  if (!isFakedData_event) {
1997  if (!(m_suppressErrorMask[c_nrMETA_MM_DHC_ERS])) {
1998  B2WARNING("DHC-Meta Experiment number mismatch");
1999  B2DEBUG(29, "DHC-Meta Experiment number mismatch" <<
2000  LogVar("DHC exp nr",
2002  LogVar("META exp nr", m_meta_experiment));
2003  }
2004  m_errorMask[c_nrMETA_MM_DHC_ERS] = true;
2005  }
2006  if (dhc.data_dhc_start_frame->get_run() != m_meta_run_nr) {
2007  if (!(m_suppressErrorMask[c_nrMETA_MM_DHC_ERS])) {
2008  B2WARNING("DHC-Meta Run number mismatch");
2009  B2DEBUG(29, "DHC-Meta Run number mismatch" <<
2010  LogVar("DHC Run nr",
2011  dhc.data_dhc_start_frame->get_run()) <<
2012  LogVar("META run nr", m_meta_run_nr));
2013  }
2014  m_errorMask[c_nrMETA_MM_DHC_ERS] = true;
2015  }
2017  if (!(m_suppressErrorMask[c_nrMETA_MM_DHC_ERS])) {
2018  B2WARNING("DHC-Meta Sub-Run number mismatch");
2019  B2DEBUG(29, "DHC-Meta Sub-Run number mismatch" <<
2020  LogVar("DHC subrun nr",
2021  dhc.data_dhc_start_frame->get_subrun()) <<
2022  LogVar("META subrun nr", m_meta_subrun_nr));
2023  }
2024  m_errorMask[c_nrMETA_MM_DHC_ERS] = true;
2025  }
2026  if ((((unsigned int)dhc.data_dhc_start_frame->getEventNrHi() << 16) | dhc.data_dhc_start_frame->getEventNrLo()) !=
2027  (m_meta_event_nr & 0xFFFFFFFF)) {
2028  if (!(m_suppressErrorMask[c_nrMETA_MM_DHC])) {
2029  B2WARNING("DHC-Meta 32 bit event number mismatch");
2030  B2DEBUG(29, "DHC-Meta 32 bit event number mismatch" <<
2031  LogVar("DHC trigger nr", (((unsigned int) dhc.data_dhc_start_frame->getEventNrHi() << 16) |
2033  LogVar("META trigger nr", (unsigned int)(m_meta_event_nr & 0xFFFFFFFF)));
2034  }
2035  m_errorMask[c_nrMETA_MM_DHC] = true;
2036  }
2037  uint32_t trig_ticks = (((unsigned int)dhc.data_dhc_start_frame->time_tag_mid & 0x7FFF) << 12) | ((unsigned int)
2039  uint32_t trig_sec = (dhc.data_dhc_start_frame->time_tag_hi * 2) ;
2040  if (dhc.data_dhc_start_frame->time_tag_mid & 0x8000) trig_sec++;
2041 
2042  if ((trig_ticks - m_meta_ticks) != 0 || (trig_sec - m_meta_sec) != 0) {
2043  m_errorMask[c_nrMETA_MM_DHC_TT] = true;
2044  if (!(m_suppressErrorMask[c_nrMETA_MM_DHC_TT])) {
2045  B2WARNING("DHC-Meta TimeTag mismatch");
2046  B2DEBUG(29, "DHC-Meta TimeTag mismatch" <<
2047  LogVar("Header Time $", static_cast < std::ostringstream && >(std::ostringstream() <<
2048  hex << dhc.data_dhc_start_frame->time_tag_hi << "." <<
2049  dhc.data_dhc_start_frame->time_tag_mid << "." <<
2051  LogVar("Meta Time $", static_cast < std::ostringstream && >(std::ostringstream() << hex << m_meta_time).str()) <<
2052  LogVar("Trigger Type", static_cast < std::ostringstream
2053  && >(std::ostringstream() << hex << (dhc.data_dhc_start_frame->time_tag_lo_and_type & 0xF)).str()) <<
2054  LogVar("Meta seconds: $", static_cast < std::ostringstream && >(std::ostringstream() << hex << m_meta_sec).str()) <<
2055  LogVar("DHC seconds $", static_cast < std::ostringstream && >(std::ostringstream() << hex << trig_sec).str()) <<
2056  LogVar("Seconds difference $", static_cast < std::ostringstream
2057  && >(std::ostringstream() << hex << (trig_sec - m_meta_sec)).str()) <<
2058  LogVar("Meta ticks from 127MHz $", static_cast < std::ostringstream && >(std::ostringstream() << hex << m_meta_ticks).str()) <<
2059  LogVar("DHC ticks from 127MHz $", static_cast < std::ostringstream && >(std::ostringstream() << hex << trig_ticks).str()) <<
2060  LogVar("Tick difference $", static_cast < std::ostringstream
2061  && >(std::ostringstream() << hex << (trig_ticks - m_meta_ticks)).str()));
2062  }
2063  } else {
2064  B2DEBUG(29, "DHC TT: $" << hex << dhc.data_dhc_start_frame->time_tag_hi << "." << dhc.data_dhc_start_frame->time_tag_mid << "." <<
2065  dhc.data_dhc_start_frame->time_tag_lo_and_type << " META " << m_meta_time << " TRG Type " <<
2067  }
2068  }
2069  mask_active_dhe = dhc.data_dhc_start_frame->get_active_dhe_mask();
2070  nr_active_dhe = nr5bits(mask_active_dhe);
2071 
2072  m_errorMaskDHC = m_errorMask; // forget about anything before this frame
2073  daqpktstat.newDHC(currentDHCID, m_errorMask);
2076 
2077  break;
2078  };
2079  case EDHCFrameHeaderDataType::c_DHE_START: {
2080  countedBytesInDHE = 0;
2081  cancheck_countedBytesInDHE = true;
2086  if (m_verbose) dhc.data_dhe_start_frame->print();
2087  dhe_first_readout_frame_id_lo = dhc.data_dhe_start_frame->getStartFrameNr();
2088  dhe_first_triggergate = dhc.data_dhe_start_frame->getTriggerGate();
2089  if (currentDHEID != 0xFFFFFFFF && (currentDHEID & 0xFFFF) >= dhc.data_dhe_start_frame->getDHEId()) {
2090  if (!(m_suppressErrorMask[c_nrDHE_WRONG_ID_SEQ])) {
2091  B2WARNING("DHH IDs are not in expected order");
2092  B2DEBUG(29, "DHH IDs are not in expected order" <<
2093  LogVar("Previous ID", (currentDHEID & 0xFFFF)) <<
2094  LogVar("Current ID", dhc.data_dhe_start_frame->getDHEId()));
2095  }
2096  m_errorMask[c_nrDHE_WRONG_ID_SEQ] = true;
2097  }
2098  currentDHEID = dhc.data_dhe_start_frame->getDHEId();
2099  dhc.check_crc(m_errorMask, m_suppressErrorMask[c_nrDHE_CRC]);
2100 
2101  if (countedDHEStartFrames > countedDHEEndFrames) {
2102  if (!(m_suppressErrorMask[c_nrDHE_START_WO_END])) B2WARNING("DHE_START without DHE_END");
2103  m_errorMask[c_nrDHE_START_WO_END] = true;
2104  }
2105  countedDHEStartFrames++;
2106 
2107  found_mask_active_dhp = 0;
2108  found_good_mask_active_dhp = 0;
2109  mask_active_dhp = dhc.data_dhe_start_frame->getActiveDHPMask();
2110 
2111  if ((((unsigned int)dhc.data_dhe_start_frame->getEventNrHi() << 16) | dhc.data_dhe_start_frame->getEventNrLo()) != (unsigned int)(
2112  m_meta_event_nr & 0xFFFFFFFF)) {
2113  if (!(m_suppressErrorMask[c_nrMETA_MM_DHE])) {
2114  B2WARNING("DHE START trigger mismatch in EVT32b/HI WORD");
2115  B2DEBUG(29, "DHE START trigger mismatch in EVT32b/HI WORD" <<
2116  LogVar("DHE Start trigger nr", (dhc.data_dhe_start_frame->getEventNrHi() << 16) | dhc.data_dhe_start_frame->getEventNrLo()) <<
2117  LogVar("Meta trigger nr", (m_meta_event_nr & 0xFFFFFFFF)));
2118  }
2119  m_errorMask[c_nrMETA_MM_DHE] = true;
2120  }
2121 // B2WARNING("DHE TT: $" << hex << dhc.data_dhe_start_frame->dhe_time_tag_hi << "." << dhc.data_dhe_start_frame->dhe_time_tag_lo <<
2122 // " META " << m_meta_time);
2123 
2124  if (currentDHEID == 0) {
2125  if (!(m_suppressErrorMask[c_nrDHE_ID_INVALID])) B2WARNING("DHE ID is invalid=0 (not initialized)");
2126  m_errorMask[c_nrDHE_ID_INVALID] = true;
2127  }
2128  // calculate the VXDID for DHE and save them for DHP unpacking
2129  {
2136  unsigned short sensor, ladder, layer;
2137  sensor = (currentDHEID & 0x1) + 1;
2138  ladder = (currentDHEID & 0x1E) >> 1; // no +1
2139  layer = ((currentDHEID & 0x20) >> 5) + 1;
2140  currentVxdId = VxdID(layer, ladder, sensor);
2141  if (ladder == 0 || (layer == 1 && ladder > 8) || (layer == 2 && ladder > 12)) {
2142  if (!(m_suppressErrorMask[c_nrDHE_ID_INVALID])) {
2143  B2WARNING("DHE ID is invalid");
2144  B2DEBUG(29, "DHE ID is invalid" <<
2145  LogVar("DHE ID", currentDHEID) <<
2146  LogVar("Layer", layer) <<
2147  LogVar("Ladder", ladder) <<
2148  LogVar("Sensor", sensor));
2149  }
2150  m_errorMask[c_nrDHE_ID_INVALID] = true;
2151  }
2152  }
2153 
2154  m_errorMaskDHE = m_errorMask; // forget about anything before this frame
2155  if (daqpktstat.dhc_size() > 0) {
2156  // if no DHC has been defined yet, do nothing!
2157  daqpktstat.dhc_back().newDHE(currentVxdId, currentDHEID, m_errorMask, dhe_first_triggergate, dhe_first_readout_frame_id_lo);
2158  }
2159  break;
2160  };
2161  case EDHCFrameHeaderDataType::c_GHOST:
2162  if (m_verbose) dhc.data_ghost_frame->print();
2163  if (currentDHEID != dhc.data_ghost_frame->getDHEId()) {
2164  if (!(m_suppressErrorMask[c_nrDHE_START_ID])) {
2165  B2WARNING("DHE ID from DHE Start and this frame do not match");
2166  B2DEBUG(29, "Start ID $" << hex << currentDHEID << " != $" << dhc.data_ghost_frame->getDHEId());
2167  }
2168  m_errorMask[c_nrDHE_START_ID] = true;
2169  }
2171  if ((found_mask_active_dhp & (1 << dhc.data_ghost_frame->getDHPPort())) != 0) {
2172  B2ERROR("Second DHP data packet (GHOST) for " << LogVar("DHE", currentDHEID) << LogVar("DHP", dhc.data_ghost_frame->getDHPPort()));
2173  }
2174  found_mask_active_dhp |= 1 << dhc.data_ghost_frame->getDHPPort();
2175 
2176  dhc.check_crc(m_errorMask, m_suppressErrorMask[c_nrDHE_CRC]);
2177 
2178  break;
2179  case EDHCFrameHeaderDataType::c_DHC_END: {
2180  if (dhc.data_dhc_end_frame->isFakedData() != isFakedData_event) {
2181  if (!(m_suppressErrorMask[c_nrFAKE_NO_FAKE_DATA])) B2WARNING("DHC END mixed Fake/no Fake event.");
2182  m_errorMask[c_nrFAKE_NO_FAKE_DATA] = true;
2183  }
2184  if (dhc.data_dhc_end_frame->isFakedData()) {
2185  if (!(m_suppressErrorMask[c_nrFAKE_NO_DATA_TRIG])) B2WARNING("Faked DHC END Data -> trigger without Data!");
2186  m_errorMask[c_nrFAKE_NO_DATA_TRIG] = true;
2187  } else {
2188  if (m_verbose) dhc.data_dhc_end_frame->print();
2189  }
2190 
2191  if (!isFakedData_event) {
2192  if (dhc.data_dhc_end_frame->get_dhc_id() != currentDHCID) {
2193  if (!(m_suppressErrorMask[c_nrDHC_DHCID_START_END_MM])) {
2194  B2WARNING("DHC ID Mismatch between Start and End");
2195  B2DEBUG(29, "DHC ID Mismatch between Start and End $" << std::hex <<
2196  currentDHCID << "!=$" << dhc.data_dhc_end_frame->get_dhc_id());
2197  }
2198  m_errorMask[c_nrDHC_DHCID_START_END_MM] = true;
2199  }
2200  int w;
2201  w = dhc.data_dhc_end_frame->get_words() * 4;
2202  if (cancheck_countedBytesInDHC) {
2203  if (countedBytesInDHC != w) {
2204  if (!(m_suppressErrorMask[c_nrDHC_WIE])) {
2205  B2WARNING("Number of Words in DHC END does not match");
2206  B2DEBUG(29, "Number of Words in DHC END does not match: WIE $" << hex << countedBytesInDHC << " != DHC END $" << hex << w);
2207  }
2208  m_errorMask[c_nrDHC_WIE] = true;
2209  } else {
2210  if (m_verbose)
2211  B2DEBUG(29, "EVT END: WIE $" << hex << countedBytesInDHC << " == DHC END $" << hex << w);
2212  }
2213  // else ... processed data -> length invalid
2214  }
2215  }
2217  if (dhc.data_dhc_end_frame->getErrorInfo() != 0) {
2218  if (!(m_suppressErrorMask[c_nrDHH_END_ERRORBITS])) B2ERROR("DHC END Error Info set to $" << hex <<
2220  m_errorMask[c_nrDHH_END_ERRORBITS] = true;
2221  }
2222  dhc.check_crc(m_errorMask, m_suppressErrorMask[c_nrDHE_CRC]);
2223  m_errorMaskDHC |= m_errorMask; // do latest updates
2224 
2225  if (daqpktstat.dhc_size() > 0) {
2226  // only is we have a DHC object... or back() is undefined
2227  // Remark, if we have a broken data (DHC_START/END) structure, we might fill the
2228  // previous DHC object ... but then the data is junk anyway
2229  daqpktstat.dhc_back().setErrorMask(m_errorMaskDHC);
2230  //B2DEBUG(98,"** DHC "<<currentDHCID<<" Raw"<<dhc.data_dhc_end_frame->get_words() * 4 <<" Red"<<countedBytesInDHC);
2231  daqpktstat.dhc_back().setCounters(dhc.data_dhc_end_frame->get_words() * 4, countedBytesInDHC);
2233  }
2234  m_errorMaskDHC = 0;
2235  currentDHEID = 0xFFFFFFFF;
2236  currentDHCID = 0xFFFFFFFF;
2237  currentVxdId = 0;
2238  break;
2239  };
2240  case EDHCFrameHeaderDataType::c_DHE_END: {
2241  if (m_verbose) dhc.data_dhe_end_frame->print();
2242  if (currentDHEID != dhc.data_dhe_end_frame->getDHEId()) {
2243  if (!(m_suppressErrorMask[c_nrDHE_START_END_ID])) {
2244  B2WARNING("DHE ID from DHE Start and this frame do not match");
2245  B2DEBUG(29, "DHE ID from DHE Start and this frame do not match $" << hex << currentDHEID << " != $" <<
2246  dhc.data_dhe_end_frame->getDHEId());
2247  }
2248  m_errorMask[c_nrDHE_START_END_ID] = true;
2249  }
2251  if (dhc.data_dhe_end_frame->getErrorInfo() != 0) {
2252  if (!(m_suppressErrorMask[c_nrDHH_END_ERRORBITS])) {
2253  B2ERROR("DHE END Error Info set to $" << hex << dhc.data_dhe_end_frame->getErrorInfo());
2254  }
2255  m_errorMask[c_nrDHH_END_ERRORBITS] = true;
2256  }
2257  dhc.check_crc(m_errorMask, m_suppressErrorMask[c_nrDHE_CRC]);
2258  if (found_mask_active_dhp != mask_active_dhp) {
2259  if (!(m_suppressErrorMask[c_nrDHP_ACTIVE])) {
2260  B2WARNING("DHE_END: DHP active mask differs from found data");
2261  B2DEBUG(29, "DHE_END: DHP active mask differs from found data $" << hex << mask_active_dhp << " != $" << hex <<
2262  found_mask_active_dhp
2263  << " mask of found dhp/ghost frames");
2264  }
2265  m_errorMask[c_nrDHP_ACTIVE] = true;
2266  }
2267  countedDHEEndFrames++;
2268  if (countedDHEStartFrames < countedDHEEndFrames) {
2269  // the other case is checked in Start
2270  if (!(m_suppressErrorMask[c_nrDHE_END_WO_START])) B2WARNING("DHE_END without DHE_START");
2271  m_errorMask[c_nrDHE_END_WO_START] = true;
2272  }
2273  {
2274  int w;
2275  w = dhc.data_dhe_end_frame->get_words() * 2;
2276  if (cancheck_countedBytesInDHE) {
2277  if (countedBytesInDHE != w) {
2278  if (!(m_suppressErrorMask[c_nrDHE_WIE])) {
2279  B2WARNING("Number of Words in DHE END does not match");
2280  B2DEBUG(29, "Number of Words in DHE END does not match: WIE $" << hex << countedBytesInDHE << " != DHE END $" << hex << w);
2281  }
2282  m_errorMask[c_nrDHE_WIE] = true;
2283  } else {
2284  if (m_verbose)
2285  B2DEBUG(29, "EVT END: WIE $" << hex << countedBytesInDHE << " == DHE END $" << hex << w);
2286  }
2287  // else ... processed data -> length invalid
2288  }
2289  }
2290  m_errorMaskDHE |= m_errorMask; // do latest updates
2291 
2292  if (daqpktstat.dhc_size() > 0) {
2293  if (daqpktstat.dhc_back().dhe_size() > 0) {
2294  // only is we have a DHC and DHE object... or back() is undefined
2295  // Remark, if we have a broken data (DHE_START/END) structure, we might fill the
2296  // previous DHE object ... but then the data is junk anyway
2297  daqpktstat.dhc_back().dhe_back().setErrorMask(m_errorMaskDHE);
2298  // B2DEBUG(98,"** DHC "<<currentDHEID<<" Raw "<<dhc.data_dhe_end_frame->get_words() * 2 <<" Red"<<countedBytesInDHE);
2299  daqpktstat.dhc_back().dhe_back().setCounters(dhc.data_dhe_end_frame->get_words() * 2, countedBytesInDHE);
2300  daqpktstat.dhc_back().dhe_back().setDHPFoundMask(found_good_mask_active_dhp);
2302  }
2303  }
2304  m_errorMaskDHE = 0;
2305  currentDHEID |= 0xFF000000;// differenciate from 0xFFFFFFFFF as initial value
2306  currentVxdId = 0;
2307  break;
2308  };
2309  case EDHCFrameHeaderDataType::c_ONSEN_ROI:
2310  if (m_verbose) dhc.data_onsen_roi_frame->print();
2311  dhc.data_onsen_roi_frame->check_error(m_errorMask, len, m_suppressErrorMask[c_nrROI_PACKET_INV_SIZE]);
2313  dhc.check_crc(m_errorMask, m_suppressErrorMask[c_nrDHE_CRC]);
2314  if (!m_doNotStore) {
2315  //dhc.data_onsen_roi_frame->save(m_storeROIs, len, (unsigned int*) data);
2316  // void save(StoreArray<PXDRawROIs>& sa, unsigned int length, unsigned int* data) const
2317  // 4 byte header, ROIS (n*8), 4 byte copy of inner CRC, 4 byte outer CRC
2318  if (len >= dhc.data_onsen_roi_frame->getMinSize()) {
2319  //if ((len - dhc.data_onsen_roi_frame->getMinSize()) % 8 != 0) {
2320  // error checking in check_error() above, this is only for dump-ing
2321  // dump_roi(data, len - 4); // dump ROI payload, minus CRC
2322  //}
2323  unsigned int l;
2324  l = (len - dhc.data_onsen_roi_frame->getMinSize()) / 8;
2325  // Endian swapping is done in Contructor of RawRoi object
2326  m_storeROIs.appendNew(l, &((unsigned int*) data)[1]);
2327  }
2328  }
2329  break;
2330  case EDHCFrameHeaderDataType::c_ONSEN_TRG:
2331  eventNrOfOnsenTrgFrame = eventNrOfThisFrame;
2332  if (dhc.data_onsen_trigger_frame->get_trig_nr1() != (unsigned int)(m_meta_event_nr & 0xFFFFFFFF)) {
2333  if (!(m_suppressErrorMask[c_nrMETA_MM_ONS_HLT])) {
2334  B2WARNING("Trigger Frame HLT Trigger Nr mismatch");
2335  B2DEBUG(29, "Trigger Frame HLT Trigger Nr mismatch: HLT $" <<
2336  dhc.data_onsen_trigger_frame->get_trig_nr1() << " META " << (m_meta_event_nr & 0xFFFFFFFF));
2337  }
2338  m_errorMask[c_nrMETA_MM_ONS_HLT] = true;
2339  }
2343  if (!(m_suppressErrorMask[c_nrMETA_MM_ONS_HLT])) {
2344  B2WARNING("Trigger Frame HLT Exp/Run/Subrun Nr mismatch");
2345  B2DEBUG(29, "Trigger Frame HLT Exp/Run/Subrun Nr mismatch: Exp HLT $" <<
2347  " Run HLT $" << dhc.data_onsen_trigger_frame->get_run1() << " META " << m_meta_run_nr <<
2348  " Subrun HLT $" << dhc.data_onsen_trigger_frame->get_subrun1() << " META " << m_meta_subrun_nr);
2349  }
2350  m_errorMask[c_nrMETA_MM_ONS_HLT] = true;
2351  }
2352 
2354  if (dhc.data_onsen_trigger_frame->get_trig_nr2() != (unsigned int)(m_meta_event_nr & 0xFFFFFFFF)) {
2355  if (!(m_suppressErrorMask[c_nrMETA_MM_ONS_DC])) {
2356  B2WARNING("Trigger Frame DATCON Trigger Nr mismatch");
2357  B2DEBUG(29, "Trigger Frame DATCON Trigger Nr mismatch: DC $" <<
2358  dhc.data_onsen_trigger_frame->get_trig_nr2() << " META " << (m_meta_event_nr & 0xFFFFFFFF));
2359  }
2360  m_errorMask[c_nrMETA_MM_ONS_DC] = true;
2361  }
2365  if (!(m_suppressErrorMask[c_nrMETA_MM_ONS_DC])) {
2366  B2WARNING("Trigger Frame DATCON Exp/Run/Subrun Nr mismatch");
2367  B2DEBUG(29, "Trigger Frame DATCON Exp/Run/Subrun Nr mismatch: Exp DC $" <<
2369  " Run DC $" << dhc.data_onsen_trigger_frame->get_run2() << " META " << m_meta_run_nr <<
2370  " Subrun DC $" << dhc.data_onsen_trigger_frame->get_subrun2() << " META " << m_meta_subrun_nr);
2371  }
2372  m_errorMask[c_nrMETA_MM_ONS_DC] = true;
2373  }
2374  }
2375 
2376 // 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);
2377 
2380  m_suppressErrorMask[c_nrMERGER_TRIGNR]);
2381  dhc.check_crc(m_errorMask, m_suppressErrorMask[c_nrDHE_CRC]);
2382  if (Frame_Number != 0) {
2383  if (!(m_suppressErrorMask[c_nrEVENT_STRUCT])) B2WARNING("ONSEN TRG Frame must be the first one.");
2384  m_errorMask[c_nrEVENT_STRUCT] = true;
2385  }
2386  isUnfiltered_event = dhc.data_onsen_trigger_frame->is_SendUnfiltered();
2387  if (isUnfiltered_event) m_sendunfiltered++;
2390  break;
2391  default:
2392  if (!(m_suppressErrorMask[c_nrDHC_UNKNOWN])) B2WARNING("UNKNOWN DHC frame type");
2393  m_errorMask[c_nrDHC_UNKNOWN] = true;
2394  if (m_verbose) hw->print();
2395  break;
2396  }
2397 
2398  if (eventNrOfThisFrame != eventNrOfOnsenTrgFrame && !isFakedData_event) {
2399  if (!(m_suppressErrorMask[c_nrFRAME_TNR_MM])) {
2400  B2WARNING("Frame TrigNr != ONSEN Trig Nr");
2401  B2DEBUG(29, "Frame TrigNr != ONSEN Trig Nr $" << hex << eventNrOfThisFrame << " != $" << eventNrOfOnsenTrgFrame);
2402  }
2403  m_errorMask[c_nrFRAME_TNR_MM] = true;
2404  }
2405 
2406  if (Frame_Number == 0) {
2408  if (frame_type != EDHCFrameHeaderDataType::c_ONSEN_TRG) {
2409  if (!m_formatBonnDAQ) {
2410  if (!(m_suppressErrorMask[c_nrONSEN_TRG_FIRST])) B2WARNING("First frame is not a ONSEN Trigger frame");
2411  m_errorMask[c_nrONSEN_TRG_FIRST] = true;
2412  }
2413  }
2414  } else { // (Frame_Number != 0 &&
2416  if (frame_type == EDHCFrameHeaderDataType::c_ONSEN_TRG) {
2417  if (!(m_suppressErrorMask[c_nrONSEN_TRG_FIRST])) B2WARNING("More than one ONSEN Trigger frame");
2418  m_errorMask[c_nrONSEN_TRG_FIRST] = true;
2419  }
2420  }
2421 
2422  if (!m_formatBonnDAQ) {
2423  if (Frame_Number == 1) {
2425  if (frame_type != EDHCFrameHeaderDataType::c_DHC_START) {
2426  if (!(m_suppressErrorMask[c_nrDHC_START_SECOND])) B2WARNING("Second frame is not a DHC start of subevent frame");
2427  m_errorMask[c_nrDHC_START_SECOND] = true;
2428  }
2429  } else { // (Frame_Number != 0 &&
2431  if (frame_type == EDHCFrameHeaderDataType::c_DHC_START) {
2432  if (!(m_suppressErrorMask[c_nrDHC_START_SECOND])) B2WARNING("More than one DHC start of subevent frame");
2433  m_errorMask[c_nrDHC_START_SECOND] = true;
2434  }
2435  }
2436  }
2437 
2438  if (Frame_Number == Frames_in_event - 1) {
2440  if (frame_type != EDHCFrameHeaderDataType::c_DHC_END) {
2441  if (!(m_suppressErrorMask[c_nrDHC_END_MISS])) B2WARNING("Last frame is not a DHC end of subevent frame");
2442  m_errorMask[c_nrDHC_END_MISS] = true;
2443  }
2444 
2446  if (countedDHEStartFrames != countedDHEEndFrames || countedDHEStartFrames != nr_active_dhe) {
2447  if (!(m_suppressErrorMask[c_nrDHE_ACTIVE]) || !(m_suppressErrorMask[c_nrDHE_START_WO_END])
2448  || !(m_suppressErrorMask[c_nrDHE_END_WO_START])) {
2449  B2WARNING("The number of DHE Start/End does not match the number of active DHE in DHC Header!");
2450  B2DEBUG(29, "The number of DHE Start/End does not match the number of active DHE in DHC Header! Header: " << nr_active_dhe <<
2451  " Start: " << countedDHEStartFrames << " End: " << countedDHEEndFrames << " Mask: $" << hex << mask_active_dhe << " in Event Nr " <<
2452  eventNrOfThisFrame);
2453  }
2454  if (countedDHEStartFrames == countedDHEEndFrames) m_errorMask[c_nrDHE_ACTIVE] = true;
2455  if (countedDHEStartFrames > countedDHEEndFrames) m_errorMask[c_nrDHE_START_WO_END] = true;
2456  if (countedDHEStartFrames < countedDHEEndFrames) m_errorMask[c_nrDHE_END_WO_START] = true;
2457  }
2458 
2459  } else { // (Frame_Number != Frames_in_event - 1 &&
2461  if (frame_type == EDHCFrameHeaderDataType::c_DHC_END) {
2462  if (!(m_suppressErrorMask[c_nrDHC_END_DBL])) B2WARNING("More than one DHC end of subevent frame");
2463  m_errorMask[c_nrDHC_END_DBL] = true;
2464  }
2465  }
2466 
2467  if (!m_formatBonnDAQ) {
2469  if (Frame_Number == 2 && nr_active_dhe != 0 && frame_type != EDHCFrameHeaderDataType::c_DHE_START) {
2470  if (!(m_suppressErrorMask[c_nrDHE_START_THIRD])) B2WARNING("Third frame is not a DHE start frame");
2471  m_errorMask[c_nrDHE_START_THIRD] = true;
2472  }
2473  }
2474 
2475  if (frame_type != EDHCFrameHeaderDataType::c_ONSEN_ROI && frame_type != EDHCFrameHeaderDataType::c_ONSEN_TRG) {
2476  // actually, they should not be withing Start and End, but better be sure.
2477  countedBytesInDHC += len;
2478  countedBytesInDHE += len;
2479  }
2480  B2DEBUG(29, "DHC/DHE $" << hex << countedBytesInDHC << ", $" << hex << countedBytesInDHE);
2481 }
2482 
2484 {
2486  const int lut[32] = {
2487  0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
2488  1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5
2489  };
2490  return lut[i & 0x1F];
2491 }
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.
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.
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.
int m_overrideFirmwareVersion
override firmware version from DB.
std::string m_PXDRawHitsName
The name of the StoreArray of PXDRawHits to be generated.
void unpack_dhc_frame_v01(void *data, const int length, const int Frame_Number, const int Frames_in_event, PXDDAQPacketStatus &daqpktstat)
==== the functions for the "old" firmware ====
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.
bool m_checkPaddingCRC
Check for susp.
PXDError::PXDErrorFlags m_errorMaskPacket
Error Mask set per packet / packet.
std::string m_RawPXDsName
The name of the StoreArray of processed RawPXDs.
void unpack_dhc_frame_v10(void *data, const int length, const int Frame_Number, const int Frames_in_event, PXDDAQPacketStatus &daqpktstat)
==== the functions for the "new" firmware ====
void unpack_dhp_v01(void *data, unsigned int length, 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.
OptionalDBObjPtr< PXDDHHFirmwareVersionPar > m_firmwareFromDB
firmware version from DB.
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.
int m_firmware
Firmware version, must be read from database on run change.
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)
PXDError::PXDErrorFlags m_criticalErrorMask
Critical error mask which defines return value of task.
void beginRun() override final
Begin Run.
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.
void unpack_dhp_raw(void *data, unsigned int length, unsigned int dhe_ID, unsigned dhe_DHPport, VxdID vxd_id)
==== more firmware version independent functions ====
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.
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.
void unpack_dhp_v10(void *data, unsigned int length, 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.
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