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