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