add option to select gpu library in hlt tpc tracker component
[u/mrichter/AliRoot.git] / HLT / TPCLib / tracking-ca / AliHLTTPCCATrackerComponent.cxx
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: Sergey Gorbunov <sergey.gorbunov@kip.uni-heidelberg.de> *
7 //                  Ivan Kisel <kisel@kip.uni-heidelberg.de>                *
8 //                  for The ALICE HLT Project.                              *
9 //                                                                          *
10 // Permission to use, copy, modify and distribute this software and its     *
11 // documentation strictly for non-commercial purposes is hereby granted     *
12 // without fee, provided that the above copyright notice appears in all     *
13 // copies and that both the copyright notice and this permission notice     *
14 // appear in the supporting documentation. The authors make no claims       *
15 // about the suitability of this software for any purpose. It is            *
16 // provided "as is" without express or implied warranty.                    *
17 //                                                                          *
18 //***************************************************************************
19
20
21 ///////////////////////////////////////////////////////////////////////////////
22 //                                                                           //
23 // a TPC tracker processing component for the HLT based on CA by Ivan Kisel  //
24 //                                                                           //
25 ///////////////////////////////////////////////////////////////////////////////
26
27 #if __GNUC__>= 3
28 using namespace std;
29 #endif
30
31 #include "AliHLTTPCCATrackerComponent.h"
32 #include "AliHLTTPCTransform.h"
33 #include "AliHLTTPCCATrackerFramework.h"
34 #include "AliHLTTPCCAParam.h"
35 #include "AliHLTTPCCATrackConvertor.h"
36 #include "AliHLTArray.h"
37
38 #include "AliHLTTPCSpacePointData.h"
39 #include "AliHLTTPCClusterDataFormat.h"
40 #include "AliHLTTPCCACompressedInputData.h"
41 #include "AliHLTTPCTransform.h"
42 #include "AliHLTTPCDefinitions.h"
43 #include "AliExternalTrackParam.h"
44 #include "TMath.h"
45 #include "AliCDBEntry.h"
46 #include "AliCDBManager.h"
47 #include "TObjString.h"
48 #include "TObjArray.h"
49 #include "AliHLTTPCCASliceOutput.h"
50 #include "AliHLTTPCCAClusterData.h"
51
52 const AliHLTComponentDataType AliHLTTPCCADefinitions::fgkTrackletsDataType = AliHLTComponentDataTypeInitializer( "CATRACKL", kAliHLTDataOriginTPC );
53
54 /** ROOT macro for the implementation of ROOT specific class methods */
55 ClassImp( AliHLTTPCCATrackerComponent )
56
57   AliHLTTPCCATrackerComponent::AliHLTTPCCATrackerComponent()
58   :
59   fTracker( NULL ),
60   fClusterData( NULL ),
61   fMinSlice( 0 ),
62   fSliceCount( fgkNSlices ),
63   fSolenoidBz( 0 ),
64   fMinNTrackClusters( 30 ),
65   fMinTrackPt(0.2),
66   fClusterZCut( 500. ),
67   fNeighboursSearchArea( 0 ), 
68   fClusterErrorCorrectionY(0), 
69   fClusterErrorCorrectionZ(0),
70   fBenchmark("CATracker"), 
71   fAllowGPU( 0),
72   fGPUHelperThreads(-1),
73   fCPUTrackers(0),
74   fGlobalTracking(0),
75   fGPULibrary("")
76 {
77   // see header file for class documentation
78   // or
79   // refer to README to build package
80   // or
81   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
82   for( int i=0; i<fgkNSlices; i++ ){
83     fSliceOutput[i] = NULL;
84   }
85 }
86
87 AliHLTTPCCATrackerComponent::AliHLTTPCCATrackerComponent( const AliHLTTPCCATrackerComponent& )
88   :
89 AliHLTProcessor(),
90   fTracker( NULL ),
91   fClusterData( NULL ),
92   fMinSlice( 0 ),
93   fSliceCount( fgkNSlices ),
94   fSolenoidBz( 0 ),
95   fMinNTrackClusters( 30 ),
96   fMinTrackPt( 0.2 ),
97   fClusterZCut( 500. ),
98   fNeighboursSearchArea(0),
99   fClusterErrorCorrectionY(0), 
100   fClusterErrorCorrectionZ(0),
101   fBenchmark("CATracker"),
102   fAllowGPU( 0),
103   fGPUHelperThreads(-1),
104   fCPUTrackers(0),
105   fGlobalTracking(0),
106   fGPULibrary("")
107 {
108   // see header file for class documentation
109   for( int i=0; i<fgkNSlices; i++ ){
110     fSliceOutput[i] = NULL;
111   }
112   HLTFatal( "copy constructor untested" );
113 }
114
115 AliHLTTPCCATrackerComponent& AliHLTTPCCATrackerComponent::operator=( const AliHLTTPCCATrackerComponent& )
116 {
117   // see header file for class documentation
118   for( int i=0; i<fgkNSlices; i++ ){
119     fSliceOutput[i] = NULL;
120   }
121   HLTFatal( "assignment operator untested" );
122   return *this;
123 }
124
125 AliHLTTPCCATrackerComponent::~AliHLTTPCCATrackerComponent()
126 {
127   // see header file for class documentation
128   if (fTracker) delete fTracker;
129   if (fClusterData) delete[] fClusterData;
130 }
131
132 //
133 // Public functions to implement AliHLTComponent's interface.
134 // These functions are required for the registration process
135 //
136
137 const char* AliHLTTPCCATrackerComponent::GetComponentID()
138 {
139   // see header file for class documentation
140   return "TPCCATracker";
141 }
142
143 void AliHLTTPCCATrackerComponent::GetInputDataTypes( vector<AliHLTComponentDataType>& list )
144 {
145   // see header file for class documentation
146   list.clear();
147   list.push_back( AliHLTTPCDefinitions::fgkClustersDataType );
148   list.push_back( AliHLTTPCCADefinitions::fgkCompressedInputDataType );
149 }
150
151 AliHLTComponentDataType AliHLTTPCCATrackerComponent::GetOutputDataType()
152 {
153   // see header file for class documentation
154   return AliHLTTPCCADefinitions::fgkTrackletsDataType;
155 }
156
157 void AliHLTTPCCATrackerComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
158 {
159   // define guess for the output data size
160   constBase = 200;       // minimum size
161   inputMultiplier = 0.6; // size relative to input
162 }
163
164 AliHLTComponent* AliHLTTPCCATrackerComponent::Spawn()
165 {
166   // see header file for class documentation
167   return new AliHLTTPCCATrackerComponent;
168 }
169
170 void AliHLTTPCCATrackerComponent::SetDefaultConfiguration()
171 {
172   // Set default configuration for the CA tracker component
173   // Some parameters can be later overwritten from the OCDB
174
175   fSolenoidBz = -5.00668;
176   fMinNTrackClusters = 30;
177   fMinTrackPt = 0.2;
178   fClusterZCut = 500.;
179   fNeighboursSearchArea = 0;
180   fClusterErrorCorrectionY = 0;
181   fClusterErrorCorrectionZ = 0;
182   fBenchmark.Reset();
183   fBenchmark.SetTimer(0,"total");
184   fBenchmark.SetTimer(1,"reco");
185 }
186
187 int AliHLTTPCCATrackerComponent::ReadConfigurationString(  const char* arguments )
188 {
189   // Set configuration parameters for the CA tracker component from the string
190
191   int iResult = 0;
192   if ( !arguments ) return iResult;
193
194   TString allArgs = arguments;
195   TString argument;
196   int bMissingParam = 0;
197
198   TObjArray* pTokens = allArgs.Tokenize( " " );
199
200   int nArgs =  pTokens ? pTokens->GetEntries() : 0;
201
202   for ( int i = 0; i < nArgs; i++ ) {
203     argument = ( ( TObjString* )pTokens->At( i ) )->GetString();
204     if ( argument.IsNull() ) continue;
205
206     if ( argument.CompareTo( "-solenoidBz" ) == 0 ) {
207       if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
208       HLTWarning("argument -solenoidBz is deprecated, magnetic field set up globally (%f)", GetBz());
209       continue;
210     }
211
212     if ( argument.CompareTo( "-minNClustersOnTrack" ) == 0 ) {
213       if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
214       fMinNTrackClusters = ( ( TObjString* )pTokens->At( i ) )->GetString().Atoi();
215       HLTInfo( "minNClustersOnTrack set to: %d", fMinNTrackClusters );
216       continue;
217     }
218
219     if ( argument.CompareTo( "-minTrackPt" ) == 0 ) {
220       if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
221       fMinTrackPt = ( ( TObjString* )pTokens->At( i ) )->GetString().Atof();
222       HLTInfo( "minTrackPt set to: %f", fMinTrackPt );
223       continue;
224     }
225
226     if ( argument.CompareTo( "-clusterZCut" ) == 0 ) {
227       if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
228       fClusterZCut = TMath::Abs( ( ( TObjString* )pTokens->At( i ) )->GetString().Atof() );
229       HLTInfo( "ClusterZCut set to: %f", fClusterZCut );
230       continue;
231     }
232
233     if ( argument.CompareTo( "-neighboursSearchArea" ) == 0 ) {
234       if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
235       fNeighboursSearchArea = TMath::Abs( ( ( TObjString* )pTokens->At( i ) )->GetString().Atof() );
236       HLTInfo( "NeighboursSearchArea set to: %f", fNeighboursSearchArea );
237       continue;
238     }
239
240     if ( argument.CompareTo( "-errorCorrectionY" ) == 0 ) {
241       if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
242       fClusterErrorCorrectionY = ( ( TObjString* )pTokens->At( i ) )->GetString().Atof();
243       HLTInfo( "Cluster Y error correction factor set to: %f", fClusterErrorCorrectionY );
244       continue;
245     }
246
247     if ( argument.CompareTo( "-errorCorrectionZ" ) == 0 ) {
248       if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
249       fClusterErrorCorrectionZ = ( ( TObjString* )pTokens->At( i ) )->GetString().Atof();
250       HLTInfo( "Cluster Z error correction factor set to: %f", fClusterErrorCorrectionZ );
251       continue;
252     }
253
254     if (argument.CompareTo( "-allowGPU" ) == 0) {
255       fAllowGPU = 1;
256       HLTImportant( "Will try to run tracker on GPU" );
257       continue;
258     }
259
260     if (argument.CompareTo( "-GlobalTracking" ) == 0) {
261       fGlobalTracking = 1;
262       HLTImportant( "Global Tracking Activated" );
263       continue;
264     }
265
266     if ( argument.CompareTo( "-GPUHelperThreads" ) == 0 ) {
267       if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
268       fGPUHelperThreads = ( ( TObjString* )pTokens->At( i ) )->GetString().Atoi();
269       HLTInfo( "Number of GPU Helper Threads set to: %d", fGPUHelperThreads );
270       continue;
271     }
272
273     if ( argument.CompareTo( "-CPUTrackers" ) == 0 ) {
274       if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
275       fCPUTrackers = ( ( TObjString* )pTokens->At( i ) )->GetString().Atoi();
276       HLTInfo( "Number of CPU Trackers set to: %d", fCPUTrackers );
277       continue;
278     }
279
280     if ( argument.CompareTo( "-GPULibrary" ) == 0 ) {
281       if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
282       fGPULibrary = ( ( TObjString* )pTokens->At( i ) )->GetString();
283       continue;
284     }
285         
286         HLTError( "Unknown option \"%s\"", argument.Data() );
287     iResult = -EINVAL;
288   }
289   delete pTokens;
290
291   if ( bMissingParam ) {
292     HLTError( "Specifier missed for parameter \"%s\"", argument.Data() );
293     iResult = -EINVAL;
294   }
295
296   return iResult;
297 }
298
299
300 int AliHLTTPCCATrackerComponent::ReadCDBEntry( const char* cdbEntry, const char* chainId )
301 {
302   // see header file for class documentation
303
304   const char* defaultNotify = "";
305
306   if ( !cdbEntry ) {
307     cdbEntry = "HLT/ConfigTPC/TPCCATracker";
308     defaultNotify = " (default)";
309     chainId = 0;
310   }
311
312   HLTInfo( "configure from entry \"%s\"%s, chain id %s", cdbEntry, defaultNotify, ( chainId != NULL && chainId[0] != 0 ) ? chainId : "<none>" );
313   AliCDBEntry *pEntry = AliCDBManager::Instance()->Get( cdbEntry );//,GetRunNo());
314
315   if ( !pEntry ) {
316     HLTError( "cannot fetch object \"%s\" from CDB", cdbEntry );
317     return -EINVAL;
318   }
319
320   TObjString* pString = dynamic_cast<TObjString*>( pEntry->GetObject() );
321
322   if ( !pString ) {
323     HLTError( "configuration object \"%s\" has wrong type, required TObjString", cdbEntry );
324     return -EINVAL;
325   }
326
327   HLTInfo( "received configuration object string: \"%s\"", pString->GetString().Data() );
328
329   return  ReadConfigurationString( pString->GetString().Data() );
330 }
331
332
333 int AliHLTTPCCATrackerComponent::Configure( const char* cdbEntry, const char* chainId, const char *commandLine )
334 {
335   // Configure the component
336   // There are few levels of configuration,
337   // parameters which are set on one step can be overwritten on the next step
338
339   //* read hard-coded values
340   SetDefaultConfiguration();
341
342   //* read the default CDB entry
343   int iResult1 = ReadCDBEntry( NULL, chainId );
344
345   //* read magnetic field
346   fSolenoidBz = GetBz();
347
348   //* read the actual CDB entry if required
349   int iResult2 = ( cdbEntry ) ? ReadCDBEntry( cdbEntry, chainId ) : 0;
350
351   //* read extra parameters from input (if they are)
352   int iResult3 = 0;
353
354   if ( commandLine && commandLine[0] != '\0' ) {
355     HLTInfo( "received configuration string from HLT framework: \"%s\"", commandLine );
356     iResult3 = ReadConfigurationString( commandLine );
357   }
358
359   if (fTracker) ConfigureSlices();
360
361   return iResult1 ? iResult1 : ( iResult2 ? iResult2 :  iResult3  );
362 }
363
364 void AliHLTTPCCATrackerComponent::ConfigureSlices()
365 {
366   // Initialize the tracker slices
367   for (int slice = 0;slice < fgkNSlices;slice++)
368   {
369     int iSec = slice;
370     float inRmin = 83.65;
371     //    float inRmax = 133.3;
372     //    float outRmin = 133.5;
373     float outRmax = 247.7;
374     float plusZmin = 0.0529937;
375     float plusZmax = 249.778;
376     float minusZmin = -249.645;
377     float minusZmax = -0.0799937;
378     float dalpha = 0.349066;
379     float alpha = 0.174533 + dalpha * iSec;
380
381     bool zPlus = ( iSec < 18 );
382     float zMin =  zPlus ? plusZmin : minusZmin;
383     float zMax =  zPlus ? plusZmax : minusZmax;
384     //TPCZmin = -249.645, ZMax = 249.778
385     //    float rMin =  inRmin;
386     //    float rMax =  outRmax;
387     int nRows = AliHLTTPCTransform::GetNRows();
388
389     float padPitch = 0.4;
390     float sigmaZ = 0.228808;
391
392     float *rowX = new float [nRows];
393     for ( int irow = 0; irow < nRows; irow++ ) {
394       rowX[irow] = AliHLTTPCTransform::Row2X( irow );
395     }
396
397     AliHLTTPCCAParam param;
398
399     param.Initialize( iSec, nRows, rowX, alpha, dalpha,
400       inRmin, outRmax, zMin, zMax, padPitch, sigmaZ, fSolenoidBz );
401     param.SetHitPickUpFactor( 2 );
402     if( fNeighboursSearchArea>0 ) param.SetNeighboursSearchArea( fNeighboursSearchArea );
403     if( fClusterErrorCorrectionY>1.e-4 ) param.SetClusterError2CorrectionY( fClusterErrorCorrectionY*fClusterErrorCorrectionY );
404     if( fClusterErrorCorrectionZ>1.e-4 ) param.SetClusterError2CorrectionZ( fClusterErrorCorrectionZ*fClusterErrorCorrectionZ );
405     param.SetMinNTrackClusters( fMinNTrackClusters );
406     param.SetMinTrackPt( fMinTrackPt );
407
408     param.Update();
409     fTracker->InitializeSliceParam( slice, param );
410     delete[] rowX;
411   }
412 }
413
414 int AliHLTTPCCATrackerComponent::DoInit( int argc, const char** argv )
415 {
416   if ( fTracker ) return EINPROGRESS;
417
418   // Configure the CA tracker component
419   TString arguments = "";
420   for ( int i = 0; i < argc; i++ ) {
421     if ( !arguments.IsNull() ) arguments += " ";
422     arguments += argv[i];
423   }
424
425   int retVal = Configure( NULL, NULL, arguments.Data() );
426   if (retVal == 0)
427   {
428     fMinSlice = 0;
429     fSliceCount = fgkNSlices;
430     //Create tracker instance and set parameters
431     fTracker = new AliHLTTPCCATrackerFramework(fAllowGPU, fGPULibrary);
432     fClusterData = new AliHLTTPCCAClusterData[fgkNSlices];
433     if (fGPUHelperThreads != -1)
434     {
435       char cc[256] = "HelperThreads";
436       fTracker->SetGPUTrackerOption(cc, fGPUHelperThreads);
437     }
438     {
439       char cc[256] = "CPUTrackers";
440       fTracker->SetGPUTrackerOption(cc, fCPUTrackers);
441       char cc2[256] = "SlicesPerCPUTracker";
442       fTracker->SetGPUTrackerOption(cc2, 1);
443     }
444     if (fGlobalTracking)
445     {
446       char cc[256] = "GlobalTracking";
447       fTracker->SetGPUTrackerOption(cc, 1);
448     }
449
450     ConfigureSlices();
451   }
452
453   return(retVal);
454 }
455
456 int AliHLTTPCCATrackerComponent::DoDeinit()
457 {
458   // see header file for class documentation
459   if (fTracker) delete fTracker;
460   fTracker = NULL;
461   if (fClusterData) delete[] fClusterData;
462   fClusterData = NULL;
463   return 0;
464 }
465
466 int AliHLTTPCCATrackerComponent::Reconfigure( const char* cdbEntry, const char* chainId )
467 {
468   // Reconfigure the component from OCDB .
469   return Configure( cdbEntry, chainId, NULL );
470 }
471
472 int AliHLTTPCCATrackerComponent::DoEvent
473   (
474   const AliHLTComponentEventData& evtData,
475   const AliHLTComponentBlockData* blocks,
476   AliHLTComponentTriggerData& /*trigData*/,
477   AliHLTUInt8_t* outputPtr,
478   AliHLTUInt32_t& size,
479   vector<AliHLTComponentBlockData>& outputBlocks )
480 {
481   //* process event
482   if (!fTracker)
483   {
484     HLTError( "CATracker not initialized properly" );
485     return -ENOENT;
486   }
487
488   AliHLTUInt32_t maxBufferSize = size;
489   size = 0; // output size
490
491   if ( GetFirstInputBlock( kAliHLTDataTypeSOR ) || GetFirstInputBlock( kAliHLTDataTypeEOR ) ) {
492     return 0;
493   }
494
495   fBenchmark.StartNewEvent();
496   fBenchmark.Start(0);
497
498   //Logging( kHLTLogWarning, "HLT::TPCCATracker::DoEvent", "DoEvent", "CA::DoEvent()" );
499   if ( evtData.fBlockCnt <= 0 ) {
500     HLTWarning( "no blocks in event" );
501     return 0;
502   }
503
504   const AliHLTComponentBlockData* iter = NULL;
505   unsigned long ndx;
506
507   // min and max patch numbers and row numbers
508   int sliceminPatch[fgkNSlices];
509   int slicemaxPatch[fgkNSlices];
510   for (int i = 0;i < fSliceCount;i++)
511   {
512     sliceminPatch[i] = 100;
513     slicemaxPatch[i] = -1;
514   }
515
516   //Prepare everything for all slices
517
518   for (int islice = 0;islice < fSliceCount;islice++)
519   {
520     int slice = fMinSlice + islice;
521
522     // total n Hits
523     int nClustersTotal = 0;
524
525     // sort patches
526     std::vector<unsigned long> patchIndices;
527
528     for ( ndx = 0; ndx < evtData.fBlockCnt; ndx++ ) {
529       iter = blocks + ndx;
530       if ( slice != AliHLTTPCDefinitions::GetMinSliceNr( *iter ) ) continue;
531       if ( iter->fDataType == AliHLTTPCDefinitions::fgkClustersDataType ){
532         AliHLTTPCClusterData* inPtrSP = ( AliHLTTPCClusterData* )( iter->fPtr );
533         nClustersTotal += inPtrSP->fSpacePointCnt;
534         fBenchmark.AddInput(iter->fSize);
535       } else 
536         if ( iter->fDataType == AliHLTTPCCADefinitions::fgkCompressedInputDataType){
537           fBenchmark.AddInput(iter->fSize);
538           const AliHLTUInt8_t * inPtr =  (const AliHLTUInt8_t *)iter->fPtr;
539           while( inPtr< ((const AliHLTUInt8_t *) iter->fPtr) + iter->fSize ){
540             AliHLTTPCCACompressedClusterRow *row = (AliHLTTPCCACompressedClusterRow*)inPtr;
541             nClustersTotal+= row->fNClusters;    
542             inPtr = (const AliHLTUInt8_t *)(row->fClusters+row->fNClusters);
543           }
544         }
545         else continue;
546
547         int patch = AliHLTTPCDefinitions::GetMinPatchNr( *iter );
548         if ( sliceminPatch[islice] > patch ) {
549           sliceminPatch[islice] = patch;
550         }
551         if ( slicemaxPatch[islice] < patch ) {
552           slicemaxPatch[islice] = patch;
553         }
554         std::vector<unsigned long>::iterator pIter = patchIndices.begin();
555         while ( pIter != patchIndices.end() && AliHLTTPCDefinitions::GetMinPatchNr( blocks[*pIter] ) < patch ) {
556           pIter++;
557         }
558         patchIndices.insert( pIter, ndx );
559     }
560
561
562     // pass event to CA Tracker
563
564
565     Logging( kHLTLogDebug, "HLT::TPCCATracker::DoEvent", "Reading hits",
566       "Total %d hits to read for slice %d", nClustersTotal, slice );
567
568     if (nClustersTotal > 500000)
569     {
570       HLTWarning( "Too many clusters in tracker input: Slice %d, Number of Clusters %d, slice not included in tracking", slice, nClustersTotal );
571       fClusterData[islice].StartReading( slice, 0 );
572     }
573     else
574     {
575       fClusterData[islice].StartReading( slice, nClustersTotal );
576
577       for ( std::vector<unsigned long>::iterator pIter = patchIndices.begin(); pIter != patchIndices.end(); pIter++ ) {
578         ndx = *pIter;
579         iter = blocks + ndx;
580         int patch = AliHLTTPCDefinitions::GetMinPatchNr( *iter );
581         int nPatchClust = 0;
582
583         if ( iter->fDataType == AliHLTTPCDefinitions::fgkClustersDataType ) {
584           AliHLTTPCCAClusterData::Data* pCluster = &fClusterData[islice].Clusters()[fClusterData[islice].NumberOfClusters()];
585           AliHLTTPCClusterData* inPtrSP = ( AliHLTTPCClusterData* )( iter->fPtr );
586           nPatchClust = inPtrSP->fSpacePointCnt;
587           const AliHLTTPCSpacePointData* pLastSpacePoint = &inPtrSP->fSpacePoints[inPtrSP->fSpacePointCnt];
588           for ( const AliHLTTPCSpacePointData* pSpacePoint = inPtrSP->fSpacePoints; pSpacePoint < pLastSpacePoint; pSpacePoint++ ) {
589             if ( pSpacePoint->fZ > fClusterZCut || pSpacePoint->fZ < -fClusterZCut) continue;
590             pCluster->fId = pSpacePoint->fID;
591             pCluster->fRow = pSpacePoint->fPadRow;
592             pCluster->fX = pSpacePoint->fX;
593             pCluster->fY = pSpacePoint->fY;
594             pCluster->fZ = pSpacePoint->fZ;
595             pCluster->fAmp = pSpacePoint->fCharge;
596             pCluster++;
597           }
598           fClusterData[islice].SetNumberOfClusters(pCluster - fClusterData[islice].Clusters());
599         }
600         else if ( iter->fDataType == AliHLTTPCCADefinitions::fgkCompressedInputDataType)
601         {
602           const AliHLTUInt8_t * inPtr = (const AliHLTUInt8_t *)iter->fPtr;
603           nPatchClust=0;
604           while( inPtr< ((const AliHLTUInt8_t *)iter->fPtr) + iter->fSize ){
605             AliHLTTPCCACompressedClusterRow *row = (AliHLTTPCCACompressedClusterRow*)inPtr;
606             UInt_t id = row->fSlicePatchRowID;
607             UInt_t jslice = id>>10;    
608             UInt_t jpatch = (id>>6) & 0x7;
609             UInt_t jrow   =  id     & 0x3F;     
610             jrow+= AliHLTTPCTransform::GetFirstRow( jpatch );
611             Double_t rowX = AliHLTTPCTransform::Row2X( jrow );
612             //cout<<"Read row: s "<<jslice<<" p "<<jpatch<<" r "<<jrow<<" x "<<row->fX<<" nclu "<<row->fNClusters<<" :"<<endl;
613             if( jrow > 159 ) {
614               HLTError( "Wrong TPC cluster with row number %d received", jrow );
615               continue;
616             }
617             for ( unsigned int i = 0; i < row->fNClusters; i++ ) {
618               AliHLTTPCCACompressedCluster *c = &( row->fClusters[i] );
619
620               UInt_t ix0 = c->fP0 >>24;
621               UInt_t ix1 = c->fP1 >>24;
622               Double_t x = (ix1<<8) + ix0;
623               Double_t y = c->fP0 & 0x00FFFFFF;
624               Double_t z = c->fP1 & 0x00FFFFFF;
625               x = (x - 32768.)*1.e-4 + rowX;
626               y = (y - 8388608.)*1.e-4;
627               z = (z - 8388608.)*1.e-4;
628
629               UInt_t cluId = AliHLTTPCSpacePointData::GetID( jslice, jpatch, nPatchClust );
630               //cout<<"clu "<<i<<": "<<x<<" "<<y<<" "<<z<<" "<<cluId<<endl;
631               if ( CAMath::Abs( z ) <= fClusterZCut){
632                 fClusterData[islice].ReadCluster( cluId, jrow, x, y, z, 0 );
633               }
634               nPatchClust++;      
635             }
636             inPtr = (const AliHLTUInt8_t *)(row->fClusters+row->fNClusters);
637           }
638         }
639         Logging( kHLTLogInfo, "HLT::TPCCATracker::DoEvent", "Reading hits",
640           "Read %d hits for slice %d - patch %d", nPatchClust, slice, patch );
641       }
642     }
643   }
644
645   //Prepare Output
646   AliHLTTPCCASliceOutput::outputControlStruct outputControl;
647   outputControl.fEndOfSpace = 0;
648   outputControl.fOutputPtr =  (char*) outputPtr;
649   outputControl.fOutputMaxSize = maxBufferSize;
650   fTracker->SetOutputControl(&outputControl);
651
652   memset(fSliceOutput, 0, fSliceCount * sizeof(AliHLTTPCCASliceOutput*));
653
654   // reconstruct the event
655   fBenchmark.Start(1);
656   fTracker->ProcessSlices(fMinSlice, fSliceCount, fClusterData, fSliceOutput);
657   fBenchmark.Stop(1);
658
659   int ret = 0;
660   unsigned int mySize = 0;
661   int ntracks = 0;
662   int error = 0;
663
664   for (int islice = 0;islice < fSliceCount;islice++)
665   {
666     if (slicemaxPatch[islice] == -1) continue;
667     int slice = fMinSlice + islice;
668
669     if( outputControl.fEndOfSpace ){
670       HLTWarning( "Output buffer size exceeded (buffer size %d, required size %d), tracks are not stored", maxBufferSize, mySize );
671       ret = -ENOSPC;
672       error = 1;
673       break;     
674     }
675
676     if (fSliceOutput[islice])
677     {
678       // write reconstructed tracks
679       Logging( kHLTLogDebug, "HLT::TPCCATracker::DoEvent", "Reconstruct", "%d tracks found for slice %d", fSliceOutput[islice]->NTracks(), slice );
680
681       mySize += fSliceOutput[islice]->Size();
682       ntracks += fSliceOutput[islice]->NTracks();    
683     }
684     else
685     {
686       HLTWarning( "Error during Tracking, no tracks stored" );
687       mySize = 0;
688       ret = -ENOSPC;
689       ntracks = 0;
690       error = 1;
691       break;
692     }
693   }
694
695   size = 0;
696   if (error == 0)
697   {
698     for (int islice = 0;islice < fSliceCount;islice++)
699     {
700       if (slicemaxPatch[islice] == -1) continue;
701       int slice = fMinSlice + islice;
702
703       mySize = fSliceOutput[islice]->Size();
704       if (mySize > 0)
705       {
706         AliHLTComponentBlockData bd;
707         FillBlockData( bd );
708         bd.fOffset = ((char*) fSliceOutput[islice] - (char*) outputPtr);
709         bd.fSize = mySize;
710         bd.fSpecification = AliHLTTPCDefinitions::EncodeDataSpecification( slice, slice, sliceminPatch[islice], slicemaxPatch[islice] );
711         bd.fDataType = GetOutputDataType();
712         outputBlocks.push_back( bd );
713         size += mySize;
714         fBenchmark.AddOutput(bd.fSize);
715       }
716     }
717   }
718
719   //No longer needed
720
721   fBenchmark.Stop(0);
722
723   // Set log level to "Warning" for on-line system monitoring
724
725   //Min and Max Patch are taken for first slice processed...
726
727   fBenchmark.SetName(Form("CATracker"));
728
729   HLTInfo(fBenchmark.GetStatistics());
730   //No longer needed
731
732   return ret;
733 }
734
735