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