Coverity
[u/mrichter/AliRoot.git] / HLT / TPCLib / AliHLTTPCClusterAccessHLTOUT.cxx
CommitLineData
c54aa300 1// $Id$
2
3//**************************************************************************
4//* This file is property of and copyright by the ALICE HLT Project *
5//* ALICE Experiment at CERN, All rights reserved. *
6//* *
7//* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
8//* for The ALICE HLT Project. *
9//* *
10//* Permission to use, copy, modify and distribute this software and its *
11//* documentation strictly for non-commercial purposes is hereby granted *
12//* without fee, provided that the above copyright notice appears in all *
13//* copies and that both the copyright notice and this permission notice *
14//* appear in the supporting documentation. The authors make no claims *
15//* about the suitability of this software for any purpose. It is *
16//* provided "as is" without express or implied warranty. *
17//**************************************************************************
18
19/// @file AliHLTTPCClusterAccessHLTOUT.h
20/// @author Matthias Richter
21/// @date 2011-06-06
22/// @brief Interface to HLT TPC clusters
23///
24
25#include "AliHLTTPCClusterAccessHLTOUT.h"
26#include "AliHLTTPCDefinitions.h"
27#include "AliHLTTPCClusterDataFormat.h"
5e75f4e0 28#include "AliHLTTPCRawCluster.h"
61e66346 29#include "AliHLTTPCTransform.h"
c54aa300 30#include "AliHLTOUT.h"
81e7f739 31#include "AliHLTComponent.h"
73db5fa6 32#include "AliHLTErrorGuard.h"
61e66346 33#include "AliHLTDataInflater.h"
34#include "AliHLTTPCDefinitions.h"
c54aa300 35#include "AliLog.h"
36#include "AliHLTSystem.h"
37#include "AliHLTPluginBase.h"
38#include "AliTPCclusterMI.h"
39#include "TClonesArray.h"
81e7f739 40#include <cstdlib>
41#include <string>
42#include <memory>
c54aa300 43
44/** ROOT macro for the implementation of ROOT specific class methods */
45ClassImp(AliHLTTPCClusterAccessHLTOUT)
46
47AliHLTTPCClusterAccessHLTOUT::AliHLTTPCClusterAccessHLTOUT()
48 : TObject()
81e7f739 49 , fVerbosity(0)
c54aa300 50 , fClusters(NULL)
51{
52 // see header file for class documentation
53 // or
54 // refer to README to build package
55 // or
56 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
57}
58
59AliHLTTPCClusterAccessHLTOUT::~AliHLTTPCClusterAccessHLTOUT()
60{
61 // destructor
62 if (fClusters) {
63 fClusters->Clear();
64 delete fClusters;
65 fClusters=NULL;
66 }
67}
68
81e7f739 69void AliHLTTPCClusterAccessHLTOUT::Execute(const char *method, const char *params, Int_t *error)
c54aa300 70{
71 /// inherited from TObject: abstract command interface
72 if (strcmp(method, "read")==0) {
81e7f739 73 int iResult=ProcessClusters(params);
74 if (error) *error=iResult;
75 return;
76 }
77 if (strcmp(method, "verbosity")==0) {
78 int iResult=0;
79 if (params) {
80 char* dummy;
81 int value=strtol(params, &dummy, 0);
82 if (dummy==NULL) {
83 fVerbosity=value;
84 } else {
85 AliError("invalid argument for command 'verbosity', expecting string with number");
86 }
87 } else {
88 iResult=-EINVAL;
89 }
c54aa300 90 if (error) *error=iResult;
91 return;
92 }
93}
94
95TObject* AliHLTTPCClusterAccessHLTOUT::FindObject(const char *name) const
96{
97 /// inherited from TObject: return the cluster array if name id "clusterarray"
98 if (strcmp(name, "clusterarray")==0) return fClusters;
99 return TObject::FindObject(name);
100}
101
102void AliHLTTPCClusterAccessHLTOUT::Clear(Option_t * /*option*/)
103{
104 /// inherited from TObject: cleanup
105 if (fClusters) fClusters->Clear();
106}
107
108void AliHLTTPCClusterAccessHLTOUT::Print(Option_t */*option*/) const
109{
110 /// inherited from TObject
111 if (!fClusters) return;
112 for (int i=0; i<fClusters->GetEntriesFast(); i++) {
113 if (!fClusters->At(i)) continue;
114 AliTPCclusterMI* pCluster=dynamic_cast<AliTPCclusterMI*>(fClusters->At(i));
115 if (!pCluster) break;
116 cout << "AliTPCclusterMI:"
117 << " row=" << pCluster->GetRow()
118 << " pad=" << pCluster->GetPad()
119 << " time=" << pCluster->GetTimeBin()
120 << " charge=" << pCluster->GetQ()
121 << " maxq=" << pCluster->GetMax()
122 << endl;
123 }
124}
125
81e7f739 126int AliHLTTPCClusterAccessHLTOUT::ProcessClusters(const char* params)
c54aa300 127{
128 /// process the cluster data from HLTOUT and fill array
129 /// the cluster data can be in many different formats, e.g.
130 /// raw or compressed
131 int iResult=0;
81e7f739 132 TString strparams(params);
133 int minSlice=0, maxSlice=35, minPart=0, maxPart=5;
134 std::auto_ptr<TObjArray> tokens(strparams.Tokenize(" "));
135 if (!tokens.get()) return -ENOMEM;
136 for (int i=0; i< tokens->GetEntriesFast(); i++) {
137 if (!tokens->At(i)) continue;
138 TString argument=tokens->At(i)->GetName();
139 if (argument.BeginsWith("sector=")) {
140 argument.ReplaceAll("sector=", "");
141 int sector=argument.Atoi();
142 // the offline code enumerates first the 36 inner (partitions 0+1) and then 36 outer
143 // sectors (partitions 2-5)
144 if (fVerbosity>0) AliInfo(Form("processing HLT clusters for sector %d", sector));
145 if (sector<36) { // inner sectors
146 minSlice=maxSlice=sector;
147 minPart=0; maxPart=1;
148 } else { // outer sectors
149 minSlice=maxSlice=sector-36;
150 minPart=2; maxPart=5;
151 }
152 }
153 }
154
c54aa300 155 if (!fClusters) {
156 fClusters=new TClonesArray("AliTPCclusterMI");
157 }
158 if (!fClusters) return -ENOMEM;
159
160 AliHLTSystem* pSystem=AliHLTPluginBase::GetInstance();
161 if (!pSystem) {
162 AliError("can not access HLT system");
163 return -ENODEV;
164 }
165 AliHLTOUT* pHLTOUT=pSystem->RequestHLTOUT();
166 if (!pHLTOUT) {
167 AliError("can not access HLTOUT");
168 return -ENODEV;
169 }
170
81e7f739 171 for (int slice=minSlice; slice<=maxSlice; slice++) {
172 for (int part=minPart; part<=maxPart; part++) {
173 if (fVerbosity>0) AliInfo(Form("processing HLT clusters for slice %d partitions %d", slice, part));
174 AliHLTUInt32_t spec=slice<<24 | slice<<16 | part<<8 | part;
175 AliHLTTPCClusterMCDataList tpcClusterLabels;
1214ab89 176 bool bHaveLabels=false;
81e7f739 177 if (pHLTOUT->SelectFirstDataBlock(AliHLTTPCDefinitions::fgkAliHLTDataTypeClusterMCInfo, spec)>=0) {
178 iResult=ReadAliHLTTPCClusterMCData(pHLTOUT, tpcClusterLabels);
1214ab89 179 bHaveLabels=true;
81e7f739 180 }
181
5e75f4e0 182 if (pHLTOUT->SelectFirstDataBlock(AliHLTTPCDefinitions::fgkRawClustersDataType, spec)>=0) {
1214ab89 183 iResult=ReadAliHLTTPCRawClusterData(pHLTOUT, fClusters, bHaveLabels?&tpcClusterLabels:NULL);
5e75f4e0 184 } else if (pHLTOUT->SelectFirstDataBlock(AliHLTTPCDefinitions::fgkClustersDataType, spec)>=0) {
73db5fa6 185 ALIHLTERRORGUARD(1, "HLTOUT data contains tarnsformed TPC clusters instead of raw TPC clusters, can not create clusters for reconstruction");
81e7f739 186 }
187 }
c54aa300 188 }
189
190 pSystem->ReleaseHLTOUT(pHLTOUT);
191 return iResult;
192}
193
81e7f739 194int AliHLTTPCClusterAccessHLTOUT::ReadAliHLTTPCClusterMCData(AliHLTOUT* pHLTOUT, AliHLTTPCClusterMCDataList &tpcClusterLabels) const
195{
196 // read cluster data from AliHLTTPCClusterData
197 int iResult=0;
198 if (!pHLTOUT) return -EINVAL;
199 do {
200 const AliHLTUInt8_t* pBuffer=NULL;
201 AliHLTUInt32_t size=0;
202 if ((iResult=pHLTOUT->GetDataBuffer(pBuffer, size))<0) {
203 continue;
204 }
205 if (pBuffer==NULL || size<4) {
206 AliError("invalid cluster mc data block");
207 continue;
208 }
209 const AliHLTTPCClusterMCData* clusterMCData = reinterpret_cast<const AliHLTTPCClusterMCData*>(pBuffer);
210 Int_t nLabels = (Int_t) clusterMCData->fCount;
211 if (nLabels*sizeof(AliHLTTPCClusterMCLabel) + sizeof(AliHLTTPCClusterMCData) != size) {
212 AliError("inconsistent cluster mc data block size, skipping block");
213 continue;
214 }
215 // id of the cluster is
216 AliHLTComponentDataType dt=kAliHLTVoidDataType;
217 AliHLTUInt32_t specification=kAliHLTVoidDataSpec;
218 if (pHLTOUT->GetDataBlockDescription(dt, specification)<0) {
219 AliError("failed to retrieve data block description, skipping mc cluster data block ...");
220 continue;
221 }
222 AliHLTUInt8_t slice = AliHLTTPCDefinitions::GetMinSliceNr(specification);
223 AliHLTUInt8_t partition = AliHLTTPCDefinitions::GetMinPatchNr(specification);
224 if (slice!=AliHLTTPCDefinitions::GetMaxSliceNr(specification) ||
225 partition!=AliHLTTPCDefinitions::GetMaxPatchNr(specification)) {
226 AliError(Form("can not read cluster mc data block with data of multiple partitions, skipping block %s %08x",
227 AliHLTComponent::DataType2Text(dt).c_str(), specification));
228 continue;
229 }
230 const AliHLTTPCClusterMCLabel *labels = clusterMCData->fLabels;
231 for (int i=0; i<nLabels; i++) {
232 AliHLTUInt32_t id=AliHLTTPCSpacePointData::GetID(slice, partition, i);
233 if (tpcClusterLabels.find(id)==tpcClusterLabels.end()) {
234 // new cluster
235 tpcClusterLabels[id]=labels[i];
236 } else {
237 AliError(Form("cluster with ID 0x%08x already existing, skipping cluster %d of data block 0x%08x",
238 id, i, specification));
239 }
240 }
241 } while (pHLTOUT->SelectNextDataBlock()>=0);
242 return iResult;
243}
244
245int AliHLTTPCClusterAccessHLTOUT::ReadAliHLTTPCClusterData(AliHLTOUT* pHLTOUT, TClonesArray* pClusters, const AliHLTTPCClusterMCDataList *tpcClusterLabels) const
c54aa300 246{
247 // read cluster data from AliHLTTPCClusterData
248 int iResult=0;
249 if (!pHLTOUT || !pClusters) return -EINVAL;
250 do {
251 const AliHLTUInt8_t* pBuffer=NULL;
252 AliHLTUInt32_t size=0;
253 if ((iResult=pHLTOUT->GetDataBuffer(pBuffer, size))<0) {
254 continue;
255 }
256 if (pBuffer==NULL || size<4) {
257 AliError("invalid cluster data block");
258 continue;
259 }
81e7f739 260 AliHLTComponentDataType dt=kAliHLTVoidDataType;
261 AliHLTUInt32_t specification=kAliHLTVoidDataSpec;
262 if (pHLTOUT->GetDataBlockDescription(dt, specification)<0) {
263 AliError("failed to retrieve data block description, skipping mc cluster data block ...");
264 continue;
265 }
c54aa300 266 const AliHLTTPCClusterData* clusterData = reinterpret_cast<const AliHLTTPCClusterData*>(pBuffer);
267 Int_t nSpacepoints = (Int_t) clusterData->fSpacePointCnt;
268 if (nSpacepoints*sizeof(AliHLTTPCSpacePointData) + sizeof(AliHLTTPCClusterData) != size) {
269 AliError("inconsistent cluster data block size, skipping block");
270 continue;
271 }
272 const AliHLTTPCSpacePointData *clusters = clusterData->fSpacePoints;
81e7f739 273 int offset=pClusters->GetEntries();
274 pClusters->ExpandCreate(offset+nSpacepoints);
0e63cf4a 275 AliHLTUInt8_t slice = AliHLTTPCDefinitions::GetMinSliceNr(specification);
276 AliHLTUInt8_t partition = AliHLTTPCDefinitions::GetMinPatchNr(specification);
277 // FIXME: get first row number of outer sectors from a common definition instead using number
80874dc5 278 unsigned rowOffset=partition<2?0:63;
c54aa300 279 for (int i=0; i<nSpacepoints; i++) {
81e7f739 280 if (!pClusters->At(offset+i)) continue;
281 AliTPCclusterMI* pCluster=dynamic_cast<AliTPCclusterMI*>(pClusters->At(offset+i));
c54aa300 282 if (!pCluster) {
283 AliError("invalid object type, expecting AliTPCclusterMI");
284 break; // this is a problem of all objects
285 }
0e63cf4a 286 if (clusters[i].fPadRow<rowOffset) {
287 AliError(Form("invalid row number %d, expecting minimum row number %d for slice %d partition %d", clusters[i].fPadRow, rowOffset, slice, partition));
288 } else {
289 pCluster->SetRow(clusters[i].fPadRow-rowOffset);
290 }
81e7f739 291 pCluster->SetPad(clusters[i].fY);
5e75f4e0 292 pCluster->SetTimeBin(clusters[i].fZ);
81e7f739 293 pCluster->SetSigmaY2(clusters[i].fSigmaY2);
294 pCluster->SetSigmaZ2(clusters[i].fSigmaZ2);
c54aa300 295 pCluster->SetQ(clusters[i].fCharge);
296 pCluster->SetMax(clusters[i].fQMax);
81e7f739 297 if (tpcClusterLabels) {
298 if (tpcClusterLabels->find(clusters[i].fID)!=tpcClusterLabels->end()) {
299 const AliHLTTPCClusterMCWeight* mcWeights=tpcClusterLabels->find(clusters[i].fID)->second.fClusterID;
300 for (int k=0; k<3; k++) {
301 // TODO: sort the labels according to the weight in order to assign the most likely mc label
302 // to the first component
303 pCluster->SetLabel(mcWeights[k].fMCID, k);
304 }
305 } else {
306 AliError(Form("can not find mc label of cluster with id %0x08x", clusters[i].fID));
307 }
308 }
c54aa300 309 }
1214ab89 310 if (fVerbosity>0) AliInfo(Form("converted %d cluster(s) from block %s 0x%08x", nSpacepoints, AliHLTComponent::DataType2Text(dt).c_str(), specification));
c54aa300 311 } while (pHLTOUT->SelectNextDataBlock()>=0);
312 return iResult;
313}
5e75f4e0 314
315int AliHLTTPCClusterAccessHLTOUT::ReadAliHLTTPCRawClusterData(AliHLTOUT* pHLTOUT, TClonesArray* pClusters, const AliHLTTPCClusterMCDataList *tpcClusterLabels)
316{
317 // read cluster data from AliHLTTPCClusterData
318
319 // FIXME: this is in large parts like ReadAliHLTTPCClusterData,
320 // make a common method
321 int iResult=0;
322 if (!pHLTOUT || !pClusters) return -EINVAL;
323 do {
324 const AliHLTUInt8_t* pBuffer=NULL;
325 AliHLTUInt32_t size=0;
326 if ((iResult=pHLTOUT->GetDataBuffer(pBuffer, size))<0) {
327 continue;
328 }
329 if (pBuffer==NULL || size<4) {
330 AliError("invalid cluster data block");
331 continue;
332 }
333 AliHLTComponentDataType dt=kAliHLTVoidDataType;
334 AliHLTUInt32_t specification=kAliHLTVoidDataSpec;
335 if (pHLTOUT->GetDataBlockDescription(dt, specification)<0) {
336 AliError("failed to retrieve data block description, skipping mc cluster data block ...");
337 continue;
338 }
339 const AliHLTTPCRawClusterData* clusterData = reinterpret_cast<const AliHLTTPCRawClusterData*>(pBuffer);
340 Int_t nCount = (Int_t) clusterData->fCount;
61e66346 341 if (clusterData->fVersion!=0) {
342 // this is encoded data of different formats
343 switch (clusterData->fVersion) {
344 case 1:
345 iResult=ReadAliHLTTPCRawClusterDataDeflateSimple(reinterpret_cast<const AliHLTUInt8_t*>(clusterData->fClusters),
346 size-sizeof(AliHLTTPCRawClusterData), nCount, specification,
347 pClusters, tpcClusterLabels);
348 break;
349 default:
350 iResult=-EPROTO;
351 }
352 return iResult;
353 }
354
5e75f4e0 355 if (nCount*sizeof(AliHLTTPCRawCluster) + sizeof(AliHLTTPCRawClusterData) != size) {
356 AliError("inconsistent cluster data block size, skipping block");
357 continue;
358 }
359 const AliHLTTPCRawCluster *clusters = clusterData->fClusters;
360 int offset=pClusters->GetEntries();
361 pClusters->ExpandCreate(offset+nCount);
0e63cf4a 362 AliHLTUInt8_t slice = AliHLTTPCDefinitions::GetMinSliceNr(specification);
363 AliHLTUInt8_t partition = AliHLTTPCDefinitions::GetMinPatchNr(specification);
364 // FIXME: get first row number of outer sectors from a common definition instead using number
80874dc5 365 int rowOffset=partition<2?0:63;
5e75f4e0 366 for (int i=0; i<nCount; i++) {
367 if (!pClusters->At(offset+i)) continue;
368 AliTPCclusterMI* pCluster=dynamic_cast<AliTPCclusterMI*>(pClusters->At(offset+i));
369 if (!pCluster) {
370 AliError("invalid object type, expecting AliTPCclusterMI");
371 break; // this is a problem of all objects
372 }
1214ab89 373 if (fVerbosity>1) AliInfo(Form("cluster padrow %d (slice %d partition %d)", clusters[i].GetPadRow(), slice, partition));
0e63cf4a 374 if (clusters[i].GetPadRow()<rowOffset) {
375 AliError(Form("invalid row number %d, expecting minimum row number %d for slice %d partition %d", clusters[i].GetPadRow(), rowOffset, slice, partition));
376 } else {
377 pCluster->SetRow(clusters[i].GetPadRow()-rowOffset);
378 }
73db5fa6 379 // using a 0.5 shift, pad coordinate with respect to middle of the pad
380 pCluster->SetPad(clusters[i].GetPad()+0.5);
5e75f4e0 381 pCluster->SetTimeBin(clusters[i].GetTime());
382 pCluster->SetSigmaY2(clusters[i].GetSigmaY2());
383 pCluster->SetSigmaZ2(clusters[i].GetSigmaZ2());
384 pCluster->SetQ(clusters[i].GetCharge());
385 pCluster->SetMax(clusters[i].GetQMax());
386 if (tpcClusterLabels) {
5e75f4e0 387 UInt_t clusterID=AliHLTTPCSpacePointData::GetID(slice, partition, i);
388 if (tpcClusterLabels->find(clusterID)!=tpcClusterLabels->end()) {
389 const AliHLTTPCClusterMCWeight* mcWeights=tpcClusterLabels->find(clusterID)->second.fClusterID;
390 for (int k=0; k<3; k++) {
391 // TODO: sort the labels according to the weight in order to assign the most likely mc label
392 // to the first component
393 pCluster->SetLabel(mcWeights[k].fMCID, k);
394 }
395 } else {
396 AliError(Form("can not find mc label of cluster with id %0x08x", clusterID));
397 }
398 }
399 }
400 if (fVerbosity>0) AliInfo(Form("converted %d cluster(s) from block %s 0x%08x", nCount, AliHLTComponent::DataType2Text(dt).c_str(), specification));
401 } while (pHLTOUT->SelectNextDataBlock()>=0);
402 return iResult;
403}
61e66346 404
405int AliHLTTPCClusterAccessHLTOUT::ReadAliHLTTPCRawClusterDataDeflateSimple(const AliHLTUInt8_t* pData, int dataSize,
406 int nofClusters, AliHLTUInt32_t specification,
407 TClonesArray* pClusters,
408 const AliHLTTPCClusterMCDataList *tpcClusterLabels)
409{
410 // read cluster data from AliHLTTPCClusterData
411
412 // FIXME: quick implementation to read the compressed cluster data from HLTOUT
413 // the data definition below is the same as in AliHLTTPCDataCompressionComponent
414 // but needs to be moved to a common class (AliHLTTPCDefinitions?)
415 // Think about a decoder class supporting iterator objects for various types
416 // of cluster data
417 int iResult=0;
418 if (!pData || !pClusters) return -EINVAL;
419 AliHLTDataInflater inflater;
420 if ((iResult=inflater.InitBitDataInput(pData, dataSize))<0) {
421 return iResult;
422 }
423
424 int offset=pClusters->GetEntries();
425 pClusters->ExpandCreate(offset+nofClusters);
426 AliHLTUInt8_t slice = AliHLTTPCDefinitions::GetMinSliceNr(specification);
427 AliHLTUInt8_t partition = AliHLTTPCDefinitions::GetMinPatchNr(specification);
428 // the compressed format stores the difference of the local row number in
429 // the partition to the row of the last cluster
430 // add the first row in the partition to get global row number
431 // offline uses row number in physical sector, inner sector consists of
432 // partitions 0 and 1, outer sector of partition 2-5
433 int rowOffset=AliHLTTPCTransform::GetFirstRow(partition)-(partition<2?0:AliHLTTPCTransform::GetFirstRow(2));
434
435 int parameterId=0;
436 int outClusterCnt=0;
437 AliHLTUInt8_t switchBit=0;
438 AliHLTUInt64_t value=0;
439 AliTPCclusterMI* pCluster=NULL;
440 AliHLTUInt32_t lastPadRow=0;
441 while (outClusterCnt<nofClusters && inflater.InputBit(switchBit)) {
442 const AliHLTTPCDefinitions::AliClusterParameter& parameter
443 =AliHLTTPCDefinitions::fgkClusterParameterDefinitions[parameterId];
444 // in mode DeflaterSimple, the optional parameter of the cluster parameter definition
445 // corresponds to the number bits of the reduced format
446 if (!inflater.InputBits(value, switchBit?parameter.fBitLength:parameter.fOptional)) {
447 break;
448 }
449
450 if (!pCluster) {
451 if (!pClusters->At(offset+outClusterCnt)) {
452 // here we should not get anymore because of the condition outClusterCnt<nofClusters
453 return -ENOSPC;
454 }
455 pCluster=dynamic_cast<AliTPCclusterMI*>(pClusters->At(offset+outClusterCnt));
456 if (!pCluster) {
457 AliError("invalid object type, expecting AliTPCclusterMI");
458 iResult=-EBADF; // this is a problem of all objects
459 break;
460 }
461 }
462 switch (parameterId) {
463 case AliHLTTPCDefinitions::kPadRow:
464 {pCluster->SetRow(value+lastPadRow+rowOffset); lastPadRow+=value;break;}
465 case AliHLTTPCDefinitions::kPad:
466 {float pad=value; pad/=parameter.fScale; pCluster->SetPad(pad); break;}
467 case AliHLTTPCDefinitions::kTime:
468 {float time=value; time/=parameter.fScale; pCluster->SetTimeBin(time); break;}
469 case AliHLTTPCDefinitions::kSigmaY2:
470 {float sigmaY2=value; sigmaY2/=parameter.fScale; pCluster->SetSigmaY2(sigmaY2); break;}
471 case AliHLTTPCDefinitions::kSigmaZ2:
472 {float sigmaZ2=value; sigmaZ2/=parameter.fScale; pCluster->SetSigmaZ2(sigmaZ2); break;}
473 case AliHLTTPCDefinitions::kCharge:
474 {pCluster->SetQ(value); break;}
475 case AliHLTTPCDefinitions::kQMax:
476 {pCluster->SetMax(value); break;}
477 }
478 if (parameterId>=AliHLTTPCDefinitions::kLast) {
479 // switch to next cluster
480 if (tpcClusterLabels) {
481 UInt_t clusterID=AliHLTTPCSpacePointData::GetID(slice, partition, outClusterCnt);
482 if (tpcClusterLabels->find(clusterID)!=tpcClusterLabels->end()) {
483 const AliHLTTPCClusterMCWeight* mcWeights=tpcClusterLabels->find(clusterID)->second.fClusterID;
484 for (int k=0; k<3; k++) {
485 // TODO: sort the labels according to the weight in order to assign the most likely mc label
486 // to the first component
487 pCluster->SetLabel(mcWeights[k].fMCID, k);
488 }
489 } else {
490 AliError(Form("can not find mc label of cluster with id %0x08x", clusterID));
491 }
492 }
493 outClusterCnt++;
494 pCluster=NULL;
495 parameterId=-1;
496 }
497 parameterId++;
498 }
499 inflater.Pad8Bits();
500 if (inflater.InputBit(switchBit)) {
501 AliWarning("format error of compressed clusters, there is more data than expected");
502 }
503 inflater.CloseBitDataInput();
504 if (iResult>=0 && nofClusters!=outClusterCnt) {
505 // is this a Fatal?
506 AliError(Form("error reading compressed cluster format: expected %d, read only %d cluster(s)", nofClusters, outClusterCnt));
507 return -EPROTO;
508 }
509 return iResult;
510}