Project
Loading...
Searching...
No Matches
Compressor.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
16
18#include "TOFBase/Geo.h"
20
21#include <fairlogger/Logger.h>
22
23#include <cstring>
24#include <iostream>
25
26// o2::ctf::CTFIOSize iosize;
27#define ENCODER_PARANOID
28//#define CHECKER_COUNTER
29
30#ifdef DECODER_PARANOID
31#warning "Building code with DecoderParanoid option. This may limit the speed."
32#endif
33#ifdef CHECKER_COUNTER
34#warning "Building code with CheckerCounter option. This may limit the speed."
35#endif
36
37#define colorReset "\033[0m"
38#define colorRed "\033[1;31m"
39#define colorGreen "\033[1;32m"
40#define colorYellow "\033[1;33m"
41#define colorBlue "\033[1;34m"
42
43// decoding macros
44#define IS_DRM_COMMON_HEADER(x) ((x & 0xF0000000) == 0x40000000)
45#define IS_DRM_GLOBAL_HEADER(x) ((x & 0xF000000F) == 0x40000001)
46#define IS_DRM_GLOBAL_TRAILER(x) ((x & 0xF000000F) == 0x50000001)
47#define IS_LTM_GLOBAL_HEADER(x) ((x & 0xF000000F) == 0x40000002)
48#define IS_LTM_GLOBAL_TRAILER(x) ((x & 0xF000000F) == 0x50000002)
49#define IS_TRM_GLOBAL_HEADER(x) ((x & 0xF0000000) == 0x40000000)
50#define IS_TRM_GLOBAL_TRAILER(x) ((x & 0xF0000003) == 0x50000003)
51#define IS_TRM_CHAINA_HEADER(x) ((x & 0xF0000000) == 0x00000000)
52#define IS_TRM_CHAINA_TRAILER(x) ((x & 0xF0000000) == 0x10000000)
53#define IS_TRM_CHAINB_HEADER(x) ((x & 0xF0000000) == 0x20000000)
54#define IS_TRM_CHAINB_TRAILER(x) ((x & 0xF0000000) == 0x30000000)
55#define IS_TRM_CHAIN_TRAILER(x, c) ((x & 0xF0000000) == (c == 0 ? 0x10000000 : 0x30000000))
56#define IS_TDC_ERROR(x) ((x & 0xF0000000) == 0x60000000)
57#define IS_FILLER(x) ((x & 0xFFFFFFFF) == 0x70000000)
58#define IS_TDC_HIT(x) ((x & 0x80000000) == 0x80000000)
59#define IS_TDC_HIT_LEADING(x) ((x & 0xA0000000) == 0xA0000000)
60#define IS_TDC_HIT_TRAILING(x) ((x & 0xC0000000) == 0xC0000000)
61#define IS_DRM_TEST_WORD(x) ((x & 0xF000000F) == 0xE000000F)
62
63// DRM getters
64#define GET_DRMDATAHEADER_DRMID(x) DRM_DRMID(x)
65#define GET_DRMDATAHEADER_EVENTWORDS(x) DRM_EVWORDS(x)
66#define GET_DRMHEADW1_PARTSLOTMASK(x) DRM_SLOTID(x)
67#define GET_DRMHEADW1_CLOCKSTATUS(x) DRM_CLKFLG(x)
68#define GET_DRMHEADW1_DRMHVERSION(x) DRM_VERSID(x)
69#define GET_DRMHEADW1_DRMHSIZE(x) DRM_HSIZE(x)
70#define GET_DRMHEADW2_ENASLOTMASK(x) DRM_ENABLEID(x)
71#define GET_DRMHEADW2_FAULTSLOTMASK(x) DRM_FAULTID(x)
72#define GET_DRMHEADW2_READOUTTIMEOUT(x) DRM_RTMO(x)
73#define GET_DRMHEADW3_GBTBUNCHCNT(x) DRM_BCGBT(x)
74#define GET_DRMHEADW3_LOCBUNCHCNT(x) DRM_BCLOC(x)
75#define GET_DRMHEADW5_EVENTCRC(x) DRM_EVCRC(x)
76#define GET_DRMDATATRAILER_LOCEVCNT(x) DRM_LOCEVCNT(x)
77
78// LTM getters
79#define GET_LTMDATAHEADER_EVENTWORDS(x) LTM_EVENTSIZE(x)
80
81// TRM getters
82#define GET_TRMDATAHEADER_SLOTID(x) TOF_GETGEO(x)
83#define GET_TRMDATAHEADER_EVENTCNT(x) TRM_EVCNT_GH(x)
84#define GET_TRMDATAHEADER_EVENTWORDS(x) TRM_EVWORDS(x)
85#define GET_TRMDATAHEADER_EMPTYBIT(x) TRM_EMPTYBIT(x)
86#define GET_TRMDATATRAILER_LUTERRORBIT(x) TRM_LUTERRBIT(x)
87#define GET_TRMDATATRAILER_EVENTCRC(x) TRM_EVCRC2(x)
88
89// TRM Chain getters
90#define GET_TRMCHAINHEADER_SLOTID(x) TOF_GETGEO(x)
91#define GET_TRMCHAINHEADER_BUNCHCNT(x) TRM_BUNCHID(x)
92#define GET_TRMCHAINTRAILER_EVENTCNT(x) TRM_EVCNT_CT(x)
93#define GET_TRMCHAINTRAILER_STATUS(x) TRM_CHAINSTAT(x)
94
95// TDC getters
96#define GET_TRMDATAHIT_TIME(x) TRM_TIME(x)
97#define GET_TRMDATAHIT_CHANID(x) TRM_CHANID(x)
98#define GET_TRMDATAHIT_TDCID(x) TRM_TDCID(x)
99#define GET_TRMDATAHIT_EBIT(x) ((x & 0x10000000) >> 28)
100
101namespace o2
102{
103namespace tof
104{
105
106template <typename RDH, bool verbose, bool paranoid>
108{
109
110 if (verbose && mDecoderVerbose) {
111 std::cout << colorBlue
112 << "--- PROCESS HBF"
114 << std::endl;
117 mDecoderRDH = reinterpret_cast<const RDH*>(mDecoderPointer);
118 mEncoderRDH = reinterpret_cast<RDH*>(mEncoderPointer);
119 auto rdh = mDecoderRDH;
120
121 if (!o2::raw::RDHUtils::checkRDH(rdh, false)) {
122 LOG(warning) << "Bad RDH found in TOF compressor -> skip it";
124 return true;
125 }
126
127 uint8_t rdhFormat = o2::raw::RDHUtils::getDataFormat(mDecoderPointer);
128 setDecoderCRUZEROES(!rdhFormat);
129
131 if (!rdh || rdh->stop || rdh->pageCnt != 0) {
132 std::cout << colorRed
133 << "[FATAL] this does not look like the first RDH in the HBF"
134 << colorReset
135 << std::endl;
137 return true;
138 }
139
141 while (!rdh->stop) {
142
143 if (verbose && mDecoderVerbose) {
144 std::cout << colorBlue
145 << "--- RDH open/continue detected"
146 << colorReset
147 << std::endl;
149 }
150
152 if (rdh->feeId != mDecoderRDH->feeId ||
153 rdh->orbit != mDecoderRDH->orbit) {
154 std::cout << colorRed
155 << "[FATAL] something does not match between this and first RDH"
156 << colorReset
157 << std::endl;
158 return true;
159 }
160
161 auto headerSize = rdh->headerSize;
162 auto memorySize = rdh->memorySize;
163 auto offsetToNext = rdh->offsetToNext;
164 auto drmPayload = memorySize - headerSize;
165
166 if (drmPayload < 0) {
167 LOG(warning) << "link = " << rdh->feeId << ": memorySize < headerSize (" << memorySize << " < " << headerSize << ")";
168 return true;
169 }
170
171 if (mDecoderSaveBufferDataSize + drmPayload >= mDecoderSaveBufferSize) {
172 // avoid to allocate memory out of the buffer
173 LOG(warning) << "link = " << rdh->feeId << ": beyond the buffer size " << mDecoderSaveBufferSize;
174 return true;
175 }
176
178 std::memcpy(mDecoderSaveBuffer + mDecoderSaveBufferDataSize, reinterpret_cast<const char*>(rdh) + headerSize, drmPayload);
179 mDecoderSaveBufferDataSize += drmPayload;
180
182 rdh = reinterpret_cast<const RDH*>(reinterpret_cast<const char*>(rdh) + offsetToNext);
185 if (reinterpret_cast<const char*>(rdh) < mDecoderBuffer + mDecoderBufferSize) {
186 continue;
187 }
188
190 return true;
191 }
192
193 if (verbose && mDecoderVerbose) {
194 std::cout << colorBlue
195 << "--- RDH close detected"
196 << colorReset
197 << std::endl;
199 }
200
202 if (rdh->feeId != mDecoderRDH->feeId ||
203 rdh->orbit != mDecoderRDH->orbit) {
204 std::cout << colorRed
205 << "[FATAL] something does not match between this and first RDH"
206 << colorReset
207 << std::endl;
208 return true;
209 }
210
213 if (mEncoderPointer + mDecoderRDH->headerSize >= mEncoderPointerMax) {
214 LOG(warning) << "link = " << rdh->feeId << ": beyond the buffer size mEncoderPointer+mDecoderRDH->headerSize = " << mEncoderPointer + mDecoderRDH->headerSize << " >= "
215 << "mEncoderPointerMax = " << mEncoderPointerMax;
216 encoderRewind();
217 return true;
218 }
219 std::memcpy(mEncoderPointer, mDecoderRDH, mDecoderRDH->headerSize);
220 mEncoderPointer = reinterpret_cast<uint32_t*>(reinterpret_cast<char*>(mEncoderPointer) + rdh->headerSize);
221
223 mDecoderPointer = reinterpret_cast<const uint32_t*>(mDecoderSaveBuffer);
224 mDecoderPointerMax = reinterpret_cast<const uint32_t*>(mDecoderSaveBuffer + mDecoderSaveBufferDataSize);
225 int nsteps = 0;
226 while (mDecoderPointer < mDecoderPointerMax) {
227 nsteps++;
228 if (nsteps > 3 && !(nsteps % 4)) {
229 LOG(debug) << "processHBF: nsteps in while loop = " << nsteps << ", infity loop?";
230 }
231 mEventCounter++;
232 if (processDRM()) { // if this breaks, we did not run the checker and the summary is not reset!
233 mDecoderSummary = {nullptr}; // reset it like this, perhaps a better way can be found
234 break;
235 }
236 }
237 mDecoderSaveBufferDataSize = 0;
238
240 if (mDecoderFatal) {
241 mFatalCounter++;
242 mEncoderPointer = mEncoderPointerStart;
243 mEncoderRDH->detectorField |= 0x00001000;
244 }
245
247 mEncoderRDH->memorySize = reinterpret_cast<char*>(mEncoderPointer) - reinterpret_cast<char*>(mEncoderRDH);
248 mEncoderRDH->offsetToNext = mEncoderRDH->memorySize;
249
250 if (mDecoderError) {
251 mErrorCounter++;
252 }
253
254 // before to move to RDH close check we are not already out of buffer (it is the last chance to call rewind and not to store RDH open)
255 if (mEncoderPointer >= mEncoderPointerMax) {
256 LOG(error) << "link = " << rdh->feeId << ": beyond the buffer size mEncoderPointer in RDH open = " << mEncoderPointer << " >= "
257 << "mEncoderPointerMax = " << mEncoderPointerMax;
258 long byteOutOfBuffer = mEncoderPointer + rdh->headerSize - mEncoderPointerMax;
259 LOG(error) << "byte out of buffer = " << byteOutOfBuffer;
260
261 encoderRewind();
262 return true;
263 }
264
267 if (mEncoderPointer + rdh->headerSize >= mEncoderPointerMax) {
268 LOG(warning) << "link = " << rdh->feeId << ": beyond the buffer size mEncoderPointer+rdh->headerSize = " << mEncoderPointer + rdh->headerSize << " >= "
269 << "mEncoderPointerMax = " << mEncoderPointerMax;
270 return true;
271 }
272 mEncoderRDH = reinterpret_cast<RDH*>(mEncoderPointer);
273 std::memcpy(mEncoderRDH, rdh, rdh->headerSize);
274 mEncoderRDH->memorySize = rdh->headerSize;
275 mEncoderRDH->offsetToNext = mEncoderRDH->memorySize;
276 mEncoderPointer = reinterpret_cast<uint32_t*>(reinterpret_cast<char*>(mEncoderPointer) + rdh->headerSize);
277
278 if (verbose && mDecoderVerbose) {
279 std::cout << colorBlue
280 << "--- END PROCESS HBF"
281 << colorReset
282 << std::endl;
283 }
284
286 mDecoderPointer = reinterpret_cast<const uint32_t*>(reinterpret_cast<const char*>(rdh) + rdh->offsetToNext);
287
289 if (reinterpret_cast<const char*>(mDecoderPointer) < mDecoderBuffer + mDecoderBufferSize) {
290 return false;
291 }
292
294 return true;
295}
296
297template <typename RDH, bool verbose, bool paranoid>
299{
300
301 if (verbose && mDecoderVerbose) {
302 std::cout << colorBlue << "--- PROCESS DRM"
303 << colorReset
304 << std::endl;
305 }
306
308 mDecoderNextWord = 1;
309 mDecoderError = false;
310 mDecoderFatal = false;
311 mEncoderPointerStart = mEncoderPointer;
312
314 if (!IS_DRM_COMMON_HEADER(*mDecoderPointer)) {
315 if (verbose) {
316 printf("%s %08x [ERROR] fatal error %s \n", colorRed, *mDecoderPointer, colorReset);
317 }
318 mDecoderFatal = true;
319 return true;
320 }
321 mDecoderSummary.tofDataHeader = mDecoderPointer;
322 if (verbose && mDecoderVerbose) {
323 auto tofDataHeader = reinterpret_cast<const raw::TOFDataHeader_t*>(mDecoderPointer);
324 auto bytePayload = tofDataHeader->bytePayload;
325 printf(" %08x TOF Data Header (bytePayload=%d) \n", *mDecoderPointer, bytePayload);
326 }
327 decoderNext();
328 if (paranoid && decoderParanoid()) {
329 return true;
330 }
331
333 mDecoderSummary.tofOrbit = mDecoderPointer;
334 if (verbose && mDecoderVerbose) {
335 auto tofOrbit = reinterpret_cast<const raw::TOFOrbit_t*>(mDecoderPointer);
336 auto orbit = tofOrbit->orbit;
337 printf(" %08x TOF Orbit (orbit=%u) \n", *mDecoderPointer, orbit);
338 }
339 decoderNext();
340 if (paranoid && decoderParanoid()) {
341 return true;
342 }
343
345 if (!IS_DRM_GLOBAL_HEADER(*mDecoderPointer)) {
346 if (verbose) {
347 printf("%s %08x [ERROR] fatal error %s \n", colorRed, *mDecoderPointer, colorReset);
348 }
349 mDecoderFatal = true;
350 return true;
351 }
352 mDecoderSummary.drmDataHeader = mDecoderPointer;
353 if (verbose && mDecoderVerbose) {
354 auto drmDataHeader = reinterpret_cast<const raw::DRMDataHeader_t*>(mDecoderPointer);
355 auto drmId = drmDataHeader->drmId;
356 auto eventWords = drmDataHeader->eventWords;
357 printf(" %08x DRM Data Header (drmId=%d, eventWords=%d) \n", *mDecoderPointer, drmId, eventWords);
358 }
359 decoderNext();
360 if (paranoid && decoderParanoid()) {
361 return true;
362 }
363
365 mDecoderSummary.drmHeadW1 = mDecoderPointer;
366 if (verbose && mDecoderVerbose) {
367 auto drmHeadW1 = reinterpret_cast<const raw::DRMHeadW1_t*>(mDecoderPointer);
368 auto partSlotMask = drmHeadW1->partSlotMask;
369 auto clockStatus = drmHeadW1->clockStatus;
370 auto drmHSize = drmHeadW1->drmHSize;
371 printf(" %08x DRM Header Word 1 (partSlotMask=0x%03x, clockStatus=%d, drmHSize=%d) \n", *mDecoderPointer, partSlotMask, clockStatus, drmHSize);
372 }
373 decoderNext();
374 if (paranoid && decoderParanoid()) {
375 return true;
376 }
377
379 mDecoderSummary.drmHeadW2 = mDecoderPointer;
380 if (verbose && mDecoderVerbose) {
381 auto drmHeadW2 = reinterpret_cast<const raw::DRMHeadW2_t*>(mDecoderPointer);
382 auto enaSlotMask = drmHeadW2->enaSlotMask;
383 auto faultSlotMask = drmHeadW2->faultSlotMask;
384 auto readoutTimeOut = drmHeadW2->readoutTimeOut;
385 printf(" %08x DRM Header Word 2 (enaSlotMask=0x%03x, faultSlotMask=0x%03x, readoutTimeOut=%d) \n", *mDecoderPointer, enaSlotMask, faultSlotMask, readoutTimeOut);
386 }
387 decoderNext();
388 if (paranoid && decoderParanoid()) {
389 return true;
390 }
391
393 mDecoderSummary.drmHeadW3 = mDecoderPointer;
394 if (verbose && mDecoderVerbose) {
395 auto drmHeadW3 = reinterpret_cast<const raw::DRMHeadW3_t*>(mDecoderPointer);
396 auto gbtBunchCnt = drmHeadW3->gbtBunchCnt;
397 auto locBunchCnt = drmHeadW3->locBunchCnt;
398 printf(" %08x DRM Header Word 3 (gbtBunchCnt=%d, locBunchCnt=%d) \n", *mDecoderPointer, gbtBunchCnt, locBunchCnt);
399 }
400 decoderNext();
401 if (paranoid && decoderParanoid()) {
402 return true;
403 }
404
406 mDecoderSummary.drmHeadW4 = mDecoderPointer;
407 if (verbose && mDecoderVerbose) {
408 printf(" %08x DRM Header Word 4 \n", *mDecoderPointer);
409 }
410 decoderNext();
411 if (paranoid && decoderParanoid()) {
412 return true;
413 }
414
416 mDecoderSummary.drmHeadW5 = mDecoderPointer;
417 if (verbose && mDecoderVerbose) {
418 printf(" %08x DRM Header Word 5 \n", *mDecoderPointer);
419 }
420 decoderNext();
421 if (paranoid && decoderParanoid()) {
422 return true;
423 }
424
426 *mEncoderPointer = 0x80000000;
427 *mEncoderPointer |= GET_DRMHEADW1_PARTSLOTMASK(*mDecoderSummary.drmHeadW1) << 12;
428 // R+OLD *mEncoderPointer |= GET_DRMDATAHEADER_DRMID(*mDecoderSummary.drmDataHeader) << 24;
429 *mEncoderPointer |= (mDecoderRDH->feeId & 0xFF) << 24;
430 *mEncoderPointer |= GET_DRMHEADW3_GBTBUNCHCNT(*mDecoderSummary.drmHeadW3);
431 if (verbose && mEncoderVerbose) {
432 auto crateHeader = reinterpret_cast<compressed::CrateHeader_t*>(mEncoderPointer);
433 auto bunchID = crateHeader->bunchID;
434 auto drmID = crateHeader->drmID;
435 auto slotPartMask = crateHeader->slotPartMask;
436 printf("%s %08x Crate header (drmID=%d, bunchID=%d, slotPartMask=0x%x) %s \n", colorGreen, *mEncoderPointer, drmID, bunchID, slotPartMask, colorReset);
437 }
438 if (encoderNext()) {
439 encoderRewind();
440 return true;
441 }
442
444 *mEncoderPointer = *mDecoderSummary.tofOrbit;
445 if (verbose && mEncoderVerbose) {
446 auto crateOrbit = reinterpret_cast<compressed::CrateOrbit_t*>(mEncoderPointer);
447 auto orbitID = crateOrbit->orbitID;
448 printf("%s %08x Crate orbit (orbitID=%u) %s \n", colorGreen, *mEncoderPointer, orbitID, colorReset);
449 }
450 if (encoderNext()) {
451 encoderRewind();
452 return true;
453 }
454
456 int nsteps = 0;
457 while (true) {
458 nsteps++;
459 if (nsteps > 19 && !(nsteps % 20)) {
460 LOG(debug) << "processDRM: nsteps in while loop = " << nsteps << ", infity loop?";
461 }
462
464 if (IS_LTM_GLOBAL_HEADER(*mDecoderPointer)) {
465 if (processLTM()) {
466 return true;
467 }
468 }
469
471 if (IS_TRM_GLOBAL_HEADER(*mDecoderPointer) && GET_TRMDATAHEADER_SLOTID(*mDecoderPointer) > 2) {
472 if (processTRM()) {
473 return true;
474 }
475 continue;
476 }
477
479 if (IS_DRM_GLOBAL_TRAILER(*mDecoderPointer)) {
480 mDecoderSummary.drmDataTrailer = mDecoderPointer;
481 if (verbose && mDecoderVerbose) {
482 auto drmDataTrailer = reinterpret_cast<const raw::DRMDataTrailer_t*>(mDecoderPointer);
483 auto locEvCnt = drmDataTrailer->locEvCnt;
484 printf(" %08x DRM Data Trailer (locEvCnt=%d) \n", *mDecoderPointer, locEvCnt);
485 }
486 decoderNext();
487
489 while ((mDecoderPointer < mDecoderPointerMax) && IS_FILLER(*mDecoderPointer)) {
490 if (verbose && mDecoderVerbose) {
491 printf(" %08x Filler \n", *mDecoderPointer);
492 }
493 decoderNext();
494 }
495
497 *mEncoderPointer = 0x80000000;
498 *mEncoderPointer |= GET_DRMDATATRAILER_LOCEVCNT(*mDecoderSummary.drmDataTrailer) << 4;
499
501 checkerCheck();
502 *mEncoderPointer |= mCheckerSummary.nDiagnosticWords;
503#if ENCODE_TDC_ERRORS
504 *mEncoderPointer |= (mCheckerSummary.nTDCErrors << 16);
505#endif
506
507 if (verbose && mEncoderVerbose) {
508 auto CrateTrailer = reinterpret_cast<compressed::CrateTrailer_t*>(mEncoderPointer);
509 auto EventCounter = CrateTrailer->eventCounter;
510 auto NumberOfDiagnostics = CrateTrailer->numberOfDiagnostics;
511 auto NumberOfErrors = CrateTrailer->numberOfErrors;
512 printf("%s %08x Crate trailer (EventCounter=%d, NumberOfDiagnostics=%d, NumberOfErrors=%d) %s \n", colorGreen, *mEncoderPointer, EventCounter, NumberOfDiagnostics, NumberOfErrors, colorReset);
513 }
514 if (encoderNext()) {
515 encoderRewind();
516 return true;
517 }
518
520 for (int iword = 0; iword < mCheckerSummary.nDiagnosticWords; ++iword) {
521 auto itrm = (mCheckerSummary.DiagnosticWord[iword] & 0xF) - 3;
522 *mEncoderPointer = mCheckerSummary.DiagnosticWord[iword];
523 if (verbose && mEncoderVerbose) {
524 auto Diagnostic = reinterpret_cast<compressed::Diagnostic_t*>(mEncoderPointer);
525 auto slotId = Diagnostic->slotID;
526 auto faultBits = Diagnostic->faultBits;
527 printf("%s %08x Diagnostic (slotId=%d, faultBits=0x%x) %s \n", colorGreen, *mEncoderPointer, slotId, faultBits, colorReset);
528 }
529 if (encoderNext()) {
530 encoderRewind();
531 return true;
532 }
533 }
534
536 for (int itrm = 0; itrm < 10; ++itrm) {
537 for (int ichain = 0; ichain < 2; ++ichain) {
538#if ENCODE_TDC_ERRORS
539 for (int ierror = 0; ierror < mDecoderSummary.trmErrors[itrm][ichain]; ++ierror) {
540 *mEncoderPointer = *mDecoderSummary.trmError[itrm][ichain][ierror];
541 *mEncoderPointer &= 0xFF07FFFF;
542 *mEncoderPointer |= ((itrm + 3) << 19);
543 *mEncoderPointer |= (ichain << 23);
544 if (verbose && mEncoderVerbose) {
545 auto Error = reinterpret_cast<compressed::Error_t*>(mEncoderPointer);
546 auto errorFlags = Error->errorFlags;
547 auto slotID = Error->slotID;
548 auto chain = Error->chain;
549 auto tdcID = Error->tdcID;
550 printf("%s %08x Error (slotId=%d, chain=%d, tdcId=%d, errorFlags=0x%x) %s \n", colorGreen, *mEncoderPointer, slotID, chain, tdcID, errorFlags, colorReset);
551 }
552 if (encoderNext()) {
553 encoderRewind();
554 return true;
555 }
556 }
557#endif
558 mDecoderSummary.trmErrors[itrm][ichain] = 0;
559 }
560 }
561
562 mCheckerSummary.nDiagnosticWords = 0;
563 mCheckerSummary.nTDCErrors = 0;
564
565 break;
566 }
567
569 if (IS_DRM_TEST_WORD(*mDecoderPointer)) {
570 if (verbose && mDecoderVerbose) {
571 printf(" %08x DRM Test Word \n", *mDecoderPointer);
572 }
573 decoderNext();
574 continue;
575 }
576
578 mDecoderError = true;
579 mDecoderSummary.drmDecodeError = true;
580
581 if (verbose && mDecoderVerbose) {
582 printf("%s %08x [ERROR] trying to recover DRM decode stream %s \n", colorRed, *mDecoderPointer, colorReset);
583 }
584
586 if (decoderParanoid()) {
587 return true;
588 }
589
590 decoderNext();
591
592 }
594 mIntegratedBytes += getDecoderByteCounter();
595
596 if (verbose && mDecoderVerbose) {
597 std::cout << colorBlue
598 << "--- END PROCESS DRM"
599 << colorReset
600 << std::endl;
601 }
602
603 return false;
604}
605
606template <typename RDH, bool verbose, bool paranoid>
608{
611 mDecoderSummary.ltmDataHeader = mDecoderPointer;
612 uint32_t eventWords = GET_LTMDATAHEADER_EVENTWORDS(*mDecoderPointer); // this is the total event size, including header/trailer
613 uint32_t payload = eventWords - 2;
614 if (verbose && mDecoderVerbose) {
615 auto ltmDataHeader = reinterpret_cast<const raw::LTMDataHeader_t*>(mDecoderPointer);
616 auto eventWords = ltmDataHeader->eventWords;
617 auto cycloneErr = ltmDataHeader->cycloneErr;
618 auto fault = ltmDataHeader->cycloneErr;
619 printf(" %08x LTM Data Header (eventWords=%d, cycloneErr=%d, fault=%d) \n", *mDecoderPointer, eventWords, cycloneErr, fault);
620 }
621 decoderNext();
622 if (paranoid && decoderParanoid()) {
623 return true;
624 }
625
627 for (int i = 0; i < payload; ++i) {
628 if (verbose && mDecoderVerbose) {
629 printf(" %08x LTM Data \n", *mDecoderPointer);
630 }
631 decoderNext();
632 if (paranoid && decoderParanoid()) {
633 return true;
634 }
635 }
636
638 if (IS_LTM_GLOBAL_TRAILER(*mDecoderPointer)) {
639 mDecoderSummary.ltmDataTrailer = mDecoderPointer;
640 if (verbose && mDecoderVerbose) {
641 printf(" %08x LTM Global Trailer \n", *mDecoderPointer);
642 }
643 decoderNext();
644 if (paranoid && decoderParanoid()) {
645 return true;
646 }
647 }
648
650 return false;
651}
652
653template <typename RDH, bool verbose, bool paranoid>
655{
658 uint32_t slotId = GET_TRMDATAHEADER_SLOTID(*mDecoderPointer);
659 int itrm = slotId - 3;
660 mDecoderSummary.trmDataHeader[itrm] = mDecoderPointer;
661 if (verbose && mDecoderVerbose) {
662 auto trmDataHeader = reinterpret_cast<const raw::TRMDataHeader_t*>(mDecoderPointer);
663 auto eventWords = trmDataHeader->eventWords;
664 auto eventCnt = trmDataHeader->eventCnt;
665 auto emptyBit = trmDataHeader->emptyBit;
666 printf(" %08x TRM Data Header (slotId=%u, eventWords=%d, eventCnt=%d, emptyBit=%01x) \n", *mDecoderPointer, slotId, eventWords, eventCnt, emptyBit);
667 }
668 decoderNext();
669 if (paranoid && decoderParanoid()) {
670 return true;
671 }
672
674 int nsteps = 0;
675 while (true) {
676 nsteps++;
677 if (nsteps > 19 && !(nsteps % 20)) {
678 LOG(debug) << "processTRM: nsteps in while loop = " << nsteps << ", infity loop?";
679 }
680
682 if (IS_TRM_CHAINA_HEADER(*mDecoderPointer) && GET_TRMCHAINHEADER_SLOTID(*mDecoderPointer) == slotId) {
683 if (processTRMchain(itrm, 0)) {
684 return true;
685 }
686 }
687
689 if (IS_TRM_CHAINB_HEADER(*mDecoderPointer) && GET_TRMCHAINHEADER_SLOTID(*mDecoderPointer) == slotId) {
690 if (processTRMchain(itrm, 1)) {
691 return true;
692 }
693 }
694
696 if (IS_TRM_GLOBAL_TRAILER(*mDecoderPointer)) {
697 mDecoderSummary.trmDataTrailer[itrm] = mDecoderPointer;
698 if (verbose && mDecoderVerbose) {
699 auto trmDataTrailer = reinterpret_cast<const raw::TRMDataTrailer_t*>(mDecoderPointer);
700 auto eventCRC = trmDataTrailer->eventCRC;
701 auto lutErrorBit = trmDataTrailer->lutErrorBit;
702 printf(" %08x TRM Data Trailer (slotId=%u, eventCRC=%d, lutErrorBit=%d) \n", *mDecoderPointer, slotId, eventCRC, lutErrorBit);
703 }
704 decoderNext();
705 if (paranoid && decoderParanoid()) {
706 return true;
707 }
708
710 if (IS_FILLER(*mDecoderPointer)) {
711 if (verbose && mDecoderVerbose) {
712 printf(" %08x Filler \n", *mDecoderPointer);
713 }
714 decoderNext();
715 if (paranoid && decoderParanoid()) {
716 return true;
717 }
718 }
719
721 if (mDecoderSummary.hasHits[itrm][0] || mDecoderSummary.hasHits[itrm][1]) {
722 if (encoderSpider(itrm)) {
723 encoderRewind();
724 return true;
725 }
726 }
727
729 return false;
730 }
731
733 mDecoderError = true;
734 mDecoderSummary.trmDecodeError[itrm] = true;
735 if (verbose && mDecoderVerbose) {
736 printf("%s %08x [ERROR] breaking TRM decode stream %s \n", colorRed, *mDecoderPointer, colorReset);
737 }
738 decoderNext();
739 if (decoderParanoid()) {
740 return true;
741 }
742
743 return false;
744
745 }
748 return false;
749}
750
751template <typename RDH, bool verbose, bool paranoid>
753{
756 int slotId = itrm + 3;
757
758 mDecoderSummary.trmChainHeader[itrm][ichain] = mDecoderPointer;
759 mDecoderSummary.hasHits[itrm][ichain] = false;
760 mDecoderSummary.hasErrors[itrm][ichain] = false;
761 if (verbose && mDecoderVerbose) {
762 auto trmChainHeader = reinterpret_cast<const raw::TRMChainHeader_t*>(mDecoderPointer);
763 auto bunchCnt = trmChainHeader->bunchCnt;
764 printf(" %08x TRM Chain-%c Header (slotId=%u, bunchCnt=%d) \n", *mDecoderPointer, ichain == 0 ? 'A' : 'B', slotId, bunchCnt);
765 }
766 decoderNext();
767 if (paranoid && decoderParanoid()) {
768 return true;
769 }
770
772 int nsteps = 0;
773 while (true) {
774 nsteps++;
775 if (nsteps > 99 && !(nsteps % 100)) {
776 LOG(debug) << "processTRMchain: nsteps in while loop = " << nsteps << ", infity loop?";
777 }
779 if (IS_TDC_HIT(*mDecoderPointer)) {
780 mDecoderSummary.hasHits[itrm][ichain] = true;
781 auto itdc = GET_TRMDATAHIT_TDCID(*mDecoderPointer);
782 auto ihit = mDecoderSummary.trmDataHits[ichain][itdc];
783 mDecoderSummary.trmDataHit[ichain][itdc][ihit] = mDecoderPointer;
784 mDecoderSummary.trmDataHits[ichain][itdc]++;
785 if (verbose && mDecoderVerbose) {
786 auto trmDataHit = reinterpret_cast<const raw::TRMDataHit_t*>(mDecoderPointer);
787 auto time = trmDataHit->time;
788 auto chanId = trmDataHit->chanId;
789 auto tdcId = trmDataHit->tdcId;
790 auto dataId = trmDataHit->dataId;
791 printf(" %08x TRM Data Hit (time=%d, chanId=%d, tdcId=%d, dataId=0x%x) \n", *mDecoderPointer, time, chanId, tdcId, dataId);
792 }
793 decoderNext();
794 if (paranoid && decoderParanoid()) {
795 return true;
796 }
797 continue;
798 }
799
801 if (IS_TDC_ERROR(*mDecoderPointer)) {
802 mDecoderSummary.hasErrors[itrm][ichain] = true;
803 auto ierror = mDecoderSummary.trmErrors[itrm][ichain];
804 mDecoderSummary.trmError[itrm][ichain][ierror] = mDecoderPointer;
805 mDecoderSummary.trmErrors[itrm][ichain]++;
806 if (verbose && mDecoderVerbose) {
807 printf("%s %08x TDC error %s \n", colorRed, *mDecoderPointer, colorReset);
808 }
809 decoderNext();
810 if (paranoid && decoderParanoid()) {
811 return true;
812 }
813 continue;
814 }
815
817 if (IS_TRM_CHAIN_TRAILER(*mDecoderPointer, ichain)) {
818 mDecoderSummary.trmChainTrailer[itrm][ichain] = mDecoderPointer;
819 if (verbose && mDecoderVerbose) {
820 auto trmChainTrailer = reinterpret_cast<const raw::TRMChainTrailer_t*>(mDecoderPointer);
821 auto eventCnt = trmChainTrailer->eventCnt;
822 printf(" %08x TRM Chain-A Trailer (slotId=%u, eventCnt=%d) \n", *mDecoderPointer, slotId, eventCnt);
823 }
824 decoderNext();
825 if (paranoid && decoderParanoid()) {
826 return true;
827 }
828 break;
829 }
830
832 mDecoderError = true;
833 mDecoderSummary.trmDecodeError[itrm] = true;
834 if (verbose && mDecoderVerbose) {
835 printf("%s %08x [ERROR] breaking TRM Chain-%c decode stream %s \n", colorRed, *mDecoderPointer, ichain == 0 ? 'A' : 'B', colorReset);
836 }
837 decoderNext();
838 if (decoderParanoid()) {
839 return true;
840 }
841
842 break;
843
844 }
847 return false;
848}
849
850template <typename RDH, bool verbose, bool paranoid>
852{
855 if (mDecoderPointer >= mDecoderPointerMax) {
856 if (verbose) {
857 printf("%s %08x [ERROR] fatal error: beyond memory size %s \n", colorRed, *mDecoderPointer, colorReset);
858 }
859 mDecoderFatal = true;
860 return true;
861 }
862 return false;
863}
864
865template <typename RDH, bool verbose, bool paranoid>
867{
870 int slotId = itrm + 3;
871
873 int firstFilledFrame = 255;
874 int lastFilledFrame = 0;
875
877 for (int ichain = 0; ichain < 2; ++ichain) {
878
879 if (!mDecoderSummary.hasHits[itrm][ichain]) {
880 continue;
881 }
882
884 for (int itdc = 0; itdc < 15; ++itdc) {
885
886 auto nhits = mDecoderSummary.trmDataHits[ichain][itdc];
887 if (nhits == 0) {
888 continue;
889 }
890
892 for (int ihit = 0; ihit < nhits; ++ihit) {
893
894 auto lhit = *mDecoderSummary.trmDataHit[ichain][itdc][ihit];
895 if (!IS_TDC_HIT_LEADING(lhit)) { // must be a leading hit
896 continue;
897 }
898
899 auto chan = GET_TRMDATAHIT_CHANID(lhit);
900 auto hitTime = GET_TRMDATAHIT_TIME(lhit);
901 auto eBit = GET_TRMDATAHIT_EBIT(lhit);
902 uint32_t totWidth = 0;
903
904 // check next hits for packing
905 for (int jhit = ihit + 1; jhit < nhits; ++jhit) {
906 auto thit = *mDecoderSummary.trmDataHit[ichain][itdc][jhit];
907 if (IS_TDC_HIT_TRAILING(thit) && GET_TRMDATAHIT_CHANID(thit) == chan) { // must be a trailing hit from same channel
908 totWidth = (GET_TRMDATAHIT_TIME(thit) - hitTime) / Geo::RATIO_TOT_TDC_BIN; // compute TOT
909 lhit = 0x0; // mark as used
910 break;
911 }
912 }
913
914 auto iframe = hitTime >> 13;
915 auto phit = mSpiderSummary.nFramePackedHits[iframe];
916
917 mSpiderSummary.FramePackedHit[iframe][phit] = 0x00000000;
918 mSpiderSummary.FramePackedHit[iframe][phit] |= (totWidth & 0x7FF) << 0;
919 mSpiderSummary.FramePackedHit[iframe][phit] |= (hitTime & 0x1FFF) << 11;
920 mSpiderSummary.FramePackedHit[iframe][phit] |= chan << 24;
921 mSpiderSummary.FramePackedHit[iframe][phit] |= itdc << 27;
922 mSpiderSummary.FramePackedHit[iframe][phit] |= ichain << 31;
923 mSpiderSummary.nFramePackedHits[iframe]++;
924
925 if (iframe < firstFilledFrame) {
926 firstFilledFrame = iframe;
927 }
928 if (iframe > lastFilledFrame) {
929 lastFilledFrame = iframe;
930 }
931 }
932
933 mDecoderSummary.trmDataHits[ichain][itdc] = 0;
934 }
935 }
936
938 for (int iframe = firstFilledFrame; iframe < lastFilledFrame + 1; iframe++) {
939
941 if (mSpiderSummary.nFramePackedHits[iframe] == 0) {
942 continue;
943 }
944
945 // encode Frame Header
946 *mEncoderPointer = 0x00000000;
947 *mEncoderPointer |= slotId << 24;
948 *mEncoderPointer |= iframe << 16;
949 *mEncoderPointer |= mSpiderSummary.nFramePackedHits[iframe];
950 if (verbose && mEncoderVerbose) {
951 auto FrameHeader = reinterpret_cast<const compressed::FrameHeader_t*>(mEncoderPointer);
952 auto NumberOfHits = FrameHeader->numberOfHits;
953 auto FrameID = FrameHeader->frameID;
954 auto TRMID = FrameHeader->trmID;
955 printf("%s %08x Frame header (TRMID=%d, FrameID=%d, NumberOfHits=%d) %s \n", colorGreen, *mEncoderPointer, TRMID, FrameID, NumberOfHits, colorReset);
956 }
957 if (encoderNext()) {
958 encoderRewind();
959 return true;
960 }
961
962 // packed hits
963 for (int ihit = 0; ihit < mSpiderSummary.nFramePackedHits[iframe]; ++ihit) {
964 *mEncoderPointer = mSpiderSummary.FramePackedHit[iframe][ihit];
965 if (verbose && mEncoderVerbose) {
966 auto PackedHit = reinterpret_cast<const compressed::PackedHit_t*>(mEncoderPointer);
967 auto Chain = PackedHit->chain;
968 auto TDCID = PackedHit->tdcID;
969 auto Channel = PackedHit->channel;
970 auto Time = PackedHit->time;
971 auto TOT = PackedHit->tot;
972 printf("%s %08x Packed hit (Chain=%d, TDCID=%d, Channel=%d, Time=%d, TOT=%d) %s \n", colorGreen, *mEncoderPointer, Chain, TDCID, Channel, Time, TOT, colorReset);
973 }
974 if (encoderNext()) {
975 encoderRewind();
976 return true;
977 }
978 }
979
980 mSpiderSummary.nFramePackedHits[iframe] = 0;
981 }
982 return 0;
983}
984
985template <typename RDH, bool verbose, bool paranoid>
987{
990 mCheckerSummary.nDiagnosticWords = 0;
991
992 if (verbose && mCheckerVerbose) {
993 std::cout << colorBlue
994 << "--- CHECK EVENT"
995 << colorReset
996 << std::endl;
997 }
998
1000 // mCheckerCounter++;
1001
1005 mCheckerSummary.DiagnosticWord[0] = 0x00000001;
1006
1008 if (verbose && mCheckerVerbose) {
1009 printf(" --- Checking DRM Data Header: %p \n", mDecoderSummary.drmDataHeader);
1010 }
1011 if (!mDecoderSummary.drmDataHeader) {
1012 mCheckerSummary.DiagnosticWord[0] |= diagnostic::DRM_HEADER_MISSING;
1013 if (verbose && mCheckerVerbose) {
1014 printf(" Missing DRM Data Header \n");
1015 }
1016 mDecoderSummary = {nullptr};
1017 mCheckerSummary.nDiagnosticWords++;
1018 for (int itrm = 0; itrm < 10; ++itrm) {
1019 mDecoderSummary.trmDataHeader[itrm] = nullptr;
1020 mDecoderSummary.trmDataTrailer[itrm] = nullptr;
1021 for (int ichain = 0; ichain < 2; ++ichain) {
1022 mDecoderSummary.trmChainHeader[itrm][ichain] = nullptr;
1023 mDecoderSummary.trmChainTrailer[itrm][ichain] = nullptr;
1024 mDecoderSummary.trmErrors[itrm][ichain] = 0;
1025 mDecoderSummary.trmErrors[itrm][ichain] = 0;
1026 }
1027 }
1028 return true;
1029 }
1030
1032 if (mDecoderSummary.drmDecodeError) {
1033 mCheckerSummary.DiagnosticWord[0] |= diagnostic::DRM_DECODE_ERROR;
1034 if (verbose && mCheckerVerbose) {
1035 printf(" DRM decode error \n");
1036 }
1037 mDecoderSummary.drmDecodeError = false;
1038 }
1039
1041 if (verbose && mCheckerVerbose) {
1042 printf(" --- Checking DRM Data Trailer: %p \n", mDecoderSummary.drmDataTrailer);
1043 }
1044 if (!mDecoderSummary.drmDataTrailer) {
1045 mCheckerSummary.DiagnosticWord[0] |= diagnostic::DRM_TRAILER_MISSING;
1046 if (verbose && mCheckerVerbose) {
1047 printf(" Missing DRM Data Trailer \n");
1048 }
1049 mDecoderSummary = {nullptr};
1050 mCheckerSummary.nDiagnosticWords++;
1051
1052 return true;
1053 }
1054
1056 uint32_t partSlotMask = GET_DRMHEADW1_PARTSLOTMASK(*mDecoderSummary.drmHeadW1) & 0x7FE; // remove LTM bit
1057 uint32_t enaSlotMask = GET_DRMHEADW2_ENASLOTMASK(*mDecoderSummary.drmHeadW2) & 0x7FE; // remove LTM bit
1058 uint32_t gbtBunchCnt = GET_DRMHEADW3_GBTBUNCHCNT(*mDecoderSummary.drmHeadW3);
1059 uint32_t locEvCnt = GET_DRMDATATRAILER_LOCEVCNT(*mDecoderSummary.drmDataTrailer);
1060
1062 if (!mDecoderCONET) {
1063 checkerCheckRDH();
1064 }
1065
1067 if (verbose && mCheckerVerbose) {
1068 printf(" --- Checking Enable/participating mask: %03x/%03x \n", enaSlotMask, partSlotMask);
1069 }
1070 if (partSlotMask != enaSlotMask) {
1071 if (verbose && mCheckerVerbose) {
1072 printf(" Enable/participating mask differ: %03x/%03x \n", enaSlotMask, partSlotMask);
1073 }
1074 mCheckerSummary.DiagnosticWord[0] |= diagnostic::DRM_ENAPARTMASK_DIFFER;
1075 }
1076
1078 if (verbose && mCheckerVerbose) {
1079 printf(" --- Checking DRM clock status: %d \n", GET_DRMHEADW1_CLOCKSTATUS(*mDecoderSummary.drmHeadW1));
1080 }
1081 if (GET_DRMHEADW1_CLOCKSTATUS(*mDecoderSummary.drmHeadW1) != 2) {
1082 mCheckerSummary.DiagnosticWord[0] |= diagnostic::DRM_CLOCKSTATUS_WRONG;
1083 if (verbose && mCheckerVerbose) {
1084 printf("%s DRM wrong clock status: %d %s\n", colorRed, GET_DRMHEADW1_CLOCKSTATUS(*mDecoderSummary.drmHeadW1), colorReset);
1085 }
1086 }
1087
1089 if (verbose && mCheckerVerbose) {
1090 printf(" --- Checking DRM fault slot mask: %x \n", GET_DRMHEADW2_FAULTSLOTMASK(*mDecoderSummary.drmHeadW2));
1091 }
1092 if (GET_DRMHEADW2_FAULTSLOTMASK(*mDecoderSummary.drmHeadW2)) {
1093 mCheckerSummary.DiagnosticWord[0] |= diagnostic::DRM_FAULTSLOTMASK_NOTZERO;
1094 if (verbose && mCheckerVerbose) {
1095 printf(" DRM fault slot mask: %x \n", GET_DRMHEADW2_FAULTSLOTMASK(*mDecoderSummary.drmHeadW2));
1096 }
1097 }
1098
1100 if (verbose && mCheckerVerbose) {
1101 printf(" --- Checking DRM readout timeout: %d \n", GET_DRMHEADW2_READOUTTIMEOUT(*mDecoderSummary.drmHeadW2));
1102 }
1103 if (GET_DRMHEADW2_READOUTTIMEOUT(*mDecoderSummary.drmHeadW2)) {
1104 mCheckerSummary.DiagnosticWord[0] |= diagnostic::DRM_READOUTTIMEOUT_NOTZERO;
1105 if (verbose && mCheckerVerbose) {
1106 printf(" DRM readout timeout \n");
1107 }
1108 }
1109
1111 auto drmEventWords = mDecoderSummary.drmDataTrailer - mDecoderSummary.drmDataHeader + 1;
1112 if (mDecoderNextWordStep) {
1113 drmEventWords -= (drmEventWords / 4) * 2;
1114 }
1115 drmEventWords -= 6;
1116 if (verbose && mCheckerVerbose) {
1117 printf(" --- Checking DRM declared/detected event words: %u/%ld \n", GET_DRMDATAHEADER_EVENTWORDS(*mDecoderSummary.drmDataHeader), drmEventWords);
1118 }
1119 if (GET_DRMDATAHEADER_EVENTWORDS(*mDecoderSummary.drmDataHeader) != drmEventWords) {
1120 mCheckerSummary.DiagnosticWord[0] |= diagnostic::DRM_EVENTWORDS_MISMATCH;
1121 if (verbose && mCheckerVerbose) {
1122 printf(" DRM declared/detected event words mismatch: %u/%ld \n", GET_DRMDATAHEADER_EVENTWORDS(*mDecoderSummary.drmDataHeader), drmEventWords);
1123 }
1124 }
1125
1127 auto iword = mCheckerSummary.nDiagnosticWords;
1128 if (mCheckerSummary.DiagnosticWord[iword] & 0xFFFFFFF0) {
1129 mCheckerSummary.nDiagnosticWords++;
1130 iword++;
1131 }
1132
1134 mCheckerSummary.DiagnosticWord[iword] = 0x00000002;
1135
1137 if (!(partSlotMask & 1)) {
1138 if (mDecoderSummary.ltmDataHeader != nullptr) {
1139 mCheckerSummary.DiagnosticWord[iword] |= diagnostic::LTM_HEADER_UNEXPECTED;
1140 if (verbose && mCheckerVerbose) {
1141 printf(" Non-participating LTM header found \n");
1142 }
1143 }
1144 } else {
1146 if (verbose && mCheckerVerbose) {
1147 printf(" --- Checking LTM Data Header: %p \n", mDecoderSummary.ltmDataHeader);
1148 }
1149 if (!mDecoderSummary.ltmDataHeader) {
1150 mCheckerSummary.DiagnosticWord[iword] |= diagnostic::LTM_HEADER_MISSING;
1151 if (verbose && mCheckerVerbose) {
1152 printf(" Missing LTM Data Header \n");
1153 }
1154 }
1155
1157 if (verbose && mCheckerVerbose) {
1158 printf(" --- Checking LTM Data Trailer: %p \n", mDecoderSummary.ltmDataTrailer);
1159 }
1160 if (!mDecoderSummary.ltmDataTrailer) {
1161 mCheckerSummary.DiagnosticWord[iword] |= diagnostic::LTM_TRAILER_MISSING;
1162 if (verbose && mCheckerVerbose) {
1163 printf(" Missing LTM Data Trailer \n");
1164 }
1165 }
1166 }
1167
1169 mDecoderSummary.ltmDataHeader = nullptr;
1170 mDecoderSummary.ltmDataTrailer = nullptr;
1171
1173 for (int itrm = 0; itrm < 10; ++itrm) {
1174 uint32_t slotId = itrm + 3;
1175
1177 if (mCheckerSummary.DiagnosticWord[iword] & 0xFFFFFFF0) {
1178 mCheckerSummary.nDiagnosticWords++;
1179 iword++;
1180 }
1181
1183 mCheckerSummary.DiagnosticWord[iword] = slotId;
1184
1186 if (!(partSlotMask & 1 << (itrm + 1))) {
1187 if (mDecoderSummary.trmDataHeader[itrm]) {
1188 mCheckerSummary.DiagnosticWord[iword] |= diagnostic::TRM_HEADER_UNEXPECTED;
1189 if (verbose && mCheckerVerbose) {
1190 printf(" Non-participating header found (slotId=%u) \n", slotId);
1191 }
1192 } else {
1193 continue;
1194 }
1195 }
1196
1198 if (GET_DRMHEADW2_FAULTSLOTMASK(*mDecoderSummary.drmHeadW2) & 1 << (itrm + 1)) {
1199 mCheckerSummary.DiagnosticWord[iword] |= diagnostic::TRM_FAULTSLOTBIT_NOTZERO;
1200 if (verbose && mCheckerVerbose) {
1201 printf(" Fault slot bit set (slotId=%u) \n", slotId);
1202 }
1203 }
1204
1206 if (!mDecoderSummary.trmDataHeader[itrm]) {
1207 mCheckerSummary.DiagnosticWord[iword] |= diagnostic::TRM_HEADER_MISSING;
1208 if (verbose && mCheckerVerbose) {
1209 printf(" Missing TRM Data Header (slotId=%u) \n", slotId);
1210 }
1211 mDecoderSummary.trmErrors[itrm][0] = 0;
1212 mDecoderSummary.trmErrors[itrm][1] = 0;
1213 continue;
1214 }
1215
1217 if (mDecoderSummary.trmDecodeError[itrm]) {
1218 mCheckerSummary.DiagnosticWord[iword] |= diagnostic::TRM_DECODE_ERROR;
1219 if (verbose && mCheckerVerbose) {
1220 printf(" Decode error in TRM (slotId=%u) \n", slotId);
1221 }
1222 mDecoderSummary.trmDecodeError[itrm] = false;
1223 }
1224
1226 if (!mDecoderSummary.trmDataTrailer[itrm]) {
1227 mCheckerSummary.DiagnosticWord[iword] |= diagnostic::TRM_TRAILER_MISSING;
1228 if (verbose && mCheckerVerbose) {
1229 printf(" Missing TRM Trailer (slotId=%u) \n", slotId);
1230 }
1231 mDecoderSummary.trmDataHeader[itrm] = nullptr;
1232 mDecoderSummary.trmErrors[itrm][0] = 0;
1233 mDecoderSummary.trmErrors[itrm][1] = 0;
1234 continue;
1235 }
1236
1238#ifdef CHECKER_COUNTER
1239 mTRMCounters[itrm].Headers++;
1240#endif
1241
1243#ifdef CHECKER_COUNTER
1244 if (!mDecoderSummary.hasHits[itrm][0] && !mDecoderSummary.hasHits[itrm][1])
1245 mTRMCounters[itrm].Empty++;
1246#endif
1247
1249 uint32_t eventCnt = GET_TRMDATAHEADER_EVENTCNT(*mDecoderSummary.trmDataHeader[itrm]);
1250 if (eventCnt != locEvCnt % 1024) {
1251 mCheckerSummary.DiagnosticWord[iword] |= diagnostic::TRM_EVENTCNT_MISMATCH;
1252#ifdef CHECKER_COUNTER
1253 mTRMCounters[itrm].EventCounterMismatch++;
1254#endif
1255 if (verbose && mCheckerVerbose) {
1256 printf(" TRM EventCounter / DRM LocalEventCounter mismatch: %u / %u (slotId=%u) \n", eventCnt, locEvCnt, slotId);
1257 }
1258 }
1259
1261 if (GET_TRMDATAHEADER_EMPTYBIT(*mDecoderSummary.trmDataHeader[itrm])) {
1262 mCheckerSummary.DiagnosticWord[iword] |= diagnostic::TRM_EMPTYBIT_NOTZERO;
1263#ifdef CHECKER_COUNTER
1264 mTRMCounters[itrm].EBit++;
1265#endif
1266 if (verbose && mCheckerVerbose) {
1267 printf(" TRM empty bit is on (slotId=%u) \n", slotId);
1268 }
1269 }
1270
1272 auto trmEventWords = mDecoderSummary.trmDataTrailer[itrm] - mDecoderSummary.trmDataHeader[itrm] + 1;
1273 if (mDecoderNextWordStep) {
1274 trmEventWords -= (trmEventWords / 4) * 2;
1275 }
1276 if (verbose && mCheckerVerbose) {
1277 printf(" --- Checking TRM (slotId=%u) declared/detected event words: %d/%ld \n", slotId, GET_TRMDATAHEADER_EVENTWORDS(*mDecoderSummary.trmDataHeader[itrm]), trmEventWords);
1278 }
1279 if (GET_TRMDATAHEADER_EVENTWORDS(*mDecoderSummary.trmDataHeader[itrm]) != trmEventWords) {
1280 mCheckerSummary.DiagnosticWord[iword] |= diagnostic::TRM_EVENTWORDS_MISMATCH;
1281 if (verbose && mCheckerVerbose) {
1282 printf(" TRM (slotId=%u) declared/detected event words mismatch: %d/%ld \n", slotId, GET_TRMDATAHEADER_EVENTWORDS(*mDecoderSummary.trmDataHeader[itrm]), trmEventWords);
1283 }
1284 }
1285
1287 for (int ichain = 0; ichain < 2; ichain++) {
1288
1290 if (!mDecoderSummary.trmChainHeader[itrm][ichain]) {
1291 mCheckerSummary.DiagnosticWord[iword] |= (diagnostic::TRMCHAIN_HEADER_MISSING << (ichain * 8));
1292 if (verbose && mCheckerVerbose) {
1293 printf(" Missing TRM Chain Header (slotId=%u, chain=%d) \n", slotId, ichain);
1294 }
1295 mDecoderSummary.trmErrors[itrm][ichain] = 0;
1296 continue;
1297 }
1298
1300 if (!mDecoderSummary.trmChainTrailer[itrm][ichain]) {
1301 mCheckerSummary.DiagnosticWord[iword] |= (diagnostic::TRMCHAIN_TRAILER_MISSING << (ichain * 8));
1302 if (verbose && mCheckerVerbose) {
1303 printf(" Missing TRM Chain Trailer (slotId=%u, chain=%d) \n", slotId, ichain);
1304 }
1305 mDecoderSummary.trmChainHeader[itrm][ichain] = nullptr;
1306 mDecoderSummary.trmErrors[itrm][ichain] = 0;
1307 continue;
1308 }
1309
1311#ifdef CHECKER_COUNTER
1312 mTRMChainCounters[itrm][ichain].Headers++;
1313#endif
1314
1316 if (mDecoderSummary.hasErrors[itrm][ichain]) {
1317 mCheckerSummary.DiagnosticWord[iword] |= (diagnostic::TRMCHAIN_TDCERROR_DETECTED << (ichain * 8));
1318 mCheckerSummary.nTDCErrors += mDecoderSummary.trmErrors[itrm][ichain];
1319#ifdef CHECKER_COUNTER
1320 mTRMChainCounters[itrm][ichain].TDCerror++;
1321#endif
1322 if (verbose && mCheckerVerbose) {
1323 printf(" TDC error detected (slotId=%u, chain=%d) \n", slotId, ichain);
1324 }
1325 }
1326
1328 uint32_t eventCnt = GET_TRMCHAINTRAILER_EVENTCNT(*mDecoderSummary.trmChainTrailer[itrm][ichain]);
1329 if (eventCnt != locEvCnt) {
1330 mCheckerSummary.DiagnosticWord[iword] |= (diagnostic::TRMCHAIN_EVENTCNT_MISMATCH << (ichain * 8));
1331#ifdef CHECKER_COUNTER
1332 mTRMChainCounters[itrm][ichain].EventCounterMismatch++;
1333#endif
1334 if (verbose && mCheckerVerbose) {
1335 printf(" TRM Chain EventCounter / DRM LocalEventCounter mismatch: %u / %u (slotId=%u, chain=%d) \n", eventCnt, locEvCnt, slotId, ichain);
1336 }
1337 }
1338
1340 uint32_t status = GET_TRMCHAINTRAILER_STATUS(*mDecoderSummary.trmChainTrailer[itrm][ichain]);
1341 if (status != 0) {
1342 mCheckerSummary.DiagnosticWord[iword] |= (diagnostic::TRMCHAIN_STATUS_NOTZERO << (ichain * 8));
1343#ifdef CHECKER_COUNTER
1344 mTRMChainCounters[itrm][ichain].BadStatus++;
1345#endif
1346 if (verbose && mCheckerVerbose) {
1347 printf(" TRM Chain bad Status: %u (slotId=%u, chain=%d) \n", status, slotId, ichain);
1348 }
1349 }
1350
1352 uint32_t bunchCnt = GET_TRMCHAINHEADER_BUNCHCNT(*mDecoderSummary.trmChainHeader[itrm][ichain]);
1353 if (bunchCnt != gbtBunchCnt) {
1354 mCheckerSummary.DiagnosticWord[iword] |= (diagnostic::TRMCHAIN_BUNCHCNT_MISMATCH << (ichain * 8));
1355#ifdef CHECKER_COUNTER
1356 mTRMChainCounters[itrm][ichain].BunchIDMismatch++;
1357#endif
1358 if (verbose && mCheckerVerbose) {
1359 printf(" TRM Chain BunchID / DRM L0BCID mismatch: %u / %u (slotId=%u, chain=%d) \n", bunchCnt, gbtBunchCnt, slotId, ichain);
1360 }
1361 }
1362
1364 mDecoderSummary.trmChainHeader[itrm][ichain] = nullptr;
1365 mDecoderSummary.trmChainTrailer[itrm][ichain] = nullptr;
1366
1367 }
1370 mDecoderSummary.trmDataHeader[itrm] = nullptr;
1371 mDecoderSummary.trmDataTrailer[itrm] = nullptr;
1372
1373 }
1376 if (mCheckerSummary.DiagnosticWord[iword] & 0xFFFFFFF0) {
1377 mCheckerSummary.nDiagnosticWords++;
1378 }
1379
1380 if (verbose && mCheckerVerbose) {
1381 std::cout << colorBlue
1382 << "--- END CHECK EVENT: " << mCheckerSummary.nDiagnosticWords << " diagnostic words"
1383 << colorReset
1384 << std::endl;
1385 }
1386
1388 mDecoderSummary.tofDataHeader = nullptr;
1389 mDecoderSummary.drmDataHeader = nullptr;
1390 mDecoderSummary.drmDataTrailer = nullptr;
1391
1392 return false;
1393}
1394
1395template <typename RDH, bool verbose, bool paranoid>
1397{
1398 uint32_t orbit = *mDecoderSummary.tofOrbit;
1399 uint32_t drmId = GET_DRMDATAHEADER_DRMID(*mDecoderSummary.drmDataHeader);
1400
1402 if (verbose && mCheckerVerbose) {
1403 printf(" --- Checking DRM/RDH orbit: %08x/%08x \n", orbit, mDecoderRDH->orbit);
1404 }
1405 if (orbit != mDecoderRDH->orbit) {
1406 if (verbose && mCheckerVerbose) {
1407 printf(" DRM/RDH orbit mismatch: %08x/%08x \n", orbit, mDecoderRDH->orbit);
1408 }
1409 mCheckerSummary.DiagnosticWord[0] |= diagnostic::DRM_ORBIT_MISMATCH;
1410 }
1411
1413 if (verbose && mCheckerVerbose) {
1414 printf(" --- Checking DRM/RDH FEE id: %d/%d \n", drmId, mDecoderRDH->feeId & 0xFF);
1415 }
1416 if (drmId != (mDecoderRDH->feeId & 0xFF)) {
1417 if (verbose && mCheckerVerbose) {
1418 printf(" DRM/RDH FEE id mismatch: %d/%d \n", drmId, mDecoderRDH->feeId & 0xFF);
1419 }
1420 mCheckerSummary.DiagnosticWord[0] |= diagnostic::DRM_FEEID_MISMATCH;
1421 }
1422}
1423
1424template <typename RDH, bool verbose, bool paranoid>
1426{
1427 mEventCounter = 0;
1428 mFatalCounter = 0;
1429 mErrorCounter = 0;
1430 mDRMCounters = {0};
1431 for (int itrm = 0; itrm < 10; ++itrm) {
1432 mTRMCounters[itrm] = {0};
1433 for (int ichain = 0; ichain < 2; ++ichain) {
1434 mTRMChainCounters[itrm][ichain] = {0};
1435 }
1436 }
1437}
1438
1439template <typename RDH, bool verbose, bool paranoid>
1441{
1442 char chname[2] = {'a', 'b'};
1443
1444 std::cout << colorBlue
1445 << "--- SUMMARY COUNTERS: " << mEventCounter << " events "
1446 << " | " << mFatalCounter << " decode fatals "
1447 << " | " << mErrorCounter << " decode errors "
1448 << colorReset
1449 << std::endl;
1450#ifndef CHECKER_COUNTER
1451 return;
1452#endif
1453 if (mEventCounter == 0) {
1454 return;
1455 }
1456 printf("\n");
1457 printf(" DRM ");
1458 float drmheaders = 100. * (float)mDRMCounters.Headers / (float)mEventCounter;
1459 printf(" \033%sheaders: %5.1f %%\033[0m ", drmheaders < 100. ? "[1;31m" : "[0m", drmheaders);
1460 if (mDRMCounters.Headers == 0) {
1461 printf("\n");
1462 return;
1463 }
1464 float cbit = 100. * (float)mDRMCounters.clockStatus / float(mDRMCounters.Headers);
1465 printf(" \033%sCbit: %5.1f %%\033[0m ", cbit > 0. ? "[1;31m" : "[0m", cbit);
1466 float fault = 100. * (float)mDRMCounters.Fault / float(mDRMCounters.Headers);
1467 printf(" \033%sfault: %5.1f %%\033[0m ", fault > 0. ? "[1;31m" : "[0m", cbit);
1468 float rtobit = 100. * (float)mDRMCounters.RTOBit / float(mDRMCounters.Headers);
1469 printf(" \033%sRTObit: %5.1f %%\033[0m ", rtobit > 0. ? "[1;31m" : "[0m", cbit);
1470 printf("\n");
1471 // std::cout << "-----------------------------------------------------------" << std::endl;
1472 // printf(" LTM | headers: %5.1f %% \n", 0.);
1473 for (int itrm = 0; itrm < 10; ++itrm) {
1474 printf("\n");
1475 printf(" %2d TRM ", itrm + 3);
1476 float trmheaders = 100. * (float)mTRMCounters[itrm].Headers / float(mDRMCounters.Headers);
1477 printf(" \033%sheaders: %5.1f %%\033[0m ", trmheaders < 100. ? "[1;31m" : "[0m", trmheaders);
1478 if (mTRMCounters[itrm].Headers == 0.) {
1479 printf("\n");
1480 continue;
1481 }
1482 float empty = 100. * (float)mTRMCounters[itrm].Empty / (float)mTRMCounters[itrm].Headers;
1483 printf(" \033%sempty: %5.1f %%\033[0m ", empty > 0. ? "[1;31m" : "[0m", empty);
1484 float evCount = 100. * (float)mTRMCounters[itrm].EventCounterMismatch / (float)mTRMCounters[itrm].Headers;
1485 printf(" \033%sevCount: %5.1f %%\033[0m ", evCount > 0. ? "[1;31m" : "[0m", evCount);
1486 float ebit = 100. * (float)mTRMCounters[itrm].EBit / (float)mTRMCounters[itrm].Headers;
1487 printf(" \033%sEbit: %5.1f %%\033[0m ", ebit > 0. ? "[1;31m" : "[0m", ebit);
1488 printf(" \n");
1489 for (int ichain = 0; ichain < 2; ++ichain) {
1490 printf(" %c ", chname[ichain]);
1491 float chainheaders = 100. * (float)mTRMChainCounters[itrm][ichain].Headers / (float)mTRMCounters[itrm].Headers;
1492 printf(" \033%sheaders: %5.1f %%\033[0m ", chainheaders < 100. ? "[1;31m" : "[0m", chainheaders);
1493 if (mTRMChainCounters[itrm][ichain].Headers == 0) {
1494 printf("\n");
1495 continue;
1496 }
1497 float status = 100. * mTRMChainCounters[itrm][ichain].BadStatus / (float)mTRMChainCounters[itrm][ichain].Headers;
1498 printf(" \033%sstatus: %5.1f %%\033[0m ", status > 0. ? "[1;31m" : "[0m", status);
1499 float bcid = 100. * mTRMChainCounters[itrm][ichain].BunchIDMismatch / (float)mTRMChainCounters[itrm][ichain].Headers;
1500 printf(" \033%sbcID: %5.1f %%\033[0m ", bcid > 0. ? "[1;31m" : "[0m", bcid);
1501 float tdcerr = 100. * mTRMChainCounters[itrm][ichain].TDCerror / (float)mTRMChainCounters[itrm][ichain].Headers;
1502 printf(" \033%sTDCerr: %5.1f %%\033[0m ", tdcerr > 0. ? "[1;31m" : "[0m", tdcerr);
1503 printf("\n");
1504 }
1505 }
1506 printf("\n");
1507}
1508
1513
1514} // namespace tof
1515} // namespace o2
#define IS_DRM_GLOBAL_TRAILER(x)
#define GET_DRMHEADW2_READOUTTIMEOUT(x)
#define GET_TRMDATAHIT_TDCID(x)
#define GET_DRMDATATRAILER_LOCEVCNT(x)
#define GET_TRMDATAHIT_CHANID(x)
#define GET_DRMHEADW1_PARTSLOTMASK(x)
#define IS_TDC_ERROR(x)
#define GET_TRMDATAHEADER_EVENTWORDS(x)
#define GET_DRMHEADW2_ENASLOTMASK(x)
#define GET_TRMDATAHEADER_EVENTCNT(x)
#define IS_TRM_CHAINA_HEADER(x)
#define colorBlue
#define GET_DRMDATAHEADER_EVENTWORDS(x)
#define GET_DRMHEADW1_CLOCKSTATUS(x)
#define IS_FILLER(x)
#define IS_TRM_CHAINB_HEADER(x)
#define GET_TRMCHAINTRAILER_STATUS(x)
#define GET_TRMCHAINHEADER_SLOTID(x)
#define IS_LTM_GLOBAL_HEADER(x)
#define GET_DRMDATAHEADER_DRMID(x)
#define IS_TRM_CHAIN_TRAILER(x, c)
#define IS_TRM_GLOBAL_HEADER(x)
#define IS_TDC_HIT_TRAILING(x)
#define GET_TRMDATAHEADER_EMPTYBIT(x)
#define colorGreen
#define IS_TDC_HIT_LEADING(x)
#define GET_DRMHEADW2_FAULTSLOTMASK(x)
#define GET_TRMCHAINHEADER_BUNCHCNT(x)
#define GET_LTMDATAHEADER_EVENTWORDS(x)
#define IS_TDC_HIT(x)
#define IS_DRM_TEST_WORD(x)
#define colorRed
#define IS_LTM_GLOBAL_TRAILER(x)
#define IS_DRM_COMMON_HEADER(x)
#define colorReset
#define GET_TRMDATAHIT_EBIT(x)
#define IS_TRM_GLOBAL_TRAILER(x)
#define GET_TRMDATAHIT_TIME(x)
#define GET_DRMHEADW3_GBTBUNCHCNT(x)
#define IS_DRM_GLOBAL_HEADER(x)
#define GET_TRMCHAINTRAILER_EVENTCNT(x)
#define GET_TRMDATAHEADER_SLOTID(x)
TOF raw data compressor.
uint64_t orbit
Definition RawEventData.h:6
int16_t time
Definition RawEventData.h:4
int32_t i
GPUChain * chain
std::ostringstream debug
int encoderSpider(int itrm)
bool processTRMchain(int itrm, int ichain)
Diagnostic class for TOF.
Definition Diagnostic.h:32
static constexpr Int_t RATIO_TOT_TDC_BIN
Definition Geo.h:152
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
void empty(int)
static void printRDH(const RDHv4 &rdh)
Definition RDHUtils.cxx:26
static bool checkRDH(const RDHv4 &rdh, bool verbose=true, bool checkZeros=false)
Definition RDHUtils.cxx:133
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"