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