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