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