make iterattion to next cluster structure better suited for decoding
[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
25 /**
26  * @class AliHLTTPCDataCompressionDecoder
27  * Generic decoder class for compressed TPC data, works on a container
28  * class implementation which fills the actual target data struct
29  */
30 class AliHLTTPCDataCompressionDecoder : public AliHLTLogging {
31  public:
32   AliHLTTPCDataCompressionDecoder();
33   ~AliHLTTPCDataCompressionDecoder();
34
35   template<typename T>
36   int ReadRemainingClustersCompressed(T& c, const AliHLTUInt8_t* pData, int dataSize, AliHLTUInt32_t specification);
37
38   template<typename T>
39   int ReadRemainingClustersCompressed(T& c, AliHLTDataInflater* pInflater, int nofClusters, AliHLTUInt32_t specification);
40
41   template<typename T>
42   int ReadTrackModelClustersCompressed(T& c, const AliHLTUInt8_t* pData, int dataSize, AliHLTUInt32_t specification);
43
44   template<typename T>
45   int ReadTrackClustersCompressed(T& c, AliHLTDataInflater* pInflater, AliHLTTPCTrackGeometry* pTrackPoints);
46
47   AliHLTDataInflater* CreateInflater(int deflater, int mode) const;
48
49  protected:
50  private:
51   ClassDef(AliHLTTPCDataCompressionDecoder, 0)
52 };
53
54 template<typename T>
55 int AliHLTTPCDataCompressionDecoder::ReadRemainingClustersCompressed(T& c, const AliHLTUInt8_t* pData, int dataSize, AliHLTUInt32_t specification)
56 {
57   // read cluster data from AliHLTTPCClusterData
58   int iResult=0;
59   if (!pData  || dataSize<4) return -EINVAL;
60
61   const AliHLTUInt8_t* pBuffer=pData;
62   AliHLTUInt32_t size=dataSize;
63   const AliHLTTPCRawClusterData* clusterData = reinterpret_cast<const AliHLTTPCRawClusterData*>(pBuffer);
64   Int_t nCount = (Int_t) clusterData->fCount;
65
66   AliHLTDataInflater* inflater=CreateInflater(clusterData->fVersion, 1);
67   if (!inflater) return -ENODEV;
68
69   if ((iResult=inflater->InitBitDataInput(reinterpret_cast<const AliHLTUInt8_t*>(clusterData->fClusters),
70                                           size-sizeof(AliHLTTPCRawClusterData)))<0) {
71     return iResult;
72   }
73
74   iResult=ReadRemainingClustersCompressed(c, inflater, nCount, specification);
75
76   return iResult;
77 }
78
79 template<typename T>
80 int AliHLTTPCDataCompressionDecoder::ReadRemainingClustersCompressed(T& c, AliHLTDataInflater* pInflater, int nofClusters, AliHLTUInt32_t specification)
81 {
82   // read cluster data
83
84   int iResult=0;
85   if (!pInflater) return -EINVAL;
86
87   AliHLTUInt8_t slice = AliHLTTPCDefinitions::GetMinSliceNr(specification);
88   AliHLTUInt8_t partition = AliHLTTPCDefinitions::GetMinPatchNr(specification);
89   // the compressed format stores the difference of the local row number in
90   // the partition to the row of the last cluster
91   // add the first row in the partition to get global row number
92   int rowOffset=AliHLTTPCTransform::GetFirstRow(partition);
93
94   int parameterId=0;
95   int outClusterCnt=0;
96   AliHLTUInt64_t value=0;
97   AliHLTUInt32_t length=0;
98   AliHLTUInt32_t lastPadRow=0;
99   bool bNextCluster=true;
100   while (outClusterCnt<nofClusters && pInflater->NextValue(value, length)) {
101     if (bNextCluster) {
102       // switch to next cluster
103       c.Next(slice, partition);
104       bNextCluster=false;
105     }
106     const AliHLTTPCDefinitions::AliClusterParameter& parameter
107       =AliHLTTPCDefinitions::fgkClusterParameterDefinitions[parameterId];
108
109     if (parameter.fBitLength!=(int)length) {
110       HLTError("decode error: expecting length %d for parameter %s, but got %d",
111                parameter.fBitLength, parameter.fName, length);
112       break;
113     }
114
115     switch (parameterId) {
116     case AliHLTTPCDefinitions::kPadRow:
117       {c.SetPadRow(value+lastPadRow+rowOffset); lastPadRow+=value;break;}
118     case AliHLTTPCDefinitions::kPad:
119       {float pad=value; pad/=parameter.fScale; c.SetPad(pad); break;}
120     case AliHLTTPCDefinitions::kTime:
121       {float time=value; time/=parameter.fScale; c.SetTime(time); break;}
122     case AliHLTTPCDefinitions::kSigmaY2:
123       {float sigmaY2=value; sigmaY2/=parameter.fScale; c.SetSigmaY2(sigmaY2); break;}
124     case AliHLTTPCDefinitions::kSigmaZ2:
125       {float sigmaZ2=value; sigmaZ2/=parameter.fScale; c.SetSigmaZ2(sigmaZ2); break;}
126     case AliHLTTPCDefinitions::kCharge:
127       {c.SetCharge(value); break;}
128     case AliHLTTPCDefinitions::kQMax:
129       {c.SetQMax(value); break;}
130     }
131     if (parameterId>=AliHLTTPCDefinitions::kLast) {
132       bNextCluster=true;
133       outClusterCnt++;
134       parameterId=-1;
135     }
136     parameterId++;
137   }
138   pInflater->Pad8Bits();
139   AliHLTUInt8_t bit=0;
140   if (pInflater->InputBit(bit)) {
141     HLTWarning("format error of compressed clusters, there is more data than expected");
142   }
143   pInflater->CloseBitDataInput();
144   if (iResult>=0 && nofClusters!=outClusterCnt) {
145     // is this a Fatal?
146     HLTError("error reading compressed cluster format of block 0x%08x: expected %d, read only %d cluster(s)", specification, nofClusters, outClusterCnt);
147     return -EPROTO;
148   }
149   return iResult;
150 }
151
152 template<typename T>
153 int AliHLTTPCDataCompressionDecoder::ReadTrackModelClustersCompressed(T& c, const AliHLTUInt8_t* pData, int dataSize, AliHLTUInt32_t /*specification*/)
154 {
155   // read cluster data from the track model data block
156   int iResult=0;
157   int dataOffset=sizeof(AliHLTTPCDataCompressionComponent::AliHLTTPCTrackModelBlock);
158   if (!pData  || dataSize<dataOffset) return -EINVAL;
159
160   const AliHLTTPCDataCompressionComponent::AliHLTTPCTrackModelBlock* trackModelBlock=reinterpret_cast<const AliHLTTPCDataCompressionComponent::AliHLTTPCTrackModelBlock*>(pData);
161   if (trackModelBlock->fVersion!=1) {
162     HLTError("unknown version %d", trackModelBlock->fVersion);
163     return -EINVAL;
164   }
165   std::auto_ptr<AliHLTDataInflater> pInflater(CreateInflater(trackModelBlock->fDeflaterMode, 2));
166   if (!pInflater.get()) {
167     HLTError("failed to create the data inflater for mode %d", trackModelBlock->fDeflaterMode);
168   }
169   int nofTracks=trackModelBlock->fTrackCount;
170   dataOffset+=trackModelBlock->fGlobalParameterCnt*sizeof(trackModelBlock->fGlobalParameters);
171   if (dataSize<dataOffset) {
172     HLTError("inconsistent data block, size %d, expecting at least %d to read AliHLTTPCTrackModelBlock with %d global parameters", dataSize, dataOffset, trackModelBlock->fGlobalParameterCnt);
173     return -ENOSPC;
174   }
175   float bz=0.0;
176   float driftTimeFactorA=0.;
177   float driftTimeOffsetA=0.;
178   float driftTimeFactorC=0.;
179   float driftTimeOffsetC=0.;
180
181   AliHLTUInt32_t parameterIndex=0;
182   switch (trackModelBlock->fGlobalParameterCnt) {
183   case 5:
184     bz              =trackModelBlock->fGlobalParameters[parameterIndex++];
185     driftTimeFactorA=trackModelBlock->fGlobalParameters[parameterIndex++];
186     driftTimeOffsetA=trackModelBlock->fGlobalParameters[parameterIndex++];
187     driftTimeFactorC=trackModelBlock->fGlobalParameters[parameterIndex++];
188     driftTimeOffsetC=trackModelBlock->fGlobalParameters[parameterIndex++];
189     break;
190   default:
191     HLTError("unknown version of global parameters %d", trackModelBlock->fGlobalParameterCnt);
192     return -ENODATA;
193   }
194
195   if (parameterIndex!=trackModelBlock->fGlobalParameterCnt) {
196     HLTError("internal error, size of parameter array has changed without providing all values");
197     return -EFAULT;
198   }
199
200   for (int trackno=0; trackno<nofTracks; trackno++) {
201     AliHLTTPCTrackGeometry trackpoints;
202     trackpoints.InitDriftTimeTransformation(driftTimeFactorA, driftTimeOffsetA, driftTimeFactorC, driftTimeOffsetC);
203     AliHLTUInt32_t  clusterBlockSize=0;
204     if ((iResult=trackpoints.Read(pData+dataOffset, dataSize-dataOffset, bz, clusterBlockSize))<0) {
205       return iResult;
206     }
207     dataOffset+=iResult;
208     if (dataSize-dataOffset<(int)clusterBlockSize) {
209       HLTError("to little data in buffer to read cluster block of size %d for track no %d", clusterBlockSize, trackno);
210       return -ENODATA;
211     }
212     if ((iResult=pInflater->InitBitDataInput(pData+dataOffset, clusterBlockSize))<0) {
213       return iResult;
214     }
215     if ((iResult=ReadTrackClustersCompressed(c, pInflater.get(), &trackpoints))<0) {
216       HLTError("reading of associated clusters failed for track %d", trackno);
217       return iResult;
218     }
219     pInflater->Pad8Bits();
220     AliHLTUInt8_t bit=0;
221     if (pInflater->InputBit(bit)) {
222       HLTWarning("format error of compressed clusters, there is more data than expected");
223     }
224     pInflater->CloseBitDataInput();
225     dataOffset+=clusterBlockSize;
226   }
227
228   return iResult;
229 }
230
231 template<typename T>
232 int AliHLTTPCDataCompressionDecoder::ReadTrackClustersCompressed(T& c, AliHLTDataInflater* pInflater, AliHLTTPCTrackGeometry* pTrackPoints)
233 {
234   // read cluster data
235
236   int iResult=0;
237   if (!pInflater || !pTrackPoints) return -EINVAL;
238
239   const vector<AliHLTTrackGeometry::AliHLTTrackPoint>& rawTrackPoints=pTrackPoints->GetRawPoints();
240   vector<AliHLTTrackGeometry::AliHLTTrackPoint>::const_iterator currentTrackPoint=rawTrackPoints.begin();
241
242   bool bReadSuccess=true;
243   AliHLTUInt32_t clusterCountBitLength=AliHLTTPCDefinitions::fgkClusterParameterDefinitions[AliHLTTPCDefinitions::kClusterCount].fBitLength;
244   //unsigned long dataPosition=pInflater->GetCurrentByteInputPosition();
245   for (unsigned row=0; row<159 && bReadSuccess; row++) {
246     AliHLTUInt8_t haveClusters=0;
247     // 1 bit for clusters on that padrow
248     bReadSuccess=bReadSuccess && pInflater->InputBit(haveClusters);
249     if (!haveClusters) continue;
250     bool bEscape=false;
251     do {
252       if (currentTrackPoint==rawTrackPoints.end()) {
253         if (bEscape || rawTrackPoints.begin()==rawTrackPoints.end()) break;
254         currentTrackPoint=rawTrackPoints.begin();
255         bEscape=true;
256       }
257       if (AliHLTTPCTransform::GetFirstRow(AliHLTTPCSpacePointData::GetPatch(currentTrackPoint->GetId())) +
258           AliHLTTPCSpacePointData::GetNumber(currentTrackPoint->GetId()) == row) {
259         break;
260       }
261       currentTrackPoint++;
262     } while (!bEscape);
263     if (currentTrackPoint==rawTrackPoints.end()) {
264       HLTError("decoding error, can not find track point on row %d", row);
265       return -EFAULT;
266     }
267     AliHLTUInt8_t slice = AliHLTTPCDefinitions::GetMinSliceNr(currentTrackPoint->GetId());
268     AliHLTUInt8_t partition = AliHLTTPCDefinitions::GetMinPatchNr(currentTrackPoint->GetId());
269     AliHLTUInt8_t nofClusters=0;
270     bReadSuccess=bReadSuccess && pInflater->InputBits(nofClusters, clusterCountBitLength);
271     if (!bReadSuccess) break;
272
273     static const AliHLTTPCDefinitions::AliClusterParameterId_t kParameterIdMapping[] = {
274       AliHLTTPCDefinitions::kResidualPad,
275       AliHLTTPCDefinitions::kResidualTime,
276       AliHLTTPCDefinitions::kSigmaY2,
277       AliHLTTPCDefinitions::kSigmaZ2,
278       AliHLTTPCDefinitions::kCharge,
279       AliHLTTPCDefinitions::kQMax,
280     };
281
282     int parameterId=0;
283     int inClusterCnt=0;
284     AliHLTUInt64_t value=0;
285     AliHLTUInt32_t length=0;
286     bool bNextCluster=true;
287     while (bReadSuccess && inClusterCnt<nofClusters && pInflater->NextValue(value, length)) {
288       if (bNextCluster) {
289         // switch to next cluster
290         c.Next(slice, partition);
291         bNextCluster=false;
292       }
293       const AliHLTTPCDefinitions::AliClusterParameter& parameter
294         =AliHLTTPCDefinitions::fgkClusterParameterDefinitions[kParameterIdMapping[parameterId]];
295
296       if (parameter.fBitLength!=(int)length) {
297         HLTError("decode error: expecting length %d for parameter %s, but got %d",
298                  parameter.fBitLength, parameter.fName, length);
299         break;
300       }
301
302       static float deltapad=0.;
303       static float deltatime=0.;
304       bool lastParameter=false;
305       switch (kParameterIdMapping[parameterId]) {
306       case AliHLTTPCDefinitions::kResidualPad:
307         {
308           AliHLTUInt8_t sign=0;
309           bReadSuccess=bReadSuccess && pInflater->InputBit(sign);
310           float pad=value*(sign?-1.:1.); pad/=parameter.fScale;
311           deltapad=pad;
312           pad+=currentTrackPoint->GetU();
313           c.SetPad(pad); 
314           break;
315         }
316       case AliHLTTPCDefinitions::kResidualTime:
317         {
318           AliHLTUInt8_t sign=0;
319           bReadSuccess=bReadSuccess && pInflater->InputBit(sign);
320           float time=value*(sign?-1.:1.); time/=parameter.fScale;
321           deltatime=time;
322           time+=currentTrackPoint->GetV();
323           c.SetTime(time);
324           break;
325         }
326       case AliHLTTPCDefinitions::kSigmaY2:
327         {float sigmaY2=value; sigmaY2/=parameter.fScale; c.SetSigmaY2(sigmaY2); break;}
328       case AliHLTTPCDefinitions::kSigmaZ2:
329         {float sigmaZ2=value; sigmaZ2/=parameter.fScale; c.SetSigmaZ2(sigmaZ2); break;}
330       case AliHLTTPCDefinitions::kCharge:
331         {c.SetCharge(value); break;}
332       case AliHLTTPCDefinitions::kQMax:
333         {c.SetQMax(value); lastParameter=true; break;}
334       default:
335         {
336           HLTError("parameter %d not expected", kParameterIdMapping[parameterId]);
337         }
338       }
339       if (lastParameter) {
340         // switch to next cluster
341         c.SetPadRow(row);
342         // cout << "  row "    << setfill(' ') << setw(3) << fixed << right                     << c.GetRow()
343         //      << "  pad "    << setfill(' ') << setw(7) << fixed << right << setprecision (4) << c.GetPad()
344         //      << "  dpad "   << setfill(' ') << setw(7) << fixed << right << setprecision (4) << deltapad
345         //      << "  time "   << setfill(' ') << setw(7) << fixed << right << setprecision (4) << c.GetTimeBin()
346         //      << "  dtime "  << setfill(' ') << setw(7) << fixed << right << setprecision (4) << deltatime
347         //      << "  charge " << setfill(' ') << setw(5) << fixed << right << setprecision (0) << c.GetQ()
348         //      << "  qmax "   << setfill(' ') << setw(4) << fixed << right << setprecision (0) << c.GetMax()
349         //      << endl;
350         bNextCluster=true;
351         inClusterCnt++;
352         parameterId=-1;
353       }
354       parameterId++;
355     }
356     if (iResult>=0 && nofClusters!=inClusterCnt) {
357       // is this a Fatal?
358       HLTError("error reading track model compressed cluster format of track: expected %d, read only %d cluster(s)", nofClusters, inClusterCnt);
359       return -EPROTO;
360     }
361     currentTrackPoint++;
362   }
363   return iResult;
364 }
365 #endif