]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/TPCLib/AliHLTTPCDigitReaderRaw.cxx
build system clean-up, support for custom LinkDef added
[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   fVerify(false),
54   fBunchPosition(0xFFFFU),
55   fBunchTimebinStart(~0U),
56   fBunchLength(0),
57   fWordInBunch((unsigned)-1),
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(const AliHLTTPCDigitReaderRaw& src)
109   :
110   fBuffer(NULL),
111   fBufferSize(0),
112   fPatch(-1),
113   fSlice(-1),
114   fRow(-1),
115   fPad(-1),
116   fAltroBlockPositionBytes(0),
117   fAltroBlockLengthBytes(0),
118   fAltroBlockHWAddress(0),
119   fAltroBlock10BitWordCnt(0),
120   fAltroBlock10BitFillWordCnt(0),
121   fDataFormatVersion(src.fDataFormatVersion),
122   fVerify(false),
123   fBunchPosition(0xFFFFU),
124   fBunchTimebinStart(~0U),
125   fBunchLength(0),
126   fWordInBunch((unsigned)-1),
127   
128   fCurrentRow(0),
129   fCurrentPad(0),
130   fCurrentBin(-1),
131   fRowOffset(0),
132   fNRows(0),
133   fNMaxRows(0),
134   fNMaxPads(0),
135   fNTimeBins(0),
136   fData(NULL),
137   fMapErrThrown(0)
138 {
139   // see header file for class documentation
140 #ifndef HAVE_TPC_MAPPING
141   memset(fgMapping0, 0, fgkMapping0Size*fgkMappingDimension*sizeof(Int_t));
142   memset(fgMapping1, 0, fgkMapping1Size*fgkMappingDimension*sizeof(Int_t));
143   memset(fgMapping2, 0, fgkMapping2Size*fgkMappingDimension*sizeof(Int_t));
144   memset(fgMapping3, 0, fgkMapping3Size*fgkMappingDimension*sizeof(Int_t));
145   memset(fgMapping4, 0, fgkMapping4Size*fgkMappingDimension*sizeof(Int_t));
146   memset(fgMapping5, 0, fgkMapping5Size*fgkMappingDimension*sizeof(Int_t));
147 #endif //#ifndef HAVE_TPC_MAPPING
148   HLTFatal("copy constructor not for use");
149 }
150
151 AliHLTTPCDigitReaderRaw& AliHLTTPCDigitReaderRaw::operator=(const AliHLTTPCDigitReaderRaw& src)
152 {
153   // see header file for class documentation
154 #ifndef HAVE_TPC_MAPPING
155   memset(fgMapping0, 0, fgkMapping0Size*fgkMappingDimension*sizeof(Int_t));
156   memset(fgMapping1, 0, fgkMapping1Size*fgkMappingDimension*sizeof(Int_t));
157   memset(fgMapping2, 0, fgkMapping2Size*fgkMappingDimension*sizeof(Int_t));
158   memset(fgMapping3, 0, fgkMapping3Size*fgkMappingDimension*sizeof(Int_t));
159   memset(fgMapping4, 0, fgkMapping4Size*fgkMappingDimension*sizeof(Int_t));
160   memset(fgMapping5, 0, fgkMapping5Size*fgkMappingDimension*sizeof(Int_t));
161 #endif //#ifndef HAVE_TPC_MAPPING
162   fBuffer=NULL;
163   fBufferSize=0;
164   fPatch=-1;
165   fSlice=-1;
166   fRow=-1;
167   fPad=-1;
168   fDataFormatVersion=src.fDataFormatVersion;
169   fCurrentRow=0;
170   fCurrentPad=0;
171   fCurrentBin=-1;
172   fVerify=false;
173   
174   // For sorting
175   fNRows=0;
176   fRowOffset=0;
177   fNMaxRows=0;
178   fNMaxPads=0;
179   fNTimeBins=0;
180   fData=NULL;
181   fMapErrThrown=0;
182   HLTFatal("assignment operator not for use");
183   return (*this);
184 }
185
186 AliHLTTPCDigitReaderRaw::~AliHLTTPCDigitReaderRaw()
187 {
188   // see header file for class documentation
189   if ( fDataFormatVersion==0 || fDataFormatVersion==2 || fDataFormatVersion==4 )
190     {
191       if ( fData )
192         delete [] fData;
193       fData = NULL;
194     }
195 }
196
197 int AliHLTTPCDigitReaderRaw::InitBlock(void* ptr,unsigned long size,Int_t firstrow,Int_t lastrow, Int_t patch, Int_t slice) 
198 {
199   // see header file for class documentation
200   return AliHLTTPCDigitReader::InitBlock(ptr, size, firstrow, lastrow, patch, slice);
201 }
202
203 int AliHLTTPCDigitReaderRaw::InitBlock(void* ptr,unsigned long size, Int_t patch, Int_t slice)
204 {
205   // see header file for class documentation
206
207     fBuffer = (AliHLTUInt8_t*) ptr;
208     if (fBuffer==NULL) {
209       HLTError("invalid data buffer");
210       return -EINVAL;
211     }
212     fBufferSize = size;
213     if (fBufferSize<=0) HLTWarning("no data available: zero length buffer");
214     fPatch = patch;
215     fSlice = slice;
216     fPad = -1;
217     fRow = -1;
218     
219     fAltroBlockPositionBytes = 0;
220     fAltroBlockLengthBytes = 0;
221     fAltroBlock10BitWordCnt = 0xFFFFU;
222     fAltroBlockHWAddress = 0xFFFFU;
223     fBunchPosition = 0xFFFFU;
224     fBunchTimebinStart = ~0U;
225     fBunchLength = 0;
226     fWordInBunch = (unsigned)-1;
227
228     Int_t firstrow=AliHLTTPCTransform::GetFirstRow(patch);
229     Int_t lastrow=AliHLTTPCTransform::GetLastRow(patch);
230
231     if ( fDataFormatVersion==0 || fDataFormatVersion==2 || fDataFormatVersion==4 )
232       {
233         fCurrentRow = 0;
234         fCurrentPad = 0;
235         fCurrentBin = -1;
236         
237         fNRows = lastrow - firstrow + 1;
238         
239         Int_t offset=0;
240         if (patch > 1) offset =  AliHLTTPCTransform::GetFirstRow( 2 );
241         
242         fRowOffset = firstrow - offset;
243         firstrow -= offset;
244         lastrow  -= offset;
245         
246         // Init array with -1
247         memset( fData, 0xFF, sizeof(Int_t)*(fNMaxRows*fNMaxPads*fNTimeBins) );
248
249         const Int_t kMaxErrorPrintout=20;
250         Int_t errorCount=0;
251         Int_t entryCount=0;
252         // read data and fill in array
253
254         while( RealNext()){
255
256           entryCount++;
257           Int_t row = GetRealRow();
258           Int_t pad = GetRealPad();
259           Int_t bin = GetRealTime();
260           
261 //        HLTFatal("Index out of array range: PAD=%d ||| ROW=%d ||| BIN=%d ||| OFFSET=%d ||| ROWOFFSET=%d", pad, row, bin, offset, fRowOffset);
262
263           if ( row < firstrow || row > lastrow || pad > AliHLTTPCTransform::GetNPads(row + offset) || bin > fNTimeBins || pad<0 || bin<0){
264 //        if ( row < firstrow || row > lastrow || pad > AliHLTTPCTransform::GetNPads(row + offset) || bin > fNTimeBins){
265             if (errorCount++<kMaxErrorPrintout) {
266               HLTFatal("Index out of range. Probably wrong patch! slice %d - patch %d", slice, patch);
267               HLTFatal("PAD=%d out of %d ||| ROW=%d (%d to %d)  ||| BIN=%d out of %d  ||| OFFSET=%d ||| ROWOFFSET=%d",
268                        pad, AliHLTTPCTransform::GetNPads(row + offset), row, firstrow, lastrow, bin, fNTimeBins,
269                        offset, fRowOffset);
270
271               if ( row < firstrow || row > lastrow ) 
272                 HLTFatal("Row out of range: %d  ( %d to %d)", row, firstrow, lastrow);
273               if ( pad > AliHLTTPCTransform::GetNPads(row + offset) ) 
274                 HLTFatal("Pad out of range: %d  (pad count %d)", pad, AliHLTTPCTransform::GetNPads(row + offset));
275               if ( bin > fNTimeBins )
276                 HLTFatal("Time bin out of range: %d (bin count %d)", bin, fNTimeBins);
277             }
278             // stop at the fist error message in order to avoid endless messages and
279             // to handle corrupted events
280             //continue;
281             break;
282           } else if ((row-fRowOffset)*fNMaxPads*fNTimeBins+ pad*fNTimeBins + bin >=  fNMaxRows*fNMaxPads*fNTimeBins ) {
283             if (errorCount++<kMaxErrorPrintout) {
284               HLTFatal("index out of range: PAD=%d ||| ROW=%d ||| BIN=%d ||| OFFSET=%d ||| ROWOFFSET=%d", pad, row, bin, offset, fRowOffset);
285             }
286             // stop at the fist error message in order to avoid endless messages and
287             // to handle corrupted events
288             //continue;
289             break;
290           } else {
291             fData[ (row-fRowOffset)*fNMaxPads*fNTimeBins+ pad*fNTimeBins + bin ] = GetRealSignal() ;
292           }
293         }
294         if (errorCount>0) {
295           HLTFatal("%d of %d entries out of range", errorCount, entryCount);
296         }
297       }
298
299     return 0;
300 }
301
302 bool AliHLTTPCDigitReaderRaw::Next()
303 {
304   // see header file for class documentation
305
306   if ( fDataFormatVersion==0 || fDataFormatVersion==2 || fDataFormatVersion==4 )
307     {
308       Bool_t readvalue = kTRUE;
309       while (1) {
310         fCurrentBin++;
311         if (fCurrentBin >= fNTimeBins){
312           fCurrentBin = 0;
313           fCurrentPad++;
314           
315           if (fCurrentPad >=fNMaxPads){
316             fCurrentPad = 0;
317             fCurrentRow++;
318             
319             if (fCurrentRow >= fNMaxRows){
320               readvalue = kFALSE;
321               break;
322             }
323           }
324         }
325         
326         if (fCurrentRow*fNMaxPads*fNTimeBins+ fCurrentPad*fNTimeBins + fCurrentBin >=  fNMaxRows*fNMaxPads*fNTimeBins ) {
327           HLTFatal("Overflow: fCurrentRow=%d fCurrentPad=%d fCurrentBin=%d", fCurrentRow, fCurrentPad, fCurrentBin);
328           readvalue = kFALSE;
329           break;
330         }
331         
332         if (fData[ fCurrentRow*fNMaxPads*fNTimeBins + fCurrentPad*fNTimeBins + fCurrentBin  ] != -1) break;
333       }
334       return readvalue;
335     }
336   else
337     return RealNext();
338 }
339
340 int AliHLTTPCDigitReaderRaw::GetRow()
341 {
342   // see header file for class documentation
343
344   if ( fDataFormatVersion==0 || fDataFormatVersion==2 || fDataFormatVersion==4 )
345     {
346       return (fCurrentRow + fRowOffset);
347     }
348   else
349     return GetRealRow();
350 }
351
352 int AliHLTTPCDigitReaderRaw::GetPad()
353 {
354   // see header file for class documentation
355
356   if ( fDataFormatVersion==0 || fDataFormatVersion==2 || fDataFormatVersion==4 )
357     {
358       return fCurrentPad;
359     }
360   else
361     return GetRealPad();
362 }
363
364 int AliHLTTPCDigitReaderRaw::GetSignal()
365 {
366   // see header file for class documentation
367
368   if ( fDataFormatVersion==0 || fDataFormatVersion==2 || fDataFormatVersion==4 )
369     {
370       return fData[ fCurrentRow*fNMaxPads*fNTimeBins+ fCurrentPad*fNTimeBins + fCurrentBin ];
371     }
372   else
373     return GetRealSignal();
374 }
375
376 int AliHLTTPCDigitReaderRaw::GetTime()
377 {
378   // see header file for class documentation
379
380   if ( fDataFormatVersion==0 || fDataFormatVersion==2 || fDataFormatVersion==4 )
381     {
382       return fCurrentBin;
383     }
384   else
385     return GetRealTime();
386 }
387
388 bool AliHLTTPCDigitReaderRaw::RealNext()
389 {
390   // see header file for class documentation
391
392 //    printf( "%u %u %u %u %u\n", fBunchPosition, fBunchLength, fBunchTimebinStart, fWordInBunch, (unsigned)fAltroBlock10BitWordCnt );
393     fWordInBunch++; // use next word in bunch
394     if ( fWordInBunch==fBunchLength ) { // we have a bunch at all but have reached its end (or do not have an altro block yet)
395         if ( fBunchPosition+fBunchLength==fAltroBlock10BitWordCnt ) { // We were at the last bunch of this altro block (or do not have an altro block yet)
396             if ( !NextAltroBlock() )
397                 return false;
398             fBunchPosition = 0;
399         }
400         else {
401             fBunchPosition += fBunchLength;
402         }
403         fBunchLength = GetAltroBlock10BitWord( fBunchPosition );
404         fBunchTimebinStart = GetAltroBlock10BitWord( fBunchPosition+1 );
405         fWordInBunch = 2;
406     }
407     //HLTDebug( "%u %u %u %u %u\n", fBunchPosition, fBunchLength, fBunchTimebinStart, fWordInBunch, (unsigned)fAltroBlock10BitWordCnt );
408     return true;
409 }
410
411 int AliHLTTPCDigitReaderRaw::GetRealRow() const
412 {
413   // see header file for class documentation
414     return fRow;
415 }
416
417 int AliHLTTPCDigitReaderRaw::GetRealPad() const
418 {
419   // see header file for class documentation
420     return fPad;
421 }
422
423 int AliHLTTPCDigitReaderRaw::GetRealSignal()
424 {
425   // see header file for class documentation
426     return GetAltroBlock10BitWord( fBunchPosition+fWordInBunch );
427 }
428
429 int AliHLTTPCDigitReaderRaw::GetRealTime() const
430 {
431   // see header file for class documentation
432   //HLTDebug( "GetRealTime: %u - %u\n", fBunchTimebinStart, fWordInBunch );
433     return fBunchTimebinStart-(fWordInBunch-2);
434 }
435
436 AliHLTUInt32_t AliHLTTPCDigitReaderRaw::GetRCUTrailer( unsigned offset ) const
437 {
438   // see header file for class documentation
439   if (fBufferSize<=0) return 0;
440   unsigned rcuDataBlockLen = GetRCUDataBlockLength(); 
441   if ( offset >= rcuDataBlockLen ) return 0;
442   return ((AliHLTUInt32_t*)(fBuffer+fBufferSize-rcuDataBlockLen))[offset];
443 }
444
445 bool AliHLTTPCDigitReaderRaw::NextAltroBlock()
446 {
447   // see header file for class documentation
448     if (fBufferSize<=0) return 0;
449     bool first = false;
450     if ( !fAltroBlockLengthBytes )
451         {
452         // First block in back linked list (last block in memory)
453         fAltroBlockPositionBytes = fBufferSize-GetRCUDataBlockLength();
454         first = true;
455         }
456     else
457         {
458         if ( fAltroBlockPositionBytes<fAltroBlockLengthBytes+GetCommonDataHeaderSize() )
459           {
460             HLTFatal("Inconsistent Data: fAltroBlockPositionBytes=%d fAltroBlockLengthBytes=%d", fAltroBlockPositionBytes, fAltroBlockLengthBytes);
461           }
462         if ( fAltroBlockPositionBytes<=fAltroBlockLengthBytes+GetCommonDataHeaderSize() )
463             return false; // We have reached the end of the back linked list
464         fAltroBlockPositionBytes -= fAltroBlockLengthBytes;
465         }
466
467       AliHLTUInt64_t altroTrailerWord = GetAltroBlock40BitWord( 0 );
468       // Undefined hack from experience to match fill words appearing in simulated data
469       // Seem to be between 0 and 3 fill words, most likely to bring the number of 40bit words
470       // to a multiple of four / to bring the total number of bytes to a common multiple of 4 and 5.
471       // (RCU sends 40 bit (5 byte) words, DDL uses 32 bit (4 bytes) words.
472       unsigned short tmpCnt=0;
473       //HLTDebug( "Altro trailer word 0: 0x%016LX\n", altroTrailerWord );
474       while ( first && altroTrailerWord==0x000000AAAAAAAAAAULL && tmpCnt++<4 ) // Allow up to 4 fill values
475         {
476           altroTrailerWord = GetAltroBlock40BitWord( tmpCnt );
477           //HLTDebug( "Altro trailer word %hu: 0x%016LX\n", tmpCnt, altroTrailerWord );
478         }
479
480       fAltroBlockPositionBytes -= 5*tmpCnt;
481       if ( fVerify && ((altroTrailerWord & 0xFFFC000000ULL)!=0xAAA8000000ULL) )
482         {
483           HLTFatal("Data inconsistency in Altro Block at byte position %#x (%d): Expected 0x2AAA in high 14 bits of altro trailer word; Found %#llx (%#llx)",
484                    fAltroBlockPositionBytes, fAltroBlockPositionBytes, 
485                    ((altroTrailerWord & 0xFFFC000000ULL) >> 26), altroTrailerWord);
486
487
488           return false;
489         }
490
491       if ( fVerify && ((altroTrailerWord & 0x000000F000ULL)!=0x000000A000ULL) )
492         {
493           HLTFatal("Data inconsistency in Altro Block at byte position %#x (%d): Expected 0xA in bits 12-15 of altro trailer word; Found %#llx .",
494                    fAltroBlockPositionBytes, fAltroBlockPositionBytes,  ((altroTrailerWord & 0x000000F000ULL) >> 12)); 
495
496           return false;
497         }
498
499       fAltroBlock10BitWordCnt = (altroTrailerWord >> 16) & 0x3FF;
500       fAltroBlockHWAddress = altroTrailerWord & 0xFFF;
501
502       // ApplyMapping
503       if (!ApplyMapping())
504         {
505           HLTFatal("Mapping failed Patch %d HWA %#x (%d) - maxHWA %#x (%d)",
506                    fPatch, fAltroBlockHWAddress, fAltroBlockHWAddress, fgMaxHWA[fPatch], fgMaxHWA[fPatch]);
507
508         }
509
510       unsigned words40Bit = fAltroBlock10BitWordCnt/4;
511       if ( fAltroBlock10BitWordCnt % 4 )
512           words40Bit++;
513       words40Bit++;
514       fAltroBlockLengthBytes = words40Bit*5;
515     if ( fAltroBlock10BitWordCnt % 4 )
516         fAltroBlock10BitFillWordCnt = 4-(fAltroBlock10BitWordCnt % 4);
517     else
518         fAltroBlock10BitFillWordCnt=0;
519     if ( fVerify )
520       {
521         for ( unsigned b = 0; b < fAltroBlock10BitFillWordCnt; b++ )
522           {
523             if ( GetAltroBlockReal10BitWord(b)!=0x2AA )
524               {
525                 HLTFatal("Data inconsistency in trailing 10 bit fill word of Altro Block at byte position %#x (%d): Expected 0x2AA; Found %#x",
526                          fAltroBlockPositionBytes, fAltroBlockPositionBytes, GetAltroBlockReal10BitWord(b));
527                 
528                 return false;
529               }
530           }
531       }
532     return true;
533 }
534
535 AliHLTUInt32_t AliHLTTPCDigitReaderRaw::GetAltroBlockHWaddr() const
536 {
537   // see header file for class documentation
538   return fAltroBlockHWAddress;
539 }
540
541 unsigned AliHLTTPCDigitReaderRaw::GetAltroBlock10BitWordCnt() const
542 {
543   // see header file for class documentation
544   return fAltroBlock10BitWordCnt;
545 }
546
547 AliHLTUInt64_t AliHLTTPCDigitReaderRaw::GetAltroBlock40BitWord( unsigned long ndx ) const
548 {
549   // see header file for class documentation
550 AliHLTUInt64_t val=0;
551 unsigned wordOffset32Bit = (ndx / 4)*5;
552 switch ( ndx % 4 ) // 40 bit word index in a 4*40 bit=5*32 bit group
553     {
554     case 0:
555         val = (*(AliHLTUInt32_t*)(fBuffer+fAltroBlockPositionBytes-(wordOffset32Bit+1)*sizeof(AliHLTUInt32_t)));
556         val <<= 8;
557         val |= (*(AliHLTUInt32_t*)(fBuffer+fAltroBlockPositionBytes-(wordOffset32Bit+2)*sizeof(AliHLTUInt32_t))) >> 24;
558         break;
559     case 1:
560         val = ((*(AliHLTUInt32_t*)(fBuffer+fAltroBlockPositionBytes-(wordOffset32Bit+2)*sizeof(AliHLTUInt32_t))) & 0x00FFFFFF);
561         val <<= 16;
562         val |= ((*(AliHLTUInt32_t*)(fBuffer+fAltroBlockPositionBytes-(wordOffset32Bit+3)*sizeof(AliHLTUInt32_t))) >> 16) & 0xFFFF;
563         break;
564     case 2:
565         val = ((*(AliHLTUInt32_t*)(fBuffer+fAltroBlockPositionBytes-(wordOffset32Bit+3)*sizeof(AliHLTUInt32_t))) & 0xFFFF);
566         val <<= 24;
567         val |= ((*(AliHLTUInt32_t*)(fBuffer+fAltroBlockPositionBytes-(wordOffset32Bit+4)*sizeof(AliHLTUInt32_t))) >> 8);
568         break;
569     case 3:
570         val = ((*(AliHLTUInt32_t*)(fBuffer+fAltroBlockPositionBytes-(wordOffset32Bit+4)*sizeof(AliHLTUInt32_t))) & 0xFF);
571         val <<= 32;
572         val |= *(AliHLTUInt32_t*)(fBuffer+fAltroBlockPositionBytes-(wordOffset32Bit+5)*sizeof(AliHLTUInt32_t));
573         break;
574     }
575 return val;
576 }
577
578 AliHLTUInt16_t AliHLTTPCDigitReaderRaw::GetAltroBlock10BitWord( unsigned long ndx )
579 {
580   // see header file for class documentation
581 unsigned long realNdx = ndx+fAltroBlock10BitFillWordCnt;
582 unsigned long word40BitNdx = (realNdx / 4)+1;
583 AliHLTUInt64_t word40Bit = GetAltroBlock40BitWord( word40BitNdx );
584 switch ( realNdx % 4 )
585     {
586     case 3:
587         return word40Bit & 0x3FF;
588     case 2:
589         return (word40Bit>>10) & 0x3FF;
590     case 1:
591         return (word40Bit>>20) & 0x3FF;
592     case 0:
593         return (word40Bit>>30) & 0x3FF;
594     }
595
596  return 0xFFFF; 
597 }
598
599 AliHLTUInt16_t AliHLTTPCDigitReaderRaw::GetAltroBlockReal10BitWord( unsigned long ndx )
600 {
601   // see header file for class documentation
602 unsigned long word40BitNdx = (ndx / 4)+1;
603 AliHLTUInt64_t word40Bit = GetAltroBlock40BitWord( word40BitNdx );
604 switch ( ndx % 4 )
605     {
606     case 3:
607         return word40Bit & 0x3FF;
608     case 2:
609         return (word40Bit>>10) & 0x3FF;
610     case 1:
611         return (word40Bit>>20) & 0x3FF;
612     case 0:
613         return (word40Bit>>30) & 0x3FF;
614     }
615
616  return 0xFFFF; 
617 }
618
619 unsigned AliHLTTPCDigitReaderRaw::GetRCUDataBlockLength() const
620 {
621   // see header file for class documentation
622   // Return length of trailing RCU data block in bytes
623     switch ( fDataFormatVersion )
624         {
625         case 0:
626         case 1:
627             return 4;
628             break;
629         case 2:
630         case 3:
631             return 12;
632             break;
633         case 4:
634         case 5:
635             return 8;
636             break;
637         default:
638             return fBufferSize;
639         }
640 }
641
642 unsigned AliHLTTPCDigitReaderRaw::GetCommonDataHeaderSize() const
643 {
644   // see header file for class documentation
645   return 32;
646 }
647
648
649 Bool_t AliHLTTPCDigitReaderRaw::ApplyMapping()
650 {
651   // see header file for class documentation
652
653 #ifndef HAVE_TPC_MAPPING
654   if (fMapErrThrown++==0) {
655     HLTFatal("mapping not available, you must compile with HAVE_TPC_MAPPING");
656   }
657   return -1;
658 #endif //#ifndef HAVE_TPC_MAPPING
659     if ( (unsigned)fAltroBlockHWAddress > fgMaxHWA[fPatch]){
660         fPad = -1;
661         fRow = -1;
662         return kFALSE;
663     }
664
665     switch(fPatch){
666         case 0:
667             fRow = fgMapping0[(unsigned)fAltroBlockHWAddress][0];
668             fPad = fgMapping0[(unsigned)fAltroBlockHWAddress][1];
669             break;
670         case 1:
671             fRow = AliHLTTPCDigitReaderRaw::fgMapping1[(unsigned)fAltroBlockHWAddress][0];
672             fPad = AliHLTTPCDigitReaderRaw::fgMapping1[(unsigned)fAltroBlockHWAddress][1];
673 #if 0
674             printf ("pad %d # row %d (hwa: %u / 0x%08X\n", fgMapping1[(unsigned)fAltroBlockHWAddress][0],fgMapping1[(unsigned)fAltroBlockHWAddress][1], (unsigned)fAltroBlockHWAddress, (unsigned)fAltroBlockHWAddress);
675             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);
676             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);
677 #endif
678             break;
679         case 2:
680             fRow = fgMapping2[(unsigned)fAltroBlockHWAddress][0];
681             fPad = fgMapping2[(unsigned)fAltroBlockHWAddress][1];
682             break;
683         case 3:
684             fRow = fgMapping3[(unsigned)fAltroBlockHWAddress][0];
685             fPad = fgMapping3[(unsigned)fAltroBlockHWAddress][1];
686             break;
687         case 4:
688             fRow = fgMapping4[(unsigned)fAltroBlockHWAddress][0];
689             fPad = fgMapping4[(unsigned)fAltroBlockHWAddress][1];
690             break;
691         case 5:
692             fRow = fgMapping5[(unsigned)fAltroBlockHWAddress][0];
693             fPad = fgMapping5[(unsigned)fAltroBlockHWAddress][1];
694             break;
695         default:
696             fRow = -1;
697             fPad = -1;
698             return kFALSE;
699     }
700     return kTRUE;
701 }
702
703
704 Int_t AliHLTTPCDigitReaderRaw::GetRow( unsigned patch, unsigned hwAddr )
705 {
706   // see header file for class documentation
707
708 #ifndef HAVE_TPC_MAPPING
709   if (fMapErrThrown++==0) {
710     HLTFatal("mapping not available, you must compile with HAVE_TPC_MAPPING");
711   }
712   return -1;
713 #endif //#ifndef HAVE_TPC_MAPPING
714     if ( (unsigned)hwAddr > fgMaxHWA[fPatch]){
715         return -1;
716     }
717
718     switch(fPatch){
719         case 0:
720             return fgMapping0[hwAddr][0];
721         case 1:
722             return fgMapping1[hwAddr][0];
723         case 2:
724             return fgMapping2[hwAddr][0];
725         case 3:
726             return fgMapping3[hwAddr][0];
727         case 4:
728             return fgMapping4[hwAddr][0];
729         case 5:
730             return fgMapping5[hwAddr][0];
731         default:
732           return -1;
733     }
734 }
735
736 Int_t AliHLTTPCDigitReaderRaw::GetPad( unsigned patch, unsigned hwAddr )
737 {
738   // see header file for class documentation
739
740 #ifndef HAVE_TPC_MAPPING
741   if (fMapErrThrown++==0) {
742     HLTFatal("mapping not available, you must compile with HAVE_TPC_MAPPING");
743   }
744   return -1;
745 #endif //#ifndef HAVE_TPC_MAPPING
746     if ( (unsigned)hwAddr > fgMaxHWA[fPatch]){
747         return -1;
748     }
749
750     switch(fPatch){
751         case 0:
752             return fgMapping0[hwAddr][1];
753         case 1:
754             return fgMapping1[hwAddr][1];
755         case 2:
756             return fgMapping2[hwAddr][1];
757         case 3:
758             return fgMapping3[hwAddr][1];
759         case 4:
760             return fgMapping4[hwAddr][1];
761         case 5:
762             return fgMapping5[hwAddr][1];
763         default:
764           return -1;
765     }
766 }
767
768 unsigned AliHLTTPCDigitReaderRaw::GetMaxHWA( unsigned patch ) const
769 {
770   // see header file for class documentation
771
772   if ( (int)patch>=fgkNofPatches )
773     return 0;
774   return fgMaxHWA[patch];
775 }
776
777 Int_t AliHLTTPCDigitReaderRaw::DecodeMode(Int_t mode) 
778 {
779   // see header file for class documentation
780
781   Int_t decodedMode;
782
783   if ( mode >= kNofRawReaderModes ) 
784     decodedMode = -1;
785   else
786     decodedMode = mode;
787
788   return decodedMode;
789 }
790
791 Int_t AliHLTTPCDigitReaderRaw::DecodeMode(const Char_t *mode) 
792 {
793   // see header file for class documentation
794
795   Int_t decodedMode;
796   Char_t *cpErr;
797
798   // Check if String is convertible to Int_t
799   // if not decode the string, otherwise, check if Int_t is valid
800   Int_t intMode = strtoul( mode, &cpErr ,0);
801
802   if ( *cpErr ) {
803     if ( !strcmp( mode, "sorted_3_trailerword" ) ) 
804       decodedMode = kSorted3Trailerword;
805     
806     else if ( !strcmp( mode, "sorted_2_trailerword" ) ) 
807       decodedMode = kSorted2Trailerword;
808     
809     else if ( !strcmp( mode, "sorted_1_trailerword" ) ) 
810       decodedMode = kSorted1Trailerword;
811     
812     else if ( !strcmp( mode, "unsorted_3_trailerword" ) ) 
813       decodedMode = kUnsorted3Trailerword;
814     
815     else if ( !strcmp( mode, "unsorted_2_trailerword" ) ) 
816       decodedMode = kUnsorted2Trailerword;
817     
818     else if ( !strcmp( mode, "unsorted_1_trailerword" ) ) 
819       decodedMode = kUnsorted1Trailerword;
820     
821     else if ( ! strcmp( mode, "offline" ) )
822       decodedMode = -2;
823     
824     else 
825       decodedMode = -1;
826   }  // END if ( *cpErr ) {
827   else {
828     if ( intMode >= kNofRawReaderModes ) 
829       decodedMode = -1;
830     else
831       decodedMode = intMode;
832   }
833
834   return decodedMode;
835 }
836
837
838 // ----- MAPPING ARRAYS
839 #if defined(HAVE_TPC_MAPPING)
840 #include "mapping_array_out.inc"
841 #else
842 // dummy definitions in case of missing mapping
843 unsigned AliHLTTPCDigitReaderRaw::fgMaxHWA[fgkNofPatches];
844 Int_t AliHLTTPCDigitReaderRaw::fgMapping0[fgkMapping0Size][fgkMappingDimension];
845 Int_t AliHLTTPCDigitReaderRaw::fgMapping1[fgkMapping1Size][fgkMappingDimension];
846 Int_t AliHLTTPCDigitReaderRaw::fgMapping2[fgkMapping2Size][fgkMappingDimension];
847 Int_t AliHLTTPCDigitReaderRaw::fgMapping3[fgkMapping3Size][fgkMappingDimension];
848 Int_t AliHLTTPCDigitReaderRaw::fgMapping4[fgkMapping4Size][fgkMappingDimension];
849 Int_t AliHLTTPCDigitReaderRaw::fgMapping5[fgkMapping5Size][fgkMappingDimension];
850 #endif //#if defined(HAVE_TPC_MAPPING)