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