]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/TPCLib/comp/AliHLTTPCCompModelDeflater.cxx
729703c22593faa1e5b9b66723b47cf53cc1e373
[u/mrichter/AliRoot.git] / HLT / TPCLib / comp / AliHLTTPCCompModelDeflater.cxx
1 // $Id: AliHLTTPCCompModelDeflater.cxx,v 1.2 2006/08/10 09:46:51 richterm Exp $
2
3 /**************************************************************************
4  * TPCCompModelDeflaterright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
5  *                                                                        *
6  * Authors: Timm Steinbeck <timm@kip.uni-heidelberg.de>                   *
7  *          for The ALICE Off-line Project.                               *
8  *                                                                        *
9  * Permission to use, copy, modify and distribute this software and its   *
10  * documentation strictly for non-commercial purposes is hereby granted   *
11  * without fee, provided that the above copyright notice appears in all   *
12  * copies and that both the copyright notice and this permission notice   *
13  * appear in the supporting documentation. The authors make no claims     *
14  * about the suitability of this software for any purpose. It is          *
15  * provided "as is" without express or implied warranty.                  *
16  **************************************************************************/
17
18 /** @file   AliHLTTPCCompModelDeflater.cxx
19     @author Timm Steinbeck
20     @date   
21     @brief  A copy processing component for the HLT. */
22
23 #if __GNUC__ >= 3
24 using namespace std;
25 #endif
26
27 #include "AliHLTTPCCompModelDeflater.h"
28 #include "AliHLTTPCTransform.h"
29 #include "AliHLTTPCTrack.h"
30 #include "AliHLTTPCModelTrack.h"
31 #include "AliHLTTPCCompDataCompressorHelper.h"
32 #include "AliHLTDataTypes.h"
33 #include <cerrno>
34
35 AliHLTTPCCompModelDeflater::AliHLTTPCCompModelDeflater():
36     fWriteShape(true),
37     fBitDataCurrentWord(0),
38     fBitDataCurrentPosInWord(0),
39     fBitDataCurrentOutput(0),
40     fBitDataCurrentOutputStart(0),
41     fBitDataCurrentOutputEnd(0)
42     {
43       // see header file for class documentation
44     }
45
46 AliHLTTPCCompModelDeflater::~AliHLTTPCCompModelDeflater()
47     {
48       // see header file for class documentation
49     }
50
51 int AliHLTTPCCompModelDeflater::CompressTracks( AliHLTUInt8_t* inData, UInt_t const& inputSize, AliHLTUInt8_t* output, UInt_t& outputSize )
52     {
53       // see header file for class documentation
54       AliHLTUInt8_t* inputPtr = inData;
55       AliHLTUInt8_t* inputEndPtr = inData+inputSize;
56       
57       if ( inputPtr+sizeof(AliHLTUInt32_t)>inputEndPtr )
58         {
59           HLTError( "Cannot read input data version number" );
60           return EIO;
61         }
62       if ( *(AliHLTUInt32_t*)inputPtr != 0 )
63         {
64           HLTError( "Only input data format version 0 is supported. Found version: %u",
65                     (unsigned)*(AliHLTUInt32_t*)inputPtr );
66           return EINVAL;
67         }
68       inputPtr += sizeof(AliHLTUInt32_t);
69       
70       printf( "outuptSize: %lu\n", (unsigned long)outputSize );
71       
72       InitBitDataOutput( output, outputSize );
73       HLTDebug( "Output: Position: %lu / %u (0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte() );
74       OutputBits( 0, 4 ); // Version information
75       HLTDebug( "Output: Position: %lu / %u (0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte() );
76       OutputBit( fWriteShape ? 1 : 0 ); // Data format flag
77       HLTDebug( "Output: Position: %lu / %u (0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte() );
78       Pad8Bits();
79       HLTDebug( "Output: Position: %lu / %u (0x%02X / 0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte(-1), (unsigned)GetCurrentOutputByte() );
80       
81       AliHLTTPCClusterModel *cluster;
82       Int_t temp;
83       Int_t power;
84       
85       Int_t timeo,pado,chargeo,padshapeo,timeshapeo;
86       timeo=pado=chargeo=padshapeo=timeshapeo=0;
87       unsigned trackCnt=0;
88       while( inputPtr<inputEndPtr )
89         {
90           if ( !OutputBytes( inputPtr, sizeof(AliHLTTPCTrackModel) ) )
91             {
92               HLTError( "Not enough space to write compressed data. %lu already written",
93                         (unsigned long)GetBitDataOutputSizeBytes() );
94               printf( "TRACE: %s:%d\n", __FILE__, __LINE__ );
95               outputSize = GetBitDataOutputSizeBytes();
96               return ENOBUFS;
97             }
98           HLTDebug( "sizeof(AliHLTTPCTrackModel): %d", sizeof(AliHLTTPCTrackModel) );
99           HLTDebug( "Output: Position: %lu / %u (0x%02X / 0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte(-1), (unsigned)GetCurrentOutputByte() );
100           inputPtr += sizeof(AliHLTTPCTrackModel);
101           
102           Int_t origslice=-1,slice,clustercount=0;
103           for(Int_t i=0; i<AliHLTTPCTransform::GetNRows(); i++)
104             {
105               cluster = (AliHLTTPCClusterModel*)inputPtr;
106               inputPtr += sizeof(AliHLTTPCClusterModel);
107               
108               //Write empty flag:
109               if ( !OutputBit( cluster->fPresent ? 1 : 0 ) )
110                 {
111                   HLTError( "Not enough space to write compressed data. %lu already written",
112                             (unsigned long)GetBitDataOutputSizeBytes() );
113                   printf( "TRACE: %s:%d\n", __FILE__, __LINE__ );
114                   outputSize = GetBitDataOutputSizeBytes();
115                   return ENOBUFS;
116                 }
117               HLTDebug( "Output: Position: %lu / %u (0x%02X / 0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte(-1), (unsigned)GetCurrentOutputByte() );
118               if ( !cluster->fPresent )
119                 continue;
120             
121               if ( cluster->fSlice<0 || cluster->fSlice>35 )
122                 {
123                   HLTError( "Inconsistent slice number %u (track %u, cluster %d)", cluster->fSlice, trackCnt, i );
124                   printf( "TRACE: %s:%d\n", __FILE__, __LINE__ );
125                   return EINVAL;
126                 }
127               
128               //Write slice number of first point
129               if ( clustercount==0 )
130                 {
131                   origslice = cluster->fSlice;
132                   if ( !OutputBits( origslice,6 ) ) //Need 6 bits to encode slice number
133                     {
134                       HLTError( "Not enough space to write compressed data. %lu already written",
135                                 (unsigned long)GetBitDataOutputSizeBytes() );
136                       printf( "TRACE: %s:%d\n", __FILE__, __LINE__ );
137                       outputSize = GetBitDataOutputSizeBytes();
138                       return ENOBUFS;
139                     }
140                   HLTDebug( "Output: Position: %lu / %u (0x%02X / 0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte(-1), (unsigned)GetCurrentOutputByte() );
141                 }
142               else
143                 {
144                   slice = cluster->fSlice;
145                   if( slice == origslice )
146                     {
147                       if ( !OutputBit( 0 ) )  //No change of slice
148                         {
149                           HLTError( "Not enough space to write compressed data. %lu already written",
150                                     (unsigned long)GetBitDataOutputSizeBytes() );
151                           outputSize = GetBitDataOutputSizeBytes();
152                           printf( "TRACE: %s:%d\n", __FILE__, __LINE__ );
153                           return ENOBUFS;
154                         }
155                       HLTDebug( "No slice change (%d/%d)", (int)origslice, (int)slice );
156                       HLTDebug( "Output: Position: %lu / %u (0x%02X / 0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte(-1), (unsigned)GetCurrentOutputByte() );
157                     }
158                   else
159                     {
160                       if ( !OutputBit( 1 ) )
161                         {
162                           HLTError( "Not enough space to write compressed data. %lu already written",
163                                     (unsigned long)GetBitDataOutputSizeBytes() );
164                           outputSize = GetBitDataOutputSizeBytes();
165                           printf( "TRACE: %s:%d\n", __FILE__, __LINE__ );
166                           return ENOBUFS;
167                         }
168                       HLTDebug( "Slice change (%d/%d)", (int)origslice, (int)slice );
169                       HLTDebug( "Output: Position: %lu / %u (0x%02X / 0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte(-1), (unsigned)GetCurrentOutputByte() );
170                       if ( !OutputBits( slice, 6 ) )
171                         {
172                           HLTError( "Not enough space to write compressed data. %lu already written",
173                                     (unsigned long)GetBitDataOutputSizeBytes() );
174                           outputSize = GetBitDataOutputSizeBytes();
175                           printf( "TRACE: %s:%d\n", __FILE__, __LINE__ );
176                           return ENOBUFS;
177                         }
178                       HLTDebug( "Output: Position: %lu / %u (0x%02X / 0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte(-1), (unsigned)GetCurrentOutputByte() );
179                       origslice=slice;
180                     }
181                 }
182               
183               //Write time information:
184               temp = (Int_t)rint(cluster->fDTime);
185               if( temp<0 )
186                 {
187                 if ( !OutputBit( 0 ) )
188                   {
189                     HLTError( "Not enough space to write compressed data. %lu already written",
190                               (unsigned long)GetBitDataOutputSizeBytes() );
191                     outputSize = GetBitDataOutputSizeBytes();
192                     printf( "TRACE: %s:%d\n", __FILE__, __LINE__ );
193                     return ENOBUFS;
194                   }
195                 HLTDebug( "Output: Position: %lu / %u (0x%02X / 0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte(-1), (unsigned)GetCurrentOutputByte() );
196                 }
197               else
198                 {
199                   if ( !OutputBit( 1 ) )
200                     {
201                       HLTError( "Not enough space to write compressed data. %lu already written",
202                                 (unsigned long)GetBitDataOutputSizeBytes() );
203                       printf( "TRACE: %s:%d\n", __FILE__, __LINE__ );
204                       outputSize = GetBitDataOutputSizeBytes();
205                       return ENOBUFS;
206                     }
207                   HLTDebug( "Output: Position: %lu / %u (0x%02X / 0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte(-1), (unsigned)GetCurrentOutputByte() );
208                 }
209               power = 1<<(AliHLTTPCCompDataCompressorHelper::GetNTimeBits()-1);
210               if ( abs(temp)>=power )
211                 {
212                   //cout<<abs(temp)<<" "<<power<<endl;
213                   timeo++;
214                   temp=power - 1;
215                 }
216               temp = abs(temp);
217               if ( !OutputBits(temp,(AliHLTTPCCompDataCompressorHelper::GetNTimeBits()-1)) )
218                 {
219                   HLTError( "Not enough space to write compressed data. %lu already written",
220                             (unsigned long)GetBitDataOutputSizeBytes() );
221                   printf( "TRACE: %s:%d\n", __FILE__, __LINE__ );
222                   outputSize = GetBitDataOutputSizeBytes();
223                   return ENOBUFS;
224                 }
225               HLTDebug( "Output: Position: %lu / %u (0x%02X / 0x%02X / 0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte(-2), (unsigned)GetCurrentOutputByte(-1), (unsigned)GetCurrentOutputByte() );
226               
227               //Write pad information:
228               temp = (Int_t)rint(cluster->fDPad);
229               HLTDebug( "cluster->fDPad (%d): %f - temp: %d", clustercount, cluster->fDPad, temp );
230               if ( temp<0 )
231                 {
232                   if ( !OutputBit( 0 ) )
233                     {
234                       HLTError( "Not enough space to write compressed data. %lu already written",
235                                 (unsigned long)GetBitDataOutputSizeBytes() );
236                       outputSize = GetBitDataOutputSizeBytes();
237                       printf( "TRACE: %s:%d\n", __FILE__, __LINE__ );
238                       return ENOBUFS;
239                     }
240                   HLTDebug( "Output: Position: %lu / %u (0x%02X / 0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte(-1), (unsigned)GetCurrentOutputByte() );
241                 }
242               else
243                 {
244                 if ( !OutputBit( 1 ) )
245                   {
246                     HLTError( "Not enough space to write compressed data. %lu already written",
247                               (unsigned long)GetBitDataOutputSizeBytes() );
248                     outputSize = GetBitDataOutputSizeBytes();
249                     printf( "TRACE: %s:%d\n", __FILE__, __LINE__ );
250                     return ENOBUFS;
251                   }
252                 HLTDebug( "Output: Position: %lu / %u (0x%02X / 0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte(-1), (unsigned)GetCurrentOutputByte() );
253                 }
254               power = 1<<(AliHLTTPCCompDataCompressorHelper::GetNPadBits()-1);
255               if ( abs(temp)>=power )
256                 {
257                   pado++;
258                   temp=power - 1;
259                 }
260               temp = abs(temp);
261               if ( !OutputBits(temp,(AliHLTTPCCompDataCompressorHelper::GetNPadBits()-1)) )
262                 {
263                   HLTError( "Not enough space to write compressed data. %lu already written",
264                             (unsigned long)GetBitDataOutputSizeBytes() );
265                   outputSize = GetBitDataOutputSizeBytes();
266                   printf( "TRACE: %s:%d\n", __FILE__, __LINE__ );
267                   return ENOBUFS;
268                 }
269               HLTDebug( "Output: Position: %lu / %u (0x%02X / 0x%02X / 0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte(-2), (unsigned)GetCurrentOutputByte(-1), (unsigned)GetCurrentOutputByte() );
270               
271               //Write charge information:
272               temp = (Int_t)cluster->fDCharge;
273               power = 1<<(AliHLTTPCCompDataCompressorHelper::GetNChargeBits());
274               if ( abs(temp)>=power )
275                 {
276                   chargeo++;
277                   temp=power - 1;
278                 }
279               temp = abs(temp);
280               if ( !OutputBits(temp,(AliHLTTPCCompDataCompressorHelper::GetNChargeBits())) )
281                 {
282                   HLTError( "Not enough space to write compressed data. %lu already written",
283                             (unsigned long)GetBitDataOutputSizeBytes() );
284                   outputSize = GetBitDataOutputSizeBytes();
285                   printf( "TRACE: %s:%d\n", __FILE__, __LINE__ );
286                   return ENOBUFS;
287                 }
288               HLTDebug( "Output: Position: %lu / %u (0x%02X / 0x%02X / 0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte(-2), (unsigned)GetCurrentOutputByte(-1), (unsigned)GetCurrentOutputByte() );
289               
290               if ( fWriteShape )
291                 {
292                   //Write shape information:
293                   // HLTInfo("DSigmaY %f", cluster->fDSigmaY);
294                   temp = (Int_t)rint(cluster->fDSigmaY);
295                   // HLTInfo("temp %d", temp);
296                   if( temp<0 )
297                     {
298                       if ( !OutputBit( 0 ) )
299                         {
300                           HLTError( "Not enough space to write compressed data. %lu already written",
301                                     (unsigned long)GetBitDataOutputSizeBytes() );
302                           printf( "TRACE: %s:%d\n", __FILE__, __LINE__ );
303                           outputSize = GetBitDataOutputSizeBytes();
304                           return ENOBUFS;
305                         }
306                       HLTDebug( "Output: Position: %lu / %u (0x%02X / 0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte(-1), (unsigned)GetCurrentOutputByte() );
307                     }
308                   else
309                     {
310                       if ( !OutputBit( 1 ) )
311                         {
312                           HLTError( "Not enough space to write compressed data. %lu already written",
313                                     (unsigned long)GetBitDataOutputSizeBytes() );
314                           outputSize = GetBitDataOutputSizeBytes();
315                           printf( "TRACE: %s:%d\n", __FILE__, __LINE__ );
316                           return ENOBUFS;
317                         }
318                       HLTDebug( "Output: Position: %lu / %u (0x%02X / 0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte(-1), (unsigned)GetCurrentOutputByte() );
319                     }
320                   power = 1<<(AliHLTTPCCompDataCompressorHelper::GetNShapeBits()-1);
321                   if ( abs(temp) >= power )
322                     {
323                       padshapeo++;
324                       temp = power - 1;
325                     }
326                   temp = abs(temp);
327                   if ( !OutputBits(temp,(AliHLTTPCCompDataCompressorHelper::GetNShapeBits()-1)) )
328                     {
329                       HLTError( "Not enough space to write compressed data. %lu already written",
330                                 (unsigned long)GetBitDataOutputSizeBytes() );
331                       printf( "TRACE: %s:%d\n", __FILE__, __LINE__ );
332                       outputSize = GetBitDataOutputSizeBytes();
333                       return ENOBUFS;
334                     }
335                   HLTDebug( "Output: Position: %lu / %u (0x%02X / 0x%02X / 0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte(-2), (unsigned)GetCurrentOutputByte(-1), (unsigned)GetCurrentOutputByte() );
336                   
337                   temp = (Int_t)rint(cluster->fDSigmaZ);
338                   if ( temp<0 )
339                     {
340                       if ( !OutputBit( 0 ) )
341                         {
342                           HLTError( "Not enough space to write compressed data. %lu already written",
343                                     (unsigned long)GetBitDataOutputSizeBytes() );
344                           printf( "TRACE: %s:%d\n", __FILE__, __LINE__ );
345                           outputSize = GetBitDataOutputSizeBytes();
346                           return ENOBUFS;
347                         }
348                       HLTDebug( "Output: Position: %lu / %u (0x%02X / 0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte(-1), (unsigned)GetCurrentOutputByte() );
349                     }
350                   else
351                     {
352                       if ( !OutputBit( 1 ) )
353                         {
354                           HLTError( "Not enough space to write compressed data. %lu already written",
355                                     (unsigned long)GetBitDataOutputSizeBytes() );
356                           printf( "TRACE: %s:%d\n", __FILE__, __LINE__ );
357                           outputSize = GetBitDataOutputSizeBytes();
358                           return ENOBUFS;
359                         }
360                       HLTDebug( "Output: Position: %lu / %u (0x%02X / 0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte(-1), (unsigned)GetCurrentOutputByte() );
361                     }
362                   power = 1<<(AliHLTTPCCompDataCompressorHelper::GetNShapeBits()-1);
363                   if ( abs(temp) >= power )
364                     {
365                       timeshapeo++;
366                       temp=power - 1;
367                     }
368                   temp = abs(temp);
369                   if ( !OutputBits(temp,(AliHLTTPCCompDataCompressorHelper::GetNShapeBits()-1)) )
370                     {
371                       HLTError( "Not enough space to write compressed data. %lu already written",
372                                 (unsigned long)GetBitDataOutputSizeBytes() );
373                       printf( "TRACE: %s:%d\n", __FILE__, __LINE__ );
374                       outputSize = GetBitDataOutputSizeBytes();
375                       return ENOBUFS;
376                     }
377                   HLTDebug( "Output: Position: %lu / %u (0x%02X / 0x%02X / 0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte(-2), (unsigned)GetCurrentOutputByte(-1), (unsigned)GetCurrentOutputByte() );
378                 }
379               
380               clustercount++;
381             }
382           trackCnt++;
383         }
384       
385       CloseBitDataOutput();
386       HLTDebug( "Output: Position: %lu / %u (0x%02X / 0x%02X)", GetCurrentByteOutputPosition(), GetCurrentBitOutputPosition(), (unsigned)GetCurrentOutputByte(-1), (unsigned)GetCurrentOutputByte() );
387       outputSize = GetBitDataOutputSizeBytes();
388       return 0;
389     }
390
391 int AliHLTTPCCompModelDeflater::CompressRemainingClusters( AliHLTUInt8_t* inData, UInt_t const& inputSize, AliHLTUInt8_t* output, UInt_t& outputSize )
392     {
393       // see header file for class documentation
394       AliHLTUInt8_t* inputPtr = inData;
395       AliHLTUInt8_t* inputEndPtr = inData+inputSize;
396       
397       AliHLTUInt32_t version = *(AliHLTUInt32_t*)inputPtr;
398       inputPtr += sizeof(AliHLTUInt32_t);
399       if ( version != 0 )
400         {
401           HLTError( "Unsupported version %hu. Only version 0 supported currently.", version );
402           return EIO;
403         }
404       
405       InitBitDataOutput( output, outputSize );
406       OutputBits( 0, 4 ); // Version information
407       //OutputBit( fWriteShape ); // Data format flag
408       Pad8Bits();
409       
410       //Write the remaining clusters in a compressed format.
411       
412       for(Int_t slice=0; slice<=35; slice++)
413         {
414           for(Int_t patch=0; patch < 6; patch++)
415             {
416               UInt_t i;
417               HLTDebug( "slice %u patch %u: %u padrows",
418                         (unsigned)slice, (unsigned)patch, (unsigned)*inputPtr );
419               //Write number of padrows with clusters
420               if ( inputPtr>=inputEndPtr )
421                 {
422                   HLTError( "Corrupt input data, cannot read row counter for slice %u, partition %u", (unsigned)slice, (unsigned)patch );
423                   return EIO;
424                 }
425               if ( !OutputBits( *inputPtr,8 ) )
426                 {
427                   HLTError( "Not enough space to write compressed data. %lu already written",
428                             (unsigned long)GetBitDataOutputSizeBytes() );
429                   outputSize = GetBitDataOutputSizeBytes();
430                   return ENOBUFS;
431                 }
432               if ( !*inputPtr )
433                 {
434                   inputPtr++;
435                   continue;
436                 }
437               UInt_t nRows=(UInt_t)*inputPtr;
438               inputPtr++;
439               if ( inputPtr>=inputEndPtr )
440                 {
441                   HLTError( "Corrupt input data, unexpected end of data after row counter for slice %u, partition %u", (unsigned)slice, (unsigned)patch );
442                   return EIO;
443                 }
444               
445               for ( UInt_t jj=0; jj<nRows; jj++ )
446                 {
447                   
448                   AliHLTTPCRemainingRow *thisRow = (AliHLTTPCRemainingRow*)inputPtr;
449                   if ( inputPtr+sizeof(AliHLTTPCRemainingRow)>inputEndPtr )
450                     {
451                       HLTError( "Corrupt input data, cannot read row data for row %u of slice %u, partition %u", (unsigned)jj, (unsigned)slice, (unsigned)patch );
452                       return EIO;
453                     }
454                   AliHLTTPCRemainingCluster *cl = thisRow->fClusters;
455                   HLTDebug( "Row %u: %u clusters", (unsigned)thisRow->fPadRow, (unsigned)thisRow->fNClusters );
456                   if ( inputPtr+sizeof(AliHLTTPCRemainingRow)+thisRow->fNClusters*sizeof(AliHLTTPCRemainingCluster)>inputEndPtr )
457                     {
458                       HLTError( "Corrupt input data, unable to read clusters for row %u, slice %u, partition %u", (unsigned)jj, (unsigned)slice, (unsigned)patch );
459                       return EIO;
460                     }
461                   Int_t padrow = thisRow->fPadRow;
462                   if ( !OutputBits(padrow,8) ) //Write padrow #
463                     {
464                       HLTError( "Not enough space to write compressed data. %lu already written",
465                                 (unsigned long)GetBitDataOutputSizeBytes() );
466                       outputSize = GetBitDataOutputSizeBytes();
467                       return ENOBUFS;
468                     }
469                   if( thisRow->fNClusters >= 1<<10)
470                     {
471                       HLTError( "Too many remaining clusters (%u)", (unsigned)thisRow->fNClusters );
472                       return ERANGE;
473                     }
474                   if ( !OutputBits(thisRow->fNClusters,10) )//Write number of clusters on this padrow
475                     {
476                       HLTError( "Not enough space to write compressed data. %lu already written",
477                                 (unsigned long)GetBitDataOutputSizeBytes() );
478                       outputSize = GetBitDataOutputSizeBytes();
479                       return ENOBUFS;
480                     }
481                   for ( i=0; i<thisRow->fNClusters; i++ )
482                     {
483                       
484                       Float_t padw = sqrt(cl[i].fSigmaY2);
485                       //HLTInfo( "padw0: %f", padw );
486                       Float_t timew = sqrt( cl[i].fSigmaZ2 );
487                       
488                       //Check for saturation in the widths.
489                       //Basically only store a certain number of decimals here, and cut the widths which is higher:
490                       if(padw >= (1<<AliHLTTPCCompDataCompressorHelper::GetNShapeBitsRemaining()) / AliHLTTPCCompDataCompressorHelper::GetPadPrecisionFactor())
491                         padw = (1<<AliHLTTPCCompDataCompressorHelper::GetNShapeBitsRemaining()) / AliHLTTPCCompDataCompressorHelper::GetPadPrecisionFactor() - 1/AliHLTTPCCompDataCompressorHelper::GetPadPrecisionFactor();
492                       //HLTInfo( "padw1: %f", padw );
493                       if(timew >= (1<<AliHLTTPCCompDataCompressorHelper::GetNShapeBitsRemaining()) / AliHLTTPCCompDataCompressorHelper::GetTimePrecisionFactor())
494                         timew = (1<<AliHLTTPCCompDataCompressorHelper::GetNShapeBitsRemaining()) / AliHLTTPCCompDataCompressorHelper::GetTimePrecisionFactor() - 1/AliHLTTPCCompDataCompressorHelper::GetTimePrecisionFactor();;
495                       
496                       //Write pad
497                       Int_t buff;
498                       buff = (Int_t)rint(cl[i].fPad*AliHLTTPCCompDataCompressorHelper::GetPadPrecisionFactor());
499                       if(buff<0)
500                         {
501                           HLTError( "Wrong pad value %d (%f, %f, row %u, i: %u)",buff, cl[i].fPad, AliHLTTPCCompDataCompressorHelper::GetPadPrecisionFactor(), (unsigned)thisRow->fNClusters, (unsigned)i );
502                           return EINVAL;
503                         }
504                       if ( !OutputBits(buff,AliHLTTPCCompDataCompressorHelper::GetNPadBitsRemaining()) )
505                         {
506                           HLTError( "Not enough space to write compressed data. %lu already written",
507                                     (unsigned long)GetBitDataOutputSizeBytes() );
508                         outputSize = GetBitDataOutputSizeBytes();
509                         return ENOBUFS;
510                         }
511                       
512                     
513                       //Write time
514                       buff = (Int_t)rint(cl[i].fTime*AliHLTTPCCompDataCompressorHelper::GetTimePrecisionFactor());
515                       if(buff<0)
516                         {
517                           HLTError( "Wrong time value %d",buff);
518                         return EINVAL;
519                         }
520                       if ( !OutputBits(buff,AliHLTTPCCompDataCompressorHelper::GetNTimeBitsRemaining()) )
521                         {
522                           HLTError( "Not enough space to write compressed data. %lu already written",
523                                     (unsigned long)GetBitDataOutputSizeBytes() );
524                           outputSize = GetBitDataOutputSizeBytes();
525                           return ENOBUFS;
526                         }
527                       
528                       //Write widths
529                       buff = (Int_t)rint(padw*AliHLTTPCCompDataCompressorHelper::GetPadPrecisionFactor());
530                       HLTDebug( "padw/buff: %d (%d / 0x%08X)", buff, 
531                                 (buff & ((1<<AliHLTTPCCompDataCompressorHelper::GetNShapeBitsRemaining())-1)),
532                                 (buff & ((1<<AliHLTTPCCompDataCompressorHelper::GetNShapeBitsRemaining())-1)) );
533                       
534                       if ( !OutputBits(buff,AliHLTTPCCompDataCompressorHelper::GetNShapeBitsRemaining()) )
535                         {
536                         HLTError( "Not enough space to write compressed data. %lu already written",
537                                   (unsigned long)GetBitDataOutputSizeBytes() );
538                         outputSize = GetBitDataOutputSizeBytes();
539                         return ENOBUFS;
540                         }
541                       buff = (Int_t)rint(timew*AliHLTTPCCompDataCompressorHelper::GetTimePrecisionFactor());
542                       if ( !OutputBits(buff,AliHLTTPCCompDataCompressorHelper::GetNShapeBitsRemaining()) )
543                         {
544                           HLTError( "Not enough space to write compressed data. %lu already written",
545                                     (unsigned long)GetBitDataOutputSizeBytes() );
546                           outputSize = GetBitDataOutputSizeBytes();
547                           return ENOBUFS;
548                         }
549                       
550                       //Write charge 
551                       buff = cl[i].fCharge;
552                       if(buff >= 1<<(AliHLTTPCCompDataCompressorHelper::GetNChargeBits()))
553                         buff = (1<<(AliHLTTPCCompDataCompressorHelper::GetNChargeBits()))-1;
554                       if ( !OutputBits(buff,AliHLTTPCCompDataCompressorHelper::GetNChargeBits()) )
555                         {
556                           HLTError( "Not enough space to write compressed data. %lu already written",
557                                     (unsigned long)GetBitDataOutputSizeBytes() );
558                           outputSize = GetBitDataOutputSizeBytes();
559                           return ENOBUFS;
560                         }
561                     }
562                   inputPtr += sizeof(AliHLTTPCRemainingRow)+thisRow->fNClusters*sizeof(AliHLTTPCRemainingCluster);
563                 }
564             }
565           
566         }
567       CloseBitDataOutput();
568       outputSize = GetBitDataOutputSizeBytes();
569       return 0;
570     }