adding option to set number of events for simulation
[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"
c54aa300 29#include "AliHLTOUT.h"
81e7f739 30#include "AliHLTComponent.h"
73db5fa6 31#include "AliHLTErrorGuard.h"
c54aa300 32#include "AliLog.h"
33#include "AliHLTSystem.h"
34#include "AliHLTPluginBase.h"
35#include "AliTPCclusterMI.h"
36#include "TClonesArray.h"
81e7f739 37#include <cstdlib>
38#include <string>
39#include <memory>
c54aa300 40
41/** ROOT macro for the implementation of ROOT specific class methods */
42ClassImp(AliHLTTPCClusterAccessHLTOUT)
43
44AliHLTTPCClusterAccessHLTOUT::AliHLTTPCClusterAccessHLTOUT()
45 : TObject()
81e7f739 46 , fVerbosity(0)
c54aa300 47 , fClusters(NULL)
48{
49 // see header file for class documentation
50 // or
51 // refer to README to build package
52 // or
53 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
54}
55
56AliHLTTPCClusterAccessHLTOUT::~AliHLTTPCClusterAccessHLTOUT()
57{
58 // destructor
59 if (fClusters) {
60 fClusters->Clear();
61 delete fClusters;
62 fClusters=NULL;
63 }
64}
65
81e7f739 66void AliHLTTPCClusterAccessHLTOUT::Execute(const char *method, const char *params, Int_t *error)
c54aa300 67{
68 /// inherited from TObject: abstract command interface
69 if (strcmp(method, "read")==0) {
81e7f739 70 int iResult=ProcessClusters(params);
71 if (error) *error=iResult;
72 return;
73 }
74 if (strcmp(method, "verbosity")==0) {
75 int iResult=0;
76 if (params) {
77 char* dummy;
78 int value=strtol(params, &dummy, 0);
79 if (dummy==NULL) {
80 fVerbosity=value;
81 } else {
82 AliError("invalid argument for command 'verbosity', expecting string with number");
83 }
84 } else {
85 iResult=-EINVAL;
86 }
c54aa300 87 if (error) *error=iResult;
88 return;
89 }
90}
91
92TObject* AliHLTTPCClusterAccessHLTOUT::FindObject(const char *name) const
93{
94 /// inherited from TObject: return the cluster array if name id "clusterarray"
95 if (strcmp(name, "clusterarray")==0) return fClusters;
96 return TObject::FindObject(name);
97}
98
99void AliHLTTPCClusterAccessHLTOUT::Clear(Option_t * /*option*/)
100{
101 /// inherited from TObject: cleanup
102 if (fClusters) fClusters->Clear();
103}
104
105void AliHLTTPCClusterAccessHLTOUT::Print(Option_t */*option*/) const
106{
107 /// inherited from TObject
108 if (!fClusters) return;
109 for (int i=0; i<fClusters->GetEntriesFast(); i++) {
110 if (!fClusters->At(i)) continue;
111 AliTPCclusterMI* pCluster=dynamic_cast<AliTPCclusterMI*>(fClusters->At(i));
112 if (!pCluster) break;
113 cout << "AliTPCclusterMI:"
114 << " row=" << pCluster->GetRow()
115 << " pad=" << pCluster->GetPad()
116 << " time=" << pCluster->GetTimeBin()
117 << " charge=" << pCluster->GetQ()
118 << " maxq=" << pCluster->GetMax()
119 << endl;
120 }
121}
122
81e7f739 123int AliHLTTPCClusterAccessHLTOUT::ProcessClusters(const char* params)
c54aa300 124{
125 /// process the cluster data from HLTOUT and fill array
126 /// the cluster data can be in many different formats, e.g.
127 /// raw or compressed
128 int iResult=0;
81e7f739 129 TString strparams(params);
130 int minSlice=0, maxSlice=35, minPart=0, maxPart=5;
131 std::auto_ptr<TObjArray> tokens(strparams.Tokenize(" "));
132 if (!tokens.get()) return -ENOMEM;
133 for (int i=0; i< tokens->GetEntriesFast(); i++) {
134 if (!tokens->At(i)) continue;
135 TString argument=tokens->At(i)->GetName();
136 if (argument.BeginsWith("sector=")) {
137 argument.ReplaceAll("sector=", "");
138 int sector=argument.Atoi();
139 // the offline code enumerates first the 36 inner (partitions 0+1) and then 36 outer
140 // sectors (partitions 2-5)
141 if (fVerbosity>0) AliInfo(Form("processing HLT clusters for sector %d", sector));
142 if (sector<36) { // inner sectors
143 minSlice=maxSlice=sector;
144 minPart=0; maxPart=1;
145 } else { // outer sectors
146 minSlice=maxSlice=sector-36;
147 minPart=2; maxPart=5;
148 }
149 }
150 }
151
c54aa300 152 if (!fClusters) {
153 fClusters=new TClonesArray("AliTPCclusterMI");
154 }
155 if (!fClusters) return -ENOMEM;
156
157 AliHLTSystem* pSystem=AliHLTPluginBase::GetInstance();
158 if (!pSystem) {
159 AliError("can not access HLT system");
160 return -ENODEV;
161 }
162 AliHLTOUT* pHLTOUT=pSystem->RequestHLTOUT();
163 if (!pHLTOUT) {
164 AliError("can not access HLTOUT");
165 return -ENODEV;
166 }
167
81e7f739 168 for (int slice=minSlice; slice<=maxSlice; slice++) {
169 for (int part=minPart; part<=maxPart; part++) {
170 if (fVerbosity>0) AliInfo(Form("processing HLT clusters for slice %d partitions %d", slice, part));
171 AliHLTUInt32_t spec=slice<<24 | slice<<16 | part<<8 | part;
172 AliHLTTPCClusterMCDataList tpcClusterLabels;
1214ab89 173 bool bHaveLabels=false;
81e7f739 174 if (pHLTOUT->SelectFirstDataBlock(AliHLTTPCDefinitions::fgkAliHLTDataTypeClusterMCInfo, spec)>=0) {
175 iResult=ReadAliHLTTPCClusterMCData(pHLTOUT, tpcClusterLabels);
1214ab89 176 bHaveLabels=true;
81e7f739 177 }
178
5e75f4e0 179 if (pHLTOUT->SelectFirstDataBlock(AliHLTTPCDefinitions::fgkRawClustersDataType, spec)>=0) {
1214ab89 180 iResult=ReadAliHLTTPCRawClusterData(pHLTOUT, fClusters, bHaveLabels?&tpcClusterLabels:NULL);
5e75f4e0 181 } else if (pHLTOUT->SelectFirstDataBlock(AliHLTTPCDefinitions::fgkClustersDataType, spec)>=0) {
73db5fa6 182 ALIHLTERRORGUARD(1, "HLTOUT data contains tarnsformed TPC clusters instead of raw TPC clusters, can not create clusters for reconstruction");
81e7f739 183 }
184 }
c54aa300 185 }
186
187 pSystem->ReleaseHLTOUT(pHLTOUT);
188 return iResult;
189}
190
81e7f739 191int AliHLTTPCClusterAccessHLTOUT::ReadAliHLTTPCClusterMCData(AliHLTOUT* pHLTOUT, AliHLTTPCClusterMCDataList &tpcClusterLabels) const
192{
193 // read cluster data from AliHLTTPCClusterData
194 int iResult=0;
195 if (!pHLTOUT) return -EINVAL;
196 do {
197 const AliHLTUInt8_t* pBuffer=NULL;
198 AliHLTUInt32_t size=0;
199 if ((iResult=pHLTOUT->GetDataBuffer(pBuffer, size))<0) {
200 continue;
201 }
202 if (pBuffer==NULL || size<4) {
203 AliError("invalid cluster mc data block");
204 continue;
205 }
206 const AliHLTTPCClusterMCData* clusterMCData = reinterpret_cast<const AliHLTTPCClusterMCData*>(pBuffer);
207 Int_t nLabels = (Int_t) clusterMCData->fCount;
208 if (nLabels*sizeof(AliHLTTPCClusterMCLabel) + sizeof(AliHLTTPCClusterMCData) != size) {
209 AliError("inconsistent cluster mc data block size, skipping block");
210 continue;
211 }
212 // id of the cluster is
213 AliHLTComponentDataType dt=kAliHLTVoidDataType;
214 AliHLTUInt32_t specification=kAliHLTVoidDataSpec;
215 if (pHLTOUT->GetDataBlockDescription(dt, specification)<0) {
216 AliError("failed to retrieve data block description, skipping mc cluster data block ...");
217 continue;
218 }
219 AliHLTUInt8_t slice = AliHLTTPCDefinitions::GetMinSliceNr(specification);
220 AliHLTUInt8_t partition = AliHLTTPCDefinitions::GetMinPatchNr(specification);
221 if (slice!=AliHLTTPCDefinitions::GetMaxSliceNr(specification) ||
222 partition!=AliHLTTPCDefinitions::GetMaxPatchNr(specification)) {
223 AliError(Form("can not read cluster mc data block with data of multiple partitions, skipping block %s %08x",
224 AliHLTComponent::DataType2Text(dt).c_str(), specification));
225 continue;
226 }
227 const AliHLTTPCClusterMCLabel *labels = clusterMCData->fLabels;
228 for (int i=0; i<nLabels; i++) {
229 AliHLTUInt32_t id=AliHLTTPCSpacePointData::GetID(slice, partition, i);
230 if (tpcClusterLabels.find(id)==tpcClusterLabels.end()) {
231 // new cluster
232 tpcClusterLabels[id]=labels[i];
233 } else {
234 AliError(Form("cluster with ID 0x%08x already existing, skipping cluster %d of data block 0x%08x",
235 id, i, specification));
236 }
237 }
238 } while (pHLTOUT->SelectNextDataBlock()>=0);
239 return iResult;
240}
241
242int AliHLTTPCClusterAccessHLTOUT::ReadAliHLTTPCClusterData(AliHLTOUT* pHLTOUT, TClonesArray* pClusters, const AliHLTTPCClusterMCDataList *tpcClusterLabels) const
c54aa300 243{
244 // read cluster data from AliHLTTPCClusterData
245 int iResult=0;
246 if (!pHLTOUT || !pClusters) return -EINVAL;
247 do {
248 const AliHLTUInt8_t* pBuffer=NULL;
249 AliHLTUInt32_t size=0;
250 if ((iResult=pHLTOUT->GetDataBuffer(pBuffer, size))<0) {
251 continue;
252 }
253 if (pBuffer==NULL || size<4) {
254 AliError("invalid cluster data block");
255 continue;
256 }
81e7f739 257 AliHLTComponentDataType dt=kAliHLTVoidDataType;
258 AliHLTUInt32_t specification=kAliHLTVoidDataSpec;
259 if (pHLTOUT->GetDataBlockDescription(dt, specification)<0) {
260 AliError("failed to retrieve data block description, skipping mc cluster data block ...");
261 continue;
262 }
c54aa300 263 const AliHLTTPCClusterData* clusterData = reinterpret_cast<const AliHLTTPCClusterData*>(pBuffer);
264 Int_t nSpacepoints = (Int_t) clusterData->fSpacePointCnt;
265 if (nSpacepoints*sizeof(AliHLTTPCSpacePointData) + sizeof(AliHLTTPCClusterData) != size) {
266 AliError("inconsistent cluster data block size, skipping block");
267 continue;
268 }
269 const AliHLTTPCSpacePointData *clusters = clusterData->fSpacePoints;
81e7f739 270 int offset=pClusters->GetEntries();
271 pClusters->ExpandCreate(offset+nSpacepoints);
0e63cf4a 272 AliHLTUInt8_t slice = AliHLTTPCDefinitions::GetMinSliceNr(specification);
273 AliHLTUInt8_t partition = AliHLTTPCDefinitions::GetMinPatchNr(specification);
274 // FIXME: get first row number of outer sectors from a common definition instead using number
80874dc5 275 unsigned rowOffset=partition<2?0:63;
c54aa300 276 for (int i=0; i<nSpacepoints; i++) {
81e7f739 277 if (!pClusters->At(offset+i)) continue;
278 AliTPCclusterMI* pCluster=dynamic_cast<AliTPCclusterMI*>(pClusters->At(offset+i));
c54aa300 279 if (!pCluster) {
280 AliError("invalid object type, expecting AliTPCclusterMI");
281 break; // this is a problem of all objects
282 }
0e63cf4a 283 if (clusters[i].fPadRow<rowOffset) {
284 AliError(Form("invalid row number %d, expecting minimum row number %d for slice %d partition %d", clusters[i].fPadRow, rowOffset, slice, partition));
285 } else {
286 pCluster->SetRow(clusters[i].fPadRow-rowOffset);
287 }
81e7f739 288 pCluster->SetPad(clusters[i].fY);
5e75f4e0 289 pCluster->SetTimeBin(clusters[i].fZ);
81e7f739 290 pCluster->SetSigmaY2(clusters[i].fSigmaY2);
291 pCluster->SetSigmaZ2(clusters[i].fSigmaZ2);
c54aa300 292 pCluster->SetQ(clusters[i].fCharge);
293 pCluster->SetMax(clusters[i].fQMax);
81e7f739 294 if (tpcClusterLabels) {
295 if (tpcClusterLabels->find(clusters[i].fID)!=tpcClusterLabels->end()) {
296 const AliHLTTPCClusterMCWeight* mcWeights=tpcClusterLabels->find(clusters[i].fID)->second.fClusterID;
297 for (int k=0; k<3; k++) {
298 // TODO: sort the labels according to the weight in order to assign the most likely mc label
299 // to the first component
300 pCluster->SetLabel(mcWeights[k].fMCID, k);
301 }
302 } else {
303 AliError(Form("can not find mc label of cluster with id %0x08x", clusters[i].fID));
304 }
305 }
c54aa300 306 }
1214ab89 307 if (fVerbosity>0) AliInfo(Form("converted %d cluster(s) from block %s 0x%08x", nSpacepoints, AliHLTComponent::DataType2Text(dt).c_str(), specification));
c54aa300 308 } while (pHLTOUT->SelectNextDataBlock()>=0);
309 return iResult;
310}
5e75f4e0 311
312int AliHLTTPCClusterAccessHLTOUT::ReadAliHLTTPCRawClusterData(AliHLTOUT* pHLTOUT, TClonesArray* pClusters, const AliHLTTPCClusterMCDataList *tpcClusterLabels)
313{
314 // read cluster data from AliHLTTPCClusterData
315
316 // FIXME: this is in large parts like ReadAliHLTTPCClusterData,
317 // make a common method
318 int iResult=0;
319 if (!pHLTOUT || !pClusters) return -EINVAL;
320 do {
321 const AliHLTUInt8_t* pBuffer=NULL;
322 AliHLTUInt32_t size=0;
323 if ((iResult=pHLTOUT->GetDataBuffer(pBuffer, size))<0) {
324 continue;
325 }
326 if (pBuffer==NULL || size<4) {
327 AliError("invalid cluster data block");
328 continue;
329 }
330 AliHLTComponentDataType dt=kAliHLTVoidDataType;
331 AliHLTUInt32_t specification=kAliHLTVoidDataSpec;
332 if (pHLTOUT->GetDataBlockDescription(dt, specification)<0) {
333 AliError("failed to retrieve data block description, skipping mc cluster data block ...");
334 continue;
335 }
336 const AliHLTTPCRawClusterData* clusterData = reinterpret_cast<const AliHLTTPCRawClusterData*>(pBuffer);
337 Int_t nCount = (Int_t) clusterData->fCount;
338 if (nCount*sizeof(AliHLTTPCRawCluster) + sizeof(AliHLTTPCRawClusterData) != size) {
339 AliError("inconsistent cluster data block size, skipping block");
340 continue;
341 }
342 const AliHLTTPCRawCluster *clusters = clusterData->fClusters;
343 int offset=pClusters->GetEntries();
344 pClusters->ExpandCreate(offset+nCount);
0e63cf4a 345 AliHLTUInt8_t slice = AliHLTTPCDefinitions::GetMinSliceNr(specification);
346 AliHLTUInt8_t partition = AliHLTTPCDefinitions::GetMinPatchNr(specification);
347 // FIXME: get first row number of outer sectors from a common definition instead using number
80874dc5 348 int rowOffset=partition<2?0:63;
5e75f4e0 349 for (int i=0; i<nCount; i++) {
350 if (!pClusters->At(offset+i)) continue;
351 AliTPCclusterMI* pCluster=dynamic_cast<AliTPCclusterMI*>(pClusters->At(offset+i));
352 if (!pCluster) {
353 AliError("invalid object type, expecting AliTPCclusterMI");
354 break; // this is a problem of all objects
355 }
1214ab89 356 if (fVerbosity>1) AliInfo(Form("cluster padrow %d (slice %d partition %d)", clusters[i].GetPadRow(), slice, partition));
0e63cf4a 357 if (clusters[i].GetPadRow()<rowOffset) {
358 AliError(Form("invalid row number %d, expecting minimum row number %d for slice %d partition %d", clusters[i].GetPadRow(), rowOffset, slice, partition));
359 } else {
360 pCluster->SetRow(clusters[i].GetPadRow()-rowOffset);
361 }
73db5fa6 362 // using a 0.5 shift, pad coordinate with respect to middle of the pad
363 pCluster->SetPad(clusters[i].GetPad()+0.5);
5e75f4e0 364 pCluster->SetTimeBin(clusters[i].GetTime());
365 pCluster->SetSigmaY2(clusters[i].GetSigmaY2());
366 pCluster->SetSigmaZ2(clusters[i].GetSigmaZ2());
367 pCluster->SetQ(clusters[i].GetCharge());
368 pCluster->SetMax(clusters[i].GetQMax());
369 if (tpcClusterLabels) {
5e75f4e0 370 UInt_t clusterID=AliHLTTPCSpacePointData::GetID(slice, partition, i);
371 if (tpcClusterLabels->find(clusterID)!=tpcClusterLabels->end()) {
372 const AliHLTTPCClusterMCWeight* mcWeights=tpcClusterLabels->find(clusterID)->second.fClusterID;
373 for (int k=0; k<3; k++) {
374 // TODO: sort the labels according to the weight in order to assign the most likely mc label
375 // to the first component
376 pCluster->SetLabel(mcWeights[k].fMCID, k);
377 }
378 } else {
379 AliError(Form("can not find mc label of cluster with id %0x08x", clusterID));
380 }
381 }
382 }
383 if (fVerbosity>0) AliInfo(Form("converted %d cluster(s) from block %s 0x%08x", nCount, AliHLTComponent::DataType2Text(dt).c_str(), specification));
384 } while (pHLTOUT->SelectNextDataBlock()>=0);
385 return iResult;
386}