Project
Loading...
Searching...
No Matches
RawProcessingHelpers.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 <array>
13#include <chrono>
14#include <fmt/format.h>
15#include <fmt/chrono.h>
16
18#include "Framework/Logger.h"
19#include "TPCBase/Mapper.h"
23
25
26using namespace o2::tpc;
27
28//______________________________________________________________________________
29bool raw_processing_helpers::processZSdata(const char* data, size_t size, rdh_utils::FEEIDType feeId, uint32_t orbit, uint32_t referenceOrbit, uint32_t syncOffsetReference, ADCCallback fillADC)
30{
31 const auto& mapper = Mapper::instance();
32
33 const auto link = rdh_utils::getLink(feeId);
34 const auto cruID = rdh_utils::getCRU(feeId);
35 const auto endPoint = rdh_utils::getEndPoint(feeId);
36 const CRU cru(cruID);
37 const int fecLinkOffsetCRU = (mapper.getPartitionInfo(cru.partition()).getNumberOfFECs() + 1) / 2;
38 int fecInPartition = link + endPoint * fecLinkOffsetCRU;
39
40 // temporarily store the sync offset until it is available in the ZS header
41 // WARNING: This only works until the TB counter wrapped afterwards the alignment might change
42 const int globalLinkID = int(link) + int(endPoint * 12);
43 const int tpcGlobalLinkID = cruID * 24 + globalLinkID;
44 static std::array<uint32_t, 360 * 24> syncOffsetLinks;
45
46 const uint32_t maxBunches = (uint32_t)o2::constants::lhc::LHCMaxBunches;
47 const int globalBCOffset = int(orbit - referenceOrbit) * o2::constants::lhc::LHCMaxBunches;
48 static int triggerBCOffset = 0;
49
50 bool hasData{false};
51
54
55 int zsVersion = -1;
56 int timeOffset = 0;
57
58 while (zsdata < zsdataEnd) {
59 const auto& header = zsdata->cont.header;
60
61 // align to header word if needed
62 if (!header.hasCorrectMagicWord()) {
63 zsdata = (zerosupp_link_based::ContainerZS*)((const char*)zsdata + sizeof(zerosupp_link_based::Header));
64 if (!header.isFillWord()) {
65 LOGP(error, "Bad LinkZS magic word (0x{:08x}), for feeId 0x{:05x} (CRU: {:3}, link: {:2}, EP {}), orbit {} , skipping data block", header.magicWord, feeId, cruID, link, endPoint, orbit);
66 LOGP(error, "Full 128b word is: 0x{:016x}{:016x}", header.word1, header.word0);
67 }
68 continue;
69 }
70
71 // set trigger offset and skip trigger info
72 if (header.isTriggerInfo()) {
73 // for the moment only skip the trigger info
74 const auto triggerInfo = (zerosupp_link_based::TriggerContainer*)zsdata;
75 const auto triggerOrbit = triggerInfo->triggerInfo.getOrbit();
76 const auto triggerBC = triggerInfo->triggerInfo.bunchCrossing;
77 triggerBCOffset = (int(triggerOrbit) - int(referenceOrbit)) * maxBunches + triggerBC;
78 LOGP(debug, "orbit: {}, triggerOrbit: {}, triggerBC: {}, triggerBCOffset: {}", orbit, triggerOrbit, triggerBC, triggerBCOffset);
79 zsdata = zsdata->next();
80 continue;
81 } else if (header.isTriggerInfoV2()) {
82 // for the moment only skip the trigger info
83 const auto triggerInfo = (zerosupp_link_based::TriggerInfoV2*)zsdata;
84 const auto triggerOrbit = triggerInfo->orbit;
85 const auto triggerBC = triggerInfo->bunchCrossing;
86 triggerBCOffset = (int(triggerOrbit) - int(referenceOrbit)) * maxBunches + triggerBC;
87 LOGP(debug, "orbit: {}, triggerOrbit: {}, triggerBC: {}, triggerBCOffset: {}", orbit, triggerOrbit, triggerBC, triggerBCOffset);
88 zsdata = zsdata->next();
89 continue;
90 } else if (header.isMetaHeader()) {
91 const auto& metaHDR = *((TPCZSHDRV2*)zsdata);
92 zsVersion = metaHDR.version;
93 timeOffset = metaHDR.timeOffset;
94
95 const auto& triggerInfo = *(zerosupp_link_based::TriggerInfoV3*)((const char*)&metaHDR + sizeof(metaHDR));
96 if (triggerInfo.hasTrigger()) {
97 const auto triggerBC = triggerInfo.getFirstBC();
98 const auto triggerOrbit = orbit;
99 triggerBCOffset = (int(triggerOrbit) - int(referenceOrbit)) * maxBunches + triggerBC;
100 }
101
102 zsdata = (zerosupp_link_based::ContainerZS*)((const char*)&triggerInfo + sizeof(triggerInfo));
103 continue;
104 }
105
106 const auto channelBits = zsdata->getChannelBits();
107 const uint32_t expectedWords = std::ceil(channelBits.count() * 0.1f);
108 const uint32_t numberOfWords = zsdata->getDataWords();
109 assert(expectedWords == numberOfWords);
110
111 const auto bunchCrossingHeader = int(zsdata->getBunchCrossing());
112 const auto syncOffset = int(header.syncOffsetBC);
113
114 // in case of old data, alignment must be done in software
115 if (zsVersion < 0) {
116 timeOffset = syncOffsetReference - syncOffset;
117 }
118
119 const int bcOffset = timeOffset + globalBCOffset + bunchCrossingHeader - triggerBCOffset;
120 if (bcOffset < 0) {
121 using namespace std::literals::chrono_literals;
122 static std::chrono::time_point<std::chrono::steady_clock> lastReport = std::chrono::steady_clock::now();
123 const auto now = std::chrono::steady_clock::now();
124 static size_t reportedErrors = 0;
125 const size_t MAXERRORS = 10;
126 const auto sleepTime = 10min;
127
128 if ((now - lastReport) < sleepTime) {
129 if (reportedErrors < MAXERRORS) {
130 ++reportedErrors;
131 std::string sleepInfo;
132 if (reportedErrors == MAXERRORS) {
133 sleepInfo = fmt::format(", maximum error count ({}) reached, not reporting for the next {}", MAXERRORS, sleepTime);
134 }
135 LOGP(warning, "skipping time bin with negative BC offset timeOffset {} + globalBCoffset (({} - {}) * {} = {}) + bunchCrossingHeader ({}) - triggerBCOffset({}) = {}{}",
136 timeOffset, orbit, referenceOrbit, o2::constants::lhc::LHCMaxBunches, globalBCOffset, bunchCrossingHeader, triggerBCOffset, bcOffset, sleepInfo);
137 lastReport = now;
138 }
139 } else {
140 lastReport = now;
141 reportedErrors = 0;
142 }
143
144 // go to next time bin
145 zsdata = zsdata->next();
146 continue;
147 }
148
149 const int timebin = bcOffset / constants::LHCBCPERTIMEBIN;
150 if (zsVersion == ZSVersionLinkBasedWithMeta) {
151 fecInPartition = header.fecInPartition;
152 }
153
154 std::size_t processedChannels = 0;
155 for (std::size_t ichannel = 0; ichannel < channelBits.size(); ++ichannel) {
156 if (!channelBits[ichannel]) {
157 continue;
158 }
159
160 // adc value
161 const auto adcValue = zsdata->getADCValueFloat(processedChannels);
162
163 // mapping to row, pad sector
164 int sampaOnFEC{}, channelOnSAMPA{};
165 Mapper::getSampaAndChannelOnFEC(cruID, ichannel, sampaOnFEC, channelOnSAMPA);
166 const auto padSecPos = mapper.padSecPos(cru, fecInPartition, sampaOnFEC, channelOnSAMPA);
167 const auto& padPos = padSecPos.getPadPos();
168
169 // add digit using callback
170 fillADC(int(cruID), int(padPos.getRow()), int(padPos.getPad()), timebin, adcValue);
171
172 ++processedChannels;
173 hasData = true;
174 }
175
176 // go to next time bin
177 zsdata = zsdata->next();
178 }
179
180 return hasData;
181}
uint64_t orbit
Definition RawEventData.h:6
Header to collect LHC related constants.
std::enable_if_t< std::is_signed< T >::value, bool > hasData(const CalArray< T > &cal)
Definition Painter.cxx:515
std::ostringstream debug
definitions to deal with the link based zero suppression format
Definitions of TPC Zero Suppression Data Headers.
unsigned char partition() const
Definition CRU.h:63
static Mapper & instance(const std::string mappingDir="")
Definition Mapper.h:44
static constexpr void getSampaAndChannelOnFEC(const int cruID, const size_t rawFECChannel, int &sampaOnFEC, int &channelOnSAMPA)
Definition Mapper.h:275
GLsizeiptr size
Definition glcorearb.h:659
GLboolean * data
Definition glcorearb.h:298
constexpr int LHCMaxBunches
constexpr int LHCBCPERTIMEBIN
Definition Constants.h:38
bool processZSdata(const char *data, size_t size, rdh_utils::FEEIDType feeId, uint32_t orbit, uint32_t referenceOrbit, uint32_t syncOffsetReference, ADCCallback fillADC)
std::function< bool(int cru, int rowInSector, int padInRow, int timeBin, float adcValue)> ADCCallback
uint16_t FEEIDType
Definition RDHUtils.h:26
Global TPC definitions and constants.
Definition SimTraits.h:167
@ ZSVersionLinkBasedWithMeta
constexpr size_t min
const int sleepTime
Definition test_Fifo.cxx:28