]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/TPCLib/AliHLTTPCClusterAccessHLTOUT.cxx
suppressing warning for missing MC info when running on raw data
[u/mrichter/AliRoot.git] / HLT / TPCLib / AliHLTTPCClusterAccessHLTOUT.cxx
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"
28 #include "AliHLTTPCRawCluster.h"
29 #include "AliHLTOUT.h"
30 #include "AliHLTComponent.h"
31 #include "AliLog.h"
32 #include "AliHLTSystem.h"
33 #include "AliHLTPluginBase.h"
34 #include "AliTPCclusterMI.h"
35 #include "TClonesArray.h"
36 #include <cstdlib>
37 #include <string>
38 #include <memory>
39
40 /** ROOT macro for the implementation of ROOT specific class methods */
41 ClassImp(AliHLTTPCClusterAccessHLTOUT)
42
43 AliHLTTPCClusterAccessHLTOUT::AliHLTTPCClusterAccessHLTOUT()
44   : TObject()
45   , fVerbosity(0)
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
55 AliHLTTPCClusterAccessHLTOUT::~AliHLTTPCClusterAccessHLTOUT()
56 {
57   // destructor
58   if (fClusters) {
59     fClusters->Clear();
60     delete fClusters;
61     fClusters=NULL;
62   }
63 }
64
65 void AliHLTTPCClusterAccessHLTOUT::Execute(const char *method,  const char *params, Int_t *error)
66 {
67   /// inherited from TObject: abstract command interface
68   if (strcmp(method, "read")==0) {
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     }
86     if (error) *error=iResult;
87     return;
88   }
89 }
90
91 TObject* 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
98 void AliHLTTPCClusterAccessHLTOUT::Clear(Option_t * /*option*/)
99 {
100   /// inherited from TObject: cleanup
101   if (fClusters) fClusters->Clear();
102 }
103
104 void 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
122 int AliHLTTPCClusterAccessHLTOUT::ProcessClusters(const char* params)
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;
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
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
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       bool bHaveLabels=false;
173       if (pHLTOUT->SelectFirstDataBlock(AliHLTTPCDefinitions::fgkAliHLTDataTypeClusterMCInfo, spec)>=0) {
174         iResult=ReadAliHLTTPCClusterMCData(pHLTOUT, tpcClusterLabels);
175         bHaveLabels=true;
176       }
177
178       if (pHLTOUT->SelectFirstDataBlock(AliHLTTPCDefinitions::fgkRawClustersDataType, spec)>=0) {
179         iResult=ReadAliHLTTPCRawClusterData(pHLTOUT, fClusters, bHaveLabels?&tpcClusterLabels:NULL);
180       } else if (pHLTOUT->SelectFirstDataBlock(AliHLTTPCDefinitions::fgkClustersDataType, spec)>=0) {
181         iResult=ReadAliHLTTPCClusterData(pHLTOUT, fClusters, bHaveLabels?&tpcClusterLabels:NULL);
182       }
183     }
184   }
185
186   pSystem->ReleaseHLTOUT(pHLTOUT);
187   return iResult;
188 }
189
190 int AliHLTTPCClusterAccessHLTOUT::ReadAliHLTTPCClusterMCData(AliHLTOUT* pHLTOUT, AliHLTTPCClusterMCDataList &tpcClusterLabels) const
191 {
192   // read cluster data from AliHLTTPCClusterData
193   int iResult=0;
194   if (!pHLTOUT) return -EINVAL;
195   do {
196     const AliHLTUInt8_t* pBuffer=NULL;
197     AliHLTUInt32_t size=0;
198     if ((iResult=pHLTOUT->GetDataBuffer(pBuffer, size))<0) {
199       continue;
200     }
201     if (pBuffer==NULL || size<4) {
202       AliError("invalid cluster mc data block");
203       continue;
204     }
205     const AliHLTTPCClusterMCData* clusterMCData = reinterpret_cast<const AliHLTTPCClusterMCData*>(pBuffer);
206     Int_t nLabels = (Int_t) clusterMCData->fCount;
207     if (nLabels*sizeof(AliHLTTPCClusterMCLabel) + sizeof(AliHLTTPCClusterMCData) != size) {
208       AliError("inconsistent cluster mc data block size, skipping block");
209       continue;
210     }
211     // id of the cluster is 
212     AliHLTComponentDataType dt=kAliHLTVoidDataType;
213     AliHLTUInt32_t specification=kAliHLTVoidDataSpec;
214     if (pHLTOUT->GetDataBlockDescription(dt, specification)<0) {
215       AliError("failed to retrieve data block description, skipping mc cluster data block ...");
216       continue;
217     }
218     AliHLTUInt8_t slice = AliHLTTPCDefinitions::GetMinSliceNr(specification);
219     AliHLTUInt8_t partition = AliHLTTPCDefinitions::GetMinPatchNr(specification);
220     if (slice!=AliHLTTPCDefinitions::GetMaxSliceNr(specification) ||
221         partition!=AliHLTTPCDefinitions::GetMaxPatchNr(specification)) {
222       AliError(Form("can not read cluster mc data block with data of multiple partitions, skipping block %s %08x",
223                     AliHLTComponent::DataType2Text(dt).c_str(), specification));
224       continue;
225     }
226     const AliHLTTPCClusterMCLabel *labels = clusterMCData->fLabels;
227     for (int i=0; i<nLabels; i++) {
228       AliHLTUInt32_t id=AliHLTTPCSpacePointData::GetID(slice, partition, i);
229       if (tpcClusterLabels.find(id)==tpcClusterLabels.end()) {
230         // new cluster
231         tpcClusterLabels[id]=labels[i];
232       } else {
233         AliError(Form("cluster with ID 0x%08x already existing, skipping cluster %d of data block 0x%08x",
234                       id, i, specification));
235       }
236     }
237   } while (pHLTOUT->SelectNextDataBlock()>=0);
238   return iResult;
239 }
240
241 int AliHLTTPCClusterAccessHLTOUT::ReadAliHLTTPCClusterData(AliHLTOUT* pHLTOUT, TClonesArray* pClusters, const AliHLTTPCClusterMCDataList *tpcClusterLabels) const
242 {
243   // read cluster data from AliHLTTPCClusterData
244   int iResult=0;
245   if (!pHLTOUT || !pClusters) return -EINVAL;
246   do {
247     const AliHLTUInt8_t* pBuffer=NULL;
248     AliHLTUInt32_t size=0;
249     if ((iResult=pHLTOUT->GetDataBuffer(pBuffer, size))<0) {
250       continue;
251     }
252     if (pBuffer==NULL || size<4) {
253       AliError("invalid cluster data block");
254       continue;
255     }
256     AliHLTComponentDataType dt=kAliHLTVoidDataType;
257     AliHLTUInt32_t specification=kAliHLTVoidDataSpec;
258     if (pHLTOUT->GetDataBlockDescription(dt, specification)<0) {
259       AliError("failed to retrieve data block description, skipping mc cluster data block ...");
260       continue;
261     }
262     const AliHLTTPCClusterData* clusterData = reinterpret_cast<const AliHLTTPCClusterData*>(pBuffer);
263     Int_t nSpacepoints = (Int_t) clusterData->fSpacePointCnt;
264     if (nSpacepoints*sizeof(AliHLTTPCSpacePointData) + sizeof(AliHLTTPCClusterData) != size) {
265       AliError("inconsistent cluster data block size, skipping block");
266       continue;
267     }
268     const AliHLTTPCSpacePointData *clusters = clusterData->fSpacePoints;
269     int offset=pClusters->GetEntries();
270     pClusters->ExpandCreate(offset+nSpacepoints);
271     AliHLTUInt8_t slice = AliHLTTPCDefinitions::GetMinSliceNr(specification);
272     AliHLTUInt8_t partition = AliHLTTPCDefinitions::GetMinPatchNr(specification);
273     // FIXME: get first row number of outer sectors from a common definition instead using number
274     unsigned rowOffset=partition<2?0:63;
275     for (int i=0; i<nSpacepoints; i++) {
276       if (!pClusters->At(offset+i)) continue;
277       AliTPCclusterMI* pCluster=dynamic_cast<AliTPCclusterMI*>(pClusters->At(offset+i));
278       if (!pCluster) {
279         AliError("invalid object type, expecting AliTPCclusterMI");
280         break; // this is a problem of all objects
281       }
282       if (clusters[i].fPadRow<rowOffset) {
283         AliError(Form("invalid row number %d, expecting minimum row number %d for slice %d partition %d", clusters[i].fPadRow, rowOffset, slice, partition));
284       } else {
285       pCluster->SetRow(clusters[i].fPadRow-rowOffset);
286       }
287       pCluster->SetPad(clusters[i].fY);
288       pCluster->SetTimeBin(clusters[i].fZ);
289       pCluster->SetSigmaY2(clusters[i].fSigmaY2);
290       pCluster->SetSigmaZ2(clusters[i].fSigmaZ2);
291       pCluster->SetQ(clusters[i].fCharge);
292       pCluster->SetMax(clusters[i].fQMax);
293       if (tpcClusterLabels) {
294         if (tpcClusterLabels->find(clusters[i].fID)!=tpcClusterLabels->end()) {
295           const AliHLTTPCClusterMCWeight* mcWeights=tpcClusterLabels->find(clusters[i].fID)->second.fClusterID;
296           for (int k=0; k<3; k++) {
297             // TODO: sort the labels according to the weight in order to assign the most likely mc label
298             // to the first component 
299             pCluster->SetLabel(mcWeights[k].fMCID, k);
300           }
301         } else {
302           AliError(Form("can not find mc label of cluster with id %0x08x", clusters[i].fID));
303         }
304       }
305     }
306     if (fVerbosity>0) AliInfo(Form("converted %d cluster(s) from block %s 0x%08x", nSpacepoints, AliHLTComponent::DataType2Text(dt).c_str(), specification));
307   } while (pHLTOUT->SelectNextDataBlock()>=0);
308   return iResult;
309 }
310
311 int AliHLTTPCClusterAccessHLTOUT::ReadAliHLTTPCRawClusterData(AliHLTOUT* pHLTOUT, TClonesArray* pClusters, const AliHLTTPCClusterMCDataList *tpcClusterLabels)
312 {
313   // read cluster data from AliHLTTPCClusterData
314
315   // FIXME: this is in large parts like ReadAliHLTTPCClusterData,
316   // make a common method
317   int iResult=0;
318   if (!pHLTOUT || !pClusters) return -EINVAL;
319   do {
320     const AliHLTUInt8_t* pBuffer=NULL;
321     AliHLTUInt32_t size=0;
322     if ((iResult=pHLTOUT->GetDataBuffer(pBuffer, size))<0) {
323       continue;
324     }
325     if (pBuffer==NULL || size<4) {
326       AliError("invalid cluster data block");
327       continue;
328     }
329     AliHLTComponentDataType dt=kAliHLTVoidDataType;
330     AliHLTUInt32_t specification=kAliHLTVoidDataSpec;
331     if (pHLTOUT->GetDataBlockDescription(dt, specification)<0) {
332       AliError("failed to retrieve data block description, skipping mc cluster data block ...");
333       continue;
334     }
335     const AliHLTTPCRawClusterData* clusterData = reinterpret_cast<const AliHLTTPCRawClusterData*>(pBuffer);
336     Int_t nCount = (Int_t) clusterData->fCount;
337     if (nCount*sizeof(AliHLTTPCRawCluster) + sizeof(AliHLTTPCRawClusterData) != size) {
338       AliError("inconsistent cluster data block size, skipping block");
339       continue;
340     }
341     const AliHLTTPCRawCluster *clusters = clusterData->fClusters;
342     int offset=pClusters->GetEntries();
343     pClusters->ExpandCreate(offset+nCount);
344     AliHLTUInt8_t slice = AliHLTTPCDefinitions::GetMinSliceNr(specification);
345     AliHLTUInt8_t partition = AliHLTTPCDefinitions::GetMinPatchNr(specification);
346     // FIXME: get first row number of outer sectors from a common definition instead using number
347     int rowOffset=partition<2?0:63;
348     for (int i=0; i<nCount; i++) {
349       if (!pClusters->At(offset+i)) continue;
350       AliTPCclusterMI* pCluster=dynamic_cast<AliTPCclusterMI*>(pClusters->At(offset+i));
351       if (!pCluster) {
352         AliError("invalid object type, expecting AliTPCclusterMI");
353         break; // this is a problem of all objects
354       }
355       if (fVerbosity>1) AliInfo(Form("cluster padrow %d (slice %d partition %d)", clusters[i].GetPadRow(), slice, partition));
356       if (clusters[i].GetPadRow()<rowOffset) {
357         AliError(Form("invalid row number %d, expecting minimum row number %d for slice %d partition %d", clusters[i].GetPadRow(), rowOffset, slice, partition));
358       } else {
359       pCluster->SetRow(clusters[i].GetPadRow()-rowOffset);
360       }
361       pCluster->SetPad(clusters[i].GetPad());
362       pCluster->SetTimeBin(clusters[i].GetTime());
363       pCluster->SetSigmaY2(clusters[i].GetSigmaY2());
364       pCluster->SetSigmaZ2(clusters[i].GetSigmaZ2());
365       pCluster->SetQ(clusters[i].GetCharge());
366       pCluster->SetMax(clusters[i].GetQMax());
367       if (tpcClusterLabels) {
368         UInt_t clusterID=AliHLTTPCSpacePointData::GetID(slice, partition, i);
369         if (tpcClusterLabels->find(clusterID)!=tpcClusterLabels->end()) {
370           const AliHLTTPCClusterMCWeight* mcWeights=tpcClusterLabels->find(clusterID)->second.fClusterID;
371           for (int k=0; k<3; k++) {
372             // TODO: sort the labels according to the weight in order to assign the most likely mc label
373             // to the first component 
374             pCluster->SetLabel(mcWeights[k].fMCID, k);
375           }
376         } else {
377           AliError(Form("can not find mc label of cluster with id %0x08x", clusterID));
378         }
379       }
380     }
381     if (fVerbosity>0) AliInfo(Form("converted %d cluster(s) from block %s 0x%08x", nCount, AliHLTComponent::DataType2Text(dt).c_str(), specification));
382   } while (pHLTOUT->SelectNextDataBlock()>=0);
383   return iResult;
384 }