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