Belle II Software  release-05-02-19
PXDUnpackerOTModule.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/PXDUnpackerOTModule.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(PXDUnpackerOT)
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 PXDUnpackerOTModule::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 PXDUnpackerOTModule::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 PXDUnpackerOTModule::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 PXDUnpackerOTModule::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 PXDUnpackerOTModule::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  m_errorMask |= c_FIX_SIZE;
316  return;
317  }
318  unsigned int dhp_header_type = 0;
319 // unsigned int dhp_reserved = 0;
320  unsigned int dhp_dhe_id = 0;
321  unsigned int dhp_dhp_id = 0;
322 
323  dhp_header_type = (dhp_pix[2] & 0xE000) >> 13;
324 // dhp_reserved = (dhp_pix[2] >> 8) & 0x1F;
325  dhp_dhe_id = (dhp_pix[2] & 0x00FC) >> 2;
326  dhp_dhp_id = dhp_pix[2] & 0x0003;
327 
328  if (dhe_ID != dhp_dhe_id) {
329  if (!(m_suppressErrorMask & c_DHE_DHP_DHEID)) {
330  B2WARNING("DHE ID in DHE and DHP header differ");
331  B2DEBUG(29, "DHE ID in DHE and DHP header differ $" << hex << dhe_ID << " != $" << dhp_dhe_id);
332  }
333  m_errorMask |= c_DHE_DHP_DHEID;
334  }
335  if (dhe_DHPport != dhp_dhp_id) {
336  if (!(m_suppressErrorMask & c_DHE_DHP_PORT)) {
337  B2WARNING("DHP ID (Chip/Port) in DHE and DHP header differ");
338  B2DEBUG(29, "DHP ID (Chip/Port) in DHE and DHP header differ $" << hex << dhe_DHPport << " != $" << dhp_dhp_id);
339  }
340  m_errorMask |= c_DHE_DHP_PORT;
341  }
342 
343  if (dhp_header_type != EDHPFrameHeaderDataType::c_RAW) {
344  if (!(m_suppressErrorMask & c_HEADERTYPE_INV)) {
345  B2WARNING("Header type invalid for this kind of DHE frame");
346  B2DEBUG(29, "Header type invalid for this kind of DHE frame: $" << hex << dhp_header_type);
347  }
348  m_errorMask |= c_HEADERTYPE_INV;
349  return;
350  }
351 
353  B2DEBUG(29, "Raw ADC Data");
354  // size checked already above
355  m_storeRawAdc.appendNew(vxd_id, data, frame_len);
356 };
357 
358 void PXDUnpackerOTModule::unpack_fce([[maybe_unused]] unsigned short* data, [[maybe_unused]] unsigned int length,
359  [[maybe_unused]] VxdID vxd_id)
360 {
367 
368  B2WARNING("FCE (Cluster) Packet have not yet been tested with real HW clusters. Dont assume that this code is working!");
369  return;
370 
371  // implement the unpacking here and not as a separate module ... when it is available in HW
372 // ubig16_t* cluster = (ubig16_t*)data;
373 // int nr_words; //words in dhp frame
374 // unsigned int words_in_cluster = 0; //counts 16bit words in cluster
375 // nr_words = length / 2;
376 // ubig16_t sor;
377 // sor = 0x0000;
378 //
379 // for (int i = 2 ; i < nr_words ; i++) {
380 // if (i != 2) { //skip header
381 // if ((((cluster[i] & 0x8000) == 0)
382 // && ((cluster[i] & 0x4000) >> 14) == 1)) { //searches for start of row frame with start of cluster flag = 1 => new cluster
383 // if (!m_doNotStore) m_storeRawCluster.appendNew(&data[i - words_in_cluster], words_in_cluster, vxd_id);
384 // words_in_cluster = 0;
385 // }
386 // }
387 // if ((cluster[i] & 0x8000) == 0) {
388 // sor = cluster[i];
389 // }
390 // words_in_cluster++;
391 //
392 // if ((cluster[nr_words - 1] & 0xFFFF) == (sor &
393 // 0xFFFF)) {//if frame is not 32bit aligned last word will be the last start of row word
394 // cluster[nr_words - 1] = 0x0000;//overwrites the last redundant word with zero to make checking easier in PXDHardwareClusterUnpacker
395 // }
396 //
397 // if (i == nr_words - 1) {
398 // if (!m_doNotStore) m_storeRawCluster.appendNew(&data[i - words_in_cluster + 1], words_in_cluster, vxd_id);
399 // }
400 // }
401 }
402 
403 void PXDUnpackerOTModule::dump_dhp(void* data, unsigned int frame_len)
404 {
405  // called only for debugging purpose, will never be called in normal running
406  unsigned int w = frame_len / 2;
407  ubig16_t* d = (ubig16_t*)data;
408 
409  B2WARNING("HEADER -- $" << hex << d[0] << ",$" << hex << d[1] << ",$" << hex << d[2] << ",$" << hex << d[3] << " -- ");
410 
411  auto dhp_header_type = (d[2] & 0xE000) >> 13;
412  auto dhp_reserved = (d[2] & 0x1F00) >> 8;
413  auto dhp_dhe_id = (d[2] & 0x00FC) >> 2;
414  auto dhp_dhp_id = d[2] & 0x0003;
415 
416  B2WARNING("DHP type | $" << hex << dhp_header_type << " ( " << dec << dhp_header_type << " ) ");
417  B2WARNING("DHP reserved | $" << hex << dhp_reserved << " ( " << dec << dhp_reserved << " ) ");
418  B2WARNING("DHP DHE ID | $" << hex << dhp_dhe_id << " ( " << dec << dhp_dhe_id << " ) ");
419  B2WARNING("DHP DHP ID | $" << hex << dhp_dhp_id << " ( " << dec << dhp_dhp_id << " ) ");
420  for (unsigned int i = 4; i < w; i++) {
421  B2WARNING("DHP DATA $" << hex << d[i]);
422  }
423  B2WARNING("DHP CRC $" << hex << d[w] << ",$" << hex << d[w + 1]);
424 }
425 
426 void PXDUnpackerOTModule::dump_roi(void* data, unsigned int frame_len)
427 {
428  // called only for debugging purpose, will never be called in normal running
429  unsigned int w = frame_len / 4;
430  ubig32_t* d = (ubig32_t*)data;
431 
432  B2WARNING("HEADER -- $" << hex << d[0] << ",$" << hex << d[1] << ",$" << hex << d[2] << ",$" << hex << d[3] << " -- Len $" << hex
433  << frame_len);
434 
435  for (unsigned int i = 0; i < w; i++) {
436  B2WARNING("ROI DATA $" << hex << d[i]);
437  }
438  B2WARNING("ROI CRC $" << hex << d[w]);
439 }
440 
441 void PXDUnpackerOTModule::unpack_dhp(void* data, unsigned int frame_len, unsigned int dhe_first_readout_frame_id_lo,
442  unsigned int dhe_ID, unsigned dhe_DHPport, unsigned dhe_reformat, VxdID vxd_id,
443  PXDDAQPacketStatus& daqpktstat)
444 {
445  unsigned int nr_words = frame_len / 2; // frame_len in bytes (excl. CRC)!!!
446  bool printflag = false;
447  ubig16_t* dhp_pix = (ubig16_t*)data;
448 
449  unsigned int dhp_readout_frame_lo = 0;
450  unsigned int dhp_header_type = 0;
451  unsigned int dhp_reserved = 0;
452  unsigned int dhp_dhe_id = 0;
453  unsigned int dhp_dhp_id = 0;
454  unsigned int wrap = 0; // workaround to recalc a relative frame number
455  int last_gate = -1; // workaround to recalc a relative frame number
456 
457  unsigned int dhp_row = 0, dhp_col = 0, dhp_adc = 0, dhp_cm = 0;
458 // unsigned int dhp_offset = 0;
459  bool rowflag = false;
460  bool pixelflag = true; // just for first row start
461 
462  if (nr_words < 4) {
463  if (!(m_suppressErrorMask & c_DHP_SIZE)) B2WARNING("DHP frame size error (too small)" << LogVar("Nr words", nr_words));
464  m_errorMask |= c_DHP_SIZE;
465  return;
466  }
467 
468  if (printflag)
469  B2DEBUG(29, "HEADER -- $" << hex << dhp_pix[0] << hex << dhp_pix[1] << hex << dhp_pix[2] << hex << dhp_pix[3] << " -- ");
470 
471  if (printflag)
472  B2DEBUG(29, "DHP Header | $" << hex << dhp_pix[2] << " ( " << dec << dhp_pix[2] << " ) ");
473  dhp_header_type = (dhp_pix[2] & 0xE000) >> 13;
474  dhp_reserved = (dhp_pix[2] & 0x1F00) >> 8;
475  dhp_dhe_id = (dhp_pix[2] & 0x00FC) >> 2;
476  dhp_dhp_id = dhp_pix[2] & 0x0003;
477 
478  if (printflag) {
479  B2DEBUG(29, "DHP type | $" << hex << dhp_header_type << " ( " << dec << dhp_header_type << " ) ");
480  B2DEBUG(29, "DHP reserved | $" << hex << dhp_reserved << " ( " << dec << dhp_reserved << " ) ");
481  B2DEBUG(29, "DHP DHE ID | $" << hex << dhp_dhe_id << " ( " << dec << dhp_dhe_id << " ) ");
482  B2DEBUG(29, "DHP DHP ID | $" << hex << dhp_dhp_id << " ( " << dec << dhp_dhp_id << " ) ");
483  }
484 
485  if (dhe_ID != dhp_dhe_id) {
486  if (!(m_suppressErrorMask & c_DHE_DHP_DHEID)) {
487  B2WARNING("DHE ID in DHE and DHP header differ");
488  B2DEBUG(29, "DHE ID in DHE and DHP header differ $" << hex << dhe_ID << " != $" << dhp_dhe_id);
489  }
490  m_errorMask |= c_DHE_DHP_DHEID;
491  }
492  if (dhe_DHPport != dhp_dhp_id) {
493  if (!(m_suppressErrorMask & c_DHE_DHP_PORT)) {
494  B2WARNING("DHP ID (Chip/Port) in DHE and DHP header differ");
495  B2DEBUG(29, "DHP ID (Chip/Port) in DHE and DHP header differ $" << hex << dhe_DHPport << " != $" << dhp_dhp_id);
496  }
497  m_errorMask |= c_DHE_DHP_PORT;
498  }
499 
500  if (dhp_header_type != EDHPFrameHeaderDataType::c_ZSD) {
501  if (!(m_suppressErrorMask & c_HEADERTYPE_INV)) {
502  B2WARNING("Header type invalid for this kind of DHE frame");
503  B2DEBUG(29, "Header type invalid for this kind of DHE frame: $" << hex << dhp_header_type);
504  }
505  m_errorMask |= c_HEADERTYPE_INV;
506  return;
507  }
508 
509 // static int offtab[4] = {0, 64, 128, 192};
510 // dhp_offset = offtab[dhp_dhp_id];
511 
512  dhp_readout_frame_lo = dhp_pix[3] & 0xFFFF;
513  if (printflag)
514  B2DEBUG(29, "DHP Frame Nr | $" << hex << dhp_readout_frame_lo << " ( " << dec << dhp_readout_frame_lo << " ) ");
515 
516  /* // TODO removed because data format error is not to be fixed soon
517  if (((dhp_readout_frame_lo - dhe_first_readout_frame_id_lo) & 0x3F) > m_maxDHPFrameDiff) {
518  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) );
519  m_errorMask |= c_DHP_DHE_FRAME_DIFFER;
520  }
521  */
522  /* // TODO removed because data format error is not to be fixed soon
523  if (m_last_dhp_readout_frame_lo[dhp_dhp_id] != -1) {
524  if (((dhp_readout_frame_lo - m_last_dhp_readout_frame_lo[dhp_dhp_id]) & 0xFFFF) > m_maxDHPFrameDiff) {
525  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] << ", " <<
526  dhp_readout_frame_lo);
527  m_errorMask |= c_DHP_NOT_CONT;
528  }
529  }
530  */
531 
532  if (daqpktstat.dhc_size() > 0) {
533  if (daqpktstat.dhc_back().dhe_size() > 0) {
534  // only is we have a DHC and DHE object... or back() is undefined
535  // Remark, if we have a broken data (DHE_START/END) structure, we might fill the
536  // previous DHE object ... but then the data is junk anyway
537  daqpktstat.dhc_back().dhe_back().newDHP(dhp_dhp_id, dhp_readout_frame_lo);
538  }
539  }
540 
541  /* // TODO removed because the data is not ordered as expected in current firmware
542  for (auto j = 0; j < 4; j++) {
543  if (m_last_dhp_readout_frame_lo[j] != -1) {
544  if (((dhp_readout_frame_lo - m_last_dhp_readout_frame_lo[j]) & 0xFFFF) > m_maxDHPFrameDiff) {
545  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] <<
546  ", " <<
547  dhp_readout_frame_lo);
548  m_errorMask |= c_DHP_DHP_FRAME_DIFFER;
549  break;// give msg only once
550  }
551  }
552  }
553  */
554  m_last_dhp_readout_frame_lo[dhp_dhp_id] = dhp_readout_frame_lo;
555 
556 // TODO Please check if this can happen by accident with valid data!
557  if (dhp_pix[2] == dhp_pix[4] && dhp_pix[3] + 1 == dhp_pix[5]) {
558  // We see a second "header" with framenr+1 ...
559  if (!(m_suppressErrorMask & c_DHP_DBL_HEADER)) {
560  B2WARNING("DHP data: seems to be double header! skipping.");
561  B2DEBUG(29, "DHP data: seems to be double header! skipping." << LogVar("Length",
562  frame_len));
563  }
564  m_errorMask |= c_DHP_DBL_HEADER;
565  // dump_dhp(data, frame_len); print out guilty dhp packet
566  return;
567  }
568 
569  // Start with offset 4, thus skipping header words
570  for (unsigned int i = 4; i < nr_words ; i++) {
571 
572  if (printflag)
573  B2DEBUG(29, "-- $" << hex << dhp_pix[i] << " -- " << dec << i);
574  {
575  if (((dhp_pix[i] & 0x8000) >> 15) == 0) {
576  rowflag = true;
577  if (!pixelflag) {
578  if (!(m_suppressErrorMask & c_DHP_ROW_WO_PIX)) B2WARNING("DHP Unpacking: Row w/o Pix");
579  m_errorMask |= c_DHP_ROW_WO_PIX;
580  }
581  pixelflag = false;
582  dhp_row = (dhp_pix[i] & 0xFFC0) >> 5;
583  dhp_cm = dhp_pix[i] & 0x3F;
584  if (last_gate != -1 && (int)dhp_row / 4 < last_gate) {
585  // B2DEBUF(29,"Wrap " << LogVar("last", last_gate) << LogVar("curr", dhp_row / 4) << LogVar("DHE", dhe_ID) << LogVar("DHP", dhp_dhp_id));
586  wrap++; // relies on the order of data before mapping and the fact that OT firmware delivers only one frame
587  }
588  last_gate = dhp_row / 4;
589 
590  if (dhp_cm == 63) { // fifo overflow
591  B2WARNING("DHP data loss (CM=63) in " << LogVar("DHE", dhe_ID) << LogVar("DHP", dhp_dhp_id));
593  m_errorMask |= c_DHH_MISC_ERROR;
594  }
595  if (daqpktstat.dhc_size() > 0) {
596  if (daqpktstat.dhc_back().dhe_size() > 0) {
597  PXDDAQDHPComMode cm(dhp_dhp_id, dhp_row, dhp_cm);
598  // only is we have a DHC and DHE object... or back() is undefined
599  // Remark, if we have a broken data (DHE_START/END) structure, we might fill the
600  // previous DHE object ... but then the data is junk anyway
601  daqpktstat.dhc_back().dhe_back().addCM(cm);
602  }
603  }
604  if (printflag)
605  B2DEBUG(29, "SetRow: $" << hex << dhp_row << " CM $" << hex << dhp_cm);
606  } else {
607  if (!rowflag) {
608  if (!(m_suppressErrorMask & c_DHP_PIX_WO_ROW)) B2WARNING("DHP Unpacking: Pix without Row!!! skip dhp data ");
609  m_errorMask |= c_DHP_PIX_WO_ROW;
610  // dump_dhp(data, frame_len);// print out faulty dhp frame
611  return;
612  } else {
613  pixelflag = true;
614  dhp_row = (dhp_row & 0xFFE) | ((dhp_pix[i] & 0x4000) >> 14);
615  dhp_col = ((dhp_pix[i] & 0x3F00) >> 8);
616  unsigned int v_cellID, u_cellID;
617  v_cellID = dhp_row;// defaults for no mapping
618  if (dhp_row >= 768) {
619  if (!(m_suppressErrorMask & c_ROW_OVERFLOW)) B2WARNING("DHP ROW Overflow " << LogVar("Row", dhp_row));
620  m_errorMask |= c_ROW_OVERFLOW;
621  }
622  // we cannot do col overflow check before mapping :-(
623 
624  if ((dhe_reformat == 0 && !m_forceNoMapping) || m_forceMapping) {
625  u_cellID = dhp_col;// defaults for no mapping
626  // data has not been pre-processed by DHH, thus we have to do the mapping ourselves
627  if ((dhe_ID & 0x21) == 0x00 || (dhe_ID & 0x21) == 0x21) {
628  // if IFOB
629  PXDMappingLookup::map_rc_to_uv_IF_OB(v_cellID, u_cellID, dhp_dhp_id, dhe_ID);
630  } else { // else OFIB
631  PXDMappingLookup::map_rc_to_uv_IB_OF(v_cellID, u_cellID, dhp_dhp_id, dhe_ID);
632  }
633  } else {
634  u_cellID = dhp_col + 64 * dhp_dhp_id; // defaults for already mapped
635  }
636  if (u_cellID >= 250) {
637  if (!(m_suppressErrorMask & c_COL_OVERFLOW)) {
638  B2WARNING("DHP COL Overflow (unconnected drain lines)");
639  B2DEBUG(29, "DHP COL Overflow (unconnected drain lines) " << u_cellID << ", reformat " << dhe_reformat << ", dhpcol " << dhp_col <<
640  ", id " << dhp_dhp_id);
641  }
642  m_errorMask |= c_COL_OVERFLOW;
643  }
644  dhp_adc = dhp_pix[i] & 0xFF;
645  if (printflag)
646  B2DEBUG(29, "SetPix: Row $" << hex << dhp_row << " Col $" << hex << dhp_col << " ADC $" << hex << dhp_adc
647  << " CM $" << hex << dhp_cm);
648 
649  if (dhp_adc == 0) {
650  // if !supress error flag
651  B2WARNING("DHE Event truncation in DHE " << dhe_ID << " DHP " << dhp_dhp_id);
652  // m_errorMask |= c_DHE_EVENT_TRUNC;
653  daqpktstat.dhc_back().dhe_back().dhp_back().setTruncated();
654  } else {
655  // in new firmware, (dhp_readout_frame_lo - dhe_first_readout_frame_id_lo) would always been 0
656  if (!m_doNotStore) m_storeRawHits.appendNew(vxd_id, v_cellID, u_cellID, dhp_adc,
657  (dhp_readout_frame_lo - dhe_first_readout_frame_id_lo + wrap) & 0x3F);
658  }
659  }
660  }
661  }
662  }
663 
664  if (printflag) {
665  B2DEBUG(29, "(DHE) DHE_ID $" << hex << dhe_ID << " (DHE) DHP ID $" << hex << dhe_DHPport << " (DHP) DHE_ID $" << hex << dhp_dhe_id
666  << " (DHP) DHP ID $" << hex << dhp_dhp_id);
667  /*for (int i = 0; i < raw_nr_words ; i++) {
668  B2DEBUG(29, "RAW | " << hex << p_pix[i]);
669  printf("raw %08X | ", p_pix[i]);
670  B2DEBUG(29, "row " << hex << ((p_pix[i] >> 20) & 0xFFF) << dec << " ( " << ((p_pix[i] >> 20) & 0xFFF) << " ) " << " col " << hex << ((p_pix[i] >> 8) & 0xFFF)
671  << " ( " << dec << ((p_pix[i] >> 8) & 0xFFF) << " ) " << " adc " << hex << (p_pix[i] & 0xFF) << " ( " << (p_pix[i] & 0xFF) << " ) "
672  );
673  }*/
674  }
675 };
676 
677 int PXDUnpackerOTModule::nr5bits(int i)
678 {
680  const int lut[32] = {
681  0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
682  1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5
683  };
684  return lut[i & 0x1F];
685 }
686 
687 void PXDUnpackerOTModule::unpack_dhc_frame(void* data, const int len, const int Frame_Number, const int Frames_in_event,
688  PXDDAQPacketStatus& daqpktstat)
689 {
693  static unsigned int eventNrOfOnsenTrgFrame = 0;
694  static int countedBytesInDHC = 0;
695  static bool cancheck_countedBytesInDHC = false;
696  static int countedBytesInDHE = 0;
697  static bool cancheck_countedBytesInDHE = false;
698  static int countedDHEStartFrames = 0;
699  static int countedDHEEndFrames = 0;
700  static int mask_active_dhe = 0;// DHE mask (5 bit)
701  static int nr_active_dhe =
702  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?
703  static int mask_active_dhp = 0;// DHP active mask, 4 bit, per current DHE
704  static int found_mask_active_dhp = 0;// mask which DHP send data and check on DHE END frame if it matches
705  static int found_good_mask_active_dhp = 0;// mask which DHP send useful data
706  static unsigned int dhe_first_readout_frame_id_lo = 0;
707  static unsigned int dhe_first_triggergate = 0;
708  static unsigned int currentDHCID = 0xFFFFFFFF;
709  static unsigned int currentDHEID = 0xFFFFFFFF;
710  static unsigned int currentVxdId = 0;
711  static bool isFakedData_event = false;
712  static bool isUnfiltered_event = false;
713 
714 
715  if (Frame_Number == 0) {
716  // We reset the counters on the first event
717  // we do this before any other check is done
718  eventNrOfOnsenTrgFrame = 0;
719  countedDHEStartFrames = 0;
720  countedDHEEndFrames = 0;
721  countedBytesInDHC = 0;
722  cancheck_countedBytesInDHC = false;
723  countedBytesInDHE = 0;
724  cancheck_countedBytesInDHE = false;
725  currentDHCID = 0xFFFFFFFF;
726  currentDHEID = 0xFFFFFFFF;
727  currentVxdId = 0;
728  isUnfiltered_event = false;
729  isFakedData_event = false;
730  mask_active_dhe = 0;
731  nr_active_dhe = 0;
732  mask_active_dhp = 0;
733  found_mask_active_dhp = 0;
734  found_good_mask_active_dhp = 0;
735  }
736 
738 
739  dhc_frames dhc;
740  dhc.set(data, hw->getFrameType(), len);
741 
742  {
743  // if a fixed size frame has a different length, how can we rely on its content???
744  // AND we could by typecasting access memory beyond end of data (but very unlikely)
745  // for that reason this we have to check before any CRC and stop unpacking the frame
746  int s = dhc.getFixedSize();
747  if (len != s && s != 0) {
748  if (!(m_suppressErrorMask & c_FIX_SIZE)) {
749  B2WARNING("Fixed frame type size does not match specs" << LogVar("expected length",
750  len) << LogVar("length in data", s));
751  }
752  m_errorMask |= c_FIX_SIZE;
753  if (!m_continueOnError) return;
754  }
755  }
756 
757  // What do we do with wrong checksum frames? As we do not know WHAT is wrong, we have to skip them alltogether.
758  // As they might contain HEADER Info, we might better skip the processing of the full package, too.
759  m_errorMask |= dhc.check_crc(m_suppressErrorMask & c_DHE_CRC);
760  if (!m_continueOnError && (m_errorMask & c_DHE_CRC) != 0) {
761  // if CRC is wrong, we cannot rely on the content of the frame, thus skipping is the best option
762  return;
763  }
764 
765  unsigned int eventNrOfThisFrame = dhc.getEventNrLo();
766  int frame_type = dhc.getFrameType();
767 
768  if (Frame_Number == 0) {
769  if (m_formatBonnDAQ) {
770  if (frame_type != EDHCFrameHeaderDataType::c_DHC_START) {
771  if (!(m_suppressErrorMask & c_EVENT_STRUCT)) B2WARNING("This looks not like BonnDAQ format.");
772  m_errorMask |= c_EVENT_STRUCT;
773 // if (!m_continueOnError) return; // requires more testing
774  }
775  } else {
776  if (frame_type == EDHCFrameHeaderDataType::c_DHC_START) {
777  if (!(m_suppressErrorMask & c_EVENT_STRUCT))
778  B2WARNING("This looks like BonnDAQ or old Desy 2013/14 testbeam format. Please use formatBonnDAQ or the pxdUnpackerDesy1314 module.");
779  m_errorMask |= c_EVENT_STRUCT;
780 // if (!m_continueOnError) return; // requires more testing
781  }
782  }
783  }
784 
785  if (!m_formatBonnDAQ) {
786  if (Frame_Number == 1) {
787  if (frame_type == EDHCFrameHeaderDataType::c_DHC_START) {
788  isFakedData_event = dhc.data_dhc_start_frame->isFakedData();
789  }
790  }
791 
792  // please check if this mask is suitable. At least here we are limited by the 16 bit trigger number in the DHH packet header.
793  // we can use more bits in the DHC and DHE START Frame
794  if ((eventNrOfThisFrame & 0xFFFF) != (m_meta_event_nr & 0xFFFF)) {
795  if (!isFakedData_event) {
796  if (!(m_suppressErrorMask & c_META_MM)) {
797  B2WARNING("Event Numbers do not match for this frame");
798  B2DEBUG(29, "Event Numbers do not match for this frame" <<
799  LogVar("Event nr in frame $", static_cast < std::ostringstream
800  && >(std::ostringstream() << hex << eventNrOfThisFrame).str()) <<
801  LogVar("Event nr in MetaInfo (bits masked) $",
802  static_cast < std::ostringstream && >(std::ostringstream() << hex << m_meta_event_nr).str()));
803  }
804  m_errorMask |= c_META_MM;
805 // if (!m_continueOnError) return; // requires more testing
806  }
807  }
808 
809  if (Frame_Number > 1 && Frame_Number < Frames_in_event - 1) {
810  if (countedDHEStartFrames != countedDHEEndFrames + 1)
811  if (frame_type != EDHCFrameHeaderDataType::c_ONSEN_ROI && frame_type != EDHCFrameHeaderDataType::c_DHE_START) {
812  if (!(m_suppressErrorMask & c_DATA_OUTSIDE)) B2WARNING("Data Frame outside a DHE START/END");
813  m_errorMask |= c_DATA_OUTSIDE;
814 // if (!m_continueOnError) return; // requires more testing
815  }
816  }
817  }
818 
819  // TODO How do we handle Frames where Error Bit is set in header?
820  // Currently there is no documentation what it actually means... ony an error bit is set (below)
821  // the following errors must be "accepted", as all firmware sets it wrong fro Ghost frames.
822  if (hw->getErrorFlag()) {
823  if (frame_type != EDHCFrameHeaderDataType::c_GHOST) {
824  m_errorMask |= c_HEADER_ERR;// TODO this should have some effect ... when does it mean something? documentation missing
825  }
826  } else {
827  if (frame_type == EDHCFrameHeaderDataType::c_GHOST) {
828  m_errorMask |= c_HEADER_ERR_GHOST;
829  }
830  }
831 
832  switch (frame_type) {
833  case EDHCFrameHeaderDataType::c_DHP_RAW: {
834 
835  if (m_verbose) dhc.data_direct_readout_frame_raw->print();
836  if (currentDHEID != dhc.data_direct_readout_frame_raw->getDHEId()) {
837  if (!(m_suppressErrorMask & c_DHE_START_ID)) {
838  B2WARNING("DHE ID from DHE Start and this frame do not match");
839  B2DEBUG(29, "DHE ID from DHE Start and this frame do not match" <<
840  LogVar("DHEID in this frame $", static_cast < std::ostringstream
841  && >(std::ostringstream() << hex << dhc.data_direct_readout_frame_raw->getDHEId()).str()) <<
842  LogVar("DHEID expected $", static_cast < std::ostringstream && >(std::ostringstream() << hex << currentDHEID).str()));
843  }
844  m_errorMask |= c_DHE_START_ID;
845  }
846  m_errorMask |= dhc.check_crc(m_suppressErrorMask & c_DHE_CRC);
847  if ((found_mask_active_dhp & (1 << dhc.data_direct_readout_frame->getDHPPort())) != 0) {
848  B2ERROR("Second DHP data packet (MEMDUMP) for " << LogVar("DHE", currentDHEID) << LogVar("DHP",
849  dhc.data_direct_readout_frame->getDHPPort()));
850  }
851 
852  found_mask_active_dhp |= 1 << dhc.data_direct_readout_frame->getDHPPort();
853 
854  unpack_dhp_raw(data, len - 4,
855  dhc.data_direct_readout_frame->getDHEId(),
856  dhc.data_direct_readout_frame->getDHPPort(),
857  currentVxdId);
858 
859  break;
860  };
861  case EDHCFrameHeaderDataType::c_ONSEN_DHP:
862  // Set the counted size invalid if negativ, needs a large negative value because we are adding up to that
863  cancheck_countedBytesInDHC = false;
864  cancheck_countedBytesInDHE = false;
865  [[fallthrough]];
866  case EDHCFrameHeaderDataType::c_DHP_ZSD: {
867 
868  if (m_verbose) dhc.data_direct_readout_frame->print();
869  if (isUnfiltered_event) {
870  if (frame_type == EDHCFrameHeaderDataType::c_ONSEN_DHP) m_errorMask |= c_SENDALL_TYPE;
871  } else {
872  if (frame_type == EDHCFrameHeaderDataType::c_DHP_ZSD) m_errorMask |= c_NOTSENDALL_TYPE;
873  }
874 
875  //m_errorMask |= dhc.data_direct_readout_frame->check_error();
876 
877  if (currentDHEID != dhc.data_direct_readout_frame_raw->getDHEId()) {
878  if (!(m_suppressErrorMask & c_DHE_START_ID)) {
879  B2WARNING("DHE ID from DHE Start and this frame do not match");
880  B2DEBUG(29, "DHE ID from DHE Start and this frame do not match" <<
881  LogVar("DHEID in this frame $", static_cast < std::ostringstream
882  && >(std::ostringstream() << hex << dhc.data_direct_readout_frame_raw->getDHEId()).str()) <<
883  LogVar("DHEID expected $", static_cast < std::ostringstream && >(std::ostringstream() << hex << currentDHEID).str()));
884  }
885  m_errorMask |= c_DHE_START_ID;
886  }
887  m_errorMask |= dhc.check_crc(m_suppressErrorMask & c_DHE_CRC);
888  if ((found_mask_active_dhp & (1 << dhc.data_direct_readout_frame->getDHPPort())) != 0) {
889  B2ERROR("Second DHP data packet for " << LogVar("DHE", currentDHEID) << LogVar("DHP", dhc.data_direct_readout_frame->getDHPPort()));
890  }
891  found_mask_active_dhp |= 1 << dhc.data_direct_readout_frame->getDHPPort();
892  found_good_mask_active_dhp |= 1 << dhc.data_direct_readout_frame->getDHPPort();// only this frametype has useful data
893  if (m_checkPaddingCRC) m_errorMask |= dhc.check_padding(); // isUnfiltered_event
894 
895 
896  unpack_dhp(data, len - 4,
897  dhe_first_readout_frame_id_lo,
898  dhc.data_direct_readout_frame->getDHEId(),
899  dhc.data_direct_readout_frame->getDHPPort(),
900  dhc.data_direct_readout_frame->getDataReformattedFlag(),
901  currentVxdId, daqpktstat);
902 
903  break;
904  };
905  case EDHCFrameHeaderDataType::c_ONSEN_FCE:
906  // Set the counted size invalid if negativ, needs a large negative value because we are adding up to that
907  cancheck_countedBytesInDHC = false;
908  cancheck_countedBytesInDHE = false;
909  [[fallthrough]];
910  case EDHCFrameHeaderDataType::c_FCE_RAW: {
911  if (!(m_suppressErrorMask & c_UNEXPECTED_FRAME_TYPE)) B2WARNING("Unexpected Frame Type (Clustering FCE)");
912  m_errorMask |= c_UNEXPECTED_FRAME_TYPE;
913  if (m_verbose) hw->print();
914  if (isUnfiltered_event) {
915  if (frame_type == EDHCFrameHeaderDataType::c_ONSEN_FCE) {
916  // TODO add error message
917  m_errorMask |= c_SENDALL_TYPE;
918  }
919  } else {
920  if (frame_type == EDHCFrameHeaderDataType::c_FCE_RAW) {
921  // TODO add error message
922  m_errorMask |= c_NOTSENDALL_TYPE;
923  }
924  }
925 
926  if (currentDHEID != dhc.data_direct_readout_frame_raw->getDHEId()) {
927  if (!(m_suppressErrorMask & c_DHE_START_ID)) {
928  B2WARNING("DHE ID from DHE Start and this frame do not match");
929  B2DEBUG(29, "DHE ID from DHE Start and this frame do not match" <<
930  LogVar("DHEID in this frame $", static_cast < std::ostringstream
931  && >(std::ostringstream() << hex << dhc.data_direct_readout_frame_raw->getDHEId()).str()) <<
932  LogVar("DHEID expected $", static_cast < std::ostringstream && >(std::ostringstream() << hex << currentDHEID).str()));
933  }
934  m_errorMask |= c_DHE_START_ID;
935  }
936  m_errorMask |= dhc.check_crc(m_suppressErrorMask & c_DHE_CRC);
937  if ((found_mask_active_dhp & (1 << dhc.data_direct_readout_frame->getDHPPort())) != 0) {
938  B2ERROR("Second DHP data packet (FCE) for " << LogVar("DHE", currentDHEID) << LogVar("DHP",
939  dhc.data_direct_readout_frame->getDHPPort()));
940  }
941  found_mask_active_dhp |= 1 << dhc.data_direct_readout_frame->getDHPPort();
942 
943  B2DEBUG(29, "UNPACK FCE FRAME with len $" << hex << len);
944  unpack_fce((unsigned short*) data, len - 4, currentVxdId);
945 
946  break;
947  };
948  case EDHCFrameHeaderDataType::c_COMMODE: {
949 
950  if (!(m_suppressErrorMask & c_UNEXPECTED_FRAME_TYPE)) B2WARNING("Unexpected Frame Type (COMMODE)");
951  m_errorMask |= c_UNEXPECTED_FRAME_TYPE;
952 
953  if (m_verbose) hw->print();
954  if (currentDHEID != dhc.data_commode_frame->getDHEId()) {
955  if (!(m_suppressErrorMask & c_DHE_START_ID)) {
956  B2WARNING("DHE ID from DHE Start and this frame do not match");
957  B2DEBUG(29, "DHE ID from DHE Start and this frame do not match" <<
958  LogVar("DHEID in this frame $", static_cast < std::ostringstream
959  && >(std::ostringstream() << hex << dhc.data_commode_frame->getDHEId()).str()) <<
960  LogVar("DHEID expected $", static_cast < std::ostringstream && >(std::ostringstream() << hex << currentDHEID).str()));
961  }
962  m_errorMask |= c_DHE_START_ID;
963  }
964  m_errorMask |= dhc.check_crc(m_suppressErrorMask & c_DHE_CRC);
965  break;
966  };
967  case EDHCFrameHeaderDataType::c_DHC_START: {
968  countedBytesInDHC = 0;
969  cancheck_countedBytesInDHC = true;
970  if (isFakedData_event != dhc.data_dhc_start_frame->isFakedData()) {
971  if (!(m_suppressErrorMask & c_FAKE_NO_FAKE_DATA)) B2WARNING("DHC START mixed Fake/no Fake event.");
972  m_errorMask |= c_FAKE_NO_FAKE_DATA;
973  }
974  if (dhc.data_dhc_start_frame->isFakedData()) {
975  if (!(m_suppressErrorMask & c_FAKE_NO_DATA_TRIG)) B2WARNING("Faked DHC START Data -> trigger without Data!");
976  m_errorMask |= c_FAKE_NO_DATA_TRIG;
977  } else {
978  if (m_verbose) dhc.data_dhc_start_frame->print();
979  }
980 
981 // eventNrOfOnsenTrgFrame = eventNrOfThisFrame;
982  currentDHEID = 0xFFFFFFFF;
983  currentVxdId = 0;
984  currentDHCID = dhc.data_dhc_start_frame->get_dhc_id();
985  m_errorMask |= dhc.check_crc(m_suppressErrorMask & c_DHE_CRC);
986 
987  if (m_formatBonnDAQ) eventNrOfOnsenTrgFrame = eventNrOfThisFrame;
988 
989  if (!isFakedData_event) {
992  if (dhc.data_dhc_start_frame->get_experiment() != m_meta_experiment) {
993  if (!(m_suppressErrorMask & c_META_MM_DHC_ERS)) {
994  B2WARNING("DHC-Meta Experiment number mismatch");
995  B2DEBUG(29, "DHC-Meta Experiment number mismatch" <<
996  LogVar("DHC exp nr",
997  dhc.data_dhc_start_frame->get_experiment()) <<
998  LogVar("META exp nr" , m_meta_experiment));
999  }
1000  m_errorMask |= c_META_MM_DHC_ERS;
1001  }
1002  if (dhc.data_dhc_start_frame->get_run() != m_meta_run_nr) {
1003  if (!(m_suppressErrorMask & c_META_MM_DHC_ERS)) {
1004  B2WARNING("DHC-Meta Run number mismatch");
1005  B2DEBUG(29, "DHC-Meta Run number mismatch" <<
1006  LogVar("DHC Run nr" ,
1007  dhc.data_dhc_start_frame->get_run()) <<
1008  LogVar("META run nr", m_meta_run_nr));
1009  }
1010  m_errorMask |= c_META_MM_DHC_ERS;
1011  }
1012  if (dhc.data_dhc_start_frame->get_subrun() != m_meta_subrun_nr) {
1013  if (!(m_suppressErrorMask & c_META_MM_DHC_ERS)) {
1014  B2WARNING("DHC-Meta Sub-Run number mismatch");
1015  B2DEBUG(29, "DHC-Meta Sub-Run number mismatch" <<
1016  LogVar("DHC subrun nr",
1017  dhc.data_dhc_start_frame->get_subrun()) <<
1018  LogVar("META subrun nr", m_meta_subrun_nr));
1019  }
1020  m_errorMask |= c_META_MM_DHC_ERS;
1021  }
1022  if ((((unsigned int)dhc.data_dhc_start_frame->getEventNrHi() << 16) | dhc.data_dhc_start_frame->getEventNrLo()) !=
1023  (m_meta_event_nr & 0xFFFFFFFF)) {
1024  if (!(m_suppressErrorMask & c_META_MM_DHC)) {
1025  B2WARNING("DHC-Meta 32 bit event number mismatch");
1026  B2DEBUG(29, "DHC-Meta 32 bit event number mismatch" <<
1027  LogVar("DHC trigger nr", (((unsigned int) dhc.data_dhc_start_frame->getEventNrHi() << 16) |
1028  dhc.data_dhc_start_frame->getEventNrLo())) <<
1029  LogVar("META trigger nr" , (unsigned int)(m_meta_event_nr & 0xFFFFFFFF)));
1030  }
1031  m_errorMask |= c_META_MM_DHC;
1032  }
1033  uint32_t trig_ticks = (((unsigned int)dhc.data_dhc_start_frame->time_tag_mid & 0x7FFF) << 12) | ((unsigned int)
1034  dhc.data_dhc_start_frame->time_tag_lo_and_type >> 4);
1035  uint32_t trig_sec = (dhc.data_dhc_start_frame->time_tag_hi * 2) ;
1036  if (dhc.data_dhc_start_frame->time_tag_mid & 0x8000) trig_sec++;
1037 
1038  if ((trig_ticks - m_meta_ticks) != 0 || (trig_sec - m_meta_sec) != 0) {
1039  m_errorMask |= c_META_MM_DHC_TT;
1040  if (!(m_suppressErrorMask & c_META_MM_DHC_TT)) {
1041  B2WARNING("DHC-Meta TimeTag mismatch");
1042  B2DEBUG(29, "DHC-Meta TimeTag mismatch" <<
1043  LogVar("Header Time $", static_cast < std::ostringstream && >(std::ostringstream() <<
1044  hex << dhc.data_dhc_start_frame->time_tag_hi << "." <<
1045  dhc.data_dhc_start_frame->time_tag_mid << "." <<
1046  dhc.data_dhc_start_frame->time_tag_lo_and_type).str()) <<
1047  LogVar("Meta Time $", static_cast < std::ostringstream && >(std::ostringstream() << hex << m_meta_time).str()) <<
1048  LogVar("Trigger Type", static_cast < std::ostringstream
1049  && >(std::ostringstream() << hex << (dhc.data_dhc_start_frame->time_tag_lo_and_type & 0xF)).str()) <<
1050  LogVar("Meta seconds: $" , static_cast < std::ostringstream && >(std::ostringstream() << hex << m_meta_sec).str()) <<
1051  LogVar("DHC seconds $" , static_cast < std::ostringstream && >(std::ostringstream() << hex << trig_sec).str()) <<
1052  LogVar("Seconds difference $" , static_cast < std::ostringstream
1053  && >(std::ostringstream() << hex << (trig_sec - m_meta_sec)).str()) <<
1054  LogVar("Meta ticks from 127MHz $" , static_cast < std::ostringstream && >(std::ostringstream() << hex << m_meta_ticks).str()) <<
1055  LogVar("DHC ticks from 127MHz $" , static_cast < std::ostringstream && >(std::ostringstream() << hex << trig_ticks).str()) <<
1056  LogVar("Tick difference $" , static_cast < std::ostringstream
1057  && >(std::ostringstream() << hex << (trig_ticks - m_meta_ticks)).str()));
1058  }
1059  } else {
1060  B2DEBUG(29, "DHC TT: $" << hex << dhc.data_dhc_start_frame->time_tag_hi << "." << dhc.data_dhc_start_frame->time_tag_mid << "." <<
1061  dhc.data_dhc_start_frame->time_tag_lo_and_type << " META " << m_meta_time << " TRG Type " <<
1062  (dhc.data_dhc_start_frame->time_tag_lo_and_type & 0xF));
1063  }
1064  }
1065  mask_active_dhe = dhc.data_dhc_start_frame->get_active_dhe_mask();
1066  nr_active_dhe = nr5bits(mask_active_dhe);
1067 
1068  m_errorMaskDHC = m_errorMask; // forget about anything before this frame
1069  daqpktstat.newDHC(currentDHCID, m_errorMask);
1070  daqpktstat.dhc_back().setGatedFlag(dhc.data_dhc_start_frame->get_gated_flag());
1071  daqpktstat.dhc_back().setGatedHER(dhc.data_dhc_start_frame->get_gated_isher());
1072 
1073  break;
1074  };
1075  case EDHCFrameHeaderDataType::c_DHE_START: {
1076  countedBytesInDHE = 0;
1077  cancheck_countedBytesInDHE = true;
1078  m_last_dhp_readout_frame_lo[0] = -1;
1079  m_last_dhp_readout_frame_lo[1] = -1;
1080  m_last_dhp_readout_frame_lo[2] = -1;
1081  m_last_dhp_readout_frame_lo[3] = -1;
1082  if (m_verbose) dhc.data_dhe_start_frame->print();
1083  dhe_first_readout_frame_id_lo = dhc.data_dhe_start_frame->getStartFrameNr();
1084  dhe_first_triggergate = dhc.data_dhe_start_frame->getTriggerGate();
1085  if (currentDHEID != 0xFFFFFFFF && (currentDHEID & 0xFFFF) >= dhc.data_dhe_start_frame->getDHEId()) {
1086  if (!(m_suppressErrorMask & c_DHE_WRONG_ID_SEQ)) {
1087  B2WARNING("DHH IDs are not in expected order");
1088  B2DEBUG(29, "DHH IDs are not in expected order" <<
1089  LogVar("Previous ID", (currentDHEID & 0xFFFF)) <<
1090  LogVar("Current ID", dhc.data_dhe_start_frame->getDHEId()));
1091  }
1092  m_errorMask |= c_DHE_WRONG_ID_SEQ;
1093  }
1094  currentDHEID = dhc.data_dhe_start_frame->getDHEId();
1095  m_errorMask |= dhc.check_crc(m_suppressErrorMask & c_DHE_CRC);
1096 
1097  if (countedDHEStartFrames > countedDHEEndFrames) {
1098  if (!(m_suppressErrorMask & c_DHE_START_WO_END)) B2WARNING("DHE_START without DHE_END");
1099  m_errorMask |= c_DHE_START_WO_END;
1100  }
1101  countedDHEStartFrames++;
1102 
1103  found_mask_active_dhp = 0;
1104  found_good_mask_active_dhp = 0;
1105  mask_active_dhp = dhc.data_dhe_start_frame->getActiveDHPMask();
1106 
1107  if ((((unsigned int)dhc.data_dhe_start_frame->getEventNrHi() << 16) | dhc.data_dhe_start_frame->getEventNrLo()) != (unsigned int)(
1108  m_meta_event_nr & 0xFFFFFFFF)) {
1109  if (!(m_suppressErrorMask & c_META_MM_DHE)) {
1110  B2WARNING("DHE START trigger mismatch in EVT32b/HI WORD");
1111  B2DEBUG(29, "DHE START trigger mismatch in EVT32b/HI WORD" <<
1112  LogVar("DHE Start trigger nr", (dhc.data_dhe_start_frame->getEventNrHi() << 16) | dhc.data_dhe_start_frame->getEventNrLo()) <<
1113  LogVar("Meta trigger nr", (m_meta_event_nr & 0xFFFFFFFF)));
1114  }
1115  m_errorMask |= c_META_MM_DHE;
1116  }
1117 // B2WARNING("DHE TT: $" << hex << dhc.data_dhe_start_frame->dhe_time_tag_hi << "." << dhc.data_dhe_start_frame->dhe_time_tag_lo <<
1118 // " META " << m_meta_time);
1119 
1120  if (currentDHEID == 0) {
1121  if (!(m_suppressErrorMask & c_DHE_ID_INVALID)) B2WARNING("DHE ID is invalid=0 (not initialized)");
1122  m_errorMask |= c_DHE_ID_INVALID;
1123  }
1124  // calculate the VXDID for DHE and save them for DHP unpacking
1125  {
1132  unsigned short sensor, ladder, layer;
1133  sensor = (currentDHEID & 0x1) + 1;
1134  ladder = (currentDHEID & 0x1E) >> 1; // no +1
1135  layer = ((currentDHEID & 0x20) >> 5) + 1;
1136  currentVxdId = VxdID(layer, ladder, sensor);
1137  if (ladder == 0 || (layer == 1 && ladder > 8) || (layer == 2 && ladder > 12)) {
1138  if (!(m_suppressErrorMask & c_DHE_ID_INVALID)) {
1139  B2WARNING("DHE ID is invalid");
1140  B2DEBUG(29, "DHE ID is invalid" <<
1141  LogVar("DHE ID", currentDHEID) <<
1142  LogVar("Layer", layer) <<
1143  LogVar("Ladder", ladder) <<
1144  LogVar("Sensor", sensor));
1145  }
1146  m_errorMask |= c_DHE_ID_INVALID;
1147  }
1148  }
1149 
1150  m_errorMaskDHE = m_errorMask; // forget about anything before this frame
1151  if (daqpktstat.dhc_size() > 0) {
1152  // if no DHC has been defined yet, do nothing!
1153  daqpktstat.dhc_back().newDHE(currentVxdId, currentDHEID, m_errorMask, dhe_first_triggergate, dhe_first_readout_frame_id_lo);
1154  }
1155  break;
1156  };
1157  case EDHCFrameHeaderDataType::c_GHOST:
1158  if (m_verbose) dhc.data_ghost_frame->print();
1159  if (currentDHEID != dhc.data_ghost_frame->getDHEId()) {
1160  if (!(m_suppressErrorMask & c_DHE_START_ID)) {
1161  B2WARNING("DHE ID from DHE Start and this frame do not match");
1162  B2DEBUG(29, "Start ID $" << hex << currentDHEID << " != $" << dhc.data_ghost_frame->getDHEId());
1163  }
1164  m_errorMask |= c_DHE_START_ID;
1165  }
1167  if ((found_mask_active_dhp & (1 << dhc.data_ghost_frame->getDHPPort())) != 0) {
1168  B2ERROR("Second DHP data packet (GHOST) for " << LogVar("DHE", currentDHEID) << LogVar("DHP", dhc.data_ghost_frame->getDHPPort()));
1169  }
1170  found_mask_active_dhp |= 1 << dhc.data_ghost_frame->getDHPPort();
1171 
1172  //found_mask_active_dhp = mask_active_dhp;/// TODO Workaround for DESY TB 2016 doesnt work
1173 
1174  m_errorMask |= dhc.check_crc(m_suppressErrorMask & c_DHE_CRC);
1175 
1176  break;
1177  case EDHCFrameHeaderDataType::c_DHC_END: {
1178  if (dhc.data_dhc_end_frame->isFakedData() != isFakedData_event) {
1179  if (!(m_suppressErrorMask & c_FAKE_NO_FAKE_DATA)) B2WARNING("DHC END mixed Fake/no Fake event.");
1180  m_errorMask |= c_FAKE_NO_FAKE_DATA;
1181  }
1182  if (dhc.data_dhc_end_frame->isFakedData()) {
1183  if (!(m_suppressErrorMask & c_FAKE_NO_DATA_TRIG)) B2WARNING("Faked DHC END Data -> trigger without Data!");
1184  m_errorMask |= c_FAKE_NO_DATA_TRIG;
1185  } else {
1186  if (m_verbose) dhc.data_dhc_end_frame->print();
1187  }
1188 
1189  if (!isFakedData_event) {
1190  if (dhc.data_dhc_end_frame->get_dhc_id() != currentDHCID) {
1191  if (!(m_suppressErrorMask & c_DHC_DHCID_START_END_MM)) {
1192  B2WARNING("DHC ID Mismatch between Start and End");
1193  B2DEBUG(29, "DHC ID Mismatch between Start and End $" << std::hex <<
1194  currentDHCID << "!=$" << dhc.data_dhc_end_frame->get_dhc_id());
1195  }
1196  m_errorMask |= c_DHC_DHCID_START_END_MM;
1197  }
1198  int w;
1199  w = dhc.data_dhc_end_frame->get_words() * 4;
1200  if (cancheck_countedBytesInDHC) {
1201  if (countedBytesInDHC != w) {
1202  if (!(m_suppressErrorMask & c_DHC_WIE)) {
1203  B2WARNING("Number of Words in DHC END does not match");
1204  B2DEBUG(29, "Number of Words in DHC END does not match: WIE $" << hex << countedBytesInDHC << " != DHC END $" << hex << w);
1205  }
1206  m_errorMask |= c_DHC_WIE;
1207  } else {
1208  if (m_verbose)
1209  B2DEBUG(29, "EVT END: WIE $" << hex << countedBytesInDHC << " == DHC END $" << hex << w);
1210  }
1211  // else ... processed data -> length invalid
1212  }
1213  }
1215  if (dhc.data_dhc_end_frame->getErrorInfo() != 0) {
1216  if (!(m_suppressErrorMask & c_DHH_END_ERRORBITS)) B2ERROR("DHC END Error Info set to $" << hex <<
1217  dhc.data_dhc_end_frame->getErrorInfo());
1218  m_errorMask |= c_DHH_END_ERRORBITS;
1219  }
1220  m_errorMask |= dhc.check_crc(m_suppressErrorMask & c_DHE_CRC);
1221  m_errorMaskDHC |= m_errorMask; // do latest updates
1222 
1223  if (daqpktstat.dhc_size() > 0) {
1224  // only is we have a DHC object... or back() is undefined
1225  // Remark, if we have a broken data (DHC_START/END) structure, we might fill the
1226  // previous DHC object ... but then the data is junk anyway
1227  daqpktstat.dhc_back().setErrorMask(m_errorMaskDHC);
1228  //B2DEBUG(98,"** DHC "<<currentDHCID<<" Raw"<<dhc.data_dhc_end_frame->get_words() * 4 <<" Red"<<countedBytesInDHC);
1229  daqpktstat.dhc_back().setCounters(dhc.data_dhc_end_frame->get_words() * 4, countedBytesInDHC);
1230  daqpktstat.dhc_back().setEndErrorInfo(dhc.data_dhc_end_frame->getErrorInfo());
1231  }
1232  m_errorMaskDHC = 0;
1233  currentDHEID = 0xFFFFFFFF;
1234  currentDHCID = 0xFFFFFFFF;
1235  currentVxdId = 0;
1236  break;
1237  };
1238  case EDHCFrameHeaderDataType::c_DHE_END: {
1239  if (m_verbose) dhc.data_dhe_end_frame->print();
1240  if (currentDHEID != dhc.data_dhe_end_frame->getDHEId()) {
1241  if (!(m_suppressErrorMask & c_DHE_START_END_ID)) {
1242  B2WARNING("DHE ID from DHE Start and this frame do not match");
1243  B2DEBUG(29, "DHE ID from DHE Start and this frame do not match $" << hex << currentDHEID << " != $" <<
1244  dhc.data_dhe_end_frame->getDHEId());
1245  }
1246  m_errorMask |= c_DHE_START_END_ID;
1247  }
1249  if (dhc.data_dhe_end_frame->getErrorInfo() != 0) {
1250  if (!(m_suppressErrorMask & c_DHH_END_ERRORBITS)) B2ERROR("DHE END Error Info set to $" << hex <<
1251  dhc.data_dhe_end_frame->getErrorInfo());
1252  m_errorMask |= c_DHH_END_ERRORBITS;
1253  }
1254  m_errorMask |= dhc.check_crc(m_suppressErrorMask & c_DHE_CRC);
1255  if (found_mask_active_dhp != mask_active_dhp) {
1256  if (!(m_suppressErrorMask & c_DHP_ACTIVE)) {
1257  B2WARNING("DHE_END: DHP active mask differs from found data");
1258  B2DEBUG(29, "DHE_END: DHP active mask differs from found data $" << hex << mask_active_dhp << " != $" << hex <<
1259  found_mask_active_dhp
1260  << " mask of found dhp/ghost frames");
1261  }
1262  m_errorMask |= c_DHP_ACTIVE;
1263  }
1264  countedDHEEndFrames++;
1265  if (countedDHEStartFrames < countedDHEEndFrames) {
1266  // the other case is checked in Start
1267  if (!(m_suppressErrorMask & c_DHE_END_WO_START)) B2WARNING("DHE_END without DHE_START");
1268  m_errorMask |= c_DHE_END_WO_START;
1269  }
1270  {
1271  int w;
1272  w = dhc.data_dhe_end_frame->get_words() * 2;
1273  if (cancheck_countedBytesInDHE) {
1274  if (countedBytesInDHE != w) {
1275  if (!(m_suppressErrorMask & c_DHE_WIE)) {
1276  B2WARNING("Number of Words in DHE END does not match");
1277  B2DEBUG(29, "Number of Words in DHE END does not match: WIE $" << hex << countedBytesInDHE << " != DHE END $" << hex << w);
1278  }
1279  m_errorMask |= c_DHE_WIE;
1280  } else {
1281  if (m_verbose)
1282  B2DEBUG(29, "EVT END: WIE $" << hex << countedBytesInDHE << " == DHE END $" << hex << w);
1283  }
1284  // else ... processed data -> length invalid
1285  }
1286  }
1287  m_errorMaskDHE |= m_errorMask; // do latest updates
1288 
1289  if (daqpktstat.dhc_size() > 0) {
1290  if (daqpktstat.dhc_back().dhe_size() > 0) {
1291  // only is we have a DHC and DHE object... or back() is undefined
1292  // Remark, if we have a broken data (DHE_START/END) structure, we might fill the
1293  // previous DHE object ... but then the data is junk anyway
1294  daqpktstat.dhc_back().dhe_back().setErrorMask(m_errorMaskDHE);
1295  // B2DEBUG(98,"** DHC "<<currentDHEID<<" Raw "<<dhc.data_dhe_end_frame->get_words() * 2 <<" Red"<<countedBytesInDHE);
1296  daqpktstat.dhc_back().dhe_back().setCounters(dhc.data_dhe_end_frame->get_words() * 2, countedBytesInDHE);
1297  daqpktstat.dhc_back().dhe_back().setDHPFoundMask(found_good_mask_active_dhp);
1298  daqpktstat.dhc_back().dhe_back().setEndErrorInfo(dhc.data_dhe_end_frame->getErrorInfo());
1299  }
1300  }
1301  m_errorMaskDHE = 0;
1302  currentDHEID |= 0xFF000000;// differenciate from 0xFFFFFFFFF as initial value
1303  currentVxdId = 0;
1304  break;
1305  };
1306  case EDHCFrameHeaderDataType::c_ONSEN_ROI:
1307  if (m_verbose) dhc.data_onsen_roi_frame->print();
1308  m_errorMask |= dhc.data_onsen_roi_frame->check_error(len, m_suppressErrorMask & c_ROI_PACKET_INV_SIZE);
1309  m_errorMask |= dhc.data_onsen_roi_frame->check_inner_crc(len - 4);
1310  m_errorMask |= dhc.check_crc(m_suppressErrorMask & c_DHE_CRC);
1311  if (!m_doNotStore) {
1312  //dhc.data_onsen_roi_frame->save(m_storeROIs, len, (unsigned int*) data);
1313  // void save(StoreArray<PXDRawROIs>& sa, unsigned int length, unsigned int* data) const
1314  // 4 byte header, ROIS (n*8), 4 byte copy of inner CRC, 4 byte outer CRC
1315  if (len >= dhc.data_onsen_roi_frame->getMinSize()) {
1316  //if ((len - dhc.data_onsen_roi_frame->getMinSize()) % 8 != 0) {
1317  // error checking in check_error() above, this is only for dump-ing
1318  // dump_roi(data, len - 4); // dump ROI payload, minus CRC
1319  //}
1320  unsigned int l;
1321  l = (len - dhc.data_onsen_roi_frame->getMinSize()) / 8;
1322  // Endian swapping is done in Contructor of RawRoi object
1323  m_storeROIs.appendNew(l, &((unsigned int*) data)[1]);
1324  }
1325  }
1326  break;
1327  case EDHCFrameHeaderDataType::c_ONSEN_TRG:
1328  eventNrOfOnsenTrgFrame = eventNrOfThisFrame;
1329  if (dhc.data_onsen_trigger_frame->get_trig_nr1() != (unsigned int)(m_meta_event_nr & 0xFFFFFFFF)) {
1330  if (!(m_suppressErrorMask & c_META_MM_ONS_HLT)) {
1331  B2WARNING("Trigger Frame HLT Trigger Nr mismatch");
1332  B2DEBUG(29, "Trigger Frame HLT Trigger Nr mismatch: HLT $" <<
1333  dhc.data_onsen_trigger_frame->get_trig_nr1() << " META " << (m_meta_event_nr & 0xFFFFFFFF));
1334  }
1335  m_errorMask |= c_META_MM_ONS_HLT;
1336  }
1337  if (dhc.data_onsen_trigger_frame->get_experiment1() != m_meta_experiment ||
1338  dhc.data_onsen_trigger_frame->get_run1() != m_meta_run_nr ||
1339  dhc.data_onsen_trigger_frame->get_subrun1() != m_meta_subrun_nr) {
1340  if (!(m_suppressErrorMask & c_META_MM_ONS_HLT)) {
1341  B2WARNING("Trigger Frame HLT Exp/Run/Subrun Nr mismatch");
1342  B2DEBUG(29, "Trigger Frame HLT Exp/Run/Subrun Nr mismatch: Exp HLT $" <<
1343  dhc.data_onsen_trigger_frame->get_experiment1() << " META " << m_meta_experiment <<
1344  " Run HLT $" << dhc.data_onsen_trigger_frame->get_run1() << " META " << m_meta_run_nr <<
1345  " Subrun HLT $" << dhc.data_onsen_trigger_frame->get_subrun1() << " META " << m_meta_subrun_nr);
1346  }
1347  m_errorMask |= c_META_MM_ONS_HLT;
1348  }
1349 
1350  if (!dhc.data_onsen_trigger_frame->is_fake_datcon()) {
1351  if (dhc.data_onsen_trigger_frame->get_trig_nr2() != (unsigned int)(m_meta_event_nr & 0xFFFFFFFF)) {
1352  if (!(m_suppressErrorMask & c_META_MM_ONS_DC)) {
1353  B2WARNING("Trigger Frame DATCON Trigger Nr mismatch");
1354  B2DEBUG(29, "Trigger Frame DATCON Trigger Nr mismatch: DC $" <<
1355  dhc.data_onsen_trigger_frame->get_trig_nr2() << " META " << (m_meta_event_nr & 0xFFFFFFFF));
1356  }
1357  m_errorMask |= c_META_MM_ONS_DC;
1358  }
1359  if (dhc.data_onsen_trigger_frame->get_experiment2() != m_meta_experiment ||
1360  dhc.data_onsen_trigger_frame->get_run2() != m_meta_run_nr ||
1361  dhc.data_onsen_trigger_frame->get_subrun2() != m_meta_subrun_nr) {
1362  if (!(m_suppressErrorMask & c_META_MM_ONS_DC)) {
1363  B2WARNING("Trigger Frame DATCON Exp/Run/Subrun Nr mismatch");
1364  B2DEBUG(29, "Trigger Frame DATCON Exp/Run/Subrun Nr mismatch: Exp DC $" <<
1365  dhc.data_onsen_trigger_frame->get_experiment2() << " META " << m_meta_experiment <<
1366  " Run DC $" << dhc.data_onsen_trigger_frame->get_run2() << " META " << m_meta_run_nr <<
1367  " Subrun DC $" << dhc.data_onsen_trigger_frame->get_subrun2() << " META " << m_meta_subrun_nr);
1368  }
1369  m_errorMask |= c_META_MM_ONS_DC;
1370  }
1371  }
1372 
1373 // 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);
1374 
1375  if (m_verbose) dhc.data_onsen_trigger_frame->print();
1376  m_errorMask |= dhc.data_onsen_trigger_frame->check_error(m_suppressErrorMask & c_NO_DATCON, m_suppressErrorMask & c_HLTROI_MAGIC,
1377  m_suppressErrorMask & c_MERGER_TRIGNR);
1378  m_errorMask |= dhc.check_crc(m_suppressErrorMask & c_DHE_CRC);
1379  if (Frame_Number != 0) {
1380  if (!(m_suppressErrorMask & c_EVENT_STRUCT)) B2WARNING("ONSEN TRG Frame must be the first one.");
1381  m_errorMask |= c_EVENT_STRUCT;
1382  }
1383  isUnfiltered_event = dhc.data_onsen_trigger_frame->is_SendUnfiltered();
1384  if (isUnfiltered_event) m_sendunfiltered++;
1385  if (dhc.data_onsen_trigger_frame->is_SendROIs()) m_sendrois++;
1386  if (!dhc.data_onsen_trigger_frame->is_Accepted()) m_notaccepted++;
1387  break;
1388  default:
1389  if (!(m_suppressErrorMask & c_DHC_UNKNOWN)) B2WARNING("UNKNOWN DHC frame type");
1390  m_errorMask |= c_DHC_UNKNOWN;
1391  if (m_verbose) hw->print();
1392  break;
1393  }
1394 
1395  if (eventNrOfThisFrame != eventNrOfOnsenTrgFrame && !isFakedData_event) {
1396  if (!(m_suppressErrorMask & c_FRAME_TNR_MM)) {
1397  B2WARNING("Frame TrigNr != ONSEN Trig Nr");
1398  B2DEBUG(29, "Frame TrigNr != ONSEN Trig Nr $" << hex << eventNrOfThisFrame << " != $" << eventNrOfOnsenTrgFrame);
1399  }
1400  m_errorMask |= c_FRAME_TNR_MM;
1401  }
1402 
1403  if (Frame_Number == 0) {
1405  if (frame_type != EDHCFrameHeaderDataType::c_ONSEN_TRG) {
1406  if (!m_formatBonnDAQ) {
1407  if (!(m_suppressErrorMask & c_ONSEN_TRG_FIRST)) B2WARNING("First frame is not a ONSEN Trigger frame");
1408  m_errorMask |= c_ONSEN_TRG_FIRST;
1409  }
1410  }
1411  } else { // (Frame_Number != 0 &&
1413  if (frame_type == EDHCFrameHeaderDataType::c_ONSEN_TRG) {
1414  if (!(m_suppressErrorMask & c_ONSEN_TRG_FIRST)) B2WARNING("More than one ONSEN Trigger frame");
1415  m_errorMask |= c_ONSEN_TRG_FIRST;
1416  }
1417  }
1418 
1419  if (!m_formatBonnDAQ) {
1420  if (Frame_Number == 1) {
1422  if (frame_type != EDHCFrameHeaderDataType::c_DHC_START) {
1423  if (!(m_suppressErrorMask & c_DHC_START_SECOND)) B2WARNING("Second frame is not a DHC start of subevent frame");
1424  m_errorMask |= c_DHC_START_SECOND;
1425  }
1426  } else { // (Frame_Number != 0 &&
1428  if (frame_type == EDHCFrameHeaderDataType::c_DHC_START) {
1429  if (!(m_suppressErrorMask & c_DHC_START_SECOND)) B2WARNING("More than one DHC start of subevent frame");
1430  m_errorMask |= c_DHC_START_SECOND;
1431  }
1432  }
1433  }
1434 
1435  if (Frame_Number == Frames_in_event - 1) {
1437  if (frame_type != EDHCFrameHeaderDataType::c_DHC_END) {
1438  if (!(m_suppressErrorMask & c_DHC_END_MISS)) B2WARNING("Last frame is not a DHC end of subevent frame");
1439  m_errorMask |= c_DHC_END_MISS;
1440  }
1441 
1443  if (countedDHEStartFrames != countedDHEEndFrames || countedDHEStartFrames != nr_active_dhe) {
1444  if (!(m_suppressErrorMask & c_DHE_ACTIVE) || !(m_suppressErrorMask & c_DHE_START_WO_END)
1445  || !(m_suppressErrorMask & c_DHE_END_WO_START)) {
1446  B2WARNING("The number of DHE Start/End does not match the number of active DHE in DHC Header!");
1447  B2DEBUG(29, "The number of DHE Start/End does not match the number of active DHE in DHC Header! Header: " << nr_active_dhe <<
1448  " Start: " << countedDHEStartFrames << " End: " << countedDHEEndFrames << " Mask: $" << hex << mask_active_dhe << " in Event Nr " <<
1449  eventNrOfThisFrame);
1450  }
1451  if (countedDHEStartFrames == countedDHEEndFrames) m_errorMask |= c_DHE_ACTIVE;
1452  if (countedDHEStartFrames > countedDHEEndFrames) m_errorMask |= c_DHE_START_WO_END;
1453  if (countedDHEStartFrames < countedDHEEndFrames) m_errorMask |= c_DHE_END_WO_START;
1454  }
1455 
1456  } else { // (Frame_Number != Frames_in_event - 1 &&
1458  if (frame_type == EDHCFrameHeaderDataType::c_DHC_END) {
1459  if (!(m_suppressErrorMask & c_DHC_END_DBL)) B2WARNING("More than one DHC end of subevent frame");
1460  m_errorMask |= c_DHC_END_DBL;
1461  }
1462  }
1463 
1464  if (!m_formatBonnDAQ) {
1466  if (Frame_Number == 2 && nr_active_dhe != 0 && frame_type != EDHCFrameHeaderDataType::c_DHE_START) {
1467  if (!(m_suppressErrorMask & c_DHE_START_THIRD)) B2WARNING("Third frame is not a DHE start frame");
1468  m_errorMask |= c_DHE_START_THIRD;
1469  }
1470  }
1471 
1472  if (frame_type != EDHCFrameHeaderDataType::c_ONSEN_ROI && frame_type != EDHCFrameHeaderDataType::c_ONSEN_TRG) {
1473  // actually, they should not be withing Start and End, but better be sure.
1474  countedBytesInDHC += len;
1475  countedBytesInDHE += len;
1476  }
1477  B2DEBUG(29, "DHC/DHE $" << hex << countedBytesInDHC << ", $" << hex << countedBytesInDHE);
1478 }
Belle2::PXD::PXDUnpackerOTModule
The PXDUnpackerOT module.
Definition: PXDUnpackerOTModule.h:51
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::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::PXDDAQDHEStatus::setDHPFoundMask
void setDHPFoundMask(unsigned short dhpmask)
set Mask for found DHPs with valid data
Definition: PXDDAQDHEStatus.h:132
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