implemented TPCDigitDump and AltroChannelSelector
[u/mrichter/AliRoot.git] / HLT / TPCLib / AliHLTTPCDigitReaderRaw.cxx
1 // $Id$
2
3 /**************************************************************************
4  * This file is property of and copyright by the ALICE HLT Project        * 
5  * ALICE Experiment at CERN, All rights reserved.                         *
6  *                                                                        *
7  * Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *
8  *                  Timm Steinbeck <timm@kip.uni-heidelberg.de>           *
9  *                  Jochen Thaeder <thaeder@kip.uni-heidelberg.de>        *
10  *                  for The ALICE HLT Project.                            *
11  *                                                                        *
12  * Permission to use, copy, modify and distribute this software and its   *
13  * documentation strictly for non-commercial purposes is hereby granted   *
14  * without fee, provided that the above copyright notice appears in all   *
15  * copies and that both the copyright notice and this permission notice   *
16  * appear in the supporting documentation. The authors make no claims     *
17  * about the suitability of this software for any purpose. It is          *
18  * provided "as is" without express or implied warranty.                  *
19  **************************************************************************/
20
21 /** @file   AliHLTTPCDigitReaderRaw.cxx
22     @author Timm Steinbeck
23     @date   
24     @brief  A digit reader implementation for the RAW data coming from the RCU.
25 */
26
27 #if __GNUC__>= 3
28 using namespace std;
29 #endif
30
31 #include "AliHLTTPCDigitReaderRaw.h"
32 #include "AliHLTTPCTransform.h"
33 #include "AliHLTTPCRootTypes.h"
34 #include "AliHLTStdIncludes.h"
35 #include "AliHLTTPCLogging.h"
36
37 ClassImp(AliHLTTPCDigitReaderRaw)
38
39 AliHLTTPCDigitReaderRaw::AliHLTTPCDigitReaderRaw( unsigned formatVersion )
40   :
41   fBuffer(NULL),
42   fBufferSize(0),
43   fPatch(-1),
44   fSlice(-1),
45   fRow(-1),
46   fPad(-1),
47   fAltroBlockPositionBytes(0),
48   fAltroBlockLengthBytes(0),
49   fAltroBlockHWAddress(0),
50   fAltroBlock10BitWordCnt(0),
51   fAltroBlock10BitFillWordCnt(0),
52   fDataFormatVersion(formatVersion),
53   fBunchPosition(0xFFFFU),
54   fBunchTimebinStart(~0U),
55   fBunchLength(0),
56   fWordInBunch((unsigned)-1),
57   fVerify(false),
58   
59   fCurrentRow(0),
60   fCurrentPad(0),
61   fCurrentBin(-1),
62   fRowOffset(0),
63   fNRows(0),
64   fNMaxRows(0),
65   fNMaxPads(0),
66   fNTimeBins(0),
67   fData(NULL),
68   fMapErrThrown(0)
69 {
70   // see header file for class documentation
71   // or
72   // refer to README to build package
73   // or
74   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
75 #ifndef HAVE_TPC_MAPPING
76   memset(fgMapping0, 0, fgkMapping0Size*fgkMappingDimension*sizeof(Int_t));
77   memset(fgMapping1, 0, fgkMapping1Size*fgkMappingDimension*sizeof(Int_t));
78   memset(fgMapping2, 0, fgkMapping2Size*fgkMappingDimension*sizeof(Int_t));
79   memset(fgMapping3, 0, fgkMapping3Size*fgkMappingDimension*sizeof(Int_t));
80   memset(fgMapping4, 0, fgkMapping4Size*fgkMappingDimension*sizeof(Int_t));
81   memset(fgMapping5, 0, fgkMapping5Size*fgkMappingDimension*sizeof(Int_t));
82 #endif //#ifndef HAVE_TPC_MAPPING
83
84     if ( fDataFormatVersion==0 || fDataFormatVersion==2 || fDataFormatVersion==4 )
85       {
86         
87         // get max number of rows
88         for (Int_t ii=0; ii < 6; ii++)
89           if (AliHLTTPCTransform::GetNRows(ii) > fNMaxRows) 
90             fNMaxRows = AliHLTTPCTransform::GetNRows(ii);
91         
92         // get max number of pads
93         for (Int_t ii=0; ii < AliHLTTPCTransform::GetNRows();ii++ )
94           if (AliHLTTPCTransform::GetNPads(ii) > fNMaxPads) 
95             fNMaxPads = AliHLTTPCTransform::GetNPads(ii);
96         
97         // get max number of bins
98         fNTimeBins = AliHLTTPCTransform::GetNTimeBins();
99         
100         //      HLTDebug("Array Borders ||| MAXPAD=%d ||| MAXROW=%d ||| MAXBIN=%d ||| MAXMUL=%d", 
101         //       fNMaxPads, fNMaxRows, fNTimeBins, fNTimeBins*fNMaxRows*fNMaxPads);
102         
103         // init Data array
104         fData = new Int_t[ fNMaxRows*fNMaxPads*fNTimeBins ];
105       }
106 }
107
108 AliHLTTPCDigitReaderRaw::~AliHLTTPCDigitReaderRaw()
109 {
110   // see header file for class documentation
111   if ( fDataFormatVersion==0 || fDataFormatVersion==2 || fDataFormatVersion==4 )
112     {
113       if ( fData )
114         delete [] fData;
115       fData = NULL;
116     }
117 }
118
119 int AliHLTTPCDigitReaderRaw::InitBlock(void* ptr,unsigned long size,Int_t firstrow,Int_t lastrow, Int_t patch, Int_t slice) 
120 {
121   // see header file for class documentation
122   return AliHLTTPCDigitReader::InitBlock(ptr, size, firstrow, lastrow, patch, slice);
123 }
124
125 int AliHLTTPCDigitReaderRaw::InitBlock(void* ptr,unsigned long size, Int_t patch, Int_t slice)
126 {
127   // see header file for class documentation
128
129     fBuffer = (AliHLTUInt8_t*) ptr;
130     if (fBuffer==NULL) {
131       HLTError("invalid data buffer");
132       return -EINVAL;
133     }
134     fBufferSize = size;
135     if (fBufferSize<=0) HLTWarning("no data available: zero length buffer");
136     fPatch = patch;
137     fSlice = slice;
138     fPad = -1;
139     fRow = -1;
140     
141     fAltroBlockPositionBytes = 0;
142     fAltroBlockLengthBytes = 0;
143     fAltroBlock10BitWordCnt = 0xFFFFU;
144     fAltroBlockHWAddress = 0xFFFFU;
145     fBunchPosition = 0xFFFFU;
146     fBunchTimebinStart = ~0U;
147     fBunchLength = 0;
148     fWordInBunch = (unsigned)-1;
149
150     Int_t firstrow=AliHLTTPCTransform::GetFirstRow(patch);
151     Int_t lastrow=AliHLTTPCTransform::GetLastRow(patch);
152
153     if ( fDataFormatVersion==0 || fDataFormatVersion==2 || fDataFormatVersion==4 )
154       {
155         fCurrentRow = 0;
156         fCurrentPad = 0;
157         fCurrentBin = -1;
158         
159         fNRows = lastrow - firstrow + 1;
160         
161         Int_t offset=0;
162         if (patch > 1) offset =  AliHLTTPCTransform::GetFirstRow( 2 );
163         
164         fRowOffset = firstrow - offset;
165         firstrow -= offset;
166         lastrow  -= offset;
167         
168         // Init array with -1
169         memset( fData, 0xFF, sizeof(Int_t)*(fNMaxRows*fNMaxPads*fNTimeBins) );
170
171         const Int_t kMaxErrorPrintout=20;
172         Int_t errorCount=0;
173         Int_t entryCount=0;
174         // read data and fill in array
175
176         while( RealNext()){
177
178           entryCount++;
179           Int_t row = GetRealRow();
180           Int_t pad = GetRealPad();
181           Int_t bin = GetRealTime();
182           
183 //        HLTFatal("Index out of array range: PAD=%d ||| ROW=%d ||| BIN=%d ||| OFFSET=%d ||| ROWOFFSET=%d", pad, row, bin, offset, fRowOffset);
184
185           if ( row < firstrow || row > lastrow || pad > AliHLTTPCTransform::GetNPads(row + offset) || bin > fNTimeBins || pad<0 || bin<0){
186 //        if ( row < firstrow || row > lastrow || pad > AliHLTTPCTransform::GetNPads(row + offset) || bin > fNTimeBins){
187             if (errorCount++<kMaxErrorPrintout) {
188               HLTFatal("Index out of range. Probably wrong patch! slice %d - patch %d", slice, patch);
189               HLTFatal("PAD=%d out of %d ||| ROW=%d (%d to %d)  ||| BIN=%d out of %d  ||| OFFSET=%d ||| ROWOFFSET=%d",
190                        pad, AliHLTTPCTransform::GetNPads(row + offset), row, firstrow, lastrow, bin, fNTimeBins,
191                        offset, fRowOffset);
192
193               if ( row < firstrow || row > lastrow ) 
194                 HLTFatal("Row out of range: %d  ( %d to %d)", row, firstrow, lastrow);
195               if ( pad > AliHLTTPCTransform::GetNPads(row + offset) ) 
196                 HLTFatal("Pad out of range: %d  (pad count %d)", pad, AliHLTTPCTransform::GetNPads(row + offset));
197               if ( bin > fNTimeBins )
198                 HLTFatal("Time bin out of range: %d (bin count %d)", bin, fNTimeBins);
199             }
200             // stop at the fist error message in order to avoid endless messages and
201             // to handle corrupted events
202             //continue;
203             break;
204           } else if ((row-fRowOffset)*fNMaxPads*fNTimeBins+ pad*fNTimeBins + bin >=  fNMaxRows*fNMaxPads*fNTimeBins ) {
205             if (errorCount++<kMaxErrorPrintout) {
206               HLTFatal("index out of range: PAD=%d ||| ROW=%d ||| BIN=%d ||| OFFSET=%d ||| ROWOFFSET=%d", pad, row, bin, offset, fRowOffset);
207             }
208             // stop at the fist error message in order to avoid endless messages and
209             // to handle corrupted events
210             //continue;
211             break;
212           } else {
213             fData[ (row-fRowOffset)*fNMaxPads*fNTimeBins+ pad*fNTimeBins + bin ] = GetRealSignal() ;
214           }
215         }
216         if (errorCount>0) {
217           HLTFatal("%d of %d entries out of range", errorCount, entryCount);
218         }
219       }
220
221     return 0;
222 }
223
224 bool AliHLTTPCDigitReaderRaw::NextSignal()
225 {
226   // see header file for class documentation
227
228   if ( fDataFormatVersion==0 || fDataFormatVersion==2 || fDataFormatVersion==4 )
229     {
230       Bool_t readvalue = kTRUE;
231       while (1) {
232         fCurrentBin++;
233         if (fCurrentBin >= fNTimeBins){
234           fCurrentBin = 0;
235           fCurrentPad++;
236           
237           if (fCurrentPad >=fNMaxPads){
238             fCurrentPad = 0;
239             fCurrentRow++;
240             
241             if (fCurrentRow >= fNMaxRows){
242               readvalue = kFALSE;
243               break;
244             }
245           }
246         }
247         
248         if (fCurrentRow*fNMaxPads*fNTimeBins+ fCurrentPad*fNTimeBins + fCurrentBin >=  fNMaxRows*fNMaxPads*fNTimeBins ) {
249           HLTFatal("Overflow: fCurrentRow=%d fCurrentPad=%d fCurrentBin=%d", fCurrentRow, fCurrentPad, fCurrentBin);
250           readvalue = kFALSE;
251           break;
252         }
253         
254         if (fData[ fCurrentRow*fNMaxPads*fNTimeBins + fCurrentPad*fNTimeBins + fCurrentBin  ] != -1) break;
255       }
256       return readvalue;
257     }
258   else
259     return RealNext();
260 }
261
262 int AliHLTTPCDigitReaderRaw::GetRow()
263 {
264   // see header file for class documentation
265
266   if ( fDataFormatVersion==0 || fDataFormatVersion==2 || fDataFormatVersion==4 )
267     {
268       return (fCurrentRow + fRowOffset);
269     }
270   else
271     return GetRealRow();
272 }
273
274 int AliHLTTPCDigitReaderRaw::GetPad()
275 {
276   // see header file for class documentation
277
278   if ( fDataFormatVersion==0 || fDataFormatVersion==2 || fDataFormatVersion==4 )
279     {
280       return fCurrentPad;
281     }
282   else
283     return GetRealPad();
284 }
285
286 int AliHLTTPCDigitReaderRaw::GetSignal()
287 {
288   // see header file for class documentation
289
290   if ( fDataFormatVersion==0 || fDataFormatVersion==2 || fDataFormatVersion==4 )
291     {
292       return fData[ fCurrentRow*fNMaxPads*fNTimeBins+ fCurrentPad*fNTimeBins + fCurrentBin ];
293     }
294   else
295     return GetRealSignal();
296 }
297
298 int AliHLTTPCDigitReaderRaw::GetTime()
299 {
300   // see header file for class documentation
301
302   if ( fDataFormatVersion==0 || fDataFormatVersion==2 || fDataFormatVersion==4 )
303     {
304       return fCurrentBin;
305     }
306   else
307     return GetRealTime();
308 }
309
310 int AliHLTTPCDigitReaderRaw::GetAltroChannelRawData(void* &pTgt, AliHLTUInt16_t &hwAddress)
311 {
312   int iResult;
313   if (fBuffer==NULL) return -ENODATA;
314   if (fAltroBlockPositionBytes-fAltroBlockLengthBytes>GetCommonDataHeaderSize()) {
315     pTgt=fBuffer+(fAltroBlockPositionBytes-fAltroBlockLengthBytes+1);
316     iResult=fAltroBlockLengthBytes;
317     hwAddress=fAltroBlockHWAddress;
318   }
319   return iResult;
320 }
321
322 bool AliHLTTPCDigitReaderRaw::RealNext()
323 {
324   // see header file for class documentation
325
326 //    printf( "%u %u %u %u %u\n", fBunchPosition, fBunchLength, fBunchTimebinStart, fWordInBunch, (unsigned)fAltroBlock10BitWordCnt );
327     fWordInBunch++; // use next word in bunch
328     if ( fWordInBunch==fBunchLength ) { // we have a bunch at all but have reached its end (or do not have an altro block yet)
329         if ( fBunchPosition+fBunchLength==fAltroBlock10BitWordCnt ) { // We were at the last bunch of this altro block (or do not have an altro block yet)
330             if ( !NextAltroBlock() )
331                 return false;
332             fBunchPosition = 0;
333         }
334         else {
335             fBunchPosition += fBunchLength;
336         }
337         fBunchLength = GetAltroBlock10BitWord( fBunchPosition );
338         fBunchTimebinStart = GetAltroBlock10BitWord( fBunchPosition+1 );
339         fWordInBunch = 2;
340     }
341     //HLTDebug( "%u %u %u %u %u\n", fBunchPosition, fBunchLength, fBunchTimebinStart, fWordInBunch, (unsigned)fAltroBlock10BitWordCnt );
342     return true;
343 }
344
345 int AliHLTTPCDigitReaderRaw::GetRealRow() const
346 {
347   // see header file for class documentation
348     return fRow;
349 }
350
351 int AliHLTTPCDigitReaderRaw::GetRealPad() const
352 {
353   // see header file for class documentation
354     return fPad;
355 }
356
357 int AliHLTTPCDigitReaderRaw::GetRealSignal()
358 {
359   // see header file for class documentation
360     return GetAltroBlock10BitWord( fBunchPosition+fWordInBunch );
361 }
362
363 int AliHLTTPCDigitReaderRaw::GetRealTime() const
364 {
365   // see header file for class documentation
366   //HLTDebug( "GetRealTime: %u - %u\n", fBunchTimebinStart, fWordInBunch );
367     return fBunchTimebinStart-(fWordInBunch-2);
368 }
369
370 AliHLTUInt32_t AliHLTTPCDigitReaderRaw::GetRCUTrailer( unsigned offset ) const
371 {
372   // see header file for class documentation
373   if (fBufferSize<=0) return 0;
374   unsigned rcuDataBlockLen = GetRCUDataBlockLength(); 
375   if ( offset >= rcuDataBlockLen ) return 0;
376   return ((AliHLTUInt32_t*)(fBuffer+fBufferSize-rcuDataBlockLen))[offset];
377 }
378
379 bool AliHLTTPCDigitReaderRaw::NextAltroBlock()
380 {
381   // see header file for class documentation
382     if (fBufferSize<=32) return 0;
383     bool first = false;
384     if ( !fAltroBlockLengthBytes )
385         {
386         // First block in back linked list (last block in memory)
387         fAltroBlockPositionBytes = fBufferSize-GetRCUDataBlockLength();
388         first = true;
389         }
390     else
391         {
392         if ( fAltroBlockPositionBytes<fAltroBlockLengthBytes+GetCommonDataHeaderSize() )
393           {
394             HLTFatal("Inconsistent Data: fAltroBlockPositionBytes=%d fAltroBlockLengthBytes=%d", fAltroBlockPositionBytes, fAltroBlockLengthBytes);
395           }
396         if ( fAltroBlockPositionBytes<=fAltroBlockLengthBytes+GetCommonDataHeaderSize() )
397             return false; // We have reached the end of the back linked list
398         fAltroBlockPositionBytes -= fAltroBlockLengthBytes;
399         }
400
401       AliHLTUInt64_t altroTrailerWord = GetAltroBlock40BitWord( 0 );
402       // Undefined hack from experience to match fill words appearing in simulated data
403       // Seem to be between 0 and 3 fill words, most likely to bring the number of 40bit words
404       // to a multiple of four / to bring the total number of bytes to a common multiple of 4 and 5.
405       // (RCU sends 40 bit (5 byte) words, DDL uses 32 bit (4 bytes) words.
406       unsigned short tmpCnt=0;
407       //HLTDebug( "Altro trailer word 0: 0x%016LX\n", altroTrailerWord );
408       while ( first && altroTrailerWord==0x000000AAAAAAAAAAULL && tmpCnt++<4 ) // Allow up to 4 fill values
409         {
410           altroTrailerWord = GetAltroBlock40BitWord( tmpCnt );
411           //HLTDebug( "Altro trailer word %hu: 0x%016LX\n", tmpCnt, altroTrailerWord );
412         }
413
414       fAltroBlockPositionBytes -= 5*tmpCnt;
415       if ( fVerify && ((altroTrailerWord & 0xFFFC000000ULL)!=0xAAA8000000ULL) )
416         {
417           HLTFatal("Data inconsistency in Altro Block at byte position %#x (%d): Expected 0x2AAA in high 14 bits of altro trailer word; Found %#llx (%#llx)",
418                    fAltroBlockPositionBytes, fAltroBlockPositionBytes, 
419                    ((altroTrailerWord & 0xFFFC000000ULL) >> 26), altroTrailerWord);
420
421
422           return false;
423         }
424
425       if ( fVerify && ((altroTrailerWord & 0x000000F000ULL)!=0x000000A000ULL) )
426         {
427           HLTFatal("Data inconsistency in Altro Block at byte position %#x (%d): Expected 0xA in bits 12-15 of altro trailer word; Found %#llx .",
428                    fAltroBlockPositionBytes, fAltroBlockPositionBytes,  ((altroTrailerWord & 0x000000F000ULL) >> 12)); 
429
430           return false;
431         }
432
433       fAltroBlock10BitWordCnt = (altroTrailerWord >> 16) & 0x3FF;
434       fAltroBlockHWAddress = altroTrailerWord & 0xFFF;
435
436       // ApplyMapping
437       if (!ApplyMapping())
438         {
439           HLTFatal("Mapping failed Patch %d HWA %#x (%d) - maxHWA %#x (%d)",
440                    fPatch, fAltroBlockHWAddress, fAltroBlockHWAddress, fgMaxHWA[fPatch], fgMaxHWA[fPatch]);
441
442         }
443
444       unsigned words40Bit = fAltroBlock10BitWordCnt/4;
445       if ( fAltroBlock10BitWordCnt % 4 )
446           words40Bit++;
447       words40Bit++;
448       fAltroBlockLengthBytes = words40Bit*5;
449     if ( fAltroBlock10BitWordCnt % 4 )
450         fAltroBlock10BitFillWordCnt = 4-(fAltroBlock10BitWordCnt % 4);
451     else
452         fAltroBlock10BitFillWordCnt=0;
453     if ( fVerify )
454       {
455         for ( unsigned b = 0; b < fAltroBlock10BitFillWordCnt; b++ )
456           {
457             if ( GetAltroBlockReal10BitWord(b)!=0x2AA )
458               {
459                 HLTFatal("Data inconsistency in trailing 10 bit fill word of Altro Block at byte position %#x (%d): Expected 0x2AA; Found %#x",
460                          fAltroBlockPositionBytes, fAltroBlockPositionBytes, GetAltroBlockReal10BitWord(b));
461                 
462                 return false;
463               }
464           }
465       }
466     return true;
467 }
468
469 AliHLTUInt32_t AliHLTTPCDigitReaderRaw::GetAltroBlockHWaddr() const
470 {
471   // see header file for class documentation
472   return fAltroBlockHWAddress;
473 }
474
475 unsigned AliHLTTPCDigitReaderRaw::GetAltroBlock10BitWordCnt() const
476 {
477   // see header file for class documentation
478   return fAltroBlock10BitWordCnt;
479 }
480
481 AliHLTUInt64_t AliHLTTPCDigitReaderRaw::GetAltroBlock40BitWord( unsigned long ndx ) const
482 {
483   // see header file for class documentation
484 AliHLTUInt64_t val=0;
485 unsigned wordOffset32Bit = (ndx / 4)*5;
486 switch ( ndx % 4 ) // 40 bit word index in a 4*40 bit=5*32 bit group
487     {
488     case 0:
489         val = (*(AliHLTUInt32_t*)(fBuffer+fAltroBlockPositionBytes-(wordOffset32Bit+1)*sizeof(AliHLTUInt32_t)));
490         val <<= 8;
491         val |= (*(AliHLTUInt32_t*)(fBuffer+fAltroBlockPositionBytes-(wordOffset32Bit+2)*sizeof(AliHLTUInt32_t))) >> 24;
492         break;
493     case 1:
494         val = ((*(AliHLTUInt32_t*)(fBuffer+fAltroBlockPositionBytes-(wordOffset32Bit+2)*sizeof(AliHLTUInt32_t))) & 0x00FFFFFF);
495         val <<= 16;
496         val |= ((*(AliHLTUInt32_t*)(fBuffer+fAltroBlockPositionBytes-(wordOffset32Bit+3)*sizeof(AliHLTUInt32_t))) >> 16) & 0xFFFF;
497         break;
498     case 2:
499         val = ((*(AliHLTUInt32_t*)(fBuffer+fAltroBlockPositionBytes-(wordOffset32Bit+3)*sizeof(AliHLTUInt32_t))) & 0xFFFF);
500         val <<= 24;
501         val |= ((*(AliHLTUInt32_t*)(fBuffer+fAltroBlockPositionBytes-(wordOffset32Bit+4)*sizeof(AliHLTUInt32_t))) >> 8);
502         break;
503     case 3:
504         val = ((*(AliHLTUInt32_t*)(fBuffer+fAltroBlockPositionBytes-(wordOffset32Bit+4)*sizeof(AliHLTUInt32_t))) & 0xFF);
505         val <<= 32;
506         val |= *(AliHLTUInt32_t*)(fBuffer+fAltroBlockPositionBytes-(wordOffset32Bit+5)*sizeof(AliHLTUInt32_t));
507         break;
508     }
509 return val;
510 }
511
512 AliHLTUInt16_t AliHLTTPCDigitReaderRaw::GetAltroBlock10BitWord( unsigned long ndx )
513 {
514   // see header file for class documentation
515 unsigned long realNdx = ndx+fAltroBlock10BitFillWordCnt;
516 unsigned long word40BitNdx = (realNdx / 4)+1;
517 AliHLTUInt64_t word40Bit = GetAltroBlock40BitWord( word40BitNdx );
518 switch ( realNdx % 4 )
519     {
520     case 3:
521         return word40Bit & 0x3FF;
522     case 2:
523         return (word40Bit>>10) & 0x3FF;
524     case 1:
525         return (word40Bit>>20) & 0x3FF;
526     case 0:
527         return (word40Bit>>30) & 0x3FF;
528     }
529
530  return 0xFFFF; 
531 }
532
533 AliHLTUInt16_t AliHLTTPCDigitReaderRaw::GetAltroBlockReal10BitWord( unsigned long ndx )
534 {
535   // see header file for class documentation
536 unsigned long word40BitNdx = (ndx / 4)+1;
537 AliHLTUInt64_t word40Bit = GetAltroBlock40BitWord( word40BitNdx );
538 switch ( ndx % 4 )
539     {
540     case 3:
541         return word40Bit & 0x3FF;
542     case 2:
543         return (word40Bit>>10) & 0x3FF;
544     case 1:
545         return (word40Bit>>20) & 0x3FF;
546     case 0:
547         return (word40Bit>>30) & 0x3FF;
548     }
549
550  return 0xFFFF; 
551 }
552
553 unsigned AliHLTTPCDigitReaderRaw::GetRCUDataBlockLength() const
554 {
555   // see header file for class documentation
556   // Return length of trailing RCU data block in bytes
557     switch ( fDataFormatVersion )
558         {
559         case 0:
560         case 1:
561             return 4;
562             break;
563         case 2:
564         case 3:
565             return 12;
566             break;
567         case 4:
568         case 5:
569             return 8;
570             break;
571         default:
572             return fBufferSize;
573         }
574 }
575
576 unsigned AliHLTTPCDigitReaderRaw::GetCommonDataHeaderSize() const
577 {
578   // see header file for class documentation
579   return 32;
580 }
581
582
583 Bool_t AliHLTTPCDigitReaderRaw::ApplyMapping()
584 {
585   // see header file for class documentation
586
587 #ifndef HAVE_TPC_MAPPING
588   if (fMapErrThrown++==0) {
589     HLTFatal("mapping not available, you must compile with HAVE_TPC_MAPPING");
590   }
591   return -1;
592 #endif //#ifndef HAVE_TPC_MAPPING
593     if ( (unsigned)fAltroBlockHWAddress > fgMaxHWA[fPatch]){
594         fPad = -1;
595         fRow = -1;
596         return kFALSE;
597     }
598
599     switch(fPatch){
600         case 0:
601             fRow = fgMapping0[(unsigned)fAltroBlockHWAddress][0];
602             fPad = fgMapping0[(unsigned)fAltroBlockHWAddress][1];
603             break;
604         case 1:
605             fRow = AliHLTTPCDigitReaderRaw::fgMapping1[(unsigned)fAltroBlockHWAddress][0];
606             fPad = AliHLTTPCDigitReaderRaw::fgMapping1[(unsigned)fAltroBlockHWAddress][1];
607 #if 0
608             printf ("pad %d # row %d (hwa: %u / 0x%08X\n", fgMapping1[(unsigned)fAltroBlockHWAddress][0],fgMapping1[(unsigned)fAltroBlockHWAddress][1], (unsigned)fAltroBlockHWAddress, (unsigned)fAltroBlockHWAddress);
609             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);
610             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);
611 #endif
612             break;
613         case 2:
614             fRow = fgMapping2[(unsigned)fAltroBlockHWAddress][0];
615             fPad = fgMapping2[(unsigned)fAltroBlockHWAddress][1];
616             break;
617         case 3:
618             fRow = fgMapping3[(unsigned)fAltroBlockHWAddress][0];
619             fPad = fgMapping3[(unsigned)fAltroBlockHWAddress][1];
620             break;
621         case 4:
622             fRow = fgMapping4[(unsigned)fAltroBlockHWAddress][0];
623             fPad = fgMapping4[(unsigned)fAltroBlockHWAddress][1];
624             break;
625         case 5:
626             fRow = fgMapping5[(unsigned)fAltroBlockHWAddress][0];
627             fPad = fgMapping5[(unsigned)fAltroBlockHWAddress][1];
628             break;
629         default:
630             fRow = -1;
631             fPad = -1;
632             return kFALSE;
633     }
634     return kTRUE;
635 }
636
637
638 Int_t AliHLTTPCDigitReaderRaw::GetRow( unsigned /*patch*/, unsigned hwAddr )
639 {
640   // see header file for class documentation
641
642 #ifndef HAVE_TPC_MAPPING
643   if (fMapErrThrown++==0) {
644     HLTFatal("mapping not available, you must compile with HAVE_TPC_MAPPING");
645   }
646   return -1;
647 #endif //#ifndef HAVE_TPC_MAPPING
648     if ( (unsigned)hwAddr > fgMaxHWA[fPatch]){
649         return -1;
650     }
651
652     switch(fPatch){
653         case 0:
654             return fgMapping0[hwAddr][0];
655         case 1:
656             return fgMapping1[hwAddr][0];
657         case 2:
658             return fgMapping2[hwAddr][0];
659         case 3:
660             return fgMapping3[hwAddr][0];
661         case 4:
662             return fgMapping4[hwAddr][0];
663         case 5:
664             return fgMapping5[hwAddr][0];
665         default:
666           return -1;
667     }
668 }
669
670 Int_t AliHLTTPCDigitReaderRaw::GetPad( unsigned /*patch*/, unsigned hwAddr )
671 {
672   // see header file for class documentation
673
674 #ifndef HAVE_TPC_MAPPING
675   if (fMapErrThrown++==0) {
676     HLTFatal("mapping not available, you must compile with HAVE_TPC_MAPPING");
677   }
678   return -1;
679 #endif //#ifndef HAVE_TPC_MAPPING
680     if ( (unsigned)hwAddr > fgMaxHWA[fPatch]){
681         return -1;
682     }
683
684     switch(fPatch){
685         case 0:
686             return fgMapping0[hwAddr][1];
687         case 1:
688             return fgMapping1[hwAddr][1];
689         case 2:
690             return fgMapping2[hwAddr][1];
691         case 3:
692             return fgMapping3[hwAddr][1];
693         case 4:
694             return fgMapping4[hwAddr][1];
695         case 5:
696             return fgMapping5[hwAddr][1];
697         default:
698           return -1;
699     }
700 }
701
702 unsigned AliHLTTPCDigitReaderRaw::GetMaxHWA( unsigned patch ) const
703 {
704   // see header file for class documentation
705
706   if ( (int)patch>=fgkNofPatches )
707     return 0;
708   return fgMaxHWA[patch];
709 }
710
711 Int_t AliHLTTPCDigitReaderRaw::DecodeMode(Int_t mode) 
712 {
713   // see header file for class documentation
714
715   Int_t decodedMode;
716
717   if ( mode >= kNofRawReaderModes ) 
718     decodedMode = -1;
719   else
720     decodedMode = mode;
721
722   return decodedMode;
723 }
724
725 Int_t AliHLTTPCDigitReaderRaw::DecodeMode(const Char_t *mode) 
726 {
727   // see header file for class documentation
728
729   Int_t decodedMode;
730   Char_t *cpErr;
731
732   // Check if String is convertible to Int_t
733   // if not decode the string, otherwise, check if Int_t is valid
734   Int_t intMode = strtoul( mode, &cpErr ,0);
735
736   if ( *cpErr ) {
737     if ( !strcmp( mode, "sorted_3_trailerword" ) ) 
738       decodedMode = kSorted3Trailerword;
739     
740     else if ( !strcmp( mode, "sorted_2_trailerword" ) ) 
741       decodedMode = kSorted2Trailerword;
742     
743     else if ( !strcmp( mode, "sorted_1_trailerword" ) ) 
744       decodedMode = kSorted1Trailerword;
745     
746     else if ( !strcmp( mode, "unsorted_3_trailerword" ) ) 
747       decodedMode = kUnsorted3Trailerword;
748     
749     else if ( !strcmp( mode, "unsorted_2_trailerword" ) ) 
750       decodedMode = kUnsorted2Trailerword;
751     
752     else if ( !strcmp( mode, "unsorted_1_trailerword" ) ) 
753       decodedMode = kUnsorted1Trailerword;
754     
755     else if ( ! strcmp( mode, "offline" ) )
756       decodedMode = -2;
757     
758     else 
759       decodedMode = -1;
760   }  // END if ( *cpErr ) {
761   else {
762     if ( intMode >= kNofRawReaderModes ) 
763       decodedMode = -1;
764     else
765       decodedMode = intMode;
766   }
767
768   return decodedMode;
769 }
770
771
772 // ----- MAPPING ARRAYS
773 #if defined(HAVE_TPC_MAPPING)
774 #include "mapping_array_out.inc"
775 #else
776 // dummy definitions in case of missing mapping
777 unsigned AliHLTTPCDigitReaderRaw::fgMaxHWA[fgkNofPatches];
778 Int_t AliHLTTPCDigitReaderRaw::fgMapping0[fgkMapping0Size][fgkMappingDimension];
779 Int_t AliHLTTPCDigitReaderRaw::fgMapping1[fgkMapping1Size][fgkMappingDimension];
780 Int_t AliHLTTPCDigitReaderRaw::fgMapping2[fgkMapping2Size][fgkMappingDimension];
781 Int_t AliHLTTPCDigitReaderRaw::fgMapping3[fgkMapping3Size][fgkMappingDimension];
782 Int_t AliHLTTPCDigitReaderRaw::fgMapping4[fgkMapping4Size][fgkMappingDimension];
783 Int_t AliHLTTPCDigitReaderRaw::fgMapping5[fgkMapping5Size][fgkMappingDimension];
784 #endif //#if defined(HAVE_TPC_MAPPING)