Line data Source code
1 : // $Id$
2 :
3 : //**************************************************************************
4 : //* This file is property of and copyright by the ALICE 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 "AliHLTTPCDataCompressionDecoder.h"
27 : #include "AliHLTTPCDefinitions.h"
28 : #include "AliHLTTPCClusterDataFormat.h"
29 : #include "AliHLTTPCRawCluster.h"
30 : #include "AliHLTTPCGeometry.h"
31 : #include "AliHLTOUT.h"
32 : #include "AliHLTComponent.h"
33 : #include "AliHLTErrorGuard.h"
34 : #include "AliHLTDataInflater.h"
35 : #include "AliLog.h"
36 : #include "AliHLTSystem.h"
37 : #include "AliHLTPluginBase.h"
38 : #include "AliTPCclusterMI.h"
39 : #include "AliTPCClustersRow.h"
40 : #include "AliTPCParam.h"
41 : #include "TClonesArray.h"
42 : #include "TString.h"
43 : #include <cstdlib>
44 : #include <string>
45 : #include <memory>
46 : #include <iostream>
47 : #include <iomanip>
48 :
49 : /** ROOT macro for the implementation of ROOT specific class methods */
50 6 : ClassImp(AliHLTTPCClusterAccessHLTOUT)
51 :
52 : AliHLTTPCClusterAccessHLTOUT::AliHLTTPCClusterAccessHLTOUT()
53 0 : : TObject()
54 0 : , fVerbosity(0)
55 0 : , fClusters(NULL)
56 0 : , fCurrentSector(-1)
57 0 : , fCurrentRow(-1)
58 0 : , fPropagateSplitClusterFlag(0)
59 0 : , fpDecoder(NULL)
60 0 : , fTPCParam(NULL)
61 0 : {
62 : // see header file for class documentation
63 : // or
64 : // refer to README to build package
65 : // or
66 : // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
67 0 : }
68 :
69 : AliHLTTPCClusterAccessHLTOUT::~AliHLTTPCClusterAccessHLTOUT()
70 0 : {
71 : // destructor
72 0 : if (fClusters) {
73 0 : fClusters->Clear();
74 0 : delete fClusters;
75 0 : fClusters=NULL;
76 0 : }
77 0 : if (fpDecoder) {
78 0 : fpDecoder->Clear();
79 0 : delete fpDecoder;
80 0 : fpDecoder=NULL;
81 0 : }
82 0 : if (fTPCParam) {
83 : // FIXME: a copy of the TPCParam object is not possible because there is
84 : // no appropriate copy constructor or assignment operator, using as
85 : // external pointer
86 : //delete fTPCParam;
87 0 : fTPCParam=NULL;
88 0 : }
89 0 : }
90 :
91 : void AliHLTTPCClusterAccessHLTOUT::Execute(const char *method, const char *params, Int_t *error)
92 : {
93 : /// inherited from TObject: abstract command interface
94 0 : if (strcmp(method, "read")==0) {
95 0 : int iResult=ProcessClusters(params);
96 0 : if (error) *error=iResult;
97 : return;
98 : }
99 0 : if (strcmp(method, "prepare_copy")==0) {
100 0 : int iResult=ScanParameters(params);
101 0 : if (error) *error=iResult;
102 : return;
103 : }
104 0 : if (strcmp(method, "verbosity")==0) {
105 : int iResult=0;
106 0 : if (params) {
107 0 : char* dummy;
108 0 : int value=strtol(params, &dummy, 0);
109 0 : if (dummy==NULL) {
110 0 : fVerbosity=value;
111 0 : } else {
112 0 : AliError("invalid argument for command 'verbosity', expecting string with number");
113 : }
114 0 : } else {
115 : iResult=-EINVAL;
116 : }
117 0 : if (error) *error=iResult;
118 : return;
119 : }
120 0 : }
121 :
122 : TObject* AliHLTTPCClusterAccessHLTOUT::FindObject(const char *name) const
123 : {
124 : /// inherited from TObject: return the cluster array if name id "clusterarray"
125 0 : if (strcmp(name, "clusterarray")==0) {
126 0 : if (fCurrentSector<0) return NULL;
127 0 : return fClusters->GetSectorArray(fCurrentSector, fPropagateSplitClusterFlag);
128 : }
129 0 : return TObject::FindObject(name);
130 0 : }
131 :
132 : void AliHLTTPCClusterAccessHLTOUT::Copy(TObject &object) const
133 : {
134 : /// inherited from TObject: supports writing of data to AliTPCClustersRow
135 0 : AliTPCClustersRow* rowcl=dynamic_cast<AliTPCClustersRow*>(&object);
136 0 : if (rowcl) {
137 0 : fClusters->FillSectorArray(rowcl->GetArray(), fCurrentSector, fCurrentRow, fPropagateSplitClusterFlag);
138 0 : return;
139 : }
140 0 : return TObject::Copy(object);
141 0 : }
142 :
143 :
144 : void AliHLTTPCClusterAccessHLTOUT::Clear(Option_t * option)
145 : {
146 : /// inherited from TObject: cleanup
147 0 : if (fClusters) fClusters->Clear(option);
148 0 : fCurrentSector=-1;
149 0 : fCurrentRow=-1;
150 0 : }
151 :
152 : void AliHLTTPCClusterAccessHLTOUT::Print(Option_t *option) const
153 : {
154 : /// inherited from TObject
155 0 : if (fClusters) fClusters->Print(option);
156 0 : }
157 :
158 : int AliHLTTPCClusterAccessHLTOUT::ScanParameters(const char* params)
159 : {
160 0 : TString strparams(params);
161 : int sector=-1;
162 : int row=-1;
163 0 : fCurrentSector=-1;
164 0 : fCurrentRow=-1;
165 0 : std::auto_ptr<TObjArray> tokens(strparams.Tokenize(" "));
166 0 : if (!tokens.get()) return -ENOMEM;
167 0 : for (int i=0; i< tokens->GetEntriesFast(); i++) {
168 0 : if (!tokens->At(i)) continue;
169 0 : TString argument=tokens->At(i)->GetName();
170 : // the offline code enumerates first the 36 inner (partitions 0+1) and then 36 outer
171 : // sectors (partitions 2-5)
172 0 : if (argument.BeginsWith("sector=")) {
173 0 : argument.ReplaceAll("sector=", "");
174 0 : sector=argument.Atoi();
175 0 : }
176 0 : if (argument.BeginsWith("row=")) {
177 0 : argument.ReplaceAll("row=", "");
178 0 : row=argument.Atoi();
179 0 : }
180 0 : }
181 0 : if (sector<0) {
182 0 : AliError("invalid argument, please specify \"sector=sectorno\"");
183 0 : return -EINVAL;
184 : }
185 0 : if (sector>=72) {
186 0 : AliError(Form("invalid sector number %d", sector));
187 0 : return -EINVAL;
188 : }
189 :
190 0 : fCurrentSector=sector;
191 0 : fCurrentRow=row;
192 :
193 0 : return 0;
194 0 : }
195 :
196 : int AliHLTTPCClusterAccessHLTOUT::ProcessClusters(const char* params)
197 : {
198 : /// process the cluster data from HLTOUT and fill array
199 : /// the cluster data can be in many different formats, e.g.
200 : /// raw or compressed
201 : int iResult=0;
202 0 : iResult = ScanParameters(params);
203 0 : if (iResult<0) return iResult;
204 :
205 0 : if (!fClusters) {
206 0 : fClusters=new AliRawClusterContainer;
207 0 : }
208 0 : if (!fClusters) return -ENOMEM;
209 :
210 0 : if (fClusters->HaveData()) {
211 : // cluster container already filled
212 : // TObjArray* pArray=fClusters->GetSectorArray(fCurrentSector, fPropagateSplitClusterFlag);
213 : // if (!pArray) {
214 : // AliError(Form("can not get cluster array for sector %d", sector));
215 : // return -ENOBUFS;
216 : // }
217 : // if (fVerbosity>0) AliInfo(Form("converted %d cluster(s) for sector %d", pArray->GetEntriesFast() ,sector));
218 0 : return 0; //pArray->GetEntriesFast();
219 : }
220 :
221 : // fill the cluster container
222 0 : AliHLTSystem* pSystem=AliHLTPluginBase::GetInstance();
223 0 : if (!pSystem) {
224 0 : AliError("can not access HLT system");
225 0 : return -ENODEV;
226 : }
227 0 : AliHLTOUT* pHLTOUT=pSystem->RequestHLTOUT();
228 0 : if (!pHLTOUT) {
229 0 : AliError("can not access HLTOUT");
230 0 : return -EACCES;
231 : }
232 :
233 0 : if (!fpDecoder) {
234 0 : fpDecoder=new AliHLTTPCDataCompressionDecoder;
235 :
236 : //Also load config objects together with fpDecoder
237 0 : TString cdbPath("HLT/ConfigTPC/TPCClusterAccessHLTOUT");
238 0 : TObject* pConf=AliHLTMisc::Instance().ExtractObject(AliHLTMisc::Instance().LoadOCDBEntry(cdbPath));
239 0 : if (pConf)
240 : {
241 0 : TObjString* pStr = dynamic_cast<TObjString*>(pConf);
242 0 : if (pStr)
243 : {
244 0 : if (pStr->GetString().Contains("-propagate-split-cluster-flag")) fPropagateSplitClusterFlag = 1;
245 : }
246 0 : }
247 0 : }
248 :
249 0 : if (!fpDecoder) {
250 0 : AliError("failed to create decoder instance");
251 0 : return -ENODEV;
252 : }
253 :
254 : AliHLTTPCDataCompressionDecoder& decoder=*fpDecoder;
255 0 : decoder.Clear();
256 0 : decoder.SetVerbosity(fVerbosity);
257 :
258 : bool bHavePartitionRawData=false;
259 : bool bHavePartitionCompressedData=false;
260 :
261 : bool bNextBlock=false;
262 : // add cluster id and mc information data blocks
263 0 : for (bNextBlock=(pHLTOUT->SelectFirstDataBlock()>=0);
264 0 : bNextBlock; bNextBlock=(pHLTOUT->SelectNextDataBlock()>=0)) {
265 0 : AliHLTComponentBlockData desc;
266 : // FIXME: extend HLTOUT to get the full descriptor
267 0 : const AliHLTUInt8_t* buffer=NULL;
268 0 : if ((iResult=pHLTOUT->GetDataBuffer(buffer, desc.fSize))<0) {
269 0 : continue;
270 : }
271 0 : desc.fPtr=(void*)buffer;
272 0 : if (pHLTOUT->GetDataBlockDescription(desc.fDataType, desc.fSpecification)<0) {
273 0 : continue;
274 : }
275 0 : if (desc.fDataType==AliHLTTPCDefinitions::RawClustersDescriptorDataType()) {
276 : // header
277 0 : if ((iResult=decoder.AddRawClustersDescriptor(&desc))<0) {
278 0 : return iResult;
279 : }
280 : bHavePartitionRawData = kTRUE;
281 0 : }
282 : //CompressionDescriptor should have priority over rawcluster descriptor in case both are present, because this describes the actual compressed data.
283 0 : if (desc.fDataType==AliHLTTPCDefinitions::DataCompressionDescriptorDataType()) {
284 : // header
285 0 : if ((iResult=decoder.AddCompressionDescriptor(&desc))<0) {
286 0 : return iResult;
287 : }
288 : bHavePartitionCompressedData = kTRUE;
289 0 : }
290 0 : if (desc.fDataType==AliHLTTPCDefinitions::AliHLTDataTypeClusterMCInfo()) {
291 : // add mc information
292 0 : if ((iResult=decoder.AddClusterMCData(&desc))<0) {
293 0 : return iResult;
294 : }
295 : }
296 0 : if (desc.fDataType==AliHLTTPCDefinitions::RemainingClusterIdsDataType() ||
297 0 : desc.fDataType==AliHLTTPCDefinitions::ClusterIdTracksDataType()) {
298 : // add cluster ids
299 0 : if ((iResult=decoder.AddClusterIds(&desc))<0) {
300 0 : return iResult;
301 : }
302 : }
303 0 : if (desc.fDataType==AliHLTTPCDefinitions::ClustersFlagsDataType()) {
304 : // add cluster flag information
305 0 : if ((iResult=decoder.AddClusterFlags(&desc))<0) {
306 0 : return iResult;
307 : }
308 : }
309 0 : }
310 :
311 0 : vector<bool> bHavePartitionData(216, false);
312 :
313 : // read data
314 : iResult=-ENODATA;
315 : int nExtractedClusters=0;
316 0 : for (bNextBlock=(pHLTOUT->SelectFirstDataBlock()>=0);
317 0 : bNextBlock; bNextBlock=(pHLTOUT->SelectNextDataBlock()>=0)) {
318 0 : decoder.SetPadShift(0.0);
319 0 : AliHLTComponentBlockData desc;
320 : // FIXME: extend HLTOUT to get the full descriptor with one call
321 0 : const AliHLTUInt8_t* buffer=NULL;
322 0 : if ((iResult=pHLTOUT->GetDataBuffer(buffer, desc.fSize))<0) {
323 0 : continue;
324 : }
325 0 : desc.fPtr=(void*)buffer;
326 0 : if (pHLTOUT->GetDataBlockDescription(desc.fDataType, desc.fSpecification)<0) {
327 0 : continue;
328 : }
329 0 : if (!TestBit(kSkipPartitionClusters) &&
330 0 : (desc.fDataType==AliHLTTPCDefinitions::RawClustersDataType())) {
331 : // This is a special handling of data blocks produced with v5-01-Release
332 : // The pad shift by 0.5 was not included in the data but was applied in the
333 : // unpacking in this class. Changed in r51306, the next tag containing this
334 : // change in the online system is v5-01-Rev-07. There are only very few runs
335 : // of Sep 2011 with recorded clusters not containing the 0.5 shift
336 : // There was also a change in the data type of the compressed partition
337 : // cluster blocks which helps to identify the blocks which need the pad shift
338 : // here
339 0 : if (desc.fSize<sizeof(AliHLTTPCRawClusterData)) continue;
340 0 : const AliHLTTPCRawClusterData* clusterData = reinterpret_cast<const AliHLTTPCRawClusterData*>(buffer);
341 0 : if (!clusterData) continue;
342 0 : if (clusterData->fVersion==1) {
343 : // compressed clusters without the pad shift
344 : // no raw clusters (version==0) have ever been recorded
345 0 : decoder.SetPadShift(0.5);
346 0 : }
347 0 : AliHLTUInt8_t slice = AliHLTTPCDefinitions::GetMinSliceNr(desc.fSpecification);
348 0 : AliHLTUInt8_t partition = AliHLTTPCDefinitions::GetMinPatchNr(desc.fSpecification);
349 0 : if (slice!=AliHLTTPCDefinitions::GetMaxSliceNr(desc.fSpecification) ||
350 0 : partition!=AliHLTTPCDefinitions::GetMaxPatchNr(desc.fSpecification)) {
351 0 : AliFatal(Form("inconsistent cluster data: can not handle blocks containing multiple partitions, "
352 : "block specification 0x%08x", desc.fSpecification));
353 : }
354 0 : iResult=decoder.ReadClustersPartition(fClusters->BeginRemainingClusterBlock(0, desc.fSpecification),
355 0 : reinterpret_cast<AliHLTUInt8_t*>(desc.fPtr),
356 0 : desc.fSize,
357 0 : desc.fSpecification);
358 0 : if (iResult>=0) nExtractedClusters+=iResult;
359 : else {
360 0 : AliFatal(Form("processing of cluster block 0x%08x failed with error code %d", desc.fSpecification, iResult));
361 : }
362 0 : unsigned index=slice*AliHLTTPCGeometry::GetNumberOfPatches()+partition;
363 0 : if (index>=bHavePartitionData.size()) bHavePartitionData.resize(index, false);
364 0 : if (bHavePartitionData[index]) {
365 0 : AliFatal(Form("inconsistent cluster data: multiple data blocks of identical specification indicate a failure "
366 : "in the production of the data. Probably an HLT emulation chain is executed in the reconstruction "
367 : "and produces data in addition to HLTOUT. Option 'ignore-hltout' is required in that case; "
368 : "block specification 0x%08x", desc.fSpecification));
369 : }
370 0 : bHavePartitionData[index]=true;
371 0 : if (bHavePartitionCompressedData) {
372 0 : AliFatal(Form("inconsistent cluster data: both compressed and raw cluster blocks present in HLTOUT, indicates a failure "
373 : "in the production of the data. Probably an HLT emulation chain is executed in the reconstruction "
374 : "and produces data in addition to HLTOUT. Option 'ignore-hltout' is required in that case; "
375 : "block specification 0x%08x", desc.fSpecification));
376 : }
377 : bHavePartitionRawData=true;
378 : continue;
379 0 : } else if (!TestBit(kSkipPartitionClusters) &&
380 0 : (desc.fDataType==AliHLTTPCDefinitions::RemainingClustersCompressedDataType())) {
381 0 : AliHLTUInt8_t slice = AliHLTTPCDefinitions::GetMinSliceNr(desc.fSpecification);
382 0 : AliHLTUInt8_t partition = AliHLTTPCDefinitions::GetMinPatchNr(desc.fSpecification);
383 0 : if (slice!=AliHLTTPCDefinitions::GetMaxSliceNr(desc.fSpecification) ||
384 0 : partition!=AliHLTTPCDefinitions::GetMaxPatchNr(desc.fSpecification)) {
385 0 : AliFatal(Form("inconsistent cluster data: can not handle blocks containing multiple partitions, "
386 : "block specification 0x%08x", desc.fSpecification));
387 : }
388 0 : iResult=decoder.ReadClustersPartition(fClusters->BeginRemainingClusterBlock(0, desc.fSpecification),
389 0 : reinterpret_cast<AliHLTUInt8_t*>(desc.fPtr),
390 0 : desc.fSize,
391 0 : desc.fSpecification);
392 0 : if (iResult>0) nExtractedClusters+=iResult;
393 0 : unsigned index=slice*AliHLTTPCGeometry::GetNumberOfPatches()+partition;
394 0 : if (index>=bHavePartitionData.size()) bHavePartitionData.resize(index, false);
395 0 : if (bHavePartitionData[index]) {
396 0 : AliFatal(Form("inconsistent cluster data: multiple data blocks of identical specification indicate a failure "
397 : "in the production of the data. Probably an HLT emulation chain is executed in the reconstruction "
398 : "and produces data in addition to HLTOUT. Option 'ignore-hltout' is required in that case; "
399 : "block specification 0x%08x", desc.fSpecification));
400 : }
401 0 : bHavePartitionData[index]=true;
402 0 : bHavePartitionData[index]=true;
403 0 : if (bHavePartitionRawData) {
404 0 : AliFatal(Form("inconsistent cluster data: both compressed and raw cluster blocks present in HLTOUT, indicates a failure "
405 : "in the production of the data. Probably an HLT emulation chain is executed in the reconstruction "
406 : "and produces data in addition to HLTOUT. Option 'ignore-hltout' is required in that case; "
407 : "block specification 0x%08x", desc.fSpecification));
408 : }
409 : bHavePartitionCompressedData=true;
410 : continue;
411 0 : } else if (!TestBit(kSkipTrackClusters) &&
412 0 : desc.fDataType==AliHLTTPCDefinitions::ClusterTracksCompressedDataType()) {
413 0 : iResult=decoder.ReadTrackModelClustersCompressed(fClusters->BeginTrackModelClusterBlock(0),
414 0 : reinterpret_cast<AliHLTUInt8_t*>(desc.fPtr),
415 0 : desc.fSize,
416 0 : desc.fSpecification);
417 0 : continue;
418 : }
419 0 : }
420 :
421 0 : pSystem->ReleaseHLTOUT(pHLTOUT);
422 :
423 0 : if (iResult<0) return iResult;
424 : // if (fVerbosity>0) {
425 : // int nConvertedClusters=0;
426 : // for (int s=0; s<72; s++) {
427 : // TObjArray* pArray=fClusters->GetSectorArray(s, fPropagateSplitClusterFlag);
428 : // if (!pArray) continue;
429 : // nConvertedClusters+=pArray->GetEntriesFast();
430 : // }
431 : // AliInfo(Form("extracted HLT clusters: %d, converted HLT clusters: %d", nExtractedClusters, nConvertedClusters));
432 : // }
433 :
434 0 : fClusters->MarkValid();
435 : // TObjArray* pArray=fClusters->GetSectorArray(fCurrentSector, fPropagateSplitClusterFlag);
436 : // if (!pArray) {
437 : // AliError(Form("can not get cluster array for sector %d", sector));
438 : // return -ENOBUFS;
439 : // }
440 : // if (fVerbosity>0) AliInfo(Form("converted %d cluster(s) for sector %d", pArray->GetEntriesFast() ,sector));
441 0 : return 0; //pArray->GetEntriesFast();
442 0 : }
443 :
444 : AliHLTTPCClusterAccessHLTOUT::AliRawClusterContainer::AliRawClusterContainer()
445 0 : : fClusterMaps()
446 0 : , fSectorArray(new TClonesArray(AliTPCclusterMI::Class()))
447 0 : , fIterator()
448 0 : , fHaveData(false)
449 0 : {
450 : /// constructor
451 0 : for (int i=0; i<72; i++) {
452 0 : fClusterMaps.push_back(new AliRawClusterEntryVector);
453 0 : fClusterMaps.back()->reserve(30000);
454 : }
455 0 : }
456 :
457 : AliHLTTPCClusterAccessHLTOUT::AliRawClusterContainer::~AliRawClusterContainer()
458 0 : {
459 : /// dectructor
460 : {
461 0 : for (vector<AliRawClusterEntryVector*>::iterator i=fClusterMaps.begin(); i!=fClusterMaps.end(); i++) {
462 0 : if (*i) {
463 0 : delete *i;
464 : }
465 : }
466 : }
467 0 : if (fSectorArray) {
468 0 : fSectorArray->Clear();
469 0 : delete fSectorArray;
470 0 : fSectorArray=NULL;
471 0 : }
472 0 : }
473 :
474 : AliHLTTPCClusterAccessHLTOUT::AliRawClusterContainer::iterator& AliHLTTPCClusterAccessHLTOUT::AliRawClusterContainer::BeginPartitionClusterBlock(int count, AliHLTUInt32_t specification)
475 : {
476 : /// iterator of remaining clusters block of specification
477 :
478 : // reserve space in the array of all clusters
479 : // reserve space in the map of the partition
480 0 : unsigned index=AliHLTTPCDefinitions::GetMinSliceNr(specification);
481 0 : AliHLTUInt8_t partition=AliHLTTPCDefinitions::GetMinPatchNr(specification);
482 0 : if (partition>=2) index+=36;
483 0 : if (index<fClusterMaps.size() &&
484 0 : fClusterMaps[index]!=NULL &&
485 0 : fClusterMaps[index]->size()+count>fClusterMaps[index]->capacity()) {
486 0 : fClusterMaps[index]->reserve(fClusterMaps[index]->size()+count);
487 0 : }
488 :
489 0 : fIterator=iterator(this);
490 0 : return fIterator;
491 : }
492 :
493 : AliHLTTPCClusterAccessHLTOUT::AliRawClusterContainer::iterator& AliHLTTPCClusterAccessHLTOUT::AliRawClusterContainer::BeginTrackModelClusterBlock(int /*count*/)
494 : {
495 : /// iterator of track model clusters
496 0 : fIterator=iterator(this);
497 0 : return fIterator;
498 : }
499 :
500 : AliHLTTPCClusterAccessHLTOUT::AliRawClusterEntry* AliHLTTPCClusterAccessHLTOUT::AliRawClusterContainer::NextCluster(int slice, int partition)
501 : {
502 : /// load next cluster from array of the sepcific sector
503 0 : unsigned sector=partition<2?slice:slice+36;
504 0 : if (fClusterMaps.size()<=sector ||
505 0 : fClusterMaps[sector]==NULL) {
506 0 : AliErrorClass(Form("no cluster array available for sector %d", sector));
507 0 : return NULL;
508 : }
509 0 : AliRawClusterEntryVector& map=*(fClusterMaps[sector]);
510 0 : map.push_back(AliRawClusterEntry());
511 0 : return &map.back();
512 0 : }
513 :
514 : void AliHLTTPCClusterAccessHLTOUT::AliRawClusterContainer::Clear(Option_t* option)
515 : {
516 : /// internal cleanup
517 0 : if (strcmp(option, "event")==0) {
518 0 : for (vector<AliRawClusterEntryVector*>::iterator i=fClusterMaps.begin(); i!=fClusterMaps.end(); i++)
519 0 : if (*i) (*i)->clear();
520 0 : if (fSectorArray) fSectorArray->Clear("C");
521 0 : fHaveData=false;
522 0 : }
523 0 : if (strcmp(option, "sector")==0) {
524 0 : if (fSectorArray) fSectorArray->Clear("C");
525 : }
526 0 : }
527 :
528 : TObjArray* AliHLTTPCClusterAccessHLTOUT::AliRawClusterContainer::GetSectorArray(unsigned sector, int propagateSplitClusterFlag) const
529 : {
530 : /// get the cluster array for a sector
531 0 : if (fClusterMaps.size()<=sector) return NULL;
532 0 : if (fSectorArray &&
533 0 : FillSectorArray(fSectorArray, sector, -1, propagateSplitClusterFlag)<0) {
534 0 : fSectorArray->Clear();
535 0 : }
536 0 : return fSectorArray;
537 0 : }
538 :
539 : int AliHLTTPCClusterAccessHLTOUT::AliRawClusterContainer::FillSectorArray(TClonesArray* pSectorArray, unsigned sector, int row, int propagateSplitClusterFlag) const
540 : {
541 : /// fill the cluster array for a sector and specific row if specified
542 0 : if (!pSectorArray) return -EINVAL;
543 0 : if (fClusterMaps.size()<=sector) return -ERANGE;
544 0 : pSectorArray->Clear();
545 :
546 0 : AliRawClusterEntryVector& map=*fClusterMaps[sector];
547 : unsigned nFilled=0;
548 0 : for (unsigned i=0; i<map.size(); i++) {
549 0 : if (row>=0 && map[i].fCluster.GetPadRow()!=row) continue;
550 0 : AliTPCclusterMI* pCluster=new ((*pSectorArray)[nFilled]) AliTPCclusterMI;
551 0 : if (!pCluster) break;
552 :
553 0 : pCluster->SetRow(map[i].fCluster.GetPadRow());
554 0 : pCluster->SetPad(map[i].fCluster.GetPad());
555 0 : pCluster->SetTimeBin(map[i].fCluster.GetTime());
556 0 : pCluster->SetSigmaY2(map[i].fCluster.GetSigmaPad2());
557 0 : pCluster->SetSigmaZ2(map[i].fCluster.GetSigmaTime2());
558 0 : pCluster->SetQ(map[i].fCluster.GetCharge());
559 0 : pCluster->SetMax(map[i].fCluster.GetQMax());
560 0 : if (propagateSplitClusterFlag)
561 : {
562 0 : pCluster->SetType((int) map[i].fCluster.GetFlagSplitPad() + ((int) map[i].fCluster.GetFlagSplitTime() << 1));
563 0 : }
564 :
565 0 : for (int k=0; k<3; k++) {
566 : // TODO: sort the labels according to the weight in order to assign the most likely mc label
567 : // to the first component
568 0 : pCluster->SetLabel(map[i].fMC.fClusterID[k].fMCID, k);
569 : }
570 0 : nFilled++;
571 0 : }
572 :
573 : return 0;
574 0 : }
575 :
576 : void AliHLTTPCClusterAccessHLTOUT::AliRawClusterContainer::Print(Option_t *option) const
577 : {
578 : /// inherited from TObject
579 0 : cout << "AliHLTTPCClusterAccessHLTOUT::AliRawClusterContainer" << endl;
580 0 : ios::fmtflags coutflags=cout.flags(); // backup cout status flags
581 : bool bAll=false;
582 0 : if ((bAll=(strcmp(option, "full")==0)) ||
583 0 : strcmp(option, "short")==0) {
584 0 : for (unsigned iArray=0; iArray<fClusterMaps.size(); iArray++) {
585 0 : if (fClusterMaps[iArray]) {
586 0 : AliRawClusterEntryVector& map=*fClusterMaps[iArray];
587 0 : cout << " sector " << setfill(' ') << setw(2) << iArray << ": " << map.size() << endl;
588 0 : if (bAll) {
589 0 : for (unsigned iCluster=0; iCluster<map.size(); iCluster++) {
590 0 : AliHLTTPCRawCluster &cluster = map[iCluster].fCluster;
591 0 : cout << " AliTPCclusterMI:"
592 0 : << " row=" << cluster.GetPadRow()
593 0 : << " pad=" << cluster.GetPad()
594 0 : << " time=" << cluster.GetTime()
595 0 : << " charge=" << cluster.GetCharge()
596 0 : << " maxq=" << cluster.GetQMax()
597 0 : << endl;
598 : }
599 0 : }
600 0 : }
601 : }
602 0 : }
603 0 : cout.flags(coutflags); // restore the original flags
604 0 : }
605 :
606 : AliHLTTPCClusterAccessHLTOUT::AliRawClusterContainer::iterator& AliHLTTPCClusterAccessHLTOUT::AliRawClusterContainer::iterator::Next(int slice, int partition)
607 : {
608 : // switch to next cluster
609 0 : if (!fData) {
610 0 : fEntry=NULL;
611 0 : return *this;
612 : }
613 0 : if (fClusterNo>=0 && !fEntry) {
614 : // end was reached before
615 0 : return *this;
616 : }
617 0 : fEntry=fData->NextCluster(slice, partition);
618 :
619 : // offline uses row number in physical sector, inner sector consists of
620 : // partitions 0 and 1, outer sector of partition 2-5
621 0 : fRowOffset=partition<2?0:AliHLTTPCGeometry::GetFirstRow(2);
622 0 : return *this;
623 0 : }
|