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