]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/TPCLib/comp/AliHLTTPCDataCompressionDecoder.h
returning the number of clusters extracted from the block and added an optional info...
[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, int formatVersion=0);
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   template<typename T>
48   int ReadClustersPartition(T& c, const AliHLTUInt8_t* pData, unsigned dataSize, AliHLTUInt32_t specification);
49
50   AliHLTDataInflater* CreateInflater(int deflater, int mode) const;
51
52   void SetVerbosity(int verbosity) {fVerbosity=verbosity;}
53  protected:
54  private:
55   int fVerbosity; //! verbosity level
56
57   ClassDef(AliHLTTPCDataCompressionDecoder, 0)
58 };
59
60 template<typename T>
61 int AliHLTTPCDataCompressionDecoder::ReadRemainingClustersCompressed(T& c, const AliHLTUInt8_t* pData, int dataSize, AliHLTUInt32_t specification)
62 {
63   // read cluster data from AliHLTTPCClusterData
64   int iResult=0;
65   if (!pData  || dataSize<4) return -EINVAL;
66
67   const AliHLTUInt8_t* pBuffer=pData;
68   AliHLTUInt32_t size=dataSize;
69   const AliHLTTPCRawClusterData* clusterData = reinterpret_cast<const AliHLTTPCRawClusterData*>(pBuffer);
70   Int_t nCount = (Int_t) clusterData->fCount;
71
72   int formatVersion=1;
73   int deflaterMode=2;
74   switch (clusterData->fVersion) {
75   case 1: deflaterMode=1; formatVersion=0; break;
76   case 2: deflaterMode=2; formatVersion=0; break;
77   case 3: deflaterMode=1; formatVersion=1; break;
78   case 4: deflaterMode=2; formatVersion=1; break;
79   default:
80     return -EBADF;
81   }
82   std::auto_ptr<AliHLTDataInflater> inflater(CreateInflater(deflaterMode, 1));
83   if (!inflater.get()) return -ENODEV;
84
85   if ((iResult=inflater->InitBitDataInput(reinterpret_cast<const AliHLTUInt8_t*>(clusterData->fClusters),
86                                           size-sizeof(AliHLTTPCRawClusterData)))<0) {
87     return iResult;
88   }
89
90   iResult=ReadRemainingClustersCompressed(c, inflater.get(), nCount, specification, formatVersion);
91
92   return iResult;
93 }
94
95 template<typename T>
96 int AliHLTTPCDataCompressionDecoder::ReadRemainingClustersCompressed(T& c, AliHLTDataInflater* pInflater, int nofClusters, AliHLTUInt32_t specification, int formatVersion)
97 {
98   // read cluster data
99
100   int iResult=0;
101   if (!pInflater) return -EINVAL;
102
103   AliHLTUInt8_t slice = AliHLTTPCDefinitions::GetMinSliceNr(specification);
104   AliHLTUInt8_t partition = AliHLTTPCDefinitions::GetMinPatchNr(specification);
105   // the compressed format stores the difference of the local row number in
106   // the partition to the row of the last cluster
107   // add the first row in the partition to get global row number
108   int rowOffset=AliHLTTPCTransform::GetFirstRow(partition);
109
110   int parameterId=pInflater->NextParameter();
111   if (parameterId<0) return parameterId;
112   int outClusterCnt=0;
113   AliHLTUInt64_t value=0;
114   AliHLTUInt32_t length=0;
115   AliHLTUInt32_t lastPadRow=0;
116   AliHLTUInt64_t lastPad64=0;
117   AliHLTUInt64_t lastTime64=0;
118   AliHLTUInt8_t isSinglePad=0;
119   AliHLTUInt8_t sign=0;
120   bool bNextCluster=true;
121   bool bReadSuccess=true;
122   while (outClusterCnt<nofClusters && bReadSuccess && pInflater->NextValue(value, length)) {
123     if (bNextCluster) {
124       // switch to next cluster
125       c.Next(slice, partition);
126       bNextCluster=false;
127     }
128     const AliHLTTPCDefinitions::AliClusterParameter& parameter
129       =AliHLTTPCDefinitions::fgkClusterParameterDefinitions[parameterId];
130
131     if (parameter.fBitLength!=(int)length) {
132       HLTError("decode error: expecting length %d for parameter %s, but got %d",
133                parameter.fBitLength, parameter.fName, length);
134       break;
135     }
136
137     switch (parameterId) {
138     case AliHLTTPCDefinitions::kPadRow:
139       {c.SetPadRow(value+lastPadRow+rowOffset); lastPadRow+=value;break;}
140     case AliHLTTPCDefinitions::kPad: {
141       if (formatVersion==1) {
142         bReadSuccess=bReadSuccess && pInflater->InputBit(isSinglePad);
143         if (isSinglePad==0) {
144           bReadSuccess=bReadSuccess && pInflater->InputBit(sign);
145           if (sign) {
146             value=lastPad64-value;
147           } else {
148             value+=lastPad64;
149           }
150           lastPad64=value;
151         }
152       }
153       float pad=value;
154       if (isSinglePad==0) pad/=parameter.fScale;
155       else pad/=2; // for the sake of the 0.5 pad offset (see AliHLTTPCHWCFSpacePointContainer::WriteSorted for details)
156       c.SetPad(pad);
157       break;
158     }
159     case AliHLTTPCDefinitions::kTime: {
160       if (formatVersion==1) {
161         bReadSuccess=bReadSuccess && pInflater->InputBit(sign);
162         if (sign) {
163           value=lastTime64-value;
164         } else {
165           value+=lastTime64;
166         }
167         lastTime64=value;
168       }
169       float time=value; time/=parameter.fScale;
170       c.SetTime(time);
171       break;
172     }
173     case AliHLTTPCDefinitions::kSigmaY2:
174       {float sigmaY2=value; sigmaY2/=parameter.fScale; c.SetSigmaY2(sigmaY2); break;}
175     case AliHLTTPCDefinitions::kSigmaZ2:
176       {float sigmaZ2=value; sigmaZ2/=parameter.fScale; c.SetSigmaZ2(sigmaZ2); break;}
177     case AliHLTTPCDefinitions::kCharge:
178       {c.SetCharge(value); break;}
179     case AliHLTTPCDefinitions::kQMax:
180       {c.SetQMax(value); break;}
181     }
182     if (parameterId>=AliHLTTPCDefinitions::kLast) {
183       bNextCluster=true;
184       outClusterCnt++;
185     }
186     parameterId=pInflater->NextParameter();
187     if (parameterId==AliHLTTPCDefinitions::kSigmaY2 && isSinglePad==1) {
188       // skip sigmaY for single pad clusters in format version 1
189       parameterId=pInflater->NextParameter();
190       isSinglePad=0;
191       c.SetSigmaY2(0.);
192     }
193   }
194   pInflater->Pad8Bits();
195   AliHLTUInt8_t bit=0;
196   if (pInflater->InputBit(bit)) {
197     HLTWarning("format error of compressed clusters, there is more data than expected");
198   }
199   pInflater->CloseBitDataInput();
200   if (iResult>=0 && nofClusters!=outClusterCnt) {
201     // is this a Fatal?
202     HLTError("error reading compressed cluster format of block 0x%08x: expected %d, read only %d cluster(s)", specification, nofClusters, outClusterCnt);
203     return -EPROTO;
204   }
205   if (iResult<0) return iResult;
206   return nofClusters;
207 }
208
209 template<typename T>
210 int AliHLTTPCDataCompressionDecoder::ReadTrackModelClustersCompressed(T& c, const AliHLTUInt8_t* pData, int dataSize, AliHLTUInt32_t /*specification*/)
211 {
212   // read cluster data from the track model data block
213   int iResult=0;
214   int dataOffset=sizeof(AliHLTTPCDataCompressionComponent::AliHLTTPCTrackModelBlock);
215   if (!pData  || dataSize<dataOffset) return -EINVAL;
216
217   const AliHLTTPCDataCompressionComponent::AliHLTTPCTrackModelBlock* trackModelBlock=reinterpret_cast<const AliHLTTPCDataCompressionComponent::AliHLTTPCTrackModelBlock*>(pData);
218   if (trackModelBlock->fVersion!=1) {
219     HLTError("unknown version %d", trackModelBlock->fVersion);
220     return -EINVAL;
221   }
222   std::auto_ptr<AliHLTDataInflater> pInflater(CreateInflater(trackModelBlock->fDeflaterMode, 2));
223   if (!pInflater.get()) {
224     HLTError("failed to create the data inflater for mode %d", trackModelBlock->fDeflaterMode);
225   }
226   int nofTracks=trackModelBlock->fTrackCount;
227   dataOffset+=trackModelBlock->fGlobalParameterCnt*sizeof(trackModelBlock->fGlobalParameters);
228   if (dataSize<dataOffset) {
229     HLTError("inconsistent data block, size %d, expecting at least %d to read AliHLTTPCTrackModelBlock with %d global parameters", dataSize, dataOffset, trackModelBlock->fGlobalParameterCnt);
230     return -ENOSPC;
231   }
232   float bz=0.0;
233   float driftTimeFactorA=0.;
234   float driftTimeOffsetA=0.;
235   float driftTimeFactorC=0.;
236   float driftTimeOffsetC=0.;
237
238   AliHLTUInt32_t parameterIndex=0;
239   switch (trackModelBlock->fGlobalParameterCnt) {
240   case 5:
241     bz              =trackModelBlock->fGlobalParameters[parameterIndex++];
242     driftTimeFactorA=trackModelBlock->fGlobalParameters[parameterIndex++];
243     driftTimeOffsetA=trackModelBlock->fGlobalParameters[parameterIndex++];
244     driftTimeFactorC=trackModelBlock->fGlobalParameters[parameterIndex++];
245     driftTimeOffsetC=trackModelBlock->fGlobalParameters[parameterIndex++];
246     break;
247   default:
248     HLTError("unknown version of global parameters %d", trackModelBlock->fGlobalParameterCnt);
249     return -ENODATA;
250   }
251
252   if (parameterIndex!=trackModelBlock->fGlobalParameterCnt) {
253     HLTError("internal error, size of parameter array has changed without providing all values");
254     return -EFAULT;
255   }
256
257   for (int trackno=0; trackno<nofTracks; trackno++) {
258     AliHLTTPCTrackGeometry trackpoints;
259     trackpoints.InitDriftTimeTransformation(driftTimeFactorA, driftTimeOffsetA, driftTimeFactorC, driftTimeOffsetC);
260     AliHLTUInt32_t  clusterBlockSize=0;
261     if ((iResult=trackpoints.Read(pData+dataOffset, dataSize-dataOffset, bz, clusterBlockSize))<0) {
262       return iResult;
263     }
264     dataOffset+=iResult;
265     if (dataSize-dataOffset<(int)clusterBlockSize) {
266       HLTError("to little data in buffer to read cluster block of size %d for track no %d", clusterBlockSize, trackno);
267       return -ENODATA;
268     }
269     if ((iResult=pInflater->InitBitDataInput(pData+dataOffset, clusterBlockSize))<0) {
270       return iResult;
271     }
272     if ((iResult=ReadTrackClustersCompressed(c, pInflater.get(), &trackpoints))<0) {
273       HLTError("reading of associated clusters failed for track %d", trackno);
274       return iResult;
275     }
276     pInflater->Pad8Bits();
277     AliHLTUInt8_t bit=0;
278     if (pInflater->InputBit(bit)) {
279       HLTWarning("format error of compressed clusters, there is more data than expected");
280     }
281     pInflater->CloseBitDataInput();
282     dataOffset+=clusterBlockSize;
283   }
284
285   return iResult;
286 }
287
288 template<typename T>
289 int AliHLTTPCDataCompressionDecoder::ReadTrackClustersCompressed(T& c, AliHLTDataInflater* pInflater, AliHLTTPCTrackGeometry* pTrackPoints)
290 {
291   // read cluster data
292
293   int iResult=0;
294   if (!pInflater || !pTrackPoints) return -EINVAL;
295
296   const vector<AliHLTTrackGeometry::AliHLTTrackPoint>& rawTrackPoints=pTrackPoints->GetRawPoints();
297   vector<AliHLTTrackGeometry::AliHLTTrackPoint>::const_iterator currentTrackPoint=rawTrackPoints.begin();
298
299   bool bReadSuccess=true;
300   AliHLTUInt32_t clusterCountBitLength=AliHLTTPCDefinitions::fgkClusterParameterDefinitions[AliHLTTPCDefinitions::kClusterCount].fBitLength;
301   //unsigned long dataPosition=pInflater->GetCurrentByteInputPosition();
302   for (unsigned row=0; row<159 && bReadSuccess; row++) {
303     AliHLTUInt8_t haveClusters=0;
304     // 1 bit for clusters on that padrow
305     bReadSuccess=bReadSuccess && pInflater->InputBit(haveClusters);
306     if (!haveClusters) continue;
307     bool bEscape=false;
308     do {
309       if (currentTrackPoint==rawTrackPoints.end()) {
310         if (bEscape || rawTrackPoints.begin()==rawTrackPoints.end()) break;
311         currentTrackPoint=rawTrackPoints.begin();
312         bEscape=true;
313       }
314       if (AliHLTTPCTransform::GetFirstRow(AliHLTTPCSpacePointData::GetPatch(currentTrackPoint->GetId())) +
315           AliHLTTPCSpacePointData::GetNumber(currentTrackPoint->GetId()) == row) {
316         break;
317       }
318       currentTrackPoint++;
319     } while (!bEscape);
320     if (currentTrackPoint==rawTrackPoints.end()) {
321       HLTError("decoding error, can not find track point on row %d", row);
322       return -EFAULT;
323     }
324     AliHLTUInt8_t slice = AliHLTTPCSpacePointData::GetSlice(currentTrackPoint->GetId());
325     AliHLTUInt8_t partition = AliHLTTPCSpacePointData::GetPatch(currentTrackPoint->GetId());
326     AliHLTUInt8_t nofClusters=0;
327     bReadSuccess=bReadSuccess && pInflater->InputBits(nofClusters, clusterCountBitLength);
328     if (!bReadSuccess) break;
329     HLTDebug("slice %02d partition %d row %03d: %d cluster(s)", slice, partition, row, nofClusters);
330
331     static const AliHLTTPCDefinitions::AliClusterParameterId_t kParameterIdMapping[] = {
332       AliHLTTPCDefinitions::kResidualPad,
333       AliHLTTPCDefinitions::kResidualTime,
334       AliHLTTPCDefinitions::kSigmaY2,
335       AliHLTTPCDefinitions::kSigmaZ2,
336       AliHLTTPCDefinitions::kCharge,
337       AliHLTTPCDefinitions::kQMax,
338     };
339
340     int parameterId=0;
341     int inClusterCnt=0;
342     AliHLTUInt64_t value=0;
343     AliHLTUInt32_t length=0;
344     bool bNextCluster=true;
345     while (bReadSuccess && inClusterCnt<nofClusters && pInflater->NextValue(value, length)) {
346       if (bNextCluster) {
347         // switch to next cluster
348         c.Next(slice, partition);
349         c.SetPadRow(row);
350         bNextCluster=false;
351       }
352       const AliHLTTPCDefinitions::AliClusterParameter& parameter
353         =AliHLTTPCDefinitions::fgkClusterParameterDefinitions[kParameterIdMapping[parameterId]];
354
355       if (parameter.fBitLength!=(int)length) {
356         HLTError("decode error: expecting length %d for parameter %s, but got %d",
357                  parameter.fBitLength, parameter.fName, length);
358         break;
359       }
360
361       static float deltapad=0.;
362       static float deltatime=0.;
363       bool lastParameter=false;
364       switch (kParameterIdMapping[parameterId]) {
365       case AliHLTTPCDefinitions::kResidualPad:
366         {
367           AliHLTUInt8_t sign=0;
368           bReadSuccess=bReadSuccess && pInflater->InputBit(sign);
369           deltapad=((float)value)*(sign?-1.:1.)/parameter.fScale;
370           AliHLTUInt64_t trackpad64=0;
371           double trackpad=currentTrackPoint->GetU();
372           trackpad*=AliHLTTPCDefinitions::fgkClusterParameterDefinitions[AliHLTTPCDefinitions::kResidualPad].fScale;
373           if (currentTrackPoint->GetU()>0.) trackpad64=(AliHLTUInt64_t)round(trackpad);
374           if (sign) {
375             value=trackpad64-value;
376           } else {
377             value+=trackpad64;
378           }
379           float pad=((float)value)/parameter.fScale;
380           c.SetPad(pad); 
381           break;
382         }
383       case AliHLTTPCDefinitions::kResidualTime:
384         {
385           AliHLTUInt8_t sign=0;
386           bReadSuccess=bReadSuccess && pInflater->InputBit(sign);
387           deltatime=((float)value)*(sign?-1.:1.)/parameter.fScale;
388           AliHLTUInt64_t tracktime64=0;
389           double tracktime=currentTrackPoint->GetV();
390           tracktime*=AliHLTTPCDefinitions::fgkClusterParameterDefinitions[AliHLTTPCDefinitions::kResidualTime].fScale;
391           if (currentTrackPoint->GetV()>0.) tracktime64=(AliHLTUInt64_t)round(tracktime);
392           if (sign) {
393             value=tracktime64-value;
394           } else {
395             value+=tracktime64;
396           }
397           float time=((float)value)/parameter.fScale;
398           c.SetTime(time); 
399           break;
400         }
401       case AliHLTTPCDefinitions::kSigmaY2:
402         {float sigmaY2=value; sigmaY2/=parameter.fScale; c.SetSigmaY2(sigmaY2); break;}
403       case AliHLTTPCDefinitions::kSigmaZ2:
404         {float sigmaZ2=value; sigmaZ2/=parameter.fScale; c.SetSigmaZ2(sigmaZ2); break;}
405       case AliHLTTPCDefinitions::kCharge:
406         {c.SetCharge(value); break;}
407       case AliHLTTPCDefinitions::kQMax:
408         {c.SetQMax(value); lastParameter=true; break;}
409       default:
410         {
411           HLTError("parameter %d not expected", kParameterIdMapping[parameterId]);
412         }
413       }
414       if (lastParameter) {
415         // switch to next cluster
416         // cout << "  row "    << setfill(' ') << setw(3) << fixed << right                     << c.GetRow()
417         //      << "  pad "    << setfill(' ') << setw(7) << fixed << right << setprecision (4) << c.GetPad()
418         //      << "  dpad "   << setfill(' ') << setw(7) << fixed << right << setprecision (4) << deltapad
419         //      << "  time "   << setfill(' ') << setw(7) << fixed << right << setprecision (4) << c.GetTimeBin()
420         //      << "  dtime "  << setfill(' ') << setw(7) << fixed << right << setprecision (4) << deltatime
421         //      << "  charge " << setfill(' ') << setw(5) << fixed << right << setprecision (0) << c.GetQ()
422         //      << "  qmax "   << setfill(' ') << setw(4) << fixed << right << setprecision (0) << c.GetMax()
423         //      << endl;
424         bNextCluster=true;
425         inClusterCnt++;
426         parameterId=-1;
427       }
428       parameterId++;
429     }
430     if (iResult>=0 && nofClusters!=inClusterCnt) {
431       // is this a Fatal?
432       HLTError("error reading track model compressed cluster format of track: expected %d, read only %d cluster(s)", nofClusters, inClusterCnt);
433       return -EPROTO;
434     }
435     currentTrackPoint++;
436   }
437   return iResult;
438 }
439
440 template<typename T>
441 int AliHLTTPCDataCompressionDecoder::ReadClustersPartition(T& c, const AliHLTUInt8_t* pData, unsigned dataSize, AliHLTUInt32_t specification)
442 {
443   // read raw cluster data
444   if (!pData) return -EINVAL;
445   if (dataSize<sizeof(AliHLTTPCRawClusterData)) return -ENODATA;
446   const AliHLTTPCRawClusterData* clusterData = reinterpret_cast<const AliHLTTPCRawClusterData*>(pData);
447   Int_t nCount = (Int_t) clusterData->fCount;
448   if (clusterData->fVersion!=0) {
449     int iResult=ReadRemainingClustersCompressed(c, pData, dataSize, specification);
450     if (iResult>=0 && fVerbosity>0) {
451       HLTInfo("extracted %d cluster(s) from block 0x%08x", iResult, specification);
452     }
453     return iResult;
454   }
455   if (nCount*sizeof(AliHLTTPCRawCluster) + sizeof(AliHLTTPCRawClusterData) != dataSize) return -EBADF;
456   AliHLTUInt8_t slice = AliHLTTPCDefinitions::GetMinSliceNr(specification);
457   AliHLTUInt8_t partition = AliHLTTPCDefinitions::GetMinPatchNr(specification);
458
459   const AliHLTTPCRawCluster *clusters = clusterData->fClusters;
460   for (int i=0; i<nCount; i++) {
461     c.Next(slice, partition);
462     c.SetPadRow(clusters[i].GetPadRow());
463     c.SetPad(clusters[i].GetPad());
464     c.SetTime(clusters[i].GetTime());
465     c.SetSigmaY2(clusters[i].GetSigmaY2());
466     c.SetSigmaZ2(clusters[i].GetSigmaZ2());
467     c.SetCharge(clusters[i].GetCharge());
468     c.SetQMax(clusters[i].GetQMax());
469   }
470   return nCount;
471 }
472 #endif