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