3 //**************************************************************************
4 //* This file is property of and copyright by the ALICE HLT Project *
5 //* ALICE Experiment at CERN, All rights reserved. *
7 //* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
8 //* for The ALICE HLT Project. *
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 //**************************************************************************
19 /// @file AliHLTTPCClusterAccessHLTOUT.h
20 /// @author Matthias Richter
22 /// @brief Interface to HLT TPC clusters
25 #include "AliHLTTPCClusterAccessHLTOUT.h"
26 #include "AliHLTTPCDefinitions.h"
27 #include "AliHLTTPCClusterDataFormat.h"
28 #include "AliHLTTPCRawCluster.h"
29 #include "AliHLTOUT.h"
30 #include "AliHLTComponent.h"
32 #include "AliHLTSystem.h"
33 #include "AliHLTPluginBase.h"
34 #include "AliTPCclusterMI.h"
35 #include "TClonesArray.h"
40 /** ROOT macro for the implementation of ROOT specific class methods */
41 ClassImp(AliHLTTPCClusterAccessHLTOUT)
43 AliHLTTPCClusterAccessHLTOUT::AliHLTTPCClusterAccessHLTOUT()
48 // see header file for class documentation
50 // refer to README to build package
52 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
55 AliHLTTPCClusterAccessHLTOUT::~AliHLTTPCClusterAccessHLTOUT()
65 void AliHLTTPCClusterAccessHLTOUT::Execute(const char *method, const char *params, Int_t *error)
67 /// inherited from TObject: abstract command interface
68 if (strcmp(method, "read")==0) {
69 int iResult=ProcessClusters(params);
70 if (error) *error=iResult;
73 if (strcmp(method, "verbosity")==0) {
77 int value=strtol(params, &dummy, 0);
81 AliError("invalid argument for command 'verbosity', expecting string with number");
86 if (error) *error=iResult;
91 TObject* AliHLTTPCClusterAccessHLTOUT::FindObject(const char *name) const
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);
98 void AliHLTTPCClusterAccessHLTOUT::Clear(Option_t * /*option*/)
100 /// inherited from TObject: cleanup
101 if (fClusters) fClusters->Clear();
104 void AliHLTTPCClusterAccessHLTOUT::Print(Option_t */*option*/) const
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()
122 int AliHLTTPCClusterAccessHLTOUT::ProcessClusters(const char* params)
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
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;
152 fClusters=new TClonesArray("AliTPCclusterMI");
154 if (!fClusters) return -ENOMEM;
156 AliHLTSystem* pSystem=AliHLTPluginBase::GetInstance();
158 AliError("can not access HLT system");
161 AliHLTOUT* pHLTOUT=pSystem->RequestHLTOUT();
163 AliError("can not access HLTOUT");
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);
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);
184 pSystem->ReleaseHLTOUT(pHLTOUT);
188 int AliHLTTPCClusterAccessHLTOUT::ReadAliHLTTPCClusterMCData(AliHLTOUT* pHLTOUT, AliHLTTPCClusterMCDataList &tpcClusterLabels) const
190 // read cluster data from AliHLTTPCClusterData
192 if (!pHLTOUT) return -EINVAL;
194 const AliHLTUInt8_t* pBuffer=NULL;
195 AliHLTUInt32_t size=0;
196 if ((iResult=pHLTOUT->GetDataBuffer(pBuffer, size))<0) {
199 if (pBuffer==NULL || size<4) {
200 AliError("invalid cluster mc data block");
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");
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 ...");
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));
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()) {
229 tpcClusterLabels[id]=labels[i];
231 AliError(Form("cluster with ID 0x%08x already existing, skipping cluster %d of data block 0x%08x",
232 id, i, specification));
235 } while (pHLTOUT->SelectNextDataBlock()>=0);
239 int AliHLTTPCClusterAccessHLTOUT::ReadAliHLTTPCClusterData(AliHLTOUT* pHLTOUT, TClonesArray* pClusters, const AliHLTTPCClusterMCDataList *tpcClusterLabels) const
241 // read cluster data from AliHLTTPCClusterData
243 if (!pHLTOUT || !pClusters) return -EINVAL;
245 const AliHLTUInt8_t* pBuffer=NULL;
246 AliHLTUInt32_t size=0;
247 if ((iResult=pHLTOUT->GetDataBuffer(pBuffer, size))<0) {
250 if (pBuffer==NULL || size<4) {
251 AliError("invalid cluster data block");
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 ...");
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");
266 const AliHLTTPCSpacePointData *clusters = clusterData->fSpacePoints;
267 int offset=pClusters->GetEntries();
268 pClusters->ExpandCreate(offset+nSpacepoints);
269 AliHLTUInt8_t slice = AliHLTTPCDefinitions::GetMinSliceNr(specification);
270 AliHLTUInt8_t partition = AliHLTTPCDefinitions::GetMinPatchNr(specification);
271 // FIXME: get first row number of outer sectors from a common definition instead using number
272 unsigned rowOffset=partition<2?rowOffset=0:rowOffset=63;
273 for (int i=0; i<nSpacepoints; i++) {
274 if (!pClusters->At(offset+i)) continue;
275 AliTPCclusterMI* pCluster=dynamic_cast<AliTPCclusterMI*>(pClusters->At(offset+i));
277 AliError("invalid object type, expecting AliTPCclusterMI");
278 break; // this is a problem of all objects
280 if (clusters[i].fPadRow<rowOffset) {
281 AliError(Form("invalid row number %d, expecting minimum row number %d for slice %d partition %d", clusters[i].fPadRow, rowOffset, slice, partition));
283 pCluster->SetRow(clusters[i].fPadRow-rowOffset);
285 pCluster->SetPad(clusters[i].fY);
286 pCluster->SetTimeBin(clusters[i].fZ);
287 pCluster->SetSigmaY2(clusters[i].fSigmaY2);
288 pCluster->SetSigmaZ2(clusters[i].fSigmaZ2);
289 pCluster->SetQ(clusters[i].fCharge);
290 pCluster->SetMax(clusters[i].fQMax);
291 if (tpcClusterLabels) {
292 if (tpcClusterLabels->find(clusters[i].fID)!=tpcClusterLabels->end()) {
293 const AliHLTTPCClusterMCWeight* mcWeights=tpcClusterLabels->find(clusters[i].fID)->second.fClusterID;
294 for (int k=0; k<3; k++) {
295 // TODO: sort the labels according to the weight in order to assign the most likely mc label
296 // to the first component
297 pCluster->SetLabel(mcWeights[k].fMCID, k);
300 AliError(Form("can not find mc label of cluster with id %0x08x", clusters[i].fID));
304 if (fVerbosity>0) AliInfo(Form("converted %d cluster(s) from block 0x%08x", nSpacepoints, specification));
305 } while (pHLTOUT->SelectNextDataBlock()>=0);
309 int AliHLTTPCClusterAccessHLTOUT::ReadAliHLTTPCRawClusterData(AliHLTOUT* pHLTOUT, TClonesArray* pClusters, const AliHLTTPCClusterMCDataList *tpcClusterLabels)
311 // read cluster data from AliHLTTPCClusterData
313 // FIXME: this is in large parts like ReadAliHLTTPCClusterData,
314 // make a common method
316 if (!pHLTOUT || !pClusters) return -EINVAL;
318 const AliHLTUInt8_t* pBuffer=NULL;
319 AliHLTUInt32_t size=0;
320 if ((iResult=pHLTOUT->GetDataBuffer(pBuffer, size))<0) {
323 if (pBuffer==NULL || size<4) {
324 AliError("invalid cluster data block");
327 AliHLTComponentDataType dt=kAliHLTVoidDataType;
328 AliHLTUInt32_t specification=kAliHLTVoidDataSpec;
329 if (pHLTOUT->GetDataBlockDescription(dt, specification)<0) {
330 AliError("failed to retrieve data block description, skipping mc cluster data block ...");
333 const AliHLTTPCRawClusterData* clusterData = reinterpret_cast<const AliHLTTPCRawClusterData*>(pBuffer);
334 Int_t nCount = (Int_t) clusterData->fCount;
335 if (nCount*sizeof(AliHLTTPCRawCluster) + sizeof(AliHLTTPCRawClusterData) != size) {
336 AliError("inconsistent cluster data block size, skipping block");
339 const AliHLTTPCRawCluster *clusters = clusterData->fClusters;
340 int offset=pClusters->GetEntries();
341 pClusters->ExpandCreate(offset+nCount);
342 AliHLTUInt8_t slice = AliHLTTPCDefinitions::GetMinSliceNr(specification);
343 AliHLTUInt8_t partition = AliHLTTPCDefinitions::GetMinPatchNr(specification);
344 // FIXME: get first row number of outer sectors from a common definition instead using number
345 int rowOffset=partition<2?rowOffset=0:rowOffset=63;
346 for (int i=0; i<nCount; i++) {
347 if (!pClusters->At(offset+i)) continue;
348 AliTPCclusterMI* pCluster=dynamic_cast<AliTPCclusterMI*>(pClusters->At(offset+i));
350 AliError("invalid object type, expecting AliTPCclusterMI");
351 break; // this is a problem of all objects
353 if (clusters[i].GetPadRow()<rowOffset) {
354 AliError(Form("invalid row number %d, expecting minimum row number %d for slice %d partition %d", clusters[i].GetPadRow(), rowOffset, slice, partition));
356 pCluster->SetRow(clusters[i].GetPadRow()-rowOffset);
358 pCluster->SetPad(clusters[i].GetPad());
359 pCluster->SetTimeBin(clusters[i].GetTime());
360 pCluster->SetSigmaY2(clusters[i].GetSigmaY2());
361 pCluster->SetSigmaZ2(clusters[i].GetSigmaZ2());
362 pCluster->SetQ(clusters[i].GetCharge());
363 pCluster->SetMax(clusters[i].GetQMax());
364 if (tpcClusterLabels) {
365 UInt_t clusterID=AliHLTTPCSpacePointData::GetID(slice, partition, i);
366 if (tpcClusterLabels->find(clusterID)!=tpcClusterLabels->end()) {
367 const AliHLTTPCClusterMCWeight* mcWeights=tpcClusterLabels->find(clusterID)->second.fClusterID;
368 for (int k=0; k<3; k++) {
369 // TODO: sort the labels according to the weight in order to assign the most likely mc label
370 // to the first component
371 pCluster->SetLabel(mcWeights[k].fMCID, k);
374 AliError(Form("can not find mc label of cluster with id %0x08x", clusterID));
378 if (fVerbosity>0) AliInfo(Form("converted %d cluster(s) from block %s 0x%08x", nCount, AliHLTComponent::DataType2Text(dt).c_str(), specification));
379 } while (pHLTOUT->SelectNextDataBlock()>=0);