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