Bug fix affecting the rcu trailer size variable
[u/mrichter/AliRoot.git] / RAW / AliAltroRawStream.cxx
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 /* $Id$ */
17
18 ///////////////////////////////////////////////////////////////////////////////
19 ///
20 /// This class provides access to Altro digits in raw data.
21 ///
22 /// It loops over all Altro digits in the raw data given by the AliRawReader.
23 /// The Next method goes to the next digit. If there are no digits left
24 /// it returns kFALSE.
25 /// Several getters provide information about the current digit.
26 ///
27 ///////////////////////////////////////////////////////////////////////////////
28
29 #include "AliAltroRawStream.h"
30 #include "AliRawReader.h"
31 #include "AliLog.h"
32
33 ClassImp(AliAltroRawStream)
34
35
36 //_____________________________________________________________________________
37 AliAltroRawStream::AliAltroRawStream(AliRawReader* rawReader) :
38   fNoAltroMapping(kTRUE),
39   fIsShortDataHeader(kFALSE),
40   fDDLNumber(-1),
41   fPrevDDLNumber(-1),
42   fRCUId(-1),
43   fPrevRCUId(-1),
44   fHWAddress(-1),
45   fPrevHWAddress(-1),
46   fTime(-1),
47   fPrevTime(-1),
48   fSignal(-1),
49   fTimeBunch(-1),
50   fRawReader(rawReader),
51   fData(NULL),
52   fPosition(0),
53   fCount(0),
54   fBunchLength(0),
55   fRCUTrailerData(NULL),
56   fRCUTrailerSize(0),
57   fFECERRA(0),
58   fFECERRB(0),
59   fERRREG2(0),
60   fERRREG3(0),
61   fERRREG4(0),
62   fActiveFECsA(0),
63   fActiveFECsB(0),
64   fAltroCFG1(0),
65   fAltroCFG2(0)
66 {
67 // create an object to read Altro raw digits
68   fSegmentation[0] = fSegmentation[1] = fSegmentation[2] = -1;
69 }
70
71 //_____________________________________________________________________________
72 AliAltroRawStream::AliAltroRawStream(const AliAltroRawStream& stream) :
73   TObject(stream),
74   fNoAltroMapping(stream.fNoAltroMapping),
75   fIsShortDataHeader(stream.fIsShortDataHeader),
76   fDDLNumber(stream.fDDLNumber),
77   fPrevDDLNumber(stream.fPrevDDLNumber),
78   fRCUId(stream.fRCUId),
79   fPrevRCUId(stream.fPrevRCUId),
80   fHWAddress(stream.fHWAddress),
81   fPrevHWAddress(stream.fPrevHWAddress),
82   fTime(stream.fTime),
83   fPrevTime(stream.fPrevTime),
84   fSignal(stream.fSignal),
85   fTimeBunch(stream.fTimeBunch),
86   fRawReader(stream.fRawReader),
87   fData(stream.fData),
88   fPosition(stream.fPosition),
89   fCount(stream.fCount),
90   fBunchLength(stream.fBunchLength),
91   fRCUTrailerData(stream.fRCUTrailerData),
92   fRCUTrailerSize(stream.fRCUTrailerSize),
93   fFECERRA(stream.fFECERRA),
94   fFECERRB(stream.fFECERRB),
95   fERRREG2(stream.fERRREG2),
96   fERRREG3(stream.fERRREG3),
97   fERRREG4(stream.fERRREG4),
98   fActiveFECsA(stream.fActiveFECsA),
99   fActiveFECsB(stream.fActiveFECsB),
100   fAltroCFG1(stream.fAltroCFG1),
101   fAltroCFG2(stream.fAltroCFG2)
102 {
103   fSegmentation[0]   = stream.fSegmentation[0];
104   fSegmentation[1]   = stream.fSegmentation[1];
105   fSegmentation[2]   = stream.fSegmentation[2];
106 }
107
108 //_____________________________________________________________________________
109 AliAltroRawStream& AliAltroRawStream::operator = (const AliAltroRawStream& stream)
110 {
111   if(&stream == this) return *this;
112
113   fNoAltroMapping    = stream.fNoAltroMapping;
114   fIsShortDataHeader = stream.fIsShortDataHeader;
115   fDDLNumber         = stream.fDDLNumber;
116   fPrevDDLNumber     = stream.fPrevDDLNumber;
117   fRCUId             = stream.fRCUId;
118   fPrevRCUId         = stream.fPrevRCUId;
119   fHWAddress         = stream.fHWAddress;
120   fPrevHWAddress     = stream.fPrevHWAddress;
121   fTime              = stream.fTime;
122   fPrevTime          = stream.fPrevTime;
123   fSignal            = stream.fSignal;
124   fTimeBunch         = stream.fTimeBunch;
125   fRawReader         = stream.fRawReader;
126   fData              = stream.fData;
127   fPosition          = stream.fPosition;
128   fCount             = stream.fCount;
129   fBunchLength       = stream.fBunchLength;
130   fRCUTrailerData    = stream.fRCUTrailerData;
131   fRCUTrailerSize    = stream.fRCUTrailerSize;
132   fFECERRA           = stream.fFECERRA;
133   fFECERRB           = stream.fFECERRB;
134   fERRREG2           = stream.fERRREG2;
135   fERRREG3           = stream.fERRREG3;
136   fERRREG4           = stream.fERRREG4;
137   fActiveFECsA       = stream.fActiveFECsA;
138   fActiveFECsB       = stream.fActiveFECsB;
139   fAltroCFG1         = stream.fAltroCFG1;
140   fAltroCFG2         = stream.fAltroCFG2;
141
142   fSegmentation[0]   = stream.fSegmentation[0];
143   fSegmentation[1]   = stream.fSegmentation[1];
144   fSegmentation[2]   = stream.fSegmentation[2];
145
146   return *this;
147 }
148
149 //_____________________________________________________________________________
150 AliAltroRawStream::~AliAltroRawStream()
151 {
152 // clean up
153
154 }
155
156 //_____________________________________________________________________________
157 void AliAltroRawStream::Reset()
158 {
159 // reset altro raw stream params
160
161   fPosition = fCount = fBunchLength = 0;
162
163   fRCUTrailerData = NULL;
164   fRCUTrailerSize = 0;
165
166   fFECERRA = fFECERRB = fERRREG2 = fERRREG3 = fERRREG4 = fActiveFECsA = fActiveFECsB = fAltroCFG1 = fAltroCFG2 = 0;
167
168   fDDLNumber = fPrevDDLNumber = fRCUId = fPrevRCUId = fHWAddress = fPrevHWAddress = fTime = fPrevTime = fSignal = fTimeBunch = -1;
169
170   if (fRawReader) fRawReader->Reset();
171
172   fSegmentation[0] = fSegmentation[1] = fSegmentation[2] = -1;
173 }
174
175 //_____________________________________________________________________________
176 Bool_t AliAltroRawStream::Next()
177 {
178 // read the next raw digit
179 // returns kFALSE if there is no digit left
180
181   fPrevDDLNumber = fDDLNumber;
182   fPrevRCUId = fRCUId;
183   fPrevHWAddress = fHWAddress;
184   fPrevTime = fTime;
185
186   while (fCount == 0) {  // next trailer
187     while (fPosition <= 0) {  // next payload
188       do {
189         if (!fRawReader->ReadNextData(fData)) return kFALSE;
190       } while (fRawReader->GetDataSize() == 0);
191
192       fDDLNumber = fRawReader->GetDDLID();
193
194       fPosition = GetPosition();
195     }
196
197     ReadTrailer();
198
199     fBunchLength = 0;
200   }
201
202   if (fBunchLength == 0) ReadBunch();
203   else fTime--;
204
205   ReadAmplitude();
206
207   return kTRUE;
208 }
209
210 //_____________________________________________________________________________
211 void AliAltroRawStream::SelectRawData(Int_t detId)
212 {
213   // Select the raw data for specific
214   // detector id
215   AliDebug(1,Form("Selecting raw data for detector %d",detId));
216   fRawReader->Select(detId);
217 }
218
219 //_____________________________________________________________________________
220 void AliAltroRawStream::SelectRawData(const char *detName)
221 {
222   // Select the raw data for specific
223   // detector name
224   AliDebug(1,Form("Selecting raw data for detector %s",detName));
225   fRawReader->Select(detName);
226 }
227
228 //_____________________________________________________________________________
229 UShort_t AliAltroRawStream::GetNextWord()
230 {
231   // Read the next 10 bit word in backward direction
232   // The input stream access is given by fData and fPosition
233
234   fPosition--;
235
236   Int_t iBit = fPosition * 10;
237   Int_t iByte = iBit / 8;
238   Int_t shift = iBit % 8;
239
240   // the raw data is written as integers where the low bits are filled first
241   // -> little endian is assumed here !
242   Int_t iByteLow = iByte;
243   iByte++;
244   Int_t iByteHigh  = iByte;
245   return ((fData[iByteHigh] * 256 + fData[iByteLow]) >> shift) & 0x03FF;
246 }
247
248 //_____________________________________________________________________________
249 Bool_t AliAltroRawStream::ReadTrailer()
250 {
251   //Read a trailer of 40 bits in the backward reading mode
252   //In case of no mapping is provided, read a dummy trailer
253   if (fNoAltroMapping) {
254     AliError("No ALTRO mapping information is loaded! Reading a dummy trailer!");
255     return ReadDummyTrailer();
256   }
257
258   //First reading filling words
259   UShort_t temp;
260   Int_t nFillWords = 0;
261   while ((temp = GetNextWord()) == 0x2AA) nFillWords++;
262   if (nFillWords == 0) {
263     fRawReader->AddMajorErrorLog(kAltroTrailerErr,"no 0x2AA");
264     //    PrintDebug();
265     AliWarning(Form("Incorrect trailer found ! Expected 0x2AA not found (0x%x != 0x2AA) ! Current position %d, DDL=%d",
266                     temp,fPosition,fDDLNumber));
267     // trying to recover and find the next bunch
268     while ((fPosition > 2) && (temp != 0x2AA)) temp = GetNextWord();
269     if (temp != 0x2AA) {
270       fCount = fPosition = 0;
271       return kFALSE;
272     }
273     temp = GetNextWord();
274   }
275
276   //Then read the trailer
277   if (fPosition < 2) {
278     fRawReader->AddMajorErrorLog(kAltroTrailerErr,Form("size %d < 5",
279                                                        fPosition));
280     //    PrintDebug();
281     AliWarning(Form("Incorrect raw data size ! Expected at least 5 words but found %d !",fPosition));
282     fCount = fPosition = 0;
283     return kFALSE;
284   }
285
286   fCount = (temp << 4) & 0x3FF;
287   if ((temp >> 6) != 0xA) {
288     fRawReader->AddMajorErrorLog(kAltroTrailerErr,"no 0xA");
289     //    PrintDebug();
290     AliWarning(Form("Incorrect trailer found ! Expecting 0xA but found 0x%x !",temp >> 6));
291     fCount = 0;
292     return kFALSE;
293   }
294
295   temp = GetNextWord();
296   fHWAddress = (temp & 0x3) << 10;
297   if (((temp >> 2) & 0xF) != 0xA) {
298     fRawReader->AddMajorErrorLog(kAltroTrailerErr,"no second 0xA");
299     //    PrintDebug();
300     AliWarning(Form("Incorrect trailer found ! Expecting second 0xA but found 0x%x !",(temp >> 2) & 0xF));
301     fCount = 0;
302     return kFALSE;
303   }
304   fCount |= ((temp & 0x3FF) >> 6);
305
306   if (fCount >= fPosition) {
307     fRawReader->AddMajorErrorLog(kAltroTrailerErr,"invalid size");
308     //    PrintDebug();
309     AliWarning(Form("Incorrect trailer found ! The altro payload size is invalid (%d >= %d) !",fCount,fPosition));
310     fCount = 0;
311     return kFALSE;
312   }
313   temp = GetNextWord();
314   fHWAddress |= temp;
315
316   fPosition -= (4 - (fCount % 4)) % 4;  // skip fill words
317
318   return kTRUE;
319 }
320
321 //_____________________________________________________________________________
322 Bool_t AliAltroRawStream::ReadDummyTrailer()
323 {
324   //Read a trailer of 40 bits in the backward reading mode
325   //In case of no mapping is provided, read a dummy trailer
326   UShort_t temp;
327   while ((temp = GetNextWord()) == 0x2AA);
328
329   fSegmentation[0] = temp;
330   fSegmentation[1] = GetNextWord();
331   fSegmentation[2] = GetNextWord();
332   fCount = GetNextWord();
333   if (fCount == 0) return kFALSE;
334   fHWAddress = -1;
335
336   fPosition -= (4 - (fCount % 4)) % 4;  // skip fill words
337
338   return kTRUE;
339 }
340
341 //_____________________________________________________________________________
342 void AliAltroRawStream::ReadBunch()
343 {
344   // Read altro payload in 
345   // backward direction
346   if (fCount <= 2) {
347     fRawReader->AddMinorErrorLog(kBunchLengthReadErr,"");
348     //    PrintDebug();
349     AliWarning(Form("Could not read bunch length and time bin ! Only %d 10-bit words are left !",fCount));
350     fBunchLength = fTimeBunch = fCount = 0;
351     return;
352   }
353
354   fBunchLength = GetNextWord() - 2;
355   if (fBunchLength > fCount) {
356     fRawReader->AddMinorErrorLog(kBunchLengthReadErr,Form("bl=%d",fBunchLength));
357     //    PrintDebug();
358     AliWarning(Form("Could not read bunch length ! Bunch length = %d (>%d)",fBunchLength,fCount));
359     fBunchLength = fTimeBunch = fCount = 0;
360     return;
361   }
362   fTimeBunch = fBunchLength;
363   fCount--;
364
365   fTime = GetNextWord();
366   fCount--;
367
368   return;
369 }
370
371 //_____________________________________________________________________________
372 void AliAltroRawStream::ReadAmplitude()
373 {
374   // Read next time bin amplitude
375   if (fCount <= 0) {
376     fRawReader->AddMinorErrorLog(kAmplitudeReadErr,"");
377     //    PrintDebug();
378     AliWarning("Could not read sample amplitude !");
379     fCount = fSignal = fBunchLength = 0;
380     return;
381   }
382
383   fSignal = GetNextWord();
384
385   fCount--;
386   fBunchLength--;
387
388   return;
389 }
390
391 //_____________________________________________________________________________
392 Int_t AliAltroRawStream::GetPosition()
393 {
394   // Sets the position in the
395   // input stream
396   // Read the RCU trailer
397   // This includes the trailer size,
398   // RCU identifier and raw data payload.
399   // The RCU trailer format is described
400   // in details in the RCU manual.
401
402   // We use the last word of the payload
403   // in order to decide which RCU firmware
404   // was used during the data taking.
405   // The firmware v2 adds 0xAAAA as 16
406   // most significant bits and since the
407   // payload size (firmware v1) can not be
408   // that big, we use this as a unique
409   // label of the firmware version.
410
411   Int_t index = fRawReader->GetDataSize();
412   UInt_t word = Get32bitWord(index);
413   if (((word >> 16) == 0xaaaa) || (word == 2)) {
414     // This is RCU formware v2
415     // The statement word==2 is needed only temporary
416     // in order to be able to read previously generated
417     // aliroot raw data
418
419     Int_t trailerSize = 0;
420     if (word == 2) {
421       AliInfo("Old simulated raw data is assumed!");
422       trailerSize = 2;
423       fRCUId = 0;
424     }
425     else {
426       // First read 32-bit word with the
427       // trailer size (7 bits), RCU ID (9 bits) and
428       // 0xAAA (the rest - 16 bits)
429       fRCUId = (Int_t)((word >> 7) & 0x1ff);
430       trailerSize = (word & 0x7F);
431     }
432
433     // Now read the beginning of the trailer
434     // where the payload size is written
435     if (trailerSize < 2) {
436       fRawReader->AddMajorErrorLog(kRCUTrailerErr,Form("tr=%d bytes",
437                                                        trailerSize*4));
438       AliWarning(Form("Invalid trailer size found (%d bytes) !",
439                       trailerSize*4));
440     }
441
442     Int_t position = ReadRCUTrailer(index,trailerSize);
443     // The size is specified in a number of 40bits
444     // Therefore we need to transform it to number of bytes
445     position *= 5;
446
447     // Check the consistency of the header and trailer
448     if (((fRawReader->GetDataSize() - trailerSize*4) < position) ||
449         ((fRawReader->GetDataSize() - trailerSize*4) >= (position + 4))) {
450       fRawReader->AddMajorErrorLog(kRCUTrailerSizeErr,Form("h=%d tr=%d rcu=%d bytes",
451                                                            fRawReader->GetDataSize(),
452                                                            trailerSize*4,
453                                                            position));
454       AliWarning(Form("Inconsistent raw data size ! Raw data size - %d bytes (from the header), RCU trailer - %d bytes, raw data paylod - %d bytes !",
455                     fRawReader->GetDataSize(),
456                     trailerSize*4,
457                     position));
458       position = fRawReader->GetDataSize() - trailerSize*4;
459     }
460
461     return position * 8 / 10;
462   }
463   else {
464     // In case of the Old RCU trailer format
465     // we have to read just the size of altro payload
466     // in units of 40-bit words
467     Int_t position = (Int_t)word;
468
469     fRCUId = -1;
470     fRCUTrailerSize = 0;
471     fRCUTrailerData = NULL;
472
473     // The size is specified in a number of 40bits
474     // Therefore we need to transform it to number of bytes
475     position *= 5;
476
477     if (!fIsShortDataHeader) {
478
479       // Check the consistency of the header and trailer
480       if (((fRawReader->GetDataSize() - 4) < position) ||
481           ((fRawReader->GetDataSize() - 4) >= (position + 4))) {
482         fRawReader->AddMajorErrorLog(kRCUTrailerSizeErr,Form("h=%d rcu=%d bytes",
483                                                              fRawReader->GetDataSize()-4,
484                                                              position));
485         //      PrintDebug();
486         AliWarning(Form("Inconsistent raw data size ! Expected %d bytes (from the header), found %d bytes (in the RCU trailer)!",
487                         fRawReader->GetDataSize()-4,
488                         position));
489         position = fRawReader->GetDataSize()-4;
490       }
491     }
492     else {
493       // Check the consistency of the header and trailer
494       // In this case the header is shorter by 4 bytes
495       if ((fRawReader->GetDataSize() < position) ||
496           (fRawReader->GetDataSize() >= (position + 4))) {
497         fRawReader->AddMajorErrorLog(kRCUTrailerSizeErr,Form("h=%d rcu=%d bytes",
498                                                              fRawReader->GetDataSize(),
499                                                              position));
500         //      PrintDebug();
501         AliWarning(Form("Inconsistent raw data size ! Expected %d bytes (from the header), found %d bytes (in the RCU trailer)!",
502                         fRawReader->GetDataSize(),
503                         position));
504         position = fRawReader->GetDataSize();
505       }
506
507       // 7 32-bit words Common Data Header
508       // therefore we have to shift back by 4 bytes
509       // the pointer to the raw data payload
510       fData -= 4;
511     }
512      
513     // Return the position in units of 10-bit words
514     return position*8/10;
515   }
516 }
517
518 //_____________________________________________________________________________
519 UInt_t AliAltroRawStream::Get32bitWord(Int_t &index)
520 {
521   // This method returns the 32 bit word at a given
522   // position inside the raw data payload.
523   // The 'index' points to the beginning of the next word.
524   // The method is supposed to be endian (platform)
525   // independent.
526   if (!fData) {
527     PrintDebug();
528     AliFatal("Raw data paylod buffer is not yet initialized !");
529   }
530
531   if (index < 4) {
532     fRawReader->AddFatalErrorLog(k32bitWordReadErr,Form("pos = %d",index));
533     //    PrintDebug();
534     AliWarning(Form("Invalid raw data payload position (%d) !",index));
535   }
536
537   UInt_t word = 0;
538   word  = fData[--index] << 24;
539   word |= fData[--index] << 16;
540   word |= fData[--index] << 8;
541   word |= fData[--index];
542
543   return word;
544 }
545
546 //_____________________________________________________________________________
547 Int_t AliAltroRawStream::ReadRCUTrailer(Int_t &index, Int_t trailerSize)
548 {
549   // The method decodes the RCU trailer data
550   // according to the RCU fw ver.2 specs
551   
552   fRCUTrailerSize = trailerSize*4;
553
554   for (trailerSize -= 2; trailerSize > 0; trailerSize--) {
555     Int_t word = Get32bitWord(index);
556     Int_t parCode = word >> 26;
557     Int_t parData = word & 0x3FFFFFF;
558     switch (parCode) {
559     case 1:
560       // ERR_REG1
561       fFECERRA = ((parData >> 13) & 0x1FFF) << 7;
562       fFECERRB = ((parData & 0x1FFF)) << 7;
563       break;
564     case 2:
565       // ERR_REG2
566       fERRREG2 = parData & 0x1FF;
567       break;
568     case 3:
569       // ERR_REG3
570       fERRREG3 = parData & 0xFFF;
571       break;
572     case 4:
573       // ERR_REG4
574       fERRREG4 = parData & 0xFFF;
575       break;
576     case 5:
577       // FEC_RO_A
578       fActiveFECsA = parData & 0xFFFF;
579       break;
580     case 6:
581       // FEC_RO_B
582       fActiveFECsB = parData & 0xFFFF;
583       break;
584     case 7:
585       // RDO_CFG1
586       fAltroCFG1 = parData & 0x7FFFF;
587       break;
588     case 8:
589       // RDO_CFG2
590       fAltroCFG2 = parData & 0x1FFFFFF;
591      break;
592     default:
593       fRawReader->AddMinorErrorLog(kRCUTrailerErr,"undef word");
594       AliWarning(Form("Undefined parameter code %d, ignore it !",
595                       parCode));
596       break;
597     }
598   }
599
600   if (index < 4) {
601     fRawReader->AddMajorErrorLog(kRCUTrailerErr,Form("tr=%d raw=%d bytes",
602                                                      fRCUTrailerSize,
603                                                      fRawReader->GetDataSize()));
604     AliWarning(Form("Invalid trailer size found (%d bytes) ! The size is bigger than the raw data size (%d bytes)!",
605                     fRCUTrailerSize,
606                     fRawReader->GetDataSize()));
607   }
608   fRCUTrailerData = fData + index;
609
610   Int_t position = Get32bitWord(index);
611
612
613   return position;
614 }
615
616 //_____________________________________________________________________________
617 Double_t AliAltroRawStream::GetTSample() const
618 {
619   // Returns the sampling time
620   // in seconds. In case the rcu trailer
621   // was note read, return an invalid number (0)
622
623   if (!fRCUTrailerData) return 0.;
624
625   const Double_t kLHCTimeSample = 25.0e-9; // LHC clocks runs at 40 MHz
626   UChar_t fq = (fAltroCFG2 >> 5) & 0xF;
627   Double_t tSample;
628   switch (fq) {
629   case 0:
630     // 20 MHz
631     tSample = 2.0*kLHCTimeSample;
632     break;
633   case 1:
634     // 10 Mhz
635     tSample = 4.0*kLHCTimeSample;
636     break;
637   case 2:
638     // 5 MHz
639     tSample = 8.0*kLHCTimeSample;
640     break;
641   default:
642     AliWarning(Form("Invalid sampling frequency value %d !",
643                       fq));
644     tSample = 0.;
645     break;
646   }
647
648   return tSample;
649 }
650
651 //_____________________________________________________________________________
652 Double_t AliAltroRawStream::GetL1Phase() const
653 {
654   // Returns the L1 phase w.r.t to the
655   // LHC clock
656   if (!fRCUTrailerData) return 0.;
657
658   const Double_t kLHCTimeSample = 25.0e-9; // LHC clocks runs at 40 MHz
659   Double_t phase = ((Double_t)(fAltroCFG2 & 0x1F))*kLHCTimeSample;
660
661   Double_t tSample = GetTSample();
662   if (phase >= tSample) {
663     AliWarning(Form("Invalid L1 trigger phase (%f >= %d) !",
664                     phase,tSample));
665     phase = 0.;
666   }
667
668   return phase;
669 }
670
671 //_____________________________________________________________________________
672 void AliAltroRawStream::PrintRCUTrailer() const
673 {
674   // Prints the contents of
675   // the RCU trailer data
676   printf("RCU trailer:\n===========\n");
677   printf("FECERRA: 0x%x\nFECERRB: 0x%x\n",fFECERRA,fFECERRB);
678   printf("ERRREG2: 0x%x\n",fERRREG2);
679   printf("#channels skipped due to address mismatch: %d\n",GetNChAddrMismatch());
680   printf("#channels skipped due to bad block length: %d\n",GetNChLengthMismatch());
681   printf("Active FECs (branch A): 0x%x\nActive FECs (branch B): 0x%x\n",fActiveFECsA,fActiveFECsB);
682   printf("Baseline corr: 0x%x\n",GetBaselineCorr());
683   printf("Number of presamples: %d\nNumber of postsamples: %d\n",GetNPresamples(),GetNPostsamples());
684   printf("Second baseline corr: %d\n",GetSecondBaselineCorr());
685   printf("GlitchFilter: %d\n",GetGlitchFilter());
686   printf("Number of non-ZS postsamples: %d\nNumber of non-ZS presamples: %d\n",GetNNonZSPostsamples(),GetNNonZSPresamples());
687   printf("Number of ALTRO buffers: %d\n",GetNAltroBuffers());
688   printf("Number of pretrigger samples: %d\n",GetNPretriggerSamples());
689   printf("Number of samples per channel: %d\n",GetNSamplesPerCh());
690   printf("Sparse readout: %d\n",GetSparseRO());
691   printf("Sampling time: %e s\n",GetTSample());
692   printf("L1 Phase: %e s\n",GetL1Phase());
693   printf("AltroCFG1: 0x%x\nAltroCFG2: 0x%x\n",GetAltroCFG1(),GetAltroCFG2());
694   printf("===========\n");
695 }
696
697 //_____________________________________________________________________________
698 Bool_t AliAltroRawStream::GetRCUTrailerData(UChar_t*& data) const
699 {
700   // Return a pointer to the RCU trailer
701   // data. Should be called always after
702   // the RCU trailer was already processed
703   // in the GetPosition() method
704   if (!fRCUTrailerSize || !fRCUTrailerData) {
705     AliError("No valid RCU trailer data is found !");
706     data = NULL;
707     return kFALSE;
708   }
709
710   data = fRCUTrailerData;
711
712   return kTRUE;
713 }
714
715 //_____________________________________________________________________________
716 void AliAltroRawStream::PrintDebug() const
717 {
718   // The method prints all the available
719   // debug information.
720   // Its is used in case of decoding errors.
721
722   AliError("Start of debug printout\n--------------------");
723
724   Dump();
725   if (fRawReader) fRawReader->Dump();
726
727   AliError("End of debug printout\n--------------------");
728 }
729
730 //_____________________________________________________________________________
731 Int_t AliAltroRawStream::GetBranch() const
732 {
733   // The method provides the RCU branch index (0 or 1)
734   // for the current hardware address.
735   // In case the hardware address has not been yet
736   // initialized, the method returns -1
737   if (fHWAddress == -1) return -1;
738
739   return ((fHWAddress >> 11) & 0x1);
740 }
741
742 //_____________________________________________________________________________
743 Int_t AliAltroRawStream::GetFEC() const
744 {
745   // The method provides the front-end card index
746   // for the current hardware address.
747   // In case the hardware address has not been yet
748   // initialized, the method returns -1
749   if (fHWAddress == -1) return -1;
750
751   return ((fHWAddress >> 7) & 0xF);
752 }
753
754 //_____________________________________________________________________________
755 Int_t AliAltroRawStream::GetAltro() const
756 {
757   // The method provides the altro chip index
758   // for the current hardware address.
759   // In case the hardware address has not been yet
760   // initialized, the method returns -1
761   if (fHWAddress == -1) return -1;
762
763   return ((fHWAddress >> 4) & 0x7);
764 }
765
766 //_____________________________________________________________________________
767 Int_t AliAltroRawStream::GetChannel() const
768 {
769   // The method provides the channel index
770   // for the current hardware address.
771   // In case the hardware address has not been yet
772   // initialized, the method returns -1
773   if (fHWAddress == -1) return -1;
774
775   return (fHWAddress & 0xF);
776 }
777
778 //_____________________________________________________________________________
779 void AliAltroRawStream::AddMappingErrorLog(const char *message)
780 {
781   // Signal a mapping error
782   // The method can be used by the TPC,PHOS,EMCAL,FMD raw stream
783   // classes in order to log an error related to bad altro mapping
784
785   if (fRawReader) fRawReader->AddMinorErrorLog(kBadAltroMapping,message);
786 }