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