13#include <unordered_map>
17#include <fmt/format.h>
18#include <fmt/chrono.h>
45void processLinkZS(
o2::framework::RawParser<>& parser, std::unique_ptr<o2::tpc::rawreader::RawReaderCRU>& reader, uint32_t firstOrbit, uint32_t syncOffsetReference, uint32_t decoderType,
int triggerBC);
52 bool sampledData =
true;
68 LOGP(info,
"Using sampled data");
76 std::vector<InputSpec>
filter = getFilter(inputs);
78 size_t errorCount = 0;
80 uint64_t activeSectors = 0;
81 uint32_t firstOrbit = 0;
82 bool readFirst =
false;
83 bool readFirstZS =
false;
85 const auto triggerBC = ((decoderType == 1 && useTrigger)) ? getTriggerBCoffset(inputs,
filter) : -1;
86 if (returnOnNoTrigger && (triggerBC < 0)) {
99 const auto* dh = DataRefUtils::getHeader<o2::header::DataHeader*>(
ref);
106 firstOrbit = dh->firstTForbit;
109 const auto subSpecification = dh->subSpecification;
116 const auto linkID = (
rdh_utils::FEEIDType)((subSpecification + (subSpecification >> 8)) & 0xFF) - 1;
118 feeID = rdh_utils::getFEEID(cruID, endPoint, linkID);
121 const uint64_t sector = rdh_utils::getCRU(feeID) / 10;
124 if (sectors.size() && (std::find(sectors.begin(), sectors.end(),
int(sector)) == sectors.end())) {
128 activeSectors |= (0x1 << sector);
133 rdh_utils::getMapping(feeID, cruID, endPoint, linkID);
134 const auto globalLinkID = linkID + endPoint * 12;
135 LOGP(
debug,
"Specifier: {}/{}/{} Part {} of {}", dh->dataOrigin, dh->dataDescription, subSpecification, dh->splitPayloadIndex, dh->splitPayloadParts);
136 LOGP(
debug,
"Payload size: {}", payloadSize);
137 LOGP(
debug,
"CRU: {}; linkID: {}; endPoint: {}; globalLinkID: {}", cruID, linkID, endPoint, globalLinkID);
141 const gsl::span<const char> raw = inputs.
get<gsl::span<char>>(
ref);
142 std::unique_ptr<o2::framework::RawParser<8192>> rawparserPtr;
147 bool isLinkZS =
false;
149 auto it = parser.begin();
152 if (!rdhPtr || rdhVersion < 6) {
153 throw std::runtime_error(fmt::format(
"could not get RDH from packet, or version {} < 6", rdhVersion).
data());
155 const auto link = RDHUtils::getLinkID(*rdhPtr);
156 const auto detField = RDHUtils::getDetectorField(*rdhPtr);
157 const auto feeID = RDHUtils::getFEEID(*rdhPtr);
158 const auto feeLinkID = rdh_utils::getLink(feeID);
159 if (detField ==
raw_data_types::LinkZS || ((link == 0 || link == rdh_utils::UserLogicLinkID) && ((feeLinkID == rdh_utils::ILBZSLinkID || feeLinkID == rdh_utils::DLBZSLinkID) && detField ==
raw_data_types::ZS))) {
162 if (feeLinkID == rdh_utils::DLBZSLinkID) {
163 LOGP(info,
"Detected Dense Link-based zero suppression");
164 }
else if (feeLinkID == rdh_utils::ILBZSLinkID) {
165 LOGP(info,
"Detected Improved Link-based zero suppression");
167 LOGP(info,
"Detected Link-based zero suppression");
169 if (!reader->getManager() || !reader->getManager()->getLinkZSCallback()) {
170 LOGP(fatal,
"LinkZSCallback must be set in RawReaderCRUManager");
178 LOGP(info,
"First orbit in present TF: {}", firstOrbit);
184 processLinkZS(parser, reader, firstOrbit, syncOffsetReference, decoderType, triggerBC);
189 }
catch (
const std::exception& e) {
191 using namespace std::literals::chrono_literals;
192 static std::unordered_map<uint32_t, size_t> nErrorPerSubspec;
193 static std::chrono::time_point<std::chrono::steady_clock> lastReport = std::chrono::steady_clock::now();
194 const auto now = std::chrono::steady_clock::now();
195 static size_t reportedErrors = 0;
198 ++nErrorPerSubspec[subSpecification];
201 if (reportedErrors < MAXERRORS) {
203 std::string sleepInfo;
204 if (reportedErrors == MAXERRORS) {
205 sleepInfo = fmt::format(
", maximum error count ({}) reached, not reporting for the next {}", MAXERRORS,
sleepTime);
207 LOGP(alarm,
"EXCEPTIION in processRawData: {} -> skipping part:{}/{} of spec:{}/{}/{}, size:{}, error count for subspec: {}{}", e.what(), dh->splitPayloadIndex, dh->splitPayloadParts,
208 dh->dataOrigin, dh->dataDescription, subSpecification, payloadSize, nErrorPerSubspec.at(subSpecification), sleepInfo);
220 *nerrors += errorCount;
222 return activeSectors;
230 rdh_utils::getMapping(feeID, cruID, endPoint, linkID);
231 const auto globalLinkID = linkID + endPoint * 12;
234 reader->forceCRU(cruID);
235 reader->setLink(globalLinkID);
240 for (
auto it = parser.
begin(),
end = parser.
end(); it !=
end; ++it) {
242 const auto size = it.size();
243 auto data = it.data();
247 for (
int i = 0;
i <
size;
i += 16) {
262 reader->runADCDataCallback(rawData);
267 for (
auto it = parser.
begin(),
end = parser.
end(); it !=
end; ++it) {
270 if (!rdhPtr || rdhVersion < 6) {
271 throw std::runtime_error(fmt::format(
"could not get RDH from packet, or version {} < 6", rdhVersion).
data());
279 const auto link = RDHUtils::getLinkID(*rdhPtr);
280 const auto detField = RDHUtils::getDetectorField(*rdhPtr);
281 const auto feeID = RDHUtils::getFEEID(*rdhPtr);
282 const auto linkID = rdh_utils::getLink(feeID);
285 ((linkID == rdh_utils::ILBZSLinkID || linkID == rdh_utils::DLBZSLinkID) && (detField == raw_data_types::Type::ZS)))) {
289 if ((decoderType == 1) && (linkID == rdh_utils::ILBZSLinkID || linkID == rdh_utils::DLBZSLinkID) && (detField == raw_data_types::Type::ZS)) {
290 std::vector<Digit>
digits;
292 gpuDecoder.
DecodePage(
digits, (
const void*)it.raw(), firstOrbit,
nullptr,
static_cast<unsigned int>((triggerBC > 0) ? triggerBC : 0));
293 for (
const auto& digit :
digits) {
294 reader->getManager()->getLinkZSCallback()(digit.getCRU(), digit.getRow(), digit.getPad(), digit.getTimeStamp(), digit.getChargeFloat());
297 const auto orbit = RDHUtils::getHeartBeatOrbit(*rdhPtr);
298 const auto data = (
const char*)it.data();
299 const auto size = it.size();
308 uint32_t syncOffsetReference = 144;
311 const auto* dh = DataRefUtils::getHeader<o2::header::DataHeader*>(
ref);
318 const gsl::span<const char> raw = inputs.
get<gsl::span<char>>(
ref);
321 for (
auto it = parser.begin(),
end = parser.end(); it !=
end; ++it) {
324 if (!rdhPtr || rdhVersion < 6) {
325 throw std::runtime_error(fmt::format(
"could not get RDH from packet, or version {} < 6", rdhVersion).
data());
329 const auto link = RDHUtils::getLinkID(*rdhPtr);
330 const auto detField = RDHUtils::getDetectorField(*rdhPtr);
331 const auto feeID = RDHUtils::getFEEID(*rdhPtr);
332 const auto linkID = rdh_utils::getLink(feeID);
335 ((linkID == rdh_utils::ILBZSLinkID) && (detField == raw_data_types::Type::ZS)))) {
339 const auto data = (
const char*)it.data();
340 const auto size = it.size();
345 while (zsdata < zsdataEnd) {
346 const auto& header = zsdata->
cont.header;
348 if (!header.hasCorrectMagicWord()) {
354 if (header.isTriggerInfo()) {
355 zsdata = zsdata->
next();
359 syncOffsetReference = std::max(header.syncOffsetBC, syncOffsetReference);
367 LOGP(info,
"syncOffsetReference in this TF: {}", syncOffsetReference);
368 return syncOffsetReference;
374 const auto orbit = RDHUtils::getTriggerOrbit(rdh);
375 int triggerBCOffset = -1;
377 const auto& header = zsdata->
cont.header;
378 if (!header.hasCorrectMagicWord()) {
382 if (header.isTriggerInfo()) {
385 const auto triggerOrbit = triggerInfo->triggerInfo.getOrbit();
386 const auto triggerBC = triggerInfo->triggerInfo.bunchCrossing;
388 LOGP(
debug,
"TriggerInfoV1: orbit: {}, firstOrbit: {}, triggerOrbit: {}, triggerBC: {}, triggerBCOffset: {}",
orbit, firstOrbit, triggerOrbit, triggerBC, triggerBCOffset);
389 zsdata = zsdata->
next();
390 return triggerBCOffset;
391 }
else if (header.isTriggerInfoV2()) {
394 const auto triggerOrbit = triggerInfo->orbit;
395 const auto triggerBC = triggerInfo->bunchCrossing;
397 LOGP(
debug,
"TriggerInfoV2: orbit: {}, firstOrbit: {}, triggerOrbit: {}, triggerBC: {}, triggerBCOffset: {}",
orbit, firstOrbit, triggerOrbit, triggerBC, triggerBCOffset);
398 zsdata = zsdata->
next();
399 return triggerBCOffset;
400 }
else if (header.isMetaHeader()) {
404 if (triggerInfo.hasTrigger()) {
405 const auto triggerBC = triggerInfo.getFirstBC();
406 const auto triggerOrbit =
orbit;
408 LOGP(
debug,
"TriggerInfoV3: orbit: {}, firstOrbit: {}, triggerOrbit: {}, triggerBC: {}, triggerBCOffset: {}",
orbit, firstOrbit, triggerOrbit, triggerBC, triggerBCOffset);
411 return triggerBCOffset;
420 const auto feeId = RDHUtils::getFEEID(rdh);
421 const auto link = rdh_utils::getLink(feeId);
423 if (link != rdh_utils::DLBZSLinkID) {
430 if (header->magicWord != 0xfd) {
431 LOGP(error,
"Wrong magic word: {}, wrong data type?", header->magicWord);
434 if (!(header->flags & TPCZSHDRV2::ZSFlags::TriggerWordPresent)) {
441 if (triggerWord->isValid(iTrg)) {
450 const auto triggerBC = triggerWord->getTriggerBC(iTrg);
451 const auto orbit = RDHUtils::getHeartBeatOrbit(rdh);
453 LOGP(
debug,
"TriggerWordDLBZS {}: Type = {}, orbit = {}, firstOrbit = {}, BC = {}, oribitBC = {}", iTrg, triggerWord->getTriggerType(iTrg),
orbit, firstOrbit, triggerWord->getTriggerBC(iTrg), orbitBC);
464 uint32_t firstOrbit = 0;
466 const auto* dh = DataRefUtils::getHeader<o2::header::DataHeader*>(
ref);
473 firstOrbit = dh->firstTForbit;
476 const gsl::span<const char> raw = inputs.
get<gsl::span<char>>(
ref);
477 std::unique_ptr<o2::framework::RawParser<8192>> rawparserPtr;
480 for (
auto it = parser.
begin(),
end = parser.
end(); it !=
end; ++it) {
483 if (!rdhPtr || rdhVersion < 6) {
484 throw std::runtime_error(fmt::format(
"could not get RDH from packet, or version {} < 6", rdhVersion).
data());
488 const auto link = RDHUtils::getLinkID(*rdhPtr);
489 const auto detField = RDHUtils::getDetectorField(*rdhPtr);
490 const auto feeID = RDHUtils::getFEEID(*rdhPtr);
491 const auto linkID = rdh_utils::getLink(feeID);
494 ((linkID == rdh_utils::ILBZSLinkID || linkID == rdh_utils::DLBZSLinkID) && (detField == raw_data_types::Type::ZS)))) {
498 const auto data = (
const char*)it.raw();
499 const auto size = it.sizeTotal();
502 if (thisTrigger >= 0 && !slowScan) {
503 triggerBC = thisTrigger;
507 if (triggerBC >= 0 && triggerBC != thisTrigger) {
508 LOGP(error,
"inconsistent trigger information in raw pages of this TF");
513 if (triggerBC >= 0 && !slowScan) {
517 if (triggerBC >= 0) {
518 LOGP(info,
"Found triggerBCoffset: {}", triggerBC);
uint32_t getBCsyncOffsetReference(InputRecord &inputs, const std::vector< InputSpec > &filter)
int getTriggerInfoLBZS(const char *data, size_t size, uint32_t firstOrbit)
void processGBT(o2::framework::RawParser<> &parser, std::unique_ptr< o2::tpc::rawreader::RawReaderCRU > &reader, const rdh_utils::FEEIDType feeID)
void processLinkZS(o2::framework::RawParser<> &parser, std::unique_ptr< o2::tpc::rawreader::RawReaderCRU > &reader, uint32_t firstOrbit, uint32_t syncOffsetReference, uint32_t decoderType, int triggerBC)
Generic parser for consecutive raw pages.
definitions to deal with the link based zero suppression format
Definitions of TPC Zero Suppression Data Headers.
const_iterator begin() const
const_iterator end() const
void DecodePage(std::vector< o2::tpc::Digit > &outputBuffer, const void *page, uint32_t tfFirstOrbit, const GPUParam *param, uint32_t triggerBC=0)
helper to store the ADC raw data
helper to encapsulate a GBTFrame
void setFrameNumber(uint32_t frameNumber)
set packet number
void readFromMemory(gsl::span< const std::byte > data)
read from memory
void updateSyncCheck(SyncArray &syncArray)
update the sync check
void getFrameHalfWords()
extract the 4 5b halfwords for the 5 data streams from one GBT frame
void getAdcValues(ADCRawData &rawData)
decode ADC values
void setPacketNumber(uint32_t packetNumber)
set packet number
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
constexpr o2::header::DataOrigin gDataOriginTPC
constexpr int LHCMaxBunches
Defining PrimaryVertex explicitly as messageable.
uint64_t processRawData(o2::framework::InputRecord &inputs, std::unique_ptr< o2::tpc::rawreader::RawReaderCRU > &reader, bool useOldSubspec=false, const std::vector< int > §ors={}, size_t *nerrors=nullptr, uint32_t syncOffsetReference=144, uint32_t decoderType=1, bool useTrigger=true, bool returnOnNoTrigger=false)
int getTriggerBCoffset(o2::framework::InputRecord &inputs, std::vector< o2::framework::InputSpec > filter={}, bool slowScan=false)
absolute BC relative to TF start (firstOrbit)
std::vector< o2::framework::InputSpec > getFilter(o2::framework::InputRecord &inputs)
absolute BC relative to TF start (firstOrbit)
@ ZS
final Zero Suppression (can be ILBZS, DLBZS)
@ LinkZS
Link-based Zero Suppression.
bool processZSdata(const char *data, size_t size, rdh_utils::FEEIDType feeId, uint32_t orbit, uint32_t referenceOrbit, uint32_t syncOffsetReference, ADCCallback fillADC)
Global TPC definitions and constants.
static o2::header::DataHeader::PayloadSizeType getPayloadSize(const DataRef &ref)
static constexpr int getVersion()
get numeric version of the RDH
static constexpr uint16_t MaxTriggerEntries
Maximum number of trigger information.
@ Cal
Laser (Calibration trigger)
ContainerT< DataBitSizeT, SignificantBitsT, HasHeaderT > cont
Templated data container.
Container * next() const
get position of next container. Validity check to be done outside!
Container for Trigger information, header + data.
Data definition for the new trigger information after FW update, allowing for interleaved triggers.
std::vector< Digit > digits