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