2 //**************************************************************************
3 //* This file is property of and copyright by the *
4 //* ALICE Experiment at CERN, All rights reserved. *
6 //* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
7 //* for The ALICE HLT Project. *
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 //**************************************************************************
18 /// @file AliHLTTPCDataCompressionComponent.cxx
19 /// @author Matthias Richter
21 /// @brief TPC component for data compression
24 #include "AliHLTTPCDataCompressionComponent.h"
25 #include "AliHLTTPCDefinitions.h"
26 #include "AliHLTTPCDataCompressionDescriptor.h"
27 #include "AliHLTTPCRawClustersDescriptor.h"
28 #include "AliHLTTPCTrackGeometry.h"
29 #include "AliHLTTPCSpacePointContainer.h"
30 #include "AliHLTTPCRawSpacePointContainer.h"
31 #include "AliHLTGlobalBarrelTrack.h"
32 #include "AliHLTComponentBenchmark.h"
33 #include "AliHLTDataDeflaterSimple.h"
34 #include "AliHLTDataDeflaterHuffman.h"
35 #include "AliHLTTPCTransform.h"
36 #include "AliHLTTPCClusterMCData.h"
37 #include "AliHLTTPCClusterTransformation.h"
38 #include "AliHLTErrorGuard.h"
39 #include "AliRawDataHeader.h"
40 #include "AliCDBManager.h"
41 #include "AliCDBPath.h"
43 #include "AliCDBMetaData.h"
44 #include "AliCDBEntry.h"
49 ClassImp(AliHLTTPCDataCompressionComponent)
51 AliHLTTPCDataCompressionComponent::AliHLTTPCDataCompressionComponent()
53 , fMode(kCompressionModeNone)
54 , fDeflaterMode(kDeflaterModeNone)
55 , fVerificationMode(0)
56 , fMaxDeltaPad(AliHLTTPCDefinitions::GetMaxClusterDeltaPad())
57 , fMaxDeltaTime(AliHLTTPCDefinitions::GetMaxClusterDeltaTime())
58 , fRawInputClusters(NULL)
59 , fInputClusters(NULL)
61 , fSpacePointGrid(NULL)
62 , fpDataDeflater(NULL)
63 , fHistoCompFactor(NULL)
64 , fHistoResidualPad(NULL)
65 , fHistoResidualTime(NULL)
66 , fHistoClustersOnTracks(NULL)
67 , fHistoClusterRatio(NULL)
68 , fHistoTrackClusterRatio(NULL)
70 , fTrainingTableOutput()
72 , fpWrittenAssociatedClusterIds(NULL)
73 , fDriftTimeFactorA(1.)
74 , fDriftTimeOffsetA(0.)
75 , fDriftTimeFactorC(1.)
76 , fDriftTimeOffsetC(0.)
81 AliHLTTPCDataCompressionComponent::~AliHLTTPCDataCompressionComponent()
84 if (fpWrittenAssociatedClusterIds) delete fpWrittenAssociatedClusterIds;
88 const char* AliHLTTPCDataCompressionComponent::GetComponentID()
90 /// inherited from AliHLTComponent: id of the component
91 return "TPCDataCompressor";
95 void AliHLTTPCDataCompressionComponent::GetInputDataTypes( AliHLTComponentDataTypeList& tgtList)
97 /// inherited from AliHLTComponent: list of data types in the vector reference
99 tgtList.push_back(AliHLTTPCDefinitions::RawClustersDataType());
100 tgtList.push_back(AliHLTTPCDefinitions::RawClustersDescriptorDataType());
101 tgtList.push_back(AliHLTTPCDefinitions::ClustersDataType());
102 tgtList.push_back(kAliHLTDataTypeTrack|kAliHLTDataOriginTPC);
105 AliHLTComponentDataType AliHLTTPCDataCompressionComponent::GetOutputDataType()
107 /// inherited from AliHLTComponent: output data type of the component.
108 return kAliHLTMultipleDataType;
111 int AliHLTTPCDataCompressionComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& tgtList)
113 /// inherited from AliHLTComponent: multiple output data types of the component.
115 tgtList.push_back(AliHLTTPCDefinitions::DataCompressionDescriptorDataType());
116 tgtList.push_back(AliHLTTPCDefinitions::RawClustersDataType());
117 tgtList.push_back(AliHLTTPCDefinitions::RemainingClustersCompressedDataType());
118 tgtList.push_back(AliHLTTPCDefinitions::RemainingClusterIdsDataType());
119 tgtList.push_back(AliHLTTPCDefinitions::ClusterTracksCompressedDataType());
120 tgtList.push_back(AliHLTTPCDefinitions::ClusterIdTracksDataType());
121 return tgtList.size();
124 void AliHLTTPCDataCompressionComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
126 /// inherited from AliHLTComponent: output data size estimator
128 inputMultiplier=1.; // there should not be more data than input
129 inputMultiplier+=.3; // slightly more data when using the old HWCF data with 20 Byte and raw clusters 22 Byte
130 if (fpWrittenAssociatedClusterIds) inputMultiplier+=.3; // space for optional cluster id array
133 AliHLTComponent* AliHLTTPCDataCompressionComponent::Spawn()
135 /// inherited from AliHLTComponent: spawn function.
136 return new AliHLTTPCDataCompressionComponent;
139 void AliHLTTPCDataCompressionComponent::GetOCDBObjectDescription(TMap* const targetMap)
141 /// Get a list of OCDB object needed for the particular component
142 if (!targetMap) return;
144 targetMap->Add(new TObjString("HLT/ConfigTPC/TPCDataCompressor"),
145 new TObjString("component arguments"));
146 if (fDeflaterMode==kDeflaterModeHuffman) {
147 targetMap->Add(new TObjString("HLT/ConfigTPC/TPCDataCompressorHuffmanTables"),
148 new TObjString("huffman tables for deflater mode 'huffman'"));
152 int AliHLTTPCDataCompressionComponent::DoEvent( const AliHLTComponentEventData& /*evtData*/,
153 const AliHLTComponentBlockData* /*inputBlocks*/,
154 AliHLTComponentTriggerData& /*trigData*/,
155 AliHLTUInt8_t* outputPtr,
156 AliHLTUInt32_t& size,
157 AliHLTComponentBlockDataList& outputBlocks )
159 /// inherited from AliHLTProcessor: data processing
161 AliHLTUInt32_t capacity=size;
164 if (!IsDataEvent()) return 0;
166 if (!fRawInputClusters) {
170 if (GetBenchmarkInstance()) {
171 GetBenchmarkInstance()->StartNewEvent();
172 GetBenchmarkInstance()->Start(0);
177 // Loop over all input blocks in the event
178 bool bHaveMC=(GetFirstInputBlock(AliHLTTPCDefinitions::fgkAliHLTDataTypeClusterMCInfo | kAliHLTDataOriginTPC))!=NULL;
179 if ((bHaveMC || fVerificationMode>0) && fpWrittenAssociatedClusterIds==NULL) {
180 fpWrittenAssociatedClusterIds=new vector<AliHLTUInt32_t>;
183 const AliHLTComponentBlockData* pDesc=NULL;
185 AliHLTUInt8_t minSlice=0xFF, maxSlice=0xFF, minPatch=0xFF, maxPatch=0xFF;
186 AliHLTUInt32_t inputRawClusterSize=0;
187 AliHLTUInt32_t outputDataSize=0;
189 int associatedClusters=0;
192 /// input track array
193 vector<AliHLTGlobalBarrelTrack> inputTrackArray;
195 if (GetBenchmarkInstance()) {
196 GetBenchmarkInstance()->Start(2);
199 bool isInputPresent = kFALSE;
201 // transformed clusters
202 // the transformed clusters have not been used yet
203 if (false) { // FIXME: condition to be adjusted
204 for (pDesc=GetFirstInputBlock(AliHLTTPCDefinitions::fgkClustersDataType);
205 pDesc!=NULL; pDesc=GetNextInputBlock()) {
206 if (GetBenchmarkInstance()) {
207 GetBenchmarkInstance()->AddInput(pDesc->fSize);
209 isInputPresent = kTRUE;
210 AliHLTUInt8_t slice = 0;
211 AliHLTUInt8_t patch = 0;
212 slice = AliHLTTPCDefinitions::GetMinSliceNr( pDesc->fSpecification );
213 patch = AliHLTTPCDefinitions::GetMinPatchNr( pDesc->fSpecification );
214 if ( minSlice==0xFF || slice<minSlice ) minSlice = slice;
215 if ( maxSlice==0xFF || slice>maxSlice ) maxSlice = slice;
216 if ( minPatch==0xFF || patch<minPatch ) minPatch = patch;
217 if ( maxPatch==0xFF || patch>maxPatch ) maxPatch = patch;
218 if (fInputClusters) {
219 fInputClusters->AddInputBlock(pDesc);
222 if (GetBenchmarkInstance()) {
223 GetBenchmarkInstance()->Stop(2);
224 GetBenchmarkInstance()->Start(3);
228 vector<int> trackindexmap; // stores index for every track id
231 if (fMode==kCompressionModeV1TrackModel || fMode==kCompressionModeV2TrackModel) {
232 for (pDesc=GetFirstInputBlock(kAliHLTDataTypeTrack|kAliHLTDataOriginTPC);
233 pDesc!=NULL; pDesc=GetNextInputBlock()) {
234 if (GetBenchmarkInstance()) {
235 GetBenchmarkInstance()->AddInput(pDesc->fSize);
237 AliHLTUInt8_t slice = 0;
238 AliHLTUInt8_t patch = 0;
239 slice = AliHLTTPCDefinitions::GetMinSliceNr( pDesc->fSpecification );
240 patch = AliHLTTPCDefinitions::GetMinPatchNr( pDesc->fSpecification );
241 if ( minSlice==0xFF || slice<minSlice ) minSlice = slice;
242 if ( maxSlice==0xFF || slice>maxSlice ) maxSlice = slice;
243 if ( minPatch==0xFF || patch<minPatch ) minPatch = patch;
244 if ( maxPatch==0xFF || patch>maxPatch ) maxPatch = patch;
245 const AliHLTTracksData* pTracks=reinterpret_cast<const AliHLTTracksData*>(pDesc->fPtr);
246 if ((iResult=AliHLTGlobalBarrelTrack::ConvertTrackDataArray(pTracks, pDesc->fSize, inputTrackArray))<0) {
249 trackindexmap.resize(inputTrackArray.size(), -1);
253 if (GetBenchmarkInstance()) {
254 GetBenchmarkInstance()->Stop(3);
255 GetBenchmarkInstance()->Start(4);
260 for (vector<AliHLTGlobalBarrelTrack>::iterator track=inputTrackArray.begin();
261 track!=inputTrackArray.end();
262 track++, trackindex++) {
263 int trackID=track->GetID();
265 // FIXME: error guard
266 HLTError("invalid track ID");
269 if (trackID>=(int)trackindexmap.size())
270 trackindexmap.resize(trackID+1, -1);
271 trackindexmap[trackID]=trackindex;
274 UInt_t nofPoints=track->GetNumberOfPoints();
275 const UInt_t* points=track->GetPoints();
276 for (unsigned i=0; i<nofPoints; i++) {
277 int slice=AliHLTTPCSpacePointData::GetSlice(points[i]);
278 int partition=AliHLTTPCSpacePointData::GetPatch(points[i]);
279 int number=AliHLTTPCSpacePointData::GetNumber(points[i]);
280 HLTInfo("track %d point %d id 0x%08x slice %d partition %d number %d", track->GetID(), i, points[i], slice, partition, number);
284 AliHLTTPCTrackGeometry* trackpoints=new AliHLTTPCTrackGeometry;
285 if (!trackpoints) continue;
286 HLTDebug("track %d id %d:", trackindex, trackID);
288 // in order to avoid rounding errors the track points are
289 // calculated in exactly the same way as in the decoding
290 // Thats why the track instance can not be used directly
291 // but a new instance is created from the values in the
293 // think about moving that to some common code used by
294 // both compression and decoding
295 AliHLTExternalTrackParam param;
296 memset(¶m, 0, sizeof(param));
297 float alpha=track->GetAlpha();
298 while (alpha<0.) alpha+=TMath::TwoPi();
299 while (alpha>TMath::TwoPi()) alpha-=TMath::TwoPi();
300 AliHLTUInt8_t tSlice=AliHLTUInt8_t(9*alpha/TMath::Pi());
301 param.fAlpha =( tSlice + 0.5 ) * TMath::Pi() / 9.0;
302 if (param.fAlpha>TMath::TwoPi()) param.fAlpha-=TMath::TwoPi();
303 param.fX = track->GetX();
304 param.fY = track->GetY();
305 param.fZ = track->GetZ();
306 param.fSinPsi = track->GetSnp();
307 param.fTgl = track->GetTgl();
308 param.fq1Pt = track->GetSigned1Pt();
309 AliHLTGlobalBarrelTrack ctrack(param);
310 ctrack.CalculateHelixParams(bz);
311 trackpoints->InitDriftTimeTransformation(fDriftTimeFactorA, fDriftTimeOffsetA, fDriftTimeFactorC, fDriftTimeOffsetC);
312 trackpoints->SetTrackId(trackID);
313 trackpoints->CalculateTrackPoints(ctrack);
314 trackpoints->RegisterTrackPoints(fTrackGrid);
315 track->SetTrackGeometry(trackpoints);
318 for (vector<AliHLTGlobalBarrelTrack>::const_iterator track=inputTrackArray.begin();
319 track!=inputTrackArray.end();
321 AliHLTTrackGeometry* trackpoints=track->GetTrackGeometry();
322 if (!trackpoints) continue;
323 trackpoints->FillTrackPoints(fTrackGrid);
329 if (GetBenchmarkInstance()) {
330 GetBenchmarkInstance()->Stop(4);
331 GetBenchmarkInstance()->Start(5);
334 // loop over raw cluster blocks, assign to tracks and write
335 // unassigned clusters
336 for (pDesc=GetFirstInputBlock(AliHLTTPCDefinitions::fgkRawClustersDataType);
337 pDesc!=NULL; pDesc=GetNextInputBlock()) {
338 if (GetBenchmarkInstance()) {
339 GetBenchmarkInstance()->Start(1);
340 GetBenchmarkInstance()->AddInput(pDesc->fSize);
342 isInputPresent = kTRUE;
343 AliHLTUInt8_t slice = 0;
344 AliHLTUInt8_t patch = 0;
345 slice = AliHLTTPCDefinitions::GetMinSliceNr( pDesc->fSpecification );
346 patch = AliHLTTPCDefinitions::GetMinPatchNr( pDesc->fSpecification );
347 if ( minSlice==0xFF || slice<minSlice ) minSlice = slice;
348 if ( maxSlice==0xFF || slice>maxSlice ) maxSlice = slice;
349 if ( minPatch==0xFF || patch<minPatch ) minPatch = patch;
350 if ( maxPatch==0xFF || patch>maxPatch ) maxPatch = patch;
351 inputRawClusterSize+=pDesc->fSize;
353 // add the data and populate the index grid
354 fRawInputClusters->AddInputBlock(pDesc);
355 fRawInputClusters->PopulateAccessGrid(fSpacePointGrid, pDesc->fSpecification);
356 if (fVerbosity>0 && fSpacePointGrid->GetNumberOfSpacePoints()>0) {
357 HLTInfo("index grid slice %d partition %d", slice, patch);
358 fSpacePointGrid->Print();
359 for (AliHLTSpacePointContainer::AliHLTSpacePointPropertyGrid::iterator& cl=fSpacePointGrid->begin();
360 cl!=fSpacePointGrid->end(); cl++) {
361 AliHLTUInt32_t id=cl.Data().fId;
362 float row=fRawInputClusters->GetX(id);
363 float pad=fRawInputClusters->GetY(id);
364 float time=fRawInputClusters->GetZ(id);
365 HLTInfo(" cluster id 0x%08x: row %f pad %f time %f", id, row, pad, time);
368 if (GetBenchmarkInstance()) {
369 GetBenchmarkInstance()->Stop(1);
370 GetBenchmarkInstance()->Start(4);
373 // process the clusters per padrow and check the track grid
374 // for tracks crossing that particular padrow
375 if (GetBenchmarkInstance()) {
376 GetBenchmarkInstance()->Stop(4);
377 GetBenchmarkInstance()->Start(5);
379 allClusters+=fSpacePointGrid->GetNumberOfSpacePoints();
380 iResult=ProcessTrackClusters(&inputTrackArray[0], inputTrackArray.size(), fTrackGrid, trackindexmap, fSpacePointGrid, fRawInputClusters, slice, patch);
381 int assignedInThisPartition=0;
383 assignedInThisPartition=iResult;
384 associatedClusters+=iResult;
386 iResult=ProcessRemainingClusters(&inputTrackArray[0], inputTrackArray.size(), fTrackGrid, trackindexmap, fSpacePointGrid, fRawInputClusters, slice, patch);
388 if (fSpacePointGrid->GetNumberOfSpacePoints()>0) {
389 if (fVerbosity>0) HLTInfo("associated %d (%d) of %d clusters in slice %d partition %d", iResult+assignedInThisPartition, assignedInThisPartition, fSpacePointGrid->GetNumberOfSpacePoints(), slice, patch);
391 associatedClusters+=iResult;
394 // write all remaining clusters not yet assigned to tracks
395 // the index grid is used to write sorted in padrow
396 // FIXME: decoder index instead of data specification to be used
397 // use an external access grid to reduce allocated memory
398 // set to NULL after writing the clusters
399 const char* writeoptions="";
400 if (fpWrittenAssociatedClusterIds) {
401 writeoptions="write-cluster-ids";
403 fRawInputClusters->SetSpacePointPropertyGrid(pDesc->fSpecification, fSpacePointGrid);
404 iResult=fRawInputClusters->Write(outputPtr+size, capacity-size, outputBlocks, fpDataDeflater, writeoptions);
405 fRawInputClusters->SetSpacePointPropertyGrid(pDesc->fSpecification, NULL);
408 outputDataSize+=iResult;
409 // the size of the optional cluster id array must be subtracted
410 if (fpWrittenAssociatedClusterIds && outputBlocks.size()>0 &&
411 outputBlocks.back().fDataType==AliHLTTPCDefinitions::RemainingClusterIdsDataType()) {
412 outputDataSize-=outputBlocks.back().fSize;
414 if (GetBenchmarkInstance()) GetBenchmarkInstance()->AddOutput(iResult);
416 if (GetBenchmarkInstance()) {
417 GetBenchmarkInstance()->Stop(5);
420 fSpacePointGrid->Clear();
422 if (fHistoClusterRatio && allClusters>0) {
423 if (fVerbosity>0) HLTInfo("associated %d of %d clusters to tracks", associatedClusters, allClusters);
424 float ratio=associatedClusters; ratio/=allClusters;
425 fHistoClusterRatio->Fill(ratio);
428 // output of track model clusters
430 AliHLTUInt32_t tracksBufferOffset=sizeof(AliHLTTPCTrackModelBlock);
431 if (capacity-size<tracksBufferOffset) {
435 if (fpWrittenAssociatedClusterIds) fpWrittenAssociatedClusterIds->clear();
436 AliHLTTPCTrackModelBlock* trackModelBlock=reinterpret_cast<AliHLTTPCTrackModelBlock*>(outputPtr+size);
437 trackModelBlock->fVersion=1;
438 trackModelBlock->fDeflaterMode=fpDataDeflater?fpDataDeflater->GetDeflaterVersion():0;
439 trackModelBlock->fTrackCount=inputTrackArray.size();
440 trackModelBlock->fClusterCount=0;
441 trackModelBlock->fGlobalParameterCnt=5;
442 tracksBufferOffset+=trackModelBlock->fGlobalParameterCnt*sizeof(trackModelBlock->fGlobalParameters);
443 if (capacity-size<tracksBufferOffset) {
448 AliHLTUInt32_t parameterIndex=0;
449 trackModelBlock->fGlobalParameters[parameterIndex++]=bz;
450 trackModelBlock->fGlobalParameters[parameterIndex++]=fDriftTimeFactorA;
451 trackModelBlock->fGlobalParameters[parameterIndex++]=fDriftTimeOffsetA;
452 trackModelBlock->fGlobalParameters[parameterIndex++]=fDriftTimeFactorC;
453 trackModelBlock->fGlobalParameters[parameterIndex++]=fDriftTimeOffsetC;
454 if (parameterIndex!=trackModelBlock->fGlobalParameterCnt) {
455 HLTError("internal error, size of parameter array has changed without providing all values");
460 if (trackindexmap.size()>0) {// condition for track model compression
461 iResult=WriteTrackClusters(inputTrackArray, fRawInputClusters, fpDataDeflater, outputPtr+size+tracksBufferOffset, capacity-size-tracksBufferOffset);
463 AliHLTComponent_BlockData bd;
466 bd.fSize = tracksBufferOffset+iResult;
467 bd.fDataType = AliHLTTPCDefinitions::ClusterTracksCompressedDataType();
468 bd.fSpecification = AliHLTTPCDefinitions::EncodeDataSpecification(minSlice, maxSlice, minPatch, maxPatch);
469 outputBlocks.push_back(bd);
471 outputDataSize+=bd.fSize;
472 HLTBenchmark("track data block of %d tracks: size %d", inputTrackArray.size(), bd.fSize);
474 if (fpWrittenAssociatedClusterIds && fpWrittenAssociatedClusterIds->size()>0) {
475 AliHLTComponent::FillBlockData(bd);
477 bd.fSize = fpWrittenAssociatedClusterIds->size()*sizeof(vector<AliHLTUInt32_t>::value_type);
478 if (capacity-size>bd.fSize) {
479 memcpy(outputPtr+bd.fOffset, &(*fpWrittenAssociatedClusterIds)[0], bd.fSize);
480 bd.fDataType = AliHLTTPCDefinitions::ClusterIdTracksDataType();
481 bd.fSpecification = AliHLTTPCDefinitions::EncodeDataSpecification(minSlice, maxSlice, minPatch, maxPatch);
482 outputBlocks.push_back(bd);
488 fpWrittenAssociatedClusterIds->clear();
494 fRawInputClusters->Clear();
496 // Write header block
498 if( isInputPresent ){
499 pDesc=GetFirstInputBlock(AliHLTTPCDefinitions::RawClustersDescriptorDataType() );
501 const AliHLTTPCRawClustersDescriptor &clDesc = *reinterpret_cast<const AliHLTTPCRawClustersDescriptor*>(pDesc->fPtr);
502 if( !clDesc.CheckSize( pDesc->fSize ) ){
503 HLTError("Corrupted cluster descriptor");
506 AliHLTComponent_BlockData bd;
509 bd.fSize = sizeof(AliHLTTPCDataCompressionDescriptor);
510 bd.fDataType = AliHLTTPCDefinitions::DataCompressionDescriptorDataType();
511 if( capacity < size + bd.fSize ){
516 AliHLTTPCDataCompressionDescriptor compDesc;
517 compDesc.SetMergedClustersFlag( clDesc.GetMergedClustersFlag() );
518 *(AliHLTTPCDataCompressionDescriptor*)(outputPtr + bd.fOffset ) = compDesc;
520 outputBlocks.push_back(bd);
522 outputDataSize+=bd.fSize;
523 //HLTBenchmark("header data block of size %d", bd.fSize);
527 float compressionFactor=(float)inputRawClusterSize;
528 if ((outputDataSize)>0) compressionFactor/=outputDataSize;
529 else compressionFactor=0.;
530 if (fHistoCompFactor) fHistoCompFactor->Fill(compressionFactor);
532 if (GetBenchmarkInstance() && allClusters>0) {
533 GetBenchmarkInstance()->Stop(0);
534 if (fDeflaterMode!=kDeflaterModeHuffmanTrainer) {
535 HLTBenchmark("%s - compression factor %.2f", GetBenchmarkInstance()->GetStatistics(), compressionFactor);
537 HLTBenchmark("%s", GetBenchmarkInstance()->GetStatistics());
541 if (fInputClusters) {
542 fInputClusters->Clear();
544 if (fRawInputClusters) {
545 fRawInputClusters->Clear();
552 for (pDesc=GetFirstInputBlock(AliHLTTPCDefinitions::fgkAliHLTDataTypeClusterMCInfo | kAliHLTDataOriginTPC);
553 pDesc!=NULL; pDesc=GetNextInputBlock()) {
554 outputBlocks.push_back(*pDesc);
560 int AliHLTTPCDataCompressionComponent::ProcessTrackClusters(AliHLTGlobalBarrelTrack* pTracks, unsigned nofTracks,
561 AliHLTTrackGeometry::AliHLTTrackGrid* pTrackIndex,
562 const vector<int>& trackIndexMap,
563 AliHLTSpacePointContainer::AliHLTSpacePointPropertyGrid* pClusterIndex,
564 AliHLTSpacePointContainer* pClusters,
565 int slice, int partition) const
567 // process to assigned track clusters
569 int assignedClusters=0;
570 if (!pTracks || nofTracks==0) return 0;
572 vector<int> processedTracks(nofTracks, -1);
573 for (AliHLTTrackGeometry::AliHLTTrackGrid::iterator& trackId=pTrackIndex->begin(slice, partition, -1);
574 trackId!=pTrackIndex->end(); trackId++) {
575 if (trackId.Data()>=trackIndexMap.size()) {
576 HLTError("can not find track id %d in index map of size %d", trackId.Data(), trackIndexMap.size());
579 int trackindex=trackIndexMap[trackId.Data()];
580 if (trackindex<0 || trackindex>=(int)nofTracks) {
581 HLTError("invalid index %d found for track id %d", trackindex, trackId.Data());
584 if (processedTracks[trackindex]>0) continue;
585 processedTracks[trackindex]=1;
586 AliHLTGlobalBarrelTrack& track=pTracks[trackindex];
587 if (!track.GetTrackGeometry()) {
588 HLTError("can not find track geometry for track %d", trackId.Data());
591 AliHLTTPCTrackGeometry* pTrackPoints=dynamic_cast<AliHLTTPCTrackGeometry*>(track.GetTrackGeometry());
593 HLTError("invalid track geometry type for track %d, expecting AliHLTTPCTrackGeometry", trackId.Data());
597 UInt_t nofTrackPoints=track.GetNumberOfPoints();
598 const UInt_t* trackPoints=track.GetPoints();
599 for (unsigned i=0; i<nofTrackPoints; i++) {
600 const AliHLTUInt32_t& clusterId=trackPoints[i];
601 if (AliHLTTPCSpacePointData::GetSlice(clusterId)!=(unsigned)slice ||
602 AliHLTTPCSpacePointData::GetPatch(clusterId)!=(unsigned)partition) {
603 // not in the current partition;
607 int clusterrow=(int)pClusters->GetX(clusterId);
608 AliHLTUInt32_t pointId=AliHLTTPCSpacePointData::GetID(slice, partition, clusterrow);
609 AliHLTTrackGeometry::AliHLTTrackPoint* point=pTrackPoints->GetRawTrackPoint(pointId);
611 //HLTError("can not find track point slice %d partition %d padrow %d (0x%08x) of track %d", slice, partition, clusterrow, pointId, trackId.Data());
614 float pad=point->GetU();
615 float time=point->GetV();
617 iResult=FindCellClusters(trackId.Data(), clusterrow, pad, time, pClusterIndex, pClusters, point, clusterId);
618 if (iResult>0) assignedClusters+=iResult;
621 return assignedClusters;
624 int AliHLTTPCDataCompressionComponent::ProcessRemainingClusters(AliHLTGlobalBarrelTrack* pTracks, unsigned nofTracks,
625 AliHLTTrackGeometry::AliHLTTrackGrid* pTrackIndex,
626 const vector<int>& trackIndexMap,
627 AliHLTSpacePointContainer::AliHLTSpacePointPropertyGrid* pClusterIndex,
628 AliHLTSpacePointContainer* pClusters,
629 int slice, int partition) const
631 // assign remaining clusters to tracks
633 int associatedClusters=0;
634 if (!pTracks || nofTracks==0) return 0;
636 for (int padrow=0; padrow<AliHLTTPCTransform::GetNRows(partition); padrow++) {
637 for (AliHLTTrackGeometry::AliHLTTrackGrid::iterator& trackId=pTrackIndex->begin(slice, partition, padrow);
638 trackId!=pTrackIndex->end(); trackId++) {
639 if (trackId.Data()>=trackIndexMap.size()) {
640 HLTError("can not find track id %d in index map of size %d", trackId.Data(), trackIndexMap.size());
643 int trackindex=trackIndexMap[trackId.Data()];
644 if (trackindex<0 || trackindex>=(int)nofTracks) {
645 HLTError("invalid index %d found for track id %d", trackindex, trackId.Data());
648 AliHLTGlobalBarrelTrack& track=pTracks[trackindex];
649 if (!track.GetTrackGeometry()) {
650 HLTError("can not find track geometry for track %d", trackId.Data());
653 AliHLTTPCTrackGeometry* pTrackPoints=dynamic_cast<AliHLTTPCTrackGeometry*>(track.GetTrackGeometry());
655 HLTError("invalid track geometry type for track %d, expecting AliHLTTPCTrackGeometry", trackId.Data());
658 AliHLTUInt32_t pointId=AliHLTTPCSpacePointData::GetID(slice, partition, padrow);
659 AliHLTTrackGeometry::AliHLTTrackPoint* point=pTrackPoints->GetRawTrackPoint(pointId);
661 //HLTError("can not find track point slice %d partition %d padrow %d (0x%08x) of track %d", slice, partition, padrow, pointId, trackId.Data());
664 float pad=point->GetU();
665 float time=point->GetV();
667 iResult=FindCellClusters(trackId.Data(), padrow, pad, time, pClusterIndex, pClusters, point);
668 if (iResult>0) associatedClusters+=iResult;
670 HLTInfo("trackpoint track %d slice %d partition %d padrow %d: %.3f \t%.3f - associated %d", track.GetID(), slice, partition, padrow, pad, time, iResult);
674 if (iResult<0) return iResult;
675 return associatedClusters;
678 int AliHLTTPCDataCompressionComponent::FindCellClusters(int trackId, int padrow, float pad, float time,
679 AliHLTSpacePointContainer::AliHLTSpacePointPropertyGrid* pClusterIndex,
680 AliHLTSpacePointContainer* pClusters,
681 AliHLTTrackGeometry::AliHLTTrackPoint* pTrackPoint,
682 AliHLTUInt32_t clusterId) const
684 // check index cell for entries and assign to track
686 // search a 4x4 matrix out of the 9x9 matrix around the cell addressed by
688 int rowindex=pClusterIndex->GetXIndex((float)padrow);
689 int padstartindex=pClusterIndex->GetYIndex(pad);
690 int timestartindex=pClusterIndex->GetZIndex(time);
691 int cellindex=pClusterIndex->Index(rowindex, padstartindex, timestartindex);
692 float centerpad=pClusterIndex->GetCenterY(cellindex);
693 float centertime=pClusterIndex->GetCenterZ(cellindex);
694 if ((TMath::Abs(centerpad-pad)>fMaxDeltaPad && pad>0.) ||
695 (TMath::Abs(centertime-time)>fMaxDeltaTime && time>0.)) {
696 ALIHLTERRORGUARD(20, "invalid pad center calculation, please check dimensions if dimensions of index grid match the maximum possible deviation");
701 if (centerpad>pad) paddirection=-1;
702 if (centertime>time) timedirection=-1;
703 for (int padcount=0, padindex=padstartindex; padcount<2; padcount++, padindex+=paddirection) {
704 if (padindex<0) continue;
705 if (padindex>=pClusterIndex->GetDimensionY()) break;
706 for (int timecount=0, timeindex=timestartindex; timecount<2; timecount++, timeindex+=timedirection) {
707 if (timeindex<0) continue;
708 if (timeindex>=pClusterIndex->GetDimensionZ()) break;
709 cellindex=pClusterIndex->Index(rowindex, padindex, timeindex);
710 float cellpad=pClusterIndex->GetCenterY(cellindex);
711 float celltime=pClusterIndex->GetCenterZ(cellindex);
712 for (AliHLTSpacePointContainer::AliHLTSpacePointPropertyGrid::iterator& cl=pClusterIndex->begin((float)padrow, cellpad, celltime);
713 cl!=pClusterIndex->end(); cl++) {
714 if (cl.Data().fTrackId>=0) continue;
715 if (clusterId!=(~(AliHLTUInt32_t)0) && clusterId!=cl.Data().fId) continue;
716 if (TMath::Abs(padrow-pClusters->GetX(cl.Data().fId))>=1.) {
717 HLTError("cluster 0x%08x: mismatch on padrow: trackpoint %d cluster %f", cl.Data().fId, padrow, pClusters->GetX(cl.Data().fId));
720 float clusterpad=pClusters->GetY(cl.Data().fId);
721 float clustertime=pClusters->GetZ(cl.Data().fId);
722 if (TMath::Abs(clusterpad-pad)<fMaxDeltaPad &&
723 TMath::Abs(clustertime-time)<fMaxDeltaTime) {
724 // add this cluster to the track point and mark in the index grid
725 cl.Data().fTrackId=trackId;
726 pTrackPoint->AddAssociatedSpacePoint(cl.Data().fId, clusterpad-pad, clustertime-time);
729 if (clusterId!=(~(AliHLTUInt32_t)0)) break;
736 int AliHLTTPCDataCompressionComponent::WriteTrackClusters(const vector<AliHLTGlobalBarrelTrack>& tracks,
737 AliHLTSpacePointContainer* pSpacePoints,
738 AliHLTDataDeflater* pDeflater,
739 AliHLTUInt8_t* outputPtr,
740 AliHLTUInt32_t capacity) const
742 // write the track data block including all associated clusters
743 AliHLTUInt32_t size=0;
744 for (vector<AliHLTGlobalBarrelTrack>::const_iterator track=tracks.begin();
747 if (!track->GetTrackGeometry()) {
748 HLTError("can not find track geometry for track %d", track->GetID());
751 AliHLTTPCTrackGeometry* pTrackPoints=dynamic_cast<AliHLTTPCTrackGeometry*>(track->GetTrackGeometry());
753 HLTError("invalid track geometry type for track %d, expecting AliHLTTPCTrackGeometry", track->GetID());
757 int result=pTrackPoints->Write(*track, pSpacePoints, pDeflater, outputPtr+size, capacity-size, fpWrittenAssociatedClusterIds);
758 if (result<0) return result;
761 UInt_t nofTrackPoints=track->GetNumberOfPoints();
762 const UInt_t* trackPoints=track->GetPoints();
764 int assignedPoints=0;
765 int assignedTrackPoints=0;
766 const vector<AliHLTTrackGeometry::AliHLTTrackPoint>& rawPoints=pTrackPoints->GetRawPoints();
767 for (vector<AliHLTTrackGeometry::AliHLTTrackPoint>::const_iterator point=rawPoints.begin();
768 point!=rawPoints.end(); point++) {
769 const vector<AliHLTTrackGeometry::AliHLTTrackSpacepoint>& spacePoints=point->GetSpacepoints();
770 for (vector<AliHLTTrackGeometry::AliHLTTrackSpacepoint>::const_iterator spacePoint=spacePoints.begin();
771 spacePoint!=spacePoints.end(); spacePoint++) {
772 float dpad=spacePoint->GetResidual(0);
773 float dtime=spacePoint->GetResidual(1);
774 if (dpad>-1000 && dtime>-1000 && fHistoResidualPad && fHistoResidualTime) {
775 fHistoResidualPad->Fill(dpad);
776 fHistoResidualTime->Fill(dtime);
779 for (unsigned i=0; i<nofTrackPoints; i++) {
780 if (trackPoints[i]==spacePoint->fId) {
781 assignedTrackPoints++;
787 if (fHistoClustersOnTracks) {
788 fHistoClustersOnTracks->Fill(assignedPoints);
790 if (fHistoTrackClusterRatio && nofTrackPoints>0) {
791 float ratio=assignedTrackPoints; ratio/=nofTrackPoints;
792 fHistoTrackClusterRatio->Fill(ratio);
798 int AliHLTTPCDataCompressionComponent::DoInit( int argc, const char** argv )
800 /// inherited from AliHLTComponent: component initialisation and argument scan.
803 // component configuration
804 //Stage 1: default initialization.
808 TString cdbPath("HLT/ConfigTPC/");
809 cdbPath += GetComponentID();
811 iResult = ConfigureFromCDBTObjString(cdbPath);
815 //Stage 3: command line arguments.
816 int mode=fMode; // just a backup for the info message below
817 int deflaterMode=fDeflaterMode;
818 if (argc && (iResult = ConfigureFromArgumentString(argc, argv)) < 0)
821 if (mode!=fMode || deflaterMode!=fDeflaterMode) {
822 HLTInfo("configured from command line: mode %d, deflater mode %d", fMode, fDeflaterMode);
825 std::auto_ptr<AliHLTComponentBenchmark> benchmark(new AliHLTComponentBenchmark);
826 if (benchmark.get()) {
827 benchmark->SetTimer(0,"total");
828 benchmark->SetTimer(1,"rawclusterinput");
829 benchmark->SetTimer(2,"clusterinput");
830 benchmark->SetTimer(3,"trackinput");
831 benchmark->SetTimer(4,"processing");
832 benchmark->SetTimer(5,"output");
837 unsigned spacePointContainerMode=0;
838 if (fMode==kCompressionModeV1TrackModel || fMode==kCompressionModeV2TrackModel) {
839 // initialize map data for cluster access in the track association loop
840 spacePointContainerMode|=AliHLTTPCRawSpacePointContainer::kModeCreateMap;
842 if (fMode==kCompressionModeV2 || fMode==kCompressionModeV2TrackModel) {
843 // optimized storage format: differential pad and time storage
844 spacePointContainerMode|=AliHLTTPCRawSpacePointContainer::kModeDifferentialPadTime;
846 std::auto_ptr<AliHLTTPCRawSpacePointContainer> rawInputClusters(new AliHLTTPCRawSpacePointContainer(spacePointContainerMode));
847 std::auto_ptr<AliHLTTPCSpacePointContainer> inputClusters(new AliHLTTPCSpacePointContainer);
849 std::auto_ptr<TH1F> histoCompFactor(new TH1F("CompressionFactor",
850 "HLT TPC data compression factor",
852 std::auto_ptr<TH1F> histoResidualPad(new TH1F("PadResidual",
853 "HLT TPC pad residual",
854 100, -fMaxDeltaPad, fMaxDeltaPad));
855 std::auto_ptr<TH1F> histoResidualTime(new TH1F("TimeResidual",
856 "HLT TPC time residual",
857 100, -fMaxDeltaTime, fMaxDeltaTime));
858 std::auto_ptr<TH1F> histoClustersOnTracks(new TH1F("ClustersOnTracks",
859 "Clusters in track model compression",
861 std::auto_ptr<TH1F> histoClusterRatio(new TH1F("ClusterRatio",
862 "Fraction of clusters in track model compression",
864 std::auto_ptr<TH1F> histoTrackClusterRatio(new TH1F("UsedTrackClusters",
865 "Fraction of track clusters in track model compression",
868 // track grid: 36 slices, each 6 partitions with max 33 rows
869 fTrackGrid=new AliHLTTrackGeometry::AliHLTTrackGrid(36, 1, 6, 1, 33, 1, 20000);
870 fSpacePointGrid=AliHLTTPCRawSpacePointContainer::AllocateIndexGrid();
872 if (!rawInputClusters.get() ||
873 !inputClusters.get() ||
876 if (fTrackGrid) delete fTrackGrid; fTrackGrid=NULL;
877 if (fSpacePointGrid) delete fSpacePointGrid; fSpacePointGrid=NULL;
881 if (fDeflaterMode>0 && (iResult=InitDeflater(fDeflaterMode))<0)
884 fpBenchmark=benchmark.release();
885 fRawInputClusters=rawInputClusters.release();
886 fInputClusters=inputClusters.release();
888 // initialize the histograms if stored at the end
889 // condition might be extended
890 if (!fHistogramFile.IsNull()) {
891 fHistoCompFactor=histoCompFactor.release();
892 fHistoResidualPad=histoResidualPad.release();
893 fHistoResidualTime=histoResidualTime.release();
894 fHistoClustersOnTracks=histoClustersOnTracks.release();
895 fHistoClusterRatio=histoClusterRatio.release();
896 fHistoTrackClusterRatio=histoTrackClusterRatio.release();
899 if (iResult>=0 && (iResult=InitDriftTimeTransformation())<0) return iResult;
904 int AliHLTTPCDataCompressionComponent::InitDeflater(int mode)
906 /// init the data deflater
908 if (mode==kDeflaterModeHuffman || mode==kDeflaterModeHuffmanTrainer) {
910 std::auto_ptr<AliHLTDataDeflaterHuffman> deflater(new AliHLTDataDeflaterHuffman(mode==kDeflaterModeHuffmanTrainer));
911 if (!deflater.get()) return -ENOMEM;
913 if (!deflater->IsTrainingMode()) {
914 TString cdbPath("HLT/ConfigTPC/");
915 cdbPath += GetComponentID();
916 cdbPath += "HuffmanTables";
917 TObject* pConf=LoadAndExtractOCDBObject(cdbPath);
918 if (!pConf) return -ENOENT;
919 if (dynamic_cast<TList*>(pConf)==NULL) {
920 HLTError("huffman table configuration object of inconsistent type");
923 iResult=deflater->InitDecoders(dynamic_cast<TList*>(pConf));
924 if (iResult<0) return iResult;
927 if (!fHistogramFile.IsNull())
928 deflater->EnableStatistics();
930 unsigned nofParameters=AliHLTTPCDefinitions::GetNumberOfClusterParameterDefinitions();
932 for (; p<nofParameters; p++) {
933 const AliHLTTPCDefinitions::AliClusterParameter& parameter=AliHLTTPCDefinitions::fgkClusterParameterDefinitions[p];
934 // use the pad/time length as reference for the calculation of ratio for residuals
935 unsigned refLength=0;
936 unsigned refLengthPad=0;
937 unsigned refLengthTime=0;
938 if (parameter.fId==AliHLTTPCDefinitions::kPad) refLengthPad=parameter.fBitLength;
939 else if (parameter.fId==AliHLTTPCDefinitions::kTime) refLengthTime=parameter.fBitLength;
940 else if (parameter.fId==AliHLTTPCDefinitions::kResidualPad) refLength=refLengthPad;
941 else if (parameter.fId==AliHLTTPCDefinitions::kResidualTime) refLength=refLengthTime;
943 if (deflater->AddParameterDefinition(parameter.fName,
944 parameter.fBitLength,
945 refLength)!=(int)parameter.fId) {
946 // for performance reason the parameter id is simply used as index in the array of
947 // definitions, the position must match the id
948 HLTFatal("mismatch between parameter id and position in array for parameter %s, rearrange definitions!", parameter.fName);
952 fpDataDeflater=deflater.release();
955 if (mode==kDeflaterModeSimple) {
956 std::auto_ptr<AliHLTDataDeflaterSimple> deflater(new AliHLTDataDeflaterSimple);
957 if (!deflater.get()) return -ENOMEM;
959 if (!fHistogramFile.IsNull())
960 deflater->EnableStatistics();
962 unsigned nofParameters=AliHLTTPCDefinitions::GetNumberOfClusterParameterDefinitions();
964 for (; p<nofParameters; p++) {
965 const AliHLTTPCDefinitions::AliClusterParameter& parameter=AliHLTTPCDefinitions::fgkClusterParameterDefinitions[p];
966 if (deflater->AddParameterDefinition(parameter.fName,
967 parameter.fBitLength,
968 parameter.fOptional)!=(int)parameter.fId) {
969 // for performance reason the parameter id is simply used as index in the array of
970 // definitions, the position must match the id
971 HLTFatal("mismatch between parameter id and position in array for parameter %s, rearrange definitions!", parameter.fName);
975 fpDataDeflater=deflater.release();
978 HLTError("invalid deflater mode %d, allowed 1=simple 2=huffman", mode);
982 int AliHLTTPCDataCompressionComponent::DoDeinit()
984 /// inherited from AliHLTComponent: component cleanup
986 if (fpBenchmark) delete fpBenchmark; fpBenchmark=NULL;
987 if (fRawInputClusters) delete fRawInputClusters; fRawInputClusters=NULL;
988 if (fInputClusters) delete fInputClusters; fInputClusters=NULL;
989 if (!fHistogramFile.IsNull()) {
990 TFile out(fHistogramFile, "RECREATE");
991 if (!out.IsZombie()) {
993 if (fHistoCompFactor) fHistoCompFactor->Write();
994 if (fHistoResidualPad) fHistoResidualPad->Write();
995 if (fHistoResidualTime) fHistoResidualTime->Write();
996 if (fHistoClusterRatio) fHistoClusterRatio->Write();
997 if (fHistoClustersOnTracks) fHistoClustersOnTracks->Write();
998 if (fHistoTrackClusterRatio) fHistoTrackClusterRatio->Write();
1002 if (fHistoCompFactor) delete fHistoCompFactor;
1003 fHistoCompFactor=NULL;
1004 if (fHistoResidualPad) delete fHistoResidualPad;
1005 fHistoResidualPad=NULL;
1006 if (fHistoResidualTime) delete fHistoResidualTime;
1007 fHistoResidualTime=NULL;
1008 if (fHistoClustersOnTracks) delete fHistoClustersOnTracks;
1009 fHistoClustersOnTracks=NULL;
1010 if (fHistoClusterRatio) delete fHistoClusterRatio;
1011 fHistoClusterRatio=NULL;
1012 if (fHistoTrackClusterRatio) delete fHistoTrackClusterRatio;
1013 fHistoTrackClusterRatio=NULL;
1015 if (fpDataDeflater) {
1016 if (!fHistogramFile.IsNull()) {
1017 TString filename=fHistogramFile;
1018 filename.ReplaceAll(".root", "-deflater.root");
1019 fpDataDeflater->SaveAs(filename);
1021 if (fDeflaterMode==kDeflaterModeHuffmanTrainer) {
1022 if (fTrainingTableOutput.IsNull()) {
1023 fTrainingTableOutput=GetComponentID();
1024 fTrainingTableOutput+="-huffman.root";
1026 // TODO: currently, the code tables are also calculated in FindObject
1027 // check if a different function is more appropriate
1028 TObject* pConf=fpDataDeflater->FindObject("DeflaterConfiguration");
1030 TString cdbEntryPath("HLT/ConfigTPC/");
1031 cdbEntryPath += GetComponentID();
1032 cdbEntryPath += "HuffmanTables";
1033 AliCDBPath cdbPath(cdbEntryPath);
1034 AliCDBId cdbId(cdbPath, AliCDBManager::Instance()->GetRun(), AliCDBRunRange::Infinity(), 0, 0);
1035 AliCDBMetaData* cdbMetaData=new AliCDBMetaData;
1036 cdbMetaData->SetResponsible("ALICE HLT Matthias.Richter@cern.ch");
1037 cdbMetaData->SetComment("Huffman encoder configuration");
1038 AliCDBEntry* entry=new AliCDBEntry(pConf, cdbId, cdbMetaData, kTRUE);
1040 entry->SaveAs(fTrainingTableOutput);
1041 // this is a small memory leak
1042 // seg fault in ROOT object handling if the two objects are deleted
1043 // investigate later
1045 //delete cdbMetaData;
1048 delete fpDataDeflater;
1050 fpDataDeflater=NULL;
1053 if (fTrackGrid) delete fTrackGrid; fTrackGrid=NULL;
1054 if (fSpacePointGrid) delete fSpacePointGrid; fSpacePointGrid=NULL;
1059 int AliHLTTPCDataCompressionComponent::ScanConfigurationArgument(int argc, const char** argv)
1061 /// inherited from AliHLTComponent: argument scan
1063 if (argc<1) return 0;
1064 int bMissingParam=0;
1066 TString argument=argv[i];
1070 if (argument.CompareTo("-mode")==0) {
1071 if ((bMissingParam=(++i>=argc))) break;
1072 TString parameter=argv[i];
1073 if (parameter.IsDigit()) {
1074 fMode=parameter.Atoi();
1077 HLTError("invalid parameter for argument %s, expecting number instead of %s", argument.Data(), parameter.Data());
1083 if (argument.CompareTo("-deflater-mode")==0) {
1084 if ((bMissingParam=(++i>=argc))) break;
1085 TString parameter=argv[i];
1086 if (parameter.IsDigit()) {
1087 fDeflaterMode=parameter.Atoi();
1090 HLTError("invalid parameter for argument %s, expecting number instead of %s", argument.Data(), parameter.Data());
1096 if (argument.CompareTo("-histogram-file")==0) {
1097 if ((bMissingParam=(++i>=argc))) break;
1098 fHistogramFile=argv[i++];
1101 // -save-histogram-table
1102 if (argument.CompareTo("-save-huffman-table")==0) {
1103 if ((bMissingParam=(++i>=argc))) break;
1104 fTrainingTableOutput=argv[i++];
1107 // -cluster-verification
1108 if (argument.CompareTo("-cluster-verification")==0) {
1109 if ((bMissingParam=(++i>=argc))) break;
1110 TString parameter=argv[i];
1111 if (parameter.IsDigit()) {
1112 fVerificationMode=parameter.Atoi();
1115 HLTError("invalid parameter for argument %s, expecting number instead of %s", argument.Data(), parameter.Data());
1119 } while (0); // using do-while only to have break available
1121 if (bMissingParam) {
1122 HLTError("missing parameter for argument %s", argument.Data());
1129 int AliHLTTPCDataCompressionComponent::InitDriftTimeTransformation()
1131 /// calculate correction factor and offset for a linear approximation of the
1132 /// drift time transformation, separately for A and C side
1134 AliHLTTPCClusterTransformation transform;
1135 if ((iResult=transform.Init( GetBz(), GetTimeStamp()))<0) {
1136 HLTError("failed to init AliHLTTPCClusterTransformation: %d", iResult);
1140 if ((iResult=CalculateDriftTimeTransformation(transform, 0, 0, fDriftTimeFactorA, fDriftTimeOffsetA))<0) return iResult;
1141 if (fVerbosity>0) HLTInfo("drift time transformation A side: m=%f n=%f", fDriftTimeFactorA, fDriftTimeOffsetA);
1142 if ((iResult=CalculateDriftTimeTransformation(transform, 18, 0, fDriftTimeFactorC, fDriftTimeOffsetC))<0) return iResult;
1143 if (fVerbosity>0) HLTInfo("drift time transformation C side: m=%f n=%f", fDriftTimeFactorC, fDriftTimeOffsetC);
1148 int AliHLTTPCDataCompressionComponent::CalculateDriftTimeTransformation(AliHLTTPCClusterTransformation& transform,
1149 int slice, int padrow,
1150 float& m, float& n) const
1152 /// calculate correction factor and offset for a linear approximation of the
1153 /// drift time transformation by just probing the range of timebins with
1154 /// AliHLTTPCClusterTransformation
1155 const int nofSteps=100;
1156 vector<float> zvalues;
1158 int nofTimebins=AliHLTTPCTransform::GetNTimeBins();
1159 int stepWidth=nofTimebins/nofSteps;
1164 for (time=0; time<nofTimebins; time+=stepWidth, count++) {
1166 transform.Transform(slice, padrow, 0, time, xyz);
1167 zvalues.push_back(xyz[2]);
1171 if (count==0) count=1;
1177 for (vector<float>::const_iterator z=zvalues.begin();
1178 z!=zvalues.end(); z++, time+=stepWidth) {
1179 sumTZ+=(time-meanT)*((*z)-meanZ);
1180 sumT2+=(time-meanT)*(time-meanT);