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