returning the number of clusters extracted from the block and added an optional info...
[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"
b60d3f6a 26#include "AliHLTTPCDataCompressionDecoder.h"
c54aa300 27#include "AliHLTTPCDefinitions.h"
28#include "AliHLTTPCClusterDataFormat.h"
5e75f4e0 29#include "AliHLTTPCRawCluster.h"
61e66346 30#include "AliHLTTPCTransform.h"
c54aa300 31#include "AliHLTOUT.h"
81e7f739 32#include "AliHLTComponent.h"
73db5fa6 33#include "AliHLTErrorGuard.h"
61e66346 34#include "AliHLTDataInflater.h"
35#include "AliHLTTPCDefinitions.h"
c54aa300 36#include "AliLog.h"
37#include "AliHLTSystem.h"
38#include "AliHLTPluginBase.h"
39#include "AliTPCclusterMI.h"
40#include "TClonesArray.h"
81e7f739 41#include <cstdlib>
42#include <string>
43#include <memory>
b60d3f6a 44#include <iostream>
45#include <iomanip>
c54aa300 46
47/** ROOT macro for the implementation of ROOT specific class methods */
48ClassImp(AliHLTTPCClusterAccessHLTOUT)
49
50AliHLTTPCClusterAccessHLTOUT::AliHLTTPCClusterAccessHLTOUT()
51 : TObject()
81e7f739 52 , fVerbosity(0)
c54aa300 53 , fClusters(NULL)
b60d3f6a 54 , fCurrentSector(-1)
c54aa300 55{
56 // see header file for class documentation
57 // or
58 // refer to README to build package
59 // or
60 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
61}
62
63AliHLTTPCClusterAccessHLTOUT::~AliHLTTPCClusterAccessHLTOUT()
64{
65 // destructor
66 if (fClusters) {
67 fClusters->Clear();
68 delete fClusters;
69 fClusters=NULL;
70 }
71}
72
81e7f739 73void AliHLTTPCClusterAccessHLTOUT::Execute(const char *method, const char *params, Int_t *error)
c54aa300 74{
75 /// inherited from TObject: abstract command interface
76 if (strcmp(method, "read")==0) {
81e7f739 77 int iResult=ProcessClusters(params);
78 if (error) *error=iResult;
79 return;
80 }
81 if (strcmp(method, "verbosity")==0) {
82 int iResult=0;
83 if (params) {
84 char* dummy;
85 int value=strtol(params, &dummy, 0);
86 if (dummy==NULL) {
87 fVerbosity=value;
88 } else {
89 AliError("invalid argument for command 'verbosity', expecting string with number");
90 }
91 } else {
92 iResult=-EINVAL;
93 }
c54aa300 94 if (error) *error=iResult;
95 return;
96 }
97}
98
99TObject* AliHLTTPCClusterAccessHLTOUT::FindObject(const char *name) const
100{
101 /// inherited from TObject: return the cluster array if name id "clusterarray"
b60d3f6a 102 if (strcmp(name, "clusterarray")==0) {
103 if (fCurrentSector<0) return NULL;
104 return fClusters->GetSectorArray(fCurrentSector);
105 }
c54aa300 106 return TObject::FindObject(name);
107}
108
b60d3f6a 109void AliHLTTPCClusterAccessHLTOUT::Clear(Option_t * option)
c54aa300 110{
111 /// inherited from TObject: cleanup
b60d3f6a 112 if (strcmp(option, "event")==0) {
113 if (fClusters) fClusters->Clear();
114 fCurrentSector=-1;
115 }
c54aa300 116}
117
b60d3f6a 118void AliHLTTPCClusterAccessHLTOUT::Print(Option_t *option) const
c54aa300 119{
120 /// inherited from TObject
b60d3f6a 121 if (fClusters) fClusters->Print(option);
c54aa300 122}
123
81e7f739 124int AliHLTTPCClusterAccessHLTOUT::ProcessClusters(const char* params)
c54aa300 125{
126 /// process the cluster data from HLTOUT and fill array
127 /// the cluster data can be in many different formats, e.g.
128 /// raw or compressed
129 int iResult=0;
81e7f739 130 TString strparams(params);
b60d3f6a 131 int sector=-1;
81e7f739 132 std::auto_ptr<TObjArray> tokens(strparams.Tokenize(" "));
133 if (!tokens.get()) return -ENOMEM;
134 for (int i=0; i< tokens->GetEntriesFast(); i++) {
135 if (!tokens->At(i)) continue;
136 TString argument=tokens->At(i)->GetName();
b60d3f6a 137 // the offline code enumerates first the 36 inner (partitions 0+1) and then 36 outer
138 // sectors (partitions 2-5)
81e7f739 139 if (argument.BeginsWith("sector=")) {
140 argument.ReplaceAll("sector=", "");
b60d3f6a 141 sector=argument.Atoi();
81e7f739 142 }
143 }
b60d3f6a 144 if (sector<0) {
145 AliError("invalid argument, please specify \"sector=sectorno\"");
146 return -EINVAL;
147 }
148 if (sector>=76) {
149 AliError(Form("invalid sector number %d", sector));
150 return -EINVAL;
151 }
81e7f739 152
c54aa300 153 if (!fClusters) {
b60d3f6a 154 fClusters=new AliTPCclusterMIContainer;
c54aa300 155 }
156 if (!fClusters) return -ENOMEM;
157
b60d3f6a 158 if (fCurrentSector>=0) {
159 // cluster container already filled
160 fCurrentSector=sector;
161 TObjArray* pArray=fClusters->GetSectorArray(fCurrentSector);
162 if (!pArray) {
163 AliError(Form("can not get cluster array for sector %d", sector));
164 return -ENOBUFS;
165 }
166 return pArray->GetEntriesFast();
167 }
168
169 // fill the cluster container
c54aa300 170 AliHLTSystem* pSystem=AliHLTPluginBase::GetInstance();
171 if (!pSystem) {
172 AliError("can not access HLT system");
173 return -ENODEV;
174 }
175 AliHLTOUT* pHLTOUT=pSystem->RequestHLTOUT();
176 if (!pHLTOUT) {
177 AliError("can not access HLTOUT");
b60d3f6a 178 return -EACCES;
c54aa300 179 }
180
b60d3f6a 181 bool bNextBlock=false;
182 bool bHaveLabels=false;
183 bool bHaveIds=false;
184 // add cluster id and mc information data blocks
185 for (bNextBlock=(pHLTOUT->SelectFirstDataBlock()>=0);
186 bNextBlock; bNextBlock=(pHLTOUT->SelectNextDataBlock()>=0)) {
187 AliHLTComponentBlockData desc;
188 // FIXME: extend HLTOUT to get the full descriptor
189 const AliHLTUInt8_t* buffer=NULL;
190 if ((iResult=pHLTOUT->GetDataBuffer(buffer, desc.fSize))<0) {
191 continue;
192 }
193 desc.fPtr=(void*)buffer;
194 if (pHLTOUT->GetDataBlockDescription(desc.fDataType, desc.fSpecification)<0) {
195 continue;
196 }
197 if (desc.fDataType==AliHLTTPCDefinitions::AliHLTDataTypeClusterMCInfo()) {
198 // add mc information
199 if ((iResult=fClusters->AddClusterMCData(&desc))<0) {
200 return iResult;
81e7f739 201 }
b60d3f6a 202 bHaveLabels=true;
203 }
204 if (desc.fDataType==AliHLTTPCDefinitions::RemainingClusterIdsDataType() ||
205 desc.fDataType==AliHLTTPCDefinitions::ClusterIdTracksDataType()) {
206 // add cluster ids
207 if ((iResult=fClusters->AddClusterIds(&desc))<0) {
208 return iResult;
81e7f739 209 }
b60d3f6a 210 bHaveIds=true;
211 }
212 }
213
214 // read data
215 iResult=-ENODATA;
216 AliHLTTPCDataCompressionDecoder decoder;
217 for (bNextBlock=(pHLTOUT->SelectFirstDataBlock()>=0);
218 bNextBlock; bNextBlock=(pHLTOUT->SelectNextDataBlock()>=0)) {
219 AliHLTComponentBlockData desc;
220 // FIXME: extend HLTOUT to get the full descriptor with one call
221 const AliHLTUInt8_t* buffer=NULL;
222 if ((iResult=pHLTOUT->GetDataBuffer(buffer, desc.fSize))<0) {
223 continue;
224 }
225 desc.fPtr=(void*)buffer;
226 if (pHLTOUT->GetDataBlockDescription(desc.fDataType, desc.fSpecification)<0) {
227 continue;
228 }
229 if (!TestBit(kSkipPartitionClusters) &&
230 (desc.fDataType==AliHLTTPCDefinitions::RemainingClustersCompressedDataType() ||
231 desc.fDataType==AliHLTTPCDefinitions::RawClustersDataType())) {
232 iResult=decoder.ReadClustersPartition(fClusters->BeginRemainingClusterBlock(0, desc.fSpecification),
233 reinterpret_cast<AliHLTUInt8_t*>(desc.fPtr),
234 desc.fSize,
235 desc.fSpecification);
236 continue;
237 } else if (!TestBit(kSkipTrackClusters) &&
238 desc.fDataType==AliHLTTPCDefinitions::ClusterTracksCompressedDataType()) {
239 iResult=decoder.ReadTrackModelClustersCompressed(fClusters->BeginTrackModelClusterBlock(0),
240 reinterpret_cast<AliHLTUInt8_t*>(desc.fPtr),
241 desc.fSize,
242 desc.fSpecification);
243 continue;
81e7f739 244 }
c54aa300 245 }
246
247 pSystem->ReleaseHLTOUT(pHLTOUT);
b60d3f6a 248
249 if (iResult<0) return iResult;
250 fCurrentSector=sector;
251 TObjArray* pArray=fClusters->GetSectorArray(fCurrentSector);
252 if (!pArray) {
253 AliError(Form("can not get cluster array for sector %d", sector));
254 return -ENOBUFS;
255 }
256 return pArray->GetEntriesFast();
c54aa300 257}
258
81e7f739 259int AliHLTTPCClusterAccessHLTOUT::ReadAliHLTTPCClusterMCData(AliHLTOUT* pHLTOUT, AliHLTTPCClusterMCDataList &tpcClusterLabels) const
260{
261 // read cluster data from AliHLTTPCClusterData
262 int iResult=0;
263 if (!pHLTOUT) return -EINVAL;
264 do {
265 const AliHLTUInt8_t* pBuffer=NULL;
266 AliHLTUInt32_t size=0;
267 if ((iResult=pHLTOUT->GetDataBuffer(pBuffer, size))<0) {
268 continue;
269 }
270 if (pBuffer==NULL || size<4) {
271 AliError("invalid cluster mc data block");
272 continue;
273 }
274 const AliHLTTPCClusterMCData* clusterMCData = reinterpret_cast<const AliHLTTPCClusterMCData*>(pBuffer);
275 Int_t nLabels = (Int_t) clusterMCData->fCount;
276 if (nLabels*sizeof(AliHLTTPCClusterMCLabel) + sizeof(AliHLTTPCClusterMCData) != size) {
277 AliError("inconsistent cluster mc data block size, skipping block");
278 continue;
279 }
280 // id of the cluster is
281 AliHLTComponentDataType dt=kAliHLTVoidDataType;
282 AliHLTUInt32_t specification=kAliHLTVoidDataSpec;
283 if (pHLTOUT->GetDataBlockDescription(dt, specification)<0) {
284 AliError("failed to retrieve data block description, skipping mc cluster data block ...");
285 continue;
286 }
287 AliHLTUInt8_t slice = AliHLTTPCDefinitions::GetMinSliceNr(specification);
288 AliHLTUInt8_t partition = AliHLTTPCDefinitions::GetMinPatchNr(specification);
289 if (slice!=AliHLTTPCDefinitions::GetMaxSliceNr(specification) ||
290 partition!=AliHLTTPCDefinitions::GetMaxPatchNr(specification)) {
291 AliError(Form("can not read cluster mc data block with data of multiple partitions, skipping block %s %08x",
292 AliHLTComponent::DataType2Text(dt).c_str(), specification));
293 continue;
294 }
295 const AliHLTTPCClusterMCLabel *labels = clusterMCData->fLabels;
296 for (int i=0; i<nLabels; i++) {
297 AliHLTUInt32_t id=AliHLTTPCSpacePointData::GetID(slice, partition, i);
298 if (tpcClusterLabels.find(id)==tpcClusterLabels.end()) {
299 // new cluster
300 tpcClusterLabels[id]=labels[i];
301 } else {
302 AliError(Form("cluster with ID 0x%08x already existing, skipping cluster %d of data block 0x%08x",
303 id, i, specification));
304 }
305 }
306 } while (pHLTOUT->SelectNextDataBlock()>=0);
307 return iResult;
308}
309
310int AliHLTTPCClusterAccessHLTOUT::ReadAliHLTTPCClusterData(AliHLTOUT* pHLTOUT, TClonesArray* pClusters, const AliHLTTPCClusterMCDataList *tpcClusterLabels) const
c54aa300 311{
312 // read cluster data from AliHLTTPCClusterData
313 int iResult=0;
314 if (!pHLTOUT || !pClusters) return -EINVAL;
315 do {
316 const AliHLTUInt8_t* pBuffer=NULL;
317 AliHLTUInt32_t size=0;
318 if ((iResult=pHLTOUT->GetDataBuffer(pBuffer, size))<0) {
319 continue;
320 }
321 if (pBuffer==NULL || size<4) {
322 AliError("invalid cluster data block");
323 continue;
324 }
81e7f739 325 AliHLTComponentDataType dt=kAliHLTVoidDataType;
326 AliHLTUInt32_t specification=kAliHLTVoidDataSpec;
327 if (pHLTOUT->GetDataBlockDescription(dt, specification)<0) {
328 AliError("failed to retrieve data block description, skipping mc cluster data block ...");
329 continue;
330 }
c54aa300 331 const AliHLTTPCClusterData* clusterData = reinterpret_cast<const AliHLTTPCClusterData*>(pBuffer);
332 Int_t nSpacepoints = (Int_t) clusterData->fSpacePointCnt;
333 if (nSpacepoints*sizeof(AliHLTTPCSpacePointData) + sizeof(AliHLTTPCClusterData) != size) {
334 AliError("inconsistent cluster data block size, skipping block");
335 continue;
336 }
337 const AliHLTTPCSpacePointData *clusters = clusterData->fSpacePoints;
81e7f739 338 int offset=pClusters->GetEntries();
339 pClusters->ExpandCreate(offset+nSpacepoints);
0e63cf4a 340 AliHLTUInt8_t slice = AliHLTTPCDefinitions::GetMinSliceNr(specification);
341 AliHLTUInt8_t partition = AliHLTTPCDefinitions::GetMinPatchNr(specification);
342 // FIXME: get first row number of outer sectors from a common definition instead using number
80874dc5 343 unsigned rowOffset=partition<2?0:63;
c54aa300 344 for (int i=0; i<nSpacepoints; i++) {
81e7f739 345 if (!pClusters->At(offset+i)) continue;
346 AliTPCclusterMI* pCluster=dynamic_cast<AliTPCclusterMI*>(pClusters->At(offset+i));
c54aa300 347 if (!pCluster) {
348 AliError("invalid object type, expecting AliTPCclusterMI");
349 break; // this is a problem of all objects
350 }
0e63cf4a 351 if (clusters[i].fPadRow<rowOffset) {
352 AliError(Form("invalid row number %d, expecting minimum row number %d for slice %d partition %d", clusters[i].fPadRow, rowOffset, slice, partition));
353 } else {
354 pCluster->SetRow(clusters[i].fPadRow-rowOffset);
355 }
81e7f739 356 pCluster->SetPad(clusters[i].fY);
5e75f4e0 357 pCluster->SetTimeBin(clusters[i].fZ);
81e7f739 358 pCluster->SetSigmaY2(clusters[i].fSigmaY2);
359 pCluster->SetSigmaZ2(clusters[i].fSigmaZ2);
c54aa300 360 pCluster->SetQ(clusters[i].fCharge);
361 pCluster->SetMax(clusters[i].fQMax);
81e7f739 362 if (tpcClusterLabels) {
363 if (tpcClusterLabels->find(clusters[i].fID)!=tpcClusterLabels->end()) {
364 const AliHLTTPCClusterMCWeight* mcWeights=tpcClusterLabels->find(clusters[i].fID)->second.fClusterID;
365 for (int k=0; k<3; k++) {
366 // TODO: sort the labels according to the weight in order to assign the most likely mc label
367 // to the first component
368 pCluster->SetLabel(mcWeights[k].fMCID, k);
369 }
370 } else {
371 AliError(Form("can not find mc label of cluster with id %0x08x", clusters[i].fID));
372 }
373 }
c54aa300 374 }
1214ab89 375 if (fVerbosity>0) AliInfo(Form("converted %d cluster(s) from block %s 0x%08x", nSpacepoints, AliHLTComponent::DataType2Text(dt).c_str(), specification));
c54aa300 376 } while (pHLTOUT->SelectNextDataBlock()>=0);
377 return iResult;
378}
5e75f4e0 379
380int AliHLTTPCClusterAccessHLTOUT::ReadAliHLTTPCRawClusterData(AliHLTOUT* pHLTOUT, TClonesArray* pClusters, const AliHLTTPCClusterMCDataList *tpcClusterLabels)
381{
382 // read cluster data from AliHLTTPCClusterData
383
384 // FIXME: this is in large parts like ReadAliHLTTPCClusterData,
385 // make a common method
386 int iResult=0;
387 if (!pHLTOUT || !pClusters) return -EINVAL;
388 do {
389 const AliHLTUInt8_t* pBuffer=NULL;
390 AliHLTUInt32_t size=0;
391 if ((iResult=pHLTOUT->GetDataBuffer(pBuffer, size))<0) {
392 continue;
393 }
394 if (pBuffer==NULL || size<4) {
395 AliError("invalid cluster data block");
396 continue;
397 }
398 AliHLTComponentDataType dt=kAliHLTVoidDataType;
399 AliHLTUInt32_t specification=kAliHLTVoidDataSpec;
400 if (pHLTOUT->GetDataBlockDescription(dt, specification)<0) {
401 AliError("failed to retrieve data block description, skipping mc cluster data block ...");
402 continue;
403 }
404 const AliHLTTPCRawClusterData* clusterData = reinterpret_cast<const AliHLTTPCRawClusterData*>(pBuffer);
405 Int_t nCount = (Int_t) clusterData->fCount;
61e66346 406 if (clusterData->fVersion!=0) {
407 // this is encoded data of different formats
408 switch (clusterData->fVersion) {
409 case 1:
410 iResult=ReadAliHLTTPCRawClusterDataDeflateSimple(reinterpret_cast<const AliHLTUInt8_t*>(clusterData->fClusters),
411 size-sizeof(AliHLTTPCRawClusterData), nCount, specification,
412 pClusters, tpcClusterLabels);
413 break;
414 default:
415 iResult=-EPROTO;
416 }
417 return iResult;
418 }
419
5e75f4e0 420 if (nCount*sizeof(AliHLTTPCRawCluster) + sizeof(AliHLTTPCRawClusterData) != size) {
421 AliError("inconsistent cluster data block size, skipping block");
422 continue;
423 }
424 const AliHLTTPCRawCluster *clusters = clusterData->fClusters;
425 int offset=pClusters->GetEntries();
426 pClusters->ExpandCreate(offset+nCount);
0e63cf4a 427 AliHLTUInt8_t slice = AliHLTTPCDefinitions::GetMinSliceNr(specification);
428 AliHLTUInt8_t partition = AliHLTTPCDefinitions::GetMinPatchNr(specification);
429 // FIXME: get first row number of outer sectors from a common definition instead using number
80874dc5 430 int rowOffset=partition<2?0:63;
5e75f4e0 431 for (int i=0; i<nCount; i++) {
432 if (!pClusters->At(offset+i)) continue;
433 AliTPCclusterMI* pCluster=dynamic_cast<AliTPCclusterMI*>(pClusters->At(offset+i));
434 if (!pCluster) {
435 AliError("invalid object type, expecting AliTPCclusterMI");
436 break; // this is a problem of all objects
437 }
1214ab89 438 if (fVerbosity>1) AliInfo(Form("cluster padrow %d (slice %d partition %d)", clusters[i].GetPadRow(), slice, partition));
0e63cf4a 439 if (clusters[i].GetPadRow()<rowOffset) {
440 AliError(Form("invalid row number %d, expecting minimum row number %d for slice %d partition %d", clusters[i].GetPadRow(), rowOffset, slice, partition));
441 } else {
442 pCluster->SetRow(clusters[i].GetPadRow()-rowOffset);
443 }
1b9cc91a 444 pCluster->SetPad(clusters[i].GetPad());
5e75f4e0 445 pCluster->SetTimeBin(clusters[i].GetTime());
446 pCluster->SetSigmaY2(clusters[i].GetSigmaY2());
447 pCluster->SetSigmaZ2(clusters[i].GetSigmaZ2());
448 pCluster->SetQ(clusters[i].GetCharge());
449 pCluster->SetMax(clusters[i].GetQMax());
450 if (tpcClusterLabels) {
5e75f4e0 451 UInt_t clusterID=AliHLTTPCSpacePointData::GetID(slice, partition, i);
452 if (tpcClusterLabels->find(clusterID)!=tpcClusterLabels->end()) {
453 const AliHLTTPCClusterMCWeight* mcWeights=tpcClusterLabels->find(clusterID)->second.fClusterID;
454 for (int k=0; k<3; k++) {
455 // TODO: sort the labels according to the weight in order to assign the most likely mc label
456 // to the first component
457 pCluster->SetLabel(mcWeights[k].fMCID, k);
458 }
459 } else {
460 AliError(Form("can not find mc label of cluster with id %0x08x", clusterID));
461 }
462 }
463 }
464 if (fVerbosity>0) AliInfo(Form("converted %d cluster(s) from block %s 0x%08x", nCount, AliHLTComponent::DataType2Text(dt).c_str(), specification));
465 } while (pHLTOUT->SelectNextDataBlock()>=0);
466 return iResult;
467}
61e66346 468
2827cd62 469int AliHLTTPCClusterAccessHLTOUT::ReadRemainingClustersCompressed(AliHLTOUT* pHLTOUT, TClonesArray* pClusters, const AliHLTTPCClusterMCDataList *tpcClusterLabels)
470{
471 // read cluster data from AliHLTTPCClusterData
472 int iResult=0;
473 if (!pHLTOUT || !pClusters) return -EINVAL;
474 do {
475 const AliHLTUInt8_t* pBuffer=NULL;
476 AliHLTUInt32_t size=0;
477 if ((iResult=pHLTOUT->GetDataBuffer(pBuffer, size))<0) {
478 continue;
479 }
480 if (pBuffer==NULL || size<4) {
481 AliError("invalid cluster data block");
482 continue;
483 }
484 AliHLTComponentDataType dt=kAliHLTVoidDataType;
485 AliHLTUInt32_t specification=kAliHLTVoidDataSpec;
486 if (pHLTOUT->GetDataBlockDescription(dt, specification)<0) {
487 AliError("failed to retrieve data block description, skipping mc cluster data block ...");
488 continue;
489 }
490 const AliHLTTPCRawClusterData* clusterData = reinterpret_cast<const AliHLTTPCRawClusterData*>(pBuffer);
491 Int_t nCount = (Int_t) clusterData->fCount;
492
493 // this is encoded data of different formats
494 switch (clusterData->fVersion) {
495 case 1:
496 iResult=ReadAliHLTTPCRawClusterDataDeflateSimple(reinterpret_cast<const AliHLTUInt8_t*>(clusterData->fClusters),
497 size-sizeof(AliHLTTPCRawClusterData), nCount, specification,
498 pClusters, tpcClusterLabels);
499 break;
500 default:
501 AliError(Form("invalid cluster format version %d", clusterData->fVersion));
502 iResult=-EPROTO;
503 }
504
505 if (fVerbosity>0) AliInfo(Form("converted %d cluster(s) from block %s 0x%08x", nCount, AliHLTComponent::DataType2Text(dt).c_str(), specification));
506 } while (pHLTOUT->SelectNextDataBlock()>=0 && iResult>=0);
507
508 return iResult;
509}
510
61e66346 511int AliHLTTPCClusterAccessHLTOUT::ReadAliHLTTPCRawClusterDataDeflateSimple(const AliHLTUInt8_t* pData, int dataSize,
512 int nofClusters, AliHLTUInt32_t specification,
513 TClonesArray* pClusters,
514 const AliHLTTPCClusterMCDataList *tpcClusterLabels)
515{
516 // read cluster data from AliHLTTPCClusterData
517
518 // FIXME: quick implementation to read the compressed cluster data from HLTOUT
519 // the data definition below is the same as in AliHLTTPCDataCompressionComponent
520 // but needs to be moved to a common class (AliHLTTPCDefinitions?)
521 // Think about a decoder class supporting iterator objects for various types
522 // of cluster data
523 int iResult=0;
524 if (!pData || !pClusters) return -EINVAL;
525 AliHLTDataInflater inflater;
526 if ((iResult=inflater.InitBitDataInput(pData, dataSize))<0) {
527 return iResult;
528 }
529
530 int offset=pClusters->GetEntries();
531 pClusters->ExpandCreate(offset+nofClusters);
532 AliHLTUInt8_t slice = AliHLTTPCDefinitions::GetMinSliceNr(specification);
533 AliHLTUInt8_t partition = AliHLTTPCDefinitions::GetMinPatchNr(specification);
534 // the compressed format stores the difference of the local row number in
535 // the partition to the row of the last cluster
536 // add the first row in the partition to get global row number
537 // offline uses row number in physical sector, inner sector consists of
538 // partitions 0 and 1, outer sector of partition 2-5
539 int rowOffset=AliHLTTPCTransform::GetFirstRow(partition)-(partition<2?0:AliHLTTPCTransform::GetFirstRow(2));
540
541 int parameterId=0;
542 int outClusterCnt=0;
543 AliHLTUInt8_t switchBit=0;
544 AliHLTUInt64_t value=0;
545 AliTPCclusterMI* pCluster=NULL;
546 AliHLTUInt32_t lastPadRow=0;
547 while (outClusterCnt<nofClusters && inflater.InputBit(switchBit)) {
548 const AliHLTTPCDefinitions::AliClusterParameter& parameter
549 =AliHLTTPCDefinitions::fgkClusterParameterDefinitions[parameterId];
550 // in mode DeflaterSimple, the optional parameter of the cluster parameter definition
551 // corresponds to the number bits of the reduced format
552 if (!inflater.InputBits(value, switchBit?parameter.fBitLength:parameter.fOptional)) {
553 break;
554 }
555
556 if (!pCluster) {
557 if (!pClusters->At(offset+outClusterCnt)) {
558 // here we should not get anymore because of the condition outClusterCnt<nofClusters
559 return -ENOSPC;
560 }
561 pCluster=dynamic_cast<AliTPCclusterMI*>(pClusters->At(offset+outClusterCnt));
562 if (!pCluster) {
563 AliError("invalid object type, expecting AliTPCclusterMI");
564 iResult=-EBADF; // this is a problem of all objects
565 break;
566 }
567 }
568 switch (parameterId) {
569 case AliHLTTPCDefinitions::kPadRow:
570 {pCluster->SetRow(value+lastPadRow+rowOffset); lastPadRow+=value;break;}
571 case AliHLTTPCDefinitions::kPad:
572 {float pad=value; pad/=parameter.fScale; pCluster->SetPad(pad); break;}
573 case AliHLTTPCDefinitions::kTime:
574 {float time=value; time/=parameter.fScale; pCluster->SetTimeBin(time); break;}
575 case AliHLTTPCDefinitions::kSigmaY2:
576 {float sigmaY2=value; sigmaY2/=parameter.fScale; pCluster->SetSigmaY2(sigmaY2); break;}
577 case AliHLTTPCDefinitions::kSigmaZ2:
578 {float sigmaZ2=value; sigmaZ2/=parameter.fScale; pCluster->SetSigmaZ2(sigmaZ2); break;}
579 case AliHLTTPCDefinitions::kCharge:
580 {pCluster->SetQ(value); break;}
581 case AliHLTTPCDefinitions::kQMax:
582 {pCluster->SetMax(value); break;}
583 }
584 if (parameterId>=AliHLTTPCDefinitions::kLast) {
585 // switch to next cluster
586 if (tpcClusterLabels) {
587 UInt_t clusterID=AliHLTTPCSpacePointData::GetID(slice, partition, outClusterCnt);
588 if (tpcClusterLabels->find(clusterID)!=tpcClusterLabels->end()) {
589 const AliHLTTPCClusterMCWeight* mcWeights=tpcClusterLabels->find(clusterID)->second.fClusterID;
590 for (int k=0; k<3; k++) {
591 // TODO: sort the labels according to the weight in order to assign the most likely mc label
592 // to the first component
593 pCluster->SetLabel(mcWeights[k].fMCID, k);
594 }
595 } else {
2827cd62 596 AliError(Form("can not find mc label of cluster with id 0x%08x", clusterID));
61e66346 597 }
598 }
599 outClusterCnt++;
600 pCluster=NULL;
601 parameterId=-1;
602 }
603 parameterId++;
604 }
605 inflater.Pad8Bits();
606 if (inflater.InputBit(switchBit)) {
607 AliWarning("format error of compressed clusters, there is more data than expected");
608 }
609 inflater.CloseBitDataInput();
610 if (iResult>=0 && nofClusters!=outClusterCnt) {
611 // is this a Fatal?
612 AliError(Form("error reading compressed cluster format: expected %d, read only %d cluster(s)", nofClusters, outClusterCnt));
613 return -EPROTO;
614 }
615 return iResult;
616}
b60d3f6a 617
618AliHLTTPCClusterAccessHLTOUT::AliTPCclusterMIContainer::AliTPCclusterMIContainer()
619 : fClusterArrays()
620 , fRemainingClusterIds()
621 , fTrackModelClusterIds()
622 , fCurrentClusterIds(NULL)
623 , fClusterMCData()
624 , fIterator()
625
626{
627 /// constructor
628 for (int i=0; i<72; i++) {
629 fClusterArrays.push_back(new TClonesArray("AliTPCclusterMI"));
630 }
631}
632
633AliHLTTPCClusterAccessHLTOUT::AliTPCclusterMIContainer::~AliTPCclusterMIContainer()
634{
635 /// dectructor
636 for (vector<TClonesArray*>::iterator i=fClusterArrays.begin(); i!=fClusterArrays.end(); i++) {
637 if (*i) {
638 (*i)->Clear();
639 delete *i;
640 }
641 }
642}
643
644AliHLTTPCClusterAccessHLTOUT::AliTPCclusterMIContainer::iterator& AliHLTTPCClusterAccessHLTOUT::AliTPCclusterMIContainer::BeginRemainingClusterBlock(int /*count*/, AliHLTUInt32_t specification)
645{
646 /// iterator of remaining clusters block of specification
647 AliHLTUInt8_t slice=AliHLTTPCDefinitions::GetMinSliceNr(specification);
648 AliHLTUInt8_t partition=AliHLTTPCDefinitions::GetMinPatchNr(specification);
649 unsigned index=slice*AliHLTTPCTransform::GetNumberOfPatches()+partition;
650 if (index<fRemainingClusterIds.size())
651 fCurrentClusterIds=&fRemainingClusterIds[index];
652 else
653 fCurrentClusterIds=NULL;
654 fIterator=iterator(this);
655 return fIterator;
656}
657
658AliHLTTPCClusterAccessHLTOUT::AliTPCclusterMIContainer::iterator& AliHLTTPCClusterAccessHLTOUT::AliTPCclusterMIContainer::BeginTrackModelClusterBlock(int /*count*/)
659{
660 /// iterator of track model clusters
661 if (fTrackModelClusterIds.fIds && fTrackModelClusterIds.fSize>0)
662 fCurrentClusterIds=&fTrackModelClusterIds;
663 else
664 fCurrentClusterIds=NULL;
665 fIterator=iterator(this);
666 return fIterator;
667}
668
669int AliHLTTPCClusterAccessHLTOUT::AliTPCclusterMIContainer::AddClusterMCData(const AliHLTComponentBlockData* pDesc)
670{
671 /// add cluster mc data block
672 if (!pDesc) return -EINVAL;
673 if (pDesc->fDataType==AliHLTTPCDefinitions::AliHLTDataTypeClusterMCInfo()) {
674 AliHLTUInt8_t slice=AliHLTTPCDefinitions::GetMinSliceNr(pDesc->fSpecification);
675 AliHLTUInt8_t partition=AliHLTTPCDefinitions::GetMinPatchNr(pDesc->fSpecification);
676 unsigned index=slice*AliHLTTPCTransform::GetNumberOfPatches()+partition;
677 if (fClusterMCData.size()<=index) {
678 if ((int)fClusterMCData.size()<AliHLTTPCTransform::GetNSlice()*AliHLTTPCTransform::GetNumberOfPatches()) {
679 fClusterMCData.resize(AliHLTTPCTransform::GetNSlice()*AliHLTTPCTransform::GetNumberOfPatches(), NULL);
680 } else {
681 fClusterMCData.resize(index+1, NULL);
682 }
683 }
684 if (pDesc->fSize<sizeof(AliHLTTPCClusterMCData)) return -EINVAL;
685 const AliHLTTPCClusterMCData* pData=reinterpret_cast<const AliHLTTPCClusterMCData*>(pDesc->fPtr);
686 unsigned nLabels = pData->fCount;
687 if (nLabels*sizeof(AliHLTTPCClusterMCLabel) + sizeof(AliHLTTPCClusterMCData) != pDesc->fSize) {
688 return -EINVAL;
689 }
690 fClusterMCData[index]=pData;
691 return 0;
692 }
693 return -ENODATA;
694}
695
696int AliHLTTPCClusterAccessHLTOUT::AliTPCclusterMIContainer::AddClusterIds(const AliHLTComponentBlockData* pDesc)
697{
698 /// add cluster id block for remaining or track model clusters
699 if (!pDesc) return -EINVAL;
700 if (pDesc->fDataType==AliHLTTPCDefinitions::ClusterIdTracksDataType()) {
701 fTrackModelClusterIds.fIds=reinterpret_cast<AliHLTUInt32_t*>(pDesc->fPtr);
702 fTrackModelClusterIds.fSize=pDesc->fSize/sizeof(AliHLTUInt32_t);
703 return 0;
704 }
705 if (pDesc->fDataType==AliHLTTPCDefinitions::RemainingClusterIdsDataType()) {
706 AliHLTUInt8_t slice=AliHLTTPCDefinitions::GetMinSliceNr(pDesc->fSpecification);
707 AliHLTUInt8_t partition=AliHLTTPCDefinitions::GetMinPatchNr(pDesc->fSpecification);
708 unsigned index=slice*AliHLTTPCTransform::GetNumberOfPatches()+partition;
709 if (fRemainingClusterIds.size()<=index) {
710 if ((int)fRemainingClusterIds.size()<AliHLTTPCTransform::GetNSlice()*AliHLTTPCTransform::GetNumberOfPatches()) {
711 fRemainingClusterIds.resize(AliHLTTPCTransform::GetNSlice()*AliHLTTPCTransform::GetNumberOfPatches());
712 } else {
713 fRemainingClusterIds.resize(index+1);
714 }
715 }
716 fRemainingClusterIds[index].fIds=reinterpret_cast<AliHLTUInt32_t*>(pDesc->fPtr);
717 fRemainingClusterIds[index].fSize=pDesc->fSize/sizeof(AliHLTUInt32_t);
718 return 0;
719 }
720 return -ENODATA;
721}
722
723AliHLTUInt32_t AliHLTTPCClusterAccessHLTOUT::AliTPCclusterMIContainer::GetClusterId(int clusterNo) const
724{
725 /// get the cluster id from the current cluster id block (optional)
726 if (!fCurrentClusterIds ||
ebba640a 727 (int)fCurrentClusterIds->fSize<=clusterNo ||
728 clusterNo<0)
b60d3f6a 729 return kAliHLTVoidDataSpec;
730 return fCurrentClusterIds->fIds[clusterNo];
731}
732
733AliTPCclusterMI* AliHLTTPCClusterAccessHLTOUT::AliTPCclusterMIContainer::NextCluster(int slice, int partition)
734{
735 /// load next cluster from array of the sepcific sector
736 unsigned sector=partition<2?slice:slice+36;
737 if (fClusterArrays.size()<=sector ||
738 fClusterArrays[sector]==NULL) {
739 AliErrorClass(Form("no cluster array available for sector %d", sector));
740 return NULL;
741 }
742 TClonesArray& array=*(fClusterArrays[sector]);
743 int count=array.GetEntriesFast();
744 return new (array[count]) AliTPCclusterMI;
745}
746
747int AliHLTTPCClusterAccessHLTOUT::AliTPCclusterMIContainer::SetMC(AliTPCclusterMI* pCluster, AliHLTUInt32_t clusterId)
748{
749 /// set MC data for the cluster
750 if (!pCluster) return -EINVAL;
751 if (clusterId==kAliHLTVoidDataSpec) return 0;
752
753 unsigned slice=AliHLTTPCSpacePointData::GetSlice(clusterId);
754 unsigned partition=AliHLTTPCSpacePointData::GetPatch(clusterId);
755 unsigned number=AliHLTTPCSpacePointData::GetNumber(clusterId);
756 if ((int)slice>=AliHLTTPCTransform::GetNSlice() ||
757 (int)partition>=AliHLTTPCTransform::GetNumberOfPatches()) return -EDOM;
758 unsigned index=slice*AliHLTTPCTransform::GetNumberOfPatches()+partition;
759 if (fClusterMCData.size()<=index ||
760 fClusterMCData[index]==NULL ||
761 fClusterMCData[index]->fCount<=number) return 0;
762 const AliHLTTPCClusterMCWeight* mcWeights=fClusterMCData[index]->fLabels[number].fClusterID;
763 for (int k=0; k<3; k++) {
764 // TODO: sort the labels according to the weight in order to assign the most likely mc label
765 // to the first component
766 pCluster->SetLabel(mcWeights[k].fMCID, k);
767 }
768
769 return 0;
770}
771
772void AliHLTTPCClusterAccessHLTOUT::AliTPCclusterMIContainer::Clear(Option_t* /*option*/)
773{
774 /// internal cleanup
775 {
776 for (vector<TClonesArray*>::iterator i=fClusterArrays.begin(); i!=fClusterArrays.end(); i++)
777 if (*i) (*i)->Clear();
778 }
779 {
780 for (vector<AliClusterIdBlock>::iterator i=fRemainingClusterIds.begin(); i!=fRemainingClusterIds.end(); i++)
781 {i->fIds=NULL; i->fSize=0;}
782 }
783 fTrackModelClusterIds.fIds=NULL; fTrackModelClusterIds.fSize=0;
784 fCurrentClusterIds=NULL;
785 {
786 for (vector<const AliHLTTPCClusterMCData*>::iterator i=fClusterMCData.begin(); i!=fClusterMCData.end(); i++)
787 *i=NULL;
788 }
789}
790
791TObjArray* AliHLTTPCClusterAccessHLTOUT::AliTPCclusterMIContainer::GetSectorArray(unsigned sector) const
792{
793 /// get the cluster array for a sector
794 if (fClusterArrays.size()<=sector) return NULL;
795 return fClusterArrays[sector];
796}
797
798void AliHLTTPCClusterAccessHLTOUT::AliTPCclusterMIContainer::Print(Option_t *option) const
799{
800 /// inherited from TObject
801 cout << "AliHLTTPCClusterAccessHLTOUT::AliTPCclusterMIContainer" << endl;
802 ios::fmtflags coutflags=cout.flags(); // backup cout status flags
803 bool bAll=false;
804 if ((bAll=(strcmp(option, "full")==0)) ||
805 strcmp(option, "short")==0) {
806 for (unsigned iArray=0; iArray<fClusterArrays.size(); iArray++) {
807 if (fClusterArrays[iArray]) {
808 TClonesArray* pArray=fClusterArrays[iArray];
809 cout << " sector " << setfill(' ') << setw(2) << iArray << ": " << pArray->GetEntriesFast() << endl;
810 if (bAll) {
811 for (int iCluster=0; iCluster<pArray->GetEntriesFast(); iCluster++) {
812 if (!pArray->At(iCluster)) continue;
813 AliTPCclusterMI* pCluster=dynamic_cast<AliTPCclusterMI*>(pArray->At(iCluster));
814 if (!pCluster) break;
815 cout << " AliTPCclusterMI:"
816 << " row=" << pCluster->GetRow()
817 << " pad=" << pCluster->GetPad()
818 << " time=" << pCluster->GetTimeBin()
819 << " charge=" << pCluster->GetQ()
820 << " maxq=" << pCluster->GetMax()
821 << endl;
822 }
823 }
824 }
825 }
826 }
827 cout.flags(coutflags); // restore the original flags
828}
829
830AliHLTTPCClusterAccessHLTOUT::AliTPCclusterMIContainer::iterator& AliHLTTPCClusterAccessHLTOUT::AliTPCclusterMIContainer::iterator::Next(int slice, int partition)
831{
832 // switch to next cluster
833 if (!fData) {
834 fCluster=NULL;
835 fClusterId=kAliHLTVoidDataSpec;
836 return *this;
837 }
838 if (fClusterNo>=0 && !fCluster) {
839 // end was reached before
840 return *this;
841 }
842 fCluster=fData->NextCluster(slice, partition);
843 fClusterId=fData->GetClusterId(++fClusterNo);
844 if (fCluster && fClusterId!=kAliHLTVoidDataSpec) {
845 fData->SetMC(fCluster, fClusterId);
846 }
847 // offline uses row number in physical sector, inner sector consists of
848 // partitions 0 and 1, outer sector of partition 2-5
849 fRowOffset=partition<2?0:AliHLTTPCTransform::GetFirstRow(2);
850 return *this;
851}