Fix
[u/mrichter/AliRoot.git] / RAW / AliAltroRawStreamV3.cxx
CommitLineData
f8e5b5a0 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
15
16///////////////////////////////////////////////////////////////////////////////
17///
18/// This is a base class for reading raw data digits in Altro format.
19/// The class is able to read the RCU v3 and above formats.
20/// The main difference between the format V3 and older ones is in
21/// the coding of the 10-bit Altro payload words. In V3 3 10-bit words
22/// are coded in one 32-bit word. The bits 30 and 31 are used to identify
23/// the payload, altro header and RCU trailer contents.
24///
25///
26/// cvetan.cheshkov@cern.ch 1/04/2009
27///////////////////////////////////////////////////////////////////////////////
28
29#include "AliAltroRawStreamV3.h"
30#include "AliRawReader.h"
31#include "AliLog.h"
0148e633 32#include "AliAltroRawStream.h"
eae29211 33#include "AliRawEventHeaderBase.h"
f8e5b5a0 34
35ClassImp(AliAltroRawStreamV3)
36
37
38//_____________________________________________________________________________
39AliAltroRawStreamV3::AliAltroRawStreamV3(AliRawReader* rawReader) :
40 fIsShortDataHeader(kFALSE),
41 fDDLNumber(-1),
42 fRCUId(-1),
43 fHWAddress(-1),
44 fRawReader(rawReader),
45 fData(NULL),
8e9fa05e 46 fChannelStartPos(-1),
f8e5b5a0 47 fPosition(-1),
48 fCount(-1),
49 fStartTimeBin(-1),
50 fBunchLength(-1),
51 fBadChannel(kFALSE),
52 fPayloadSize(-1),
e76a0935 53 fChannelPayloadSize(-1),
6d4dd848 54 fBunchDataPointer(NULL),
55 fBunchDataIndex(-1),
f8e5b5a0 56 fRCUTrailerData(NULL),
57 fRCUTrailerSize(0),
58 fFECERRA(0),
59 fFECERRB(0),
60 fERRREG2(0),
61 fERRREG3(0),
f8e5b5a0 62 fActiveFECsA(0),
63 fActiveFECsB(0),
64 fAltroCFG1(0),
0148e633 65 fAltroCFG2(0),
3ce326c0 66 fOldStream(NULL),
38f5da76 67 fCheckAltroPayload(kTRUE),
68 fFormatVersion(0)
f8e5b5a0 69{
70 // Constructor
71 // Create an object to read Altro raw digits in
72 // RCU version 3 and beyond format
73 for(Int_t i = 0; i < kMaxNTimeBins; i++) fBunchData[i] = 0;
74}
75
76//_____________________________________________________________________________
77AliAltroRawStreamV3::~AliAltroRawStreamV3()
78{
79// destructor
0148e633 80// delete old stream object if one exists
81 if (fOldStream) delete fOldStream;
f8e5b5a0 82}
83
84//_____________________________________________________________________________
85AliAltroRawStreamV3::AliAltroRawStreamV3(const AliAltroRawStreamV3& stream) :
86 TObject(stream),
87 fIsShortDataHeader(stream.fIsShortDataHeader),
88 fDDLNumber(stream.fDDLNumber),
89 fRCUId(stream.fRCUId),
90 fHWAddress(stream.fHWAddress),
91 fRawReader(stream.fRawReader),
92 fData(stream.fData),
8e9fa05e 93 fChannelStartPos(stream.fChannelStartPos),
f8e5b5a0 94 fPosition(stream.fPosition),
95 fCount(stream.fCount),
96 fStartTimeBin(stream.fStartTimeBin),
97 fBunchLength(stream.fBunchLength),
98 fBadChannel(stream.fBadChannel),
99 fPayloadSize(stream.fPayloadSize),
e76a0935 100 fChannelPayloadSize(stream.fChannelPayloadSize),
6d4dd848 101 fBunchDataPointer(stream.fBunchDataPointer),
102 fBunchDataIndex(stream.fBunchDataIndex),
f8e5b5a0 103 fRCUTrailerData(stream.fRCUTrailerData),
104 fRCUTrailerSize(stream.fRCUTrailerSize),
105 fFECERRA(stream.fFECERRA),
106 fFECERRB(stream.fFECERRB),
107 fERRREG2(stream.fERRREG2),
108 fERRREG3(stream.fERRREG3),
f8e5b5a0 109 fActiveFECsA(stream.fActiveFECsA),
110 fActiveFECsB(stream.fActiveFECsB),
111 fAltroCFG1(stream.fAltroCFG1),
0148e633 112 fAltroCFG2(stream.fAltroCFG2),
3ce326c0 113 fOldStream(NULL),
38f5da76 114 fCheckAltroPayload(stream.fCheckAltroPayload),
115 fFormatVersion(0)
f8e5b5a0 116{
117 // Copy constructor
118 // Copy the bunch data array
119 for(Int_t i = 0; i < kMaxNTimeBins; i++) fBunchData[i] = stream.fBunchData[i];
0148e633 120
121 if (stream.fOldStream)
122 fOldStream = new AliAltroRawStream(*stream.fOldStream);
f8e5b5a0 123}
124
125//_____________________________________________________________________________
126AliAltroRawStreamV3& AliAltroRawStreamV3::operator = (const AliAltroRawStreamV3& stream)
127{
128 // assignment operator
129 // ...
130 if(&stream == this) return *this;
131
132 fIsShortDataHeader = stream.fIsShortDataHeader;
133 fDDLNumber = stream.fDDLNumber;
134 fRCUId = stream.fRCUId;
135 fHWAddress = stream.fHWAddress;
136 fRawReader = stream.fRawReader;
137 fData = stream.fData;
8e9fa05e 138 fChannelStartPos = stream.fChannelStartPos;
f8e5b5a0 139 fPosition = stream.fPosition;
140 fCount = stream.fCount;
141 fStartTimeBin = stream.fStartTimeBin;
142 fBunchLength = stream.fBunchLength;
143 fBadChannel = stream.fBadChannel;
144 fPayloadSize = stream.fPayloadSize;
e76a0935 145 fChannelPayloadSize= stream.fChannelPayloadSize;
6d4dd848 146 fBunchDataPointer = stream.fBunchDataPointer;
147 fBunchDataIndex = stream.fBunchDataIndex;
f8e5b5a0 148 fRCUTrailerData = stream.fRCUTrailerData;
149 fRCUTrailerSize = stream.fRCUTrailerSize;
150 fFECERRA = stream.fFECERRA;
151 fFECERRB = stream.fFECERRB;
152 fERRREG2 = stream.fERRREG2;
153 fERRREG3 = stream.fERRREG3;
f8e5b5a0 154 fActiveFECsA = stream.fActiveFECsA;
155 fActiveFECsB = stream.fActiveFECsB;
156 fAltroCFG1 = stream.fAltroCFG1;
157 fAltroCFG2 = stream.fAltroCFG2;
38f5da76 158 fFormatVersion = stream.fFormatVersion;
f8e5b5a0 159
160 for(Int_t i = 0; i < kMaxNTimeBins; i++) fBunchData[i] = stream.fBunchData[i];
161
0148e633 162 if (stream.fOldStream) {
163 if (fOldStream) delete fOldStream;
164 fOldStream = new AliAltroRawStream(stream.fRawReader);
165 *fOldStream = *stream.fOldStream;
166 }
167
3ce326c0 168 fCheckAltroPayload = stream.fCheckAltroPayload;
169
f8e5b5a0 170 return *this;
171}
172
173//_____________________________________________________________________________
174void AliAltroRawStreamV3::Reset()
175{
176// Complete reset of raw stream params
177// Reset of the raw-reader as well
178
179 fDDLNumber = fRCUId = fHWAddress = -1;
8e9fa05e 180 fChannelStartPos = -1;
f8e5b5a0 181 fPosition = fCount = -1;
182 fBunchLength = fStartTimeBin = -1;
183 fBadChannel = kFALSE;
184 fPayloadSize = -1;
e76a0935 185 fChannelPayloadSize = -1;
6d4dd848 186 fBunchDataPointer = NULL;
187 fBunchDataIndex = -1;
f8e5b5a0 188
189 fRCUTrailerData = NULL;
190 fRCUTrailerSize = 0;
191
9283f3a5 192 fFECERRA = fFECERRB = fERRREG2 = fERRREG3 = fActiveFECsA = fActiveFECsB = fAltroCFG1 = fAltroCFG2 = 0;
f8e5b5a0 193
194 if (fRawReader) fRawReader->Reset();
195
0148e633 196 if (fOldStream) fOldStream->Reset();
f8e5b5a0 197}
198
199//_____________________________________________________________________________
200Bool_t AliAltroRawStreamV3::NextDDL()
201{
202// Read the next DDL payload (CDH + RCU trailer)
203// Updates the information which is coming from these
204// two sources
38f5da76 205 fFormatVersion = 0;
f8e5b5a0 206 fPosition = 0;
207 // Get next DDL payload
208 // return wtih false in case no more data payloads
209 // are found
210 do {
211 if (!fRawReader->ReadNextData(fData)) return kFALSE;
212 } while (fRawReader->GetDataSize() == 0);
213
214 fDDLNumber = fRawReader->GetDDLID();
e76a0935 215 fChannelPayloadSize = -1;
8e9fa05e 216 fChannelStartPos = -1;
f8e5b5a0 217
3bc742e5 218 fFormatVersion = (fRawReader->GetBlockAttributes() & 0xF);
f8e5b5a0 219
38f5da76 220 if (fFormatVersion < 2) {
0148e633 221 // old altro format data
222 if (!fOldStream) {
223 fOldStream = new AliAltroRawStream(fRawReader);
224 AliInfo(Form("RCU firmware verion %d detected. Using AliAltroRawStream to decode the data.",
38f5da76 225 fFormatVersion));
0148e633 226 }
227 Bool_t status = fOldStream->NextDDL(fData);
228 if (status) {
229 fRCUId = fOldStream->GetRCUId();
230 fRCUTrailerSize = fOldStream->GetRCUTrailerSize();
231 fOldStream->GetRCUTrailerData(fRCUTrailerData);
232 fFECERRA = fOldStream->GetFECERRA();
233 fFECERRB = fOldStream->GetFECERRB();
234 fERRREG2 = fOldStream->GetERRREG2();
235 fERRREG3 = ((UInt_t)fOldStream->GetNChAddrMismatch()) |
236 (((UInt_t)fOldStream->GetNChLengthMismatch()) << 12);
237 fActiveFECsA = fOldStream->GetActiveFECsA();
238 fActiveFECsB = fOldStream->GetActiveFECsB();
239 fAltroCFG1 = fOldStream->GetAltroCFG1();
240 fAltroCFG2 = fOldStream->GetAltroCFG2();
eae29211 241 if (fRawReader->GetType() == AliRawEventHeaderBase::kStartOfData)
242 fPayloadSize = fOldStream->GetRCUPayloadSizeInSOD();
0148e633 243 }
244 return status;
245 }
f8e5b5a0 246
38f5da76 247 return ReadRCUTrailer(fFormatVersion);
f8e5b5a0 248}
249
250//_____________________________________________________________________________
251Bool_t AliAltroRawStreamV3::NextChannel()
252{
253 // Read the next Altro channel from the
254 // raw-data stream
255 // Updates the channel hardware address member and
256 // channel data size. Sets the error flag in case
257 // RCU signals readout error in this channel
0148e633 258 if (fOldStream) {
259 Bool_t status = fOldStream->NextChannel();
e76a0935 260 if (status) {
261 fHWAddress = fOldStream->GetHWAddress();
262 fChannelPayloadSize = fOldStream->GetChannelPayloadSize();
263 }
0148e633 264 return status;
265 }
266
8e9fa05e 267 Int_t channelStartPos=fPosition;
268 fChannelStartPos = -1;
f8e5b5a0 269 fCount = -1;
270 fBadChannel = kFALSE;
6d4dd848 271 fBunchDataIndex = 0;
3ce326c0 272 fBunchLength = -1;
f8e5b5a0 273
274 UInt_t word = 0;
275 do {
276 word = Get32bitWord(fPosition++);
6d4dd848 277 if (fPosition > fPayloadSize) return kFALSE;
f8e5b5a0 278 }
6d4dd848 279 while ((word >> 30) != 1);
f8e5b5a0 280
281 // check for readout errors
6d4dd848 282 fBadChannel = (word >> 29) & 0x1;
f8e5b5a0 283
284 // extract channel payload and hw address
6d4dd848 285 fCount = (word >> 16) & 0x3FF;
e76a0935 286 fChannelPayloadSize = fCount;
f8e5b5a0 287 fHWAddress = word & 0xFFF;
288
6d4dd848 289 // Now unpack the altro data
290 // Revert the order of the samples
291 // inside the bunch so that the
292 // first time is first in the samples
293 // array
294 Int_t isample = 0;
295 Int_t nwords = (fCount+2)/3;
296 for (Int_t iword = 0; iword < nwords; iword++) {
297 word = Get32bitWord(fPosition++);
298 if ((word >> 30) != 0) {
299 // Unexpected end of altro channel payload
499187ca 300 AliWarning(Form("Unexpected end of payload in altro channel payload! DDL=%03d, Address=0x%x, word=0x%x",
301 fDDLNumber,fHWAddress,word));
6d4dd848 302 fRawReader->AddMinorErrorLog(kAltroPayloadErr,Form("hw=0x%x",fHWAddress));
499187ca 303 if (AliDebugLevel() > 0) HexDumpChannel();
6d4dd848 304 fCount = -1;
305 fPosition--;
306 return kFALSE;
307 }
308 fBunchData[isample++] = (word >> 20) & 0x3FF;
309 fBunchData[isample++] = (word >> 10) & 0x3FF;
310 fBunchData[isample++] = word & 0x3FF;
311 }
312
8e9fa05e 313 fChannelStartPos=channelStartPos;
f8e5b5a0 314 return kTRUE;
315}
316
317//_____________________________________________________________________________
318Bool_t AliAltroRawStreamV3::NextBunch()
319{
320 // Read next altro bunch from the
321 // raw-data stream.
322 // Updates the start/end time-bins
323 // and the array with altro samples
0148e633 324 if (fOldStream) {
325 Bool_t status = fOldStream->NextBunch(fBunchData,fBunchLength,fStartTimeBin);
326 if (status) fBunchDataPointer = &fBunchData[0];
327 else fBunchDataPointer = NULL;
328 return status;
329 }
330
3ce326c0 331 Int_t prevTimeBin = (fBunchLength > 0) ? fStartTimeBin-fBunchLength+1 : 1024;
f8e5b5a0 332 fBunchLength = fStartTimeBin = -1;
6d4dd848 333 fBunchDataPointer = NULL;
f8e5b5a0 334
6d4dd848 335 if ((fBunchDataIndex >= fCount) || fBadChannel) return kFALSE;
f8e5b5a0 336
6d4dd848 337 fBunchLength = fBunchData[fBunchDataIndex];
3ce326c0 338 if (fBunchLength <= 2) {
339 // Invalid bunch size
86871266 340 AliDebug(1,Form("Too short bunch length (%d) @ %d in Address=0x%x (DDL=%03d)!",
f3aadf33 341 fBunchLength,fBunchDataIndex,fHWAddress,fDDLNumber));
3ce326c0 342 fRawReader->AddMinorErrorLog(kAltroBunchHeadErr,Form("hw=0x%x",fHWAddress));
499187ca 343 if (AliDebugLevel() > 0) HexDumpChannel();
3ce326c0 344 fCount = fBunchLength = -1;
345 return kFALSE;
346 }
6d4dd848 347 if ((fBunchDataIndex + fBunchLength) > fCount) {
f8e5b5a0 348 // Too long bunch detected
b421b5a2 349 AliDebug(1,Form("Too long bunch detected @ %d in Address=0x%x (DDL=%03d) ! Expected <= %d 10-bit words, found %d !", fBunchDataIndex,
499187ca 350 fHWAddress,fDDLNumber,fCount-fBunchDataIndex,fBunchLength));
f8e5b5a0 351 fRawReader->AddMinorErrorLog(kAltroBunchHeadErr,Form("hw=0x%x",fHWAddress));
499187ca 352 if (AliDebugLevel() > 0) HexDumpChannel();
f8e5b5a0 353 fCount = fBunchLength = -1;
354 return kFALSE;
355 }
6d4dd848 356 fBunchDataIndex++;
f8e5b5a0 357 fBunchLength -= 2;
358
6d4dd848 359 fStartTimeBin = fBunchData[fBunchDataIndex++];
3ce326c0 360 if (fCheckAltroPayload) {
361 if ((fStartTimeBin-fBunchLength+1) < 0) {
f3aadf33 362 AliWarning(Form("Invalid start time-bin @ %d in Address=0x%x (DDL=%03d)! (%d-%d+1) < 0", fBunchDataIndex-1,
499187ca 363 fHWAddress,fDDLNumber,fStartTimeBin,fBunchLength));
3ce326c0 364 fRawReader->AddMinorErrorLog(kAltroPayloadErr,Form("hw=0x%x",fHWAddress));
499187ca 365 if (AliDebugLevel() > 0) HexDumpChannel();
3ce326c0 366 fCount = fBunchLength = -1;
367 return kFALSE;
368 }
369 if (fStartTimeBin >= prevTimeBin) {
f3aadf33 370 AliWarning(Form("Invalid start time-bin @ %d in Address=0x%x (DDL=%03d)! (%d>=%d)", fBunchDataIndex-1,
499187ca 371 fHWAddress,fDDLNumber,fStartTimeBin,prevTimeBin));
3ce326c0 372 fRawReader->AddMinorErrorLog(kAltroPayloadErr,Form("hw=0x%x",fHWAddress));
499187ca 373 if (AliDebugLevel() > 0) HexDumpChannel();
3ce326c0 374 fCount = fBunchLength = -1;
375 return kFALSE;
376 }
377 }
f8e5b5a0 378
6d4dd848 379 fBunchDataPointer = &fBunchData[fBunchDataIndex];
f8e5b5a0 380
6d4dd848 381 fBunchDataIndex += fBunchLength;
f8e5b5a0 382
383 return kTRUE;
384}
385
386//_____________________________________________________________________________
8e9fa05e 387const UChar_t *AliAltroRawStreamV3::GetChannelPayload() const
388{
389 //returns raw channel data, length 4+(fChannelPayloadSize+2)/3*4
390 if (fChannelStartPos<0 || fChannelPayloadSize<0) return NULL;
391 Int_t channelSize=1+(fChannelPayloadSize+2)/3; // nof 32bit words
392 if (fPosition<fChannelStartPos+channelSize) return NULL;
393 return fData+(fChannelStartPos<<2);
394}
395
396//_____________________________________________________________________________
f8e5b5a0 397UInt_t AliAltroRawStreamV3::Get32bitWord(Int_t index) const
398{
399 // This method returns the 32 bit word at a given
400 // position inside the raw data payload.
401 // The 'index' points to the beginning of the word.
402 // The method is supposed to be endian (platform)
403 // independent.
404
405 index = (index << 2);
406 UInt_t word = 0;
407 word |= fData[index++];
408 word |= fData[index++] << 8;
409 word |= fData[index++] << 16;
410 word |= fData[index++] << 24;
411
412 return word;
413}
414
415///_____________________________________________________________________________
416Bool_t AliAltroRawStreamV3::ReadRCUTrailer(UChar_t rcuVer)
417{
418 // Read the RCU trailer according
419 // to the RCU formware version
420 // specified in CDH
421 // Cross-check with version found in the
422 // trailer
423
424 fRCUTrailerData = NULL;
425 fRCUTrailerSize = 0;
426 fPayloadSize = -1;
427
428 Int_t index = fRawReader->GetDataSize()/4;
429
430 // First read 32-bit word with the
431 // trailer size (7 bits), RCU ID (9 bits) and
432 // RCU firmware version (8 bits?)
433 // The two major bit should be 11 (identifies
434 // the end of the trailer)
435 UInt_t word = Get32bitWord(--index);
436
437 if ((word >> 30) != 3) {
438 fRawReader->AddFatalErrorLog(kRCUTrailerErr,"");
439 AliError("Last RCU trailer word not found!");
440 return kFALSE;
441 }
442
443 UChar_t ver = (word >> 16) & 0xFF;
444 if (ver != rcuVer) {
445 // Wrong RCU firmware version detected
446 fRawReader->AddMajorErrorLog(kRCUVerErr,Form("%d!=%d",
447 ver,rcuVer));
448 AliDebug(1,Form("Wrong RCU firmware version detected: %d != %d",
449 ver,rcuVer));
450 }
451
452 fRCUId = (Int_t)((word >> 7) & 0x1FF);
453 Int_t trailerSize = (word & 0x7F);
454
455 // Now read the beginning of the trailer
456 // where the payload size is written
457 if (trailerSize < 2) {
458 fRawReader->AddMajorErrorLog(kRCUTrailerErr,Form("tr=%d bytes",
459 trailerSize*4));
460 AliWarning(Form("Invalid trailer size found (%d bytes) !",
461 trailerSize*4));
462 return kFALSE;
463 }
464
465 trailerSize -= 2;
466 fRCUTrailerSize = trailerSize*4;
467
468 for (; trailerSize > 0; trailerSize--) {
469 word = Get32bitWord(--index);
470 if ((word >> 30) != 2) {
471 fRawReader->AddMinorErrorLog(kRCUTrailerErr,"missing 10");
472 AliWarning("Missing RCU trailer identifier pattern!");
473 continue;
474 }
475 Int_t parCode = (word >> 26) & 0xF;
476 Int_t parData = word & 0x3FFFFFF;
477 switch (parCode) {
478 case 1:
479 // ERR_REG1
480 fFECERRA = ((parData >> 13) & 0x1FFF) << 7;
481 fFECERRB = ((parData & 0x1FFF)) << 7;
482 break;
483 case 2:
484 // ERR_REG2
485 fERRREG2 = parData & 0x1FF;
486 break;
487 case 3:
488 // ERR_REG3
9283f3a5 489 fERRREG3 = parData & 0x1FFFFFF;
f8e5b5a0 490 break;
491 case 4:
f8e5b5a0 492 // FEC_RO_A
493 fActiveFECsA = parData & 0xFFFF;
494 break;
9283f3a5 495 case 5:
f8e5b5a0 496 // FEC_RO_B
497 fActiveFECsB = parData & 0xFFFF;
498 break;
9283f3a5 499 case 6:
f8e5b5a0 500 // RDO_CFG1
501 fAltroCFG1 = parData & 0xFFFFF;
502 break;
9283f3a5 503 case 7:
f8e5b5a0 504 // RDO_CFG2
505 fAltroCFG2 = parData & 0x1FFFFFF;
506 break;
507 default:
508 fRawReader->AddMinorErrorLog(kRCUTrailerErr,"undef word");
509 AliWarning(Form("Undefined parameter code %d, ignore it !",
510 parCode));
511 break;
512 }
513 }
514
515 if (index < 1) {
516 fRawReader->AddMajorErrorLog(kRCUTrailerErr,Form("tr=%d raw=%d bytes",
517 fRCUTrailerSize+8,
518 fRawReader->GetDataSize()));
519 AliWarning(Form("Invalid trailer size found (%d bytes) ! The size is bigger than the raw data size (%d bytes)!",
520 fRCUTrailerSize,
521 fRawReader->GetDataSize()));
522 }
523
524 fRCUTrailerData = fData + index*4;
525
526 // Now read the payload size
527 // (First word in the RCU trailer)
528 fPayloadSize = Get32bitWord(--index) & 0x3FFFFFF;
529
530 if ((fRawReader->GetDataSize() - fRCUTrailerSize - 8) != (fPayloadSize*4)) {
531 fRawReader->AddMajorErrorLog(kRCUTrailerSizeErr,Form("h=%d tr=%d rcu=%d bytes",
532 fRawReader->GetDataSize(),
533 fRCUTrailerSize+8,
534 fPayloadSize*4));
535 AliWarning(Form("Inconsistent raw data size ! Raw data size - %d bytes (from CDH), RCU trailer - %d bytes, raw data size (from RCU trailer) - %d bytes !",
536 fRawReader->GetDataSize(),
537 fRCUTrailerSize+8,
538 fPayloadSize*4));
539 }
540
541 return kTRUE;
542}
543
544//_____________________________________________________________________________
545Int_t AliAltroRawStreamV3::GetBranch() const
546{
547 // The method provides the RCU branch index (0 or 1)
548 // for the current hardware address.
549 // In case the hardware address has not been yet
550 // initialized, the method returns -1
551 if (fHWAddress == -1) return -1;
552
553 return ((fHWAddress >> 11) & 0x1);
554}
555
556//_____________________________________________________________________________
557Int_t AliAltroRawStreamV3::GetFEC() const
558{
559 // The method provides the front-end card index
560 // for the current hardware address.
561 // In case the hardware address has not been yet
562 // initialized, the method returns -1
563 if (fHWAddress == -1) return -1;
564
565 return ((fHWAddress >> 7) & 0xF);
566}
567
568//_____________________________________________________________________________
569Int_t AliAltroRawStreamV3::GetAltro() const
570{
571 // The method provides the altro chip index
572 // for the current hardware address.
573 // In case the hardware address has not been yet
574 // initialized, the method returns -1
575 if (fHWAddress == -1) return -1;
576
577 return ((fHWAddress >> 4) & 0x7);
578}
579
580//_____________________________________________________________________________
581Int_t AliAltroRawStreamV3::GetChannel() const
582{
583 // The method provides the channel index
584 // for the current hardware address.
585 // In case the hardware address has not been yet
586 // initialized, the method returns -1
587 if (fHWAddress == -1) return -1;
588
589 return (fHWAddress & 0xF);
590}
591
592//_____________________________________________________________________________
593Bool_t AliAltroRawStreamV3::GetRCUTrailerData(UChar_t*& data) const
594{
595 // Return a pointer to the RCU trailer
596 // data. Should be called always after
597 // the RCU trailer was already processed
598 // in the GetPosition() method
599 if (!fRCUTrailerSize || !fRCUTrailerData) {
600 AliError("No valid RCU trailer data is found !");
601 data = NULL;
602 return kFALSE;
603 }
604
605 data = fRCUTrailerData;
606
607 return kTRUE;
608}
609
610//_____________________________________________________________________________
611void AliAltroRawStreamV3::PrintRCUTrailer() const
612{
613 // Prints the contents of
614 // the RCU trailer data
38f5da76 615 printf("RCU trailer (Format version %d):\n"
616 "==================================================\n", GetFormatVersion());
617 printf("FECERRA: 0x%x\n", fFECERRA);
618 printf("FECERRB: 0x%x\n", fFECERRB);
619 printf("ERRREG2: 0x%x\n", fERRREG2);
f8e5b5a0 620 printf("#channels skipped due to address mismatch: %d\n",GetNChAddrMismatch());
621 printf("#channels skipped due to bad block length: %d\n",GetNChLengthMismatch());
38f5da76 622 printf("Active FECs (branch A): 0x%x\n", fActiveFECsA);
623 printf("Active FECs (branch B): 0x%x\n", fActiveFECsB);
624 printf("Baseline corr: 0x%x\n",GetBaselineCorr());
625 printf("Number of presamples: %d\n", GetNPresamples());
626 printf("Number of postsamples: %d\n",GetNPostsamples());
627 printf("Second baseline corr: %d\n",GetSecondBaselineCorr());
628 printf("GlitchFilter: %d\n",GetGlitchFilter());
629 printf("Number of non-ZS postsamples: %d\n",GetNNonZSPostsamples());
630 printf("Number of non-ZS presamples: %d\n",GetNNonZSPresamples());
631 printf("Number of ALTRO buffers: %d\n",GetNAltroBuffers());
632 printf("Number of pretrigger samples: %d\n",GetNPretriggerSamples());
633 printf("Number of samples per channel: %d\n",GetNSamplesPerCh());
634 printf("Sparse readout: %d\n",GetSparseRO());
635 printf("Sampling time: %e s\n",GetTSample());
636 printf("L1 Phase: %e s\n",GetL1Phase());
637 printf("AltroCFG1: 0x%x\n",GetAltroCFG1());
638 printf("AltroCFG2: 0x%x\n",GetAltroCFG2());
639 printf("==================================================\n");
f8e5b5a0 640}
641
642//_____________________________________________________________________________
643void AliAltroRawStreamV3::SelectRawData(Int_t detId)
644{
645 // Select the raw data for specific
646 // detector id
647 AliDebug(1,Form("Selecting raw data for detector %d",detId));
648 fRawReader->Select(detId);
649}
650
651//_____________________________________________________________________________
652void AliAltroRawStreamV3::SelectRawData(const char *detName)
653{
654 // Select the raw data for specific
655 // detector name
656 AliDebug(1,Form("Selecting raw data for detector %s",detName));
657 fRawReader->Select(detName);
658}
659
660//_____________________________________________________________________________
661Double_t AliAltroRawStreamV3::GetTSample() const
662{
663 // Returns the sampling time
664 // in seconds. In case the rcu trailer
665 // was note read, return an invalid number (0)
666
667 if (!fRCUTrailerData) return 0.;
668
669 const Double_t kLHCTimeSample = 25.0e-9; // LHC clocks runs at 40 MHz
670 UChar_t fq = (fAltroCFG2 >> 5) & 0xF;
671 Double_t tSample;
672 switch (fq) {
673 case 0:
674 // 20 MHz
675 tSample = 2.0*kLHCTimeSample;
676 break;
677 case 1:
678 // 10 Mhz
679 tSample = 4.0*kLHCTimeSample;
680 break;
681 case 2:
682 // 5 MHz
683 tSample = 8.0*kLHCTimeSample;
684 break;
685 default:
686 AliWarning(Form("Invalid sampling frequency value %d !",
687 fq));
688 tSample = 0.;
689 break;
690 }
691
692 return tSample;
693}
694
695//_____________________________________________________________________________
696Double_t AliAltroRawStreamV3::GetL1Phase() const
697{
698 // Returns the L1 phase w.r.t to the
699 // LHC clock
700 if (!fRCUTrailerData) return 0.;
701
702 const Double_t kLHCTimeSample = 25.0e-9; // LHC clocks runs at 40 MHz
703 Double_t phase = ((Double_t)(fAltroCFG2 & 0x1F))*kLHCTimeSample;
704
705 Double_t tSample = GetTSample();
706 if (phase >= tSample) {
6c12d59f 707 AliWarning(Form("Invalid L1 trigger phase (%f >= %f) !",
f8e5b5a0 708 phase,tSample));
709 phase = 0.;
710 }
711
712 return phase;
713}
714
715//_____________________________________________________________________________
716void AliAltroRawStreamV3::AddMappingErrorLog(const char *message)
717{
718 // Signal a mapping error
719 // The method can be used by the TPC,PHOS,EMCAL,FMD raw stream
720 // classes in order to log an error related to bad altro mapping
721
722 if (fRawReader) fRawReader->AddMinorErrorLog(kBadAltroMapping,message);
723}
eae29211 724
725//_____________________________________________________________________________
726UChar_t *AliAltroRawStreamV3::GetRCUPayloadInSOD() const
727{
728 // Get a pointer to the data in case
729 // of SOD events
730 if (fRawReader) {
731 if (fRawReader->GetType() == AliRawEventHeaderBase::kStartOfData) {
732 return fData;
733 }
734 }
735 return NULL;
736}
737
738//_____________________________________________________________________________
739Int_t AliAltroRawStreamV3::GetRCUPayloadSizeInSOD() const
740{
741 // Get the size of the RCU data in case
742 // of SOD events
743 if (fRawReader) {
744 if (fRawReader->GetType() == AliRawEventHeaderBase::kStartOfData) {
745 return fPayloadSize;
746 }
747 }
748 return -1;
749}
499187ca 750
751//_____________________________________________________________________________
752
753void AliAltroRawStreamV3::HexDumpChannel() const
754{
755 // Print of the Hex Data of the current channel
756 // to decipher read-out warnings and errors
757 if (fCount>0 && fPosition>0) {
758 printf("Hex-Dump of DDL: %3d, RCU ID: %d, HWADDR: 0x%03x\n",
759 fDDLNumber,fRCUId,fHWAddress);
f3aadf33 760 printf("32-bit - 2bit 10bit 10bit 10bit - ");
761 printf("Index 10bit 10bit 10bit\n");
762 printf("********** **** ***** ***** ***** - ");
763 printf("***** ****** ****** ******\n");
499187ca 764 Int_t nwords = (fCount+2)/3+1;
765 for (Int_t iword = 0; iword < nwords; iword++) {
766 UInt_t word32 = Get32bitWord(fPosition-nwords+iword);
767 UInt_t marker = word32 >> 30 & 0x3;
768 UInt_t word101 = word32 >> 20 & 0x3FF;
769 UInt_t word102 = word32 >> 10 & 0x3FF;
770 UInt_t word103 = word32 >> 00 & 0x3FF; // nice octal number
f3aadf33 771 printf("0x%08x - 0b%1d%1d 0x%03x 0x%03x 0x%03x",
499187ca 772 word32,marker>>1,marker&0x1,word101,word102,word103);
f3aadf33 773 if (iword == 0) { printf(" - Channel Header\n"); continue; }
774 Int_t base = 3*(iword-1);
775 printf(" - %5d 0x%03x%c 0x%03x%c 0x%03x%c\n", base,
776 fBunchData[base], (fBunchDataIndex == base ? '*' : ' '),
777 fBunchData[base+1], (fBunchDataIndex == base+1 ? '*' : ' '),
778 fBunchData[base+2], (fBunchDataIndex == base+2 ? '*' : ' '));
499187ca 779 }
780 }
781}