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