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