Project
Loading...
Searching...
No Matches
CalibProcessingHelper.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 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
12#include <fmt/core.h>
13#include <unordered_map>
14#include <vector>
15#include <algorithm>
16#include <chrono>
17#include <fmt/format.h>
18#include <fmt/chrono.h>
19
20#include "GPUO2InterfaceUtils.h"
23#include "Framework/Logger.h"
24#include "DPLUtils/RawParser.h"
27#include "Headers/RDHAny.h"
32
33#include "TPCBase/RDHUtils.h"
36
38
39using namespace o2::tpc;
40using namespace o2::framework;
43
44void processGBT(o2::framework::RawParser<>& parser, std::unique_ptr<o2::tpc::rawreader::RawReaderCRU>& reader, const rdh_utils::FEEIDType feeID);
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);
46uint32_t getBCsyncOffsetReference(InputRecord& inputs, const std::vector<InputSpec>& filter);
47
48std::vector<o2::framework::InputSpec> calib_processing_helper::getFilter(o2::framework::InputRecord& inputs)
49{
50 std::vector<InputSpec> filter = {{"check", ConcreteDataTypeMatcher{o2::header::gDataOriginTPC, "RAWDATA"}, Lifetime::Timeframe}};
51 // TODO: check if presence of data sampling can be checked in another way
52 bool sampledData = true;
53 for ([[maybe_unused]] auto const& ref : InputRecordWalker(inputs, filter)) {
54 sampledData = false;
55 break;
56 }
57 // used for online monitor
58 if (sampledData) {
59 filter = {{"sampled-rawdata", ConcreteDataTypeMatcher{"DS2", "RAWDATA"}, Lifetime::Timeframe}};
60 for ([[maybe_unused]] auto const& ref : InputRecordWalker(inputs, filter)) {
61 sampledData = false;
62 break;
63 }
64 }
65 // used for QC
66 if (sampledData) {
67 filter = {{"sampled-rawdata", ConcreteDataTypeMatcher{"DS", "RAWDATA"}, Lifetime::Timeframe}};
68 LOGP(info, "Using sampled data");
69 }
70
71 return filter;
72}
73
74uint64_t calib_processing_helper::processRawData(o2::framework::InputRecord& inputs, std::unique_ptr<rawreader::RawReaderCRU>& reader, bool useOldSubspec, const std::vector<int>& sectors, size_t* nerrors, uint32_t syncOffsetReference, uint32_t decoderType, bool useTrigger, bool returnOnNoTrigger)
75{
76 std::vector<InputSpec> filter = getFilter(inputs);
77
78 size_t errorCount = 0;
79
80 uint64_t activeSectors = 0;
81 uint32_t firstOrbit = 0;
82 bool readFirst = false;
83 bool readFirstZS = false;
84
85 const auto triggerBC = ((decoderType == 1 && useTrigger)) ? getTriggerBCoffset(inputs, filter) : -1;
86 if (returnOnNoTrigger && (triggerBC < 0)) {
87 return 0;
88 }
89
90 // for LinkZS data the maximum sync offset is needed to align the data properly.
91 // getBCsyncOffsetReference only works, if the full TF is seen. Alternatively, this value could be set
92 // fixed to e.g. 144 or 152 which is the maximum sync delay expected
93 // this is less precise and might lead to more time bins which have to be removed at the beginnig
94 // or end of the TF
95 // uint32_t syncOffsetReference = getBCsyncOffsetReference(inputs, filter);
96 // uint32_t syncOffsetReference = 144;
97
98 for (auto const& ref : InputRecordWalker(inputs, filter)) {
99 const auto* dh = DataRefUtils::getHeader<o2::header::DataHeader*>(ref);
100 auto payloadSize = DataRefUtils::getPayloadSize(ref);
101 // skip empty HBF
102 if (payloadSize == 2 * sizeof(o2::header::RAWDataHeader)) {
103 continue;
104 }
105
106 firstOrbit = dh->firstTForbit;
107
108 // ---| extract hardware information to do the processing |---
109 const auto subSpecification = dh->subSpecification;
110 rdh_utils::FEEIDType feeID = (rdh_utils::FEEIDType)dh->subSpecification;
111
112 if (useOldSubspec) {
113 //---| old definition by Gvozden |---
114 // TODO: make auto detect from firt RDH?
115 const auto cruID = (rdh_utils::FEEIDType)(subSpecification >> 16);
116 const auto linkID = (rdh_utils::FEEIDType)((subSpecification + (subSpecification >> 8)) & 0xFF) - 1;
117 const auto endPoint = (rdh_utils::FEEIDType)((subSpecification >> 8) & 0xFF) > 0;
118 feeID = rdh_utils::getFEEID(cruID, endPoint, linkID);
119 }
120
121 const uint64_t sector = rdh_utils::getCRU(feeID) / 10;
122
123 // sector selection should be better done by directly subscribing to a range of subspecs. But this might not be that simple
124 if (sectors.size() && (std::find(sectors.begin(), sectors.end(), int(sector)) == sectors.end())) {
125 continue;
126 }
127
128 activeSectors |= (0x1 << sector);
129
130 // ===| for debugging only |===
131 // remove later
132 rdh_utils::FEEIDType cruID, linkID, endPoint;
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);
138 // ^^^^^^
139
140 // TODO: exception handling needed?
141 const gsl::span<const char> raw = inputs.get<gsl::span<char>>(ref);
142 std::unique_ptr<o2::framework::RawParser<8192>> rawparserPtr;
143 try {
144
145 o2::framework::RawParser parser(raw.data(), raw.size());
146 // detect decoder type by analysing first RDH
147 bool isLinkZS = false;
148 {
149 auto it = parser.begin();
150 auto rdhPtr = reinterpret_cast<const o2::header::RDHAny*>(it.raw());
151 const auto rdhVersion = RDHUtils::getVersion(rdhPtr);
152 if (!rdhPtr || rdhVersion < 6) {
153 throw std::runtime_error(fmt::format("could not get RDH from packet, or version {} < 6", rdhVersion).data());
154 }
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))) {
160 isLinkZS = true;
161 if (!readFirstZS) {
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");
166 } else {
167 LOGP(info, "Detected Link-based zero suppression");
168 }
169 if (!reader->getManager() || !reader->getManager()->getLinkZSCallback()) {
170 LOGP(fatal, "LinkZSCallback must be set in RawReaderCRUManager");
171 }
172 readFirstZS = true;
173 }
174 }
175
176 // firstOrbit = RDHUtils::getHeartBeatOrbit(*rdhPtr);
177 if (!readFirst) {
178 LOGP(info, "First orbit in present TF: {}", firstOrbit);
179 }
180 readFirst = true;
181 }
182
183 if (isLinkZS) {
184 processLinkZS(parser, reader, firstOrbit, syncOffsetReference, decoderType, triggerBC);
185 } else {
186 processGBT(parser, reader, feeID);
187 }
188
189 } catch (const std::exception& e) {
190 // error message throtteling
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;
196 const size_t MAXERRORS = 10;
197 const auto sleepTime = 10min;
198 ++nErrorPerSubspec[subSpecification];
199
200 if ((now - lastReport) < sleepTime) {
201 if (reportedErrors < MAXERRORS) {
202 ++reportedErrors;
203 std::string sleepInfo;
204 if (reportedErrors == MAXERRORS) {
205 sleepInfo = fmt::format(", maximum error count ({}) reached, not reporting for the next {}", MAXERRORS, sleepTime);
206 }
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);
209 lastReport = now;
210 }
211 } else {
212 lastReport = now;
213 reportedErrors = 0;
214 }
215 errorCount++;
216 continue;
217 }
218 }
219 if (nerrors) {
220 *nerrors += errorCount;
221 }
222 return activeSectors;
223}
224
225void processGBT(o2::framework::RawParser<>& parser, std::unique_ptr<o2::tpc::rawreader::RawReaderCRU>& reader, const rdh_utils::FEEIDType feeID)
226{
227 // TODO: currently this will only work for HBa1, since the sync is in the first packet and
228 // the decoder expects all packets of one link to be processed at once
229 rdh_utils::FEEIDType cruID, linkID, endPoint;
230 rdh_utils::getMapping(feeID, cruID, endPoint, linkID);
231 const auto globalLinkID = linkID + endPoint * 12;
232
233 // ---| update hardware information in the reader |---
234 reader->forceCRU(cruID);
235 reader->setLink(globalLinkID);
236
237 rawreader::ADCRawData rawData;
238 rawreader::GBTFrame gFrame;
239
240 for (auto it = parser.begin(), end = parser.end(); it != end; ++it) {
241
242 const auto size = it.size();
243 auto data = it.data();
244 // LOGP(info, "Data size: {}", size);
245
246 int iFrame = 0;
247 for (int i = 0; i < size; i += 16) {
248 gFrame.setFrameNumber(iFrame);
249 gFrame.setPacketNumber(iFrame / 508);
250 gFrame.readFromMemory(gsl::span<const std::byte>((std::byte*)data + i, 16));
251
252 // extract the half words from the 4 32-bit words
253 gFrame.getFrameHalfWords();
254
255 gFrame.getAdcValues(rawData);
256 gFrame.updateSyncCheck(false);
257
258 ++iFrame;
259 }
260 }
261
262 reader->runADCDataCallback(rawData);
263}
264
265void processLinkZS(o2::framework::RawParser<>& parser, std::unique_ptr<o2::tpc::rawreader::RawReaderCRU>& reader, uint32_t firstOrbit, uint32_t syncOffsetReference, uint32_t decoderType, int triggerBC)
266{
267 for (auto it = parser.begin(), end = parser.end(); it != end; ++it) {
268 auto rdhPtr = reinterpret_cast<const o2::header::RDHAny*>(it.raw());
269 const auto rdhVersion = RDHUtils::getVersion(rdhPtr);
270 if (!rdhPtr || rdhVersion < 6) {
271 throw std::runtime_error(fmt::format("could not get RDH from packet, or version {} < 6", rdhVersion).data());
272 }
273 // workaround for MW2 data
274 // const bool useTimeBins = true;
275 // const auto cru = RDHUtils::getCRUID(*rdhPtr);
276 // const auto feeID = (RDHUtils::getFEEID(*rdhPtr) & 0x7f) | (cru << 7);
277
278 // skip all data that is not Link-base zero suppression
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);
283 if (!((detField == raw_data_types::LinkZS) ||
284 ((detField == raw_data_types::RAWDATA || detField == 0xdeadbeef) && (link == rdh_utils::UserLogicLinkID)) ||
285 ((linkID == rdh_utils::ILBZSLinkID || linkID == rdh_utils::DLBZSLinkID) && (detField == raw_data_types::Type::ZS)))) {
286 continue;
287 }
288
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());
295 }
296 } else {
297 const auto orbit = RDHUtils::getHeartBeatOrbit(*rdhPtr);
298 const auto data = (const char*)it.data();
299 const auto size = it.size();
300 raw_processing_helpers::processZSdata(data, size, feeID, orbit, firstOrbit, syncOffsetReference, reader->getManager()->getLinkZSCallback());
301 }
302 }
303}
304
305// find the global sync offset reference, using the large sync offset to avoid negative time bins
306uint32_t getBCsyncOffsetReference(InputRecord& inputs, const std::vector<InputSpec>& filter)
307{
308 uint32_t syncOffsetReference = 144;
309
310 for (auto const& ref : InputRecordWalker(inputs, filter)) {
311 const auto* dh = DataRefUtils::getHeader<o2::header::DataHeader*>(ref);
312 auto payloadSize = DataRefUtils::getPayloadSize(ref);
313 // skip empty HBF
314 if (payloadSize == 2 * sizeof(o2::header::RAWDataHeader)) {
315 continue;
316 }
317
318 const gsl::span<const char> raw = inputs.get<gsl::span<char>>(ref);
319 o2::framework::RawParser parser(raw.data(), raw.size());
320
321 for (auto it = parser.begin(), end = parser.end(); it != end; ++it) {
322 auto rdhPtr = reinterpret_cast<const o2::header::RDHAny*>(it.raw());
323 const auto rdhVersion = RDHUtils::getVersion(rdhPtr);
324 if (!rdhPtr || rdhVersion < 6) {
325 throw std::runtime_error(fmt::format("could not get RDH from packet, or version {} < 6", rdhVersion).data());
326 }
327
328 // only process LinkZSdata, only supported for data where this is already set in the UL
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);
333 if (!((detField == raw_data_types::LinkZS) ||
334 ((detField == raw_data_types::RAWDATA || detField == 0xdeadbeef) && (link == rdh_utils::UserLogicLinkID)) ||
335 ((linkID == rdh_utils::ILBZSLinkID) && (detField == raw_data_types::Type::ZS)))) {
336 continue;
337 }
338
339 const auto data = (const char*)it.data();
340 const auto size = it.size();
341
344
345 while (zsdata < zsdataEnd) {
346 const auto& header = zsdata->cont.header;
347 // align to header word if needed
348 if (!header.hasCorrectMagicWord()) {
349 zsdata = (zerosupp_link_based::ContainerZS*)((const char*)zsdata + sizeof(zerosupp_link_based::Header));
350 continue;
351 }
352
353 // skip trigger info
354 if (header.isTriggerInfo()) {
355 zsdata = zsdata->next();
356 continue;
357 }
358
359 syncOffsetReference = std::max(header.syncOffsetBC, syncOffsetReference);
360
361 // only read first time bin for each link
362 break;
363 }
364 }
365 }
366
367 LOGP(info, "syncOffsetReference in this TF: {}", syncOffsetReference);
368 return syncOffsetReference;
369}
370
371int getTriggerInfoLBZS(const char* data, size_t size, uint32_t firstOrbit)
372{
373 auto rdh = (const RDHAny*)data;
374 const auto orbit = RDHUtils::getTriggerOrbit(rdh);
375 int triggerBCOffset = -1;
377 const auto& header = zsdata->cont.header;
378 if (!header.hasCorrectMagicWord()) {
379 return -1;
380 }
381
382 if (header.isTriggerInfo()) {
383 // for the moment only skip the trigger info
384 const auto triggerInfo = (zerosupp_link_based::TriggerContainer*)zsdata;
385 const auto triggerOrbit = triggerInfo->triggerInfo.getOrbit();
386 const auto triggerBC = triggerInfo->triggerInfo.bunchCrossing;
387 triggerBCOffset = int(triggerOrbit - firstOrbit) * o2::constants::lhc::LHCMaxBunches + triggerBC;
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()) {
392 // for the moment only skip the trigger info
393 const auto triggerInfo = (zerosupp_link_based::TriggerInfoV2*)zsdata;
394 const auto triggerOrbit = triggerInfo->orbit;
395 const auto triggerBC = triggerInfo->bunchCrossing;
396 triggerBCOffset = int(triggerOrbit - firstOrbit) * o2::constants::lhc::LHCMaxBunches + triggerBC;
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()) {
401 const auto& metaHDR = *((TPCZSHDRV2*)zsdata);
402
403 const auto& triggerInfo = *(zerosupp_link_based::TriggerInfoV3*)((const char*)&metaHDR + sizeof(metaHDR));
404 if (triggerInfo.hasTrigger()) {
405 const auto triggerBC = triggerInfo.getFirstBC();
406 const auto triggerOrbit = orbit;
407 triggerBCOffset = int(triggerOrbit - firstOrbit) * o2::constants::lhc::LHCMaxBunches + triggerBC;
408 LOGP(debug, "TriggerInfoV3: orbit: {}, firstOrbit: {}, triggerOrbit: {}, triggerBC: {}, triggerBCOffset: {}", orbit, firstOrbit, triggerOrbit, triggerBC, triggerBCOffset);
409 }
410
411 return triggerBCOffset;
412 }
413
414 return -1;
415}
416
417int calib_processing_helper::getTriggerBCoffset(const char* data, size_t size, uint32_t firstOrbit)
418{
419 auto rdh = (const RDHAny*)data;
420 const auto feeId = RDHUtils::getFEEID(rdh);
421 const auto link = rdh_utils::getLink(feeId);
422
423 if (link != rdh_utils::DLBZSLinkID) {
424 return getTriggerInfoLBZS(data, size, firstOrbit);
425 }
426
427 // treatment for dense link-based
428 TPCZSHDR* const headerV1 = (TPCZSHDR*)(link == rdh_utils::DLBZSLinkID ? (data + size - sizeof(TPCZSHDRV2)) : data);
429 const auto header = (TPCZSHDRV2*)headerV1;
430 if (header->magicWord != 0xfd) {
431 LOGP(error, "Wrong magic word: {}, wrong data type?", header->magicWord);
432 return -1;
433 }
434 if (!(header->flags & TPCZSHDRV2::ZSFlags::TriggerWordPresent)) {
435 return -1;
436 }
437 const auto triggerWord = (TriggerWordDLBZS*)(data + size - sizeof(TPCZSHDRV2) - sizeof(TriggerWordDLBZS));
438 // Only process calibration (Laser) triggers
439 int iTrg;
440 for (iTrg = 0; iTrg < TriggerWordDLBZS::MaxTriggerEntries; ++iTrg) {
441 if (triggerWord->isValid(iTrg)) {
442 if (triggerWord->getTriggerType(iTrg) == TriggerWordDLBZS::Cal) {
443 break;
444 }
445 } else {
446 return -1;
447 }
448 }
449
450 const auto triggerBC = triggerWord->getTriggerBC(iTrg);
451 const auto orbit = RDHUtils::getHeartBeatOrbit(rdh);
452 const int orbitBC = ((orbit - firstOrbit) * o2::constants::lhc::LHCMaxBunches) + triggerBC;
453 LOGP(debug, "TriggerWordDLBZS {}: Type = {}, orbit = {}, firstOrbit = {}, BC = {}, oribitBC = {}", iTrg, triggerWord->getTriggerType(iTrg), orbit, firstOrbit, triggerWord->getTriggerBC(iTrg), orbitBC);
454 return orbitBC;
455}
456
457int calib_processing_helper::getTriggerBCoffset(o2::framework::InputRecord& inputs, std::vector<o2::framework::InputSpec> filter, bool slowScan)
458{
459 if (filter.size() == 0) {
460 filter = getFilter(inputs);
461 }
462
463 int triggerBC = -1;
464 uint32_t firstOrbit = 0;
465 for (auto const& ref : InputRecordWalker(inputs, filter)) {
466 const auto* dh = DataRefUtils::getHeader<o2::header::DataHeader*>(ref);
467 auto payloadSize = DataRefUtils::getPayloadSize(ref);
468 // skip empty HBF
469 if (payloadSize == 2 * sizeof(o2::header::RAWDataHeader)) {
470 continue;
471 }
472
473 firstOrbit = dh->firstTForbit;
474
475 try {
476 const gsl::span<const char> raw = inputs.get<gsl::span<char>>(ref);
477 std::unique_ptr<o2::framework::RawParser<8192>> rawparserPtr;
478
479 o2::framework::RawParser parser(raw.data(), raw.size());
480 for (auto it = parser.begin(), end = parser.end(); it != end; ++it) {
481 auto rdhPtr = reinterpret_cast<const o2::header::RDHAny*>(it.raw());
482 const auto rdhVersion = RDHUtils::getVersion(rdhPtr);
483 if (!rdhPtr || rdhVersion < 6) {
484 throw std::runtime_error(fmt::format("could not get RDH from packet, or version {} < 6", rdhVersion).data());
485 }
486
487 // only process LinkZSdata, only supported for data where this is already set in the UL
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);
492 if (!((detField == raw_data_types::LinkZS) ||
493 ((detField == raw_data_types::RAWDATA || detField == 0xdeadbeef) && (link == rdh_utils::UserLogicLinkID)) ||
494 ((linkID == rdh_utils::ILBZSLinkID || linkID == rdh_utils::DLBZSLinkID) && (detField == raw_data_types::Type::ZS)))) {
495 continue;
496 }
497
498 const auto data = (const char*)it.raw();
499 const auto size = it.sizeTotal();
500
501 const auto thisTrigger = getTriggerBCoffset(data, size, firstOrbit);
502 if (thisTrigger >= 0 && !slowScan) {
503 triggerBC = thisTrigger;
504 break;
505 }
506 // slow scan, check consistency of trigger info in all pages
507 if (triggerBC >= 0 && triggerBC != thisTrigger) {
508 LOGP(error, "inconsistent trigger information in raw pages of this TF");
509 }
510 }
511 } catch (...) {
512 }
513 if (triggerBC >= 0 && !slowScan) {
514 break;
515 }
516 }
517 if (triggerBC >= 0) {
518 LOGP(info, "Found triggerBCoffset: {}", triggerBC);
519 }
520 return triggerBC;
521}
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)
Definition of the TPC Digit.
uint64_t orbit
Definition RawEventData.h:6
int32_t i
A helper class to iteratate over all parts of all input routes.
Generic parser for consecutive raw pages.
std::ostringstream debug
definitions to deal with the link based zero suppression format
Definitions of TPC Zero Suppression Data Headers.
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...
decltype(auto) get(R binding, int part=0) const
const_iterator begin() const
Definition RawParser.h:618
const_iterator end() const
Definition RawParser.h:623
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
GLsizeiptr size
Definition glcorearb.h:659
GLuint GLuint end
Definition glcorearb.h:469
GLboolean * data
Definition glcorearb.h:298
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition glcorearb.h:1308
GLint ref
Definition glcorearb.h:291
constexpr o2::header::DataOrigin gDataOriginTPC
Definition DataHeader.h:576
constexpr int LHCMaxBunches
uint64_t now() noexcept
Definition Clock.h:69
Defining PrimaryVertex explicitly as messageable.
Definition TFIDInfo.h:20
const int MAXERRORS
uint64_t processRawData(o2::framework::InputRecord &inputs, std::unique_ptr< o2::tpc::rawreader::RawReaderCRU > &reader, bool useOldSubspec=false, const std::vector< int > &sectors={}, 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)
@ RAWDATA
GBT raw data.
@ 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)
uint16_t FEEIDType
Definition RDHUtils.h:26
Global TPC definitions and constants.
Definition SimTraits.h:167
static o2::header::DataHeader::PayloadSizeType getPayloadSize(const DataRef &ref)
static constexpr int getVersion()
get numeric version of the RDH
Definition RDHUtils.h:58
static constexpr uint16_t MaxTriggerEntries
Maximum number of trigger information.
@ Cal
Laser (Calibration trigger)
constexpr size_t min
const int sleepTime
Definition test_Fifo.cxx:28
std::vector< Digit > digits