]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - RAW/AliAltroRawStream.cxx
Bug fix affecting the rcu trailer size variable
[u/mrichter/AliRoot.git] / RAW / AliAltroRawStream.cxx
index be92382744c0d527e5af307e43931d067f76799c..49ce330488bc4a4652818804ec1d534d04e515e0 100644 (file)
@@ -36,6 +36,7 @@ ClassImp(AliAltroRawStream)
 //_____________________________________________________________________________
 AliAltroRawStream::AliAltroRawStream(AliRawReader* rawReader) :
   fNoAltroMapping(kTRUE),
+  fIsShortDataHeader(kFALSE),
   fDDLNumber(-1),
   fPrevDDLNumber(-1),
   fRCUId(-1),
@@ -52,7 +53,16 @@ AliAltroRawStream::AliAltroRawStream(AliRawReader* rawReader) :
   fCount(0),
   fBunchLength(0),
   fRCUTrailerData(NULL),
-  fRCUTrailerSize(0)
+  fRCUTrailerSize(0),
+  fFECERRA(0),
+  fFECERRB(0),
+  fERRREG2(0),
+  fERRREG3(0),
+  fERRREG4(0),
+  fActiveFECsA(0),
+  fActiveFECsB(0),
+  fAltroCFG1(0),
+  fAltroCFG2(0)
 {
 // create an object to read Altro raw digits
   fSegmentation[0] = fSegmentation[1] = fSegmentation[2] = -1;
@@ -61,33 +71,78 @@ AliAltroRawStream::AliAltroRawStream(AliRawReader* rawReader) :
 //_____________________________________________________________________________
 AliAltroRawStream::AliAltroRawStream(const AliAltroRawStream& stream) :
   TObject(stream),
-  fNoAltroMapping(kTRUE),
-  fDDLNumber(-1),
-  fPrevDDLNumber(-1),
-  fRCUId(-1),
-  fPrevRCUId(-1),
-  fHWAddress(-1),
-  fPrevHWAddress(-1),
-  fTime(-1),
-  fPrevTime(-1),
-  fSignal(-1),
-  fTimeBunch(-1),
-  fRawReader(NULL),
-  fData(NULL),
-  fPosition(0),
-  fCount(0),
-  fBunchLength(0),
-  fRCUTrailerData(NULL),
-  fRCUTrailerSize(0)
+  fNoAltroMapping(stream.fNoAltroMapping),
+  fIsShortDataHeader(stream.fIsShortDataHeader),
+  fDDLNumber(stream.fDDLNumber),
+  fPrevDDLNumber(stream.fPrevDDLNumber),
+  fRCUId(stream.fRCUId),
+  fPrevRCUId(stream.fPrevRCUId),
+  fHWAddress(stream.fHWAddress),
+  fPrevHWAddress(stream.fPrevHWAddress),
+  fTime(stream.fTime),
+  fPrevTime(stream.fPrevTime),
+  fSignal(stream.fSignal),
+  fTimeBunch(stream.fTimeBunch),
+  fRawReader(stream.fRawReader),
+  fData(stream.fData),
+  fPosition(stream.fPosition),
+  fCount(stream.fCount),
+  fBunchLength(stream.fBunchLength),
+  fRCUTrailerData(stream.fRCUTrailerData),
+  fRCUTrailerSize(stream.fRCUTrailerSize),
+  fFECERRA(stream.fFECERRA),
+  fFECERRB(stream.fFECERRB),
+  fERRREG2(stream.fERRREG2),
+  fERRREG3(stream.fERRREG3),
+  fERRREG4(stream.fERRREG4),
+  fActiveFECsA(stream.fActiveFECsA),
+  fActiveFECsB(stream.fActiveFECsB),
+  fAltroCFG1(stream.fAltroCFG1),
+  fAltroCFG2(stream.fAltroCFG2)
 {
-  Fatal("AliAltroRawStream", "copy constructor not implemented");
+  fSegmentation[0]   = stream.fSegmentation[0];
+  fSegmentation[1]   = stream.fSegmentation[1];
+  fSegmentation[2]   = stream.fSegmentation[2];
 }
 
 //_____________________________________________________________________________
-AliAltroRawStream& AliAltroRawStream::operator = (const AliAltroRawStream& 
-                                             /* stream */)
+AliAltroRawStream& AliAltroRawStream::operator = (const AliAltroRawStream& stream)
 {
-  Fatal("operator =", "assignment operator not implemented");
+  if(&stream == this) return *this;
+
+  fNoAltroMapping    = stream.fNoAltroMapping;
+  fIsShortDataHeader = stream.fIsShortDataHeader;
+  fDDLNumber         = stream.fDDLNumber;
+  fPrevDDLNumber     = stream.fPrevDDLNumber;
+  fRCUId             = stream.fRCUId;
+  fPrevRCUId         = stream.fPrevRCUId;
+  fHWAddress         = stream.fHWAddress;
+  fPrevHWAddress     = stream.fPrevHWAddress;
+  fTime              = stream.fTime;
+  fPrevTime          = stream.fPrevTime;
+  fSignal            = stream.fSignal;
+  fTimeBunch         = stream.fTimeBunch;
+  fRawReader         = stream.fRawReader;
+  fData              = stream.fData;
+  fPosition          = stream.fPosition;
+  fCount             = stream.fCount;
+  fBunchLength       = stream.fBunchLength;
+  fRCUTrailerData    = stream.fRCUTrailerData;
+  fRCUTrailerSize    = stream.fRCUTrailerSize;
+  fFECERRA           = stream.fFECERRA;
+  fFECERRB           = stream.fFECERRB;
+  fERRREG2           = stream.fERRREG2;
+  fERRREG3           = stream.fERRREG3;
+  fERRREG4           = stream.fERRREG4;
+  fActiveFECsA       = stream.fActiveFECsA;
+  fActiveFECsB       = stream.fActiveFECsB;
+  fAltroCFG1         = stream.fAltroCFG1;
+  fAltroCFG2         = stream.fAltroCFG2;
+
+  fSegmentation[0]   = stream.fSegmentation[0];
+  fSegmentation[1]   = stream.fSegmentation[1];
+  fSegmentation[2]   = stream.fSegmentation[2];
+
   return *this;
 }
 
@@ -108,6 +163,8 @@ void AliAltroRawStream::Reset()
   fRCUTrailerData = NULL;
   fRCUTrailerSize = 0;
 
+  fFECERRA = fFECERRB = fERRREG2 = fERRREG3 = fERRREG4 = fActiveFECsA = fActiveFECsB = fAltroCFG1 = fAltroCFG2 = 0;
+
   fDDLNumber = fPrevDDLNumber = fRCUId = fPrevRCUId = fHWAddress = fPrevHWAddress = fTime = fPrevTime = fSignal = fTimeBunch = -1;
 
   if (fRawReader) fRawReader->Reset();
@@ -127,7 +184,7 @@ Bool_t AliAltroRawStream::Next()
   fPrevTime = fTime;
 
   while (fCount == 0) {  // next trailer
-    if (fPosition <= 0) {  // next payload
+    while (fPosition <= 0) {  // next payload
       do {
        if (!fRawReader->ReadNextData(fData)) return kFALSE;
       } while (fRawReader->GetDataSize() == 0);
@@ -137,8 +194,7 @@ Bool_t AliAltroRawStream::Next()
       fPosition = GetPosition();
     }
 
-    if (!ReadTrailer())
-      AliFatal("Incorrect trailer information !");
+    ReadTrailer();
 
     fBunchLength = 0;
   }
@@ -160,6 +216,15 @@ void AliAltroRawStream::SelectRawData(Int_t detId)
   fRawReader->Select(detId);
 }
 
+//_____________________________________________________________________________
+void AliAltroRawStream::SelectRawData(const char *detName)
+{
+  // Select the raw data for specific
+  // detector name
+  AliDebug(1,Form("Selecting raw data for detector %s",detName));
+  fRawReader->Select(detName);
+}
+
 //_____________________________________________________________________________
 UShort_t AliAltroRawStream::GetNextWord()
 {
@@ -194,24 +259,57 @@ Bool_t AliAltroRawStream::ReadTrailer()
   UShort_t temp;
   Int_t nFillWords = 0;
   while ((temp = GetNextWord()) == 0x2AA) nFillWords++;
-  if (nFillWords == 0)
-    AliFatal("Incorrect trailer found ! Expected 0x2AA not found !");
+  if (nFillWords == 0) {
+    fRawReader->AddMajorErrorLog(kAltroTrailerErr,"no 0x2AA");
+    //    PrintDebug();
+    AliWarning(Form("Incorrect trailer found ! Expected 0x2AA not found (0x%x != 0x2AA) ! Current position %d, DDL=%d",
+                   temp,fPosition,fDDLNumber));
+    // trying to recover and find the next bunch
+    while ((fPosition > 2) && (temp != 0x2AA)) temp = GetNextWord();
+    if (temp != 0x2AA) {
+      fCount = fPosition = 0;
+      return kFALSE;
+    }
+    temp = GetNextWord();
+  }
 
   //Then read the trailer
-  if (fPosition <= 4)
-    AliFatal(Form("Incorrect raw data size ! Expected at lest 4 words but found %d !",fPosition));
+  if (fPosition < 2) {
+    fRawReader->AddMajorErrorLog(kAltroTrailerErr,Form("size %d < 5",
+                                                      fPosition));
+    //    PrintDebug();
+    AliWarning(Form("Incorrect raw data size ! Expected at least 5 words but found %d !",fPosition));
+    fCount = fPosition = 0;
+    return kFALSE;
+  }
 
   fCount = (temp << 4) & 0x3FF;
-  if ((temp >> 6) != 0xA)
-    AliFatal(Form("Incorrect trailer found ! Expecting 0xA but found %x !",temp >> 6));
+  if ((temp >> 6) != 0xA) {
+    fRawReader->AddMajorErrorLog(kAltroTrailerErr,"no 0xA");
+    //    PrintDebug();
+    AliWarning(Form("Incorrect trailer found ! Expecting 0xA but found 0x%x !",temp >> 6));
+    fCount = 0;
+    return kFALSE;
+  }
 
   temp = GetNextWord();
   fHWAddress = (temp & 0x3) << 10;
-  if (((temp >> 2) & 0xF) != 0xA)
-    AliFatal(Form("Incorrect trailer found ! Expecting second 0xA but found %x !",(temp >> 2) & 0xF));
+  if (((temp >> 2) & 0xF) != 0xA) {
+    fRawReader->AddMajorErrorLog(kAltroTrailerErr,"no second 0xA");
+    //    PrintDebug();
+    AliWarning(Form("Incorrect trailer found ! Expecting second 0xA but found 0x%x !",(temp >> 2) & 0xF));
+    fCount = 0;
+    return kFALSE;
+  }
   fCount |= ((temp & 0x3FF) >> 6);
-  if (fCount == 0) return kFALSE;
 
+  if (fCount >= fPosition) {
+    fRawReader->AddMajorErrorLog(kAltroTrailerErr,"invalid size");
+    //    PrintDebug();
+    AliWarning(Form("Incorrect trailer found ! The altro payload size is invalid (%d >= %d) !",fCount,fPosition));
+    fCount = 0;
+    return kFALSE;
+  }
   temp = GetNextWord();
   fHWAddress |= temp;
 
@@ -245,16 +343,25 @@ void AliAltroRawStream::ReadBunch()
 {
   // Read altro payload in 
   // backward direction
-  if (fPosition <= 0)
-    AliFatal("Could not read bunch length !");
+  if (fCount <= 2) {
+    fRawReader->AddMinorErrorLog(kBunchLengthReadErr,"");
+    //    PrintDebug();
+    AliWarning(Form("Could not read bunch length and time bin ! Only %d 10-bit words are left !",fCount));
+    fBunchLength = fTimeBunch = fCount = 0;
+    return;
+  }
 
   fBunchLength = GetNextWord() - 2;
+  if (fBunchLength > fCount) {
+    fRawReader->AddMinorErrorLog(kBunchLengthReadErr,Form("bl=%d",fBunchLength));
+    //    PrintDebug();
+    AliWarning(Form("Could not read bunch length ! Bunch length = %d (>%d)",fBunchLength,fCount));
+    fBunchLength = fTimeBunch = fCount = 0;
+    return;
+  }
   fTimeBunch = fBunchLength;
   fCount--;
 
-  if (fPosition <= 0)
-    AliFatal("Could not read time bin !");
-
   fTime = GetNextWord();
   fCount--;
 
@@ -265,10 +372,16 @@ void AliAltroRawStream::ReadBunch()
 void AliAltroRawStream::ReadAmplitude()
 {
   // Read next time bin amplitude
-  if (fPosition <= 0)
-    AliFatal("Could not read sample amplitude !");
+  if (fCount <= 0) {
+    fRawReader->AddMinorErrorLog(kAmplitudeReadErr,"");
+    //    PrintDebug();
+    AliWarning("Could not read sample amplitude !");
+    fCount = fSignal = fBunchLength = 0;
+    return;
+  }
 
   fSignal = GetNextWord();
+
   fCount--;
   fBunchLength--;
 
@@ -286,37 +399,120 @@ Int_t AliAltroRawStream::GetPosition()
   // The RCU trailer format is described
   // in details in the RCU manual.
 
-  // First read 32-bit word with the
-  // trailer size (22 bits) and RCU ID (the rest)
+  // We use the last word of the payload
+  // in order to decide which RCU firmware
+  // was used during the data taking.
+  // The firmware v2 adds 0xAAAA as 16
+  // most significant bits and since the
+  // payload size (firmware v1) can not be
+  // that big, we use this as a unique
+  // label of the firmware version.
+
   Int_t index = fRawReader->GetDataSize();
   UInt_t word = Get32bitWord(index);
-  fRCUId = (Int_t)(word >> 22);
-  Int_t trailerSize = (word & 0x3FFFFF);
-
-  // Now read the beginning of the trailer
-  // where the payload size is written
-  if (trailerSize < 2)
-    AliFatal(Form("Invalid trailer size found (%d bytes) !",trailerSize*4));
-  fRCUTrailerSize = (trailerSize-2)*4;
-  index -= fRCUTrailerSize;
-  if (index < 4)
-    AliFatal(Form("Invalid trailer size found (%d bytes) ! The size is bigger than the raw data size (%d bytes)!",
-                 trailerSize*4,
-                 fRawReader->GetDataSize()));
-  fRCUTrailerData = fData + index;
-  Int_t position = Get32bitWord(index);
-  // The size is specified in a number of 40bits
-  // Therefore we need to transform it to number of bytes
-  position *= 5;
-
-  // Check the consistency of the header and trailer
-  if ((fRawReader->GetDataSize() - trailerSize*4) != position)
-    AliFatal(Form("Inconsistent raw data size ! Raw data size - %d bytes (from the header), RCU trailer - %d bytes, raw data paylod - %d bytes !",
-                 fRawReader->GetDataSize(),
-                 trailerSize*4,
-                 position));
-
-  return position * 8 / 10;
+  if (((word >> 16) == 0xaaaa) || (word == 2)) {
+    // This is RCU formware v2
+    // The statement word==2 is needed only temporary
+    // in order to be able to read previously generated
+    // aliroot raw data
+
+    Int_t trailerSize = 0;
+    if (word == 2) {
+      AliInfo("Old simulated raw data is assumed!");
+      trailerSize = 2;
+      fRCUId = 0;
+    }
+    else {
+      // First read 32-bit word with the
+      // trailer size (7 bits), RCU ID (9 bits) and
+      // 0xAAA (the rest - 16 bits)
+      fRCUId = (Int_t)((word >> 7) & 0x1ff);
+      trailerSize = (word & 0x7F);
+    }
+
+    // Now read the beginning of the trailer
+    // where the payload size is written
+    if (trailerSize < 2) {
+      fRawReader->AddMajorErrorLog(kRCUTrailerErr,Form("tr=%d bytes",
+                                                      trailerSize*4));
+      AliWarning(Form("Invalid trailer size found (%d bytes) !",
+                     trailerSize*4));
+    }
+
+    Int_t position = ReadRCUTrailer(index,trailerSize);
+    // The size is specified in a number of 40bits
+    // Therefore we need to transform it to number of bytes
+    position *= 5;
+
+    // Check the consistency of the header and trailer
+    if (((fRawReader->GetDataSize() - trailerSize*4) < position) ||
+       ((fRawReader->GetDataSize() - trailerSize*4) >= (position + 4))) {
+      fRawReader->AddMajorErrorLog(kRCUTrailerSizeErr,Form("h=%d tr=%d rcu=%d bytes",
+                                                          fRawReader->GetDataSize(),
+                                                          trailerSize*4,
+                                                          position));
+      AliWarning(Form("Inconsistent raw data size ! Raw data size - %d bytes (from the header), RCU trailer - %d bytes, raw data paylod - %d bytes !",
+                   fRawReader->GetDataSize(),
+                   trailerSize*4,
+                   position));
+      position = fRawReader->GetDataSize() - trailerSize*4;
+    }
+
+    return position * 8 / 10;
+  }
+  else {
+    // In case of the Old RCU trailer format
+    // we have to read just the size of altro payload
+    // in units of 40-bit words
+    Int_t position = (Int_t)word;
+
+    fRCUId = -1;
+    fRCUTrailerSize = 0;
+    fRCUTrailerData = NULL;
+
+    // The size is specified in a number of 40bits
+    // Therefore we need to transform it to number of bytes
+    position *= 5;
+
+    if (!fIsShortDataHeader) {
+
+      // Check the consistency of the header and trailer
+      if (((fRawReader->GetDataSize() - 4) < position) ||
+          ((fRawReader->GetDataSize() - 4) >= (position + 4))) {
+       fRawReader->AddMajorErrorLog(kRCUTrailerSizeErr,Form("h=%d rcu=%d bytes",
+                                                            fRawReader->GetDataSize()-4,
+                                                            position));
+       //      PrintDebug();
+       AliWarning(Form("Inconsistent raw data size ! Expected %d bytes (from the header), found %d bytes (in the RCU trailer)!",
+                       fRawReader->GetDataSize()-4,
+                       position));
+       position = fRawReader->GetDataSize()-4;
+      }
+    }
+    else {
+      // Check the consistency of the header and trailer
+      // In this case the header is shorter by 4 bytes
+      if ((fRawReader->GetDataSize() < position) ||
+          (fRawReader->GetDataSize() >= (position + 4))) {
+       fRawReader->AddMajorErrorLog(kRCUTrailerSizeErr,Form("h=%d rcu=%d bytes",
+                                                            fRawReader->GetDataSize(),
+                                                            position));
+       //      PrintDebug();
+       AliWarning(Form("Inconsistent raw data size ! Expected %d bytes (from the header), found %d bytes (in the RCU trailer)!",
+                       fRawReader->GetDataSize(),
+                       position));
+       position = fRawReader->GetDataSize();
+      }
+
+      // 7 32-bit words Common Data Header
+      // therefore we have to shift back by 4 bytes
+      // the pointer to the raw data payload
+      fData -= 4;
+    }
+     
+    // Return the position in units of 10-bit words
+    return position*8/10;
+  }
 }
 
 //_____________________________________________________________________________
@@ -327,10 +523,16 @@ UInt_t AliAltroRawStream::Get32bitWord(Int_t &index)
   // The 'index' points to the beginning of the next word.
   // The method is supposed to be endian (platform)
   // independent.
-  if (!fData)
+  if (!fData) {
+    PrintDebug();
     AliFatal("Raw data paylod buffer is not yet initialized !");
-  if (index < 4)
-    AliFatal(Form("Invalid raw data payload index (%d) !",index));
+  }
+
+  if (index < 4) {
+    fRawReader->AddFatalErrorLog(k32bitWordReadErr,Form("pos = %d",index));
+    //    PrintDebug();
+    AliWarning(Form("Invalid raw data payload position (%d) !",index));
+  }
 
   UInt_t word = 0;
   word  = fData[--index] << 24;
@@ -341,6 +543,157 @@ UInt_t AliAltroRawStream::Get32bitWord(Int_t &index)
   return word;
 }
 
+//_____________________________________________________________________________
+Int_t AliAltroRawStream::ReadRCUTrailer(Int_t &index, Int_t trailerSize)
+{
+  // The method decodes the RCU trailer data
+  // according to the RCU fw ver.2 specs
+  
+  fRCUTrailerSize = trailerSize*4;
+
+  for (trailerSize -= 2; trailerSize > 0; trailerSize--) {
+    Int_t word = Get32bitWord(index);
+    Int_t parCode = word >> 26;
+    Int_t parData = word & 0x3FFFFFF;
+    switch (parCode) {
+    case 1:
+      // ERR_REG1
+      fFECERRA = ((parData >> 13) & 0x1FFF) << 7;
+      fFECERRB = ((parData & 0x1FFF)) << 7;
+      break;
+    case 2:
+      // ERR_REG2
+      fERRREG2 = parData & 0x1FF;
+      break;
+    case 3:
+      // ERR_REG3
+      fERRREG3 = parData & 0xFFF;
+      break;
+    case 4:
+      // ERR_REG4
+      fERRREG4 = parData & 0xFFF;
+      break;
+    case 5:
+      // FEC_RO_A
+      fActiveFECsA = parData & 0xFFFF;
+      break;
+    case 6:
+      // FEC_RO_B
+      fActiveFECsB = parData & 0xFFFF;
+      break;
+    case 7:
+      // RDO_CFG1
+      fAltroCFG1 = parData & 0x7FFFF;
+      break;
+    case 8:
+      // RDO_CFG2
+      fAltroCFG2 = parData & 0x1FFFFFF;
+     break;
+    default:
+      fRawReader->AddMinorErrorLog(kRCUTrailerErr,"undef word");
+      AliWarning(Form("Undefined parameter code %d, ignore it !",
+                     parCode));
+      break;
+    }
+  }
+
+  if (index < 4) {
+    fRawReader->AddMajorErrorLog(kRCUTrailerErr,Form("tr=%d raw=%d bytes",
+                                                    fRCUTrailerSize,
+                                                    fRawReader->GetDataSize()));
+    AliWarning(Form("Invalid trailer size found (%d bytes) ! The size is bigger than the raw data size (%d bytes)!",
+                   fRCUTrailerSize,
+                   fRawReader->GetDataSize()));
+  }
+  fRCUTrailerData = fData + index;
+
+  Int_t position = Get32bitWord(index);
+
+
+  return position;
+}
+
+//_____________________________________________________________________________
+Double_t AliAltroRawStream::GetTSample() const
+{
+  // Returns the sampling time
+  // in seconds. In case the rcu trailer
+  // was note read, return an invalid number (0)
+
+  if (!fRCUTrailerData) return 0.;
+
+  const Double_t kLHCTimeSample = 25.0e-9; // LHC clocks runs at 40 MHz
+  UChar_t fq = (fAltroCFG2 >> 5) & 0xF;
+  Double_t tSample;
+  switch (fq) {
+  case 0:
+    // 20 MHz
+    tSample = 2.0*kLHCTimeSample;
+    break;
+  case 1:
+    // 10 Mhz
+    tSample = 4.0*kLHCTimeSample;
+    break;
+  case 2:
+    // 5 MHz
+    tSample = 8.0*kLHCTimeSample;
+    break;
+  default:
+    AliWarning(Form("Invalid sampling frequency value %d !",
+                     fq));
+    tSample = 0.;
+    break;
+  }
+
+  return tSample;
+}
+
+//_____________________________________________________________________________
+Double_t AliAltroRawStream::GetL1Phase() const
+{
+  // Returns the L1 phase w.r.t to the
+  // LHC clock
+  if (!fRCUTrailerData) return 0.;
+
+  const Double_t kLHCTimeSample = 25.0e-9; // LHC clocks runs at 40 MHz
+  Double_t phase = ((Double_t)(fAltroCFG2 & 0x1F))*kLHCTimeSample;
+
+  Double_t tSample = GetTSample();
+  if (phase >= tSample) {
+    AliWarning(Form("Invalid L1 trigger phase (%f >= %d) !",
+                   phase,tSample));
+    phase = 0.;
+  }
+
+  return phase;
+}
+
+//_____________________________________________________________________________
+void AliAltroRawStream::PrintRCUTrailer() const
+{
+  // Prints the contents of
+  // the RCU trailer data
+  printf("RCU trailer:\n===========\n");
+  printf("FECERRA: 0x%x\nFECERRB: 0x%x\n",fFECERRA,fFECERRB);
+  printf("ERRREG2: 0x%x\n",fERRREG2);
+  printf("#channels skipped due to address mismatch: %d\n",GetNChAddrMismatch());
+  printf("#channels skipped due to bad block length: %d\n",GetNChLengthMismatch());
+  printf("Active FECs (branch A): 0x%x\nActive FECs (branch B): 0x%x\n",fActiveFECsA,fActiveFECsB);
+  printf("Baseline corr: 0x%x\n",GetBaselineCorr());
+  printf("Number of presamples: %d\nNumber of postsamples: %d\n",GetNPresamples(),GetNPostsamples());
+  printf("Second baseline corr: %d\n",GetSecondBaselineCorr());
+  printf("GlitchFilter: %d\n",GetGlitchFilter());
+  printf("Number of non-ZS postsamples: %d\nNumber of non-ZS presamples: %d\n",GetNNonZSPostsamples(),GetNNonZSPresamples());
+  printf("Number of ALTRO buffers: %d\n",GetNAltroBuffers());
+  printf("Number of pretrigger samples: %d\n",GetNPretriggerSamples());
+  printf("Number of samples per channel: %d\n",GetNSamplesPerCh());
+  printf("Sparse readout: %d\n",GetSparseRO());
+  printf("Sampling time: %e s\n",GetTSample());
+  printf("L1 Phase: %e s\n",GetL1Phase());
+  printf("AltroCFG1: 0x%x\nAltroCFG2: 0x%x\n",GetAltroCFG1(),GetAltroCFG2());
+  printf("===========\n");
+}
+
 //_____________________________________________________________________________
 Bool_t AliAltroRawStream::GetRCUTrailerData(UChar_t*& data) const
 {
@@ -358,3 +711,76 @@ Bool_t AliAltroRawStream::GetRCUTrailerData(UChar_t*& data) const
 
   return kTRUE;
 }
+
+//_____________________________________________________________________________
+void AliAltroRawStream::PrintDebug() const
+{
+  // The method prints all the available
+  // debug information.
+  // Its is used in case of decoding errors.
+
+  AliError("Start of debug printout\n--------------------");
+
+  Dump();
+  if (fRawReader) fRawReader->Dump();
+
+  AliError("End of debug printout\n--------------------");
+}
+
+//_____________________________________________________________________________
+Int_t AliAltroRawStream::GetBranch() const
+{
+  // The method provides the RCU branch index (0 or 1)
+  // for the current hardware address.
+  // In case the hardware address has not been yet
+  // initialized, the method returns -1
+  if (fHWAddress == -1) return -1;
+
+  return ((fHWAddress >> 11) & 0x1);
+}
+
+//_____________________________________________________________________________
+Int_t AliAltroRawStream::GetFEC() const
+{
+  // The method provides the front-end card index
+  // for the current hardware address.
+  // In case the hardware address has not been yet
+  // initialized, the method returns -1
+  if (fHWAddress == -1) return -1;
+
+  return ((fHWAddress >> 7) & 0xF);
+}
+
+//_____________________________________________________________________________
+Int_t AliAltroRawStream::GetAltro() const
+{
+  // The method provides the altro chip index
+  // for the current hardware address.
+  // In case the hardware address has not been yet
+  // initialized, the method returns -1
+  if (fHWAddress == -1) return -1;
+
+  return ((fHWAddress >> 4) & 0x7);
+}
+
+//_____________________________________________________________________________
+Int_t AliAltroRawStream::GetChannel() const
+{
+  // The method provides the channel index
+  // for the current hardware address.
+  // In case the hardware address has not been yet
+  // initialized, the method returns -1
+  if (fHWAddress == -1) return -1;
+
+  return (fHWAddress & 0xF);
+}
+
+//_____________________________________________________________________________
+void AliAltroRawStream::AddMappingErrorLog(const char *message)
+{
+  // Signal a mapping error
+  // The method can be used by the TPC,PHOS,EMCAL,FMD raw stream
+  // classes in order to log an error related to bad altro mapping
+
+  if (fRawReader) fRawReader->AddMinorErrorLog(kBadAltroMapping,message);
+}