15#ifndef GPUCA_STANDALONE
44#include <oneapi/tbb.h>
49using namespace std::string_literals;
53 memset((
void*)&native, 0,
sizeof(native));
64 for (
uint32_t j = 0;
j < GPUTPCGeometry::NROWS;
j++) {
85 for (
uint32_t j = 0;
j < GPUTPCGeometry::NROWS;
j++) {
114 for (
uint32_t j = 0;
j < GPUTrackingInOutZS::NENDPOINTS;
j++) {
123 if (hdr2->
flags & TPCZSHDRV2::ZSFlags::nTimeBinSpanBit8) {
127 uint32_t timeBin = (
hdr->
timeOffset + (o2::raw::RDHUtils::getHeartBeatOrbit(*rdh) - firstHBF) * o2::constants::lhc::LHCMaxBunches) / LHCBCPERTIMEBIN + nTimeBinSpan;
148typedef std::array<int64_t, TPCZSHDR::TPC_ZS_PAGE_SIZE /
sizeof(int64_t)> zsPage;
170 void ZSfillEmpty(
void*
ptr, int32_t shift,
uint32_t feeId, int32_t
orbit, int32_t linkid);
172 int64_t getHbf(
int64_t timestamp) {
return (timestamp * LHCBCPERTIMEBIN + bcShiftInFirstHBF) / o2::constants::lhc::LHCMaxBunches; }
175inline void zsEncoder::ZSfillEmpty(
void*
ptr, int32_t shift,
uint32_t feeId, int32_t
orbit, int32_t linkid)
179 o2::raw::RDHUtils::setHeartBeatBC(*rdh, shift);
197 bufOut[lenOut++] = (
uint8_t)(
byte & 0xFF);
203 bufOut[lenOut++] = byte;
210#ifndef GPUCA_STANDALONE
212static inline auto ZSEncoderGetDigits(
const DigitArray& in, int32_t
i) {
return in[
i].data(); }
213static inline auto ZSEncoderGetNDigits(
const DigitArray& in, int32_t
i) {
return in[
i].size(); }
218struct zsEncoderRow :
public zsEncoder {
228 constexpr static int32_t RAWLNK = rdh_utils::UserLogicLinkID;
230 bool checkInput(std::vector<o2::tpc::Digit>& tmpBuffer,
uint32_t k);
232 void init() {
encodeBits =
zsVersion == 2 ? TPCZSHDR::TPC_ZS_NBITS_V2 : TPCZSHDR::TPC_ZS_NBITS_V1; }
234 uint32_t encodeSequence(std::vector<o2::tpc::Digit>& tmpBuffer,
uint32_t k);
242 int32_t endpointa = GPUTPCGeometry::GetRegion(
a.getRow());
243 int32_t endpointb = GPUTPCGeometry::GetRegion(
b.getRow());
244 endpointa = 2 * endpointa + (
a.getRow() >= GPUTPCGeometry::GetRegionStart(endpointa) + GPUTPCGeometry::GetRegionRows(endpointa) / 2);
245 endpointb = 2 * endpointb + (
b.getRow() >= GPUTPCGeometry::GetRegionStart(endpointb) + GPUTPCGeometry::GetRegionRows(endpointb) / 2);
246 if (endpointa != endpointb) {
247 return endpointa <= endpointb;
249 if (
a.getTimeStamp() !=
b.getTimeStamp()) {
250 return a.getTimeStamp() <
b.getTimeStamp();
252 if (
a.getRow() !=
b.getRow()) {
253 return a.getRow() <
b.getRow();
255 return a.getPad() <
b.getPad();
258bool zsEncoderRow::checkInput(std::vector<o2::tpc::Digit>& tmpBuffer,
uint32_t k)
261 if (
lastRow != tmpBuffer[k].getRow()) {
269 for (
uint32_t l = k + 1; l < tmpBuffer.size(); l++) {
270 if (tmpBuffer[l].getRow() == tmpBuffer[k].getRow() && tmpBuffer[l].
getTimeStamp() == tmpBuffer[k].
getTimeStamp() && tmpBuffer[l].getPad() == tmpBuffer[l - 1].getPad() + 1) {
284 sizeChk += (tmpBuffer[k].getTimeStamp() !=
lastTime || tmpBuffer[k].getRow() !=
lastRow) ? 3 : 0;
288 if (sizeChk + (
encodeBits + streamSizeChkBits + 7) / 8 > TPCZSHDR::TPC_ZS_PAGE_SIZE) {
290 }
else if (sizeChk + (
seqLen *
encodeBits + streamSizeChkBits + 7) / 8 > TPCZSHDR::TPC_ZS_PAGE_SIZE) {
291 seqLen = ((TPCZSHDR::TPC_ZS_PAGE_SIZE - sizeChk) * 8 - streamSizeChkBits) /
encodeBits;
299bool zsEncoderRow::writeSubPage()
306 throw std::runtime_error(
"internal error during ZS encoding");
309 for (int32_t l = 1; l <
nRowsInTB; l++) {
316uint32_t zsEncoderRow::encodeSequence(std::vector<o2::tpc::Digit>& tmpBuffer,
uint32_t k)
330 lastRow = GPUTPCGeometry::NROWS;
332 if (tmpBuffer[k].getRow() !=
lastRow) {
345 for (int32_t l = 0; l <
seqLen; l++) {
351void zsEncoderRow::decodePage(std::vector<o2::tpc::Digit>& outputBuffer,
const zsPage* decPage,
uint32_t decEndpoint,
uint32_t firstOrbit,
uint32_t triggerBC)
353 const uint8_t* decPagePtr =
reinterpret_cast<const uint8_t*
>(decPage);
360 decPagePtr +=
sizeof(*decHDR);
364 const float decodeBitsFactor = 1.f / (1 << (
encodeBits - 10));
369 throw std::runtime_error(
"invalid TPC sector");
372 if ((
uint32_t)region != decEndpoint / 2) {
373 throw std::runtime_error(
"CRU ID / endpoint mismatch");
375 int32_t nRowsRegion = GPUTPCGeometry::GetRegionRows(region);
377 int32_t timeBin = (decHDR->
timeOffset + (
uint64_t)(o2::raw::RDHUtils::getHeartBeatOrbit(*rdh) - firstOrbit) * o2::constants::lhc::LHCMaxBunches) / LHCBCPERTIMEBIN;
379 if ((decPagePtr -
reinterpret_cast<const uint8_t*
>(decPage)) & 1) {
383 bool upperRows = tbHdr->
rowMask & 0x8000;
384 if (tbHdr->
rowMask != 0 && ((upperRows) ^ ((decEndpoint & 1) != 0))) {
385 throw std::runtime_error(
"invalid endpoint");
387 const int32_t rowOffset = GPUTPCGeometry::GetRegionStart(region) + (upperRows ? (nRowsRegion / 2) : 0);
388 const int32_t nRows = upperRows ? (nRowsRegion - nRowsRegion / 2) : (nRowsRegion / 2);
390 decPagePtr += nRowsUsed ? (2 * nRowsUsed) : 2;
392 for (int32_t
m = 0;
m <
nRows;
m++) {
393 if ((tbHdr->
rowMask & (1 <<
m)) == 0) {
396 const uint8_t* rowData = rowPos == 0 ? decPagePtr : (
reinterpret_cast<const uint8_t*
>(decPage) + tbHdr->rowAddr1()[rowPos - 1]);
397 const int32_t nSeqRead = *rowData;
398 const uint8_t* adcData = rowData + 2 * nSeqRead + 1;
400 decPagePtr += 1 + 2 * nSeqRead + nADC;
402 std::array<uint16_t, TPCZSHDR::TPC_ZS_PAGE_SIZE> decBuffer;
403 for (int32_t
n = 0;
n < nADC;
n++) {
404 byte |= *(adcData++) <<
bits;
407 decBuffer[posXbits++] =
byte &
mask;
413 for (int32_t
n = 0;
n < nSeqRead;
n++) {
414 const int32_t decSeqLen = rowData[(
n + 1) * 2] - (
n ? rowData[
n * 2] : 0);
415 for (int32_t o = 0; o < decSeqLen; o++) {
426#ifndef GPUCA_STANDALONE
427struct zsEncoderLinkBased :
public zsEncoder {
437 void createBitmask(std::vector<o2::tpc::Digit>& tmpBuffer,
uint32_t k);
442void zsEncoderLinkBased::init()
445 for (int32_t
i = 0;
i < 5;
i++) {
446 for (int32_t
j = 0;
j < 32;
j++) {
450 for (int32_t iCRU = 0; iCRU < 2; iCRU++) {
451 for (int32_t iChannel = 0; iChannel < 80; iChannel++) {
452 int32_t sampaOnFEC = 0, channelOnSAMPA = 0;
455 GPUError(
"ERROR: Channel conflict: %d %d: %d vs %d", sampaOnFEC, channelOnSAMPA,
inverseChannelMapping[sampaOnFEC][channelOnSAMPA], iChannel);
456 throw std::runtime_error(
"ZS error");
461 for (int32_t
i = 0;
i < 5;
i++) {
462 for (int32_t
j = 0;
j < 32;
j++) {
464 GPUError(
"ERROR: Map missing for sampa %d channel %d",
i,
j);
465 throw std::runtime_error(
"ZS error");
471void zsEncoderLinkBased::createBitmask(std::vector<o2::tpc::Digit>& tmpBuffer,
uint32_t k)
478 for (l = k; l < tmpBuffer.size(); l++) {
479 const auto&
a = tmpBuffer[l];
480 int32_t cruinsector = GPUTPCGeometry::GetRegion(
a.getRow());
485 int32_t tmpEndpoint = 2 * cruinsector + (fecInPartition >= (mapper.getPartitionInfo(cru.
partition()).getNumberOfFECs() + 1) / 2);
487 link = fecInPartition;
502 int32_t cruinsectora = GPUTPCGeometry::GetRegion(
a.getRow());
503 int32_t cruinsectorb = GPUTPCGeometry::GetRegion(
b.getRow());
504 if (cruinsectora != cruinsectorb) {
505 return cruinsectora < cruinsectorb;
516 int32_t endpointa = 2 * cruinsectora + (fecInPartitiona >= (mapper.getPartitionInfo(cru.
partition()).getNumberOfFECs() + 1) / 2);
517 int32_t endpointb = 2 * cruinsectorb + (fecInPartitionb >= (mapper.getPartitionInfo(cru.
partition()).getNumberOfFECs() + 1) / 2);
518 if (endpointa != endpointb) {
519 return endpointa < endpointb;
521 if (
a.getTimeStamp() !=
b.getTimeStamp()) {
522 return a.getTimeStamp() <
b.getTimeStamp();
524 if (fecInPartitiona != fecInPartitionb) {
525 return fecInPartitiona < fecInPartitionb;
532struct zsEncoderImprovedLinkBased :
public zsEncoderLinkBased {
533 bool checkInput(std::vector<o2::tpc::Digit>& tmpBuffer,
uint32_t k);
534 uint32_t encodeSequence(std::vector<o2::tpc::Digit>& tmpBuffer,
uint32_t k);
539 constexpr static int32_t RAWLNK = rdh_utils::ILBZSLinkID;
542bool zsEncoderImprovedLinkBased::checkInput(std::vector<o2::tpc::Digit>& tmpBuffer,
uint32_t k)
544 createBitmask(tmpBuffer, k);
552 if (TPCZSHDRV2::TIGHTLY_PACKED_V3) {
553 sizeChk += (
nSamples * TPCZSHDRV2::TPC_ZS_NBITS_V34 + 127) / 128 * 16;
555 sizeChk += (
nSamples + 2 * TPCZSHDRV2::SAMPLESPER64BIT - 1) / (2 * TPCZSHDRV2::SAMPLESPER64BIT) * 16;
557 if (sizeChk > TPCZSHDR::TPC_ZS_PAGE_SIZE) {
564uint32_t zsEncoderImprovedLinkBased::encodeSequence(std::vector<o2::tpc::Digit>& tmpBuffer,
uint32_t k)
569 tbHdr->
magicWord = o2::tpc::zerosupp_link_based::CommonHeader::MagicWordLinkZS;
571 tbHdr->
bitMaskLow = (
bitmask & std::bitset<80>(0xFFFFFFFFFFFFFFFFlu)).to_ulong();
575 hdr->nTimebinHeaders++;
576 if (TPCZSHDRV2::TIGHTLY_PACKED_V3) {
588 payloadPtr[
i / TPCZSHDRV2::SAMPLESPER64BIT] |= ((
uint64_t)
adcValues[
i]) << ((
i % TPCZSHDRV2::SAMPLESPER64BIT) * TPCZSHDRV2::TPC_ZS_NBITS_V34);
595bool zsEncoderImprovedLinkBased::writeSubPage()
600void zsEncoderImprovedLinkBased::initPage()
602 hdr->magicWord = o2::tpc::zerosupp_link_based::CommonHeader::MagicWordLinkZSMetaHeader;
603 hdr->nTimebinHeaders = 0;
604 hdr->firstZSDataOffset = 0;
607void zsEncoderImprovedLinkBased::decodePage(std::vector<o2::tpc::Digit>& outputBuffer,
const zsPage* decPage,
uint32_t decEndpoint,
uint32_t firstOrbit,
uint32_t triggerBC)
610 const uint8_t* decPagePtr =
reinterpret_cast<const uint8_t*
>(decPage);
617 decPagePtr +=
sizeof(*decHDR);
618 if (decHDR->
version != ZSVersion::ZSVersionLinkBasedWithMeta) {
621 if (decHDR->
magicWord != o2::tpc::zerosupp_link_based::CommonHeader::MagicWordLinkZSMetaHeader) {
622 throw std::runtime_error(
"Magic word missing");
624 const float decodeBitsFactor = 1.f / (1 << (
encodeBits - 10));
629 throw std::runtime_error(
"invalid TPC sector");
639 outputBuffer.emplace_back(
o2::tpc::Digit{cruid, adcValue, rowInSector, padInRow, timeBin});
643 raw_processing_helpersa::processZSdata((
const char*)decPagePtr,
size, rdh_utils::getFEEID(cruid, decEndpoint & 1, feeLink), o2::raw::RDHUtils::getHeartBeatOrbit(*rdh), firstOrbit, decHDR->
timeOffset, fillADC);
646 throw std::runtime_error(
"ZS TB Hdr does not have linkZS magic word");
650 LOGP(
debug,
"zsEncoderImprovedLinkBased::decodePage skipping digits hdr->tOff {} + hdr->bc {} + (orbit {} - firstOrbit {}) * maxBunch {} - triggerBC {} = {} < 0", decHDR->
timeOffset, tbHdr->
bunchCrossing, o2::raw::RDHUtils::getHeartBeatOrbit(*rdh), firstOrbit, o2::constants::lhc::LHCMaxBunches, triggerBC, timeBin);
653 const uint8_t* adcData = (
const uint8_t*)(decPagePtr +
sizeof(*tbHdr));
656 std::vector<uint16_t> decBuffer(nADC);
657 if (TPCZSHDRV2::TIGHTLY_PACKED_V3) {
659 while (posXbits < nADC) {
660 byte |= *(adcData++) <<
bits;
663 decBuffer[posXbits++] =
byte &
mask;
670 for (int32_t
j = 0;
j < nADC;
j++) {
671 decBuffer[
j] = (adcData64[
j / TPCZSHDRV2::SAMPLESPER64BIT] >> ((
j % TPCZSHDRV2::SAMPLESPER64BIT) * TPCZSHDRV2::TPC_ZS_NBITS_V34)) &
mask;
674 for (int32_t
j = 0, k = 0;
j <
bitmask.size();
j++) {
676 int32_t sampaOnFEC = 0, channelOnSAMPA = 0;
677 mapper.getSampaAndChannelOnFEC(cruid,
j, sampaOnFEC, channelOnSAMPA);
678 const auto padSecPos = mapper.padSecPos(cruid, tbHdr->
fecInPartition, sampaOnFEC, channelOnSAMPA);
679 const auto& padPos = padSecPos.getPadPos();
690struct zsEncoderDenseLinkBased :
public zsEncoderLinkBased {
691 bool checkInput(std::vector<o2::tpc::Digit>& tmpBuffer,
uint32_t k);
692 uint32_t encodeSequence(std::vector<o2::tpc::Digit>& tmpBuffer,
uint32_t k);
702 constexpr static int32_t RAWLNK = rdh_utils::DLBZSLinkID;
703 constexpr static int32_t v2nbits = 10;
706bool zsEncoderDenseLinkBased::checkInput(std::vector<o2::tpc::Digit>& tmpBuffer,
uint32_t k)
708 createBitmask(tmpBuffer, k);
715uint32_t zsEncoderDenseLinkBased::encodeSequence(std::vector<o2::tpc::Digit>& tmpBuffer,
uint32_t k)
719 if (
zsVersion == ZSVersion::ZSVersionDenseLinkBasedV2) {
727 hdr->flags |= TPCZSHDRV2::ZSFlags::nTimeBinSpanBit8;
729 hdr->nTimebinHeaders++;
736 std::bitset<10> bitmaskL2;
737 for (int32_t
i = 9;
i >= 0;
i--) {
738 bitmaskL2.set(
i, ((
bitmask >> (
i * 8)) & std::bitset<80>(0xFF)).any());
740 if (bitmaskL2.all()) {
741 *plink |= 0b00100000;
743 *plink |= (bitmaskL2.to_ulong() >> 2) & 0b11000000;
747 for (int32_t
i = 0;
i < 10;
i++) {
748 if (bitmaskL2.test(
i)) {
753 static_assert(TPCZSHDRV2::TPC_ZS_NBITS_V34 == 12);
761bool zsEncoderDenseLinkBased::writeSubPage()
765 bool need12bit =
zsVersion != ZSVersion::ZSVersionDenseLinkBasedV2;
767 if (
zsVersion == ZSVersion::ZSVersionDenseLinkBasedV2) {
777 encodeBitsBlock = v2nbits;
805void zsEncoderDenseLinkBased::initPage()
807 hdr->magicWord = o2::tpc::zerosupp_link_based::CommonHeader::MagicWordLinkZSMetaHeader;
808 hdr->nTimebinHeaders = 0;
816void zsEncoderDenseLinkBased::decodePage(std::vector<o2::tpc::Digit>& outputBuffer,
const zsPage* decPage,
uint32_t decEndpoint,
uint32_t firstOrbit,
uint32_t triggerBC)
819 const uint8_t* decPagePtr =
reinterpret_cast<const uint8_t*
>(decPage);
826 if (decHDR->
version < ZSVersion::ZSVersionDenseLinkBased || decHDR->
version > ZSVersion::ZSVersionDenseLinkBasedV2) {
829 if (decHDR->
magicWord != o2::tpc::zerosupp_link_based::CommonHeader::MagicWordLinkZSMetaHeader) {
830 throw std::runtime_error(
"Magic word missing");
832 const uint8_t* payloadEnd = ((
const uint8_t*)decPage) + o2::raw::RDHUtils::getMemorySize(*rdh) -
sizeof(
TPCZSHDRV2) - ((decHDR->
flags & TPCZSHDRV2::ZSFlags::TriggerWordPresent) ? TPCZSHDRV2::TRIGGER_WORD_SIZE : 0);
833 const float decodeBitsFactor = 1.f / (1 << (
encodeBits - 10));
837 throw std::runtime_error(
"invalid TPC sector");
841 std::vector<uint8_t> tmpBuffer;
842 bool extendFailure =
false;
844 uint32_t minTimeBin = -1, maxTimeBin = 0;
846 int32_t sizeLeftInPage = payloadEnd - decPagePtr;
847 if (sizeLeftInPage <= 0) {
848 throw std::runtime_error(
"Decoding ran beyond end of page before processing extended timebin");
851 if (o2::raw::RDHUtils::getMemorySize(*rdh) != TPCZSHDR::TPC_ZS_PAGE_SIZE) {
852 throw std::runtime_error(
"pageExtends signaled, but current page is not full");
855 const uint8_t* pageNext = ((
const uint8_t*)decPage) + TPCZSHDR::TPC_ZS_PAGE_SIZE;
858 if ((
uint16_t)(o2::raw::RDHUtils::getPageCounter(*rdh) + 1) != o2::raw::RDHUtils::getPageCounter(*rdhNext)) {
859 GPUError(
"Incomplete HBF: Payload extended to next page, but next page missing in stream (packet counters %d %d)", (int32_t)o2::raw::RDHUtils::getPageCounter(*rdh), (int32_t)o2::raw::RDHUtils::getPageCounter(*rdhNext));
860 extendFailure =
true;
861 decPagePtr = payloadEnd;
867 memcpy(tmpBuffer.data(), decPagePtr, sizeLeftInPage);
869 decPagePtr = tmpBuffer.data();
870 payloadEnd = decPagePtr + tmpBuffer.size();
874 bool v2Flag = decHDR->
version == ZSVersion::ZSVersionDenseLinkBasedV2 && *((
const uint8_t*)decPagePtr) & 0x10;
875 if (decHDR->
version == ZSVersion::ZSVersionDenseLinkBasedV2) {
879 std::vector<int32_t>
links;
880 std::vector<std::bitset<80>> bitmasks;
882 for (
uint32_t l = 0; l < linkCount; l++) {
885 uint8_t decLink = decLinkX & 0b00011111;
886 std::bitset<10> bitmaskL2;
887 if (decLinkX & 0b00100000) {
890 bitmaskL2 = std::bitset<10>(((((
uint16_t)decLinkX) & 0b11000000) << 2) | (
uint16_t)*((
const uint8_t*)decPagePtr));
895 for (int32_t
i = 0;
i < 10;
i++) {
896 if (bitmaskL2.test(
i)) {
901 links.emplace_back(decLink);
902 bitmasks.emplace_back(
bitmask);
903 nTotalSamples +=
bitmask.count();
908 decPagePtr += (nTotalSamples * encodeBitsBlock + 7) / 8;
911 int32_t timeBin = (
int32_t(linkBC) + (
int32_t)(o2::raw::RDHUtils::getHeartBeatOrbit(*rdh) - firstOrbit) * o2::constants::lhc::LHCMaxBunches -
int32_t(triggerBC)) / LHCBCPERTIMEBIN;
912 if (timeBin < 0 || nTotalSamples == 0) {
913 if (timeBin < 0 && nTotalSamples > 0) {
914 LOGP(
debug,
"zsEncoderDenseLinkBased::decodePage skipping digits (linkBC {} + orbit {} - firstOrbit {}) * maxBunch {} - triggerBC {} = {} < 0, nTotalSamples {}", linkBC, o2::raw::RDHUtils::getHeartBeatOrbit(*rdh), firstOrbit, o2::constants::lhc::LHCMaxBunches, triggerBC, timeBin, nTotalSamples);
918 if (timeBin > maxTimeBin) {
919 maxTimeBin = timeBin;
921 if (timeBin < minTimeBin) {
922 minTimeBin = timeBin;
925 std::vector<uint16_t>
samples(nTotalSamples);
928 while (posXbits < nTotalSamples) {
929 byte |= *(adcData++) <<
bits;
931 while (
bits >= encodeBitsBlock && posXbits < nTotalSamples) {
933 byte =
byte >> encodeBitsBlock;
934 bits -= encodeBitsBlock;
939 for (
uint32_t l = 0; l < linkCount; l++) {
941 const auto&
bitmask = bitmasks[l];
944 for (int32_t
j = 0;
j <
bitmask.size();
j++) {
946 int32_t sampaOnFEC = 0, channelOnSAMPA = 0;
947 mapper.getSampaAndChannelOnFEC(cruid,
j, sampaOnFEC, channelOnSAMPA);
948 const auto padSecPos = mapper.padSecPos(cruid, decLink, sampaOnFEC, channelOnSAMPA);
949 const auto& padPos = padSecPos.getPadPos();
957 int32_t hdrMinTimeBin = (
int32_t(decHDR->
timeOffset) +
int32_t(o2::raw::RDHUtils::getHeartBeatOrbit(*rdh) - firstOrbit) * o2::constants::lhc::LHCMaxBunches - triggerBC);
958 if (triggerBC > 0 && hdrMinTimeBin < 0) {
961 hdrMinTimeBin /= LHCBCPERTIMEBIN;
962 int32_t hdrMaxTimeBin = hdrMinTimeBin + decHDR->
nTimeBinSpan + ((decHDR->
flags & TPCZSHDRV2::ZSFlags::nTimeBinSpanBit8) ? 256 : 0);
964 if (!extendFailure && nOutput != decHDR->
nADCsamples) {
965 std::ostringstream oss;
966 oss <<
"Number of decoded digits " << nOutput <<
" does not match value from MetaInfo " << decHDR->
nADCsamples;
967 amendPageErrorMessage(oss, rdh, decHDR,
nullptr,
nullptr, nOutput);
968 throw std::runtime_error(oss.str());
971 if (decHDR->
nADCsamples && (minTimeBin < hdrMinTimeBin || maxTimeBin > hdrMaxTimeBin)) {
972 std::ostringstream oss;
973 oss <<
"Incorrect time bin range in MetaInfo, header reports " << hdrMinTimeBin <<
" - " << hdrMaxTimeBin <<
"(timeOffset: " << decHDR->
timeOffset <<
" + (orbit: " << o2::raw::RDHUtils::getHeartBeatOrbit(*rdh) <<
" - firstOrbit " << firstOrbit <<
") * LHCMaxBunches - triggerBC: " << triggerBC <<
", decoded data is " << minTimeBin <<
" - " << maxTimeBin;
974 amendPageErrorMessage(oss, rdh, decHDR, payloadEnd, decPagePtr, nOutput);
975 throw std::runtime_error(oss.str());
979 std::ostringstream oss;
980 oss <<
"Decoding ran over end of page";
981 amendPageErrorMessage(oss, rdh, decHDR, payloadEnd, decPagePtr, nOutput);
982 throw std::runtime_error(oss.str());
984 if (decHDR->
nTimebinHeaders && payloadEnd - decPagePtr >= 2 * o2::raw::RDHUtils::GBTWord128) {
985 std::ostringstream oss;
986 oss <<
"Decoding didn't reach end of page";
987 amendPageErrorMessage(oss, rdh, decHDR, payloadEnd, decPagePtr, nOutput);
988 throw std::runtime_error(oss.str());
994 if (payloadEnd && decPagePtr) {
995 oss <<
" (payloadEnd " << (
void*)payloadEnd <<
" - decPagePtr " << (
void*)decPagePtr <<
" - " << (payloadEnd - decPagePtr) <<
" bytes left, " << nOutput <<
" of " << decHDR->
nADCsamples <<
" digits decoded)\n";
999 constexpr size_t bufferSize = 3 * std::max(
sizeof(*rdh),
sizeof(*decHDR)) + 1;
1001 for (
size_t i = 0;
i <
sizeof(*rdh);
i++) {
1002 snprintf(dumpBuffer + 3 *
i, 4,
"%02X ", (int32_t)((
uint8_t*)rdh)[
i]);
1004 oss <<
"RDH of page: " <<
dumpBuffer <<
"\n";
1005 for (
size_t i = 0;
i <
sizeof(*decHDR);
i++) {
1006 snprintf(dumpBuffer + 3 *
i, 4,
"%02X ", (int32_t)((
uint8_t*)decHDR)[
i]);
1008 oss <<
"Meta header of page: " <<
dumpBuffer <<
"\n";
1016struct zsEncoderRun :
public T {
1017 uint32_t run(std::vector<zsPage>*
buffer, std::vector<o2::tpc::Digit>& tmpBuffer,
size_t* totalSize =
nullptr);
1018 size_t compare(std::vector<zsPage>*
buffer, std::vector<o2::tpc::Digit>& tmpBuffer);
1020 using T::bcShiftInFirstHBF;
1021 using T::checkInput;
1023 using T::decodePage;
1024 using T::encodeBits;
1025 using T::encodeBitsFactor;
1026 using T::encodeSequence;
1028 using T::firstTimebinInPage;
1036 using T::lastEndpoint;
1039 using T::needAnotherPage;
1041 using T::outputEndpoint;
1042 using T::outputRegion;
1043 using T::packetCounter;
1046 using T::pageCounter;
1051 using T::writeSubPage;
1052 using T::ZSfillEmpty;
1057inline uint32_t zsEncoderRun<T>::run(std::vector<zsPage>*
buffer, std::vector<o2::tpc::Digit>& tmpBuffer,
size_t* totalSize)
1060 zsPage singleBuffer;
1061#ifndef GPUCA_STANDALONE
1063 int32_t minhbf = o2::constants::lhc::LHCMaxBunches;
1069 (
void)(rawcru + rawendpoint);
1073 for (
uint32_t k = 0; k <= tmpBuffer.size();) {
1074 bool mustWritePage =
false, mustWriteSubPage =
false;
1077 mustWritePage =
true;
1079 if (k < tmpBuffer.size()) {
1083 throw std::runtime_error(
"Received digit before the defined first orbit");
1087 mustWritePage =
true;
1090 if (
lastRow != tmpBuffer[k].getRow()) {
1091 curRegion = GPUTPCGeometry::GetRegion(tmpBuffer[k].getRow());
1093 mustWriteSubPage = checkInput(tmpBuffer, k);
1096 mustWritePage =
true;
1099 if (mustWritePage || mustWriteSubPage) {
1100 mustWritePage |= writeSubPage();
1102 if (
page && mustWritePage) {
1103 if constexpr (std::is_same_v<T, struct zsEncoderDenseLinkBased>) {
1107 uint8_t* triggerWord =
nullptr;
1111 pagePtr += o2::raw::RDHUtils::GBTWord128;
1118 needAnotherPage =
true;
1123 pagePtr += o2::tpc::TPCZSHDRV2::TRIGGER_WORD_SIZE;
1126 pagePtr += o2::raw::RDHUtils::GBTWord128;
1131 throw std::runtime_error(
"TPC ZS page overflow");
1133 memcpy(pagehdr,
hdr,
sizeof(*
hdr));
1135 memset(triggerWord, 0, o2::tpc::TPCZSHDRV2::TRIGGER_WORD_SIZE);
1143 size = CAMath::nextMultipleOf<o2::raw::RDHUtils::GBTWord128>(
size);
1144#ifndef GPUCA_STANDALONE
1147 maxhbf = std::max<int32_t>(maxhbf,
hbf);
1148 minhbf = std::min<int32_t>(minhbf,
hbf);
1168 if (mustWritePage) {
1180 page = &singleBuffer;
1194 std::fill(
page->begin(),
page->end(), 0);
1196 if constexpr (std::is_same_v<T, struct zsEncoderDenseLinkBased>) {
1216 uint32_t nEncoded = encodeSequence(tmpBuffer, k);
1217 lastTime = tmpBuffer[k].getTimeStamp();
1218 lastRow = tmpBuffer[k].getRow();
1223#ifndef GPUCA_STANDALONE
1225 for (int32_t
i = minhbf;
i <= maxhbf;
i++) {
1226 raw->
addData(46208, 360, rdh_utils::SACLinkID, 0, *
ir +
i * o2::constants::lhc::LHCMaxBunches, gsl::span<char>((
char*)&singleBuffer, (
char*)&singleBuffer),
true, 0, 4);
1231 for (
uint32_t j = 0;
j < GPUTrackingInOutZS::NENDPOINTS;
j++) {
1243size_t zsEncoderRun<T>::compare(std::vector<zsPage>*
buffer, std::vector<o2::tpc::Digit>& tmpBuffer)
1246 std::vector<o2::tpc::Digit> compareBuffer;
1247 compareBuffer.reserve(tmpBuffer.size());
1248 for (
uint32_t j = 0;
j < GPUTrackingInOutZS::NENDPOINTS;
j++) {
1251 zsPage* decPage = &
buffer[
j][k];
1252 decodePage(compareBuffer, decPage,
j, firstOrbit);
1255 if (tmpBuffer.size() != compareBuffer.size()) {
1256 nErrors += tmpBuffer.size();
1257 printf(
"Number of clusters mismatch %d %d\n", (int32_t)tmpBuffer.size(), (int32_t)compareBuffer.size());
1260 const float decodeBitsFactor = (1 << (
encodeBits - 10));
1261 const float c = CAMath::Round(tmpBuffer[
j].getChargeFloat() * decodeBitsFactor) / decodeBitsFactor;
1267 printf(
"%4u: OK %d: Charge %3d %3d Time %4d %4d Pad %3d %3d Row %3d %3d\n",
j, ok,
1268 (int32_t)
c, (int32_t)compareBuffer[
j].getChargeFloat(), (int32_t)tmpBuffer[
j].
getTimeStamp(), (int32_t)compareBuffer[
j].
getTimeStamp(), (int32_t)tmpBuffer[
j].getPad(), (int32_t)compareBuffer[
j].getPad(), (int32_t)tmpBuffer[
j].getRow(), (int32_t)compareBuffer[
j].getRow());
1279void GPUReconstructionConvert::RunZSEncoder(
const S& in, std::unique_ptr<uint64_t[]>* outBuffer, uint32_t* outSizes,
o2::raw::RawFileWriter* raw,
const o2::InteractionRecord*
ir,
const GPUParam&
param, int32_t
version,
bool verify,
float threshold,
bool padding, std::function<
void(std::vector<o2::tpc::Digit>&)> digitsFilter)
1283 if (((outBuffer ==
nullptr) ^ (outSizes ==
nullptr)) || ((
raw !=
nullptr) && (
ir ==
nullptr)) || !((outBuffer ==
nullptr) ^ (
raw ==
nullptr)) || (
raw && verify)) {
1284 throw std::runtime_error(
"Invalid parameters");
1287 std::vector<zsPage>
buffer[
NSECTORS][GPUTrackingInOutZS::NENDPOINTS];
1288 struct tmpReductionResult {
1290 size_t totalSize = 0;
1292 size_t digitsInput = 0;
1293 size_t digitsEncoded = 0;
1295 auto reduced = tbb::parallel_reduce(tbb::blocked_range<uint32_t>(0,
NSECTORS), tmpReductionResult(), [&](
const auto range,
auto red) {
1297 std::vector<o2::tpc::Digit> tmpBuffer;
1298 red.digitsInput += ZSEncoderGetNDigits(in,
i);
1299 tmpBuffer.resize(ZSEncoderGetNDigits(in,
i));
1300 if (threshold > 0.f && !digitsFilter) {
1301 auto it = std::copy_if(ZSEncoderGetDigits(in,
i), ZSEncoderGetDigits(in,
i) + ZSEncoderGetNDigits(in,
i), tmpBuffer.begin(), [threshold](
auto&
v) { return v.getChargeFloat() >= threshold; });
1302 tmpBuffer.resize(std::distance(tmpBuffer.begin(), it));
1304 std::copy(ZSEncoderGetDigits(in,
i), ZSEncoderGetDigits(in,
i) + ZSEncoderGetNDigits(in,
i), tmpBuffer.begin());
1308 digitsFilter(tmpBuffer);
1309 if (threshold > 0.f) {
1310 std::vector<o2::tpc::Digit> tmpBuffer2 = std::move(tmpBuffer);
1311 tmpBuffer = std::vector<o2::tpc::Digit>(tmpBuffer2.size());
1312 auto it = std::copy_if(tmpBuffer2.begin(), tmpBuffer2.end(), tmpBuffer.begin(), [threshold](
auto&
v) { return v.getChargeFloat() >= threshold; });
1313 tmpBuffer.resize(std::distance(tmpBuffer.begin(), it));
1316 red.digitsEncoded += tmpBuffer.size();
1318 auto runZS = [&](
auto& encoder) {
1321 red.totalPages += encoder.run(
buffer[
i], tmpBuffer, &red.totalSize);
1323 red.nErrors += encoder.compare(
buffer[
i], tmpBuffer);
1327 if (
version >= ZSVersion::ZSVersionRowBased10BitADC &&
version <= ZSVersion::ZSVersionRowBased12BitADC) {
1328 zsEncoderRun<zsEncoderRow> enc{{{.iSector =
i, .raw =
raw, .ir =
ir, .param = &
param, .padding =
padding}}};
1330 }
else if (
version >= ZSVersion::ZSVersionLinkBasedWithMeta &&
version <= ZSVersion::ZSVersionDenseLinkBasedV2) {
1331#ifndef GPUCA_STANDALONE
1332 if (
version == ZSVersion::ZSVersionLinkBasedWithMeta) {
1333 zsEncoderRun<zsEncoderImprovedLinkBased> enc{{{{.iSector =
i, .raw =
raw, .ir =
ir, .param = &
param, .padding =
padding}}}};
1335 }
else if (
version >= ZSVersion::ZSVersionDenseLinkBased &&
version <= ZSVersion::ZSVersionDenseLinkBasedV2) {
1336 zsEncoderRun<zsEncoderDenseLinkBased> enc{{{{.iSector =
i, .raw =
raw, .ir =
ir, .param = &
param, .padding =
padding}}}};
1340 throw std::runtime_error(
"Link based ZS encoding not supported in standalone build");
1346 return red; }, [&](
const auto& red1,
const auto& red2) {
1348 red.totalPages += red2.totalPages;
1349 red.totalSize += red2.totalSize;
1350 red.nErrors += red2.nErrors;
1351 red.digitsInput += red2.digitsInput;
1352 red.digitsEncoded += red2.digitsEncoded;
1356 outBuffer->reset(
new uint64_t[reduced.totalPages * TPCZSHDR::TPC_ZS_PAGE_SIZE /
sizeof(
uint64_t)]);
1359 for (
uint32_t j = 0;
j < GPUTrackingInOutZS::NENDPOINTS;
j++) {
1360 memcpy((
char*)outBuffer->get() +
offset,
buffer[
i][
j].data(),
buffer[
i][
j].size() * TPCZSHDR::TPC_ZS_PAGE_SIZE);
1362 outSizes[
i * GPUTrackingInOutZS::NENDPOINTS +
j] =
buffer[
i][
j].size();
1366 if (reduced.nErrors) {
1367 GPUError(
"ERROR: %lu INCORRECT SAMPLES DURING ZS ENCODING VERIFICATION!!!", reduced.nErrors);
1368 }
else if (verify) {
1369 GPUInfo(
"ENCODING VERIFICATION PASSED");
1371 GPUInfo(
"TOTAL ENCODED SIZE: %lu (%lu of %lu digits encoded)", reduced.totalSize, reduced.digitsEncoded, reduced.digitsInput);
1375template void GPUReconstructionConvert::RunZSEncoder<GPUTrackingInOutDigits>(
const GPUTrackingInOutDigits&, std::unique_ptr<uint64_t[]>*, uint32_t*,
o2::raw::RawFileWriter*,
const o2::InteractionRecord*,
const GPUParam&, int32_t,
bool,
float,
bool, std::function<
void(std::vector<o2::tpc::Digit>&)> digitsFilter);
1376#ifndef GPUCA_STANDALONE
1377template void GPUReconstructionConvert::RunZSEncoder<DigitArray>(
const DigitArray&, std::unique_ptr<uint64_t[]>*, uint32_t*,
o2::raw::RawFileWriter*,
const o2::InteractionRecord*,
const GPUParam&, int32_t,
bool,
float,
bool, std::function<
void(std::vector<o2::tpc::Digit>&)> digitsFilter);
1384 for (
uint32_t j = 0;
j < GPUTrackingInOutZS::NENDPOINTS;
j++) {
1385 ptrs[
i * GPUTrackingInOutZS::NENDPOINTS +
j] = (
char*)
buffer +
offset;
1386 offset +=
sizes[
i * GPUTrackingInOutZS::NENDPOINTS +
j] * TPCZSHDR::TPC_ZS_PAGE_SIZE;
1387 out->
sector[
i].
zsPtr[
j] = &ptrs[
i * GPUTrackingInOutZS::NENDPOINTS +
j];
1397 if (
buffers[
i].get() != ptrs[
i] || nsb != ns) {
1398 throw std::runtime_error(
"Not owning digits");
1401 const uint32_t decodeBits = zs12bit ? TPCZSHDR::TPC_ZS_NBITS_V2 : TPCZSHDR::TPC_ZS_NBITS_V1;
1402 const float decodeBitsFactor = (1 << (decodeBits - 10));
1404 if (
buffers[
i][k].getChargeFloat() >= threshold) {
1409 buffers[
i][
j].setCharge(CAMath::Round(
buffers[
i][
j].getChargeFloat() * decodeBitsFactor) / decodeBitsFactor);
1420#ifndef GPUCA_STANDALONE
1426 std::shared_ptr<T> enc = std::make_shared<T>();
1427 if (
param ==
nullptr) {
1429 param = &dummyParam;
1434 return [enc](std::vector<o2::tpc::Digit>& outBuffer,
const void*
page,
uint32_t firstTfOrbit,
uint32_t triggerBC = 0) {
1439 if (o2::raw::RDHUtils::getDetectorField(rdh) != 2) {
1443 enc->iSector = cru.sector();
1444 int32_t endpoint = cru.region() * 2 + o2::tpc::rdh_utils::getEndPoint(rdh);
1445 enc->decodePage(outBuffer, (
const zsPage*)
page,
endpoint, firstTfOrbit, triggerBC);
1453 return o2::gpu::internal::GetDecoder_internal<zsEncoderRow>(
param,
version);
1455 return o2::gpu::internal::GetDecoder_internal<zsEncoderImprovedLinkBased>(
param,
version);
1457 return o2::gpu::internal::GetDecoder_internal<zsEncoderDenseLinkBased>(
param,
version);
unsigned short int uint16_t
std::array< uint8_t, TPCZSHDR::TPC_ZS_PAGE_SIZE > streamBuffer8
std::array< uint16_t, TPCZSHDR::TPC_ZS_PAGE_SIZE > streamBuffer
std::bitset< 80 > bitmask
int32_t inverseChannelMapping[5][32]
int32_t bcShiftInFirstHBF
std::vector< uint8_t > sequenceBuffer
std::vector< uint16_t > sequenceBufferADC
std::vector< uint16_t > adcValues
int32_t firstTimebinInPage
o2::raw::RawFileWriter * raw
configStandalone Light OpenGL display display_light Apply smoothing to points Enable Z buffer Highlight links Highlight seeds Highlight sector tracks Highlight final tracks Show individual sector
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error s
Timeframe settings Average distance in cm of events merged into Randomize distance around average distance of merged events Simulate correct bunch interactions instead of placing only the average number of events A value[n] sets TFlen for[n] collisions in Number of bunches per trainsort Number of bunch trains Instantaneous interaction rate Do not simulate border Total number of collisions to be placed in the interior of all time Do not select random but walk over array of events in stride steps h Event generator settings h configStandalone Use CPU for GPU Force usage of the specified GPU device no CPU fallback Continue processing after an error First event to Number of events to Number of iterations to Number of iterations to Number of initial iterations excluded from const char Directory with events to Events directory is and not inside events Show standalone event Run event generator maximum time bin of continuous for triggered for automatic continuous for automatic continuous triggered uint64_t
configStandalone Reconstruction rec_tpc multiplier for the combined cluster track error during track following area in cm for the search of for z only used if decrease removal by when above this local occupancy rowx Shift of TPC revert cluster flag edge bit distance to edge exceeds this ZOffset for secondary multiple of radius max P of electron K BB bands crossing max P of electron p BB bands crossing max P of electron d BB bands crossing max P of electron t BB bands crossing min accepted dEdxMaxTPC of the track Additive extra cluster error for Y2 if edge flag set Additive extra cluster error for Y2 if single set Additive extra cluster error for Y2 if or single set Additive extra cluster error for Z2 if or single set Extra errors to add to track when crossing depending on addErrorsCECrossing Inner portion of y range in sector that is not used in searching for extrapolated track candidates factor2YS for track merging factor2K for track merging Margin in cm of Y position when rejecting edge clusters based on uncorrected track Y Max fraction of shared clusters for tracklet Except pad from cluster finding if total number of charges in a fragment is above this Except pad from cluster finding if number of consecutive charges in a fragment is above this Threshold where a timebin is considered disabling the noisy pad check for that pad Treat signal above this minimum as saturated Smoothing factor for the exponential Highly Ionising Particle tail filter Number of timebins to use for the averaging Add additional custom track errors when crossing relative as fraction of Do N fit passes in final fit of< 0:reject at max -n hits") AddOptionRTC(rejectIFCLowRadiusCluster, uint8_t, 1, "", 0, "Reject clusters that get the IFC mask error during refit") AddOptionRTC(dEdxTruncLow, uint8_t, 2, "", 0, "Low truncation threshold, fraction of 128") AddOptionRTC(dEdxTruncHigh, uint8_t, 77, "", 0, "High truncation threshold, fraction of 128") AddOptionRTC(extrapolationTracking, int8_t, 1, "", 0, "Enable Extrapolation Tracking(prolong tracks to adjacent sectors to find short segments)") AddOptionRTC(disableRefitAttachment, uint8_t, 0, "", 0, "Bitmask to disable certain attachment steps during refit(1:attachment, 2:propagation, 4:loop following, 8:mirroring)") AddOptionRTC(rejectionStrategy, uint8_t, o2::gpu::GPUSettings::RejectionStrategyA, "", 0, "Enable rejection of TPC clusters for compression(0=no, 1=strategy A, 2=strategy B)") AddOptionRTC(mergeLoopersAfterburner, uint8_t, 1, "", 0, "Run afterburner for additional looper merging") AddOptionRTC(compressionTypeMask, uint8_t, o2::gpu::GPUSettings::CompressionFull, "", 0, "TPC Compression mode bits(1=truncate charge/width LSB, 2=differences, 4=track-model)") AddOptionRTC(compressionSortOrder, uint8_t, o2::gpu::GPUSettings::SortTime, "", 0, "Sort order of TPC compression(0=time, 1=pad, 2=Z-time-pad, 3=Z-pad-time, 4=no sorting(use incoming order))") AddOptionRTC(sigBitsCharge, uint8_t, 4, "", 0, "Number of significant bits for TPC cluster charge in compression mode 1") AddOptionRTC(sigBitsWidth, uint8_t, 3, "", 0, "Number of significant bits for TPC cluster width in compression mode 1") AddOptionRTC(dropLoopers, uint8_t, 0, "", 0, "Drop looping tracks starting from second loop") AddOptionRTC(mergerInterpolateErrors, uint8_t, 1, "", 0, "Use interpolation instead of extrapolation for chi2 based cluster rejection") AddOptionRTC(mergerInterpolateRejectAlsoOnCurrentPosition, uint8_t, 1, "", 0, "When using mergerInterpolateErrors, reject based on chi2 twice computed with interpolated and current track position starting from NDF > mergerNonInterpolateRejectMinNDF Merge tracks accross the central electrode Enable PID response Add sub threshold clusters in TPC dEdx computation OR mask of TPC flags that will reject the cluster in alternative dEdx Reject edge clusters based on uncorrected track Y during track fit Increase decrease removal by when on this number of pads from the edge h configStandalone Reconstruction rec_trd Max chi2 for TRD tracklets to be matched to a track Chi2 cut for strict matching mode Number of sigmas for ITS TPC track time error estimate Addition to search road around track prolongation along Y in cm Optimal tracklet rphi resolution in maximum chi2 per attached tracklet for TRD tracks take into account the full likelihood of the slope including exponential tails Tracks with less attached tracklets are discarded after the tracking Post trigger Pile up integration time in BCs fits all iterations but the last one in projections Use material lookup table for TPC refit Apply workarounds to avoid cyclic merge should not be needed tpc dyn configStandalone Processing proc_rtc Replace constant variables static by constexpr expressions Compile RTC in deterministic with NO_FAST_MATH flags and GPUCA_DETERMINISTIC_MODE define Use RTC to optimize GPU code h configStandalone Processing proc_rtctech Use a file lock to serialize access to the cache folder int32_t
Header to collect LHC related constants.
Utility class to write detectors data to (multiple) raw data file(s) respecting CRU format.
definitions to deal with the link based zero suppression format
Definitions of TPC Zero Suppression Data Headers.
static void RunZSEncoder(const S &in, std::unique_ptr< uint64_t[]> *outBuffer, uint32_t *outSizes, o2::raw::RawFileWriter *raw, const o2::InteractionRecord *ir, const GPUParam ¶m, int32_t version, bool verify, float threshold=0.f, bool padding=false, std::function< void(std::vector< o2::tpc::Digit > &)> digitsFilter=nullptr)
static std::function< void(std::vector< o2::tpc::Digit > &, const void *, uint32_t, uint32_t)> GetDecoder(int32_t version, const GPUParam *param)
static void RunZSFilter(std::unique_ptr< o2::tpc::Digit[]> *buffers, const o2::tpc::Digit *const *ptrs, size_t *nsb, const size_t *ns, const GPUParam ¶m, bool zs12bit, float threshold)
static int32_t GetMaxTimeBin(const o2::tpc::ClusterNativeAccess &native)
static constexpr uint32_t NSECTORS
static void RunZSEncoderCreateMeta(const uint64_t *buffer, const uint32_t *sizes, void **ptrs, GPUTrackingInOutZS *out)
static void ConvertRun2RawToNative(o2::tpc::ClusterNativeAccess &native, std::unique_ptr< o2::tpc::ClusterNative[]> &nativeBuffer, const AliHLTTPCRawCluster **rawClusters, uint32_t *nRawClusters)
void addData(uint16_t feeid, uint16_t cru, uint8_t lnk, uint8_t endpoint, const IR &ir, const gsl::span< char > data, bool preformatted=false, uint32_t trigger=0, uint32_t detField=0)
unsigned char partition() const
unsigned char getSampaChannel() const
unsigned char getIndex() const
unsigned char getSampaChip() const
static Mapper & instance(const std::string mappingDir="")
static constexpr void getSampaAndChannelOnFEC(const int cruID, const size_t rawFECChannel, int &sampaOnFEC, int &channelOnSAMPA)
static constexpr int MAXSECTOR
std::array< gsl::span< const o2::tpc::Digit >, Sector::MAXSECTOR > DigitArray
GLuint GLsizei const GLuint const GLintptr const GLsizeiptr * sizes
GLboolean GLboolean GLboolean b
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const void * bits
typedef void(APIENTRYP PFNGLCULLFACEPROC)(GLenum mode)
GLboolean GLboolean GLboolean GLboolean a
const GBTLinkAttributes links[kNGBTLinks]
void dumpBuffer(gsl::span< const std::byte > buffer, std::ostream &out=std::cout, size_t maxbytes=std::numeric_limits< size_t >::max())
uint64_t getTimeStamp(o2::framework::ProcessingContext &pc)
Global TPC definitions and constants.
@ ZSVersionDenseLinkBased
@ ZSVersionLinkBasedWithMeta
@ ZSVersionDenseLinkBasedV2
@ ZSVersionRowBased10BitADC
@ ZSVersionRowBased12BitADC
unsigned short GlobalPadNumber
global pad number
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
std::string to_string(gsl::span< T, Size > span)
int32_t GetCharge() const
uint16_t GetFlags() const
float GetSigmaTime2() const
int32_t GetPadRow() const
float GetSigmaPad2() const
uint16_t bc
bunch crossing ID of interaction
const o2::tpc::Digit * tpcDigits[NSECTORS]
size_t nTPCDigits[NSECTORS]
const void *const * zsPtr[NENDPOINTS]
uint32_t count[NENDPOINTS]
const uint32_t * nZSPtr[NENDPOINTS]
GPUTrackingInOutZSSector sector[NSECTORS]
static void setLinkID(H &rdh, uint8_t v, NOTPTR(H))
static void setDetectorField(H &rdh, uint32_t v, NOTPTR(H))
static void setPageCounter(H &rdh, uint16_t v, NOTPTR(H))
static void setMemorySize(H &rdh, uint16_t v, NOTPTR(H))
static void setVersion(H &rdh, uint8_t v, NOTPTR(H))
static void setPacketCounter(H &rdh, uint8_t v, NOTPTR(H))
static void setHeartBeatOrbit(RDHv4 &rdh, uint32_t v)
static void setFEEID(RDHv4 &rdh, uint16_t v)
unsigned int nClusters[constants::MAXSECTOR][constants::MAXGLOBALPADROW]
unsigned int nClustersTotal
const ClusterNative * clusters[constants::MAXSECTOR][constants::MAXGLOBALPADROW]
unsigned int clusterOffset[constants::MAXSECTOR][constants::MAXGLOBALPADROW]
const ClusterNative * clustersLinear
@ payloadExtendsToNextPage
unsigned short nTimebinHeaders
unsigned short firstZSDataOffset
unsigned char nTimeBinSpan
unsigned short timeOffset
unsigned short nADCsamples
void compare(std::string_view s1, std::string_view s2)
o2::InteractionRecord ir(0, 0)
std::vector< Digit > digits