]>
Commit | Line | Data |
---|---|---|
1 | // $Id$ | |
2 | //************************************************************************** | |
3 | //* This file is property of and copyright by the ALICE HLT Project * | |
4 | //* ALICE Experiment at CERN, All rights reserved. * | |
5 | //* * | |
6 | //* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> * | |
7 | //* for The ALICE HLT Project. * | |
8 | //* * | |
9 | //* Permission to use, copy, modify and distribute this software and its * | |
10 | //* documentation strictly for non-commercial purposes is hereby granted * | |
11 | //* without fee, provided that the above copyright notice appears in all * | |
12 | //* copies and that both the copyright notice and this permission notice * | |
13 | //* appear in the supporting documentation. The authors make no claims * | |
14 | //* about the suitability of this software for any purpose. It is * | |
15 | //* provided "as is" without express or implied warranty. * | |
16 | //************************************************************************** | |
17 | ||
18 | /// @file AliHLTTPCDataCompressionComponent.cxx | |
19 | /// @author Matthias Richter | |
20 | /// @date 2011-08-08 | |
21 | /// @brief TPC component for data compression | |
22 | /// | |
23 | ||
24 | #include "AliHLTTPCDataCompressionComponent.h" | |
25 | #include "AliHLTTPCDefinitions.h" | |
26 | #include "AliHLTTPCTrackGeometry.h" | |
27 | #include "AliHLTTPCSpacePointContainer.h" | |
28 | #include "AliHLTTPCHWCFSpacePointContainer.h" | |
29 | #include "AliHLTGlobalBarrelTrack.h" | |
30 | #include "AliHLTComponentBenchmark.h" | |
31 | #include "AliHLTDataDeflaterSimple.h" | |
32 | #include "AliHLTDataDeflaterHuffman.h" | |
33 | #include "AliHLTTPCTransform.h" | |
34 | #include "AliHLTTPCClusterMCData.h" | |
35 | #include "AliHLTTPCClusterTransformation.h" | |
36 | #include "AliHLTErrorGuard.h" | |
37 | #include "AliRawDataHeader.h" | |
38 | #include "AliCDBManager.h" | |
39 | #include "AliCDBPath.h" | |
40 | #include "AliCDBId.h" | |
41 | #include "AliCDBMetaData.h" | |
42 | #include "AliCDBEntry.h" | |
43 | #include "TH1F.h" | |
44 | #include "TFile.h" | |
45 | #include <memory> | |
46 | ||
47 | ClassImp(AliHLTTPCDataCompressionComponent) | |
48 | ||
49 | AliHLTTPCDataCompressionComponent::AliHLTTPCDataCompressionComponent() | |
50 | : AliHLTProcessor() | |
51 | , fMode(0) | |
52 | , fDeflaterMode(0) | |
53 | , fVerificationMode(0) | |
54 | , fMaxDeltaPad(AliHLTTPCDefinitions::GetMaxClusterDeltaPad()) | |
55 | , fMaxDeltaTime(AliHLTTPCDefinitions::GetMaxClusterDeltaTime()) | |
56 | , fRawInputClusters(NULL) | |
57 | , fInputClusters(NULL) | |
58 | , fTrackGrid(NULL) | |
59 | , fSpacePointGrid(NULL) | |
60 | , fpDataDeflater(NULL) | |
61 | , fHistoCompFactor(NULL) | |
62 | , fHistoResidualPad(NULL) | |
63 | , fHistoResidualTime(NULL) | |
64 | , fHistoClustersOnTracks(NULL) | |
65 | , fHistoClusterRatio(NULL) | |
66 | , fHistoTrackClusterRatio(NULL) | |
67 | , fHistogramFile() | |
68 | , fTrainingTableOutput() | |
69 | , fpBenchmark(NULL) | |
70 | , fpWrittenAssociatedClusterIds(NULL) | |
71 | , fDriftTimeFactorA(1.) | |
72 | , fDriftTimeOffsetA(0.) | |
73 | , fDriftTimeFactorC(1.) | |
74 | , fDriftTimeOffsetC(0.) | |
75 | , fVerbosity(0) | |
76 | { | |
77 | } | |
78 | ||
79 | AliHLTTPCDataCompressionComponent::~AliHLTTPCDataCompressionComponent() | |
80 | { | |
81 | /// destructor | |
82 | if (fpWrittenAssociatedClusterIds) delete fpWrittenAssociatedClusterIds; | |
83 | } | |
84 | ||
85 | ||
86 | const char* AliHLTTPCDataCompressionComponent::GetComponentID() | |
87 | { | |
88 | /// inherited from AliHLTComponent: id of the component | |
89 | return "TPCDataCompressor"; | |
90 | } | |
91 | ||
92 | ||
93 | void AliHLTTPCDataCompressionComponent::GetInputDataTypes( AliHLTComponentDataTypeList& tgtList) | |
94 | { | |
95 | /// inherited from AliHLTComponent: list of data types in the vector reference | |
96 | tgtList.clear(); | |
97 | tgtList.push_back(AliHLTTPCDefinitions::fgkHWClustersDataType); | |
98 | tgtList.push_back(AliHLTTPCDefinitions::fgkClustersDataType); | |
99 | tgtList.push_back(kAliHLTDataTypeTrack|kAliHLTDataOriginTPC); | |
100 | } | |
101 | ||
102 | AliHLTComponentDataType AliHLTTPCDataCompressionComponent::GetOutputDataType() | |
103 | { | |
104 | /// inherited from AliHLTComponent: output data type of the component. | |
105 | return kAliHLTMultipleDataType; | |
106 | } | |
107 | ||
108 | int AliHLTTPCDataCompressionComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList) | |
109 | { | |
110 | /// inherited from AliHLTComponent: multiple output data types of the component. | |
111 | tgtList.clear(); | |
112 | tgtList.push_back(AliHLTTPCDefinitions::RawClustersDataType()); | |
113 | tgtList.push_back(AliHLTTPCDefinitions::RemainingClustersCompressedDataType()); | |
114 | tgtList.push_back(AliHLTTPCDefinitions::RemainingClusterIdsDataType()); | |
115 | tgtList.push_back(AliHLTTPCDefinitions::ClusterTracksCompressedDataType()); | |
116 | tgtList.push_back(AliHLTTPCDefinitions::ClusterIdTracksDataType()); | |
117 | return tgtList.size(); | |
118 | } | |
119 | ||
120 | void AliHLTTPCDataCompressionComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier ) | |
121 | { | |
122 | /// inherited from AliHLTComponent: output data size estimator | |
123 | constBase=0; | |
124 | inputMultiplier=1.; // there should not be more data than input | |
125 | inputMultiplier+=.3; // slightly more data when using the old HWCF data with 20 Byte and raw clusters 22 Byte | |
126 | if (fpWrittenAssociatedClusterIds) inputMultiplier+=.3; // space for optional cluster id array | |
127 | } | |
128 | ||
129 | AliHLTComponent* AliHLTTPCDataCompressionComponent::Spawn() | |
130 | { | |
131 | /// inherited from AliHLTComponent: spawn function. | |
132 | return new AliHLTTPCDataCompressionComponent; | |
133 | } | |
134 | ||
135 | void AliHLTTPCDataCompressionComponent::GetOCDBObjectDescription(TMap* const targetMap) | |
136 | { | |
137 | /// Get a list of OCDB object needed for the particular component | |
138 | if (!targetMap) return; | |
139 | ||
140 | targetMap->Add(new TObjString("HLT/ConfigTPC/TPCDataCompressor"), | |
141 | new TObjString("component arguments")); | |
142 | if (fDeflaterMode==2) { | |
143 | targetMap->Add(new TObjString("HLT/ConfigTPC/TPCDataCompressorHuffmanTables"), | |
144 | new TObjString("huffman tables for deflater mode 2")); | |
145 | } | |
146 | } | |
147 | ||
148 | int AliHLTTPCDataCompressionComponent::DoEvent( const AliHLTComponentEventData& /*evtData*/, | |
149 | const AliHLTComponentBlockData* /*inputBlocks*/, | |
150 | AliHLTComponentTriggerData& /*trigData*/, | |
151 | AliHLTUInt8_t* outputPtr, | |
152 | AliHLTUInt32_t& size, | |
153 | AliHLTComponentBlockDataList& outputBlocks ) | |
154 | { | |
155 | /// inherited from AliHLTProcessor: data processing | |
156 | int iResult=0; | |
157 | AliHLTUInt32_t capacity=size; | |
158 | size=0; | |
159 | ||
160 | if (!IsDataEvent()) return 0; | |
161 | ||
162 | if (!fRawInputClusters) { | |
163 | return -ENODEV; | |
164 | } | |
165 | ||
166 | if (GetBenchmarkInstance()) { | |
167 | GetBenchmarkInstance()->StartNewEvent(); | |
168 | GetBenchmarkInstance()->Start(0); | |
169 | } | |
170 | ||
171 | // Process an event | |
172 | // Loop over all input blocks in the event | |
173 | bool bHaveMC=(GetFirstInputBlock(AliHLTTPCDefinitions::fgkAliHLTDataTypeClusterMCInfo | kAliHLTDataOriginTPC))!=NULL; | |
174 | if ((bHaveMC || fVerificationMode>0) && fpWrittenAssociatedClusterIds==NULL) { | |
175 | fpWrittenAssociatedClusterIds=new vector<AliHLTUInt32_t>; | |
176 | } | |
177 | ||
178 | const AliHLTComponentBlockData* pDesc=NULL; | |
179 | ||
180 | AliHLTUInt8_t minSlice=0xFF, maxSlice=0xFF, minPatch=0xFF, maxPatch=0xFF; | |
181 | AliHLTUInt32_t inputRawClusterSize=0; | |
182 | AliHLTUInt32_t outputDataSize=0; | |
183 | int allClusters=0; | |
184 | int associatedClusters=0; | |
185 | float bz=GetBz(); | |
186 | ||
187 | /// input track array | |
188 | vector<AliHLTGlobalBarrelTrack> inputTrackArray; | |
189 | ||
190 | if (GetBenchmarkInstance()) { | |
191 | GetBenchmarkInstance()->Start(2); | |
192 | } | |
193 | ||
194 | // transformed clusters | |
195 | if (fMode==10) { // FIXME: condition to be adjusted | |
196 | for (pDesc=GetFirstInputBlock(AliHLTTPCDefinitions::fgkClustersDataType); | |
197 | pDesc!=NULL; pDesc=GetNextInputBlock()) { | |
198 | if (GetBenchmarkInstance()) { | |
199 | GetBenchmarkInstance()->AddInput(pDesc->fSize); | |
200 | } | |
201 | AliHLTUInt8_t slice = 0; | |
202 | AliHLTUInt8_t patch = 0; | |
203 | slice = AliHLTTPCDefinitions::GetMinSliceNr( pDesc->fSpecification ); | |
204 | patch = AliHLTTPCDefinitions::GetMinPatchNr( pDesc->fSpecification ); | |
205 | if ( minSlice==0xFF || slice<minSlice ) minSlice = slice; | |
206 | if ( maxSlice==0xFF || slice>maxSlice ) maxSlice = slice; | |
207 | if ( minPatch==0xFF || patch<minPatch ) minPatch = patch; | |
208 | if ( maxPatch==0xFF || patch>maxPatch ) maxPatch = patch; | |
209 | if (fInputClusters) { | |
210 | fInputClusters->AddInputBlock(pDesc); | |
211 | } | |
212 | } | |
213 | if (GetBenchmarkInstance()) { | |
214 | GetBenchmarkInstance()->Stop(2); | |
215 | GetBenchmarkInstance()->Start(3); | |
216 | } | |
217 | } | |
218 | ||
219 | vector<int> trackindexmap; // stores index for every track id | |
220 | ||
221 | // track data input | |
222 | if (fMode==2 || fMode==4) { | |
223 | for (pDesc=GetFirstInputBlock(kAliHLTDataTypeTrack|kAliHLTDataOriginTPC); | |
224 | pDesc!=NULL; pDesc=GetNextInputBlock()) { | |
225 | if (GetBenchmarkInstance()) { | |
226 | GetBenchmarkInstance()->AddInput(pDesc->fSize); | |
227 | } | |
228 | AliHLTUInt8_t slice = 0; | |
229 | AliHLTUInt8_t patch = 0; | |
230 | slice = AliHLTTPCDefinitions::GetMinSliceNr( pDesc->fSpecification ); | |
231 | patch = AliHLTTPCDefinitions::GetMinPatchNr( pDesc->fSpecification ); | |
232 | if ( minSlice==0xFF || slice<minSlice ) minSlice = slice; | |
233 | if ( maxSlice==0xFF || slice>maxSlice ) maxSlice = slice; | |
234 | if ( minPatch==0xFF || patch<minPatch ) minPatch = patch; | |
235 | if ( maxPatch==0xFF || patch>maxPatch ) maxPatch = patch; | |
236 | const AliHLTTracksData* pTracks=reinterpret_cast<const AliHLTTracksData*>(pDesc->fPtr); | |
237 | if ((iResult=AliHLTGlobalBarrelTrack::ConvertTrackDataArray(pTracks, pDesc->fSize, inputTrackArray))<0) { | |
238 | return iResult; | |
239 | } | |
240 | trackindexmap.resize(inputTrackArray.size(), -1); | |
241 | } | |
242 | } | |
243 | ||
244 | if (GetBenchmarkInstance()) { | |
245 | GetBenchmarkInstance()->Stop(3); | |
246 | GetBenchmarkInstance()->Start(4); | |
247 | } | |
248 | ||
249 | // processing | |
250 | int trackindex=0; | |
251 | for (vector<AliHLTGlobalBarrelTrack>::iterator track=inputTrackArray.begin(); | |
252 | track!=inputTrackArray.end(); | |
253 | track++, trackindex++) { | |
254 | int trackID=track->GetID(); | |
255 | if (trackID<0) { | |
256 | // FIXME: error guard | |
257 | HLTError("invalid track ID"); | |
258 | continue; | |
259 | } | |
260 | if (trackID>=(int)trackindexmap.size()) | |
261 | trackindexmap.resize(trackID+1, -1); | |
262 | trackindexmap[trackID]=trackindex; | |
263 | ||
264 | if (fVerbosity>0) { | |
265 | UInt_t nofPoints=track->GetNumberOfPoints(); | |
266 | const UInt_t* points=track->GetPoints(); | |
267 | for (unsigned i=0; i<nofPoints; i++) { | |
268 | int slice=AliHLTTPCSpacePointData::GetSlice(points[i]); | |
269 | int partition=AliHLTTPCSpacePointData::GetPatch(points[i]); | |
270 | int number=AliHLTTPCSpacePointData::GetNumber(points[i]); | |
271 | HLTInfo("track %d point %d id 0x%08x slice %d partition %d number %d", track->GetID(), i, points[i], slice, partition, number); | |
272 | } | |
273 | } | |
274 | ||
275 | AliHLTTPCTrackGeometry* trackpoints=new AliHLTTPCTrackGeometry; | |
276 | if (!trackpoints) continue; | |
277 | HLTDebug("track %d id %d:", trackindex, trackID); | |
278 | ||
279 | // in order to avoid rounding errors the track points are | |
280 | // calculated in exactly the same way as in the decoding | |
281 | // Thats why the track instance can not be used directly | |
282 | // but a new instance is created from the values in the | |
283 | // storage format. | |
284 | // think about moving that to some common code used by | |
285 | // both compression and decoding | |
286 | AliHLTExternalTrackParam param; | |
287 | memset(¶m, 0, sizeof(param)); | |
288 | float alpha=track->GetAlpha(); | |
289 | while (alpha<0.) alpha+=TMath::TwoPi(); | |
290 | while (alpha>TMath::TwoPi()) alpha-=TMath::TwoPi(); | |
291 | AliHLTUInt8_t tSlice=AliHLTUInt8_t(9*alpha/TMath::Pi()); | |
292 | param.fAlpha =( tSlice + 0.5 ) * TMath::Pi() / 9.0; | |
293 | if (param.fAlpha>TMath::TwoPi()) param.fAlpha-=TMath::TwoPi(); | |
294 | param.fX = track->GetX(); | |
295 | param.fY = track->GetY(); | |
296 | param.fZ = track->GetZ(); | |
297 | param.fSinPsi = track->GetSnp(); | |
298 | param.fTgl = track->GetTgl(); | |
299 | param.fq1Pt = track->GetSigned1Pt(); | |
300 | AliHLTGlobalBarrelTrack ctrack(param); | |
301 | ctrack.CalculateHelixParams(bz); | |
302 | trackpoints->InitDriftTimeTransformation(fDriftTimeFactorA, fDriftTimeOffsetA, fDriftTimeFactorC, fDriftTimeOffsetC); | |
303 | trackpoints->SetTrackId(trackID); | |
304 | trackpoints->CalculateTrackPoints(ctrack); | |
305 | trackpoints->RegisterTrackPoints(fTrackGrid); | |
306 | track->SetTrackGeometry(trackpoints); | |
307 | } | |
308 | ||
309 | for (vector<AliHLTGlobalBarrelTrack>::const_iterator track=inputTrackArray.begin(); | |
310 | track!=inputTrackArray.end(); | |
311 | track++) { | |
312 | AliHLTTrackGeometry* trackpoints=track->GetTrackGeometry(); | |
313 | if (!trackpoints) continue; | |
314 | trackpoints->FillTrackPoints(fTrackGrid); | |
315 | } | |
316 | if (fVerbosity>0) { | |
317 | fTrackGrid->Print(); | |
318 | } | |
319 | ||
320 | if (GetBenchmarkInstance()) { | |
321 | GetBenchmarkInstance()->Stop(4); | |
322 | GetBenchmarkInstance()->Start(5); | |
323 | } | |
324 | ||
325 | // loop over raw cluster blocks, assign to tracks and write | |
326 | // unassigned clusters | |
327 | for (pDesc=GetFirstInputBlock(AliHLTTPCDefinitions::fgkHWClustersDataType); | |
328 | pDesc!=NULL; pDesc=GetNextInputBlock()) { | |
329 | if (pDesc->fSize<=sizeof(AliRawDataHeader)) continue; | |
330 | if (GetBenchmarkInstance()) { | |
331 | GetBenchmarkInstance()->Start(1); | |
332 | GetBenchmarkInstance()->AddInput(pDesc->fSize); | |
333 | } | |
334 | AliHLTUInt8_t slice = 0; | |
335 | AliHLTUInt8_t patch = 0; | |
336 | slice = AliHLTTPCDefinitions::GetMinSliceNr( pDesc->fSpecification ); | |
337 | patch = AliHLTTPCDefinitions::GetMinPatchNr( pDesc->fSpecification ); | |
338 | if ( minSlice==0xFF || slice<minSlice ) minSlice = slice; | |
339 | if ( maxSlice==0xFF || slice>maxSlice ) maxSlice = slice; | |
340 | if ( minPatch==0xFF || patch<minPatch ) minPatch = patch; | |
341 | if ( maxPatch==0xFF || patch>maxPatch ) maxPatch = patch; | |
342 | inputRawClusterSize+=pDesc->fSize; | |
343 | ||
344 | // add the data and populate the index grid | |
345 | fRawInputClusters->AddInputBlock(pDesc); | |
346 | fRawInputClusters->PopulateAccessGrid(fSpacePointGrid, pDesc->fSpecification); | |
347 | if (fVerbosity>0 && fSpacePointGrid->GetNumberOfSpacePoints()>0) { | |
348 | HLTInfo("index grid slice %d partition %d", slice, patch); | |
349 | fSpacePointGrid->Print(); | |
350 | for (AliHLTSpacePointContainer::AliHLTSpacePointPropertyGrid::iterator& cl=fSpacePointGrid->begin(); | |
351 | cl!=fSpacePointGrid->end(); cl++) { | |
352 | AliHLTUInt32_t id=cl.Data().fId; | |
353 | float row=fRawInputClusters->GetX(id); | |
354 | float pad=fRawInputClusters->GetY(id); | |
355 | float time=fRawInputClusters->GetZ(id); | |
356 | HLTInfo(" cluster id 0x%08x: row %f pad %f time %f", id, row, pad, time); | |
357 | } | |
358 | } | |
359 | if (GetBenchmarkInstance()) { | |
360 | GetBenchmarkInstance()->Stop(1); | |
361 | GetBenchmarkInstance()->Start(4); | |
362 | } | |
363 | ||
364 | // process the clusters per padrow and check the track grid | |
365 | // for tracks crossing that particular padrow | |
366 | if (GetBenchmarkInstance()) { | |
367 | GetBenchmarkInstance()->Stop(4); | |
368 | GetBenchmarkInstance()->Start(5); | |
369 | } | |
370 | allClusters+=fSpacePointGrid->GetNumberOfSpacePoints(); | |
371 | iResult=ProcessTrackClusters(&inputTrackArray[0], inputTrackArray.size(), fTrackGrid, trackindexmap, fSpacePointGrid, fRawInputClusters, slice, patch); | |
372 | int assignedInThisPartition=0; | |
373 | if (iResult>=0) { | |
374 | assignedInThisPartition=iResult; | |
375 | associatedClusters+=iResult; | |
376 | } | |
377 | iResult=ProcessRemainingClusters(&inputTrackArray[0], inputTrackArray.size(), fTrackGrid, trackindexmap, fSpacePointGrid, fRawInputClusters, slice, patch); | |
378 | if (iResult>=0) { | |
379 | if (fSpacePointGrid->GetNumberOfSpacePoints()>0) { | |
380 | if (fVerbosity>0) HLTInfo("associated %d (%d) of %d clusters in slice %d partition %d", iResult+assignedInThisPartition, assignedInThisPartition, fSpacePointGrid->GetNumberOfSpacePoints(), slice, patch); | |
381 | } | |
382 | associatedClusters+=iResult; | |
383 | } | |
384 | ||
385 | // write all remaining clusters not yet assigned to tracks | |
386 | // the index grid is used to write sorted in padrow | |
387 | // FIXME: decoder index instead of data specification to be used | |
388 | // use an external access grid to reduce allocated memory | |
389 | // set to NULL after writing the clusters | |
390 | const char* writeoptions=""; | |
391 | if (fpWrittenAssociatedClusterIds) { | |
392 | writeoptions="write-cluster-ids"; | |
393 | } | |
394 | fRawInputClusters->SetSpacePointPropertyGrid(pDesc->fSpecification, fSpacePointGrid); | |
395 | iResult=fRawInputClusters->Write(outputPtr+size, capacity-size, outputBlocks, fpDataDeflater, writeoptions); | |
396 | fRawInputClusters->SetSpacePointPropertyGrid(pDesc->fSpecification, NULL); | |
397 | if (iResult>=0) { | |
398 | size+=iResult; | |
399 | outputDataSize+=iResult; | |
400 | // the size of the optional cluster id array must be subtracted | |
401 | if (fpWrittenAssociatedClusterIds && outputBlocks.size()>0 && | |
402 | outputBlocks.back().fDataType==AliHLTTPCDefinitions::RemainingClusterIdsDataType()) { | |
403 | outputDataSize-=outputBlocks.back().fSize; | |
404 | } | |
405 | if (GetBenchmarkInstance()) GetBenchmarkInstance()->AddOutput(iResult); | |
406 | } | |
407 | if (GetBenchmarkInstance()) { | |
408 | GetBenchmarkInstance()->Stop(5); | |
409 | } | |
410 | ||
411 | fSpacePointGrid->Clear(); | |
412 | } | |
413 | if (fHistoClusterRatio && allClusters>0) { | |
414 | if (fVerbosity>0) HLTInfo("associated %d of %d clusters to tracks", associatedClusters, allClusters); | |
415 | float ratio=associatedClusters; ratio/=allClusters; | |
416 | fHistoClusterRatio->Fill(ratio); | |
417 | } | |
418 | ||
419 | // output of track model clusters | |
420 | if (iResult>=0) do { | |
421 | AliHLTUInt32_t tracksBufferOffset=sizeof(AliHLTTPCTrackModelBlock); | |
422 | if (capacity-size<tracksBufferOffset) { | |
423 | iResult=-ENOSPC; | |
424 | break; | |
425 | } | |
426 | if (fpWrittenAssociatedClusterIds) fpWrittenAssociatedClusterIds->clear(); | |
427 | AliHLTTPCTrackModelBlock* trackModelBlock=reinterpret_cast<AliHLTTPCTrackModelBlock*>(outputPtr+size); | |
428 | trackModelBlock->fVersion=1; | |
429 | trackModelBlock->fDeflaterMode=fpDataDeflater?fpDataDeflater->GetDeflaterVersion():0; | |
430 | trackModelBlock->fTrackCount=inputTrackArray.size(); | |
431 | trackModelBlock->fClusterCount=0; | |
432 | trackModelBlock->fGlobalParameterCnt=5; | |
433 | tracksBufferOffset+=trackModelBlock->fGlobalParameterCnt*sizeof(trackModelBlock->fGlobalParameters); | |
434 | if (capacity-size<tracksBufferOffset) { | |
435 | iResult=-ENOSPC; | |
436 | break; | |
437 | } | |
438 | ||
439 | AliHLTUInt32_t parameterIndex=0; | |
440 | trackModelBlock->fGlobalParameters[parameterIndex++]=bz; | |
441 | trackModelBlock->fGlobalParameters[parameterIndex++]=fDriftTimeFactorA; | |
442 | trackModelBlock->fGlobalParameters[parameterIndex++]=fDriftTimeOffsetA; | |
443 | trackModelBlock->fGlobalParameters[parameterIndex++]=fDriftTimeFactorC; | |
444 | trackModelBlock->fGlobalParameters[parameterIndex++]=fDriftTimeOffsetC; | |
445 | if (parameterIndex!=trackModelBlock->fGlobalParameterCnt) { | |
446 | HLTError("internal error, size of parameter array has changed without providing all values"); | |
447 | iResult=-EFAULT; | |
448 | break; | |
449 | } | |
450 | ||
451 | if (trackindexmap.size()>0) {// condition for track model compression | |
452 | iResult=WriteTrackClusters(inputTrackArray, fRawInputClusters, fpDataDeflater, outputPtr+size+tracksBufferOffset, capacity-size-tracksBufferOffset); | |
453 | if (iResult>=0) { | |
454 | AliHLTComponent_BlockData bd; | |
455 | FillBlockData(bd); | |
456 | bd.fOffset = size; | |
457 | bd.fSize = tracksBufferOffset+iResult; | |
458 | bd.fDataType = AliHLTTPCDefinitions::ClusterTracksCompressedDataType(); | |
459 | bd.fSpecification = AliHLTTPCDefinitions::EncodeDataSpecification(minSlice, maxSlice, minPatch, maxPatch); | |
460 | outputBlocks.push_back(bd); | |
461 | size += bd.fSize; | |
462 | outputDataSize+=bd.fSize; | |
463 | HLTBenchmark("track data block of %d tracks: size %d", inputTrackArray.size(), bd.fSize); | |
464 | ||
465 | if (fpWrittenAssociatedClusterIds && fpWrittenAssociatedClusterIds->size()>0) { | |
466 | AliHLTComponent::FillBlockData(bd); | |
467 | bd.fOffset = size; | |
468 | bd.fSize = fpWrittenAssociatedClusterIds->size()*sizeof(vector<AliHLTUInt32_t>::value_type); | |
469 | if (capacity-size>bd.fSize) { | |
470 | memcpy(outputPtr+bd.fOffset, &(*fpWrittenAssociatedClusterIds)[0], bd.fSize); | |
471 | bd.fDataType = AliHLTTPCDefinitions::ClusterIdTracksDataType(); | |
472 | bd.fSpecification = AliHLTTPCDefinitions::EncodeDataSpecification(minSlice, maxSlice, minPatch, maxPatch); | |
473 | outputBlocks.push_back(bd); | |
474 | size += bd.fSize; | |
475 | } else { | |
476 | iResult=-ENOSPC; | |
477 | } | |
478 | ||
479 | fpWrittenAssociatedClusterIds->clear(); | |
480 | } | |
481 | } | |
482 | } | |
483 | } while (0); | |
484 | ||
485 | fRawInputClusters->Clear(); | |
486 | ||
487 | float compressionFactor=(float)inputRawClusterSize; | |
488 | if ((outputDataSize)>0) compressionFactor/=outputDataSize; | |
489 | else compressionFactor=0.; | |
490 | if (fHistoCompFactor) fHistoCompFactor->Fill(compressionFactor); | |
491 | ||
492 | if (GetBenchmarkInstance()) { | |
493 | GetBenchmarkInstance()->Stop(0); | |
494 | if (fDeflaterMode!=3) { | |
495 | HLTBenchmark("%s - compression factor %.2f", GetBenchmarkInstance()->GetStatistics(), compressionFactor); | |
496 | } else { | |
497 | HLTBenchmark("%s", GetBenchmarkInstance()->GetStatistics()); | |
498 | } | |
499 | } | |
500 | ||
501 | if (fInputClusters) { | |
502 | fInputClusters->Clear(); | |
503 | } | |
504 | if (fRawInputClusters) { | |
505 | fRawInputClusters->Clear(); | |
506 | } | |
507 | if (fTrackGrid) { | |
508 | fTrackGrid->Clear(); | |
509 | } | |
510 | ||
511 | // forward MC labels | |
512 | for (pDesc=GetFirstInputBlock(AliHLTTPCDefinitions::fgkAliHLTDataTypeClusterMCInfo | kAliHLTDataOriginTPC); | |
513 | pDesc!=NULL; pDesc=GetNextInputBlock()) { | |
514 | outputBlocks.push_back(*pDesc); | |
515 | } | |
516 | ||
517 | return iResult; | |
518 | } | |
519 | ||
520 | int AliHLTTPCDataCompressionComponent::ProcessTrackClusters(AliHLTGlobalBarrelTrack* pTracks, unsigned nofTracks, | |
521 | AliHLTTrackGeometry::AliHLTTrackGrid* pTrackIndex, | |
522 | const vector<int>& trackIndexMap, | |
523 | AliHLTSpacePointContainer::AliHLTSpacePointPropertyGrid* pClusterIndex, | |
524 | AliHLTSpacePointContainer* pClusters, | |
525 | int slice, int partition) const | |
526 | { | |
527 | // process to assigned track clusters | |
528 | int iResult=0; | |
529 | int assignedClusters=0; | |
530 | if (!pTracks || nofTracks==0) return 0; | |
531 | ||
532 | vector<int> processedTracks(nofTracks, -1); | |
533 | for (AliHLTTrackGeometry::AliHLTTrackGrid::iterator& trackId=pTrackIndex->begin(slice, partition, -1); | |
534 | trackId!=pTrackIndex->end(); trackId++) { | |
535 | if (trackId.Data()>=trackIndexMap.size()) { | |
536 | HLTError("can not find track id %d in index map of size %d", trackId.Data(), trackIndexMap.size()); | |
537 | continue; | |
538 | } | |
539 | int trackindex=trackIndexMap[trackId.Data()]; | |
540 | if (trackindex<0 || trackindex>=(int)nofTracks) { | |
541 | HLTError("invalid index %d found for track id %d", trackindex, trackId.Data()); | |
542 | continue; | |
543 | } | |
544 | if (processedTracks[trackindex]>0) continue; | |
545 | processedTracks[trackindex]=1; | |
546 | AliHLTGlobalBarrelTrack& track=pTracks[trackindex]; | |
547 | if (!track.GetTrackGeometry()) { | |
548 | HLTError("can not find track geometry for track %d", trackId.Data()); | |
549 | continue; | |
550 | } | |
551 | AliHLTTPCTrackGeometry* pTrackPoints=dynamic_cast<AliHLTTPCTrackGeometry*>(track.GetTrackGeometry()); | |
552 | if (!pTrackPoints) { | |
553 | HLTError("invalid track geometry type for track %d, expecting AliHLTTPCTrackGeometry", trackId.Data()); | |
554 | continue; | |
555 | } | |
556 | ||
557 | UInt_t nofTrackPoints=track.GetNumberOfPoints(); | |
558 | const UInt_t* trackPoints=track.GetPoints(); | |
559 | for (unsigned i=0; i<nofTrackPoints; i++) { | |
560 | const AliHLTUInt32_t& clusterId=trackPoints[i]; | |
561 | if (AliHLTTPCSpacePointData::GetSlice(clusterId)!=(unsigned)slice || | |
562 | AliHLTTPCSpacePointData::GetPatch(clusterId)!=(unsigned)partition) { | |
563 | // not in the current partition; | |
564 | continue; | |
565 | } | |
566 | ||
567 | int clusterrow=(int)pClusters->GetX(clusterId); | |
568 | AliHLTUInt32_t pointId=AliHLTTPCSpacePointData::GetID(slice, partition, clusterrow); | |
569 | AliHLTTrackGeometry::AliHLTTrackPoint* point=pTrackPoints->GetRawTrackPoint(pointId); | |
570 | if (!point) { | |
571 | //HLTError("can not find track point slice %d partition %d padrow %d (0x%08x) of track %d", slice, partition, clusterrow, pointId, trackId.Data()); | |
572 | continue; | |
573 | } | |
574 | float pad=point->GetU(); | |
575 | float time=point->GetV(); | |
576 | ||
577 | iResult=FindCellClusters(trackId.Data(), clusterrow, pad, time, pClusterIndex, pClusters, point, clusterId); | |
578 | if (iResult>0) assignedClusters+=iResult; | |
579 | } | |
580 | } | |
581 | return assignedClusters; | |
582 | } | |
583 | ||
584 | int AliHLTTPCDataCompressionComponent::ProcessRemainingClusters(AliHLTGlobalBarrelTrack* pTracks, unsigned nofTracks, | |
585 | AliHLTTrackGeometry::AliHLTTrackGrid* pTrackIndex, | |
586 | const vector<int>& trackIndexMap, | |
587 | AliHLTSpacePointContainer::AliHLTSpacePointPropertyGrid* pClusterIndex, | |
588 | AliHLTSpacePointContainer* pClusters, | |
589 | int slice, int partition) const | |
590 | { | |
591 | // assign remaining clusters to tracks | |
592 | int iResult=0; | |
593 | int associatedClusters=0; | |
594 | if (!pTracks || nofTracks==0) return 0; | |
595 | ||
596 | for (int padrow=0; padrow<AliHLTTPCTransform::GetNRows(partition); padrow++) { | |
597 | for (AliHLTTrackGeometry::AliHLTTrackGrid::iterator& trackId=pTrackIndex->begin(slice, partition, padrow); | |
598 | trackId!=pTrackIndex->end(); trackId++) { | |
599 | if (trackId.Data()>=trackIndexMap.size()) { | |
600 | HLTError("can not find track id %d in index map of size %d", trackId.Data(), trackIndexMap.size()); | |
601 | continue; | |
602 | } | |
603 | int trackindex=trackIndexMap[trackId.Data()]; | |
604 | if (trackindex<0 || trackindex>=(int)nofTracks) { | |
605 | HLTError("invalid index %d found for track id %d", trackindex, trackId.Data()); | |
606 | continue; | |
607 | } | |
608 | AliHLTGlobalBarrelTrack& track=pTracks[trackindex]; | |
609 | if (!track.GetTrackGeometry()) { | |
610 | HLTError("can not find track geometry for track %d", trackId.Data()); | |
611 | continue; | |
612 | } | |
613 | AliHLTTPCTrackGeometry* pTrackPoints=dynamic_cast<AliHLTTPCTrackGeometry*>(track.GetTrackGeometry()); | |
614 | if (!pTrackPoints) { | |
615 | HLTError("invalid track geometry type for track %d, expecting AliHLTTPCTrackGeometry", trackId.Data()); | |
616 | continue; | |
617 | } | |
618 | AliHLTUInt32_t pointId=AliHLTTPCSpacePointData::GetID(slice, partition, padrow); | |
619 | AliHLTTrackGeometry::AliHLTTrackPoint* point=pTrackPoints->GetRawTrackPoint(pointId); | |
620 | if (!point) { | |
621 | //HLTError("can not find track point slice %d partition %d padrow %d (0x%08x) of track %d", slice, partition, padrow, pointId, trackId.Data()); | |
622 | continue; | |
623 | } | |
624 | float pad=point->GetU(); | |
625 | float time=point->GetV(); | |
626 | ||
627 | iResult=FindCellClusters(trackId.Data(), padrow, pad, time, pClusterIndex, pClusters, point); | |
628 | if (iResult>0) associatedClusters+=iResult; | |
629 | if (fVerbosity>0) { | |
630 | HLTInfo("trackpoint track %d slice %d partition %d padrow %d: %.3f \t%.3f - associated %d", track.GetID(), slice, partition, padrow, pad, time, iResult); | |
631 | } | |
632 | } | |
633 | } | |
634 | if (iResult<0) return iResult; | |
635 | return associatedClusters; | |
636 | } | |
637 | ||
638 | int AliHLTTPCDataCompressionComponent::FindCellClusters(int trackId, int padrow, float pad, float time, | |
639 | AliHLTSpacePointContainer::AliHLTSpacePointPropertyGrid* pClusterIndex, | |
640 | AliHLTSpacePointContainer* pClusters, | |
641 | AliHLTTrackGeometry::AliHLTTrackPoint* pTrackPoint, | |
642 | AliHLTUInt32_t clusterId) const | |
643 | { | |
644 | // check index cell for entries and assign to track | |
645 | int count=0; | |
646 | // search a 4x4 matrix out of the 9x9 matrix around the cell addressed by | |
647 | // pad and time | |
648 | int rowindex=pClusterIndex->GetXIndex((float)padrow); | |
649 | int padstartindex=pClusterIndex->GetYIndex(pad); | |
650 | int timestartindex=pClusterIndex->GetZIndex(time); | |
651 | int cellindex=pClusterIndex->Index(rowindex, padstartindex, timestartindex); | |
652 | float centerpad=pClusterIndex->GetCenterY(cellindex); | |
653 | float centertime=pClusterIndex->GetCenterZ(cellindex); | |
654 | if ((TMath::Abs(centerpad-pad)>fMaxDeltaPad && pad>0.) || | |
655 | (TMath::Abs(centertime-time)>fMaxDeltaTime && time>0.)) { | |
656 | ALIHLTERRORGUARD(20, "invalid pad center calculation, please check dimensions if dimensions of index grid match the maximum possible deviation"); | |
657 | } | |
658 | ||
659 | int paddirection=1; | |
660 | int timedirection=1; | |
661 | if (centerpad>pad) paddirection=-1; | |
662 | if (centertime>time) timedirection=-1; | |
663 | for (int padcount=0, padindex=padstartindex; padcount<2; padcount++, padindex+=paddirection) { | |
664 | if (padindex<0) continue; | |
665 | if (padindex>=pClusterIndex->GetDimensionY()) break; | |
666 | for (int timecount=0, timeindex=timestartindex; timecount<2; timecount++, timeindex+=timedirection) { | |
667 | if (timeindex<0) continue; | |
668 | if (timeindex>=pClusterIndex->GetDimensionZ()) break; | |
669 | cellindex=pClusterIndex->Index(rowindex, padindex, timeindex); | |
670 | float cellpad=pClusterIndex->GetCenterY(cellindex); | |
671 | float celltime=pClusterIndex->GetCenterZ(cellindex); | |
672 | for (AliHLTSpacePointContainer::AliHLTSpacePointPropertyGrid::iterator& cl=pClusterIndex->begin((float)padrow, cellpad, celltime); | |
673 | cl!=pClusterIndex->end(); cl++) { | |
674 | if (cl.Data().fTrackId>=0) continue; | |
675 | if (clusterId!=(~(AliHLTUInt32_t)0) && clusterId!=cl.Data().fId) continue; | |
676 | if (TMath::Abs(padrow-pClusters->GetX(cl.Data().fId))>=1.) { | |
677 | HLTError("cluster 0x%08x: mismatch on padrow: trackpoint %d cluster %f", cl.Data().fId, padrow, pClusters->GetX(cl.Data().fId)); | |
678 | continue; | |
679 | } | |
680 | float clusterpad=pClusters->GetY(cl.Data().fId); | |
681 | float clustertime=pClusters->GetZ(cl.Data().fId); | |
682 | if (TMath::Abs(clusterpad-pad)<fMaxDeltaPad && | |
683 | TMath::Abs(clustertime-time)<fMaxDeltaTime) { | |
684 | // add this cluster to the track point and mark in the index grid | |
685 | cl.Data().fTrackId=trackId; | |
686 | pTrackPoint->AddAssociatedSpacePoint(cl.Data().fId, clusterpad-pad, clustertime-time); | |
687 | count++; | |
688 | } | |
689 | if (clusterId!=(~(AliHLTUInt32_t)0)) break; | |
690 | } | |
691 | } | |
692 | } | |
693 | return count; | |
694 | } | |
695 | ||
696 | int AliHLTTPCDataCompressionComponent::WriteTrackClusters(const vector<AliHLTGlobalBarrelTrack>& tracks, | |
697 | AliHLTSpacePointContainer* pSpacePoints, | |
698 | AliHLTDataDeflater* pDeflater, | |
699 | AliHLTUInt8_t* outputPtr, | |
700 | AliHLTUInt32_t capacity) const | |
701 | { | |
702 | // write the track data block including all associated clusters | |
703 | AliHLTUInt32_t size=0; | |
704 | for (vector<AliHLTGlobalBarrelTrack>::const_iterator track=tracks.begin(); | |
705 | track!=tracks.end(); | |
706 | track++) { | |
707 | if (!track->GetTrackGeometry()) { | |
708 | HLTError("can not find track geometry for track %d", track->GetID()); | |
709 | return -EBADF; | |
710 | } | |
711 | AliHLTTPCTrackGeometry* pTrackPoints=dynamic_cast<AliHLTTPCTrackGeometry*>(track->GetTrackGeometry()); | |
712 | if (!pTrackPoints) { | |
713 | HLTError("invalid track geometry type for track %d, expecting AliHLTTPCTrackGeometry", track->GetID()); | |
714 | return -EBADF; | |
715 | } | |
716 | ||
717 | int result=pTrackPoints->Write(*track, pSpacePoints, pDeflater, outputPtr+size, capacity-size, fpWrittenAssociatedClusterIds); | |
718 | if (result<0) return result; | |
719 | size+=result; | |
720 | ||
721 | UInt_t nofTrackPoints=track->GetNumberOfPoints(); | |
722 | const UInt_t* trackPoints=track->GetPoints(); | |
723 | ||
724 | int assignedPoints=0; | |
725 | int assignedTrackPoints=0; | |
726 | const vector<AliHLTTrackGeometry::AliHLTTrackPoint>& rawPoints=pTrackPoints->GetRawPoints(); | |
727 | for (vector<AliHLTTrackGeometry::AliHLTTrackPoint>::const_iterator point=rawPoints.begin(); | |
728 | point!=rawPoints.end(); point++) { | |
729 | const vector<AliHLTTrackGeometry::AliHLTTrackSpacepoint>& spacePoints=point->GetSpacepoints(); | |
730 | for (vector<AliHLTTrackGeometry::AliHLTTrackSpacepoint>::const_iterator spacePoint=spacePoints.begin(); | |
731 | spacePoint!=spacePoints.end(); spacePoint++) { | |
732 | float dpad=spacePoint->GetResidual(0); | |
733 | float dtime=spacePoint->GetResidual(1); | |
734 | if (dpad>-1000 && dtime>-1000 && fHistoResidualPad && fHistoResidualTime) { | |
735 | fHistoResidualPad->Fill(dpad); | |
736 | fHistoResidualTime->Fill(dtime); | |
737 | } | |
738 | assignedPoints++; | |
739 | for (unsigned i=0; i<nofTrackPoints; i++) { | |
740 | if (trackPoints[i]==spacePoint->fId) { | |
741 | assignedTrackPoints++; | |
742 | break; | |
743 | } | |
744 | } | |
745 | } | |
746 | } | |
747 | if (fHistoClustersOnTracks) { | |
748 | fHistoClustersOnTracks->Fill(assignedPoints); | |
749 | } | |
750 | if (fHistoTrackClusterRatio && nofTrackPoints>0) { | |
751 | float ratio=assignedTrackPoints; ratio/=nofTrackPoints; | |
752 | fHistoTrackClusterRatio->Fill(ratio); | |
753 | } | |
754 | } | |
755 | return size; | |
756 | } | |
757 | ||
758 | int AliHLTTPCDataCompressionComponent::DoInit( int argc, const char** argv ) | |
759 | { | |
760 | /// inherited from AliHLTComponent: component initialisation and argument scan. | |
761 | int iResult=0; | |
762 | ||
763 | // component configuration | |
764 | //Stage 1: default initialization. | |
765 | //Default values. | |
766 | ||
767 | //Stage 2: OCDB. | |
768 | TString cdbPath("HLT/ConfigTPC/"); | |
769 | cdbPath += GetComponentID(); | |
770 | // | |
771 | iResult = ConfigureFromCDBTObjString(cdbPath); | |
772 | if (iResult < 0) | |
773 | return iResult; | |
774 | ||
775 | //Stage 3: command line arguments. | |
776 | if (argc && (iResult = ConfigureFromArgumentString(argc, argv)) < 0) | |
777 | return iResult; | |
778 | ||
779 | std::auto_ptr<AliHLTComponentBenchmark> benchmark(new AliHLTComponentBenchmark); | |
780 | if (benchmark.get()) { | |
781 | benchmark->SetTimer(0,"total"); | |
782 | benchmark->SetTimer(1,"rawclusterinput"); | |
783 | benchmark->SetTimer(2,"clusterinput"); | |
784 | benchmark->SetTimer(3,"trackinput"); | |
785 | benchmark->SetTimer(4,"processing"); | |
786 | benchmark->SetTimer(5,"output"); | |
787 | } else { | |
788 | return -ENOMEM; | |
789 | } | |
790 | ||
791 | unsigned spacePointContainerMode=0; | |
792 | if (fMode==2 || fMode==4) { | |
793 | // initialize map data for cluster access in the track association loop | |
794 | spacePointContainerMode|=AliHLTTPCHWCFSpacePointContainer::kModeCreateMap; | |
795 | } | |
796 | if (fMode==3 || fMode==4) { | |
797 | // optimized storage format: differential pad and time storage | |
798 | spacePointContainerMode|=AliHLTTPCHWCFSpacePointContainer::kModeDifferentialPadTime; | |
799 | } | |
800 | std::auto_ptr<AliHLTTPCHWCFSpacePointContainer> rawInputClusters(new AliHLTTPCHWCFSpacePointContainer(spacePointContainerMode)); | |
801 | std::auto_ptr<AliHLTTPCSpacePointContainer> inputClusters(new AliHLTTPCSpacePointContainer); | |
802 | ||
803 | std::auto_ptr<TH1F> histoCompFactor(new TH1F("CompressionFactor", | |
804 | "HLT TPC data compression factor", | |
805 | 100, 0., 10.)); | |
806 | std::auto_ptr<TH1F> histoResidualPad(new TH1F("PadResidual", | |
807 | "HLT TPC pad residual", | |
808 | 100, -fMaxDeltaPad, fMaxDeltaPad)); | |
809 | std::auto_ptr<TH1F> histoResidualTime(new TH1F("TimeResidual", | |
810 | "HLT TPC time residual", | |
811 | 100, -fMaxDeltaTime, fMaxDeltaTime)); | |
812 | std::auto_ptr<TH1F> histoClustersOnTracks(new TH1F("ClustersOnTracks", | |
813 | "Clusters in track model compression", | |
814 | 200, 0., 600)); | |
815 | std::auto_ptr<TH1F> histoClusterRatio(new TH1F("ClusterRatio", | |
816 | "Fraction of clusters in track model compression", | |
817 | 100, 0., 1.)); | |
818 | std::auto_ptr<TH1F> histoTrackClusterRatio(new TH1F("UsedTrackClusters", | |
819 | "Fraction of track clusters in track model compression", | |
820 | 100, 0., 1.)); | |
821 | ||
822 | // track grid: 36 slices, each 6 partitions with max 33 rows | |
823 | fTrackGrid=new AliHLTTrackGeometry::AliHLTTrackGrid(36, 1, 6, 1, 33, 1, 20000); | |
824 | fSpacePointGrid=AliHLTTPCHWCFSpacePointContainer::AllocateIndexGrid(); | |
825 | ||
826 | if (!rawInputClusters.get() || | |
827 | !inputClusters.get() || | |
828 | !fTrackGrid || | |
829 | !fSpacePointGrid) { | |
830 | if (fTrackGrid) delete fTrackGrid; fTrackGrid=NULL; | |
831 | if (fSpacePointGrid) delete fSpacePointGrid; fSpacePointGrid=NULL; | |
832 | return -ENOMEM; | |
833 | } | |
834 | ||
835 | if (fDeflaterMode>0 && (iResult=InitDeflater(fDeflaterMode))<0) | |
836 | return iResult; | |
837 | ||
838 | fpBenchmark=benchmark.release(); | |
839 | fRawInputClusters=rawInputClusters.release(); | |
840 | fInputClusters=inputClusters.release(); | |
841 | ||
842 | // initialize the histograms if stored at the end | |
843 | // condition might be extended | |
844 | if (!fHistogramFile.IsNull()) { | |
845 | fHistoCompFactor=histoCompFactor.release(); | |
846 | fHistoResidualPad=histoResidualPad.release(); | |
847 | fHistoResidualTime=histoResidualTime.release(); | |
848 | fHistoClustersOnTracks=histoClustersOnTracks.release(); | |
849 | fHistoClusterRatio=histoClusterRatio.release(); | |
850 | fHistoTrackClusterRatio=histoTrackClusterRatio.release(); | |
851 | } | |
852 | ||
853 | if (iResult>=0 && (iResult=InitDriftTimeTransformation())<0) return iResult; | |
854 | ||
855 | return iResult; | |
856 | } | |
857 | ||
858 | int AliHLTTPCDataCompressionComponent::InitDeflater(int mode) | |
859 | { | |
860 | /// init the data deflater | |
861 | int iResult=0; | |
862 | if (mode==2 || mode==3) { | |
863 | // huffman deflater | |
864 | std::auto_ptr<AliHLTDataDeflaterHuffman> deflater(new AliHLTDataDeflaterHuffman(mode==3)); | |
865 | if (!deflater.get()) return -ENOMEM; | |
866 | ||
867 | if (!deflater->IsTrainingMode()) { | |
868 | TString cdbPath("HLT/ConfigTPC/"); | |
869 | cdbPath += GetComponentID(); | |
870 | cdbPath += "HuffmanTables"; | |
871 | TObject* pConf=LoadAndExtractOCDBObject(cdbPath); | |
872 | if (!pConf) return -ENOENT; | |
873 | if (dynamic_cast<TList*>(pConf)==NULL) { | |
874 | HLTError("huffman table configuration object of inconsistent type"); | |
875 | return -EINVAL; | |
876 | } | |
877 | iResult=deflater->InitDecoders(dynamic_cast<TList*>(pConf)); | |
878 | if (iResult<0) return iResult; | |
879 | } | |
880 | ||
881 | unsigned nofParameters=AliHLTTPCDefinitions::GetNumberOfClusterParameterDefinitions(); | |
882 | unsigned p=0; | |
883 | for (; p<nofParameters; p++) { | |
884 | const AliHLTTPCDefinitions::AliClusterParameter& parameter=AliHLTTPCDefinitions::fgkClusterParameterDefinitions[p]; | |
885 | if (deflater->AddParameterDefinition(parameter.fName, | |
886 | parameter.fBitLength)!=(int)parameter.fId) { | |
887 | // for performance reason the parameter id is simply used as index in the array of | |
888 | // definitions, the position must match the id | |
889 | HLTFatal("mismatch between parameter id and position in array for parameter %s, rearrange definitions!", parameter.fName); | |
890 | return -EFAULT; | |
891 | } | |
892 | } | |
893 | fpDataDeflater=deflater.release(); | |
894 | return 0; | |
895 | } | |
896 | if (mode==1) { | |
897 | std::auto_ptr<AliHLTDataDeflaterSimple> deflater(new AliHLTDataDeflaterSimple); | |
898 | if (!deflater.get()) return -ENOMEM; | |
899 | ||
900 | unsigned nofParameters=AliHLTTPCDefinitions::GetNumberOfClusterParameterDefinitions(); | |
901 | unsigned p=0; | |
902 | for (; p<nofParameters; p++) { | |
903 | const AliHLTTPCDefinitions::AliClusterParameter& parameter=AliHLTTPCDefinitions::fgkClusterParameterDefinitions[p]; | |
904 | if (deflater->AddParameterDefinition(parameter.fName, | |
905 | parameter.fBitLength, | |
906 | parameter.fOptional)!=(int)parameter.fId) { | |
907 | // for performance reason the parameter id is simply used as index in the array of | |
908 | // definitions, the position must match the id | |
909 | HLTFatal("mismatch between parameter id and position in array for parameter %s, rearrange definitions!", parameter.fName); | |
910 | return -EFAULT; | |
911 | } | |
912 | } | |
913 | fpDataDeflater=deflater.release(); | |
914 | return 0; | |
915 | } | |
916 | HLTError("invalid deflater mode %d, allowed 1=simple 2=huffman", mode); | |
917 | return -EINVAL; | |
918 | } | |
919 | ||
920 | int AliHLTTPCDataCompressionComponent::DoDeinit() | |
921 | { | |
922 | /// inherited from AliHLTComponent: component cleanup | |
923 | int iResult=0; | |
924 | if (fpBenchmark) delete fpBenchmark; fpBenchmark=NULL; | |
925 | if (fRawInputClusters) delete fRawInputClusters; fRawInputClusters=NULL; | |
926 | if (fInputClusters) delete fInputClusters; fInputClusters=NULL; | |
927 | if (!fHistogramFile.IsNull()) { | |
928 | TFile out(fHistogramFile, "RECREATE"); | |
929 | if (!out.IsZombie()) { | |
930 | out.cd(); | |
931 | if (fHistoCompFactor) fHistoCompFactor->Write(); | |
932 | if (fHistoResidualPad) fHistoResidualPad->Write(); | |
933 | if (fHistoResidualTime) fHistoResidualTime->Write(); | |
934 | if (fHistoClusterRatio) fHistoClusterRatio->Write(); | |
935 | if (fHistoClustersOnTracks) fHistoClustersOnTracks->Write(); | |
936 | if (fHistoTrackClusterRatio) fHistoTrackClusterRatio->Write(); | |
937 | out.Close(); | |
938 | } | |
939 | } | |
940 | if (fHistoCompFactor) delete fHistoCompFactor; | |
941 | fHistoCompFactor=NULL; | |
942 | if (fHistoResidualPad) delete fHistoResidualPad; | |
943 | fHistoResidualPad=NULL; | |
944 | if (fHistoResidualTime) delete fHistoResidualTime; | |
945 | fHistoResidualTime=NULL; | |
946 | if (fHistoClustersOnTracks) delete fHistoClustersOnTracks; | |
947 | fHistoClustersOnTracks=NULL; | |
948 | if (fHistoClusterRatio) delete fHistoClusterRatio; | |
949 | fHistoClusterRatio=NULL; | |
950 | if (fHistoTrackClusterRatio) delete fHistoTrackClusterRatio; | |
951 | fHistoTrackClusterRatio=NULL; | |
952 | ||
953 | if (fpDataDeflater) { | |
954 | if (!fHistogramFile.IsNull()) { | |
955 | TString filename=fHistogramFile; | |
956 | filename.ReplaceAll(".root", "-deflater.root"); | |
957 | fpDataDeflater->SaveAs(filename); | |
958 | } | |
959 | if (fDeflaterMode==3) { | |
960 | if (fTrainingTableOutput.IsNull()) { | |
961 | fTrainingTableOutput=GetComponentID(); | |
962 | fTrainingTableOutput+="-huffman.root"; | |
963 | } | |
964 | // TODO: currently, the code tables are also calculated in FindObject | |
965 | // check if a different function is more appropriate | |
966 | TObject* pConf=fpDataDeflater->FindObject("DeflaterConfiguration"); | |
967 | if (pConf) { | |
968 | TString cdbEntryPath("HLT/ConfigTPC/"); | |
969 | cdbEntryPath += GetComponentID(); | |
970 | cdbEntryPath += "HuffmanTables"; | |
971 | AliCDBPath cdbPath(cdbEntryPath); | |
972 | AliCDBId cdbId(cdbPath, AliCDBManager::Instance()->GetRun(), AliCDBRunRange::Infinity(), 0, 0); | |
973 | AliCDBMetaData* cdbMetaData=new AliCDBMetaData; | |
974 | cdbMetaData->SetResponsible("ALICE HLT Matthias.Richter@cern.ch"); | |
975 | cdbMetaData->SetComment("Huffman encoder configuration"); | |
976 | AliCDBEntry* entry=new AliCDBEntry(pConf, cdbId, cdbMetaData, kTRUE); | |
977 | ||
978 | entry->SaveAs(fTrainingTableOutput); | |
979 | // this is a small memory leak | |
980 | // seg fault in ROOT object handling if the two objects are deleted | |
981 | // investigate later | |
982 | //delete entry; | |
983 | //delete cdbMetaData; | |
984 | } | |
985 | } | |
986 | delete fpDataDeflater; | |
987 | } | |
988 | fpDataDeflater=NULL; | |
989 | ||
990 | ||
991 | if (fTrackGrid) delete fTrackGrid; fTrackGrid=NULL; | |
992 | if (fSpacePointGrid) delete fSpacePointGrid; fSpacePointGrid=NULL; | |
993 | ||
994 | return iResult; | |
995 | } | |
996 | ||
997 | int AliHLTTPCDataCompressionComponent::ScanConfigurationArgument(int argc, const char** argv) | |
998 | { | |
999 | /// inherited from AliHLTComponent: argument scan | |
1000 | int iResult=0; | |
1001 | if (argc<1) return 0; | |
1002 | int bMissingParam=0; | |
1003 | int i=0; | |
1004 | TString argument=argv[i]; | |
1005 | ||
1006 | do { | |
1007 | // -mode | |
1008 | if (argument.CompareTo("-mode")==0) { | |
1009 | if ((bMissingParam=(++i>=argc))) break; | |
1010 | TString parameter=argv[i]; | |
1011 | if (parameter.IsDigit()) { | |
1012 | fMode=parameter.Atoi(); | |
1013 | return 2; | |
1014 | } else { | |
1015 | HLTError("invalid parameter for argument %s, expecting number instead of %s", argument.Data(), parameter.Data()); | |
1016 | return -EPROTO; | |
1017 | } | |
1018 | } | |
1019 | ||
1020 | // -deflater-mode | |
1021 | if (argument.CompareTo("-deflater-mode")==0) { | |
1022 | if ((bMissingParam=(++i>=argc))) break; | |
1023 | TString parameter=argv[i]; | |
1024 | if (parameter.IsDigit()) { | |
1025 | fDeflaterMode=parameter.Atoi(); | |
1026 | return 2; | |
1027 | } else { | |
1028 | HLTError("invalid parameter for argument %s, expecting number instead of %s", argument.Data(), parameter.Data()); | |
1029 | return -EPROTO; | |
1030 | } | |
1031 | } | |
1032 | ||
1033 | // -histogram-file | |
1034 | if (argument.CompareTo("-histogram-file")==0) { | |
1035 | if ((bMissingParam=(++i>=argc))) break; | |
1036 | fHistogramFile=argv[i++]; | |
1037 | return 2; | |
1038 | } | |
1039 | // -save-histogram-table | |
1040 | if (argument.CompareTo("-save-huffman-table")==0) { | |
1041 | if ((bMissingParam=(++i>=argc))) break; | |
1042 | fTrainingTableOutput=argv[i++]; | |
1043 | return 2; | |
1044 | } | |
1045 | // -cluster-verification | |
1046 | if (argument.CompareTo("-cluster-verification")==0) { | |
1047 | if ((bMissingParam=(++i>=argc))) break; | |
1048 | TString parameter=argv[i]; | |
1049 | if (parameter.IsDigit()) { | |
1050 | fVerificationMode=parameter.Atoi(); | |
1051 | return 2; | |
1052 | } else { | |
1053 | HLTError("invalid parameter for argument %s, expecting number instead of %s", argument.Data(), parameter.Data()); | |
1054 | return -EPROTO; | |
1055 | } | |
1056 | } | |
1057 | } while (0); // using do-while only to have break available | |
1058 | ||
1059 | if (bMissingParam) { | |
1060 | HLTError("missing parameter for argument %s", argument.Data()); | |
1061 | iResult=-EPROTO; | |
1062 | } | |
1063 | ||
1064 | return iResult; | |
1065 | } | |
1066 | ||
1067 | int AliHLTTPCDataCompressionComponent::InitDriftTimeTransformation() | |
1068 | { | |
1069 | /// calculate correction factor and offset for a linear approximation of the | |
1070 | /// drift time transformation, separately for A and C side | |
1071 | int iResult=0; | |
1072 | AliHLTTPCClusterTransformation transform; | |
1073 | if ((iResult=transform.Init( GetBz(), GetTimeStamp()))<0) { | |
1074 | HLTError("failed to init AliHLTTPCClusterTransformation: %d", iResult); | |
1075 | return iResult; | |
1076 | } | |
1077 | ||
1078 | if ((iResult=CalculateDriftTimeTransformation(transform, 0, 0, fDriftTimeFactorA, fDriftTimeOffsetA))<0) return iResult; | |
1079 | if (fVerbosity>0) HLTInfo("drift time transformation A side: m=%f n=%f", fDriftTimeFactorA, fDriftTimeOffsetA); | |
1080 | if ((iResult=CalculateDriftTimeTransformation(transform, 18, 0, fDriftTimeFactorC, fDriftTimeOffsetC))<0) return iResult; | |
1081 | if (fVerbosity>0) HLTInfo("drift time transformation C side: m=%f n=%f", fDriftTimeFactorC, fDriftTimeOffsetC); | |
1082 | ||
1083 | return 0; | |
1084 | } | |
1085 | ||
1086 | int AliHLTTPCDataCompressionComponent::CalculateDriftTimeTransformation(AliHLTTPCClusterTransformation& transform, | |
1087 | int slice, int padrow, | |
1088 | float& m, float& n) const | |
1089 | { | |
1090 | /// calculate correction factor and offset for a linear approximation of the | |
1091 | /// drift time transformation by just probing the range of timebins with | |
1092 | /// AliHLTTPCClusterTransformation | |
1093 | const int nofSteps=100; | |
1094 | vector<float> zvalues; | |
1095 | ||
1096 | int nofTimebins=AliHLTTPCTransform::GetNTimeBins(); | |
1097 | int stepWidth=nofTimebins/nofSteps; | |
1098 | int time=0; | |
1099 | int count=0; | |
1100 | float meanT=0.; | |
1101 | float meanZ=0.; | |
1102 | for (time=0; time<nofTimebins; time+=stepWidth, count++) { | |
1103 | Float_t xyz[3]; | |
1104 | transform.Transform(slice, padrow, 0, time, xyz); | |
1105 | zvalues.push_back(xyz[2]); | |
1106 | meanT+=time; | |
1107 | meanZ+=xyz[2]; | |
1108 | } | |
1109 | meanT/=count; | |
1110 | meanZ/=count; | |
1111 | float sumTZ=.0; | |
1112 | float sumT2=.0; | |
1113 | time=0; | |
1114 | for (vector<float>::const_iterator z=zvalues.begin(); | |
1115 | z!=zvalues.end(); z++, time+=stepWidth) { | |
1116 | sumTZ+=(time-meanT)*((*z)-meanZ); | |
1117 | sumT2+=(time-meanT)*(time-meanT); | |
1118 | } | |
1119 | m=sumTZ/sumT2; | |
1120 | n=meanZ-m*meanT; | |
1121 | ||
1122 | return 0; | |
1123 | } |