Project
Loading...
Searching...
No Matches
Decoder.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
13#include <iostream>
14#include <chrono>
15#include <algorithm>
17#include "TString.h"
18#include <fairlogger/Logger.h>
20
21//#define VERBOSE
22
23namespace o2
24{
25namespace tof
26{
27namespace compressed
28{
30
32{
33 for (int i = 0; i < NCRU; i++) {
34 mIntegratedBytes[i] = 0.;
35 mBuffer[i] = nullptr;
36 mCruIn[i] = false;
37 }
39}
40
41bool Decoder::open(const std::string name)
42{
43 int nfileopened = NCRU;
44
45 int fullsize = 0;
46 for (int i = 0; i < NCRU; i++) {
47 std::string nametmp;
48 nametmp.append(Form("cru%02d", i));
49 nametmp.append(name);
50
51 if (mFile[i].is_open()) {
52 std::cout << "Warning: a file (" << i << ") was already open, closing" << std::endl;
53 mFile[i].close();
54 }
55 mFile[i].open(nametmp.c_str(), std::fstream::in | std::fstream::binary);
56 if (!mFile[i].is_open()) {
57 std::cout << "Cannot open " << nametmp << std::endl;
58 nfileopened--;
59 mSize[i] = 0;
60 mCruIn[i] = false;
61 } else {
62 mFile[i].seekg(0, mFile[i].end);
63 mSize[i] = mFile[i].tellg();
64 mFile[i].seekg(0);
65
66 fullsize += mSize[i];
67
68 mCruIn[i] = true;
69 }
70 }
71
72 if (!nfileopened) {
73 std::cerr << "No streams available" << std::endl;
74 return true;
75 }
76
77 // mBufferLocal.resize(fullsize);
78
79 printf("Full input buffer size = %d byte\n", fullsize);
80
81 char* pos = new char[fullsize]; //mBufferLocal.data();
82 for (int i = 0; i < NCRU; i++) {
83 if (!mCruIn[i]) {
84 continue;
85 }
86
87 mBuffer[i] = pos;
88
89 // read content of infile
90 mFile[i].read(mBuffer[i], mSize[i]);
91 mUnion[i] = reinterpret_cast<Union_t*>(mBuffer[i]);
92 mUnionEnd[i] = reinterpret_cast<Union_t*>(mBuffer[i] + mSize[i] - 1);
93
94 pos += mSize[i];
95 }
96
97 printf("Number of TOF compressed streamers = %d/%d\n", nfileopened, NCRU);
98
99 close();
100
101 return false;
102}
103
105{
106 for (int i = 0; i < NCRU; i++) {
107 if (mFile[i].is_open()) {
108 mFile[i].close();
109 }
110 }
111 return false;
112}
113
115{
116 reset();
117 clearCounts();
118
119 mPatterns.clear();
120 mCratePatterns.clear();
121 mCrateHeaderData.clear();
122 mErrors.clear();
124}
125
126void Decoder::InsertDigit(int icrate, int itrm, int itdc, int ichain, int channel, uint32_t orbit, uint16_t bunchid, int time_ext, int tdc, int tot)
127{
128 DigitInfo digitInfo;
129
130 if (itrm == 3 && ((icrate % 2 == 0) || (itdc / 3 > 0))) { // Signal not coming from a TOF pad but -probably- from a TOF OR signal
131 // add operation on LTM (Trigger) if needed (not used) if (crate % 2 == 1)
132 return;
133 }
134
135 fromRawHit2Digit(icrate, itrm, itdc, ichain, channel, orbit, bunchid, time_ext + tdc, tot, digitInfo);
136
137 if (digitInfo.channel < 0) { // check needed for the moment. To be removed once debugged
138 return;
139 }
140
141 mChannelCounts[digitInfo.channel]++;
142
143 mHitDecoded++;
144
145 uint64_t isnext = digitInfo.bcAbs * Geo::BC_IN_WINDOW_INV;
146
147 if (isnext >= uint64_t(MAXWINDOWS)) { // accumulate all digits which are not in the first windows
148 insertDigitInFuture(digitInfo.channel, digitInfo.tdc, digitInfo.tot, digitInfo.bcAbs, 0, digitInfo.orbit, digitInfo.bc);
149 } else {
150 std::vector<Strip>* cstrip = mStripsCurrent; // first window
151 if (isnext) {
152 cstrip = mStripsNext[isnext - 1]; // next window
153 }
154 UInt_t istrip = digitInfo.channel / Geo::NPADS;
155
156 // add digit
157 fillDigitsInStrip(cstrip, digitInfo.channel, digitInfo.tdc, digitInfo.tot, digitInfo.bcAbs, istrip);
158 }
159}
160
161void Decoder::readTRM(int icru, int icrate, uint32_t orbit, uint16_t bunchid)
162{
163
164 if (orbit < mFirstIR.orbit || (orbit == mFirstIR.orbit && bunchid < mFirstIR.bc)) {
166 mFirstIR.bc = bunchid;
167 }
168
169 if (mVerbose) {
170 printTRMInfo(icru);
171 }
172 int nhits = mUnion[icru]->frameHeader.numberOfHits;
173 int time_ext = mUnion[icru]->frameHeader.frameID << 13;
174 int itrm = mUnion[icru]->frameHeader.trmID;
175 int deltaBC = mUnion[icru]->frameHeader.deltaBC;
176
177 if (deltaBC != 0) {
178 printf("DeltaBC = %d\n", deltaBC);
179 }
180 mUnion[icru]++;
181 mIntegratedBytes[icru] += 4;
182
183 DigitInfo digitInfo;
184
185 for (int i = 0; i < nhits; i++) {
186 if (icrate % 2 == 1 && itrm == 3 && mUnion[icru]->packedHit.tdcID / 3 > 0) { // Signal not coming from a TOF pad but -probably- from a TOF OR signal
187 // add operation on LTM (Trigger) if needed (not used)
188
189 mUnion[icru]++;
190 mIntegratedBytes[icru] += 4;
191 continue;
192 }
193
194 fromRawHit2Digit(icrate, itrm, mUnion[icru]->packedHit.tdcID, mUnion[icru]->packedHit.chain, mUnion[icru]->packedHit.channel, orbit, bunchid,
195 time_ext + mUnion[icru]->packedHit.time, mUnion[icru]->packedHit.tot, digitInfo);
196
197 if (digitInfo.channel < 0) { // check needed for the moment. To be removed once debugged
198 mUnion[icru]++;
199 mIntegratedBytes[icru] += 4;
200 continue;
201 }
202
203 mChannelCounts[digitInfo.channel]++;
204
205 mHitDecoded++;
206
207 if (mVerbose) {
208 printHitInfo(icru);
209 }
210
211 uint64_t isnext = digitInfo.bcAbs * Geo::BC_IN_WINDOW_INV;
212
213 if (isnext >= MAXWINDOWS) { // accumulate all digits which are not in the first windows
214
215 insertDigitInFuture(digitInfo.channel, digitInfo.tdc, digitInfo.tot, digitInfo.bcAbs, 0, digitInfo.orbit, digitInfo.bc);
216 } else {
217 std::vector<Strip>* cstrip = mStripsCurrent; // first window
218 if (isnext) {
219 cstrip = mStripsNext[isnext - 1]; // next window
220 }
221
222 UInt_t istrip = digitInfo.channel / Geo::NPADS;
223
224 // add digit
225 fillDigitsInStrip(cstrip, digitInfo.channel, digitInfo.tdc, digitInfo.tot, digitInfo.bcAbs, istrip);
226 }
227
228 mUnion[icru]++;
229 mIntegratedBytes[icru] += 4;
230 }
231}
232
233void Decoder::fromRawHit2Digit(int icrate, int itrm, int itdc, int ichain, int channel, uint32_t orbit, uint16_t bunchid, int tdc, int tot, Decoder::DigitInfo& dinfo)
234{
235 // convert raw info in digit info (channel, tdc, tot, bc)
236 // tdc = packetHit.time + (frameHeader.frameID << 13)
237 int echannel = Geo::getECHFromIndexes(icrate, itrm, ichain, itdc, channel);
238 dinfo.channel = Geo::getCHFromECH(echannel);
239
240 if (dinfo.channel < 0) { // it should not happen!
241 LOG(debug) << "No valid channel for icrate = " << icrate << ", itrm = " << itrm << ", ichain = " << ichain << ", itdc = " << itdc << ", channel = " << channel;
242 }
243
244 dinfo.tot = tot;
245 dinfo.bcAbs = uint64_t(orbit) * o2::tof::Geo::BC_IN_ORBIT + bunchid + tdc / 1024;
246 dinfo.tdc = tdc % 1024;
247 dinfo.orbit = orbit;
248 dinfo.bc = bunchid;
249}
250
251char* Decoder::nextPage(void* current, int shift)
252{
253 char* point = reinterpret_cast<char*>(current);
254 point += shift;
255
256 return point;
257}
258
259bool Decoder::decode() // return a vector of digits in a TOF readout window
260{
262 mFirstIR.orbit = 0;
263 mFirstIR.bc = 0;
264
265#ifdef VERBOSE
266 if (mVerbose)
267 std::cout << "-------- START DECODE EVENTS IN THE HB ----------------------------------------" << std::endl;
268#endif
269 auto start = std::chrono::high_resolution_clock::now();
270
271 // start from the beginning of the timeframe
272
273 // loop over CRUs
274 for (int icru = 0; icru < NCRU; icru++) {
275 if (!mCruIn[icru]) {
276 continue; // no data stream available for this cru
277 }
278
279 printf("decoding cru %d\n", icru);
280
281 while (mUnion[icru] < mUnionEnd[icru]) { // read all the buffer
282 // read open RDH
283 mRDH = reinterpret_cast<o2::header::RAWDataHeader*>(mUnion[icru]);
284 if (mVerbose) {
285 printRDH();
286 }
287
288 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
289 // note that RDH continue is not yet considered as option (to be added)
290 // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
291
292 // move after RDH
293 char* shift = reinterpret_cast<char*>(mRDH);
294 auto rdhsz = RDHUtils::getHeaderSize(*mRDH);
295 mUnion[icru] = reinterpret_cast<Union_t*>(shift + rdhsz);
296 mIntegratedBytes[icru] += rdhsz;
297
298 if (mUnion[icru] >= mUnionEnd[icru]) {
299 continue; // end of data stream reac
300 }
301 for (int window = 0; window < Geo::NWINDOW_IN_ORBIT; window++) {
302 // read Crate Header
303 int bunchid = mUnion[icru]->crateHeader.bunchID;
304 int icrate = mUnion[icru]->crateHeader.drmID;
305 if (mVerbose) {
306 printCrateInfo(icru);
307 }
308 mUnion[icru]++;
309 mIntegratedBytes[icru] += 4;
310
311 //read Orbit
312 int orbit = mUnion[icru]->crateOrbit.orbitID;
313 if (mVerbose) {
314 printf("%d) orbit ID = %d -- bunch ID = %d\n", icrate, orbit, bunchid);
315 }
316 mUnion[icru]++;
317 mIntegratedBytes[icru] += 4;
318
319 while (!mUnion[icru]->frameHeader.mustBeZero) {
320 readTRM(icru, icrate, orbit, bunchid);
321 }
322
323 // read Crate Trailer
324 if (mVerbose) {
326 }
327 auto ndw = mUnion[icru]->crateTrailer.numberOfDiagnostics;
328 mUnion[icru]++;
329 mIntegratedBytes[icru] += 4;
330
331 // loop over number of diagnostic words
332 for (int idw = 0; idw < ndw; ++idw) {
333 mUnion[icru]++;
334 mIntegratedBytes[icru] += 4;
335 }
336 }
337
338 // read close RDH
339 mRDH = reinterpret_cast<o2::header::RAWDataHeader*>(nextPage(mRDH, RDHUtils::getMemorySize(*mRDH)));
340 if (mVerbose) {
341 printRDH();
342 }
343 mIntegratedBytes[icru] += RDHUtils::getHeaderSize(*mRDH);
344
345 // go to next page
346 mUnion[icru] = reinterpret_cast<Union_t*>(nextPage(mRDH, RDHUtils::getMemorySize(*mRDH)));
347 }
348 }
349
350 // since digits are not yet divided in tof readout window we need to do it
351 // flushOutputContainer does the job
352 fillWindows();
354
355 return false;
356}
357
359{
360 std::vector<Digit> digTemp;
361 flushOutputContainer(digTemp);
362}
363
364void Decoder::printCrateInfo(int icru) const
365{
366 printf("___CRATE HEADER____\n");
367 printf("DRM ID = %d\n", mUnion[icru]->crateHeader.drmID);
368 printf("Bunch ID = %d\n", mUnion[icru]->crateHeader.bunchID);
369 printf("Slot part. mask = %d\n", mUnion[icru]->crateHeader.slotPartMask);
370 printf("Must be ONE = %d\n", mUnion[icru]->crateHeader.mustBeOne);
371 printf("___________________\n");
372}
373
375{
376 printf("___CRATE TRAILER___\n");
377 printf("Event counter = %d\n", mUnion[icru]->crateTrailer.eventCounter);
378 printf("Number of diagnostics = %d\n", mUnion[icru]->crateTrailer.numberOfDiagnostics);
379 printf("Must be ONE = %d\n", mUnion[icru]->crateTrailer.mustBeOne);
380 printf("___________________\n");
381}
382
383void Decoder::printTRMInfo(int icru) const
384{
385 printf("______TRM_INFO_____\n");
386 printf("TRM ID = %d\n", mUnion[icru]->frameHeader.trmID);
387 printf("Frame ID = %d\n", mUnion[icru]->frameHeader.frameID);
388 printf("N. hits = %d\n", mUnion[icru]->frameHeader.numberOfHits);
389 printf("DeltaBC = %d\n", mUnion[icru]->frameHeader.deltaBC);
390 printf("Must be Zero = %d\n", mUnion[icru]->frameHeader.mustBeZero);
391 printf("___________________\n");
392}
393
394void Decoder::printHitInfo(int icru) const
395{
396 printf("______HIT_INFO_____\n");
397 printf("TDC ID = %d\n", mUnion[icru]->packedHit.tdcID);
398 printf("CHAIN ID = %d\n", mUnion[icru]->packedHit.chain);
399 printf("CHANNEL ID = %d\n", mUnion[icru]->packedHit.channel);
400 printf("TIME = %d\n", mUnion[icru]->packedHit.time);
401 printf("TOT = %d\n", mUnion[icru]->packedHit.tot);
402 printf("___________________\n");
403}
404
406{
407 printf("______RDH_INFO_____\n");
409 printf("VERSION = %d\n", v);
410 if (v == 4) {
411 printf("BLOCK LENGTH = %d\n", int(RDHUtils::getBlockLength(mRDH)));
412 }
413 printf("HEADER SIZE = %d\n", int(RDHUtils::getHeaderSize(*mRDH)));
414 printf("MEMORY SIZE = %d\n", int(RDHUtils::getMemorySize(*mRDH)));
415 printf("PACKET COUNTER= %d\n", int(RDHUtils::getPacketCounter(*mRDH)));
416 printf("CRU ID = %d\n", int(RDHUtils::getCRUID(*mRDH)));
417 printf("LINK ID = %d\n", int(RDHUtils::getLinkID(*mRDH)));
418 printf("___________________\n");
419}
420} // namespace compressed
421} // namespace tof
422} // namespace o2
Definition of the TOF encoder.
uint64_t orbit
Definition RawEventData.h:6
int32_t i
Header to collect LHC related constants.
uint16_t pos
Definition RawData.h:3
std::ostringstream debug
static constexpr Int_t NPADS
Definition Geo.h:110
static constexpr double BC_IN_WINDOW_INV
Definition Geo.h:166
static Int_t getCHFromECH(int echan)
Definition Geo.h:352
static constexpr int BC_IN_ORBIT
Definition Geo.h:105
static Int_t getECHFromIndexes(int crate, int trm, int chain, int tdc, int chan)
Definition Geo.h:350
static constexpr int NWINDOW_IN_ORBIT
Definition Geo.h:163
std::vector< uint64_t > mErrors
void fillDigitsInStrip(std::vector< Strip > *strips, int channel, int tdc, int tot, uint64_t nbc, UInt_t istrip, uint32_t triggerorbit=0, uint16_t triggerbunch=0)
std::vector< CrateHeaderData > mCrateHeaderData
static const int MAXWINDOWS
std::vector< PatternData > mCratePatterns
std::vector< Strip > * mStripsCurrent
int mChannelCounts[o2::tof::Geo::NCHANNELS]
std::vector< Strip > * mStripsNext[MAXWINDOWS - 1]
void flushOutputContainer(std::vector< Digit > &digits)
std::vector< uint8_t > mPatterns
Diagnostic mDiagnosticFrequency
void insertDigitInFuture(Int_t channel, Int_t tdc, Int_t tot, uint64_t bc, Int_t label=0, uint32_t triggerorbit=0, uint16_t triggerbunch=0)
InteractionRecord mFirstIR
void printHitInfo(int icru) const
Definition Decoder.cxx:394
void readTRM(int icru, int icrate, uint32_t orbit, uint16_t bunchid)
Definition Decoder.cxx:161
void printTRMInfo(int icru) const
Definition Decoder.cxx:383
static const int NCRU
Definition Decoder.h:79
Union_t * mUnionEnd[NCRU]
Definition Decoder.h:93
char * nextPage(void *current, int shift=8192)
Definition Decoder.cxx:251
void printCrateInfo(int icru) const
Definition Decoder.cxx:364
bool open(std::string name)
Definition Decoder.cxx:41
std::ifstream mFile[NCRU]
Definition Decoder.h:85
static void fromRawHit2Digit(int icrate, int itrm, int itdc, int ichain, int channel, uint32_t orbit, uint16_t bunchid, int tdc, int tot, DigitInfo &dinfo)
Definition Decoder.cxx:233
void printCrateTrailerInfo(int icru) const
Definition Decoder.cxx:374
o2::header::RAWDataHeader * mRDH
Definition Decoder.h:97
void InsertDigit(int icrate, int itrm, int itdc, int ichain, int channel, uint32_t orbit, uint16_t bunchid, int time_ext, int tdc, int tot)
Definition Decoder.cxx:126
Union_t * mUnion[NCRU]
Definition Decoder.h:92
GLuint GLuint end
Definition glcorearb.h:469
const GLdouble * v
Definition glcorearb.h:832
GLuint const GLchar * name
Definition glcorearb.h:781
GLuint start
Definition glcorearb.h:469
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
uint32_t orbit
LHC orbit.
uint16_t bc
bunch crossing ID of interaction
static constexpr int getVersion()
get numeric version of the RDH
Definition RDHUtils.h:58
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"