Project
Loading...
Searching...
No Matches
Digits2Raw.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
14
16#include <fairlogger/Logger.h>
18
19using namespace o2::ctp;
20
27
29{
30 //
31 // Register links
32 //
33 std::string outd = mOutDir;
34 if (outd.back() != '/') {
35 outd += '/';
36 }
37 LOG(info) << "Raw outpud dir:" << mOutDir;
38 //
39 LOG(info) << "Raw Data padding:" << mPadding;
40 // Interaction Record
41 int ilink = 0;
42 uint64_t feeID = getFEEIDIR();
43 std::string outFileLink0 = mOutputPerLink ? fmt::format("{}{}_feeid{}.raw", outd, mCTPRawDataFileName, feeID) : fmt::format("{}{}.raw", outd, mCTPRawDataFileName);
44 mWriter.registerLink(feeID, mCruID, ilink, mEndPointID, outFileLink0);
45 // Trigger Class record
46 ilink = 1;
47 feeID = getFEEIDTC();
48 std::string outFileLink1 = mOutputPerLink ? fmt::format("{}{}_feeid{}.raw", outd, mCTPRawDataFileName, feeID) : fmt::format("{}{}.raw", outd, mCTPRawDataFileName);
49 mWriter.registerLink(feeID, mCruID, ilink, mEndPointID, outFileLink1);
50 // ilink = 2: HBMap, Counters - tbd
51 mWriter.setEmptyPageCallBack(this);
52}
53void Digits2Raw::processDigits(const std::string& fileDigitsName)
54{
55 std::unique_ptr<TFile> digiFile(TFile::Open(fileDigitsName.c_str()));
56 if (!digiFile || digiFile->IsZombie()) {
57 LOG(fatal) << "Failed to open input digits file " << fileDigitsName;
58 return;
59 }
60 LOG(info) << "Processing digits to raw file:" << fileDigitsName;
61 TTree* digiTree = (TTree*)digiFile->Get("o2sim");
62 if (!digiTree) {
63 LOG(fatal) << "Failed to get digits tree";
64 return;
65 }
66 std::vector<o2::ctp::CTPDigit> CTPDigits, *fCTPDigitsPtr = &CTPDigits;
67 if (digiTree->GetBranch("CTPDigits")) {
68 digiTree->SetBranchAddress("CTPDigits", &fCTPDigitsPtr);
69 } else {
70 LOG(fatal) << "Branch CTPDigits is missing";
71 return;
72 }
73 o2::InteractionRecord intRec = {0, 0};
74 // Get first orbit
75 uint32_t orbit0 = 0;
76 bool firstorbit = 1;
77 // Add all CTPdigits for given orbit
78 LOG(info) << "Number of entries: " << digiTree->GetEntries();
79 for (int ient = 0; ient < digiTree->GetEntries(); ient++) {
80 digiTree->GetEntry(ient);
81 int nbc = CTPDigits.size();
82 LOG(debug) << "Entry " << ient << " : " << nbc << " BCs stored";
83 std::vector<gbtword80_t> hbfIR;
84 std::vector<gbtword80_t> hbfTC;
85 for (auto const& ctpdig : CTPDigits) {
86 LOG(debug) << ctpdig.intRecord.bc << " bc all orbit " << ctpdig.intRecord.orbit;
87 if ((orbit0 == ctpdig.intRecord.orbit) || firstorbit) {
88 if (firstorbit == true) {
89 firstorbit = false;
90 orbit0 = ctpdig.intRecord.orbit;
91 LOG(info) << "First orbit:" << orbit0;
92 }
93 LOG(debug) << ctpdig.intRecord.orbit << " orbit bc " << ctpdig.intRecord.bc;
94 gbtword80_t gbtdigIR;
95 gbtword80_t gbtdigTC;
96 digit2GBTdigit(gbtdigIR, gbtdigTC, ctpdig);
97 LOG(debug) << "ir:" << gbtdigIR << " " << (gbtdigIR.to_ullong() & 0xfff);
98 LOG(debug) << "tr:" << gbtdigTC;
99 hbfIR.push_back(gbtdigIR);
100 hbfTC.push_back(gbtdigTC);
101 } else {
102 std::vector<char> buffer;
103 LOG(info) << "Packing orbit:" << orbit0 << " hbfIR:" << hbfIR.size() << " hbfTC:" << hbfTC.size();
104 intRec.orbit = orbit0;
105 if (mZeroSuppressedIntRec == true) {
106 buffer = digits2HBTPayload(hbfIR, NIntRecPayload);
107 } else {
108 std::vector<gbtword80_t> hbfIRnonZS = addEmptyBC(hbfIR);
109 buffer = digits2HBTPayload(hbfIRnonZS, NIntRecPayload);
110 }
111 // add data for IR
112 LOG(debug) << "IR buffer size:" << buffer.size() << ":";
113 mWriter.addData(getFEEIDIR(), mCruID, GBTLinkIDIntRec, mEndPointID, intRec, buffer);
114 // add data for Trigger Class Record
115 buffer.clear();
116 buffer = digits2HBTPayload(hbfTC, NClassPayload);
117 LOG(debug) << "TC buffer size:" << buffer.size() << ":";
118 mWriter.addData(getFEEIDTC(), mCruID, GBTLinkIDClassRec, mEndPointID, intRec, buffer);
119 //
120 orbit0 = ctpdig.intRecord.orbit;
121 hbfIR.clear();
122 hbfTC.clear();
123 LOG(debug) << ctpdig.intRecord.orbit << " orbit bc " << ctpdig.intRecord.bc;
124 gbtword80_t gbtdigIR;
125 gbtword80_t gbtdigTC;
126 digit2GBTdigit(gbtdigIR, gbtdigTC, ctpdig);
127 LOG(debug) << "ir:" << gbtdigIR;
128 LOG(debug) << "tr:" << gbtdigTC;
129 hbfIR.push_back(gbtdigIR);
130 hbfTC.push_back(gbtdigTC);
131 }
132 intRec = ctpdig.intRecord;
133 }
134 // Last orbit in record
135 std::vector<char> buffer;
136 LOG(info) << "Packing orbit last:" << orbit0;
137 intRec.orbit = orbit0;
138 if (mZeroSuppressedIntRec == true) {
139 buffer = digits2HBTPayload(hbfIR, NIntRecPayload);
140 } else {
141 std::vector<gbtword80_t> hbfIRnonZS = addEmptyBC(hbfIR);
142 buffer = digits2HBTPayload(hbfIRnonZS, NIntRecPayload);
143 }
144 // add data for IR
145 LOG(debug) << "IR buffer size:" << buffer.size() << " orbit:" << intRec.orbit;
146 mWriter.addData(getFEEIDIR(), mCruID, GBTLinkIDIntRec, mEndPointID, intRec, buffer);
147 // add data for Trigger Class Record
148 buffer.clear();
149 buffer = digits2HBTPayload(hbfTC, NClassPayload);
150 LOG(debug) << "TC buffer size:" << buffer.size() << " orbit:" << intRec.orbit;
151 mWriter.addData(getFEEIDTC(), mCruID, GBTLinkIDClassRec, mEndPointID, intRec, buffer);
152 //
153 //orbit0 = ctpdig.intRecord.orbit;
154 firstorbit = true;
155 hbfIR.clear();
156 hbfTC.clear();
157 }
158}
159void Digits2Raw::emptyHBFMethod(const header::RDHAny* rdh, std::vector<char>& toAdd) const
160{
161 // TriClassRecord data zero suppressed
162 // CTP INteraction Data
163 if (((o2::raw::RDHUtils::getFEEID(rdh) & 0xf00) >> 8) == GBTLinkIDIntRec) {
164 if (mZeroSuppressedIntRec == false) {
165 toAdd.clear();
166 std::vector<gbtword80_t> digits;
167 for (uint32_t i = 0; i < o2::constants::lhc::LHCMaxBunches; i++) {
168 gbtword80_t dig = i;
169 digits.push_back(dig);
170 }
171 toAdd = digits2HBTPayload(digits, NIntRecPayload);
172 }
173 }
174}
175std::vector<char> Digits2Raw::digits2HBTPayload(const gsl::span<gbtword80_t> digits, uint32_t Npld) const
176{
177 std::vector<char> toAdd;
178 int countBytes = 0;
179 uint32_t size_gbt = 0;
180 gbtword80_t gbtword;
181 gbtword80_t gbtsend;
182 bool valid;
183 for (auto const& dig : digits) {
184 valid = makeGBTWord(dig, gbtword, size_gbt, Npld, gbtsend);
185 LOG(debug) << Npld << " digit:" << dig << " " << (dig.to_ulong() & 0xfff) << " ";
186 LOG(debug) << "gbt :" << gbtsend << " valid:" << valid;
187 if (valid == true) {
188 for (uint32_t i = 0; i < NGBT; i += 8) {
189 uint32_t w = 0;
190 for (uint32_t j = 0; j < 8; j++) {
191 w += (1 << j) * gbtsend[i + j];
192 }
193 countBytes++;
194 char c = w;
195 toAdd.push_back(c);
196 }
197 if (mPadding) {
198 // Pad zeros up to 128 bits
199 uint32_t NZeros = (o2::raw::RDHUtils::GBTWord128 * 8 - NGBT) / 8;
200 for (uint32_t i = 0; i < NZeros; i++) {
201 char c = 0;
202 toAdd.push_back(c);
203 }
204 }
205 }
206 }
207 // add what is left: maybe never left anything - tbc
208 LOG(debug) << size_gbt << " size valid " << valid;
209 LOG(debug) << "gbtword:" << gbtword;
210 LOG(debug) << "gbtsend:" << gbtsend;
211 if (size_gbt > 0) {
212 // LOG(info) << "Adding left over.";
213 gbtword80_t gbtsend = gbtword;
214 for (uint32_t i = 0; i < NGBT; i += 8) {
215 uint32_t w = 0;
216 for (uint32_t j = 0; j < 8; j++) {
217 w += (1 << j) * gbtsend[i + j];
218 }
219 countBytes++;
220 char c = w;
221 toAdd.push_back(c);
222 }
223 // Pad zeros up to 128 bits
224 if (mPadding) {
225 uint32_t NZeros = (o2::raw::RDHUtils::GBTWord128 * 8 - NGBT) / 8;
226 for (uint32_t i = 0; i < NZeros; i++) {
227 char c = 0;
228 toAdd.push_back(c);
229 }
230 }
231 }
232 return std::move(toAdd);
233}
234// Adding payload of size < NGBT to GBT words of size NGBT
235// gbtsend valid only when return 1
236bool Digits2Raw::makeGBTWord(const gbtword80_t& pld, gbtword80_t& gbtword, uint32_t& size_gbt, uint32_t Npld, gbtword80_t& gbtsend) const
237{
238 bool valid = false;
239 //printBitset(gbtword,"GBTword");
240 gbtword |= (pld << size_gbt);
241 if ((size_gbt + Npld) < NGBT) {
242 size_gbt += Npld;
243 } else {
244 // sendData
245 //printBitset(gbtword,"Sending");
246 gbtsend = gbtword;
247 gbtword = pld >> (NGBT - size_gbt);
248 size_gbt = size_gbt + Npld - NGBT;
249 valid = true;
250 }
251 return valid;
252}
253int Digits2Raw::digit2GBTdigit(gbtword80_t& gbtdigitIR, gbtword80_t& gbtdigitTR, const CTPDigit& digit)
254{
255 //
256 // CTP Interaction record (CTP inputs)
257 //
258 gbtdigitIR = 0;
259 gbtdigitIR = (digit.CTPInputMask).to_ullong() << 12;
260 gbtdigitIR |= digit.intRecord.bc;
261 //
262 // Trig Classes
263 //
264 gbtdigitTR = 0;
265 //gbtdigitTR = (digit.CTPClassMask).to_ullong() << 12;
266 gbtdigitTR |= digit.intRecord.bc;
267 for (int i = 0; i < CTP_NCLASSES; i++) {
268 gbtdigitTR[i + 12] = digit.CTPClassMask[i];
269 }
270 return 0;
271}
272std::vector<gbtword80_t> Digits2Raw::addEmptyBC(std::vector<gbtword80_t>& hbfIRZS)
273{
274 std::vector<gbtword80_t> hbfIRnonZS;
275 if (hbfIRZS.size() == 0) {
276 LOG(error) << "Int record with zero size not expected here.";
277 return hbfIRnonZS;
278 }
279 uint32_t bcnonzero = 0;
280 if (hbfIRZS[0] != 0) {
281 gbtword80_t bs = 0;
282 hbfIRnonZS.push_back(bs);
283 }
284 for (auto const& item : hbfIRZS) {
285 uint32_t bcnonzeroNext = (item.to_ulong()) & 0xfff;
286 for (int i = (bcnonzero + 1); i < bcnonzeroNext; i++) {
287 gbtword80_t bs = i;
288 hbfIRnonZS.push_back(bs);
289 }
290 bcnonzero = bcnonzeroNext;
291 hbfIRnonZS.push_back(item);
292 }
293 for (int i = (bcnonzero + 1); i < 3564; i++) {
294 gbtword80_t bs = i;
295 hbfIRnonZS.push_back(bs);
296 }
297 return hbfIRnonZS;
298}
299void Digits2Raw::printDigit(std::string text, const gbtword80_t& dig) const
300{
301 int bcid = 0;
302 uint64_t payload1 = 0;
303 uint64_t payload2 = 0;
304 std::cout << text;
305 for (int i = 0; i < 12; i++) {
306 bcid += dig[i] << i;
307 }
308 for (uint64_t i = 0; i < 64; i++) {
309 payload1 += uint64_t(dig[i]) << i;
310 }
311 for (uint64_t i = 64; i < NGBT; i++) {
312 payload2 += uint64_t(dig[i]) << (i - 64ull);
313 }
314 std::cout << "BCID:" << std::hex << bcid << " " << payload2 << payload1 << std::endl;
315}
317{
318 std::ifstream input(filename, std::ios::binary);
319 std::vector<unsigned char> buffer(std::istreambuf_iterator<char>(input), {});
320 for (auto const& cc : buffer) {
321 }
322}
Digits tw Raw translation.
int32_t i
uint32_t j
Definition RawData.h:0
uint32_t c
Definition RawData.h:2
std::ostringstream debug
void processDigits(const std::string &fileDigitsName)
void dumpRawData(std::string filename="ctp.raw")
std::vector< gbtword80_t > addEmptyBC(std::vector< gbtword80_t > &hbfIRZS)
int digit2GBTdigit(gbtword80_t &gbtdigitIR, gbtword80_t &gbtdigitTR, const CTPDigit &digit)
uint64_t getFEEIDIR() const
Definition Digits2Raw.h:46
std::vector< char > digits2HBTPayload(const gsl::span< gbtword80_t > digits, uint32_t Npld) const
void emptyHBFMethod(const header::RDHAny *rdh, std::vector< char > &toAdd) const
uint64_t getFEEIDTC() const
Definition Digits2Raw.h:47
bool makeGBTWord(const gbtword80_t &pld, gbtword80_t &gbtword, uint32_t &size_gbt, uint32_t Npld, gbtword80_t &gbtsend) const
void printDigit(std::string text, const gbtword80_t &dig) const
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)
LinkData & registerLink(uint16_t fee, uint16_t cru, uint8_t link, uint8_t endpoint, std::string_view outFileName)
void setEmptyPageCallBack(const T *t)
GLuint buffer
Definition glcorearb.h:655
GLubyte GLubyte GLubyte GLubyte w
Definition glcorearb.h:852
constexpr int LHCMaxBunches
std::bitset< NGBT > gbtword80_t
Definition Digits.h:36
std::string filename()
uint32_t orbit
LHC orbit.
uint16_t bc
bunch crossing ID of interaction
std::bitset< CTP_NCLASSES > CTPClassMask
Definition Digits.h:53
o2::InteractionRecord intRecord
Definition Digits.h:51
std::bitset< CTP_NINPUTS > CTPInputMask
Definition Digits.h:52
static constexpr int GBTWord128
Definition RDHUtils.h:52
std::vector< o2::mch::ChannelCode > cc
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::vector< Digit > digits