3 /**************************************************************************
4 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
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. *
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 **************************************************************************/
20 /** @file AliHLTTPCDigitReaderRaw.cxx
21 @author Timm Steinbeck
23 @brief A digit reader implementation for the RAW data coming from the RCU.
30 #if defined(HAVE_TPC_MAPPING)
32 #include "AliHLTTPCDigitReaderRaw.h"
33 #include "AliHLTTPCTransform.h"
34 #include "AliHLTTPCRootTypes.h"
35 #include "AliHLTTPCStandardIncludes.h"
36 #include "AliHLTTPCLogging.h"
38 ClassImp(AliHLTTPCDigitReaderRaw)
40 AliHLTTPCDigitReaderRaw::AliHLTTPCDigitReaderRaw( unsigned formatVersion )
46 fDataFormatVersion(formatVersion),
60 if ( fDataFormatVersion==0 || fDataFormatVersion==2 )
63 // get max number of rows
64 for (Int_t ii=0; ii < 6; ii++)
65 if (AliHLTTPCTransform::GetNRows(ii) > fNMaxRows)
66 fNMaxRows = AliHLTTPCTransform::GetNRows(ii);
68 // get max number of pads
69 for (Int_t ii=0; ii < AliHLTTPCTransform::GetNRows();ii++ )
70 if (AliHLTTPCTransform::GetNPads(ii) > fNMaxPads)
71 fNMaxPads = AliHLTTPCTransform::GetNPads(ii);
73 // get max number of bins
74 fNTimeBins = AliHLTTPCTransform::GetNTimeBins();
76 HLTDebug("Array Borders ||| MAXPAD=%d ||| MAXROW=%d ||| MAXBIN=%d ||| MAXMUL=%d",
77 fNMaxPads, fNMaxRows, fNTimeBins, fNTimeBins*fNMaxRows*fNMaxPads);
80 fData = new Int_t[ fNMaxRows*fNMaxPads*fNTimeBins ];
84 AliHLTTPCDigitReaderRaw::AliHLTTPCDigitReaderRaw(const AliHLTTPCDigitReaderRaw& src)
90 fDataFormatVersion(src.fDataFormatVersion),
104 HLTFatal("copy constructor not for use");
107 AliHLTTPCDigitReaderRaw& AliHLTTPCDigitReaderRaw::operator=(const AliHLTTPCDigitReaderRaw& src)
113 fDataFormatVersion=src.fDataFormatVersion;
126 HLTFatal("assignment operator not for use");
130 AliHLTTPCDigitReaderRaw::~AliHLTTPCDigitReaderRaw(){
131 if ( fDataFormatVersion==0 || fDataFormatVersion==2 )
139 int AliHLTTPCDigitReaderRaw::InitBlock(void* ptr,unsigned long size, Int_t patch, Int_t slice){
141 fBuffer = (AliHLTUInt8_t*) ptr;
143 HLTError("invalid data buffer");
147 if (fBufferSize<=0) HLTWarning("no data available: zero length buffer");
153 fAltroBlockPositionBytes = 0;
154 fAltroBlockLengthBytes = 0;
155 fAltroBlock10BitWordCnt = 0xFFFFU;
156 fAltroBlockHWAddress = 0xFFFFU;
157 fBunchPosition = 0xFFFFU;
158 fBunchTimebinStart = ~0U;
160 fWordInBunch = (unsigned)-1;
162 Int_t firstrow=AliHLTTPCTransform::GetFirstRow(patch);
163 Int_t lastrow=AliHLTTPCTransform::GetLastRow(patch);
165 if ( fDataFormatVersion==0 || fDataFormatVersion==2 )
171 fNRows = lastrow - firstrow + 1;
174 if (patch > 1) offset = AliHLTTPCTransform::GetFirstRow( 2 );
176 fRowOffset = firstrow - offset;
180 // Init array with -1
181 memset( fData, 0xFF, sizeof(Int_t)*(fNMaxRows*fNMaxPads*fNTimeBins) );
183 const Int_t maxErrorPrintout=20;
186 // read data and fill in array
191 Int_t row = GetRealRow();
192 Int_t pad = GetRealPad();
193 Int_t bin = GetRealTime();
195 // HLTFatal("Index out of array range: PAD=%d ||| ROW=%d ||| BIN=%d ||| OFFSET=%d ||| ROWOFFSET=%d", pad, row, bin, offset, fRowOffset);
197 if ( row < firstrow || row > lastrow || pad > AliHLTTPCTransform::GetNPads(row + offset) || bin > fNTimeBins || pad<0 || bin<0){
198 // if ( row < firstrow || row > lastrow || pad > AliHLTTPCTransform::GetNPads(row + offset) || bin > fNTimeBins){
199 if (errorCount++<maxErrorPrintout) {
200 HLTFatal("Index out of range. Probably wrong patch! slice %d - patch %d", slice, patch);
201 HLTFatal("PAD=%d out of %d ||| ROW=%d (%d to %d) ||| BIN=%d out of %d ||| OFFSET=%d ||| ROWOFFSET=%d",
202 pad, AliHLTTPCTransform::GetNPads(row + offset), row, firstrow, lastrow, bin, fNTimeBins,
205 if ( row < firstrow || row > lastrow )
206 HLTFatal("Row out of range: %d ( %d to %d)", row, firstrow, lastrow);
207 if ( pad > AliHLTTPCTransform::GetNPads(row + offset) )
208 HLTFatal("Pad out of range: %d (pad count %d)", pad, AliHLTTPCTransform::GetNPads(row + offset));
209 if ( bin > fNTimeBins )
210 HLTFatal("Time bin out of range: %d (bin count %d)", bin, fNTimeBins);
213 } else if ((row-fRowOffset)*fNMaxPads*fNTimeBins+ pad*fNTimeBins + bin >= fNMaxRows*fNMaxPads*fNTimeBins ) {
214 if (errorCount++<maxErrorPrintout) {
215 HLTFatal("index out of range: PAD=%d ||| ROW=%d ||| BIN=%d ||| OFFSET=%d ||| ROWOFFSET=%d", pad, row, bin, offset, fRowOffset);
219 fData[ (row-fRowOffset)*fNMaxPads*fNTimeBins+ pad*fNTimeBins + bin ] = GetRealSignal() ;
223 HLTFatal("%d of %d entries out of range", errorCount, entryCount);
230 bool AliHLTTPCDigitReaderRaw::Next(){
231 if ( fDataFormatVersion==0 || fDataFormatVersion==2 )
233 Bool_t readvalue = kTRUE;
236 if (fCurrentBin >= fNTimeBins){
240 if (fCurrentPad >=fNMaxPads){
244 if (fCurrentRow >= fNMaxRows){
251 if (fCurrentRow*fNMaxPads*fNTimeBins+ fCurrentPad*fNTimeBins + fCurrentBin >= fNMaxRows*fNMaxPads*fNTimeBins ) {
252 HLTFatal("Overflow: fCurrentRow=%d fCurrentPad=%d fCurrentBin=%d", fCurrentRow, fCurrentPad, fCurrentBin);
257 if (fData[ fCurrentRow*fNMaxPads*fNTimeBins + fCurrentPad*fNTimeBins + fCurrentBin ] != -1) break;
265 int AliHLTTPCDigitReaderRaw::GetRow(){
266 if ( fDataFormatVersion==0 || fDataFormatVersion==2 )
268 return (fCurrentRow + fRowOffset);
273 int AliHLTTPCDigitReaderRaw::GetPad(){
274 if ( fDataFormatVersion==0 || fDataFormatVersion==2 )
281 int AliHLTTPCDigitReaderRaw::GetSignal(){
282 if ( fDataFormatVersion==0 || fDataFormatVersion==2 )
284 return fData[ fCurrentRow*fNMaxPads*fNTimeBins+ fCurrentPad*fNTimeBins + fCurrentBin ];
287 return GetRealSignal();
289 int AliHLTTPCDigitReaderRaw::GetTime(){
290 if ( fDataFormatVersion==0 || fDataFormatVersion==2 )
295 return GetRealTime();
299 bool AliHLTTPCDigitReaderRaw::RealNext(){
300 // printf( "%u %u %u %u %u\n", fBunchPosition, fBunchLength, fBunchTimebinStart, fWordInBunch, (unsigned)fAltroBlock10BitWordCnt );
301 fWordInBunch++; // use next word in bunch
302 if ( fWordInBunch==fBunchLength ) { // we have a bunch at all but have reached its end (or do not have an altro block yet)
303 if ( fBunchPosition+fBunchLength==fAltroBlock10BitWordCnt ) { // We were at the last bunch of this altro block (or do not have an altro block yet)
304 if ( !NextAltroBlock() )
309 fBunchPosition += fBunchLength;
311 fBunchLength = GetAltroBlock10BitWord( fBunchPosition );
312 fBunchTimebinStart = GetAltroBlock10BitWord( fBunchPosition+1 );
315 //HLTDebug( "%u %u %u %u %u\n", fBunchPosition, fBunchLength, fBunchTimebinStart, fWordInBunch, (unsigned)fAltroBlock10BitWordCnt );
318 int AliHLTTPCDigitReaderRaw::GetRealRow(){
321 int AliHLTTPCDigitReaderRaw::GetRealPad(){
324 int AliHLTTPCDigitReaderRaw::GetRealSignal(){
325 return GetAltroBlock10BitWord( fBunchPosition+fWordInBunch );
327 int AliHLTTPCDigitReaderRaw::GetRealTime(){
328 //HLTDebug( "GetRealTime: %u - %u\n", fBunchTimebinStart, fWordInBunch );
329 return fBunchTimebinStart-(fWordInBunch-2);
332 AliHLTUInt32_t AliHLTTPCDigitReaderRaw::GetRCUTrailer(){
333 if (fBufferSize<=0) return 0;
334 unsigned rcuDataBlockLen = GetRCUDataBlockLength();
335 return *((AliHLTUInt32_t*)(fBuffer+fBufferSize-rcuDataBlockLen));
338 bool AliHLTTPCDigitReaderRaw::NextAltroBlock()
340 if (fBufferSize<=0) return 0;
341 if ( !fAltroBlockLengthBytes )
343 // First block in back linked list (last block in memory)
344 fAltroBlockPositionBytes = fBufferSize-GetRCUDataBlockLength();
348 if ( fAltroBlockPositionBytes<fAltroBlockLengthBytes+GetCommonDataHeaderSize() )
350 HLTFatal("Inconsistent Data: fAltroBlockPositionBytes=%d fAltroBlockLengthBytes=%d", fAltroBlockPositionBytes, fAltroBlockLengthBytes);
352 if ( fAltroBlockPositionBytes<=fAltroBlockLengthBytes+GetCommonDataHeaderSize() )
353 return false; // We have reached the end of the back linked list
354 fAltroBlockPositionBytes -= fAltroBlockLengthBytes;
357 AliHLTUInt64_t altroTrailerWord = GetAltroBlock40BitWord( 0 );
359 if ( fVerify && ((altroTrailerWord & 0xFFFC000000ULL)!=0xAAA8000000ULL) )
361 HLTFatal("Data inconsistency in Altro Block at byte position %#x (%d): Expected 0x2AAA in high 14 bits of altro trailer word; Found %#llx (%#llx)",
362 fAltroBlockPositionBytes, fAltroBlockPositionBytes,
363 ((altroTrailerWord & 0xFFFC000000ULL) >> 26), altroTrailerWord);
369 if ( fVerify && ((altroTrailerWord & 0x000000F000ULL)!=0x000000A000ULL) )
371 HLTFatal("Data inconsistency in Altro Block at byte position %#x (%d): Expected 0xA in bits 12-15 of altro trailer word; Found %#llx .",
372 fAltroBlockPositionBytes, fAltroBlockPositionBytes, ((altroTrailerWord & 0x000000F000ULL) >> 12));
377 fAltroBlock10BitWordCnt = (altroTrailerWord >> 16) & 0x3FF;
378 fAltroBlockHWAddress = altroTrailerWord & 0xFFF;
383 HLTFatal("Mapping failed Patch %d HWA %#x (%d) - maxHWA %#x (%d)",
384 fPatch, fAltroBlockHWAddress, fAltroBlockHWAddress, fMaxHWA[fPatch], fMaxHWA[fPatch]);
388 unsigned words40Bit = fAltroBlock10BitWordCnt/4;
389 if ( fAltroBlock10BitWordCnt % 4 )
392 fAltroBlockLengthBytes = words40Bit*5;
393 if ( fAltroBlock10BitWordCnt % 4 )
394 fAltroBlock10BitFillWordCnt = 4-(fAltroBlock10BitWordCnt % 4);
396 fAltroBlock10BitFillWordCnt=0;
399 for ( unsigned b = 0; b < fAltroBlock10BitFillWordCnt; b++ )
401 if ( GetAltroBlockReal10BitWord(b)!=0x2AA )
403 HLTFatal("Data inconsistency in trailing 10 bit fill word of Altro Block at byte position %#x (%d): Expected 0x2AA; Found %#x",
404 fAltroBlockPositionBytes, fAltroBlockPositionBytes, GetAltroBlockReal10BitWord(b));
413 AliHLTUInt32_t AliHLTTPCDigitReaderRaw::GetAltroBlockHWaddr(){
414 return fAltroBlockHWAddress;
416 unsigned AliHLTTPCDigitReaderRaw::GetAltroBlock10BitWordCnt(){
417 return fAltroBlock10BitWordCnt;
419 AliHLTUInt64_t AliHLTTPCDigitReaderRaw::GetAltroBlock40BitWord( unsigned long ndx ){
420 AliHLTUInt64_t val=0;
421 unsigned wordOffset32Bit = (ndx / 4)*5;
422 switch ( ndx % 4 ) // 40 bit word index in a 4*40 bit=5*32 bit group
425 val = (*(AliHLTUInt32_t*)(fBuffer+fAltroBlockPositionBytes-(wordOffset32Bit+1)*sizeof(AliHLTUInt32_t)));
427 val |= (*(AliHLTUInt32_t*)(fBuffer+fAltroBlockPositionBytes-(wordOffset32Bit+2)*sizeof(AliHLTUInt32_t))) >> 24;
430 val = ((*(AliHLTUInt32_t*)(fBuffer+fAltroBlockPositionBytes-(wordOffset32Bit+2)*sizeof(AliHLTUInt32_t))) & 0x00FFFFFF);
432 val |= ((*(AliHLTUInt32_t*)(fBuffer+fAltroBlockPositionBytes-(wordOffset32Bit+3)*sizeof(AliHLTUInt32_t))) >> 16) & 0xFFFF;
435 val = ((*(AliHLTUInt32_t*)(fBuffer+fAltroBlockPositionBytes-(wordOffset32Bit+3)*sizeof(AliHLTUInt32_t))) & 0xFFFF);
437 val |= ((*(AliHLTUInt32_t*)(fBuffer+fAltroBlockPositionBytes-(wordOffset32Bit+4)*sizeof(AliHLTUInt32_t))) >> 8);
440 val = ((*(AliHLTUInt32_t*)(fBuffer+fAltroBlockPositionBytes-(wordOffset32Bit+4)*sizeof(AliHLTUInt32_t))) & 0xFF);
442 val |= *(AliHLTUInt32_t*)(fBuffer+fAltroBlockPositionBytes-(wordOffset32Bit+5)*sizeof(AliHLTUInt32_t));
447 AliHLTUInt16_t AliHLTTPCDigitReaderRaw::GetAltroBlock10BitWord( unsigned long ndx ){
448 unsigned long realNdx = ndx+fAltroBlock10BitFillWordCnt;
449 unsigned long word40BitNdx = (realNdx / 4)+1;
450 AliHLTUInt64_t word40Bit = GetAltroBlock40BitWord( word40BitNdx );
451 switch ( realNdx % 4 )
454 return word40Bit & 0x3FF;
456 return (word40Bit>>10) & 0x3FF;
458 return (word40Bit>>20) & 0x3FF;
460 return (word40Bit>>30) & 0x3FF;
466 AliHLTUInt16_t AliHLTTPCDigitReaderRaw::GetAltroBlockReal10BitWord( unsigned long ndx ){
467 unsigned long word40BitNdx = (ndx / 4)+1;
468 AliHLTUInt64_t word40Bit = GetAltroBlock40BitWord( word40BitNdx );
472 return word40Bit & 0x3FF;
474 return (word40Bit>>10) & 0x3FF;
476 return (word40Bit>>20) & 0x3FF;
478 return (word40Bit>>30) & 0x3FF;
484 // Return length of trailing RCU data block in bytes
485 unsigned AliHLTTPCDigitReaderRaw::GetRCUDataBlockLength() const
487 switch ( fDataFormatVersion )
502 unsigned AliHLTTPCDigitReaderRaw::GetCommonDataHeaderSize() const
508 Bool_t AliHLTTPCDigitReaderRaw::ApplyMapping(){
510 if ( (unsigned)fAltroBlockHWAddress > fMaxHWA[fPatch]){
518 fRow = fMapping_0[(unsigned)fAltroBlockHWAddress][0];
519 fPad = fMapping_0[(unsigned)fAltroBlockHWAddress][1];
522 fRow = AliHLTTPCDigitReaderRaw::fMapping_1[(unsigned)fAltroBlockHWAddress][0];
523 fPad = AliHLTTPCDigitReaderRaw::fMapping_1[(unsigned)fAltroBlockHWAddress][1];
525 printf ("pad %d # row %d (hwa: %u / 0x%08X\n", fMapping_1[(unsigned)fAltroBlockHWAddress][0],fMapping_1[(unsigned)fAltroBlockHWAddress][1], (unsigned)fAltroBlockHWAddress, (unsigned)fAltroBlockHWAddress);
526 printf ("pad %d # row %d (hwa: %u / 0x%08X\n", fMapping_1[(unsigned)fAltroBlockHWAddress-1][0],fMapping_1[(unsigned)fAltroBlockHWAddress-1][1], (unsigned)fAltroBlockHWAddress-1, (unsigned)fAltroBlockHWAddress-1);
527 printf ("pad %d # row %d (hwa: %u / 0x%08X\n", fMapping_1[(unsigned)fAltroBlockHWAddress+1][0],fMapping_1[(unsigned)fAltroBlockHWAddress+1][1], (unsigned)fAltroBlockHWAddress+1, (unsigned)fAltroBlockHWAddress+1);
531 fRow = fMapping_2[(unsigned)fAltroBlockHWAddress][0];
532 fPad = fMapping_2[(unsigned)fAltroBlockHWAddress][1];
535 fRow = fMapping_3[(unsigned)fAltroBlockHWAddress][0];
536 fPad = fMapping_3[(unsigned)fAltroBlockHWAddress][1];
539 fRow = fMapping_4[(unsigned)fAltroBlockHWAddress][0];
540 fPad = fMapping_4[(unsigned)fAltroBlockHWAddress][1];
543 fRow = fMapping_5[(unsigned)fAltroBlockHWAddress][0];
544 fPad = fMapping_5[(unsigned)fAltroBlockHWAddress][1];
555 Int_t AliHLTTPCDigitReaderRaw::GetRow( unsigned patch, unsigned hw_addr )
557 if ( (unsigned)hw_addr > fMaxHWA[fPatch]){
563 return fMapping_0[hw_addr][0];
565 return fMapping_1[hw_addr][0];
567 return fMapping_2[hw_addr][0];
569 return fMapping_3[hw_addr][0];
571 return fMapping_4[hw_addr][0];
573 return fMapping_5[hw_addr][0];
578 Int_t AliHLTTPCDigitReaderRaw::GetPad( unsigned patch, unsigned hw_addr )
580 if ( (unsigned)hw_addr > fMaxHWA[fPatch]){
586 return fMapping_0[hw_addr][1];
588 return fMapping_1[hw_addr][1];
590 return fMapping_2[hw_addr][1];
592 return fMapping_3[hw_addr][1];
594 return fMapping_4[hw_addr][1];
596 return fMapping_5[hw_addr][1];
602 unsigned AliHLTTPCDigitReaderRaw::GetMaxHWA( unsigned patch )
606 return fMaxHWA[patch];
610 // ----- MAPPING ARRAYS
611 #include "mapping_array_out.inc"
613 #endif //#if defined(HAVE_TPC_MAPPING)