implementing association of cluster MC labels and cluster ids to the unpacked cluster...
[u/mrichter/AliRoot.git] / HLT / TPCLib / comp / AliHLTTPCDataCompressionDecoder.h
1 //-*- Mode: C++ -*-
2 // $Id$
3 #ifndef ALIHLTTPCDATACOMPRESSIONDECODER_H
4 #define ALIHLTTPCDATACOMPRESSIONDECODER_H
5 //* This file is property of and copyright by the ALICE HLT Project        * 
6 //* ALICE Experiment at CERN, All rights reserved.                         *
7 //* See cxx source for full Copyright notice                               *
8
9 /// @file   AliHLTTPCDataCompressionDecoder.h
10 /// @author Matthias Richter
11 /// @date   2011-10-04
12 /// @brief  Generic decoder class for compressed TPC data, works on a container
13 ///         class implementation which fills the actual target data struct
14
15 #include "AliHLTLogging.h"
16 #include "AliHLTMisc.h"
17 #include "AliHLTTPCDataCompressionComponent.h"
18 #include "AliHLTTPCDefinitions.h"
19 #include "AliHLTTPCClusterDataFormat.h"
20 #include "AliHLTTPCRawCluster.h"
21 #include "AliHLTTPCTransform.h"
22 #include "AliHLTTPCTrackGeometry.h"
23 #include "AliHLTDataInflater.h"
24 #include "AliHLTTPCHWClusterMerger.h"
25 #include <vector>
26
27 /**
28  * @class AliHLTTPCDataCompressionDecoder
29  * Generic decoder class for compressed TPC data, works on a container
30  * class implementation which fills the actual target data struct
31  */
32 class AliHLTTPCDataCompressionDecoder : public AliHLTLogging {
33  public:
34   AliHLTTPCDataCompressionDecoder();
35   ~AliHLTTPCDataCompressionDecoder();
36
37   template<typename T>
38   int ReadRemainingClustersCompressed(T& c, const AliHLTUInt8_t* pData, int dataSize, AliHLTUInt32_t specification);
39
40   template<typename T>
41   int ReadRemainingClustersCompressed(T& c, AliHLTDataInflater* pInflater, int nofClusters, AliHLTUInt32_t specification, int formatVersion=0);
42
43   template<typename T>
44   int ReadTrackModelClustersCompressed(T& c, const AliHLTUInt8_t* pData, int dataSize, AliHLTUInt32_t specification);
45
46   template<typename T>
47   int ReadTrackClustersCompressed(T& c, AliHLTDataInflater* pInflater, AliHLTTPCTrackGeometry* pTrackPoints);
48
49   template<typename T>
50   int ReadClustersPartition(T& c, const AliHLTUInt8_t* pData, unsigned dataSize, AliHLTUInt32_t specification);
51
52   AliHLTDataInflater* CreateInflater(int deflater, int mode) const;
53
54   void SetPadShift(float padShift) {fPadShift=padShift;}
55   float PadShift() const {return fPadShift;}
56   void SetVerbosity(int verbosity) {fVerbosity=verbosity;}
57   void EnableClusterMerger() {if (!fpClusterMerger) fpClusterMerger=new AliHLTTPCHWClusterMerger;}
58
59   int InitPartitionClusterDecoding(AliHLTUInt32_t specification);
60   int InitTrackModelClusterClusterDecoding();
61   int AddClusterMCData(const AliHLTComponentBlockData* pDesc);
62   int AddClusterIds(const AliHLTComponentBlockData* pDesc);
63   AliHLTUInt32_t GetClusterId(int clusterNo) const;
64   const AliHLTTPCClusterMCLabel* GetMCLabel(AliHLTUInt32_t clusterId) const;
65
66   void Clear(const char* option);
67
68   struct AliClusterIdBlock {
69     AliClusterIdBlock() : fIds(NULL), fSize(0) {}
70     AliHLTUInt32_t* fIds; //!
71     AliHLTUInt32_t  fSize; //!
72   };
73
74  protected:
75  private:
76   AliHLTTPCDataCompressionDecoder(const AliHLTTPCDataCompressionDecoder&);
77   AliHLTTPCDataCompressionDecoder& operator=(const AliHLTTPCDataCompressionDecoder&);
78
79   float fPadShift; //! pad shift
80   int fVerbosity; //! verbosity level
81   AliHLTDataInflater* fpDataInflaterPartition; //! instance of inflater for partition clusters
82   AliHLTDataInflater* fpDataInflaterTrack; //! instance of inflater for track clusters
83   AliHLTTPCHWClusterMerger* fpClusterMerger; //! merger instance
84
85   vector<AliClusterIdBlock> fRemainingClusterIds; //! clusters ids for remaining cluster ids
86   AliClusterIdBlock fTrackModelClusterIds; //! cluster ids for track model clusters
87   AliClusterIdBlock* fCurrentClusterIds; //! id block currently active in the iteration
88   vector<const AliHLTTPCClusterMCData*> fClusterMCData; //! references to MC data blocks
89
90   ClassDef(AliHLTTPCDataCompressionDecoder, 0)
91 };
92
93 template<typename T>
94 int AliHLTTPCDataCompressionDecoder::ReadRemainingClustersCompressed(T& c, const AliHLTUInt8_t* pData, int dataSize, AliHLTUInt32_t specification)
95 {
96   // read cluster data from AliHLTTPCClusterData
97   int iResult=0;
98   if (!pData  || dataSize<4) return -EINVAL;
99
100   const AliHLTUInt8_t* pBuffer=pData;
101   AliHLTUInt32_t size=dataSize;
102   const AliHLTTPCRawClusterData* clusterData = reinterpret_cast<const AliHLTTPCRawClusterData*>(pBuffer);
103   Int_t nCount = (Int_t) clusterData->fCount;
104
105   int formatVersion=1;
106   int deflaterMode=2;
107   switch (clusterData->fVersion) {
108   case 1: deflaterMode=1; formatVersion=0; break;
109   case 2: deflaterMode=2; formatVersion=0; break;
110   case 3: deflaterMode=1; formatVersion=1; break;
111   case 4: deflaterMode=2; formatVersion=1; break;
112   default:
113     return -EBADF;
114   }
115   if (!fpDataInflaterPartition)
116     fpDataInflaterPartition=CreateInflater(deflaterMode, 1);
117   else
118     fpDataInflaterPartition->Clear();
119   if (!fpDataInflaterPartition) return -ENODEV;
120
121   if ((iResult=fpDataInflaterPartition->InitBitDataInput(reinterpret_cast<const AliHLTUInt8_t*>(clusterData->fClusters),
122                                                 size-sizeof(AliHLTTPCRawClusterData)))<0) {
123     return iResult;
124   }
125
126   iResult=ReadRemainingClustersCompressed(c, fpDataInflaterPartition, nCount, specification, formatVersion);
127
128   return iResult;
129 }
130
131 template<typename T>
132 int AliHLTTPCDataCompressionDecoder::ReadRemainingClustersCompressed(T& c, AliHLTDataInflater* pInflater, int nofClusters, AliHLTUInt32_t specification, int formatVersion)
133 {
134   // read cluster data
135
136   int iResult=0;
137   if (!pInflater) return -EINVAL;
138
139   if ((iResult= InitPartitionClusterDecoding(specification))<0)
140     return iResult;
141
142   AliHLTUInt8_t slice = AliHLTTPCDefinitions::GetMinSliceNr(specification);
143   AliHLTUInt8_t partition = AliHLTTPCDefinitions::GetMinPatchNr(specification);
144   // the compressed format stores the difference of the local row number in
145   // the partition to the row of the last cluster
146   // add the first row in the partition to get global row number
147   int rowOffset=AliHLTTPCTransform::GetFirstRow(partition);
148
149   int parameterId=pInflater->NextParameter();
150   if (parameterId<0) return parameterId;
151   int decodedClusterCnt=0;
152   int outClusterCnt=0;
153   AliHLTUInt64_t value=0;
154   AliHLTUInt32_t length=0;
155   AliHLTUInt32_t lastPadRow=0;
156   AliHLTUInt64_t lastPad64=0;
157   AliHLTUInt64_t lastTime64=0;
158   AliHLTUInt8_t isSinglePad=0;
159   AliHLTUInt8_t sign=0;
160   bool bNextCluster=true;
161   bool bReadSuccess=true;
162   AliHLTTPCRawCluster rawCluster;
163   if (fpClusterMerger)
164     fpClusterMerger->Clear();
165
166   while (decodedClusterCnt<nofClusters && bReadSuccess && pInflater->NextValue(value, length)) {
167     if (bNextCluster) {
168       // switch to next cluster
169       rawCluster.Clear();
170       bNextCluster=false;
171     }
172     const AliHLTTPCDefinitions::AliClusterParameter& parameter
173       =AliHLTTPCDefinitions::fgkClusterParameterDefinitions[parameterId];
174
175     if (parameter.fBitLength!=(int)length) {
176       HLTError("decode error: expecting length %d for parameter %s, but got %d",
177                parameter.fBitLength, parameter.fName, length);
178       break;
179     }
180
181     switch (parameterId) {
182     case AliHLTTPCDefinitions::kPadRow:
183       {rawCluster.SetPadRow(value+lastPadRow); lastPadRow+=value;break;}
184     case AliHLTTPCDefinitions::kPad: {
185       if (formatVersion==1) {
186         bReadSuccess=bReadSuccess && pInflater->InputBit(isSinglePad);
187         if (isSinglePad==0) {
188           bReadSuccess=bReadSuccess && pInflater->InputBit(sign);
189           if (sign) {
190             value=lastPad64-value;
191           } else {
192             value+=lastPad64;
193           }
194           lastPad64=value;
195         }
196       }
197       float pad=value;
198       if (isSinglePad==0) pad/=parameter.fScale;
199       else pad/=2; // for the sake of the 0.5 pad offset (see AliHLTTPCHWCFSpacePointContainer::WriteSorted for details)
200       rawCluster.SetPad(pad+PadShift());
201       break;
202     }
203     case AliHLTTPCDefinitions::kTime: {
204       if (formatVersion==1) {
205         bReadSuccess=bReadSuccess && pInflater->InputBit(sign);
206         if (sign) {
207           value=lastTime64-value;
208         } else {
209           value+=lastTime64;
210         }
211         lastTime64=value;
212       }
213       float time=value; time/=parameter.fScale;
214       rawCluster.SetTime(time);
215       break;
216     }
217     case AliHLTTPCDefinitions::kSigmaY2:
218       {float sigmaY2=value; sigmaY2/=parameter.fScale; rawCluster.SetSigmaY2(sigmaY2); break;}
219     case AliHLTTPCDefinitions::kSigmaZ2:
220       {float sigmaZ2=value; sigmaZ2/=parameter.fScale; rawCluster.SetSigmaZ2(sigmaZ2); break;}
221     case AliHLTTPCDefinitions::kCharge:
222       {rawCluster.SetCharge(value); break;}
223     case AliHLTTPCDefinitions::kQMax:
224       {rawCluster.SetQMax(value); break;}
225     }
226     if (parameterId>=AliHLTTPCDefinitions::kLast) {
227       AliHLTUInt32_t id=GetClusterId(decodedClusterCnt);
228       const AliHLTTPCClusterMCLabel* pMC=GetMCLabel(id);
229       if (fpClusterMerger && fpClusterMerger->CheckCandidate(slice, partition, rawCluster)) {
230         fpClusterMerger->AddCandidate(slice, partition, id, rawCluster, pMC);
231       } else {
232       c.Next(slice, partition);
233       c.SetPadRow(rawCluster.GetPadRow()+rowOffset);
234       c.SetPad(rawCluster.GetPad());
235       c.SetTime(rawCluster.GetTime());
236       c.SetSigmaY2(rawCluster.GetSigmaY2());
237       c.SetSigmaZ2(rawCluster.GetSigmaZ2());
238       c.SetCharge(rawCluster.GetCharge());
239       c.SetQMax(rawCluster.GetQMax());
240       if (pMC) c.SetMC(pMC);
241       outClusterCnt++;
242       }
243       bNextCluster=true;
244       decodedClusterCnt++;
245     }
246     parameterId=pInflater->NextParameter();
247     if (parameterId==AliHLTTPCDefinitions::kSigmaY2 && isSinglePad==1) {
248       // skip sigmaY for single pad clusters in format version 1
249       parameterId=pInflater->NextParameter();
250       isSinglePad=0;
251       rawCluster.SetSigmaY2(0.);
252     }
253   }
254   pInflater->Pad8Bits();
255   AliHLTUInt8_t bit=0;
256   if (pInflater->InputBit(bit)) {
257     HLTWarning("format error of compressed clusters, there is more data than expected");
258   }
259   pInflater->CloseBitDataInput();
260   int mergedClusterCnt=0;
261   if (fpClusterMerger) {
262     mergedClusterCnt=fpClusterMerger->Merge();
263     int remainingCnt=0;
264     if (mergedClusterCnt>=0) {
265       for (AliHLTTPCHWClusterMerger::iterator i=fpClusterMerger->begin();
266            i!=fpClusterMerger->end(); i++) {
267         c.Next((*i).GetSlice(), (*i).GetPartition());
268         const AliHLTTPCRawCluster& mergedCluster=(*i).GetCluster();
269         const AliHLTTPCClusterMCLabel& mc=(*i).MCLabel();
270         c.SetPadRow(mergedCluster.GetPadRow()+rowOffset);
271         c.SetPad(mergedCluster.GetPad());
272         c.SetTime(mergedCluster.GetTime());
273         c.SetSigmaY2(mergedCluster.GetSigmaY2());
274         c.SetSigmaZ2(mergedCluster.GetSigmaZ2());
275         c.SetCharge(mergedCluster.GetCharge());
276         c.SetQMax(mergedCluster.GetQMax());
277         c.SetMC(&mc);
278         outClusterCnt++;
279         remainingCnt++;
280       }
281     } else {
282       iResult=mergedClusterCnt;
283     }
284     HLTDebug("copied %d cluster(s) from merger, %d merged, specification 0x%08x", remainingCnt, mergedClusterCnt, specification);
285     fpClusterMerger->Clear();
286   }
287   if (iResult>=0 && nofClusters!=outClusterCnt+mergedClusterCnt) {
288     // is this a Fatal?
289     HLTError("error reading compressed cluster format of block 0x%08x: expected %d, read %d cluster(s), merged %d cluster(s)", specification, nofClusters, outClusterCnt, mergedClusterCnt);
290     return -EPROTO;
291   }
292   if (iResult<0) return iResult;
293   return outClusterCnt;
294 }
295
296 template<typename T>
297 int AliHLTTPCDataCompressionDecoder::ReadTrackModelClustersCompressed(T& c, const AliHLTUInt8_t* pData, int dataSize, AliHLTUInt32_t /*specification*/)
298 {
299   // read cluster data from the track model data block
300   int iResult=0;
301   int dataOffset=sizeof(AliHLTTPCDataCompressionComponent::AliHLTTPCTrackModelBlock);
302   if (!pData  || dataSize<dataOffset) return -EINVAL;
303
304   const AliHLTTPCDataCompressionComponent::AliHLTTPCTrackModelBlock* trackModelBlock=reinterpret_cast<const AliHLTTPCDataCompressionComponent::AliHLTTPCTrackModelBlock*>(pData);
305   if (trackModelBlock->fVersion!=1) {
306     HLTError("unknown version %d", trackModelBlock->fVersion);
307     return -EINVAL;
308   }
309   if (!fpDataInflaterTrack)
310     fpDataInflaterTrack=CreateInflater(trackModelBlock->fDeflaterMode, 2);
311   else
312     fpDataInflaterTrack->Clear();
313   if (!fpDataInflaterTrack) {
314     HLTError("failed to create the data inflater for mode %d", trackModelBlock->fDeflaterMode);
315     return -ENODEV;
316   }
317   int nofTracks=trackModelBlock->fTrackCount;
318   dataOffset+=trackModelBlock->fGlobalParameterCnt*sizeof(trackModelBlock->fGlobalParameters);
319   if (dataSize<dataOffset) {
320     HLTError("inconsistent data block, size %d, expecting at least %d to read AliHLTTPCTrackModelBlock with %d global parameters", dataSize, dataOffset, trackModelBlock->fGlobalParameterCnt);
321     return -ENOSPC;
322   }
323   float bz=0.0;
324   float driftTimeFactorA=0.;
325   float driftTimeOffsetA=0.;
326   float driftTimeFactorC=0.;
327   float driftTimeOffsetC=0.;
328
329   AliHLTUInt32_t parameterIndex=0;
330   switch (trackModelBlock->fGlobalParameterCnt) {
331   case 5:
332     bz              =trackModelBlock->fGlobalParameters[parameterIndex++];
333     driftTimeFactorA=trackModelBlock->fGlobalParameters[parameterIndex++];
334     driftTimeOffsetA=trackModelBlock->fGlobalParameters[parameterIndex++];
335     driftTimeFactorC=trackModelBlock->fGlobalParameters[parameterIndex++];
336     driftTimeOffsetC=trackModelBlock->fGlobalParameters[parameterIndex++];
337     break;
338   default:
339     HLTError("unknown version of global parameters %d", trackModelBlock->fGlobalParameterCnt);
340     return -ENODATA;
341   }
342
343   if (parameterIndex!=trackModelBlock->fGlobalParameterCnt) {
344     HLTError("internal error, size of parameter array has changed without providing all values");
345     return -EFAULT;
346   }
347
348   for (int trackno=0; trackno<nofTracks; trackno++) {
349     AliHLTTPCTrackGeometry trackpoints;
350     trackpoints.InitDriftTimeTransformation(driftTimeFactorA, driftTimeOffsetA, driftTimeFactorC, driftTimeOffsetC);
351     AliHLTUInt32_t  clusterBlockSize=0;
352     if ((iResult=trackpoints.Read(pData+dataOffset, dataSize-dataOffset, bz, clusterBlockSize))<0) {
353       return iResult;
354     }
355     dataOffset+=iResult;
356     if (dataSize-dataOffset<(int)clusterBlockSize) {
357       HLTError("to little data in buffer to read cluster block of size %d for track no %d", clusterBlockSize, trackno);
358       return -ENODATA;
359     }
360     if ((iResult=fpDataInflaterTrack->InitBitDataInput(pData+dataOffset, clusterBlockSize))<0) {
361       return iResult;
362     }
363     if ((iResult=ReadTrackClustersCompressed(c, fpDataInflaterTrack, &trackpoints))<0) {
364       HLTError("reading of associated clusters failed for track %d", trackno);
365       return iResult;
366     }
367     fpDataInflaterTrack->Pad8Bits();
368     AliHLTUInt8_t bit=0;
369     if (fpDataInflaterTrack->InputBit(bit)) {
370       HLTWarning("format error of compressed clusters, there is more data than expected");
371     }
372     fpDataInflaterTrack->CloseBitDataInput();
373     dataOffset+=clusterBlockSize;
374   }
375
376   return iResult;
377 }
378
379 template<typename T>
380 int AliHLTTPCDataCompressionDecoder::ReadTrackClustersCompressed(T& c, AliHLTDataInflater* pInflater, AliHLTTPCTrackGeometry* pTrackPoints)
381 {
382   // read cluster data
383
384   int iResult=0;
385   if (!pInflater || !pTrackPoints) return -EINVAL;
386
387   if ((iResult= InitTrackModelClusterClusterDecoding())<0)
388     return iResult;
389
390   const vector<AliHLTTrackGeometry::AliHLTTrackPoint>& rawTrackPoints=pTrackPoints->GetRawPoints();
391   vector<AliHLTTrackGeometry::AliHLTTrackPoint>::const_iterator currentTrackPoint=rawTrackPoints.begin();
392
393   bool bReadSuccess=true;
394   AliHLTUInt32_t clusterCountBitLength=AliHLTTPCDefinitions::fgkClusterParameterDefinitions[AliHLTTPCDefinitions::kClusterCount].fBitLength;
395   //unsigned long dataPosition=pInflater->GetCurrentByteInputPosition();
396   for (unsigned row=0; row<159 && bReadSuccess; row++) {
397     AliHLTUInt8_t haveClusters=0;
398     // 1 bit for clusters on that padrow
399     bReadSuccess=bReadSuccess && pInflater->InputBit(haveClusters);
400     if (!haveClusters) continue;
401     bool bEscape=false;
402     do {
403       if (currentTrackPoint==rawTrackPoints.end()) {
404         if (bEscape || rawTrackPoints.begin()==rawTrackPoints.end()) break;
405         currentTrackPoint=rawTrackPoints.begin();
406         bEscape=true;
407       }
408       if (AliHLTTPCTransform::GetFirstRow(AliHLTTPCSpacePointData::GetPatch(currentTrackPoint->GetId())) +
409           AliHLTTPCSpacePointData::GetNumber(currentTrackPoint->GetId()) == row) {
410         break;
411       }
412       currentTrackPoint++;
413     } while (!bEscape);
414     if (currentTrackPoint==rawTrackPoints.end()) {
415       HLTError("decoding error, can not find track point on row %d", row);
416       return -EFAULT;
417     }
418     AliHLTUInt8_t slice = AliHLTTPCSpacePointData::GetSlice(currentTrackPoint->GetId());
419     AliHLTUInt8_t partition = AliHLTTPCSpacePointData::GetPatch(currentTrackPoint->GetId());
420     AliHLTUInt8_t nofClusters=0;
421     bReadSuccess=bReadSuccess && pInflater->InputBits(nofClusters, clusterCountBitLength);
422     if (!bReadSuccess) break;
423     HLTDebug("slice %02d partition %d row %03d: %d cluster(s)", slice, partition, row, nofClusters);
424
425     static const AliHLTTPCDefinitions::AliClusterParameterId_t kParameterIdMapping[] = {
426       AliHLTTPCDefinitions::kResidualPad,
427       AliHLTTPCDefinitions::kResidualTime,
428       AliHLTTPCDefinitions::kSigmaY2,
429       AliHLTTPCDefinitions::kSigmaZ2,
430       AliHLTTPCDefinitions::kCharge,
431       AliHLTTPCDefinitions::kQMax,
432     };
433
434     int parameterId=0;
435     int inClusterCnt=0;
436     AliHLTUInt64_t value=0;
437     AliHLTUInt32_t length=0;
438     bool bNextCluster=true;
439     while (bReadSuccess && inClusterCnt<nofClusters && pInflater->NextValue(value, length)) {
440       if (bNextCluster) {
441         // switch to next cluster
442         c.Next(slice, partition);
443         c.SetPadRow(row);
444         bNextCluster=false;
445       }
446       const AliHLTTPCDefinitions::AliClusterParameter& parameter
447         =AliHLTTPCDefinitions::fgkClusterParameterDefinitions[kParameterIdMapping[parameterId]];
448
449       if (parameter.fBitLength!=(int)length) {
450         HLTError("decode error: expecting length %d for parameter %s, but got %d",
451                  parameter.fBitLength, parameter.fName, length);
452         break;
453       }
454
455       static float deltapad=0.;
456       static float deltatime=0.;
457       bool lastParameter=false;
458       switch (kParameterIdMapping[parameterId]) {
459       case AliHLTTPCDefinitions::kResidualPad:
460         {
461           AliHLTUInt8_t sign=0;
462           bReadSuccess=bReadSuccess && pInflater->InputBit(sign);
463           deltapad=((float)value)*(sign?-1.:1.)/parameter.fScale;
464           AliHLTUInt64_t trackpad64=0;
465           double trackpad=currentTrackPoint->GetU();
466           trackpad*=AliHLTTPCDefinitions::fgkClusterParameterDefinitions[AliHLTTPCDefinitions::kResidualPad].fScale;
467           if (currentTrackPoint->GetU()>0.) trackpad64=(AliHLTUInt64_t)round(trackpad);
468           if (sign) {
469             value=trackpad64-value;
470           } else {
471             value+=trackpad64;
472           }
473           float pad=((float)value)/parameter.fScale;
474           c.SetPad(pad+PadShift()); 
475           break;
476         }
477       case AliHLTTPCDefinitions::kResidualTime:
478         {
479           AliHLTUInt8_t sign=0;
480           bReadSuccess=bReadSuccess && pInflater->InputBit(sign);
481           deltatime=((float)value)*(sign?-1.:1.)/parameter.fScale;
482           AliHLTUInt64_t tracktime64=0;
483           double tracktime=currentTrackPoint->GetV();
484           tracktime*=AliHLTTPCDefinitions::fgkClusterParameterDefinitions[AliHLTTPCDefinitions::kResidualTime].fScale;
485           if (currentTrackPoint->GetV()>0.) tracktime64=(AliHLTUInt64_t)round(tracktime);
486           if (sign) {
487             value=tracktime64-value;
488           } else {
489             value+=tracktime64;
490           }
491           float time=((float)value)/parameter.fScale;
492           c.SetTime(time); 
493           break;
494         }
495       case AliHLTTPCDefinitions::kSigmaY2:
496         {float sigmaY2=value; sigmaY2/=parameter.fScale; c.SetSigmaY2(sigmaY2); break;}
497       case AliHLTTPCDefinitions::kSigmaZ2:
498         {float sigmaZ2=value; sigmaZ2/=parameter.fScale; c.SetSigmaZ2(sigmaZ2); break;}
499       case AliHLTTPCDefinitions::kCharge:
500         {c.SetCharge(value); break;}
501       case AliHLTTPCDefinitions::kQMax:
502         {c.SetQMax(value); lastParameter=true; break;}
503       default:
504         {
505           HLTError("parameter %d not expected", kParameterIdMapping[parameterId]);
506         }
507       }
508       if (lastParameter) {
509         // switch to next cluster
510         // cout << "  row "    << setfill(' ') << setw(3) << fixed << right                     << c.GetRow()
511         //      << "  pad "    << setfill(' ') << setw(7) << fixed << right << setprecision (4) << c.GetPad()
512         //      << "  dpad "   << setfill(' ') << setw(7) << fixed << right << setprecision (4) << deltapad
513         //      << "  time "   << setfill(' ') << setw(7) << fixed << right << setprecision (4) << c.GetTimeBin()
514         //      << "  dtime "  << setfill(' ') << setw(7) << fixed << right << setprecision (4) << deltatime
515         //      << "  charge " << setfill(' ') << setw(5) << fixed << right << setprecision (0) << c.GetQ()
516         //      << "  qmax "   << setfill(' ') << setw(4) << fixed << right << setprecision (0) << c.GetMax()
517         //      << endl;
518         bNextCluster=true;
519         inClusterCnt++;
520         parameterId=-1;
521       }
522       parameterId++;
523     }
524     if (iResult>=0 && nofClusters!=inClusterCnt) {
525       // is this a Fatal?
526       HLTError("error reading track model compressed cluster format of track: expected %d, read only %d cluster(s)", nofClusters, inClusterCnt);
527       return -EPROTO;
528     }
529     currentTrackPoint++;
530   }
531   return iResult;
532 }
533
534 template<typename T>
535 int AliHLTTPCDataCompressionDecoder::ReadClustersPartition(T& c, const AliHLTUInt8_t* pData, unsigned dataSize, AliHLTUInt32_t specification)
536 {
537   // read raw cluster data
538   if (!pData) return -EINVAL;
539   if (dataSize<sizeof(AliHLTTPCRawClusterData)) return -ENODATA;
540   const AliHLTTPCRawClusterData* clusterData = reinterpret_cast<const AliHLTTPCRawClusterData*>(pData);
541   Int_t nCount = (Int_t) clusterData->fCount;
542   if (clusterData->fVersion!=0) {
543     int iResult=ReadRemainingClustersCompressed(c, pData, dataSize, specification);
544     if (iResult>=0 && fVerbosity>0) {
545       HLTInfo("extracted %d cluster(s) from block 0x%08x", iResult, specification);
546     }
547     return iResult;
548   }
549   if (nCount*sizeof(AliHLTTPCRawCluster) + sizeof(AliHLTTPCRawClusterData) != dataSize) return -EBADF;
550   AliHLTUInt8_t slice = AliHLTTPCDefinitions::GetMinSliceNr(specification);
551   AliHLTUInt8_t partition = AliHLTTPCDefinitions::GetMinPatchNr(specification);
552
553   const AliHLTTPCRawCluster *clusters = clusterData->fClusters;
554   for (int i=0; i<nCount; i++) {
555     c.Next(slice, partition);
556     c.SetPadRow(clusters[i].GetPadRow());
557     c.SetPad(clusters[i].GetPad()+PadShift());
558     c.SetTime(clusters[i].GetTime());
559     c.SetSigmaY2(clusters[i].GetSigmaY2());
560     c.SetSigmaZ2(clusters[i].GetSigmaZ2());
561     c.SetCharge(clusters[i].GetCharge());
562     c.SetQMax(clusters[i].GetQMax());
563   }
564   return nCount;
565 }
566 #endif