- version HLT-v0-4 ready
[u/mrichter/AliRoot.git] / HLT / TPCLib / AliHLTTPCDigitReaderRaw.cxx
1 // $Id$
2
3 /**************************************************************************
4  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
5  *                                                                        *
6  * Authors: Matthias Richter <Matthias.Richter@ift.uib.no>                *
7  *          Timm Steinbeck <timm@kip.uni-heidelberg.de>                   *
8  *          Jochen Thaeder <thaeder@kip.uni-heidelberg.de>                *
9  *          for The ALICE Off-line Project.                               *
10  *                                                                        *
11  * Permission to use, copy, modify and distribute this software and its   *
12  * documentation strictly for non-commercial purposes is hereby granted   *
13  * without fee, provided that the above copyright notice appears in all   *
14  * copies and that both the copyright notice and this permission notice   *
15  * appear in the supporting documentation. The authors make no claims     *
16  * about the suitability of this software for any purpose. It is          *
17  * provided "as is" without express or implied warranty.                  *
18  **************************************************************************/
19
20 /** @file   AliHLTTPCDigitReaderRaw.cxx
21     @author Timm Steinbeck
22     @date   
23     @brief  A digit reader implementation for the RAW data coming from the RCU.
24 */
25
26 #if __GNUC__>= 3
27 using namespace std;
28 #endif
29
30 #if defined(HAVE_TPC_MAPPING)
31
32 #include "AliHLTTPCDigitReaderRaw.h"
33 #include "AliHLTTPCTransform.h"
34 #include "AliHLTTPCRootTypes.h"
35 #include "AliHLTStdIncludes.h"
36 #include "AliHLTTPCLogging.h"
37
38 ClassImp(AliHLTTPCDigitReaderRaw)
39
40 AliHLTTPCDigitReaderRaw::AliHLTTPCDigitReaderRaw( unsigned formatVersion )
41   :
42   fBuffer(NULL),
43   fBufferSize(0),
44   fPatch(-1),
45   fSlice(-1),
46   fDataFormatVersion(formatVersion),
47   fCurrentRow(0),
48   fCurrentPad(0),
49   fCurrentBin(-1),
50   fVerify(false),
51   
52   // For sorting
53   fNRows(0),
54   fRowOffset(0),
55   fNMaxRows(0),
56   fNMaxPads(0),
57   fNTimeBins(0),
58   fData(NULL)
59 {
60     if ( fDataFormatVersion==0 || fDataFormatVersion==2 )
61       {
62         
63         // get max number of rows
64         for (Int_t ii=0; ii < 6; ii++)
65           if (AliHLTTPCTransform::GetNRows(ii) > fNMaxRows) 
66             fNMaxRows = AliHLTTPCTransform::GetNRows(ii);
67         
68         // get max number of pads
69         for (Int_t ii=0; ii < AliHLTTPCTransform::GetNRows();ii++ )
70           if (AliHLTTPCTransform::GetNPads(ii) > fNMaxPads) 
71             fNMaxPads = AliHLTTPCTransform::GetNPads(ii);
72         
73         // get max number of bins
74         fNTimeBins = AliHLTTPCTransform::GetNTimeBins();
75         
76         HLTDebug("Array Borders ||| MAXPAD=%d ||| MAXROW=%d ||| MAXBIN=%d ||| MAXMUL=%d", 
77                  fNMaxPads, fNMaxRows, fNTimeBins, fNTimeBins*fNMaxRows*fNMaxPads);
78         
79         // init Data array
80         fData = new Int_t[ fNMaxRows*fNMaxPads*fNTimeBins ];
81       }
82 }
83
84 AliHLTTPCDigitReaderRaw::AliHLTTPCDigitReaderRaw(const AliHLTTPCDigitReaderRaw& src)
85   :
86   fBuffer(NULL),
87   fBufferSize(0),
88   fPatch(-1),
89   fSlice(-1),
90   fDataFormatVersion(src.fDataFormatVersion),
91   fCurrentRow(0),
92   fCurrentPad(0),
93   fCurrentBin(-1),
94   fVerify(false),
95   
96   // For sorting
97   fNRows(0),
98   fRowOffset(0),
99   fNMaxRows(0),
100   fNMaxPads(0),
101   fNTimeBins(0),
102   fData(NULL)
103 {
104   HLTFatal("copy constructor not for use");
105 }
106
107 AliHLTTPCDigitReaderRaw& AliHLTTPCDigitReaderRaw::operator=(const AliHLTTPCDigitReaderRaw& src)
108 {
109   fBuffer=NULL;
110   fBufferSize=0;
111   fPatch=-1;
112   fSlice=-1;
113   fDataFormatVersion=src.fDataFormatVersion;
114   fCurrentRow=0;
115   fCurrentPad=0;
116   fCurrentBin=-1;
117   fVerify=false;
118   
119   // For sorting
120   fNRows=0;
121   fRowOffset=0;
122   fNMaxRows=0;
123   fNMaxPads=0;
124   fNTimeBins=0;
125   fData=NULL;
126   HLTFatal("assignment operator not for use");
127   return (*this);
128 }
129
130 AliHLTTPCDigitReaderRaw::~AliHLTTPCDigitReaderRaw(){
131   if ( fDataFormatVersion==0 || fDataFormatVersion==2 )
132     {
133       if ( fData )
134         delete [] fData;
135       fData = NULL;
136     }
137 }
138
139 int AliHLTTPCDigitReaderRaw::InitBlock(void* ptr,unsigned long size,Int_t firstrow,Int_t lastrow, Int_t patch, Int_t slice) {
140   return AliHLTTPCDigitReader::InitBlock(ptr, size, firstrow, lastrow, patch, slice);
141 }
142
143 int AliHLTTPCDigitReaderRaw::InitBlock(void* ptr,unsigned long size, Int_t patch, Int_t slice){
144
145     fBuffer = (AliHLTUInt8_t*) ptr;
146     if (fBuffer==NULL) {
147       HLTError("invalid data buffer");
148       return -EINVAL;
149     }
150     fBufferSize = size;
151     if (fBufferSize<=0) HLTWarning("no data available: zero length buffer");
152     fPatch = patch;
153     fSlice = slice;
154     fPad = -1;
155     fRow = -1;
156     
157     fAltroBlockPositionBytes = 0;
158     fAltroBlockLengthBytes = 0;
159     fAltroBlock10BitWordCnt = 0xFFFFU;
160     fAltroBlockHWAddress = 0xFFFFU;
161     fBunchPosition = 0xFFFFU;
162     fBunchTimebinStart = ~0U;
163     fBunchLength = 0;
164     fWordInBunch = (unsigned)-1;
165
166     Int_t firstrow=AliHLTTPCTransform::GetFirstRow(patch);
167     Int_t lastrow=AliHLTTPCTransform::GetLastRow(patch);
168
169     if ( fDataFormatVersion==0 || fDataFormatVersion==2 )
170       {
171         fCurrentRow = 0;
172         fCurrentPad = 0;
173         fCurrentBin = -1;
174         
175         fNRows = lastrow - firstrow + 1;
176         
177         Int_t offset=0;
178         if (patch > 1) offset =  AliHLTTPCTransform::GetFirstRow( 2 );
179         
180         fRowOffset = firstrow - offset;
181         firstrow -= offset;
182         lastrow  -= offset;
183         
184         // Init array with -1
185         memset( fData, 0xFF, sizeof(Int_t)*(fNMaxRows*fNMaxPads*fNTimeBins) );
186
187         const Int_t maxErrorPrintout=20;
188         Int_t errorCount=0;
189         Int_t entryCount=0;
190         // read data and fill in array
191
192         while( RealNext()){
193
194           entryCount++;
195           Int_t row = GetRealRow();
196           Int_t pad = GetRealPad();
197           Int_t bin = GetRealTime();
198           
199 //        HLTFatal("Index out of array range: PAD=%d ||| ROW=%d ||| BIN=%d ||| OFFSET=%d ||| ROWOFFSET=%d", pad, row, bin, offset, fRowOffset);
200
201           if ( row < firstrow || row > lastrow || pad > AliHLTTPCTransform::GetNPads(row + offset) || bin > fNTimeBins || pad<0 || bin<0){
202 //        if ( row < firstrow || row > lastrow || pad > AliHLTTPCTransform::GetNPads(row + offset) || bin > fNTimeBins){
203             if (errorCount++<maxErrorPrintout) {
204               HLTFatal("Index out of range. Probably wrong patch! slice %d - patch %d", slice, patch);
205               HLTFatal("PAD=%d out of %d ||| ROW=%d (%d to %d)  ||| BIN=%d out of %d  ||| OFFSET=%d ||| ROWOFFSET=%d",
206                        pad, AliHLTTPCTransform::GetNPads(row + offset), row, firstrow, lastrow, bin, fNTimeBins,
207                        offset, fRowOffset);
208
209               if ( row < firstrow || row > lastrow ) 
210                 HLTFatal("Row out of range: %d  ( %d to %d)", row, firstrow, lastrow);
211               if ( pad > AliHLTTPCTransform::GetNPads(row + offset) ) 
212                 HLTFatal("Pad out of range: %d  (pad count %d)", pad, AliHLTTPCTransform::GetNPads(row + offset));
213               if ( bin > fNTimeBins )
214                 HLTFatal("Time bin out of range: %d (bin count %d)", bin, fNTimeBins);
215             }
216             // stop at the fist error message in order to avoid endless messages and
217             // to handle corrupted events
218             //continue;
219             break;
220           } else if ((row-fRowOffset)*fNMaxPads*fNTimeBins+ pad*fNTimeBins + bin >=  fNMaxRows*fNMaxPads*fNTimeBins ) {
221             if (errorCount++<maxErrorPrintout) {
222               HLTFatal("index out of range: PAD=%d ||| ROW=%d ||| BIN=%d ||| OFFSET=%d ||| ROWOFFSET=%d", pad, row, bin, offset, fRowOffset);
223             }
224             // stop at the fist error message in order to avoid endless messages and
225             // to handle corrupted events
226             //continue;
227             break;
228           } else {
229             fData[ (row-fRowOffset)*fNMaxPads*fNTimeBins+ pad*fNTimeBins + bin ] = GetRealSignal() ;
230           }
231         }
232         if (errorCount>0) {
233           HLTFatal("%d of %d entries out of range", errorCount, entryCount);
234         }
235       }
236
237     return 0;
238 }
239
240 bool AliHLTTPCDigitReaderRaw::Next(){
241   if ( fDataFormatVersion==0 || fDataFormatVersion==2 )
242     {
243       Bool_t readvalue = kTRUE;
244       while (1) {
245         fCurrentBin++;
246         if (fCurrentBin >= fNTimeBins){
247           fCurrentBin = 0;
248           fCurrentPad++;
249           
250           if (fCurrentPad >=fNMaxPads){
251             fCurrentPad = 0;
252             fCurrentRow++;
253             
254             if (fCurrentRow >= fNMaxRows){
255               readvalue = kFALSE;
256               break;
257             }
258           }
259         }
260         
261         if (fCurrentRow*fNMaxPads*fNTimeBins+ fCurrentPad*fNTimeBins + fCurrentBin >=  fNMaxRows*fNMaxPads*fNTimeBins ) {
262           HLTFatal("Overflow: fCurrentRow=%d fCurrentPad=%d fCurrentBin=%d", fCurrentRow, fCurrentPad, fCurrentBin);
263           readvalue = kFALSE;
264           break;
265         }
266         
267         if (fData[ fCurrentRow*fNMaxPads*fNTimeBins + fCurrentPad*fNTimeBins + fCurrentBin  ] != -1) break;
268       }
269       return readvalue;
270     }
271   else
272     return RealNext();
273 }
274
275 int AliHLTTPCDigitReaderRaw::GetRow(){
276   if ( fDataFormatVersion==0 || fDataFormatVersion==2 )
277     {
278       return (fCurrentRow + fRowOffset);
279     }
280   else
281     return GetRealRow();
282 }
283 int AliHLTTPCDigitReaderRaw::GetPad(){
284   if ( fDataFormatVersion==0 || fDataFormatVersion==2 )
285     {
286       return fCurrentPad;
287     }
288   else
289     return GetRealPad();
290 }
291 int AliHLTTPCDigitReaderRaw::GetSignal(){
292   if ( fDataFormatVersion==0 || fDataFormatVersion==2 )
293     {
294       return fData[ fCurrentRow*fNMaxPads*fNTimeBins+ fCurrentPad*fNTimeBins + fCurrentBin ];
295     }
296   else
297     return GetRealSignal();
298 }
299 int AliHLTTPCDigitReaderRaw::GetTime(){
300   if ( fDataFormatVersion==0 || fDataFormatVersion==2 )
301     {
302       return fCurrentBin;
303     }
304   else
305     return GetRealTime();
306 }
307
308
309 bool AliHLTTPCDigitReaderRaw::RealNext(){
310 //    printf( "%u %u %u %u %u\n", fBunchPosition, fBunchLength, fBunchTimebinStart, fWordInBunch, (unsigned)fAltroBlock10BitWordCnt );
311     fWordInBunch++; // use next word in bunch
312     if ( fWordInBunch==fBunchLength ) { // we have a bunch at all but have reached its end (or do not have an altro block yet)
313         if ( fBunchPosition+fBunchLength==fAltroBlock10BitWordCnt ) { // We were at the last bunch of this altro block (or do not have an altro block yet)
314             if ( !NextAltroBlock() )
315                 return false;
316             fBunchPosition = 0;
317         }
318         else {
319             fBunchPosition += fBunchLength;
320         }
321         fBunchLength = GetAltroBlock10BitWord( fBunchPosition );
322         fBunchTimebinStart = GetAltroBlock10BitWord( fBunchPosition+1 );
323         fWordInBunch = 2;
324     }
325     //HLTDebug( "%u %u %u %u %u\n", fBunchPosition, fBunchLength, fBunchTimebinStart, fWordInBunch, (unsigned)fAltroBlock10BitWordCnt );
326     return true;
327 }
328 int AliHLTTPCDigitReaderRaw::GetRealRow(){
329     return fRow;
330 }
331 int AliHLTTPCDigitReaderRaw::GetRealPad(){
332     return fPad;
333 }
334 int AliHLTTPCDigitReaderRaw::GetRealSignal(){
335     return GetAltroBlock10BitWord( fBunchPosition+fWordInBunch );
336 }
337 int AliHLTTPCDigitReaderRaw::GetRealTime(){
338   //HLTDebug( "GetRealTime: %u - %u\n", fBunchTimebinStart, fWordInBunch );
339     return fBunchTimebinStart-(fWordInBunch-2);
340 }
341
342 AliHLTUInt32_t AliHLTTPCDigitReaderRaw::GetRCUTrailer(){
343   if (fBufferSize<=0) return 0;
344   unsigned rcuDataBlockLen = GetRCUDataBlockLength(); 
345   return *((AliHLTUInt32_t*)(fBuffer+fBufferSize-rcuDataBlockLen));
346 }
347
348 bool AliHLTTPCDigitReaderRaw::NextAltroBlock()
349     {
350     if (fBufferSize<=0) return 0;
351     if ( !fAltroBlockLengthBytes )
352         {
353         // First block in back linked list (last block in memory)
354         fAltroBlockPositionBytes = fBufferSize-GetRCUDataBlockLength();
355         }
356     else
357         {
358         if ( fAltroBlockPositionBytes<fAltroBlockLengthBytes+GetCommonDataHeaderSize() )
359           {
360             HLTFatal("Inconsistent Data: fAltroBlockPositionBytes=%d fAltroBlockLengthBytes=%d", fAltroBlockPositionBytes, fAltroBlockLengthBytes);
361           }
362         if ( fAltroBlockPositionBytes<=fAltroBlockLengthBytes+GetCommonDataHeaderSize() )
363             return false; // We have reached the end of the back linked list
364         fAltroBlockPositionBytes -= fAltroBlockLengthBytes;
365         }
366
367       AliHLTUInt64_t altroTrailerWord = GetAltroBlock40BitWord( 0 );
368
369       if ( fVerify && ((altroTrailerWord & 0xFFFC000000ULL)!=0xAAA8000000ULL) )
370         {
371           HLTFatal("Data inconsistency in Altro Block at byte position %#x (%d): Expected 0x2AAA in high 14 bits of altro trailer word; Found %#llx (%#llx)",
372                    fAltroBlockPositionBytes, fAltroBlockPositionBytes, 
373                    ((altroTrailerWord & 0xFFFC000000ULL) >> 26), altroTrailerWord);
374
375
376           return false;
377         }
378
379       if ( fVerify && ((altroTrailerWord & 0x000000F000ULL)!=0x000000A000ULL) )
380         {
381           HLTFatal("Data inconsistency in Altro Block at byte position %#x (%d): Expected 0xA in bits 12-15 of altro trailer word; Found %#llx .",
382                    fAltroBlockPositionBytes, fAltroBlockPositionBytes,  ((altroTrailerWord & 0x000000F000ULL) >> 12)); 
383
384           return false;
385         }
386
387       fAltroBlock10BitWordCnt = (altroTrailerWord >> 16) & 0x3FF;
388       fAltroBlockHWAddress = altroTrailerWord & 0xFFF;
389
390       // ApplyMapping
391       if (!ApplyMapping())
392         {
393           HLTFatal("Mapping failed Patch %d HWA %#x (%d) - maxHWA %#x (%d)",
394                    fPatch, fAltroBlockHWAddress, fAltroBlockHWAddress, fMaxHWA[fPatch], fMaxHWA[fPatch]);
395
396         }
397
398       unsigned words40Bit = fAltroBlock10BitWordCnt/4;
399       if ( fAltroBlock10BitWordCnt % 4 )
400           words40Bit++;
401       words40Bit++;
402       fAltroBlockLengthBytes = words40Bit*5;
403     if ( fAltroBlock10BitWordCnt % 4 )
404         fAltroBlock10BitFillWordCnt = 4-(fAltroBlock10BitWordCnt % 4);
405     else
406         fAltroBlock10BitFillWordCnt=0;
407     if ( fVerify )
408       {
409         for ( unsigned b = 0; b < fAltroBlock10BitFillWordCnt; b++ )
410           {
411             if ( GetAltroBlockReal10BitWord(b)!=0x2AA )
412               {
413                 HLTFatal("Data inconsistency in trailing 10 bit fill word of Altro Block at byte position %#x (%d): Expected 0x2AA; Found %#x",
414                          fAltroBlockPositionBytes, fAltroBlockPositionBytes, GetAltroBlockReal10BitWord(b));
415                 
416                 return false;
417               }
418           }
419       }
420     return true;
421     }
422
423 AliHLTUInt32_t AliHLTTPCDigitReaderRaw::GetAltroBlockHWaddr(){
424 return fAltroBlockHWAddress;
425 }
426 unsigned AliHLTTPCDigitReaderRaw::GetAltroBlock10BitWordCnt(){
427 return fAltroBlock10BitWordCnt;
428 }
429 AliHLTUInt64_t AliHLTTPCDigitReaderRaw::GetAltroBlock40BitWord( unsigned long ndx ){
430 AliHLTUInt64_t val=0;
431 unsigned wordOffset32Bit = (ndx / 4)*5;
432 switch ( ndx % 4 ) // 40 bit word index in a 4*40 bit=5*32 bit group
433     {
434     case 0:
435         val = (*(AliHLTUInt32_t*)(fBuffer+fAltroBlockPositionBytes-(wordOffset32Bit+1)*sizeof(AliHLTUInt32_t)));
436         val <<= 8;
437         val |= (*(AliHLTUInt32_t*)(fBuffer+fAltroBlockPositionBytes-(wordOffset32Bit+2)*sizeof(AliHLTUInt32_t))) >> 24;
438         break;
439     case 1:
440         val = ((*(AliHLTUInt32_t*)(fBuffer+fAltroBlockPositionBytes-(wordOffset32Bit+2)*sizeof(AliHLTUInt32_t))) & 0x00FFFFFF);
441         val <<= 16;
442         val |= ((*(AliHLTUInt32_t*)(fBuffer+fAltroBlockPositionBytes-(wordOffset32Bit+3)*sizeof(AliHLTUInt32_t))) >> 16) & 0xFFFF;
443         break;
444     case 2:
445         val = ((*(AliHLTUInt32_t*)(fBuffer+fAltroBlockPositionBytes-(wordOffset32Bit+3)*sizeof(AliHLTUInt32_t))) & 0xFFFF);
446         val <<= 24;
447         val |= ((*(AliHLTUInt32_t*)(fBuffer+fAltroBlockPositionBytes-(wordOffset32Bit+4)*sizeof(AliHLTUInt32_t))) >> 8);
448         break;
449     case 3:
450         val = ((*(AliHLTUInt32_t*)(fBuffer+fAltroBlockPositionBytes-(wordOffset32Bit+4)*sizeof(AliHLTUInt32_t))) & 0xFF);
451         val <<= 32;
452         val |= *(AliHLTUInt32_t*)(fBuffer+fAltroBlockPositionBytes-(wordOffset32Bit+5)*sizeof(AliHLTUInt32_t));
453         break;
454     }
455 return val;
456 }
457 AliHLTUInt16_t AliHLTTPCDigitReaderRaw::GetAltroBlock10BitWord( unsigned long ndx ){
458 unsigned long realNdx = ndx+fAltroBlock10BitFillWordCnt;
459 unsigned long word40BitNdx = (realNdx / 4)+1;
460 AliHLTUInt64_t word40Bit = GetAltroBlock40BitWord( word40BitNdx );
461 switch ( realNdx % 4 )
462     {
463     case 3:
464         return word40Bit & 0x3FF;
465     case 2:
466         return (word40Bit>>10) & 0x3FF;
467     case 1:
468         return (word40Bit>>20) & 0x3FF;
469     case 0:
470         return (word40Bit>>30) & 0x3FF;
471     }
472
473  return 0xFFFF; 
474 }
475
476 AliHLTUInt16_t AliHLTTPCDigitReaderRaw::GetAltroBlockReal10BitWord( unsigned long ndx ){
477 unsigned long word40BitNdx = (ndx / 4)+1;
478 AliHLTUInt64_t word40Bit = GetAltroBlock40BitWord( word40BitNdx );
479 switch ( ndx % 4 )
480     {
481     case 3:
482         return word40Bit & 0x3FF;
483     case 2:
484         return (word40Bit>>10) & 0x3FF;
485     case 1:
486         return (word40Bit>>20) & 0x3FF;
487     case 0:
488         return (word40Bit>>30) & 0x3FF;
489     }
490
491  return 0xFFFF; 
492 }
493
494 // Return length of trailing RCU data block in bytes
495 unsigned AliHLTTPCDigitReaderRaw::GetRCUDataBlockLength() const
496     {
497     switch ( fDataFormatVersion )
498         {
499         case 0:
500         case 1:
501             return 4;
502             break;
503         case 2:
504         case 3:
505             return 12;
506             break;
507         default:
508             return fBufferSize;
509         }
510     }
511
512 unsigned AliHLTTPCDigitReaderRaw::GetCommonDataHeaderSize() const
513     {
514     return 32;
515     }
516
517
518 Bool_t AliHLTTPCDigitReaderRaw::ApplyMapping(){
519
520     if ( (unsigned)fAltroBlockHWAddress > fMaxHWA[fPatch]){
521         fPad = -1;
522         fRow = -1;
523         return kFALSE;
524     }
525
526     switch(fPatch){
527         case 0:
528             fRow = fMapping_0[(unsigned)fAltroBlockHWAddress][0];
529             fPad = fMapping_0[(unsigned)fAltroBlockHWAddress][1];
530             break;
531         case 1:
532             fRow = AliHLTTPCDigitReaderRaw::fMapping_1[(unsigned)fAltroBlockHWAddress][0];
533             fPad = AliHLTTPCDigitReaderRaw::fMapping_1[(unsigned)fAltroBlockHWAddress][1];
534 #if 0
535             printf ("pad %d # row %d (hwa: %u / 0x%08X\n", fMapping_1[(unsigned)fAltroBlockHWAddress][0],fMapping_1[(unsigned)fAltroBlockHWAddress][1], (unsigned)fAltroBlockHWAddress, (unsigned)fAltroBlockHWAddress);
536             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);
537             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);
538 #endif
539             break;
540         case 2:
541             fRow = fMapping_2[(unsigned)fAltroBlockHWAddress][0];
542             fPad = fMapping_2[(unsigned)fAltroBlockHWAddress][1];
543             break;
544         case 3:
545             fRow = fMapping_3[(unsigned)fAltroBlockHWAddress][0];
546             fPad = fMapping_3[(unsigned)fAltroBlockHWAddress][1];
547             break;
548         case 4:
549             fRow = fMapping_4[(unsigned)fAltroBlockHWAddress][0];
550             fPad = fMapping_4[(unsigned)fAltroBlockHWAddress][1];
551             break;
552         case 5:
553             fRow = fMapping_5[(unsigned)fAltroBlockHWAddress][0];
554             fPad = fMapping_5[(unsigned)fAltroBlockHWAddress][1];
555             break;
556         default:
557             fRow = -1;
558             fPad = -1;
559             return kFALSE;
560     }
561     return kTRUE;
562 }
563
564
565 Int_t AliHLTTPCDigitReaderRaw::GetRow( unsigned patch, unsigned hw_addr )
566 {
567     if ( (unsigned)hw_addr > fMaxHWA[fPatch]){
568         return -1;
569     }
570
571     switch(fPatch){
572         case 0:
573             return fMapping_0[hw_addr][0];
574         case 1:
575             return fMapping_1[hw_addr][0];
576         case 2:
577             return fMapping_2[hw_addr][0];
578         case 3:
579             return fMapping_3[hw_addr][0];
580         case 4:
581             return fMapping_4[hw_addr][0];
582         case 5:
583             return fMapping_5[hw_addr][0];
584         default:
585           return -1;
586     }
587 }
588 Int_t AliHLTTPCDigitReaderRaw::GetPad( unsigned patch, unsigned hw_addr )
589 {
590     if ( (unsigned)hw_addr > fMaxHWA[fPatch]){
591         return -1;
592     }
593
594     switch(fPatch){
595         case 0:
596             return fMapping_0[hw_addr][1];
597         case 1:
598             return fMapping_1[hw_addr][1];
599         case 2:
600             return fMapping_2[hw_addr][1];
601         case 3:
602             return fMapping_3[hw_addr][1];
603         case 4:
604             return fMapping_4[hw_addr][1];
605         case 5:
606             return fMapping_5[hw_addr][1];
607         default:
608           return -1;
609     }
610 }
611
612 unsigned AliHLTTPCDigitReaderRaw::GetMaxHWA( unsigned patch )
613 {
614   if ( patch>=6 )
615     return 0;
616   return fMaxHWA[patch];
617 }
618
619
620 // ----- MAPPING ARRAYS
621 #include "mapping_array_out.inc"
622
623 #endif //#if defined(HAVE_TPC_MAPPING)