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