3 //**************************************************************************
4 //* This file is property of and copyright by the ALICE HLT Project *
5 //* ALICE Experiment at CERN, All rights reserved. *
7 //* Primary Authors: Timm Steinbeck <timm@kip.uni-heidelberg.de> *
8 //* for The ALICE HLT Project. *
10 //* Permission to use, copy, modify and distribute this software and its *
11 //* documentation strictly for non-commercial purposes is hereby granted *
12 //* without fee, provided that the above copyright notice appears in all *
13 //* copies and that both the copyright notice and this permission notice *
14 //* appear in the supporting documentation. The authors make no claims *
15 //* about the suitability of this software for any purpose. It is *
16 //* provided "as is" without express or implied warranty. *
17 //**************************************************************************
19 /** @file AliHLTTPCCompModelInflater.cxx
20 @author Timm Steinbeck
22 @brief A copy processing component for the HLT.
24 * The model inflater is the counterpart of the deflater component
25 * which decompresses the data after a conversion and compression.
26 * The deflater is followed by a deconverter in order to get the
27 * original standard HLT cluster track format back
35 #include "AliHLTTPCCompModelInflater.h"
36 #include "AliHLTTPCTransform.h"
37 #include "AliHLTTPCTrack.h"
38 #include "AliHLTTPCModelTrack.h"
39 #include "AliHLTTPCCompDataCompressorHelper.h"
40 #include "AliHLTDataTypes.h"
43 AliHLTTPCCompModelInflater::AliHLTTPCCompModelInflater():
44 fBitDataCurrentWord(0),
45 fBitDataCurrentPosInWord(0),
46 fBitDataCurrentInput(0),
47 fBitDataCurrentInputStart(0),
48 fBitDataCurrentInputEnd(0)
50 // see header file for class documentation
53 AliHLTTPCCompModelInflater::~AliHLTTPCCompModelInflater()
55 // see header file for class documentation
58 void AliHLTTPCCompModelInflater::InitBitDataInput( AliHLTUInt8_t* input, UInt_t inputSize )
60 // sse header file for class documentation
61 fBitDataCurrentWord = 0;
62 fBitDataCurrentPosInWord = 7;
63 fBitDataCurrentInput = fBitDataCurrentInputStart = input;
64 fBitDataCurrentInputEnd = input+inputSize;
65 fBitDataCurrentWord = *fBitDataCurrentInput;
68 bool AliHLTTPCCompModelInflater::InputBit( AliHLTUInt8_t & value )
70 // see header file for class documenation
71 if ( fBitDataCurrentInput>=fBitDataCurrentInputEnd )
73 value = (fBitDataCurrentWord >> fBitDataCurrentPosInWord) & 1;
74 if ( fBitDataCurrentPosInWord )
75 fBitDataCurrentPosInWord--;
78 fBitDataCurrentInput++;
79 if ( fBitDataCurrentInput<fBitDataCurrentInputEnd )
81 fBitDataCurrentWord = *fBitDataCurrentInput;
82 fBitDataCurrentPosInWord = 7;
88 bool AliHLTTPCCompModelInflater::InputBits( AliHLTUInt8_t & value, UInt_t const & bitCount )
90 // see header file for clas documentation
93 HLTFatal( "Internal error: Attempt to write more than 32 bits (%u)", (unsigned)bitCount );
97 if ( !InputBits( temp, bitCount ) )
99 value = (AliHLTUInt8_t)( temp & (AliHLTUInt64_t)0xFFFFFFFFULL );
103 bool AliHLTTPCCompModelInflater::InputBits( AliHLTUInt16_t & value, UInt_t const & bitCount )
105 // see header file for class documenation
108 HLTFatal( "Internal error: Attempt to write more than 32 bits (%u)", (unsigned)bitCount );
112 if ( !InputBits( temp, bitCount ) )
114 value = (AliHLTUInt16_t)( temp & (AliHLTUInt64_t)0xFFFFFFFFULL );
118 bool AliHLTTPCCompModelInflater::InputBits( AliHLTUInt32_t & value, UInt_t const & bitCount )
120 // see header file for class documentation
123 HLTFatal( "Internal error: Attempt to write more than 32 bits (%u)", (unsigned)bitCount );
127 if ( !InputBits( temp, bitCount ) )
129 value = (AliHLTUInt32_t)( temp & (AliHLTUInt64_t)0xFFFFFFFFULL );
133 bool AliHLTTPCCompModelInflater::InputBits( Int_t & value, UInt_t const & bitCount )
135 // see header file for class documentation
138 HLTFatal( "Internal error: Attempt to write more than 32 bits (%u)", (unsigned)bitCount );
142 if ( !InputBits( temp, bitCount ) )
144 value = (Int_t)( temp & (AliHLTUInt64_t)0xFFFFFFFFULL );
148 bool AliHLTTPCCompModelInflater::InputBits( AliHLTUInt64_t & value, UInt_t const & bitCount )
150 // see header file for class documenation
153 HLTFatal( "Internal error: Attempt to write more than 64 bits (%u)", (unsigned)bitCount );
156 UInt_t bitsToRead=bitCount;
159 while ( bitsToRead>0 )
161 if ( fBitDataCurrentInput>=fBitDataCurrentInputEnd )
163 if ( bitsToRead >= fBitDataCurrentPosInWord+1 )
164 curBitCount = fBitDataCurrentPosInWord+1;
166 curBitCount = bitsToRead;
167 value = (value << curBitCount) | ( (fBitDataCurrentWord >> (fBitDataCurrentPosInWord-curBitCount+1)) & ((1 << curBitCount)-1) );
168 if ( fBitDataCurrentPosInWord < curBitCount )
170 fBitDataCurrentInput++;
171 if ( fBitDataCurrentInput<fBitDataCurrentInputEnd )
173 fBitDataCurrentWord = *fBitDataCurrentInput;
174 fBitDataCurrentPosInWord = 7;
178 fBitDataCurrentPosInWord -= curBitCount;
179 bitsToRead -= curBitCount;
184 void AliHLTTPCCompModelInflater::Pad8Bits()
186 // see header file for class documenation
187 if ( fBitDataCurrentPosInWord == 7 )
189 fBitDataCurrentInput++;
190 if ( fBitDataCurrentInput<fBitDataCurrentInputEnd )
192 fBitDataCurrentWord = *fBitDataCurrentInput;
193 fBitDataCurrentPosInWord = 7;
197 bool AliHLTTPCCompModelInflater::InputBytes( AliHLTUInt8_t* data, UInt_t const & byteCount )
199 // see header file for class documenation
201 if ( fBitDataCurrentInput+byteCount>fBitDataCurrentInputEnd )
203 memcpy( data, fBitDataCurrentInput, byteCount );
204 fBitDataCurrentInput += byteCount;
205 if ( fBitDataCurrentInput<fBitDataCurrentInputEnd )
207 fBitDataCurrentWord = *fBitDataCurrentInput;
208 fBitDataCurrentPosInWord = 7;
213 int AliHLTTPCCompModelInflater::DecompressTracks( AliHLTUInt8_t* inData, UInt_t const& inputSize, AliHLTUInt8_t* output, UInt_t& outputSize )
215 // see header file for class documentation
216 AliHLTUInt8_t* inputPtr = inData;
217 //AliHLTUInt8_t* inputEndPtr = inData+inputSize;
218 AliHLTUInt8_t* outputPtr = output;
219 AliHLTUInt8_t* outputEndPtr = output+outputSize;
221 printf( "outuptSize: %lu\n", (unsigned long)outputSize );
223 InitBitDataInput( inputPtr, inputSize );
224 AliHLTUInt8_t version;
225 if ( !InputBits( version, 4 ) ) // Version information
227 HLTError( "Corrupt input data. Cannot read data version number at position %u",
228 (unsigned)(inputPtr-inData) );
233 HLTError( "Unsupported version %hu. Only version 0 supported currently.", version );
236 AliHLTUInt8_t readShape;
237 if ( !InputBit( readShape ) ) // Data format flag
239 HLTError( "Corrupt input data. Cannot read shape flag at position %u",
240 (unsigned)(inputPtr-inData) );
244 if ( outputPtr+sizeof(AliHLTUInt32_t)>outputEndPtr )
246 HLTError( "Not enough space to write decompressed data. %lu already written",
247 (unsigned)(outputPtr-output) );
250 *(AliHLTUInt32_t*)outputPtr = 0; // Write format version number
251 outputPtr += sizeof(AliHLTUInt32_t);
255 AliHLTTPCClusterModel *cluster;
257 Int_t chargeo,padshapeo,timeshapeo;
258 chargeo=padshapeo=timeshapeo=0;
260 while( !EndOfBitInput() )
262 if ( outputPtr+sizeof(AliHLTTPCTrackModel)>outputEndPtr )
264 HLTError( "Not enough space to write decompressed data. %lu already written",
265 (unsigned)(outputPtr-output) );
268 if ( !InputBytes( outputPtr, sizeof(AliHLTTPCTrackModel) ) )
270 HLTError( "Corrupt input data. Cannot read track model data at position %u",
271 (unsigned)(inputPtr-inData) );
274 outputPtr += sizeof(AliHLTTPCTrackModel);
276 Int_t clustercount=0;
277 AliHLTUInt32_t slice;
278 for(Int_t i=0; i<AliHLTTPCTransform::GetNRows(); i++)
280 if ( outputPtr+sizeof(AliHLTTPCClusterModel)>outputEndPtr )
282 HLTError( "Not enough space to write decompressed data. %lu already written",
283 (unsigned)(outputPtr-output) );
286 cluster = (AliHLTTPCClusterModel*)outputPtr;
287 outputPtr += sizeof(AliHLTTPCClusterModel);
289 // Read present flag:
290 AliHLTUInt8_t present;
291 if ( !InputBit( present ) )
293 HLTError( "Corrupt input data. Cannot read cluster presence bit at position %u",
294 (unsigned)(inputPtr-inData) );
297 HLTDebug( "Cluster for row %d %s", i, (present ? "present" : "not present") );
298 cluster->fPresent = present;
303 //Read slice number of first point
304 if ( clustercount==0 )
306 if ( !InputBits( slice,6 ) ) //Need 6 bits to encode slice number
308 HLTError( "Corrupt input data. Cannot read cluster slice number at position %u",
309 (unsigned)(inputPtr-inData) );
315 AliHLTUInt8_t sliceChange;
316 if ( !InputBit( sliceChange ) )
318 HLTError( "Corrupt input data. Cannot read cluster slice change bit at position %u",
319 (unsigned)(inputPtr-inData) );
324 if ( !InputBits( slice, 6 ) )
326 HLTError( "Corrupt input data. Cannot read cluster slice number at position %u",
327 (unsigned)(inputPtr-inData) );
332 HLTDebug( "Slice: %d", slice );
333 cluster->fSlice = slice;
334 if ( cluster->fSlice<0 || cluster->fSlice>35 )
336 HLTError( "Inconsistent slice number %u (track %u, cluster %d)", cluster->fSlice, trackCnt, i );
337 printf( "TRACE: %s:%d\n", __FILE__, __LINE__ );
341 AliHLTUInt8_t signBit;
345 //Read time information:
346 if ( !InputBit( signBit ) )
348 HLTError( "Corrupt input data. Cannot read DTime sign bit at position %u",
349 (unsigned)(inputPtr-inData) );
354 if ( !InputBits( temp, AliHLTTPCCompDataCompressorHelper::GetNTimeBits()-1 ) )
356 HLTError( "Corrupt input data. Cannot read DTime data at position %u",
357 (unsigned)(inputPtr-inData) );
361 cluster->fDTime = val*sign;
363 //Read pad information:
364 if ( !InputBit( signBit ) )
366 HLTError( "Corrupt input data. Cannot read DPad sign bit at position %u",
367 (unsigned)(inputPtr-inData) );
372 if ( !InputBits( temp, AliHLTTPCCompDataCompressorHelper::GetNPadBits()-1 ) )
374 HLTError( "Corrupt input data. Cannot read DPad data at position %u",
375 (unsigned)(inputPtr-inData) );
380 cluster->fDPad = val*sign;
382 // Read charge information:
383 if ( !InputBits( temp, AliHLTTPCCompDataCompressorHelper::GetNChargeBits() ) )
385 HLTError( "Corrupt input data. Cannot read charge data at position %u",
386 (unsigned)(inputPtr-inData) );
389 cluster->fDCharge = temp;
393 // Read shape information:
394 if ( !InputBit( signBit ) )
396 HLTError( "Corrupt input data. Cannot read DSigmaY sign bit at position %u",
397 (unsigned)(inputPtr-inData) );
402 if ( !InputBits( temp, AliHLTTPCCompDataCompressorHelper::GetNShapeBits()-1 ) )
404 HLTError( "Corrupt input data. Cannot read DSigmaY data at position %u",
405 (unsigned)(inputPtr-inData) );
410 cluster->fDSigmaY = val*sign;
411 //HLTInfo("DSigmaY: %f", cluster->fDSigmaY);
414 if ( !InputBit( signBit ) )
416 HLTError( "Corrupt input data. Cannot read DSigmaZ sign bit at position %u",
417 (unsigned)(inputPtr-inData) );
422 if ( !InputBits( temp, AliHLTTPCCompDataCompressorHelper::GetNShapeBits()-1 ) )
424 HLTError( "Corrupt input data. Cannot read DSigmaZ data at position %u",
425 (unsigned)(inputPtr-inData) );
429 cluster->fDSigmaZ = val*sign;
435 HLTDebug( "Track %u: %d clusters", trackCnt, clustercount );
438 outputSize = (UInt_t)( outputPtr - output );
442 int AliHLTTPCCompModelInflater::DecompressRemainingClusters( AliHLTUInt8_t* inData, UInt_t const& inputSize, AliHLTUInt8_t* output, UInt_t& outputSize )
444 // see header file for class documentation
445 AliHLTUInt8_t* inputPtr = inData;
446 AliHLTUInt8_t* outputPtr = output;
447 AliHLTUInt8_t* outputEndPtr = output+outputSize;
449 InitBitDataInput( inputPtr, inputSize );
450 AliHLTUInt8_t version;
451 if ( !InputBits( version, 4 ) ) // Version information
453 HLTError( "Corrupt input data. Cannot read data version number at position %u",
454 (unsigned)(inputPtr-inData) );
459 HLTError( "Unsupported version %hu. Only version 0 supported currently.", version );
463 if ( outputPtr+sizeof(AliHLTUInt32_t)>outputEndPtr )
465 HLTError( "Not enough space to write uncompressed data. %lu already written",
466 (unsigned long)(outputPtr-output) );
467 outputSize = (unsigned long)(outputPtr-output);
471 *(AliHLTUInt32_t*)outputPtr = 0; // Write format version
472 outputPtr += sizeof(AliHLTUInt32_t);
474 //Read the remaining clusters in a compressed format.
476 for(Int_t slice=0; slice<=35; slice++)
478 for(Int_t patch=0; patch < 6; patch++)
481 HLTDebug( "slice %u patch %u: %u padrows",
482 (unsigned)slice, (unsigned)patch, (unsigned)*inputPtr );
483 //Write number of padrows with clusters
484 if ( outputPtr>=outputEndPtr )
486 HLTError( "Not enough space to write uncompressed data. %lu already written",
487 (unsigned long)(outputPtr-output) );
488 outputSize = (unsigned long)(outputPtr-output);
491 if ( !InputBits( *outputPtr,8 ) )
493 HLTError( "Corrupt input data. Cannot read padrow count at position %u",
494 (unsigned)(inputPtr-inData) );
502 UInt_t nRows=(UInt_t)*outputPtr;
504 if ( outputPtr>=outputEndPtr )
506 HLTError( "Not enough space to write uncompressed data. %lu already written",
507 (unsigned long)(outputPtr-output) );
508 outputSize = (unsigned long)(outputPtr-output);
512 for ( UInt_t jj=0; jj<nRows; jj++ )
515 AliHLTTPCRemainingRow *thisRow = (AliHLTTPCRemainingRow*)outputPtr;
516 if ( outputPtr+sizeof(AliHLTTPCRemainingRow)>outputEndPtr )
518 HLTError( "Not enough space to write uncompressed data. %lu already written",
519 (unsigned long)(outputPtr-output) );
520 outputSize = (unsigned long)(outputPtr-output);
523 AliHLTTPCRemainingCluster *cl = thisRow->fClusters;
524 if ( !InputBits(thisRow->fPadRow,8) ) //Read padrow #
526 HLTError( "Corrupt input data. Cannot read padrow number at position %u",
527 (unsigned)(inputPtr-inData) );
530 if ( !InputBits(thisRow->fNClusters,10) )//Read number of clusters on this padrow
532 HLTError( "Corrupt input data. Cannot read cluster count at position %u",
533 (unsigned)(inputPtr-inData) );
536 if ( outputPtr+sizeof(AliHLTTPCRemainingRow)+thisRow->fNClusters*sizeof(AliHLTTPCRemainingCluster)>outputEndPtr )
538 HLTError( "Not enough space to write uncompressed data. %lu already written",
539 (unsigned long)(outputPtr-output) );
540 outputSize = (unsigned long)(outputPtr-output);
543 for ( i=0; i<thisRow->fNClusters; i++ )
547 if ( !InputBits(buff,AliHLTTPCCompDataCompressorHelper::GetNPadBitsRemaining()) )
549 HLTError( "Corrupt input data. Cannot read cluster count at position %u",
550 (unsigned)(inputPtr-inData) );
553 cl[i].fPad = (Float_t)( ((double)buff) / AliHLTTPCCompDataCompressorHelper::GetPadPrecisionFactor() );
556 if ( !InputBits(buff,AliHLTTPCCompDataCompressorHelper::GetNTimeBitsRemaining()) )
558 HLTError( "Corrupt input data. Cannot read cluster count at position %u",
559 (unsigned)(inputPtr-inData) );
562 cl[i].fTime = (Float_t)( ((double)buff) / AliHLTTPCCompDataCompressorHelper::GetTimePrecisionFactor() );
565 if ( !InputBits(buff,AliHLTTPCCompDataCompressorHelper::GetNShapeBitsRemaining()) )
567 HLTError( "Corrupt input data. Cannot read cluster count at position %u",
568 (unsigned)(inputPtr-inData) );
572 //HLTInfo("fDSgimaY = %d",buff);
574 Float_t padw = (Float_t)( ((double)buff) / AliHLTTPCCompDataCompressorHelper::GetPadPrecisionFactor() );
575 cl[i].fSigmaY2 = padw*padw;
576 //HLTInfo("sigmaY2: %f", cl[i].fSigmaY2);
578 if ( !InputBits(buff,AliHLTTPCCompDataCompressorHelper::GetNShapeBitsRemaining()) )
580 HLTError( "Corrupt input data. Cannot read cluster count at position %u",
581 (unsigned)(inputPtr-inData) );
584 Float_t timew = (Float_t)( ((double)buff) / AliHLTTPCCompDataCompressorHelper::GetTimePrecisionFactor() );
585 cl[i].fSigmaZ2 = timew*timew;
588 if ( !InputBits(buff,AliHLTTPCCompDataCompressorHelper::GetNChargeBits()) )
590 HLTError( "Corrupt input data. Cannot read cluster count at position %u",
591 (unsigned)(inputPtr-inData) );
594 cl[i].fCharge = buff;
596 outputPtr += sizeof(AliHLTTPCRemainingRow)+thisRow->fNClusters*sizeof(AliHLTTPCRemainingCluster);
601 outputSize = (UInt_t)( outputPtr - output );