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