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