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