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