35template <
class Mapping>
41 mTimerFetchData.Stop();
49template <
class Mapping>
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");
68 LOGP(info,
"{} decoded {} hits in {} non-empty chips in {} ROFs with {} threads, {} external triggers", mSelfName, mNPixelsFired, mNChipsFired, mROFCounter, mNThreads, mNExtTriggers);
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);
80template <
class Mapping>
85 mInteractionRecord.clear();
86 if (mROFRampUpStage && mSkipRampUpData) {
89 int nru = mRUDecodeVec.size();
90 int prevNTrig = mExtTriggers.size();
93#pragma omp parallel for schedule(dynamic) num_threads(mNThreads)
95 for (
int iru = 0; iru < nru; iru++) {
96 collectROFCableData(iru);
101 if (!doIRMajorityPoll()) {
106#pragma omp parallel for schedule(dynamic) num_threads(mNThreads) reduction(+ : mNChipsFiredROF, mNPixelsFiredROF)
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;
115 ru.clearSeenChipIDs();
119 if (mNChipsFiredROF || (mAlloEmptyROFs && mNLinksDone < mNLinksInTF)) {
120 mTrigger = mLinkForTriggers ? mLinkForTriggers->trigger : 0;
121 mNChipsFired += mNChipsFiredROF;
122 mNPixelsFired += mNPixelsFiredROF;
124 mLastReadChipID = -1;
128 }
while (mNLinksDone < mNLinksInTF);
129 mNExtTriggers += mExtTriggers.size() - prevNTrig;
130 ensureChipOrdering();
133 return (mNLinksDone < mNLinksInTF) ? mNChipsFiredROF : -1;
138template <
class Mapping>
141 mTimerTFStart.Start(
false);
142 for (
auto&
link : mGBTLinks) {
143 link.lastRDH =
nullptr;
144 link.clear(
false,
true);
146 for (
auto& ru : mRUDecodeVec) {
149 ru.linkHBFToDump.clear();
154 mExtTriggers.clear();
155 mTimerTFStart.Stop();
160template <
class Mapping>
163 auto& ru = mRUDecodeVec[iru];
166 auto*
link = getGBTLink(ru.links[il]);
168 auto res =
link->collectROFCableData(mMAP);
180template <
class Mapping>
184 mInteractionRecord.clear();
185 for (
auto&
link : mGBTLinks) {
189 if (mVerbosity >= GBTLink::Verbosity::VerboseHeaders) {
190 LOGP(info,
"doIRMajorityPoll: {} contributes to poll {}",
link.describe(),
link.ir.asString());
194 if (mVerbosity >= GBTLink::Verbosity::VerboseHeaders) {
195 LOGP(info,
"doIRMajorityPoll: {} DONE, status = {}",
link.describe(),
int(
link.status));
201 if (mNLinksDone == mNLinksInTF) {
202 if (mVerbosity >= GBTLink::Verbosity::VerboseHeaders) {
203 LOGP(info,
"doIRMajorityPoll: All {} links registered in TF are done", mNLinksInTF);
208 for (
const auto& entIR : mIRPoll) {
209 if (entIR.second > majIR) {
210 majIR = entIR.second;
211 mInteractionRecord = entIR.first;
214 if (mInteractionRecord.isDummy()) {
215 if (mVerbosity >= GBTLink::Verbosity::VerboseHeaders) {
216 LOG(info) <<
"doIRMajorityPoll: did not find any valid IR";
220 if (mVerbosity >= GBTLink::Verbosity::VerboseHeaders) {
221 LOG(info) <<
"doIRMajorityPoll: " << mInteractionRecord.asString() <<
" majority = " << majIR <<
" for " << mNLinksInTF <<
" links seen, LinksDone = " << mNLinksDone;
228template <
class Mapping>
231 constexpr uint32_t ROF_RAMP_FLAG = 0x1 << 4;
232 constexpr uint32_t LINK_RECOVERY_FLAG = 0x1 << 5;
234 mCurRUDecodeID = NORUDECODED;
235 auto nLinks = mGBTLinks.size();
239 for (
auto& filt : mInputFilter) {
240 if (std::holds_alternative<o2::framework::ConcreteDataMatcher>(filt.matcher)) {
241 std::get<o2::framework::ConcreteDataMatcher>(filt.matcher).origin =
origin;
242 std::get<o2::framework::ConcreteDataMatcher>(filt.matcher).description = datadesc;
250 static size_t contDeadBeef = 0;
253 const auto dh = o2::framework::DataRefUtils::getHeader<o2::header::DataHeader*>(
ref);
255 if (payloadSize == 0) {
257 if (++contDeadBeef <= maxWarn) {
258 LOGP(warn,
"Found input [{}/{}/{:#x}] TF#{} 1st_orbit:{} Payload {} : assuming no payload for all links in this TF{}",
259 dh->dataOrigin.str, dh->dataDescription.str, dh->subSpecification, dh->tfCounter, dh->firstTForbit, payloadSize,
260 contDeadBeef == maxWarn ? fmt::format(
". {} such inputs in row received, stopping reporting", contDeadBeef) :
"");
267 mROFRampUpStage =
false;
270 static size_t cntParserFailures = 0;
271 parser.setExtFailureCounter(&cntParserFailures);
273 uint32_t currSSpec = 0xffffffff;
276 for (
auto it = parser.begin(); it != parser.end(); ++it) {
277 auto const* dh = it.o2DataHeader();
278 auto& lnkref = mSubsSpec2LinkID[dh->subSpecification];
279 const auto& rdh = *
reinterpret_cast<const header::RDHAny*
>(it.raw());
280 const auto feeID = RDHUtils::getFEEID(rdh);
281 mMAP.expandFEEId(feeID, lr, dummy, dummy);
283 if (lnkref.entry == -1) {
284 lnkref.entry =
int(mGBTLinks.size());
285 auto& lnk = mGBTLinks.emplace_back(RDHUtils::getCRUID(rdh), feeID, RDHUtils::getEndPointID(rdh), RDHUtils::getLinkID(rdh), lnkref.entry);
286 lnk.subSpec = dh->subSpecification;
288 getCreateRUDecode(mMAP.FEEId2RUSW(feeID));
290 lnk.alwaysParseTrigger = mAlwaysParseTrigger;
291 if (mVerbosity >= GBTLink::Verbosity::VerboseHeaders) {
292 LOG(info) << mSelfName <<
" registered new " << lnk.describe() <<
" RUSW=" <<
int(mMAP.FEEId2RUSW(lnk.feeID));
296 auto&
link = mGBTLinks[lnkref.entry];
297 if (currSSpec != dh->subSpecification) {
298 currSSpec = dh->subSpecification;
300 static bool errorDone =
false;
302 LOGP(error,
"{} was already registered, inform PDP on-call about error!!!",
link.describe());
309 auto detField = RDHUtils::getDetectorField(&rdh);
310 if (detField & ROF_RAMP_FLAG) {
311 mROFRampUpStage =
true;
315 link.rawData.clear();
317 link.accountLinkRecovery(RDHUtils::getHeartBeatIR(rdh));
321 link.cacheData(it.raw(), RDHUtils::getMemorySize(rdh));
327 if (mVerbosity >= GBTLink::Verbosity::VerboseHeaders) {
328 LOG(warn) << mSelfName <<
" New links appeared although the initialization was already done";
330 for (
auto& ru : mRUDecodeVec) {
336 std::sort(mRUDecodeVec.begin(), mRUDecodeVec.end(), [](
const RUDecodeData& ruA,
const RUDecodeData& ruB) ->
bool { return ruA.ruSWID < ruB.ruSWID; });
337 for (
auto i = 0;
i < mRUDecodeVec.size();
i++) {
338 mRUEntry[mRUDecodeVec[
i].ruSWID] =
i;
340 nLinks = mGBTLinks.size();
342 for (
int il = 0; il < nLinks; il++) {
343 auto&
link = mGBTLinks[il];
344 bool newLinkAdded = (
link.ruPtr ==
nullptr);
345 link.ruPtr = getRUDecode(mMAP.FEEId2RUSW(
link.feeID));
346 uint16_t lr, ruOnLr, linkInRU;
347 mMAP.expandFEEId(
link.feeID, lr, ruOnLr, linkInRU);
349 if (mVerbosity >= GBTLink::Verbosity::VerboseHeaders) {
350 LOGP(info,
"{} Attaching {} to RU#{:02} (stave {:02} of layer {})", mSelfName,
link.describe(),
int(mMAP.FEEId2RUSW(
link.feeID)), ruOnLr, lr);
353 link.idInRU = linkInRU;
354 link.ruPtr->links[linkInRU] = il;
355 link.ruPtr->nLinks++;
359 for (
auto&
link : mGBTLinks) {
361 link.extTrigVec = &mExtTriggers;
362 mLinkForTriggers = &
link;
370template <
class Mapping>
373 assert(ruSW < mMAP.getNRUs());
374 if (mRUEntry[ruSW] < 0) {
375 mRUEntry[ruSW] = mRUDecodeVec.size();
376 auto& ru = mRUDecodeVec.emplace_back();
378 ru.ruInfo = mMAP.getRUInfoSW(ruSW);
379 ru.chipsData.resize(mMAP.getNChipsOnRUType(ru.ruInfo->ruType));
380 ru.verbosity = mVerbosity;
381 if (mVerbosity >= GBTLink::Verbosity::VerboseHeaders) {
382 LOG(info) << mSelfName <<
" Defining container for RU " << ruSW <<
" at slot " << mRUEntry[ruSW];
385 return mRUDecodeVec[mRUEntry[ruSW]];
389template <
class Mapping>
393 for (; mCurRUDecodeID < mRUDecodeVec.size(); mCurRUDecodeID++) {
394 auto& ru = mRUDecodeVec[mCurRUDecodeID];
395 if (ru.lastChipChecked < ru.nChipsFired) {
396 auto& chipData = ru.chipsData[ru.lastChipChecked++];
398 if (mLastReadChipID >= chipData.getChipID()) {
399 if (!mROFRampUpStage) {
400 const int MaxErrLog = 2;
401 static int errLocCount = 0;
402 if (errLocCount < MaxErrLog) {
403 LOGP(warn,
"Wrong order/duplication: encountered chip {} after processing chip {}, skipping.",
404 chipData.getChipID(), mLastReadChipID, ++errLocCount, MaxErrLog);
409 mLastReadChipID = chipData.getChipID();
410 chipDataVec[mLastReadChipID].swap(chipData);
411 return &chipDataVec[mLastReadChipID];
415 if (!mDecodeNextAuto || decodeNextTrigger() < 0) {
418 return getNextChipData(chipDataVec);
422template <
class Mapping>
426 for (; mCurRUDecodeID < mRUDecodeVec.size(); mCurRUDecodeID++) {
427 auto& ru = mRUDecodeVec[mCurRUDecodeID];
428 if (ru.lastChipChecked < ru.nChipsFired) {
429 auto& ruchip = ru.chipsData[ru.lastChipChecked++];
430 assert(mLastReadChipID < chipData.
getChipID());
432 chipData.
swap(ruchip);
437 if (!mDecodeNextAuto || decodeNextTrigger() < 0) {
440 return getNextChipData(chipData);
447 mOrderedChipsPtr.clear();
449 if (mCurRUDecodeID < mRUDecodeVec.size()) {
450 for (; mCurRUDecodeID < mRUDecodeVec.size(); mCurRUDecodeID++) {
451 auto& ru = mRUDecodeVec[mCurRUDecodeID];
452 while (ru.lastChipChecked < ru.nChipsFired) {
453 mOrderedChipsPtr.push_back(&ru.chipsData[ru.lastChipChecked++]);
457 std::sort(mOrderedChipsPtr.begin(), mOrderedChipsPtr.end(), [](
const ChipPixelData*
a,
const ChipPixelData*
b) { return a->getChipID() > b->getChipID(); });
465 if (!mOrderedChipsPtr.empty()) {
466 auto chipData = *mOrderedChipsPtr.back();
467 assert(mLastReadChipID < chipData.getChipID());
468 mLastReadChipID = chipData.getChipID();
469 chipDataVec[mLastReadChipID].swap(chipData);
470 mOrderedChipsPtr.pop_back();
471 return &chipDataVec[mLastReadChipID];
474 if (!mDecodeNextAuto || decodeNextTrigger() < 0) {
477 return getNextChipData(chipDataVec);
484 if (!mOrderedChipsPtr.empty()) {
485 auto ruChip = *mOrderedChipsPtr.back();
486 assert(mLastReadChipID < ruChip.getChipID());
487 mLastReadChipID = ruChip.getChipID();
488 ruChip.swap(chipData);
489 mOrderedChipsPtr.pop_back();
493 if (!mDecodeNextAuto || decodeNextTrigger() < 0) {
496 return getNextChipData(chipData);
500template <
class Mapping>
504 for (
auto&
link : mGBTLinks) {
510template <
class Mapping>
514 mNThreads =
n > 0 ?
n : 1;
516 LOG(warning) << mSelfName <<
" Multithreading is not supported, imposing single thread";
522template <
class Mapping>
526 for (
auto& lnk : mGBTLinks) {
527 lnk.clear(
true, resetRaw);
529 mNChipsFiredROF = mNPixelsFiredROF = 0;
530 mNChipsFired = mNPixelsFired = mNExtTriggers = 0;
534template <
class Mapping>
538 bool dumpFullTF =
false;
539 for (
auto& ru : mRUDecodeVec) {
540 if (ru.linkHBFToDump.size()) {
541 if (
dump ==
int(GBTLink::RawDataDumps::DUMP_TF)) {
545 for (
auto it : ru.linkHBFToDump) {
546 if (
dump ==
int(GBTLink::RawDataDumps::DUMP_HBF)) {
547 const auto& lnk = mGBTLinks[mSubsSpec2LinkID[it.first >> 32].entry];
548 int entry = it.first & 0xffffffff;
549 bool allHBFs =
false;
551 if (
entry >= lnk.rawData.getNPieces()) {
554 fnm = fmt::format(
"{}{}rawdump_{}_run{}_tf_orb{}_full_feeID{:#06x}.raw", mRawDumpDirectory, mRawDumpDirectory.empty() ?
"" :
"/",
557 fnm = fmt::format(
"{}{}rawdump_{}_run{}_tf_orb{}_hbf_orb{}_feeID{:#06x}.raw", mRawDumpDirectory, mRawDumpDirectory.empty() ?
"" :
"/",
560 std::ofstream ostrm(fnm, std::ios::binary);
562 LOG(error) <<
"failed to open " << fnm;
565 while (
entry < lnk.rawData.getNPieces()) {
566 const auto* piece = lnk.rawData.getPiece(
entry);
567 if (!allHBFs && RDHUtils::getHeartBeatOrbit(
reinterpret_cast<const RDH*
>(piece->data)) != it.second) {
570 ostrm.write(
reinterpret_cast<const char*
>(piece->data), piece->size);
571 outSize += piece->size;
574 LOG(info) <<
"produced " << std::filesystem::current_path().c_str() <<
'/' << fnm;
580 std::string fnm = fmt::format(
"rawdump_{}_run{}_tf_orb{}_full.raw",
582 std::ofstream ostrm(fnm, std::ios::binary);
584 LOG(error) <<
"failed to open " << fnm;
587 for (
const auto& lnk : mGBTLinks) {
588 for (
size_t i = 0;
i < lnk.rawData.getNPieces();
i++) {
589 const auto* piece = lnk.rawData.getPiece(
i);
590 ostrm.write(
reinterpret_cast<const char*
>(piece->data), piece->size);
591 outSize += piece->size;
594 LOG(info) <<
"produced " << std::filesystem::current_path().c_str() <<
'/' << fnm;
601template <
class Mapping>
604 mTimerTFStart.Reset();
605 mTimerDecode.Reset();
606 mTimerFetchData.Reset();
607 for (
auto& ru : mRUDecodeVec) {
608 for (
auto& cab : ru.cableData) {
612 for (
auto&
link : mGBTLinks) {
613 link.rofJumpWasSeen =
false;
header::DataOrigin origin
A raw page parser for DPL input.
void setupLinks(o2::itsmft::MC2RawEncoder< MAP > &m2r, std::string_view outDir, std::string_view outPrefix, std::string_view fileFor)
Definition of the Alpide pixel reader for raw data processing.
static const VerbosityConfig & Instance()
The parser handles transparently input in the format of raw pages.
static void setCheckIncompleteHBF(bool v)
void swap(ChipPixelData &other)
uint16_t getChipID() const
void ensureChipOrdering()
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)
int decodeNextTrigger() final
void collectROFCableData(int iru)
void dump(const std::string what, DPMAP m, int verbose)
GLboolean GLboolean GLboolean b
GLboolean GLboolean GLboolean GLboolean a
constexpr o2::header::DataDescription gDataDescriptionInvalid
constexpr o2::header::DataOrigin gDataOriginInvalid
constexpr o2::header::DataDescription gDataDescriptionRawData
uint8_t itsSharedClusterMap uint8_t
Defining ITS Vertex explicitly as messageable.
constexpr int GBTPaddedWordLength
constexpr int GBTWordLength
static o2::header::DataHeader::PayloadSizeType getPayloadSize(const DataRef &ref)
support for the GBT single link data
static constexpr int MaxCablesPerRU
static constexpr int MaxLinksPerRU
static std::string concat_string(Ts const &... ts)
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"