]> git.uio.no Git - u/mrichter/AliRoot.git/blame - 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
CommitLineData
f899e060 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 */
30class 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>
8a3426fd 39 int ReadRemainingClustersCompressed(T& c, AliHLTDataInflater* pInflater, int nofClusters, AliHLTUInt32_t specification, int formatVersion=0);
f899e060 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
a4fad4be 47 template<typename T>
48 int ReadClustersPartition(T& c, const AliHLTUInt8_t* pData, unsigned dataSize, AliHLTUInt32_t specification);
49
f899e060 50 AliHLTDataInflater* CreateInflater(int deflater, int mode) const;
51
f2cfbdd1 52 void SetVerbosity(int verbosity) {fVerbosity=verbosity;}
f899e060 53 protected:
54 private:
f2cfbdd1 55 int fVerbosity; //! verbosity level
56
f899e060 57 ClassDef(AliHLTTPCDataCompressionDecoder, 0)
58};
59
60template<typename T>
61int 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
8a3426fd 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 }
6dc3748f 82 std::auto_ptr<AliHLTDataInflater> inflater(CreateInflater(deflaterMode, 1));
83 if (!inflater.get()) return -ENODEV;
f899e060 84
85 if ((iResult=inflater->InitBitDataInput(reinterpret_cast<const AliHLTUInt8_t*>(clusterData->fClusters),
86 size-sizeof(AliHLTTPCRawClusterData)))<0) {
87 return iResult;
88 }
89
6dc3748f 90 iResult=ReadRemainingClustersCompressed(c, inflater.get(), nCount, specification, formatVersion);
f899e060 91
92 return iResult;
93}
94
95template<typename T>
8a3426fd 96int AliHLTTPCDataCompressionDecoder::ReadRemainingClustersCompressed(T& c, AliHLTDataInflater* pInflater, int nofClusters, AliHLTUInt32_t specification, int formatVersion)
f899e060 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
bf1a9c81 108 int rowOffset=AliHLTTPCTransform::GetFirstRow(partition);
f899e060 109
8a3426fd 110 int parameterId=pInflater->NextParameter();
111 if (parameterId<0) return parameterId;
f899e060 112 int outClusterCnt=0;
113 AliHLTUInt64_t value=0;
114 AliHLTUInt32_t length=0;
115 AliHLTUInt32_t lastPadRow=0;
8a3426fd 116 AliHLTUInt64_t lastPad64=0;
117 AliHLTUInt64_t lastTime64=0;
118 AliHLTUInt8_t isSinglePad=0;
119 AliHLTUInt8_t sign=0;
bf1a9c81 120 bool bNextCluster=true;
8a3426fd 121 bool bReadSuccess=true;
122 while (outClusterCnt<nofClusters && bReadSuccess && pInflater->NextValue(value, length)) {
bf1a9c81 123 if (bNextCluster) {
124 // switch to next cluster
125 c.Next(slice, partition);
126 bNextCluster=false;
127 }
f899e060 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;}
8a3426fd 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 }
f899e060 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) {
bf1a9c81 183 bNextCluster=true;
f899e060 184 outClusterCnt++;
f899e060 185 }
8a3426fd 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 }
f899e060 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 }
f2cfbdd1 205 if (iResult<0) return iResult;
206 return nofClusters;
f899e060 207}
208
209template<typename T>
210int 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
288template<typename T>
289int 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 }
88c75640 324 AliHLTUInt8_t slice = AliHLTTPCSpacePointData::GetSlice(currentTrackPoint->GetId());
325 AliHLTUInt8_t partition = AliHLTTPCSpacePointData::GetPatch(currentTrackPoint->GetId());
f899e060 326 AliHLTUInt8_t nofClusters=0;
327 bReadSuccess=bReadSuccess && pInflater->InputBits(nofClusters, clusterCountBitLength);
328 if (!bReadSuccess) break;
88c75640 329 HLTDebug("slice %02d partition %d row %03d: %d cluster(s)", slice, partition, row, nofClusters);
f899e060 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;
bf1a9c81 344 bool bNextCluster=true;
f899e060 345 while (bReadSuccess && inClusterCnt<nofClusters && pInflater->NextValue(value, length)) {
bf1a9c81 346 if (bNextCluster) {
347 // switch to next cluster
348 c.Next(slice, partition);
8a3426fd 349 c.SetPadRow(row);
bf1a9c81 350 bNextCluster=false;
351 }
f899e060 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);
8a3426fd 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;
f899e060 380 c.SetPad(pad);
381 break;
382 }
383 case AliHLTTPCDefinitions::kResidualTime:
384 {
385 AliHLTUInt8_t sign=0;
386 bReadSuccess=bReadSuccess && pInflater->InputBit(sign);
8a3426fd 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);
f899e060 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
f899e060 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;
bf1a9c81 424 bNextCluster=true;
f899e060 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}
a4fad4be 439
440template<typename T>
441int 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) {
f2cfbdd1 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;
a4fad4be 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 }
f2cfbdd1 470 return nCount;
a4fad4be 471}
f899e060 472#endif