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