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