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