]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - HLT/TPCLib/AliHLTTPCDigitReaderRaw.cxx
bugfix: corrected buffer size check
[u/mrichter/AliRoot.git] / HLT / TPCLib / AliHLTTPCDigitReaderRaw.cxx
index 546625401107f95415753e5eb4d12665eb8938f3..ca7c672c24697f47c7e92509b84eb152b142b0fc 100644 (file)
@@ -1,12 +1,13 @@
 // $Id$
 
 /**************************************************************************
- * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * This file is property of and copyright by the ALICE HLT Project        * 
+ * ALICE Experiment at CERN, All rights reserved.                         *
  *                                                                        *
- * Authors: Matthias Richter <Matthias.Richter@ift.uib.no>                *
- *          Timm Steinbeck <timm@kip.uni-heidelberg.de>                   *
- *          Jochen Thaeder <thaeder@kip.uni-heidelberg.de>                *
- *          for The ALICE Off-line Project.                               *
+ * Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
+ *                  Timm Steinbeck <timm@kip.uni-heidelberg.de>           *
+ *                  Jochen Thaeder <thaeder@kip.uni-heidelberg.de>        *
+ *                  for The ALICE HLT Project.                            *
  *                                                                        *
  * Permission to use, copy, modify and distribute this software and its   *
  * documentation strictly for non-commercial purposes is hereby granted   *
@@ -27,8 +28,6 @@
 using namespace std;
 #endif
 
-#if defined(HAVE_TPC_MAPPING)
-
 #include "AliHLTTPCDigitReaderRaw.h"
 #include "AliHLTTPCTransform.h"
 #include "AliHLTTPCRootTypes.h"
@@ -43,21 +42,46 @@ AliHLTTPCDigitReaderRaw::AliHLTTPCDigitReaderRaw( unsigned formatVersion )
   fBufferSize(0),
   fPatch(-1),
   fSlice(-1),
+  fRow(-1),
+  fPad(-1),
+  fAltroBlockPositionBytes(0),
+  fAltroBlockLengthBytes(0),
+  fAltroBlockHWAddress(0),
+  fAltroBlock10BitWordCnt(0),
+  fAltroBlock10BitFillWordCnt(0),
   fDataFormatVersion(formatVersion),
+  fBunchPosition(0xFFFFU),
+  fBunchTimebinStart(~0U),
+  fBunchLength(0),
+  fWordInBunch((unsigned)-1),
+  fVerify(false),
+  
   fCurrentRow(0),
   fCurrentPad(0),
   fCurrentBin(-1),
-  fVerify(false),
-  
-  // For sorting
-  fNRows(0),
   fRowOffset(0),
+  fNRows(0),
   fNMaxRows(0),
   fNMaxPads(0),
   fNTimeBins(0),
-  fData(NULL)
+  fData(NULL),
+  fMapErrThrown(0)
 {
-    if ( fDataFormatVersion==0 || fDataFormatVersion==2 )
+  // see header file for class documentation
+  // or
+  // refer to README to build package
+  // or
+  // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
+#ifndef HAVE_TPC_MAPPING
+  memset(fgMapping0, 0, fgkMapping0Size*fgkMappingDimension*sizeof(Int_t));
+  memset(fgMapping1, 0, fgkMapping1Size*fgkMappingDimension*sizeof(Int_t));
+  memset(fgMapping2, 0, fgkMapping2Size*fgkMappingDimension*sizeof(Int_t));
+  memset(fgMapping3, 0, fgkMapping3Size*fgkMappingDimension*sizeof(Int_t));
+  memset(fgMapping4, 0, fgkMapping4Size*fgkMappingDimension*sizeof(Int_t));
+  memset(fgMapping5, 0, fgkMapping5Size*fgkMappingDimension*sizeof(Int_t));
+#endif //#ifndef HAVE_TPC_MAPPING
+
+    if ( fDataFormatVersion==0 || fDataFormatVersion==2 || fDataFormatVersion==4 )
       {
        
        // get max number of rows
@@ -73,62 +97,18 @@ AliHLTTPCDigitReaderRaw::AliHLTTPCDigitReaderRaw( unsigned formatVersion )
        // get max number of bins
        fNTimeBins = AliHLTTPCTransform::GetNTimeBins();
        
-       HLTDebug("Array Borders ||| MAXPAD=%d ||| MAXROW=%d ||| MAXBIN=%d ||| MAXMUL=%d", 
-                fNMaxPads, fNMaxRows, fNTimeBins, fNTimeBins*fNMaxRows*fNMaxPads);
+       //      HLTDebug("Array Borders ||| MAXPAD=%d ||| MAXROW=%d ||| MAXBIN=%d ||| MAXMUL=%d", 
+       //       fNMaxPads, fNMaxRows, fNTimeBins, fNTimeBins*fNMaxRows*fNMaxPads);
        
        // init Data array
        fData = new Int_t[ fNMaxRows*fNMaxPads*fNTimeBins ];
       }
 }
 
-AliHLTTPCDigitReaderRaw::AliHLTTPCDigitReaderRaw(const AliHLTTPCDigitReaderRaw& src)
-  :
-  fBuffer(NULL),
-  fBufferSize(0),
-  fPatch(-1),
-  fSlice(-1),
-  fDataFormatVersion(src.fDataFormatVersion),
-  fCurrentRow(0),
-  fCurrentPad(0),
-  fCurrentBin(-1),
-  fVerify(false),
-  
-  // For sorting
-  fNRows(0),
-  fRowOffset(0),
-  fNMaxRows(0),
-  fNMaxPads(0),
-  fNTimeBins(0),
-  fData(NULL)
-{
-  HLTFatal("copy constructor not for use");
-}
-
-AliHLTTPCDigitReaderRaw& AliHLTTPCDigitReaderRaw::operator=(const AliHLTTPCDigitReaderRaw& src)
+AliHLTTPCDigitReaderRaw::~AliHLTTPCDigitReaderRaw()
 {
-  fBuffer=NULL;
-  fBufferSize=0;
-  fPatch=-1;
-  fSlice=-1;
-  fDataFormatVersion=src.fDataFormatVersion;
-  fCurrentRow=0;
-  fCurrentPad=0;
-  fCurrentBin=-1;
-  fVerify=false;
-  
-  // For sorting
-  fNRows=0;
-  fRowOffset=0;
-  fNMaxRows=0;
-  fNMaxPads=0;
-  fNTimeBins=0;
-  fData=NULL;
-  HLTFatal("assignment operator not for use");
-  return (*this);
-}
-
-AliHLTTPCDigitReaderRaw::~AliHLTTPCDigitReaderRaw(){
-  if ( fDataFormatVersion==0 || fDataFormatVersion==2 )
+  // see header file for class documentation
+  if ( fDataFormatVersion==0 || fDataFormatVersion==2 || fDataFormatVersion==4 )
     {
       if ( fData )
        delete [] fData;
@@ -136,11 +116,15 @@ AliHLTTPCDigitReaderRaw::~AliHLTTPCDigitReaderRaw(){
     }
 }
 
-int AliHLTTPCDigitReaderRaw::InitBlock(void* ptr,unsigned long size,Int_t firstrow,Int_t lastrow, Int_t patch, Int_t slice) {
+int AliHLTTPCDigitReaderRaw::InitBlock(void* ptr,unsigned long size,Int_t firstrow,Int_t lastrow, Int_t patch, Int_t slice) 
+{
+  // see header file for class documentation
   return AliHLTTPCDigitReader::InitBlock(ptr, size, firstrow, lastrow, patch, slice);
 }
 
-int AliHLTTPCDigitReaderRaw::InitBlock(void* ptr,unsigned long size, Int_t patch, Int_t slice){
+int AliHLTTPCDigitReaderRaw::InitBlock(void* ptr,unsigned long size, Int_t patch, Int_t slice)
+{
+  // see header file for class documentation
 
     fBuffer = (AliHLTUInt8_t*) ptr;
     if (fBuffer==NULL) {
@@ -166,7 +150,7 @@ int AliHLTTPCDigitReaderRaw::InitBlock(void* ptr,unsigned long size, Int_t patch
     Int_t firstrow=AliHLTTPCTransform::GetFirstRow(patch);
     Int_t lastrow=AliHLTTPCTransform::GetLastRow(patch);
 
-    if ( fDataFormatVersion==0 || fDataFormatVersion==2 )
+    if ( fDataFormatVersion==0 || fDataFormatVersion==2 || fDataFormatVersion==4 )
       {
        fCurrentRow = 0;
        fCurrentPad = 0;
@@ -184,7 +168,7 @@ int AliHLTTPCDigitReaderRaw::InitBlock(void* ptr,unsigned long size, Int_t patch
        // Init array with -1
        memset( fData, 0xFF, sizeof(Int_t)*(fNMaxRows*fNMaxPads*fNTimeBins) );
 
-       const Int_t maxErrorPrintout=20;
+       const Int_t kMaxErrorPrintout=20;
        Int_t errorCount=0;
        Int_t entryCount=0;
        // read data and fill in array
@@ -200,7 +184,7 @@ int AliHLTTPCDigitReaderRaw::InitBlock(void* ptr,unsigned long size, Int_t patch
 
          if ( row < firstrow || row > lastrow || pad > AliHLTTPCTransform::GetNPads(row + offset) || bin > fNTimeBins || pad<0 || bin<0){
 //       if ( row < firstrow || row > lastrow || pad > AliHLTTPCTransform::GetNPads(row + offset) || bin > fNTimeBins){
-           if (errorCount++<maxErrorPrintout) {
+           if (errorCount++<kMaxErrorPrintout) {
              HLTFatal("Index out of range. Probably wrong patch! slice %d - patch %d", slice, patch);
              HLTFatal("PAD=%d out of %d ||| ROW=%d (%d to %d)  ||| BIN=%d out of %d  ||| OFFSET=%d ||| ROWOFFSET=%d",
                       pad, AliHLTTPCTransform::GetNPads(row + offset), row, firstrow, lastrow, bin, fNTimeBins,
@@ -218,7 +202,7 @@ int AliHLTTPCDigitReaderRaw::InitBlock(void* ptr,unsigned long size, Int_t patch
            //continue;
            break;
          } else if ((row-fRowOffset)*fNMaxPads*fNTimeBins+ pad*fNTimeBins + bin >=  fNMaxRows*fNMaxPads*fNTimeBins ) {
-           if (errorCount++<maxErrorPrintout) {
+           if (errorCount++<kMaxErrorPrintout) {
              HLTFatal("index out of range: PAD=%d ||| ROW=%d ||| BIN=%d ||| OFFSET=%d ||| ROWOFFSET=%d", pad, row, bin, offset, fRowOffset);
            }
            // stop at the fist error message in order to avoid endless messages and
@@ -237,8 +221,11 @@ int AliHLTTPCDigitReaderRaw::InitBlock(void* ptr,unsigned long size, Int_t patch
     return 0;
 }
 
-bool AliHLTTPCDigitReaderRaw::Next(){
-  if ( fDataFormatVersion==0 || fDataFormatVersion==2 )
+bool AliHLTTPCDigitReaderRaw::Next()
+{
+  // see header file for class documentation
+
+  if ( fDataFormatVersion==0 || fDataFormatVersion==2 || fDataFormatVersion==4 )
     {
       Bool_t readvalue = kTRUE;
       while (1) {
@@ -272,32 +259,47 @@ bool AliHLTTPCDigitReaderRaw::Next(){
     return RealNext();
 }
 
-int AliHLTTPCDigitReaderRaw::GetRow(){
-  if ( fDataFormatVersion==0 || fDataFormatVersion==2 )
+int AliHLTTPCDigitReaderRaw::GetRow()
+{
+  // see header file for class documentation
+
+  if ( fDataFormatVersion==0 || fDataFormatVersion==2 || fDataFormatVersion==4 )
     {
       return (fCurrentRow + fRowOffset);
     }
   else
     return GetRealRow();
 }
-int AliHLTTPCDigitReaderRaw::GetPad(){
-  if ( fDataFormatVersion==0 || fDataFormatVersion==2 )
+
+int AliHLTTPCDigitReaderRaw::GetPad()
+{
+  // see header file for class documentation
+
+  if ( fDataFormatVersion==0 || fDataFormatVersion==2 || fDataFormatVersion==4 )
     {
       return fCurrentPad;
     }
   else
     return GetRealPad();
 }
-int AliHLTTPCDigitReaderRaw::GetSignal(){
-  if ( fDataFormatVersion==0 || fDataFormatVersion==2 )
+
+int AliHLTTPCDigitReaderRaw::GetSignal()
+{
+  // see header file for class documentation
+
+  if ( fDataFormatVersion==0 || fDataFormatVersion==2 || fDataFormatVersion==4 )
     {
       return fData[ fCurrentRow*fNMaxPads*fNTimeBins+ fCurrentPad*fNTimeBins + fCurrentBin ];
     }
   else
     return GetRealSignal();
 }
-int AliHLTTPCDigitReaderRaw::GetTime(){
-  if ( fDataFormatVersion==0 || fDataFormatVersion==2 )
+
+int AliHLTTPCDigitReaderRaw::GetTime()
+{
+  // see header file for class documentation
+
+  if ( fDataFormatVersion==0 || fDataFormatVersion==2 || fDataFormatVersion==4 )
     {
       return fCurrentBin;
     }
@@ -305,8 +307,10 @@ int AliHLTTPCDigitReaderRaw::GetTime(){
     return GetRealTime();
 }
 
+bool AliHLTTPCDigitReaderRaw::RealNext()
+{
+  // see header file for class documentation
 
-bool AliHLTTPCDigitReaderRaw::RealNext(){
 //    printf( "%u %u %u %u %u\n", fBunchPosition, fBunchLength, fBunchTimebinStart, fWordInBunch, (unsigned)fAltroBlock10BitWordCnt );
     fWordInBunch++; // use next word in bunch
     if ( fWordInBunch==fBunchLength ) { // we have a bunch at all but have reached its end (or do not have an altro block yet)
@@ -325,33 +329,51 @@ bool AliHLTTPCDigitReaderRaw::RealNext(){
     //HLTDebug( "%u %u %u %u %u\n", fBunchPosition, fBunchLength, fBunchTimebinStart, fWordInBunch, (unsigned)fAltroBlock10BitWordCnt );
     return true;
 }
-int AliHLTTPCDigitReaderRaw::GetRealRow(){
+
+int AliHLTTPCDigitReaderRaw::GetRealRow() const
+{
+  // see header file for class documentation
     return fRow;
 }
-int AliHLTTPCDigitReaderRaw::GetRealPad(){
+
+int AliHLTTPCDigitReaderRaw::GetRealPad() const
+{
+  // see header file for class documentation
     return fPad;
 }
-int AliHLTTPCDigitReaderRaw::GetRealSignal(){
+
+int AliHLTTPCDigitReaderRaw::GetRealSignal()
+{
+  // see header file for class documentation
     return GetAltroBlock10BitWord( fBunchPosition+fWordInBunch );
 }
-int AliHLTTPCDigitReaderRaw::GetRealTime(){
+
+int AliHLTTPCDigitReaderRaw::GetRealTime() const
+{
+  // see header file for class documentation
   //HLTDebug( "GetRealTime: %u - %u\n", fBunchTimebinStart, fWordInBunch );
     return fBunchTimebinStart-(fWordInBunch-2);
 }
 
-AliHLTUInt32_t AliHLTTPCDigitReaderRaw::GetRCUTrailer(){
+AliHLTUInt32_t AliHLTTPCDigitReaderRaw::GetRCUTrailer( unsigned offset ) const
+{
+  // see header file for class documentation
   if (fBufferSize<=0) return 0;
   unsigned rcuDataBlockLen = GetRCUDataBlockLength(); 
-  return *((AliHLTUInt32_t*)(fBuffer+fBufferSize-rcuDataBlockLen));
+  if ( offset >= rcuDataBlockLen ) return 0;
+  return ((AliHLTUInt32_t*)(fBuffer+fBufferSize-rcuDataBlockLen))[offset];
 }
 
 bool AliHLTTPCDigitReaderRaw::NextAltroBlock()
-    {
-    if (fBufferSize<=0) return 0;
+{
+  // see header file for class documentation
+    if (fBufferSize<=32) return 0;
+    bool first = false;
     if ( !fAltroBlockLengthBytes )
        {
        // First block in back linked list (last block in memory)
        fAltroBlockPositionBytes = fBufferSize-GetRCUDataBlockLength();
+       first = true;
        }
     else
        {
@@ -365,7 +387,19 @@ bool AliHLTTPCDigitReaderRaw::NextAltroBlock()
        }
 
       AliHLTUInt64_t altroTrailerWord = GetAltroBlock40BitWord( 0 );
+      // Undefined hack from experience to match fill words appearing in simulated data
+      // Seem to be between 0 and 3 fill words, most likely to bring the number of 40bit words
+      // to a multiple of four / to bring the total number of bytes to a common multiple of 4 and 5.
+      // (RCU sends 40 bit (5 byte) words, DDL uses 32 bit (4 bytes) words.
+      unsigned short tmpCnt=0;
+      //HLTDebug( "Altro trailer word 0: 0x%016LX\n", altroTrailerWord );
+      while ( first && altroTrailerWord==0x000000AAAAAAAAAAULL && tmpCnt++<4 ) // Allow up to 4 fill values
+       {
+         altroTrailerWord = GetAltroBlock40BitWord( tmpCnt );
+         //HLTDebug( "Altro trailer word %hu: 0x%016LX\n", tmpCnt, altroTrailerWord );
+       }
 
+      fAltroBlockPositionBytes -= 5*tmpCnt;
       if ( fVerify && ((altroTrailerWord & 0xFFFC000000ULL)!=0xAAA8000000ULL) )
        {
          HLTFatal("Data inconsistency in Altro Block at byte position %#x (%d): Expected 0x2AAA in high 14 bits of altro trailer word; Found %#llx (%#llx)",
@@ -391,7 +425,7 @@ bool AliHLTTPCDigitReaderRaw::NextAltroBlock()
       if (!ApplyMapping())
        {
          HLTFatal("Mapping failed Patch %d HWA %#x (%d) - maxHWA %#x (%d)",
-                  fPatch, fAltroBlockHWAddress, fAltroBlockHWAddress, fMaxHWA[fPatch], fMaxHWA[fPatch]);
+                  fPatch, fAltroBlockHWAddress, fAltroBlockHWAddress, fgMaxHWA[fPatch], fgMaxHWA[fPatch]);
 
        }
 
@@ -418,15 +452,23 @@ bool AliHLTTPCDigitReaderRaw::NextAltroBlock()
          }
       }
     return true;
-    }
+}
 
-AliHLTUInt32_t AliHLTTPCDigitReaderRaw::GetAltroBlockHWaddr(){
-return fAltroBlockHWAddress;
+AliHLTUInt32_t AliHLTTPCDigitReaderRaw::GetAltroBlockHWaddr() const
+{
+  // see header file for class documentation
+  return fAltroBlockHWAddress;
 }
-unsigned AliHLTTPCDigitReaderRaw::GetAltroBlock10BitWordCnt(){
-return fAltroBlock10BitWordCnt;
+
+unsigned AliHLTTPCDigitReaderRaw::GetAltroBlock10BitWordCnt() const
+{
+  // see header file for class documentation
+  return fAltroBlock10BitWordCnt;
 }
-AliHLTUInt64_t AliHLTTPCDigitReaderRaw::GetAltroBlock40BitWord( unsigned long ndx ){
+
+AliHLTUInt64_t AliHLTTPCDigitReaderRaw::GetAltroBlock40BitWord( unsigned long ndx ) const
+{
+  // see header file for class documentation
 AliHLTUInt64_t val=0;
 unsigned wordOffset32Bit = (ndx / 4)*5;
 switch ( ndx % 4 ) // 40 bit word index in a 4*40 bit=5*32 bit group
@@ -454,7 +496,10 @@ switch ( ndx % 4 ) // 40 bit word index in a 4*40 bit=5*32 bit group
     }
 return val;
 }
-AliHLTUInt16_t AliHLTTPCDigitReaderRaw::GetAltroBlock10BitWord( unsigned long ndx ){
+
+AliHLTUInt16_t AliHLTTPCDigitReaderRaw::GetAltroBlock10BitWord( unsigned long ndx )
+{
+  // see header file for class documentation
 unsigned long realNdx = ndx+fAltroBlock10BitFillWordCnt;
 unsigned long word40BitNdx = (realNdx / 4)+1;
 AliHLTUInt64_t word40Bit = GetAltroBlock40BitWord( word40BitNdx );
@@ -473,7 +518,9 @@ switch ( realNdx % 4 )
  return 0xFFFF; 
 }
 
-AliHLTUInt16_t AliHLTTPCDigitReaderRaw::GetAltroBlockReal10BitWord( unsigned long ndx ){
+AliHLTUInt16_t AliHLTTPCDigitReaderRaw::GetAltroBlockReal10BitWord( unsigned long ndx )
+{
+  // see header file for class documentation
 unsigned long word40BitNdx = (ndx / 4)+1;
 AliHLTUInt64_t word40Bit = GetAltroBlock40BitWord( word40BitNdx );
 switch ( ndx % 4 )
@@ -491,9 +538,10 @@ switch ( ndx % 4 )
  return 0xFFFF; 
 }
 
-// Return length of trailing RCU data block in bytes
 unsigned AliHLTTPCDigitReaderRaw::GetRCUDataBlockLength() const
-    {
+{
+  // see header file for class documentation
+  // Return length of trailing RCU data block in bytes
     switch ( fDataFormatVersion )
        {
        case 0:
@@ -504,20 +552,33 @@ unsigned AliHLTTPCDigitReaderRaw::GetRCUDataBlockLength() const
        case 3:
            return 12;
            break;
+       case 4:
+       case 5:
+           return 8;
+           break;
        default:
            return fBufferSize;
        }
-    }
+}
 
 unsigned AliHLTTPCDigitReaderRaw::GetCommonDataHeaderSize() const
-    {
-    return 32;
-    }
-
+{
+  // see header file for class documentation
+  return 32;
+}
 
-Bool_t AliHLTTPCDigitReaderRaw::ApplyMapping(){
 
-    if ( (unsigned)fAltroBlockHWAddress > fMaxHWA[fPatch]){
+Bool_t AliHLTTPCDigitReaderRaw::ApplyMapping()
+{
+  // see header file for class documentation
+
+#ifndef HAVE_TPC_MAPPING
+  if (fMapErrThrown++==0) {
+    HLTFatal("mapping not available, you must compile with HAVE_TPC_MAPPING");
+  }
+  return -1;
+#endif //#ifndef HAVE_TPC_MAPPING
+    if ( (unsigned)fAltroBlockHWAddress > fgMaxHWA[fPatch]){
        fPad = -1;
        fRow = -1;
        return kFALSE;
@@ -525,33 +586,33 @@ Bool_t AliHLTTPCDigitReaderRaw::ApplyMapping(){
 
     switch(fPatch){
        case 0:
-           fRow = fMapping_0[(unsigned)fAltroBlockHWAddress][0];
-           fPad = fMapping_0[(unsigned)fAltroBlockHWAddress][1];
+           fRow = fgMapping0[(unsigned)fAltroBlockHWAddress][0];
+           fPad = fgMapping0[(unsigned)fAltroBlockHWAddress][1];
            break;
         case 1:
-           fRow = AliHLTTPCDigitReaderRaw::fMapping_1[(unsigned)fAltroBlockHWAddress][0];
-           fPad = AliHLTTPCDigitReaderRaw::fMapping_1[(unsigned)fAltroBlockHWAddress][1];
+           fRow = AliHLTTPCDigitReaderRaw::fgMapping1[(unsigned)fAltroBlockHWAddress][0];
+           fPad = AliHLTTPCDigitReaderRaw::fgMapping1[(unsigned)fAltroBlockHWAddress][1];
 #if 0
-           printf ("pad %d # row %d (hwa: %u / 0x%08X\n", fMapping_1[(unsigned)fAltroBlockHWAddress][0],fMapping_1[(unsigned)fAltroBlockHWAddress][1], (unsigned)fAltroBlockHWAddress, (unsigned)fAltroBlockHWAddress);
-           printf ("pad %d # row %d (hwa: %u / 0x%08X\n", fMapping_1[(unsigned)fAltroBlockHWAddress-1][0],fMapping_1[(unsigned)fAltroBlockHWAddress-1][1], (unsigned)fAltroBlockHWAddress-1, (unsigned)fAltroBlockHWAddress-1);
-           printf ("pad %d # row %d (hwa: %u / 0x%08X\n", fMapping_1[(unsigned)fAltroBlockHWAddress+1][0],fMapping_1[(unsigned)fAltroBlockHWAddress+1][1], (unsigned)fAltroBlockHWAddress+1, (unsigned)fAltroBlockHWAddress+1);
+           printf ("pad %d # row %d (hwa: %u / 0x%08X\n", fgMapping1[(unsigned)fAltroBlockHWAddress][0],fgMapping1[(unsigned)fAltroBlockHWAddress][1], (unsigned)fAltroBlockHWAddress, (unsigned)fAltroBlockHWAddress);
+           printf ("pad %d # row %d (hwa: %u / 0x%08X\n", fgMapping1[(unsigned)fAltroBlockHWAddress-1][0],fgMapping1[(unsigned)fAltroBlockHWAddress-1][1], (unsigned)fAltroBlockHWAddress-1, (unsigned)fAltroBlockHWAddress-1);
+           printf ("pad %d # row %d (hwa: %u / 0x%08X\n", fgMapping1[(unsigned)fAltroBlockHWAddress+1][0],fgMapping1[(unsigned)fAltroBlockHWAddress+1][1], (unsigned)fAltroBlockHWAddress+1, (unsigned)fAltroBlockHWAddress+1);
 #endif
            break;
        case 2:
-           fRow = fMapping_2[(unsigned)fAltroBlockHWAddress][0];
-           fPad = fMapping_2[(unsigned)fAltroBlockHWAddress][1];
+           fRow = fgMapping2[(unsigned)fAltroBlockHWAddress][0];
+           fPad = fgMapping2[(unsigned)fAltroBlockHWAddress][1];
            break;
         case 3:
-           fRow = fMapping_3[(unsigned)fAltroBlockHWAddress][0];
-           fPad = fMapping_3[(unsigned)fAltroBlockHWAddress][1];
+           fRow = fgMapping3[(unsigned)fAltroBlockHWAddress][0];
+           fPad = fgMapping3[(unsigned)fAltroBlockHWAddress][1];
            break;
        case 4:
-           fRow = fMapping_4[(unsigned)fAltroBlockHWAddress][0];
-           fPad = fMapping_4[(unsigned)fAltroBlockHWAddress][1];
+           fRow = fgMapping4[(unsigned)fAltroBlockHWAddress][0];
+           fPad = fgMapping4[(unsigned)fAltroBlockHWAddress][1];
            break;
         case 5:
-           fRow = fMapping_5[(unsigned)fAltroBlockHWAddress][0];
-           fPad = fMapping_5[(unsigned)fAltroBlockHWAddress][1];
+           fRow = fgMapping5[(unsigned)fAltroBlockHWAddress][0];
+           fPad = fgMapping5[(unsigned)fAltroBlockHWAddress][1];
            break;
        default:
            fRow = -1;
@@ -562,62 +623,150 @@ Bool_t AliHLTTPCDigitReaderRaw::ApplyMapping(){
 }
 
 
-Int_t AliHLTTPCDigitReaderRaw::GetRow( unsigned patch, unsigned hw_addr )
+Int_t AliHLTTPCDigitReaderRaw::GetRow( unsigned /*patch*/, unsigned hwAddr )
 {
-    if ( (unsigned)hw_addr > fMaxHWA[fPatch]){
+  // see header file for class documentation
+
+#ifndef HAVE_TPC_MAPPING
+  if (fMapErrThrown++==0) {
+    HLTFatal("mapping not available, you must compile with HAVE_TPC_MAPPING");
+  }
+  return -1;
+#endif //#ifndef HAVE_TPC_MAPPING
+    if ( (unsigned)hwAddr > fgMaxHWA[fPatch]){
        return -1;
     }
 
     switch(fPatch){
        case 0:
-           return fMapping_0[hw_addr][0];
+           return fgMapping0[hwAddr][0];
         case 1:
-           return fMapping_1[hw_addr][0];
+           return fgMapping1[hwAddr][0];
        case 2:
-           return fMapping_2[hw_addr][0];
+           return fgMapping2[hwAddr][0];
         case 3:
-           return fMapping_3[hw_addr][0];
+           return fgMapping3[hwAddr][0];
        case 4:
-           return fMapping_4[hw_addr][0];
+           return fgMapping4[hwAddr][0];
         case 5:
-           return fMapping_5[hw_addr][0];
+           return fgMapping5[hwAddr][0];
        default:
          return -1;
     }
 }
-Int_t AliHLTTPCDigitReaderRaw::GetPad( unsigned patch, unsigned hw_addr )
+
+Int_t AliHLTTPCDigitReaderRaw::GetPad( unsigned /*patch*/, unsigned hwAddr )
 {
-    if ( (unsigned)hw_addr > fMaxHWA[fPatch]){
+  // see header file for class documentation
+
+#ifndef HAVE_TPC_MAPPING
+  if (fMapErrThrown++==0) {
+    HLTFatal("mapping not available, you must compile with HAVE_TPC_MAPPING");
+  }
+  return -1;
+#endif //#ifndef HAVE_TPC_MAPPING
+    if ( (unsigned)hwAddr > fgMaxHWA[fPatch]){
        return -1;
     }
 
     switch(fPatch){
        case 0:
-           return fMapping_0[hw_addr][1];
+           return fgMapping0[hwAddr][1];
         case 1:
-           return fMapping_1[hw_addr][1];
+           return fgMapping1[hwAddr][1];
        case 2:
-           return fMapping_2[hw_addr][1];
+           return fgMapping2[hwAddr][1];
         case 3:
-           return fMapping_3[hw_addr][1];
+           return fgMapping3[hwAddr][1];
        case 4:
-           return fMapping_4[hw_addr][1];
+           return fgMapping4[hwAddr][1];
         case 5:
-           return fMapping_5[hw_addr][1];
+           return fgMapping5[hwAddr][1];
        default:
          return -1;
     }
 }
 
-unsigned AliHLTTPCDigitReaderRaw::GetMaxHWA( unsigned patch )
+unsigned AliHLTTPCDigitReaderRaw::GetMaxHWA( unsigned patch ) const
 {
-  if ( patch>=6 )
+  // see header file for class documentation
+
+  if ( (int)patch>=fgkNofPatches )
     return 0;
-  return fMaxHWA[patch];
+  return fgMaxHWA[patch];
+}
+
+Int_t AliHLTTPCDigitReaderRaw::DecodeMode(Int_t mode) 
+{
+  // see header file for class documentation
+
+  Int_t decodedMode;
+
+  if ( mode >= kNofRawReaderModes ) 
+    decodedMode = -1;
+  else
+    decodedMode = mode;
+
+  return decodedMode;
+}
+
+Int_t AliHLTTPCDigitReaderRaw::DecodeMode(const Char_t *mode) 
+{
+  // see header file for class documentation
+
+  Int_t decodedMode;
+  Char_t *cpErr;
+
+  // Check if String is convertible to Int_t
+  // if not decode the string, otherwise, check if Int_t is valid
+  Int_t intMode = strtoul( mode, &cpErr ,0);
+
+  if ( *cpErr ) {
+    if ( !strcmp( mode, "sorted_3_trailerword" ) ) 
+      decodedMode = kSorted3Trailerword;
+    
+    else if ( !strcmp( mode, "sorted_2_trailerword" ) ) 
+      decodedMode = kSorted2Trailerword;
+    
+    else if ( !strcmp( mode, "sorted_1_trailerword" ) ) 
+      decodedMode = kSorted1Trailerword;
+    
+    else if ( !strcmp( mode, "unsorted_3_trailerword" ) ) 
+      decodedMode = kUnsorted3Trailerword;
+    
+    else if ( !strcmp( mode, "unsorted_2_trailerword" ) ) 
+      decodedMode = kUnsorted2Trailerword;
+    
+    else if ( !strcmp( mode, "unsorted_1_trailerword" ) ) 
+      decodedMode = kUnsorted1Trailerword;
+    
+    else if ( ! strcmp( mode, "offline" ) )
+      decodedMode = -2;
+    
+    else 
+      decodedMode = -1;
+  }  // END if ( *cpErr ) {
+  else {
+    if ( intMode >= kNofRawReaderModes ) 
+      decodedMode = -1;
+    else
+      decodedMode = intMode;
+  }
+
+  return decodedMode;
 }
 
 
 // ----- MAPPING ARRAYS
+#if defined(HAVE_TPC_MAPPING)
 #include "mapping_array_out.inc"
-
+#else
+// dummy definitions in case of missing mapping
+unsigned AliHLTTPCDigitReaderRaw::fgMaxHWA[fgkNofPatches];
+Int_t AliHLTTPCDigitReaderRaw::fgMapping0[fgkMapping0Size][fgkMappingDimension];
+Int_t AliHLTTPCDigitReaderRaw::fgMapping1[fgkMapping1Size][fgkMappingDimension];
+Int_t AliHLTTPCDigitReaderRaw::fgMapping2[fgkMapping2Size][fgkMappingDimension];
+Int_t AliHLTTPCDigitReaderRaw::fgMapping3[fgkMapping3Size][fgkMappingDimension];
+Int_t AliHLTTPCDigitReaderRaw::fgMapping4[fgkMapping4Size][fgkMappingDimension];
+Int_t AliHLTTPCDigitReaderRaw::fgMapping5[fgkMapping5Size][fgkMappingDimension];
 #endif //#if defined(HAVE_TPC_MAPPING)