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