]>
Commit | Line | Data |
---|---|---|
c54aa300 | 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" | |
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" | |
40 | #include "TClonesArray.h" | |
81e7f739 | 41 | #include <cstdlib> |
42 | #include <string> | |
43 | #include <memory> | |
b60d3f6a | 44 | #include <iostream> |
45 | #include <iomanip> | |
c54aa300 | 46 | |
47 | /** ROOT macro for the implementation of ROOT specific class methods */ | |
48 | ClassImp(AliHLTTPCClusterAccessHLTOUT) | |
49 | ||
50 | AliHLTTPCClusterAccessHLTOUT::AliHLTTPCClusterAccessHLTOUT() | |
51 | : TObject() | |
81e7f739 | 52 | , fVerbosity(0) |
c54aa300 | 53 | , fClusters(NULL) |
b60d3f6a | 54 | , fCurrentSector(-1) |
768dad20 | 55 | , fpDecoder(NULL) |
c54aa300 | 56 | { |
57 | // see header file for class documentation | |
58 | // or | |
59 | // refer to README to build package | |
60 | // or | |
61 | // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt | |
62 | } | |
63 | ||
64 | AliHLTTPCClusterAccessHLTOUT::~AliHLTTPCClusterAccessHLTOUT() | |
65 | { | |
66 | // destructor | |
67 | if (fClusters) { | |
68 | fClusters->Clear(); | |
69 | delete fClusters; | |
70 | fClusters=NULL; | |
71 | } | |
768dad20 | 72 | if (fpDecoder) { |
73 | fpDecoder->Clear(); | |
74 | delete fpDecoder; | |
75 | fpDecoder=NULL; | |
76 | } | |
c54aa300 | 77 | } |
78 | ||
81e7f739 | 79 | void AliHLTTPCClusterAccessHLTOUT::Execute(const char *method, const char *params, Int_t *error) |
c54aa300 | 80 | { |
81 | /// inherited from TObject: abstract command interface | |
82 | if (strcmp(method, "read")==0) { | |
81e7f739 | 83 | int iResult=ProcessClusters(params); |
84 | if (error) *error=iResult; | |
85 | return; | |
86 | } | |
87 | if (strcmp(method, "verbosity")==0) { | |
88 | int iResult=0; | |
89 | if (params) { | |
90 | char* dummy; | |
91 | int value=strtol(params, &dummy, 0); | |
92 | if (dummy==NULL) { | |
93 | fVerbosity=value; | |
94 | } else { | |
95 | AliError("invalid argument for command 'verbosity', expecting string with number"); | |
96 | } | |
97 | } else { | |
98 | iResult=-EINVAL; | |
99 | } | |
c54aa300 | 100 | if (error) *error=iResult; |
101 | return; | |
102 | } | |
103 | } | |
104 | ||
105 | TObject* AliHLTTPCClusterAccessHLTOUT::FindObject(const char *name) const | |
106 | { | |
107 | /// inherited from TObject: return the cluster array if name id "clusterarray" | |
b60d3f6a | 108 | if (strcmp(name, "clusterarray")==0) { |
109 | if (fCurrentSector<0) return NULL; | |
110 | return fClusters->GetSectorArray(fCurrentSector); | |
111 | } | |
c54aa300 | 112 | return TObject::FindObject(name); |
113 | } | |
114 | ||
b60d3f6a | 115 | void AliHLTTPCClusterAccessHLTOUT::Clear(Option_t * option) |
c54aa300 | 116 | { |
117 | /// inherited from TObject: cleanup | |
b60d3f6a | 118 | if (strcmp(option, "event")==0) { |
119 | if (fClusters) fClusters->Clear(); | |
120 | fCurrentSector=-1; | |
121 | } | |
c54aa300 | 122 | } |
123 | ||
b60d3f6a | 124 | void AliHLTTPCClusterAccessHLTOUT::Print(Option_t *option) const |
c54aa300 | 125 | { |
126 | /// inherited from TObject | |
b60d3f6a | 127 | if (fClusters) fClusters->Print(option); |
c54aa300 | 128 | } |
129 | ||
81e7f739 | 130 | int AliHLTTPCClusterAccessHLTOUT::ProcessClusters(const char* params) |
c54aa300 | 131 | { |
132 | /// process the cluster data from HLTOUT and fill array | |
133 | /// the cluster data can be in many different formats, e.g. | |
134 | /// raw or compressed | |
135 | int iResult=0; | |
81e7f739 | 136 | TString strparams(params); |
b60d3f6a | 137 | int sector=-1; |
81e7f739 | 138 | std::auto_ptr<TObjArray> tokens(strparams.Tokenize(" ")); |
139 | if (!tokens.get()) return -ENOMEM; | |
140 | for (int i=0; i< tokens->GetEntriesFast(); i++) { | |
141 | if (!tokens->At(i)) continue; | |
142 | TString argument=tokens->At(i)->GetName(); | |
b60d3f6a | 143 | // the offline code enumerates first the 36 inner (partitions 0+1) and then 36 outer |
144 | // sectors (partitions 2-5) | |
81e7f739 | 145 | if (argument.BeginsWith("sector=")) { |
146 | argument.ReplaceAll("sector=", ""); | |
b60d3f6a | 147 | sector=argument.Atoi(); |
81e7f739 | 148 | } |
149 | } | |
b60d3f6a | 150 | if (sector<0) { |
151 | AliError("invalid argument, please specify \"sector=sectorno\""); | |
152 | return -EINVAL; | |
153 | } | |
154 | if (sector>=76) { | |
155 | AliError(Form("invalid sector number %d", sector)); | |
156 | return -EINVAL; | |
157 | } | |
81e7f739 | 158 | |
c54aa300 | 159 | if (!fClusters) { |
b60d3f6a | 160 | fClusters=new AliTPCclusterMIContainer; |
c54aa300 | 161 | } |
162 | if (!fClusters) return -ENOMEM; | |
163 | ||
b60d3f6a | 164 | if (fCurrentSector>=0) { |
165 | // cluster container already filled | |
166 | fCurrentSector=sector; | |
167 | TObjArray* pArray=fClusters->GetSectorArray(fCurrentSector); | |
168 | if (!pArray) { | |
169 | AliError(Form("can not get cluster array for sector %d", sector)); | |
170 | return -ENOBUFS; | |
171 | } | |
af9e48d7 | 172 | if (fVerbosity>0) AliInfo(Form("converted %d cluster(s) for sector %d", pArray->GetEntriesFast() ,sector)); |
b60d3f6a | 173 | return pArray->GetEntriesFast(); |
174 | } | |
175 | ||
176 | // fill the cluster container | |
c54aa300 | 177 | AliHLTSystem* pSystem=AliHLTPluginBase::GetInstance(); |
178 | if (!pSystem) { | |
179 | AliError("can not access HLT system"); | |
180 | return -ENODEV; | |
181 | } | |
182 | AliHLTOUT* pHLTOUT=pSystem->RequestHLTOUT(); | |
183 | if (!pHLTOUT) { | |
184 | AliError("can not access HLTOUT"); | |
b60d3f6a | 185 | return -EACCES; |
c54aa300 | 186 | } |
187 | ||
768dad20 | 188 | if (!fpDecoder) { |
189 | fpDecoder=new AliHLTTPCDataCompressionDecoder; | |
190 | } | |
191 | ||
192 | if (!fpDecoder) { | |
193 | AliError("failed to create decoder instance"); | |
194 | return -ENODEV; | |
195 | } | |
196 | ||
197 | AliHLTTPCDataCompressionDecoder& decoder=*fpDecoder; | |
198 | decoder.Clear(); | |
efa1bd1b | 199 | decoder.SetVerbosity(fVerbosity); |
200 | decoder.EnableClusterMerger(); | |
201 | ||
b60d3f6a | 202 | bool bNextBlock=false; |
b60d3f6a | 203 | // add cluster id and mc information data blocks |
204 | for (bNextBlock=(pHLTOUT->SelectFirstDataBlock()>=0); | |
205 | bNextBlock; bNextBlock=(pHLTOUT->SelectNextDataBlock()>=0)) { | |
206 | AliHLTComponentBlockData desc; | |
207 | // FIXME: extend HLTOUT to get the full descriptor | |
208 | const AliHLTUInt8_t* buffer=NULL; | |
209 | if ((iResult=pHLTOUT->GetDataBuffer(buffer, desc.fSize))<0) { | |
210 | continue; | |
211 | } | |
212 | desc.fPtr=(void*)buffer; | |
213 | if (pHLTOUT->GetDataBlockDescription(desc.fDataType, desc.fSpecification)<0) { | |
214 | continue; | |
215 | } | |
216 | if (desc.fDataType==AliHLTTPCDefinitions::AliHLTDataTypeClusterMCInfo()) { | |
217 | // add mc information | |
efa1bd1b | 218 | if ((iResult=decoder.AddClusterMCData(&desc))<0) { |
b60d3f6a | 219 | return iResult; |
81e7f739 | 220 | } |
b60d3f6a | 221 | } |
222 | if (desc.fDataType==AliHLTTPCDefinitions::RemainingClusterIdsDataType() || | |
223 | desc.fDataType==AliHLTTPCDefinitions::ClusterIdTracksDataType()) { | |
224 | // add cluster ids | |
efa1bd1b | 225 | if ((iResult=decoder.AddClusterIds(&desc))<0) { |
b60d3f6a | 226 | return iResult; |
81e7f739 | 227 | } |
b60d3f6a | 228 | } |
229 | } | |
230 | ||
14f37d68 | 231 | bool bHavePartitionRawData=false; |
232 | bool bHavePartitionCompressedData=false; | |
233 | vector<bool> bHavePartitionData(216, false); | |
234 | ||
b60d3f6a | 235 | // read data |
236 | iResult=-ENODATA; | |
af9e48d7 | 237 | int nExtractedClusters=0; |
b60d3f6a | 238 | for (bNextBlock=(pHLTOUT->SelectFirstDataBlock()>=0); |
239 | bNextBlock; bNextBlock=(pHLTOUT->SelectNextDataBlock()>=0)) { | |
14f37d68 | 240 | decoder.SetPadShift(0.0); |
b60d3f6a | 241 | AliHLTComponentBlockData desc; |
242 | // FIXME: extend HLTOUT to get the full descriptor with one call | |
243 | const AliHLTUInt8_t* buffer=NULL; | |
244 | if ((iResult=pHLTOUT->GetDataBuffer(buffer, desc.fSize))<0) { | |
245 | continue; | |
246 | } | |
247 | desc.fPtr=(void*)buffer; | |
248 | if (pHLTOUT->GetDataBlockDescription(desc.fDataType, desc.fSpecification)<0) { | |
249 | continue; | |
250 | } | |
251 | if (!TestBit(kSkipPartitionClusters) && | |
14f37d68 | 252 | (desc.fDataType==AliHLTTPCDefinitions::RawClustersDataType())) { |
253 | // This is a special handling of data blocks produced with v5-01-Release | |
254 | // The pad shift by 0.5 was not included in the data but was applied in the | |
255 | // unpacking in this class. Changed in r51306, the next tag containing this | |
256 | // change in the online system is v5-01-Rev-07. There are only very few runs | |
257 | // of Sep 2011 with recorded clusters not containing the 0.5 shift | |
258 | // There was also a chenge in the data type of the compressed partition | |
259 | // cluster blocks which helps to identify the blocks which need the pad shift | |
260 | // here | |
261 | if (desc.fSize<sizeof(AliHLTTPCRawClusterData)) continue; | |
262 | const AliHLTTPCRawClusterData* clusterData = reinterpret_cast<const AliHLTTPCRawClusterData*>(buffer); | |
263 | if (!clusterData) continue; | |
264 | if (clusterData->fVersion==1) { | |
265 | // compressed clusters without the pad shift | |
266 | // no raw clusters (version==0) have ever been recorded | |
267 | decoder.SetPadShift(0.5); | |
268 | } | |
269 | AliHLTUInt8_t slice = AliHLTTPCDefinitions::GetMinSliceNr(desc.fSpecification); | |
270 | AliHLTUInt8_t partition = AliHLTTPCDefinitions::GetMinPatchNr(desc.fSpecification); | |
271 | if (slice!=AliHLTTPCDefinitions::GetMaxSliceNr(desc.fSpecification) || | |
272 | partition!=AliHLTTPCDefinitions::GetMaxPatchNr(desc.fSpecification)) { | |
273 | AliFatal(Form("inconsistent cluster data: can not handle blocks containing multiple partitions, " | |
274 | "block specification 0x%08x", desc.fSpecification)); | |
275 | } | |
276 | iResult=decoder.ReadClustersPartition(fClusters->BeginRemainingClusterBlock(0, desc.fSpecification), | |
277 | reinterpret_cast<AliHLTUInt8_t*>(desc.fPtr), | |
278 | desc.fSize, | |
279 | desc.fSpecification); | |
be2dd46a | 280 | if (iResult>=0) nExtractedClusters+=iResult; |
281 | else { | |
282 | AliFatal(Form("processing of cluster block 0x%08x failed with error code %d", desc.fSpecification, iResult)); | |
283 | } | |
14f37d68 | 284 | unsigned index=slice*AliHLTTPCTransform::GetNumberOfPatches()+partition; |
285 | if (index>=bHavePartitionData.size()) bHavePartitionData.resize(index, false); | |
286 | if (bHavePartitionData[index]) { | |
287 | AliFatal(Form("inconsistent cluster data: multiple data blocks of identical specification indicate a failure " | |
288 | "in the production of the data. Probably an HLT emulation chain is executed in the reconstruction " | |
289 | "and produces data in addition to HLTOUT. Option 'ignore-hltout' is required in that case; " | |
290 | "block specification 0x%08x", desc.fSpecification)); | |
291 | } | |
292 | bHavePartitionData[index]=true; | |
293 | if (bHavePartitionCompressedData) { | |
294 | AliFatal(Form("inconsistent cluster data: both compressed and raw cluster blocks present in HLTOUT, indicates a failure " | |
295 | "in the production of the data. Probably an HLT emulation chain is executed in the reconstruction " | |
296 | "and produces data in addition to HLTOUT. Option 'ignore-hltout' is required in that case; " | |
297 | "block specification 0x%08x", desc.fSpecification)); | |
298 | } | |
299 | bHavePartitionRawData=true; | |
300 | continue; | |
301 | } else if (!TestBit(kSkipPartitionClusters) && | |
302 | (desc.fDataType==AliHLTTPCDefinitions::RemainingClustersCompressedDataType())) { | |
303 | AliHLTUInt8_t slice = AliHLTTPCDefinitions::GetMinSliceNr(desc.fSpecification); | |
304 | AliHLTUInt8_t partition = AliHLTTPCDefinitions::GetMinPatchNr(desc.fSpecification); | |
305 | if (slice!=AliHLTTPCDefinitions::GetMaxSliceNr(desc.fSpecification) || | |
306 | partition!=AliHLTTPCDefinitions::GetMaxPatchNr(desc.fSpecification)) { | |
307 | AliFatal(Form("inconsistent cluster data: can not handle blocks containing multiple partitions, " | |
308 | "block specification 0x%08x", desc.fSpecification)); | |
309 | } | |
b60d3f6a | 310 | iResult=decoder.ReadClustersPartition(fClusters->BeginRemainingClusterBlock(0, desc.fSpecification), |
311 | reinterpret_cast<AliHLTUInt8_t*>(desc.fPtr), | |
312 | desc.fSize, | |
313 | desc.fSpecification); | |
af9e48d7 | 314 | if (iResult>0) nExtractedClusters+=iResult; |
14f37d68 | 315 | unsigned index=slice*AliHLTTPCTransform::GetNumberOfPatches()+partition; |
316 | if (index>=bHavePartitionData.size()) bHavePartitionData.resize(index, false); | |
317 | if (bHavePartitionData[index]) { | |
318 | AliFatal(Form("inconsistent cluster data: multiple data blocks of identical specification indicate a failure " | |
319 | "in the production of the data. Probably an HLT emulation chain is executed in the reconstruction " | |
320 | "and produces data in addition to HLTOUT. Option 'ignore-hltout' is required in that case; " | |
321 | "block specification 0x%08x", desc.fSpecification)); | |
322 | } | |
323 | bHavePartitionData[index]=true; | |
324 | bHavePartitionData[index]=true; | |
325 | if (bHavePartitionRawData) { | |
326 | AliFatal(Form("inconsistent cluster data: both compressed and raw cluster blocks present in HLTOUT, indicates a failure " | |
327 | "in the production of the data. Probably an HLT emulation chain is executed in the reconstruction " | |
328 | "and produces data in addition to HLTOUT. Option 'ignore-hltout' is required in that case; " | |
329 | "block specification 0x%08x", desc.fSpecification)); | |
330 | } | |
331 | bHavePartitionCompressedData=true; | |
b60d3f6a | 332 | continue; |
333 | } else if (!TestBit(kSkipTrackClusters) && | |
334 | desc.fDataType==AliHLTTPCDefinitions::ClusterTracksCompressedDataType()) { | |
335 | iResult=decoder.ReadTrackModelClustersCompressed(fClusters->BeginTrackModelClusterBlock(0), | |
336 | reinterpret_cast<AliHLTUInt8_t*>(desc.fPtr), | |
337 | desc.fSize, | |
338 | desc.fSpecification); | |
339 | continue; | |
81e7f739 | 340 | } |
c54aa300 | 341 | } |
342 | ||
343 | pSystem->ReleaseHLTOUT(pHLTOUT); | |
b60d3f6a | 344 | |
345 | if (iResult<0) return iResult; | |
af9e48d7 | 346 | if (fVerbosity>0) { |
347 | int nConvertedClusters=0; | |
348 | for (int s=0; s<72; s++) { | |
349 | TObjArray* pArray=fClusters->GetSectorArray(s); | |
350 | if (!pArray) continue; | |
351 | nConvertedClusters+=pArray->GetEntriesFast(); | |
352 | } | |
353 | AliInfo(Form("extracted HLT clusters: %d, converted HLT clusters: %d", nExtractedClusters, nConvertedClusters)); | |
354 | } | |
355 | ||
b60d3f6a | 356 | fCurrentSector=sector; |
357 | TObjArray* pArray=fClusters->GetSectorArray(fCurrentSector); | |
358 | if (!pArray) { | |
359 | AliError(Form("can not get cluster array for sector %d", sector)); | |
360 | return -ENOBUFS; | |
361 | } | |
af9e48d7 | 362 | if (fVerbosity>0) AliInfo(Form("converted %d cluster(s) for sector %d", pArray->GetEntriesFast() ,sector)); |
b60d3f6a | 363 | return pArray->GetEntriesFast(); |
c54aa300 | 364 | } |
365 | ||
81e7f739 | 366 | int AliHLTTPCClusterAccessHLTOUT::ReadAliHLTTPCClusterMCData(AliHLTOUT* pHLTOUT, AliHLTTPCClusterMCDataList &tpcClusterLabels) const |
367 | { | |
368 | // read cluster data from AliHLTTPCClusterData | |
369 | int iResult=0; | |
370 | if (!pHLTOUT) return -EINVAL; | |
371 | do { | |
372 | const AliHLTUInt8_t* pBuffer=NULL; | |
373 | AliHLTUInt32_t size=0; | |
374 | if ((iResult=pHLTOUT->GetDataBuffer(pBuffer, size))<0) { | |
375 | continue; | |
376 | } | |
377 | if (pBuffer==NULL || size<4) { | |
378 | AliError("invalid cluster mc data block"); | |
379 | continue; | |
380 | } | |
381 | const AliHLTTPCClusterMCData* clusterMCData = reinterpret_cast<const AliHLTTPCClusterMCData*>(pBuffer); | |
382 | Int_t nLabels = (Int_t) clusterMCData->fCount; | |
383 | if (nLabels*sizeof(AliHLTTPCClusterMCLabel) + sizeof(AliHLTTPCClusterMCData) != size) { | |
384 | AliError("inconsistent cluster mc data block size, skipping block"); | |
385 | continue; | |
386 | } | |
387 | // id of the cluster is | |
388 | AliHLTComponentDataType dt=kAliHLTVoidDataType; | |
389 | AliHLTUInt32_t specification=kAliHLTVoidDataSpec; | |
390 | if (pHLTOUT->GetDataBlockDescription(dt, specification)<0) { | |
391 | AliError("failed to retrieve data block description, skipping mc cluster data block ..."); | |
392 | continue; | |
393 | } | |
394 | AliHLTUInt8_t slice = AliHLTTPCDefinitions::GetMinSliceNr(specification); | |
395 | AliHLTUInt8_t partition = AliHLTTPCDefinitions::GetMinPatchNr(specification); | |
396 | if (slice!=AliHLTTPCDefinitions::GetMaxSliceNr(specification) || | |
397 | partition!=AliHLTTPCDefinitions::GetMaxPatchNr(specification)) { | |
398 | AliError(Form("can not read cluster mc data block with data of multiple partitions, skipping block %s %08x", | |
399 | AliHLTComponent::DataType2Text(dt).c_str(), specification)); | |
400 | continue; | |
401 | } | |
402 | const AliHLTTPCClusterMCLabel *labels = clusterMCData->fLabels; | |
403 | for (int i=0; i<nLabels; i++) { | |
404 | AliHLTUInt32_t id=AliHLTTPCSpacePointData::GetID(slice, partition, i); | |
405 | if (tpcClusterLabels.find(id)==tpcClusterLabels.end()) { | |
406 | // new cluster | |
407 | tpcClusterLabels[id]=labels[i]; | |
408 | } else { | |
409 | AliError(Form("cluster with ID 0x%08x already existing, skipping cluster %d of data block 0x%08x", | |
410 | id, i, specification)); | |
411 | } | |
412 | } | |
413 | } while (pHLTOUT->SelectNextDataBlock()>=0); | |
414 | return iResult; | |
415 | } | |
416 | ||
417 | int AliHLTTPCClusterAccessHLTOUT::ReadAliHLTTPCClusterData(AliHLTOUT* pHLTOUT, TClonesArray* pClusters, const AliHLTTPCClusterMCDataList *tpcClusterLabels) const | |
c54aa300 | 418 | { |
419 | // read cluster data from AliHLTTPCClusterData | |
420 | int iResult=0; | |
421 | if (!pHLTOUT || !pClusters) return -EINVAL; | |
422 | do { | |
423 | const AliHLTUInt8_t* pBuffer=NULL; | |
424 | AliHLTUInt32_t size=0; | |
425 | if ((iResult=pHLTOUT->GetDataBuffer(pBuffer, size))<0) { | |
426 | continue; | |
427 | } | |
428 | if (pBuffer==NULL || size<4) { | |
429 | AliError("invalid cluster data block"); | |
430 | continue; | |
431 | } | |
81e7f739 | 432 | AliHLTComponentDataType dt=kAliHLTVoidDataType; |
433 | AliHLTUInt32_t specification=kAliHLTVoidDataSpec; | |
434 | if (pHLTOUT->GetDataBlockDescription(dt, specification)<0) { | |
435 | AliError("failed to retrieve data block description, skipping mc cluster data block ..."); | |
436 | continue; | |
437 | } | |
c54aa300 | 438 | const AliHLTTPCClusterData* clusterData = reinterpret_cast<const AliHLTTPCClusterData*>(pBuffer); |
439 | Int_t nSpacepoints = (Int_t) clusterData->fSpacePointCnt; | |
440 | if (nSpacepoints*sizeof(AliHLTTPCSpacePointData) + sizeof(AliHLTTPCClusterData) != size) { | |
441 | AliError("inconsistent cluster data block size, skipping block"); | |
442 | continue; | |
443 | } | |
444 | const AliHLTTPCSpacePointData *clusters = clusterData->fSpacePoints; | |
81e7f739 | 445 | int offset=pClusters->GetEntries(); |
446 | pClusters->ExpandCreate(offset+nSpacepoints); | |
0e63cf4a | 447 | AliHLTUInt8_t slice = AliHLTTPCDefinitions::GetMinSliceNr(specification); |
448 | AliHLTUInt8_t partition = AliHLTTPCDefinitions::GetMinPatchNr(specification); | |
449 | // FIXME: get first row number of outer sectors from a common definition instead using number | |
80874dc5 | 450 | unsigned rowOffset=partition<2?0:63; |
c54aa300 | 451 | for (int i=0; i<nSpacepoints; i++) { |
81e7f739 | 452 | if (!pClusters->At(offset+i)) continue; |
453 | AliTPCclusterMI* pCluster=dynamic_cast<AliTPCclusterMI*>(pClusters->At(offset+i)); | |
c54aa300 | 454 | if (!pCluster) { |
455 | AliError("invalid object type, expecting AliTPCclusterMI"); | |
456 | break; // this is a problem of all objects | |
457 | } | |
0e63cf4a | 458 | if (clusters[i].fPadRow<rowOffset) { |
459 | AliError(Form("invalid row number %d, expecting minimum row number %d for slice %d partition %d", clusters[i].fPadRow, rowOffset, slice, partition)); | |
460 | } else { | |
461 | pCluster->SetRow(clusters[i].fPadRow-rowOffset); | |
462 | } | |
81e7f739 | 463 | pCluster->SetPad(clusters[i].fY); |
5e75f4e0 | 464 | pCluster->SetTimeBin(clusters[i].fZ); |
81e7f739 | 465 | pCluster->SetSigmaY2(clusters[i].fSigmaY2); |
466 | pCluster->SetSigmaZ2(clusters[i].fSigmaZ2); | |
c54aa300 | 467 | pCluster->SetQ(clusters[i].fCharge); |
468 | pCluster->SetMax(clusters[i].fQMax); | |
81e7f739 | 469 | if (tpcClusterLabels) { |
470 | if (tpcClusterLabels->find(clusters[i].fID)!=tpcClusterLabels->end()) { | |
471 | const AliHLTTPCClusterMCWeight* mcWeights=tpcClusterLabels->find(clusters[i].fID)->second.fClusterID; | |
472 | for (int k=0; k<3; k++) { | |
473 | // TODO: sort the labels according to the weight in order to assign the most likely mc label | |
474 | // to the first component | |
475 | pCluster->SetLabel(mcWeights[k].fMCID, k); | |
476 | } | |
477 | } else { | |
478 | AliError(Form("can not find mc label of cluster with id %0x08x", clusters[i].fID)); | |
479 | } | |
480 | } | |
c54aa300 | 481 | } |
1214ab89 | 482 | if (fVerbosity>0) AliInfo(Form("converted %d cluster(s) from block %s 0x%08x", nSpacepoints, AliHLTComponent::DataType2Text(dt).c_str(), specification)); |
c54aa300 | 483 | } while (pHLTOUT->SelectNextDataBlock()>=0); |
484 | return iResult; | |
485 | } | |
5e75f4e0 | 486 | |
487 | int AliHLTTPCClusterAccessHLTOUT::ReadAliHLTTPCRawClusterData(AliHLTOUT* pHLTOUT, TClonesArray* pClusters, const AliHLTTPCClusterMCDataList *tpcClusterLabels) | |
488 | { | |
489 | // read cluster data from AliHLTTPCClusterData | |
490 | ||
491 | // FIXME: this is in large parts like ReadAliHLTTPCClusterData, | |
492 | // make a common method | |
493 | int iResult=0; | |
494 | if (!pHLTOUT || !pClusters) return -EINVAL; | |
495 | do { | |
496 | const AliHLTUInt8_t* pBuffer=NULL; | |
497 | AliHLTUInt32_t size=0; | |
498 | if ((iResult=pHLTOUT->GetDataBuffer(pBuffer, size))<0) { | |
499 | continue; | |
500 | } | |
501 | if (pBuffer==NULL || size<4) { | |
502 | AliError("invalid cluster data block"); | |
503 | continue; | |
504 | } | |
505 | AliHLTComponentDataType dt=kAliHLTVoidDataType; | |
506 | AliHLTUInt32_t specification=kAliHLTVoidDataSpec; | |
507 | if (pHLTOUT->GetDataBlockDescription(dt, specification)<0) { | |
508 | AliError("failed to retrieve data block description, skipping mc cluster data block ..."); | |
509 | continue; | |
510 | } | |
511 | const AliHLTTPCRawClusterData* clusterData = reinterpret_cast<const AliHLTTPCRawClusterData*>(pBuffer); | |
512 | Int_t nCount = (Int_t) clusterData->fCount; | |
61e66346 | 513 | if (clusterData->fVersion!=0) { |
514 | // this is encoded data of different formats | |
515 | switch (clusterData->fVersion) { | |
516 | case 1: | |
517 | iResult=ReadAliHLTTPCRawClusterDataDeflateSimple(reinterpret_cast<const AliHLTUInt8_t*>(clusterData->fClusters), | |
518 | size-sizeof(AliHLTTPCRawClusterData), nCount, specification, | |
519 | pClusters, tpcClusterLabels); | |
520 | break; | |
521 | default: | |
522 | iResult=-EPROTO; | |
523 | } | |
524 | return iResult; | |
525 | } | |
526 | ||
5e75f4e0 | 527 | if (nCount*sizeof(AliHLTTPCRawCluster) + sizeof(AliHLTTPCRawClusterData) != size) { |
528 | AliError("inconsistent cluster data block size, skipping block"); | |
529 | continue; | |
530 | } | |
531 | const AliHLTTPCRawCluster *clusters = clusterData->fClusters; | |
532 | int offset=pClusters->GetEntries(); | |
533 | pClusters->ExpandCreate(offset+nCount); | |
0e63cf4a | 534 | AliHLTUInt8_t slice = AliHLTTPCDefinitions::GetMinSliceNr(specification); |
535 | AliHLTUInt8_t partition = AliHLTTPCDefinitions::GetMinPatchNr(specification); | |
536 | // FIXME: get first row number of outer sectors from a common definition instead using number | |
80874dc5 | 537 | int rowOffset=partition<2?0:63; |
5e75f4e0 | 538 | for (int i=0; i<nCount; i++) { |
539 | if (!pClusters->At(offset+i)) continue; | |
540 | AliTPCclusterMI* pCluster=dynamic_cast<AliTPCclusterMI*>(pClusters->At(offset+i)); | |
541 | if (!pCluster) { | |
542 | AliError("invalid object type, expecting AliTPCclusterMI"); | |
543 | break; // this is a problem of all objects | |
544 | } | |
1214ab89 | 545 | if (fVerbosity>1) AliInfo(Form("cluster padrow %d (slice %d partition %d)", clusters[i].GetPadRow(), slice, partition)); |
0e63cf4a | 546 | if (clusters[i].GetPadRow()<rowOffset) { |
547 | AliError(Form("invalid row number %d, expecting minimum row number %d for slice %d partition %d", clusters[i].GetPadRow(), rowOffset, slice, partition)); | |
548 | } else { | |
549 | pCluster->SetRow(clusters[i].GetPadRow()-rowOffset); | |
550 | } | |
1b9cc91a | 551 | pCluster->SetPad(clusters[i].GetPad()); |
5e75f4e0 | 552 | pCluster->SetTimeBin(clusters[i].GetTime()); |
553 | pCluster->SetSigmaY2(clusters[i].GetSigmaY2()); | |
554 | pCluster->SetSigmaZ2(clusters[i].GetSigmaZ2()); | |
555 | pCluster->SetQ(clusters[i].GetCharge()); | |
556 | pCluster->SetMax(clusters[i].GetQMax()); | |
557 | if (tpcClusterLabels) { | |
5e75f4e0 | 558 | UInt_t clusterID=AliHLTTPCSpacePointData::GetID(slice, partition, i); |
559 | if (tpcClusterLabels->find(clusterID)!=tpcClusterLabels->end()) { | |
560 | const AliHLTTPCClusterMCWeight* mcWeights=tpcClusterLabels->find(clusterID)->second.fClusterID; | |
561 | for (int k=0; k<3; k++) { | |
562 | // TODO: sort the labels according to the weight in order to assign the most likely mc label | |
563 | // to the first component | |
564 | pCluster->SetLabel(mcWeights[k].fMCID, k); | |
565 | } | |
566 | } else { | |
567 | AliError(Form("can not find mc label of cluster with id %0x08x", clusterID)); | |
568 | } | |
569 | } | |
570 | } | |
571 | if (fVerbosity>0) AliInfo(Form("converted %d cluster(s) from block %s 0x%08x", nCount, AliHLTComponent::DataType2Text(dt).c_str(), specification)); | |
572 | } while (pHLTOUT->SelectNextDataBlock()>=0); | |
573 | return iResult; | |
574 | } | |
61e66346 | 575 | |
2827cd62 | 576 | int AliHLTTPCClusterAccessHLTOUT::ReadRemainingClustersCompressed(AliHLTOUT* pHLTOUT, TClonesArray* pClusters, const AliHLTTPCClusterMCDataList *tpcClusterLabels) |
577 | { | |
578 | // read cluster data from AliHLTTPCClusterData | |
579 | int iResult=0; | |
580 | if (!pHLTOUT || !pClusters) return -EINVAL; | |
581 | do { | |
582 | const AliHLTUInt8_t* pBuffer=NULL; | |
583 | AliHLTUInt32_t size=0; | |
584 | if ((iResult=pHLTOUT->GetDataBuffer(pBuffer, size))<0) { | |
585 | continue; | |
586 | } | |
587 | if (pBuffer==NULL || size<4) { | |
588 | AliError("invalid cluster data block"); | |
589 | continue; | |
590 | } | |
591 | AliHLTComponentDataType dt=kAliHLTVoidDataType; | |
592 | AliHLTUInt32_t specification=kAliHLTVoidDataSpec; | |
593 | if (pHLTOUT->GetDataBlockDescription(dt, specification)<0) { | |
594 | AliError("failed to retrieve data block description, skipping mc cluster data block ..."); | |
595 | continue; | |
596 | } | |
597 | const AliHLTTPCRawClusterData* clusterData = reinterpret_cast<const AliHLTTPCRawClusterData*>(pBuffer); | |
598 | Int_t nCount = (Int_t) clusterData->fCount; | |
599 | ||
600 | // this is encoded data of different formats | |
601 | switch (clusterData->fVersion) { | |
602 | case 1: | |
603 | iResult=ReadAliHLTTPCRawClusterDataDeflateSimple(reinterpret_cast<const AliHLTUInt8_t*>(clusterData->fClusters), | |
604 | size-sizeof(AliHLTTPCRawClusterData), nCount, specification, | |
605 | pClusters, tpcClusterLabels); | |
606 | break; | |
607 | default: | |
608 | AliError(Form("invalid cluster format version %d", clusterData->fVersion)); | |
609 | iResult=-EPROTO; | |
610 | } | |
611 | ||
612 | if (fVerbosity>0) AliInfo(Form("converted %d cluster(s) from block %s 0x%08x", nCount, AliHLTComponent::DataType2Text(dt).c_str(), specification)); | |
613 | } while (pHLTOUT->SelectNextDataBlock()>=0 && iResult>=0); | |
614 | ||
615 | return iResult; | |
616 | } | |
617 | ||
61e66346 | 618 | int AliHLTTPCClusterAccessHLTOUT::ReadAliHLTTPCRawClusterDataDeflateSimple(const AliHLTUInt8_t* pData, int dataSize, |
619 | int nofClusters, AliHLTUInt32_t specification, | |
620 | TClonesArray* pClusters, | |
621 | const AliHLTTPCClusterMCDataList *tpcClusterLabels) | |
622 | { | |
623 | // read cluster data from AliHLTTPCClusterData | |
624 | ||
625 | // FIXME: quick implementation to read the compressed cluster data from HLTOUT | |
626 | // the data definition below is the same as in AliHLTTPCDataCompressionComponent | |
627 | // but needs to be moved to a common class (AliHLTTPCDefinitions?) | |
628 | // Think about a decoder class supporting iterator objects for various types | |
629 | // of cluster data | |
630 | int iResult=0; | |
631 | if (!pData || !pClusters) return -EINVAL; | |
632 | AliHLTDataInflater inflater; | |
633 | if ((iResult=inflater.InitBitDataInput(pData, dataSize))<0) { | |
634 | return iResult; | |
635 | } | |
636 | ||
637 | int offset=pClusters->GetEntries(); | |
638 | pClusters->ExpandCreate(offset+nofClusters); | |
639 | AliHLTUInt8_t slice = AliHLTTPCDefinitions::GetMinSliceNr(specification); | |
640 | AliHLTUInt8_t partition = AliHLTTPCDefinitions::GetMinPatchNr(specification); | |
641 | // the compressed format stores the difference of the local row number in | |
642 | // the partition to the row of the last cluster | |
643 | // add the first row in the partition to get global row number | |
644 | // offline uses row number in physical sector, inner sector consists of | |
645 | // partitions 0 and 1, outer sector of partition 2-5 | |
646 | int rowOffset=AliHLTTPCTransform::GetFirstRow(partition)-(partition<2?0:AliHLTTPCTransform::GetFirstRow(2)); | |
647 | ||
648 | int parameterId=0; | |
649 | int outClusterCnt=0; | |
650 | AliHLTUInt8_t switchBit=0; | |
651 | AliHLTUInt64_t value=0; | |
652 | AliTPCclusterMI* pCluster=NULL; | |
653 | AliHLTUInt32_t lastPadRow=0; | |
654 | while (outClusterCnt<nofClusters && inflater.InputBit(switchBit)) { | |
655 | const AliHLTTPCDefinitions::AliClusterParameter& parameter | |
656 | =AliHLTTPCDefinitions::fgkClusterParameterDefinitions[parameterId]; | |
657 | // in mode DeflaterSimple, the optional parameter of the cluster parameter definition | |
658 | // corresponds to the number bits of the reduced format | |
659 | if (!inflater.InputBits(value, switchBit?parameter.fBitLength:parameter.fOptional)) { | |
660 | break; | |
661 | } | |
662 | ||
663 | if (!pCluster) { | |
664 | if (!pClusters->At(offset+outClusterCnt)) { | |
665 | // here we should not get anymore because of the condition outClusterCnt<nofClusters | |
666 | return -ENOSPC; | |
667 | } | |
668 | pCluster=dynamic_cast<AliTPCclusterMI*>(pClusters->At(offset+outClusterCnt)); | |
669 | if (!pCluster) { | |
670 | AliError("invalid object type, expecting AliTPCclusterMI"); | |
671 | iResult=-EBADF; // this is a problem of all objects | |
672 | break; | |
673 | } | |
674 | } | |
675 | switch (parameterId) { | |
676 | case AliHLTTPCDefinitions::kPadRow: | |
677 | {pCluster->SetRow(value+lastPadRow+rowOffset); lastPadRow+=value;break;} | |
678 | case AliHLTTPCDefinitions::kPad: | |
679 | {float pad=value; pad/=parameter.fScale; pCluster->SetPad(pad); break;} | |
680 | case AliHLTTPCDefinitions::kTime: | |
681 | {float time=value; time/=parameter.fScale; pCluster->SetTimeBin(time); break;} | |
682 | case AliHLTTPCDefinitions::kSigmaY2: | |
683 | {float sigmaY2=value; sigmaY2/=parameter.fScale; pCluster->SetSigmaY2(sigmaY2); break;} | |
684 | case AliHLTTPCDefinitions::kSigmaZ2: | |
685 | {float sigmaZ2=value; sigmaZ2/=parameter.fScale; pCluster->SetSigmaZ2(sigmaZ2); break;} | |
686 | case AliHLTTPCDefinitions::kCharge: | |
687 | {pCluster->SetQ(value); break;} | |
688 | case AliHLTTPCDefinitions::kQMax: | |
689 | {pCluster->SetMax(value); break;} | |
690 | } | |
691 | if (parameterId>=AliHLTTPCDefinitions::kLast) { | |
692 | // switch to next cluster | |
693 | if (tpcClusterLabels) { | |
694 | UInt_t clusterID=AliHLTTPCSpacePointData::GetID(slice, partition, outClusterCnt); | |
695 | if (tpcClusterLabels->find(clusterID)!=tpcClusterLabels->end()) { | |
696 | const AliHLTTPCClusterMCWeight* mcWeights=tpcClusterLabels->find(clusterID)->second.fClusterID; | |
697 | for (int k=0; k<3; k++) { | |
698 | // TODO: sort the labels according to the weight in order to assign the most likely mc label | |
699 | // to the first component | |
700 | pCluster->SetLabel(mcWeights[k].fMCID, k); | |
701 | } | |
702 | } else { | |
2827cd62 | 703 | AliError(Form("can not find mc label of cluster with id 0x%08x", clusterID)); |
61e66346 | 704 | } |
705 | } | |
706 | outClusterCnt++; | |
707 | pCluster=NULL; | |
708 | parameterId=-1; | |
709 | } | |
710 | parameterId++; | |
711 | } | |
712 | inflater.Pad8Bits(); | |
713 | if (inflater.InputBit(switchBit)) { | |
714 | AliWarning("format error of compressed clusters, there is more data than expected"); | |
715 | } | |
716 | inflater.CloseBitDataInput(); | |
717 | if (iResult>=0 && nofClusters!=outClusterCnt) { | |
718 | // is this a Fatal? | |
719 | AliError(Form("error reading compressed cluster format: expected %d, read only %d cluster(s)", nofClusters, outClusterCnt)); | |
720 | return -EPROTO; | |
721 | } | |
722 | return iResult; | |
723 | } | |
b60d3f6a | 724 | |
725 | AliHLTTPCClusterAccessHLTOUT::AliTPCclusterMIContainer::AliTPCclusterMIContainer() | |
726 | : fClusterArrays() | |
727 | , fRemainingClusterIds() | |
728 | , fTrackModelClusterIds() | |
729 | , fCurrentClusterIds(NULL) | |
730 | , fClusterMCData() | |
731 | , fIterator() | |
732 | ||
733 | { | |
734 | /// constructor | |
735 | for (int i=0; i<72; i++) { | |
736 | fClusterArrays.push_back(new TClonesArray("AliTPCclusterMI")); | |
737 | } | |
738 | } | |
739 | ||
740 | AliHLTTPCClusterAccessHLTOUT::AliTPCclusterMIContainer::~AliTPCclusterMIContainer() | |
741 | { | |
742 | /// dectructor | |
743 | for (vector<TClonesArray*>::iterator i=fClusterArrays.begin(); i!=fClusterArrays.end(); i++) { | |
744 | if (*i) { | |
745 | (*i)->Clear(); | |
746 | delete *i; | |
747 | } | |
748 | } | |
749 | } | |
750 | ||
751 | AliHLTTPCClusterAccessHLTOUT::AliTPCclusterMIContainer::iterator& AliHLTTPCClusterAccessHLTOUT::AliTPCclusterMIContainer::BeginRemainingClusterBlock(int /*count*/, AliHLTUInt32_t specification) | |
752 | { | |
753 | /// iterator of remaining clusters block of specification | |
754 | AliHLTUInt8_t slice=AliHLTTPCDefinitions::GetMinSliceNr(specification); | |
755 | AliHLTUInt8_t partition=AliHLTTPCDefinitions::GetMinPatchNr(specification); | |
756 | unsigned index=slice*AliHLTTPCTransform::GetNumberOfPatches()+partition; | |
757 | if (index<fRemainingClusterIds.size()) | |
758 | fCurrentClusterIds=&fRemainingClusterIds[index]; | |
759 | else | |
760 | fCurrentClusterIds=NULL; | |
761 | fIterator=iterator(this); | |
762 | return fIterator; | |
763 | } | |
764 | ||
765 | AliHLTTPCClusterAccessHLTOUT::AliTPCclusterMIContainer::iterator& AliHLTTPCClusterAccessHLTOUT::AliTPCclusterMIContainer::BeginTrackModelClusterBlock(int /*count*/) | |
766 | { | |
767 | /// iterator of track model clusters | |
768 | if (fTrackModelClusterIds.fIds && fTrackModelClusterIds.fSize>0) | |
769 | fCurrentClusterIds=&fTrackModelClusterIds; | |
770 | else | |
771 | fCurrentClusterIds=NULL; | |
772 | fIterator=iterator(this); | |
773 | return fIterator; | |
774 | } | |
775 | ||
776 | int AliHLTTPCClusterAccessHLTOUT::AliTPCclusterMIContainer::AddClusterMCData(const AliHLTComponentBlockData* pDesc) | |
777 | { | |
778 | /// add cluster mc data block | |
779 | if (!pDesc) return -EINVAL; | |
780 | if (pDesc->fDataType==AliHLTTPCDefinitions::AliHLTDataTypeClusterMCInfo()) { | |
781 | AliHLTUInt8_t slice=AliHLTTPCDefinitions::GetMinSliceNr(pDesc->fSpecification); | |
782 | AliHLTUInt8_t partition=AliHLTTPCDefinitions::GetMinPatchNr(pDesc->fSpecification); | |
783 | unsigned index=slice*AliHLTTPCTransform::GetNumberOfPatches()+partition; | |
784 | if (fClusterMCData.size()<=index) { | |
785 | if ((int)fClusterMCData.size()<AliHLTTPCTransform::GetNSlice()*AliHLTTPCTransform::GetNumberOfPatches()) { | |
786 | fClusterMCData.resize(AliHLTTPCTransform::GetNSlice()*AliHLTTPCTransform::GetNumberOfPatches(), NULL); | |
787 | } else { | |
788 | fClusterMCData.resize(index+1, NULL); | |
789 | } | |
790 | } | |
791 | if (pDesc->fSize<sizeof(AliHLTTPCClusterMCData)) return -EINVAL; | |
792 | const AliHLTTPCClusterMCData* pData=reinterpret_cast<const AliHLTTPCClusterMCData*>(pDesc->fPtr); | |
793 | unsigned nLabels = pData->fCount; | |
794 | if (nLabels*sizeof(AliHLTTPCClusterMCLabel) + sizeof(AliHLTTPCClusterMCData) != pDesc->fSize) { | |
795 | return -EINVAL; | |
796 | } | |
797 | fClusterMCData[index]=pData; | |
798 | return 0; | |
799 | } | |
800 | return -ENODATA; | |
801 | } | |
802 | ||
803 | int AliHLTTPCClusterAccessHLTOUT::AliTPCclusterMIContainer::AddClusterIds(const AliHLTComponentBlockData* pDesc) | |
804 | { | |
805 | /// add cluster id block for remaining or track model clusters | |
806 | if (!pDesc) return -EINVAL; | |
807 | if (pDesc->fDataType==AliHLTTPCDefinitions::ClusterIdTracksDataType()) { | |
808 | fTrackModelClusterIds.fIds=reinterpret_cast<AliHLTUInt32_t*>(pDesc->fPtr); | |
809 | fTrackModelClusterIds.fSize=pDesc->fSize/sizeof(AliHLTUInt32_t); | |
810 | return 0; | |
811 | } | |
812 | if (pDesc->fDataType==AliHLTTPCDefinitions::RemainingClusterIdsDataType()) { | |
813 | AliHLTUInt8_t slice=AliHLTTPCDefinitions::GetMinSliceNr(pDesc->fSpecification); | |
814 | AliHLTUInt8_t partition=AliHLTTPCDefinitions::GetMinPatchNr(pDesc->fSpecification); | |
815 | unsigned index=slice*AliHLTTPCTransform::GetNumberOfPatches()+partition; | |
816 | if (fRemainingClusterIds.size()<=index) { | |
817 | if ((int)fRemainingClusterIds.size()<AliHLTTPCTransform::GetNSlice()*AliHLTTPCTransform::GetNumberOfPatches()) { | |
818 | fRemainingClusterIds.resize(AliHLTTPCTransform::GetNSlice()*AliHLTTPCTransform::GetNumberOfPatches()); | |
819 | } else { | |
820 | fRemainingClusterIds.resize(index+1); | |
821 | } | |
822 | } | |
823 | fRemainingClusterIds[index].fIds=reinterpret_cast<AliHLTUInt32_t*>(pDesc->fPtr); | |
824 | fRemainingClusterIds[index].fSize=pDesc->fSize/sizeof(AliHLTUInt32_t); | |
825 | return 0; | |
826 | } | |
827 | return -ENODATA; | |
828 | } | |
829 | ||
830 | AliHLTUInt32_t AliHLTTPCClusterAccessHLTOUT::AliTPCclusterMIContainer::GetClusterId(int clusterNo) const | |
831 | { | |
832 | /// get the cluster id from the current cluster id block (optional) | |
833 | if (!fCurrentClusterIds || | |
ebba640a | 834 | (int)fCurrentClusterIds->fSize<=clusterNo || |
835 | clusterNo<0) | |
b60d3f6a | 836 | return kAliHLTVoidDataSpec; |
837 | return fCurrentClusterIds->fIds[clusterNo]; | |
838 | } | |
839 | ||
840 | AliTPCclusterMI* AliHLTTPCClusterAccessHLTOUT::AliTPCclusterMIContainer::NextCluster(int slice, int partition) | |
841 | { | |
842 | /// load next cluster from array of the sepcific sector | |
843 | unsigned sector=partition<2?slice:slice+36; | |
844 | if (fClusterArrays.size()<=sector || | |
845 | fClusterArrays[sector]==NULL) { | |
846 | AliErrorClass(Form("no cluster array available for sector %d", sector)); | |
847 | return NULL; | |
848 | } | |
849 | TClonesArray& array=*(fClusterArrays[sector]); | |
850 | int count=array.GetEntriesFast(); | |
851 | return new (array[count]) AliTPCclusterMI; | |
852 | } | |
853 | ||
854 | int AliHLTTPCClusterAccessHLTOUT::AliTPCclusterMIContainer::SetMC(AliTPCclusterMI* pCluster, AliHLTUInt32_t clusterId) | |
855 | { | |
856 | /// set MC data for the cluster | |
857 | if (!pCluster) return -EINVAL; | |
858 | if (clusterId==kAliHLTVoidDataSpec) return 0; | |
859 | ||
860 | unsigned slice=AliHLTTPCSpacePointData::GetSlice(clusterId); | |
861 | unsigned partition=AliHLTTPCSpacePointData::GetPatch(clusterId); | |
862 | unsigned number=AliHLTTPCSpacePointData::GetNumber(clusterId); | |
863 | if ((int)slice>=AliHLTTPCTransform::GetNSlice() || | |
864 | (int)partition>=AliHLTTPCTransform::GetNumberOfPatches()) return -EDOM; | |
865 | unsigned index=slice*AliHLTTPCTransform::GetNumberOfPatches()+partition; | |
866 | if (fClusterMCData.size()<=index || | |
867 | fClusterMCData[index]==NULL || | |
868 | fClusterMCData[index]->fCount<=number) return 0; | |
869 | const AliHLTTPCClusterMCWeight* mcWeights=fClusterMCData[index]->fLabels[number].fClusterID; | |
870 | for (int k=0; k<3; k++) { | |
871 | // TODO: sort the labels according to the weight in order to assign the most likely mc label | |
872 | // to the first component | |
873 | pCluster->SetLabel(mcWeights[k].fMCID, k); | |
874 | } | |
875 | ||
876 | return 0; | |
877 | } | |
878 | ||
879 | void AliHLTTPCClusterAccessHLTOUT::AliTPCclusterMIContainer::Clear(Option_t* /*option*/) | |
880 | { | |
881 | /// internal cleanup | |
882 | { | |
883 | for (vector<TClonesArray*>::iterator i=fClusterArrays.begin(); i!=fClusterArrays.end(); i++) | |
884 | if (*i) (*i)->Clear(); | |
885 | } | |
886 | { | |
887 | for (vector<AliClusterIdBlock>::iterator i=fRemainingClusterIds.begin(); i!=fRemainingClusterIds.end(); i++) | |
888 | {i->fIds=NULL; i->fSize=0;} | |
889 | } | |
890 | fTrackModelClusterIds.fIds=NULL; fTrackModelClusterIds.fSize=0; | |
891 | fCurrentClusterIds=NULL; | |
892 | { | |
893 | for (vector<const AliHLTTPCClusterMCData*>::iterator i=fClusterMCData.begin(); i!=fClusterMCData.end(); i++) | |
894 | *i=NULL; | |
895 | } | |
896 | } | |
897 | ||
898 | TObjArray* AliHLTTPCClusterAccessHLTOUT::AliTPCclusterMIContainer::GetSectorArray(unsigned sector) const | |
899 | { | |
900 | /// get the cluster array for a sector | |
901 | if (fClusterArrays.size()<=sector) return NULL; | |
902 | return fClusterArrays[sector]; | |
903 | } | |
904 | ||
905 | void AliHLTTPCClusterAccessHLTOUT::AliTPCclusterMIContainer::Print(Option_t *option) const | |
906 | { | |
907 | /// inherited from TObject | |
908 | cout << "AliHLTTPCClusterAccessHLTOUT::AliTPCclusterMIContainer" << endl; | |
909 | ios::fmtflags coutflags=cout.flags(); // backup cout status flags | |
910 | bool bAll=false; | |
911 | if ((bAll=(strcmp(option, "full")==0)) || | |
912 | strcmp(option, "short")==0) { | |
913 | for (unsigned iArray=0; iArray<fClusterArrays.size(); iArray++) { | |
914 | if (fClusterArrays[iArray]) { | |
915 | TClonesArray* pArray=fClusterArrays[iArray]; | |
916 | cout << " sector " << setfill(' ') << setw(2) << iArray << ": " << pArray->GetEntriesFast() << endl; | |
917 | if (bAll) { | |
918 | for (int iCluster=0; iCluster<pArray->GetEntriesFast(); iCluster++) { | |
919 | if (!pArray->At(iCluster)) continue; | |
920 | AliTPCclusterMI* pCluster=dynamic_cast<AliTPCclusterMI*>(pArray->At(iCluster)); | |
921 | if (!pCluster) break; | |
922 | cout << " AliTPCclusterMI:" | |
923 | << " row=" << pCluster->GetRow() | |
924 | << " pad=" << pCluster->GetPad() | |
925 | << " time=" << pCluster->GetTimeBin() | |
926 | << " charge=" << pCluster->GetQ() | |
927 | << " maxq=" << pCluster->GetMax() | |
928 | << endl; | |
929 | } | |
930 | } | |
931 | } | |
932 | } | |
933 | } | |
934 | cout.flags(coutflags); // restore the original flags | |
935 | } | |
936 | ||
937 | AliHLTTPCClusterAccessHLTOUT::AliTPCclusterMIContainer::iterator& AliHLTTPCClusterAccessHLTOUT::AliTPCclusterMIContainer::iterator::Next(int slice, int partition) | |
938 | { | |
939 | // switch to next cluster | |
940 | if (!fData) { | |
941 | fCluster=NULL; | |
942 | fClusterId=kAliHLTVoidDataSpec; | |
943 | return *this; | |
944 | } | |
945 | if (fClusterNo>=0 && !fCluster) { | |
946 | // end was reached before | |
947 | return *this; | |
948 | } | |
949 | fCluster=fData->NextCluster(slice, partition); | |
950 | fClusterId=fData->GetClusterId(++fClusterNo); | |
951 | if (fCluster && fClusterId!=kAliHLTVoidDataSpec) { | |
952 | fData->SetMC(fCluster, fClusterId); | |
953 | } | |
954 | // offline uses row number in physical sector, inner sector consists of | |
955 | // partitions 0 and 1, outer sector of partition 2-5 | |
956 | fRowOffset=partition<2?0:AliHLTTPCTransform::GetFirstRow(2); | |
957 | return *this; | |
958 | } |