Project
Loading...
Searching...
No Matches
RawPixelDecoder.cxx
Go to the documentation of this file.
1// Copyright 2019-2026 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
14
23#include <filesystem>
24
25#ifdef WITH_OPENMP
26#include <omp.h>
27#endif
28
29using namespace o2::itsmft;
30using namespace o2::framework;
32
35template <class Mapping>
37{
38 mRUEntry.fill(-1); // no known links in the beginning
39 mTimerTFStart.Stop();
40 mTimerDecode.Stop();
41 mTimerFetchData.Stop();
42 mSelfName = o2::utils::Str::concat_string(Mapping::getName(), "Decoder");
43 DPLRawParser<>::setCheckIncompleteHBF(false); // Disable incomplete HBF checking, see ErrPacketCounterJump check in GBTLink.cxx
44 mInputFilter = {InputSpec{"filter", ConcreteDataTypeMatcher{Mapping::getOrigin(), o2::header::gDataDescriptionRawData}}}; // by default take all raw data
45}
46
49template <class Mapping>
50void RawPixelDecoder<Mapping>::printReport(bool decstat, bool skipNoErr) const
51{
52 double cpu = 0, real = 0;
53 auto& tmrS = const_cast<TStopwatch&>(mTimerTFStart);
54 LOGP(info, "{} Timing Start TF: CPU = {:.3e} Real = {:.3e} in {} slots", mSelfName, tmrS.CpuTime(), tmrS.RealTime(), tmrS.Counter() - 1);
55 cpu += tmrS.CpuTime();
56 real += tmrS.RealTime();
57 auto& tmrD = const_cast<TStopwatch&>(mTimerDecode);
58 LOGP(info, "{} Timing Decode: CPU = {:.3e} Real = {:.3e} in {} slots", mSelfName, tmrD.CpuTime(), tmrD.RealTime(), tmrD.Counter() - 1);
59 cpu += tmrD.CpuTime();
60 real += tmrD.RealTime();
61 auto& tmrF = const_cast<TStopwatch&>(mTimerFetchData);
62 LOGP(info, "{} Timing FetchData: CPU = {:.3e} Real = {:.3e} in {} slots", mSelfName, tmrF.CpuTime(), tmrF.RealTime(), tmrF.Counter() - 1);
63 cpu += tmrF.CpuTime();
64 real += tmrF.RealTime();
65 LOGP(info, "{} Timing Total: CPU = {:.3e} Real = {:.3e} in {} slots in {} mode", mSelfName, cpu, real, tmrS.Counter() - 1,
66 mDecodeNextAuto ? "AutoDecode" : "ExternalCall");
67
68 LOGP(info, "{} decoded {} hits in {} non-empty chips in {} ROFs with {} threads, {} external triggers", mSelfName, mNPixelsFired, mNChipsFired, mROFCounter, mNThreads, mNExtTriggers);
69 if (decstat) {
70 LOG(info) << "GBT Links decoding statistics" << (skipNoErr ? " (only links with errors are reported)" : "");
71 for (auto& lnk : mGBTLinks) {
72 lnk.statistics.print(skipNoErr);
73 lnk.chipStat.print(skipNoErr);
74 }
75 }
76}
77
80template <class Mapping>
82{
83 mNChipsFiredROF = 0;
84 mNPixelsFiredROF = 0;
85 mInteractionRecord.clear();
86 if (mROFRampUpStage && mSkipRampUpData) {
87 return -1;
88 }
89 int nru = mRUDecodeVec.size();
90 int prevNTrig = mExtTriggers.size();
91 do {
92#ifdef WITH_OPENMP
93#pragma omp parallel for schedule(dynamic) num_threads(mNThreads)
94#endif
95 for (int iru = 0; iru < nru; iru++) {
96 collectROFCableData(iru);
97 }
98
99 mROFCounter++;
100
101 if (!doIRMajorityPoll()) {
102 continue; // no links with data
103 }
104
105#ifdef WITH_OPENMP
106#pragma omp parallel for schedule(dynamic) num_threads(mNThreads) reduction(+ : mNChipsFiredROF, mNPixelsFiredROF)
107#endif
108 for (int iru = 0; iru < nru; iru++) {
109 auto& ru = mRUDecodeVec[iru];
110 if (ru.nNonEmptyLinks) {
111 ru.ROFRampUpStage = mROFRampUpStage;
112 mNPixelsFiredROF += ru.decodeROF(mMAP, mInteractionRecord, mVerifyDecoder);
113 mNChipsFiredROF += ru.nChipsFired;
114 } else {
115 ru.clearSeenChipIDs();
116 }
117 }
118
119 if (mNChipsFiredROF || (mAlloEmptyROFs && mNLinksDone < mNLinksInTF)) { // fill some statistics
120 mTrigger = mLinkForTriggers ? mLinkForTriggers->trigger : 0;
121 mNChipsFired += mNChipsFiredROF;
122 mNPixelsFired += mNPixelsFiredROF;
123 mCurRUDecodeID = 0; // getNextChipData will start from here
124 mLastReadChipID = -1;
125 break;
126 }
127
128 } while (mNLinksDone < mNLinksInTF);
129 mNExtTriggers += mExtTriggers.size() - prevNTrig;
130 ensureChipOrdering();
131 mTimerDecode.Stop();
132
133 return (mNLinksDone < mNLinksInTF) ? mNChipsFiredROF : -1;
134}
135
138template <class Mapping>
140{
141 mTimerTFStart.Start(false);
142 for (auto& link : mGBTLinks) {
143 link.lastRDH = nullptr; // pointers will be invalid
144 link.clear(false, true); // clear data but not the statistics
145 }
146 for (auto& ru : mRUDecodeVec) {
147 ru.clear();
148 // ru.chipErrorsTF.clear(); // will be cleared in the collectDecodingErrors
149 ru.linkHBFToDump.clear();
150 ru.nLinksDone = 0;
151 }
152 setupLinks(inputs);
153 mNLinksDone = 0;
154 mExtTriggers.clear();
155 mTimerTFStart.Stop();
156}
157
160template <class Mapping>
162{
163 auto& ru = mRUDecodeVec[iru];
164 ru.clear();
165 for (int il = 0; il < RUDecodeData::MaxLinksPerRU; il++) {
166 auto* link = getGBTLink(ru.links[il]);
167 if (link && link->statusInTF == GBTLink::DataSeen) {
168 auto res = link->collectROFCableData(mMAP);
169 if (res == GBTLink::DataSeen || res == GBTLink::CachedDataExist) { // at the moment process only DataSeen
170 ru.nNonEmptyLinks++;
171 } else if (res == GBTLink::StoppedOnEndOfData || res == GBTLink::AbortedOnError) { // this link has exhausted its data or it has to be discarded due to the error
172 ru.nLinksDone++;
173 }
174 }
175 }
176}
177
179// do majority IR poll for synchronization
180template <class Mapping>
182{
183 mIRPoll.clear();
184 mInteractionRecord.clear();
185 for (auto& link : mGBTLinks) {
186 if (link.statusInTF == GBTLink::DataSeen) {
187 if (link.status == GBTLink::DataSeen || link.status == GBTLink::CachedDataExist) {
188 mIRPoll[link.ir]++;
189 if (mVerbosity >= GBTLink::Verbosity::VerboseHeaders) {
190 LOGP(info, "doIRMajorityPoll: {} contributes to poll {}", link.describe(), link.ir.asString());
191 }
192 } else if (link.status == GBTLink::StoppedOnEndOfData || link.status == GBTLink::AbortedOnError) {
194 if (mVerbosity >= GBTLink::Verbosity::VerboseHeaders) {
195 LOGP(info, "doIRMajorityPoll: {} DONE, status = {}", link.describe(), int(link.status));
196 }
197 mNLinksDone++;
198 }
199 }
200 }
201 if (mNLinksDone == mNLinksInTF) {
202 if (mVerbosity >= GBTLink::Verbosity::VerboseHeaders) {
203 LOGP(info, "doIRMajorityPoll: All {} links registered in TF are done", mNLinksInTF);
204 }
205 return false;
206 }
207 int majIR = -1;
208 for (const auto& entIR : mIRPoll) {
209 if (entIR.second > majIR) {
210 majIR = entIR.second;
211 mInteractionRecord = entIR.first;
212 }
213 }
214 if (mInteractionRecord.isDummy()) {
215 if (mVerbosity >= GBTLink::Verbosity::VerboseHeaders) {
216 LOG(info) << "doIRMajorityPoll: did not find any valid IR";
217 }
218 return false;
219 }
220 if (mVerbosity >= GBTLink::Verbosity::VerboseHeaders) {
221 LOG(info) << "doIRMajorityPoll: " << mInteractionRecord.asString() << " majority = " << majIR << " for " << mNLinksInTF << " links seen, LinksDone = " << mNLinksDone;
222 }
223 return true;
224}
225
228template <class Mapping>
230{
231 constexpr uint32_t ROF_RAMP_FLAG = 0x1 << 4;
232 constexpr uint32_t LINK_RECOVERY_FLAG = 0x1 << 5;
233 mNLinksInTF = 0;
234 mCurRUDecodeID = NORUDECODED;
235 auto nLinks = mGBTLinks.size();
236 auto origin = (mUserDataOrigin == o2::header::gDataOriginInvalid) ? mMAP.getOrigin() : mUserDataOrigin;
237 auto datadesc = (mUserDataDescription == o2::header::gDataDescriptionInvalid) ? o2::header::gDataDescriptionRawData : mUserDataDescription;
238 // if we see requested data type input with 0xDEADBEEF subspec and 0 payload this means that the "delayed message"
239 // mechanism created it in absence of real data from upstream. Processor should send empty output to not block the workflow
240 {
241 static size_t contDeadBeef = 0; // number of times 0xDEADBEEF was seen continuously
242 std::vector<InputSpec> dummy{InputSpec{"dummy", ConcreteDataMatcher{origin, datadesc, 0xDEADBEEF}}};
243 for (const auto& ref : InputRecordWalker(inputs, dummy)) {
244 const auto dh = o2::framework::DataRefUtils::getHeader<o2::header::DataHeader*>(ref);
246 if (payloadSize == 0) {
248 if (++contDeadBeef <= maxWarn) {
249 LOGP(warn, "Found input [{}/{}/{:#x}] TF#{} 1st_orbit:{} Payload {} : assuming no payload for all links in this TF{}",
250 dh->dataOrigin.str, dh->dataDescription.str, dh->subSpecification, dh->tfCounter, dh->firstTForbit, payloadSize,
251 contDeadBeef == maxWarn ? fmt::format(". {} such inputs in row received, stopping reporting", contDeadBeef) : "");
252 }
253 return;
254 }
255 }
256 contDeadBeef = 0; // if good data, reset the counter
257 }
258 mROFRampUpStage = false;
259 DPLRawParser parser(inputs, mInputFilter, o2::conf::VerbosityConfig::Instance().rawParserSeverity);
260 parser.setMaxFailureMessages(o2::conf::VerbosityConfig::Instance().maxWarnRawParser);
261 static size_t cntParserFailures = 0;
262 parser.setExtFailureCounter(&cntParserFailures);
263
264 uint32_t currSSpec = 0xffffffff; // dummy starting subspec
265 int linksAdded = 0;
266 uint16_t lr, dummy; // extraxted info from FEEId
267 for (auto it = parser.begin(); it != parser.end(); ++it) {
268 auto const* dh = it.o2DataHeader();
269 auto& lnkref = mSubsSpec2LinkID[dh->subSpecification];
270 const auto& rdh = *reinterpret_cast<const header::RDHAny*>(it.raw()); // RSTODO this is a hack in absence of generic header getter
271 const auto feeID = RDHUtils::getFEEID(rdh);
272 mMAP.expandFEEId(feeID, lr, dummy, dummy);
273
274 if (lnkref.entry == -1) { // new link needs to be added
275 lnkref.entry = int(mGBTLinks.size());
276 auto& lnk = mGBTLinks.emplace_back(RDHUtils::getCRUID(rdh), feeID, RDHUtils::getEndPointID(rdh), RDHUtils::getLinkID(rdh), lnkref.entry);
277 lnk.subSpec = dh->subSpecification;
278 lnk.wordLength = (lnk.expectPadding = (RDHUtils::getDataFormat(rdh) == 0)) ? o2::itsmft::GBTPaddedWordLength : o2::itsmft::GBTWordLength;
279 getCreateRUDecode(mMAP.FEEId2RUSW(feeID)); // make sure there is a RU for this link
280 lnk.verbosity = GBTLink::Verbosity(mVerbosity);
281 lnk.alwaysParseTrigger = mAlwaysParseTrigger;
282 if (mVerbosity >= GBTLink::Verbosity::VerboseHeaders) {
283 LOG(info) << mSelfName << " registered new " << lnk.describe() << " RUSW=" << int(mMAP.FEEId2RUSW(lnk.feeID));
284 }
285 linksAdded++;
286 }
287 auto& link = mGBTLinks[lnkref.entry];
288 if (currSSpec != dh->subSpecification) { // this is the 1st part for this link in this TF, next parts must follow contiguously!!!
289 currSSpec = dh->subSpecification;
290 if (link.statusInTF != GBTLink::None) {
291 static bool errorDone = false;
292 if (!errorDone) {
293 LOGP(error, "{} was already registered, inform PDP on-call about error!!!", link.describe());
294 errorDone = true;
295 }
296 }
297 link.statusInTF = GBTLink::DataSeen;
298 mNLinksInTF++;
299 }
300 auto detField = RDHUtils::getDetectorField(&rdh);
301 if (detField & ROF_RAMP_FLAG) {
302 mROFRampUpStage = true;
303 }
304 if ((detField & LINK_RECOVERY_FLAG) && (link.statusInTF != GBTLink::Recovery)) {
305 link.statusInTF = GBTLink::Recovery; // data will be discarded
306 link.rawData.clear();
308 link.accountLinkRecovery(RDHUtils::getHeartBeatIR(rdh));
309 mNLinksInTF--;
310 }
311 if (link.statusInTF != GBTLink::Recovery) {
312 link.cacheData(it.raw(), RDHUtils::getMemorySize(rdh));
313 }
314 }
315
316 if (linksAdded) { // new links were added, update link<->RU mapping, usually is done for 1st TF only
317 if (nLinks) {
318 if (mVerbosity >= GBTLink::Verbosity::VerboseHeaders) {
319 LOG(warn) << mSelfName << " New links appeared although the initialization was already done";
320 }
321 for (auto& ru : mRUDecodeVec) { // reset RU->link references since they may have been changed
322 memset(&ru.links[0], -1, RUDecodeData::MaxLinksPerRU * sizeof(int));
323 memset(&ru.cableLinkPtr[0], 0, RUDecodeData::MaxCablesPerRU * sizeof(GBTLink*));
324 }
325 }
326 // sort RUs in stave increasing order
327 std::sort(mRUDecodeVec.begin(), mRUDecodeVec.end(), [](const RUDecodeData& ruA, const RUDecodeData& ruB) -> bool { return ruA.ruSWID < ruB.ruSWID; });
328 for (auto i = 0; i < mRUDecodeVec.size(); i++) {
329 mRUEntry[mRUDecodeVec[i].ruSWID] = i;
330 }
331 nLinks = mGBTLinks.size();
332 // attach link to corresponding RU: this can be done once all RUs are created, to make sure their pointers don't change
333 for (int il = 0; il < nLinks; il++) {
334 auto& link = mGBTLinks[il];
335 bool newLinkAdded = (link.ruPtr == nullptr);
336 link.ruPtr = getRUDecode(mMAP.FEEId2RUSW(link.feeID)); // link to RU reference, reattach even it was already set before
337 uint16_t lr, ruOnLr, linkInRU;
338 mMAP.expandFEEId(link.feeID, lr, ruOnLr, linkInRU);
339 if (newLinkAdded) {
340 if (mVerbosity >= GBTLink::Verbosity::VerboseHeaders) {
341 LOGP(info, "{} Attaching {} to RU#{:02} (stave {:02} of layer {})", mSelfName, link.describe(), int(mMAP.FEEId2RUSW(link.feeID)), ruOnLr, lr);
342 }
343 }
344 link.idInRU = linkInRU;
345 link.ruPtr->links[linkInRU] = il; // RU to link reference
346 link.ruPtr->nLinks++;
347 }
348 }
349 // set the link extracting triggers
350 for (auto& link : mGBTLinks) {
351 if (link.statusInTF == GBTLink::DataSeen) { // designate 1st link with valid data to register triggers
352 link.extTrigVec = &mExtTriggers;
353 mLinkForTriggers = &link;
354 break;
355 }
356 }
357}
358
361template <class Mapping>
363{
364 assert(ruSW < mMAP.getNRUs());
365 if (mRUEntry[ruSW] < 0) {
366 mRUEntry[ruSW] = mRUDecodeVec.size();
367 auto& ru = mRUDecodeVec.emplace_back();
368 ru.ruSWID = ruSW;
369 ru.ruInfo = mMAP.getRUInfoSW(ruSW); // info on the stave/RU
370 ru.chipsData.resize(mMAP.getNChipsOnRUType(ru.ruInfo->ruType));
371 ru.verbosity = mVerbosity;
372 if (mVerbosity >= GBTLink::Verbosity::VerboseHeaders) {
373 LOG(info) << mSelfName << " Defining container for RU " << ruSW << " at slot " << mRUEntry[ruSW];
374 }
375 }
376 return mRUDecodeVec[mRUEntry[ruSW]];
377}
378
380template <class Mapping>
381ChipPixelData* RawPixelDecoder<Mapping>::getNextChipData(std::vector<ChipPixelData>& chipDataVec)
382{
383 // decode new RU if no cached non-empty chips
384 for (; mCurRUDecodeID < mRUDecodeVec.size(); mCurRUDecodeID++) {
385 auto& ru = mRUDecodeVec[mCurRUDecodeID];
386 if (ru.lastChipChecked < ru.nChipsFired) {
387 auto& chipData = ru.chipsData[ru.lastChipChecked++];
388 // assert(mLastReadChipID < chipData.getChipID());
389 if (mLastReadChipID >= chipData.getChipID()) {
390 if (!mROFRampUpStage) {
391 const int MaxErrLog = 2;
392 static int errLocCount = 0;
393 if (errLocCount < MaxErrLog) {
394 LOGP(warn, "Wrong order/duplication: encountered chip {} after processing chip {}, skipping.",
395 chipData.getChipID(), mLastReadChipID, ++errLocCount, MaxErrLog);
396 }
397 }
398 continue;
399 }
400 mLastReadChipID = chipData.getChipID();
401 chipDataVec[mLastReadChipID].swap(chipData);
402 return &chipDataVec[mLastReadChipID];
403 }
404 }
405 // will need to decode new trigger
406 if (!mDecodeNextAuto || decodeNextTrigger() < 0) { // no more data to decode
407 return nullptr;
408 }
409 return getNextChipData(chipDataVec);
410}
411
413template <class Mapping>
415{
417 for (; mCurRUDecodeID < mRUDecodeVec.size(); mCurRUDecodeID++) {
418 auto& ru = mRUDecodeVec[mCurRUDecodeID];
419 if (ru.lastChipChecked < ru.nChipsFired) {
420 auto& ruchip = ru.chipsData[ru.lastChipChecked++];
421 assert(mLastReadChipID < chipData.getChipID());
422 mLastReadChipID = chipData.getChipID();
423 chipData.swap(ruchip);
424 return true;
425 }
426 }
427 // will need to decode new trigger
428 if (!mDecodeNextAuto || decodeNextTrigger() < 0) { // no more data to decode
429 return false;
430 }
431 return getNextChipData(chipData); // is it ok to use recursion here?
432}
433
435template <>
437{
438 mOrderedChipsPtr.clear();
439 // define looping order, if mCurRUDecodeID < mRUDecodeVec.size(), this means that decodeNextTrigger() was called before
440 if (mCurRUDecodeID < mRUDecodeVec.size()) { // define sort order
441 for (; mCurRUDecodeID < mRUDecodeVec.size(); mCurRUDecodeID++) {
442 auto& ru = mRUDecodeVec[mCurRUDecodeID];
443 while (ru.lastChipChecked < ru.nChipsFired) {
444 mOrderedChipsPtr.push_back(&ru.chipsData[ru.lastChipChecked++]);
445 }
446 }
447 // sort in decreasing order
448 std::sort(mOrderedChipsPtr.begin(), mOrderedChipsPtr.end(), [](const ChipPixelData* a, const ChipPixelData* b) { return a->getChipID() > b->getChipID(); });
449 }
450}
451
453template <>
454ChipPixelData* RawPixelDecoder<ChipMappingMFT>::getNextChipData(std::vector<ChipPixelData>& chipDataVec)
455{
456 if (!mOrderedChipsPtr.empty()) {
457 auto chipData = *mOrderedChipsPtr.back();
458 assert(mLastReadChipID < chipData.getChipID());
459 mLastReadChipID = chipData.getChipID();
460 chipDataVec[mLastReadChipID].swap(chipData);
461 mOrderedChipsPtr.pop_back();
462 return &chipDataVec[mLastReadChipID];
463 }
464 // will need to decode new trigger
465 if (!mDecodeNextAuto || decodeNextTrigger() < 0) { // no more data to decode
466 return nullptr;
467 }
468 return getNextChipData(chipDataVec);
469}
470
472template <>
474{
475 if (!mOrderedChipsPtr.empty()) {
476 auto ruChip = *mOrderedChipsPtr.back();
477 assert(mLastReadChipID < ruChip.getChipID());
478 mLastReadChipID = ruChip.getChipID();
479 ruChip.swap(chipData);
480 mOrderedChipsPtr.pop_back();
481 return true;
482 }
483 // will need to decode new trigger
484 if (!mDecodeNextAuto || decodeNextTrigger() < 0) { // no more data to decode
485 return false;
486 }
487 return getNextChipData(chipData); // is it ok to use recursion here?
488}
489
491template <class Mapping>
493{
494 mVerbosity = v;
495 for (auto& link : mGBTLinks) {
496 link.verbosity = GBTLink::Verbosity(v);
497 }
498}
499
501template <class Mapping>
503{
504#ifdef WITH_OPENMP
505 mNThreads = n > 0 ? n : 1;
506#else
507 LOG(warning) << mSelfName << " Multithreading is not supported, imposing single thread";
508 mNThreads = 1;
509#endif
510}
511
513template <class Mapping>
515{
516 // clear statistics
517 for (auto& lnk : mGBTLinks) {
518 lnk.clear(true, resetRaw);
519 }
520 mNChipsFiredROF = mNPixelsFiredROF = 0;
521 mNChipsFired = mNPixelsFired = mNExtTriggers = 0;
522}
523
525template <class Mapping>
527{
528 size_t outSize = 0;
529 bool dumpFullTF = false;
530 for (auto& ru : mRUDecodeVec) {
531 if (ru.linkHBFToDump.size()) {
532 if (dump == int(GBTLink::RawDataDumps::DUMP_TF)) {
533 dumpFullTF = true;
534 break;
535 }
536 for (auto it : ru.linkHBFToDump) {
537 if (dump == int(GBTLink::RawDataDumps::DUMP_HBF)) {
538 const auto& lnk = mGBTLinks[mSubsSpec2LinkID[it.first >> 32].entry];
539 int entry = it.first & 0xffffffff;
540 bool allHBFs = false;
541 std::string fnm;
542 if (entry >= lnk.rawData.getNPieces()) {
543 allHBFs = true;
544 entry = 0;
545 fnm = fmt::format("{}{}rawdump_{}_run{}_tf_orb{}_full_feeID{:#06x}.raw", mRawDumpDirectory, mRawDumpDirectory.empty() ? "" : "/",
546 Mapping::getName(), tinfo.runNumber, tinfo.firstTForbit, lnk.feeID);
547 } else {
548 fnm = fmt::format("{}{}rawdump_{}_run{}_tf_orb{}_hbf_orb{}_feeID{:#06x}.raw", mRawDumpDirectory, mRawDumpDirectory.empty() ? "" : "/",
549 Mapping::getName(), tinfo.runNumber, tinfo.firstTForbit, it.second, lnk.feeID);
550 }
551 std::ofstream ostrm(fnm, std::ios::binary);
552 if (!ostrm.good()) {
553 LOG(error) << "failed to open " << fnm;
554 continue;
555 }
556 while (entry < lnk.rawData.getNPieces()) {
557 const auto* piece = lnk.rawData.getPiece(entry);
558 if (!allHBFs && RDHUtils::getHeartBeatOrbit(reinterpret_cast<const RDH*>(piece->data)) != it.second) {
559 break;
560 }
561 ostrm.write(reinterpret_cast<const char*>(piece->data), piece->size);
562 outSize += piece->size;
563 entry++;
564 }
565 LOG(info) << "produced " << std::filesystem::current_path().c_str() << '/' << fnm;
566 }
567 }
568 }
569 }
570 while (dumpFullTF) {
571 std::string fnm = fmt::format("rawdump_{}_run{}_tf_orb{}_full.raw",
572 Mapping::getName(), tinfo.runNumber, tinfo.firstTForbit);
573 std::ofstream ostrm(fnm, std::ios::binary);
574 if (!ostrm.good()) {
575 LOG(error) << "failed to open " << fnm;
576 break;
577 }
578 for (const auto& lnk : mGBTLinks) {
579 for (size_t i = 0; i < lnk.rawData.getNPieces(); i++) {
580 const auto* piece = lnk.rawData.getPiece(i);
581 ostrm.write(reinterpret_cast<const char*>(piece->data), piece->size);
582 outSize += piece->size;
583 }
584 }
585 LOG(info) << "produced " << std::filesystem::current_path().c_str() << '/' << fnm;
586 break;
587 }
588 return outSize;
589}
590
592template <class Mapping>
594{
595 mTimerTFStart.Reset();
596 mTimerDecode.Reset();
597 mTimerFetchData.Reset();
598 for (auto& ru : mRUDecodeVec) {
599 for (auto& cab : ru.cableData) {
600 cab.clear();
601 }
602 }
603 for (auto& link : mGBTLinks) {
604 link.rofJumpWasSeen = false;
605 link.statusInTF = GBTLink::None;
606 }
607 clearStat(true);
608}
609
header::DataOrigin origin
A raw page parser for DPL input.
int32_t i
void setupLinks(o2::itsmft::MC2RawEncoder< MAP > &m2r, std::string_view outDir, std::string_view outPrefix, std::string_view fileFor)
Definition digi2raw.cxx:407
A helper class to iteratate over all parts of all input routes.
uint32_t cpu
Definition RawData.h:6
uint32_t res
Definition RawData.h:0
Definition of the Alpide pixel reader for raw data processing.
The parser handles transparently input in the format of raw pages.
static void setCheckIncompleteHBF(bool v)
A helper class to iteratate over all parts of all input routes.
The input API of the Data Processing Layer This class holds the inputs which are valid for processing...
void swap(ChipPixelData &other)
Definition PixelData.h:156
uint16_t getChipID() const
Definition PixelData.h:108
void startNewTF(o2::framework::InputRecord &inputs)
size_t produceRawDataDumps(int dump, const o2::framework::TimingInfo &tinfo)
void printReport(bool decstat=true, bool skipNoErr=true) const
bool getNextChipData(ChipPixelData &chipData) final
void clearStat(bool resetRaw=false)
void dump(const std::string what, DPMAP m, int verbose)
Definition dcs-ccdb.cxx:79
GLdouble n
Definition glcorearb.h:1982
GLuint entry
Definition glcorearb.h:5735
const GLdouble * v
Definition glcorearb.h:832
GLboolean GLboolean GLboolean b
Definition glcorearb.h:1233
GLboolean GLboolean GLboolean GLboolean a
Definition glcorearb.h:1233
constexpr o2::header::DataDescription gDataDescriptionInvalid
Definition DataHeader.h:597
constexpr o2::header::DataOrigin gDataOriginInvalid
Definition DataHeader.h:561
constexpr o2::header::DataDescription gDataDescriptionRawData
Definition DataHeader.h:598
uint8_t itsSharedClusterMap uint8_t
Defining ITS Vertex explicitly as messageable.
Definition Cartesian.h:288
constexpr int GBTPaddedWordLength
Definition GBTWord.h:56
constexpr int GBTWordLength
Definition GBTWord.h:55
static o2::header::DataHeader::PayloadSizeType getPayloadSize(const DataRef &ref)
static constexpr int MaxCablesPerRU
static constexpr int MaxLinksPerRU
static std::string concat_string(Ts const &... ts)
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"