adding further optimized compression format with additional 15% compression ratio...
[u/mrichter/AliRoot.git] / HLT / TPCLib / comp / AliHLTTPCDataCompressionComponent.cxx
CommitLineData
7ab8209c 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"
8b1d554b 31#include "AliHLTDataDeflaterSimple.h"
80ae4557 32#include "AliHLTDataDeflaterHuffman.h"
4f573ca4 33#include "AliHLTTPCTransform.h"
0fa10601 34#include "AliHLTTPCClusterMCData.h"
9b72add5 35#include "AliHLTTPCClusterTransformation.h"
4653ce26 36#include "AliHLTErrorGuard.h"
0fa10601 37#include "AliRawDataHeader.h"
80ae4557 38#include "AliCDBManager.h"
39#include "AliCDBPath.h"
40#include "AliCDBId.h"
41#include "AliCDBMetaData.h"
42#include "AliCDBEntry.h"
8b1d554b 43#include "TH1F.h"
44#include "TFile.h"
45#include <memory>
7ab8209c 46
0fa10601 47ClassImp(AliHLTTPCDataCompressionComponent)
48
7ab8209c 49AliHLTTPCDataCompressionComponent::AliHLTTPCDataCompressionComponent()
50 : AliHLTProcessor()
51 , fMode(0)
8b1d554b 52 , fDeflaterMode(0)
9b72add5 53 , fVerificationMode(0)
4f573ca4 54 , fMaxDeltaPad(AliHLTTPCDefinitions::GetMaxClusterDeltaPad())
55 , fMaxDeltaTime(AliHLTTPCDefinitions::GetMaxClusterDeltaTime())
7ab8209c 56 , fRawInputClusters(NULL)
57 , fInputClusters(NULL)
0fa10601 58 , fTrackGrid(NULL)
59 , fSpacePointGrid(NULL)
8b1d554b 60 , fpDataDeflater(NULL)
61 , fHistoCompFactor(NULL)
4f573ca4 62 , fHistoResidualPad(NULL)
63 , fHistoResidualTime(NULL)
64 , fHistoClustersOnTracks(NULL)
65 , fHistoClusterRatio(NULL)
66 , fHistoTrackClusterRatio(NULL)
8b1d554b 67 , fHistogramFile()
80ae4557 68 , fTrainingTableOutput()
7ab8209c 69 , fpBenchmark(NULL)
9b72add5 70 , fpWrittenAssociatedClusterIds(NULL)
71 , fDriftTimeFactorA(1.)
72 , fDriftTimeOffsetA(0.)
73 , fDriftTimeFactorC(1.)
74 , fDriftTimeOffsetC(0.)
4f573ca4 75 , fVerbosity(0)
7ab8209c 76{
77}
78
79AliHLTTPCDataCompressionComponent::~AliHLTTPCDataCompressionComponent()
80{
81 /// destructor
9b72add5 82 if (fpWrittenAssociatedClusterIds) delete fpWrittenAssociatedClusterIds;
7ab8209c 83}
84
85
86const char* AliHLTTPCDataCompressionComponent::GetComponentID()
87{
88 /// inherited from AliHLTComponent: id of the component
89 return "TPCDataCompressor";
90}
91
92
93void 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
102AliHLTComponentDataType AliHLTTPCDataCompressionComponent::GetOutputDataType()
103{
104 /// inherited from AliHLTComponent: output data type of the component.
105 return kAliHLTMultipleDataType;
106}
107
108int AliHLTTPCDataCompressionComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList)
109{
110 /// inherited from AliHLTComponent: multiple output data types of the component.
111 tgtList.clear();
9b72add5 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());
7ab8209c 117 return tgtList.size();
118}
119
120void AliHLTTPCDataCompressionComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
121{
122 /// inherited from AliHLTComponent: output data size estimator
123 constBase=0;
9b72add5 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
7ab8209c 127}
128
129AliHLTComponent* AliHLTTPCDataCompressionComponent::Spawn()
130{
131 /// inherited from AliHLTComponent: spawn function.
132 return new AliHLTTPCDataCompressionComponent;
133}
134
8a3426fd 135void 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
b60d3f6a 148int AliHLTTPCDataCompressionComponent::DoEvent( const AliHLTComponentEventData& /*evtData*/,
149 const AliHLTComponentBlockData* /*inputBlocks*/,
7ab8209c 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
0fa10601 162 if (!fRawInputClusters) {
163 return -ENODEV;
164 }
165
7ab8209c 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
0fa10601 173 bool bHaveMC=(GetFirstInputBlock(AliHLTTPCDefinitions::fgkAliHLTDataTypeClusterMCInfo | kAliHLTDataOriginTPC))!=NULL;
9b72add5 174 if ((bHaveMC || fVerificationMode>0) && fpWrittenAssociatedClusterIds==NULL) {
175 fpWrittenAssociatedClusterIds=new vector<AliHLTUInt32_t>;
176 }
0fa10601 177
7ab8209c 178 const AliHLTComponentBlockData* pDesc=NULL;
179
8b1d554b 180 AliHLTUInt8_t minSlice=0xFF, maxSlice=0xFF, minPatch=0xFF, maxPatch=0xFF;
181 AliHLTUInt32_t inputRawClusterSize=0;
0fa10601 182 AliHLTUInt32_t outputDataSize=0;
4f573ca4 183 int allClusters=0;
184 int associatedClusters=0;
8a3426fd 185 float bz=GetBz();
8b1d554b 186
7ab8209c 187 /// input track array
188 vector<AliHLTGlobalBarrelTrack> inputTrackArray;
189
190 if (GetBenchmarkInstance()) {
7ab8209c 191 GetBenchmarkInstance()->Start(2);
192 }
193
194 // transformed clusters
61e66346 195 if (fMode==10) { // FIXME: condition to be adjusted
7ab8209c 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
4653ce26 219 vector<int> trackindexmap; // stores index for every track id
220
7ab8209c 221 // track data input
8a3426fd 222 if (fMode==2 || fMode==4) {
7ab8209c 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 }
4653ce26 240 trackindexmap.resize(inputTrackArray.size(), -1);
7ab8209c 241 }
242 }
243
244 if (GetBenchmarkInstance()) {
245 GetBenchmarkInstance()->Stop(3);
246 GetBenchmarkInstance()->Start(4);
247 }
248
249 // processing
4653ce26 250 int trackindex=0;
0fa10601 251 for (vector<AliHLTGlobalBarrelTrack>::iterator track=inputTrackArray.begin();
7ab8209c 252 track!=inputTrackArray.end();
4653ce26 253 track++, trackindex++) {
7ab8209c 254 int trackID=track->GetID();
255 if (trackID<0) {
256 // FIXME: error guard
257 HLTError("invalid track ID");
258 continue;
259 }
4653ce26 260 if (trackID>=(int)trackindexmap.size())
261 trackindexmap.resize(trackID+1, -1);
262 trackindexmap[trackID]=trackindex;
4f573ca4 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
9b72add5 275 AliHLTTPCTrackGeometry* trackpoints=new AliHLTTPCTrackGeometry;
0fa10601 276 if (!trackpoints) continue;
4653ce26 277 HLTDebug("track %d id %d:", trackindex, trackID);
8a3426fd 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(&param, 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);
9b72add5 302 trackpoints->InitDriftTimeTransformation(fDriftTimeFactorA, fDriftTimeOffsetA, fDriftTimeFactorC, fDriftTimeOffsetC);
0fa10601 303 trackpoints->SetTrackId(trackID);
8a3426fd 304 trackpoints->CalculateTrackPoints(ctrack);
0fa10601 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 }
4f573ca4 316 if (fVerbosity>0) {
317 fTrackGrid->Print();
7ab8209c 318 }
319
320 if (GetBenchmarkInstance()) {
321 GetBenchmarkInstance()->Stop(4);
322 GetBenchmarkInstance()->Start(5);
323 }
324
61e66346 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()) {
0fa10601 329 if (pDesc->fSize<=sizeof(AliRawDataHeader)) continue;
61e66346 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;
0fa10601 342 inputRawClusterSize+=pDesc->fSize;
343
344 // add the data and populate the index grid
345 fRawInputClusters->AddInputBlock(pDesc);
346 fRawInputClusters->PopulateAccessGrid(fSpacePointGrid, pDesc->fSpecification);
4f573ca4 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 }
61e66346 359 if (GetBenchmarkInstance()) {
360 GetBenchmarkInstance()->Stop(1);
0fa10601 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);
61e66346 368 GetBenchmarkInstance()->Start(5);
369 }
4f573ca4 370 allClusters+=fSpacePointGrid->GetNumberOfSpacePoints();
1e21c76d 371 iResult=ProcessTrackClusters(&inputTrackArray[0], inputTrackArray.size(), fTrackGrid, trackindexmap, fSpacePointGrid, fRawInputClusters, slice, patch);
4f573ca4 372 int assignedInThisPartition=0;
373 if (iResult>=0) {
374 assignedInThisPartition=iResult;
375 associatedClusters+=iResult;
376 }
3ca47235 377 iResult=ProcessRemainingClusters(&inputTrackArray[0], inputTrackArray.size(), fTrackGrid, trackindexmap, fSpacePointGrid, fRawInputClusters, slice, patch);
4f573ca4 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 }
0fa10601 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
9b72add5 390 const char* writeoptions="";
391 if (fpWrittenAssociatedClusterIds) {
392 writeoptions="write-cluster-ids";
393 }
0fa10601 394 fRawInputClusters->SetSpacePointPropertyGrid(pDesc->fSpecification, fSpacePointGrid);
9b72add5 395 iResult=fRawInputClusters->Write(outputPtr+size, capacity-size, outputBlocks, fpDataDeflater, writeoptions);
0fa10601 396 fRawInputClusters->SetSpacePointPropertyGrid(pDesc->fSpecification, NULL);
7ab8209c 397 if (iResult>=0) {
398 size+=iResult;
0fa10601 399 outputDataSize+=iResult;
b60d3f6a 400 // the size of the optional cluster id array must be subtracted
401 if (fpWrittenAssociatedClusterIds && outputBlocks.size()>0 &&
4653ce26 402 outputBlocks.back().fDataType==AliHLTTPCDefinitions::RemainingClusterIdsDataType()) {
b60d3f6a 403 outputDataSize-=outputBlocks.back().fSize;
404 }
7ab8209c 405 if (GetBenchmarkInstance()) GetBenchmarkInstance()->AddOutput(iResult);
406 }
61e66346 407 if (GetBenchmarkInstance()) {
408 GetBenchmarkInstance()->Stop(5);
409 }
0fa10601 410
0fa10601 411 fSpacePointGrid->Clear();
7ab8209c 412 }
4f573ca4 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 }
7ab8209c 418
0fa10601 419 // output of track model clusters
bdad7033 420 if (iResult>=0) do {
421 AliHLTUInt32_t tracksBufferOffset=sizeof(AliHLTTPCTrackModelBlock);
422 if (capacity-size<tracksBufferOffset) {
423 iResult=-ENOSPC;
424 break;
425 }
9b72add5 426 if (fpWrittenAssociatedClusterIds) fpWrittenAssociatedClusterIds->clear();
bdad7033 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;
8a3426fd 440 trackModelBlock->fGlobalParameters[parameterIndex++]=bz;
bdad7033 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
8a3426fd 451 if (trackindexmap.size()>0) {// condition for track model compression
bdad7033 452 iResult=WriteTrackClusters(inputTrackArray, fRawInputClusters, fpDataDeflater, outputPtr+size+tracksBufferOffset, capacity-size-tracksBufferOffset);
4f573ca4 453 if (iResult>=0) {
454 AliHLTComponent_BlockData bd;
455 FillBlockData(bd);
456 bd.fOffset = size;
bdad7033 457 bd.fSize = tracksBufferOffset+iResult;
4f573ca4 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);
9b72add5 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);
9b2c9b8b 469 if (capacity-size>bd.fSize) {
bdad7033 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 }
9b72add5 478
479 fpWrittenAssociatedClusterIds->clear();
480 }
4f573ca4 481 }
b60d3f6a 482 }
bdad7033 483 } while (0);
0fa10601 484
485 fRawInputClusters->Clear();
486
8b1d554b 487 float compressionFactor=(float)inputRawClusterSize;
0fa10601 488 if ((outputDataSize)>0) compressionFactor/=outputDataSize;
8b1d554b 489 else compressionFactor=0.;
490 if (fHistoCompFactor) fHistoCompFactor->Fill(compressionFactor);
491
7ab8209c 492 if (GetBenchmarkInstance()) {
7ab8209c 493 GetBenchmarkInstance()->Stop(0);
80ae4557 494 if (fDeflaterMode!=3) {
495 HLTBenchmark("%s - compression factor %.2f", GetBenchmarkInstance()->GetStatistics(), compressionFactor);
496 } else {
497 HLTBenchmark("%s", GetBenchmarkInstance()->GetStatistics());
498 }
7ab8209c 499 }
500
501 if (fInputClusters) {
502 fInputClusters->Clear();
503 }
504 if (fRawInputClusters) {
505 fRawInputClusters->Clear();
506 }
0fa10601 507 if (fTrackGrid) {
508 fTrackGrid->Clear();
8b1d554b 509 }
510
b60d3f6a 511 // forward MC labels
512 for (pDesc=GetFirstInputBlock(AliHLTTPCDefinitions::fgkAliHLTDataTypeClusterMCInfo | kAliHLTDataOriginTPC);
513 pDesc!=NULL; pDesc=GetNextInputBlock()) {
514 outputBlocks.push_back(*pDesc);
515 }
516
7ab8209c 517 return iResult;
518}
519
4f573ca4 520int AliHLTTPCDataCompressionComponent::ProcessTrackClusters(AliHLTGlobalBarrelTrack* pTracks, unsigned nofTracks,
521 AliHLTTrackGeometry::AliHLTTrackGrid* pTrackIndex,
1e21c76d 522 const vector<int>& trackIndexMap,
4f573ca4 523 AliHLTSpacePointContainer::AliHLTSpacePointPropertyGrid* pClusterIndex,
524 AliHLTSpacePointContainer* pClusters,
525 int slice, int partition) const
526{
527 // process to assigned track clusters
1e21c76d 528 int iResult=0;
4f573ca4 529 int assignedClusters=0;
530 if (!pTracks || nofTracks==0) return 0;
531
1e21c76d 532 vector<int> processedTracks(nofTracks, -1);
4f573ca4 533 for (AliHLTTrackGeometry::AliHLTTrackGrid::iterator& trackId=pTrackIndex->begin(slice, partition, -1);
534 trackId!=pTrackIndex->end(); trackId++) {
1e21c76d 535 if (trackId.Data()>=trackIndexMap.size()) {
536 HLTError("can not find track id %d in index map of size %d", trackId.Data(), trackIndexMap.size());
4f573ca4 537 continue;
538 }
1e21c76d 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());
4f573ca4 542 continue;
543 }
1e21c76d 544 if (processedTracks[trackindex]>0) continue;
545 processedTracks[trackindex]=1;
4f573ca4 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 }
4f573ca4 566
567 int clusterrow=(int)pClusters->GetX(clusterId);
4f573ca4 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();
1e21c76d 576
577 iResult=FindCellClusters(trackId.Data(), clusterrow, pad, time, pClusterIndex, pClusters, point, clusterId);
578 if (iResult>0) assignedClusters+=iResult;
4f573ca4 579 }
580 }
581 return assignedClusters;
582}
583
584int AliHLTTPCDataCompressionComponent::ProcessRemainingClusters(AliHLTGlobalBarrelTrack* pTracks, unsigned nofTracks,
585 AliHLTTrackGeometry::AliHLTTrackGrid* pTrackIndex,
3ca47235 586 const vector<int>& trackIndexMap,
4f573ca4 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++) {
3ca47235 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;
4f573ca4 602 }
3ca47235 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());
4f573ca4 606 continue;
607 }
3ca47235 608 AliHLTGlobalBarrelTrack& track=pTracks[trackindex];
4f573ca4 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
638int AliHLTTPCDataCompressionComponent::FindCellClusters(int trackId, int padrow, float pad, float time,
639 AliHLTSpacePointContainer::AliHLTSpacePointPropertyGrid* pClusterIndex,
640 AliHLTSpacePointContainer* pClusters,
1e21c76d 641 AliHLTTrackGeometry::AliHLTTrackPoint* pTrackPoint,
642 AliHLTUInt32_t clusterId) const
4f573ca4 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
4653ce26 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);
1e21c76d 654 if ((TMath::Abs(centerpad-pad)>fMaxDeltaPad && pad>0.) ||
655 (TMath::Abs(centertime-time)>fMaxDeltaTime && time>0.)) {
4653ce26 656 ALIHLTERRORGUARD(20, "invalid pad center calculation, please check dimensions if dimensions of index grid match the maximum possible deviation");
657 }
658
1e21c76d 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) {
4f573ca4 664 if (padindex<0) continue;
665 if (padindex>=pClusterIndex->GetDimensionY()) break;
1e21c76d 666 for (int timecount=0, timeindex=timestartindex; timecount<2; timecount++, timeindex+=timedirection) {
4f573ca4 667 if (timeindex<0) continue;
668 if (timeindex>=pClusterIndex->GetDimensionZ()) break;
4653ce26 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);
4f573ca4 673 cl!=pClusterIndex->end(); cl++) {
674 if (cl.Data().fTrackId>=0) continue;
1e21c76d 675 if (clusterId!=(~(AliHLTUInt32_t)0) && clusterId!=cl.Data().fId) continue;
4653ce26 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 }
4f573ca4 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 }
1e21c76d 689 if (clusterId!=(~(AliHLTUInt32_t)0)) break;
4f573ca4 690 }
691 }
692 }
693 return count;
694}
695
696int 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
9b72add5 717 int result=pTrackPoints->Write(*track, pSpacePoints, pDeflater, outputPtr+size, capacity-size, fpWrittenAssociatedClusterIds);
4f573ca4 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
7ab8209c 758int 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 //
8b1d554b 771 iResult = ConfigureFromCDBTObjString(cdbPath);
7ab8209c 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
8b1d554b 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;
7ab8209c 789 }
790
8a3426fd 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 }
4f573ca4 800 std::auto_ptr<AliHLTTPCHWCFSpacePointContainer> rawInputClusters(new AliHLTTPCHWCFSpacePointContainer(spacePointContainerMode));
8b1d554b 801 std::auto_ptr<AliHLTTPCSpacePointContainer> inputClusters(new AliHLTTPCSpacePointContainer);
4f573ca4 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
0fa10601 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() ||
0fa10601 828 !fTrackGrid ||
829 !fSpacePointGrid) {
830 if (fTrackGrid) delete fTrackGrid; fTrackGrid=NULL;
831 if (fSpacePointGrid) delete fSpacePointGrid; fSpacePointGrid=NULL;
832 return -ENOMEM;
833 }
8b1d554b 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();
4f573ca4 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 }
7ab8209c 852
9b72add5 853 if (iResult>=0 && (iResult=InitDriftTimeTransformation())<0) return iResult;
854
7ab8209c 855 return iResult;
856}
857
8b1d554b 858int AliHLTTPCDataCompressionComponent::InitDeflater(int mode)
859{
860 /// init the data deflater
80ae4557 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 }
8b1d554b 896 if (mode==1) {
897 std::auto_ptr<AliHLTDataDeflaterSimple> deflater(new AliHLTDataDeflaterSimple);
898 if (!deflater.get()) return -ENOMEM;
899
0fa10601 900 unsigned nofParameters=AliHLTTPCDefinitions::GetNumberOfClusterParameterDefinitions();
901 unsigned p=0;
902 for (; p<nofParameters; p++) {
71300445 903 const AliHLTTPCDefinitions::AliClusterParameter& parameter=AliHLTTPCDefinitions::fgkClusterParameterDefinitions[p];
904 if (deflater->AddParameterDefinition(parameter.fName,
905 parameter.fBitLength,
906 parameter.fOptional)!=(int)parameter.fId) {
8b1d554b 907 // for performance reason the parameter id is simply used as index in the array of
908 // definitions, the position must match the id
0fa10601 909 HLTFatal("mismatch between parameter id and position in array for parameter %s, rearrange definitions!", parameter.fName);
8b1d554b 910 return -EFAULT;
911 }
912 }
913 fpDataDeflater=deflater.release();
914 return 0;
8b1d554b 915 }
916 HLTError("invalid deflater mode %d, allowed 1=simple 2=huffman", mode);
917 return -EINVAL;
918}
919
7ab8209c 920int AliHLTTPCDataCompressionComponent::DoDeinit()
921{
922 /// inherited from AliHLTComponent: component cleanup
923 int iResult=0;
8b1d554b 924 if (fpBenchmark) delete fpBenchmark; fpBenchmark=NULL;
925 if (fRawInputClusters) delete fRawInputClusters; fRawInputClusters=NULL;
926 if (fInputClusters) delete fInputClusters; fInputClusters=NULL;
4f573ca4 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();
8b1d554b 938 }
8b1d554b 939 }
4f573ca4 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
80ae4557 953 if (fpDataDeflater) {
9b72add5 954 if (!fHistogramFile.IsNull()) {
955 TString filename=fHistogramFile;
956 filename.ReplaceAll(".root", "-deflater.root");
957 fpDataDeflater->SaveAs(filename);
958 }
80ae4557 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
0fa10601 991 if (fTrackGrid) delete fTrackGrid; fTrackGrid=NULL;
992 if (fSpacePointGrid) delete fSpacePointGrid; fSpacePointGrid=NULL;
8b1d554b 993
7ab8209c 994 return iResult;
995}
996
997int AliHLTTPCDataCompressionComponent::ScanConfigurationArgument(int argc, const char** argv)
998{
999 /// inherited from AliHLTComponent: argument scan
1000 int iResult=0;
8b1d554b 1001 if (argc<1) return 0;
7ab8209c 1002 int bMissingParam=0;
1003 int i=0;
8b1d554b 1004 TString argument=argv[i];
7ab8209c 1005
8b1d554b 1006 do {
7ab8209c 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();
8b1d554b 1013 return 2;
7ab8209c 1014 } else {
1015 HLTError("invalid parameter for argument %s, expecting number instead of %s", argument.Data(), parameter.Data());
1016 return -EPROTO;
1017 }
1018 }
8b1d554b 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 }
80ae4557 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 }
9b2c9b8b 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 }
0fa10601 1057 } while (0); // using do-while only to have break available
7ab8209c 1058
1059 if (bMissingParam) {
1060 HLTError("missing parameter for argument %s", argument.Data());
1061 iResult=-EPROTO;
1062 }
1063
7ab8209c 1064 return iResult;
1065}
0fa10601 1066
9b72add5 1067int 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
1086int 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}