]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/TPCLib/tracking-ca/AliHLTTPCCATrackerComponent.cxx
cosmetic changes
[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 "AliHLTTPCCAOutTrack.h"
35 #include "AliHLTTPCCAParam.h"
36 #include "AliHLTTPCCATrackConvertor.h"
37 #include "AliHLTArray.h"
38
39 #include "AliHLTTPCSpacePointData.h"
40 #include "AliHLTTPCClusterDataFormat.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     fOutputTRAKSEGS( 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     fOutputTRAKSEGS( 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   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 }
131
132 AliHLTComponentDataType AliHLTTPCCATrackerComponent::GetOutputDataType()
133 {
134   // see header file for class documentation
135   if ( fOutputTRAKSEGS ) return AliHLTTPCDefinitions::fgkTrackSegmentsDataType;
136   else 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.5; // 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   fOutputTRAKSEGS = 0;
164   fFullTime = 0;
165   fRecoTime = 0;
166   fNEvents = 0;
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       fSolenoidBz = ( ( TObjString* )pTokens->At( i ) )->GetString().Atof();
191       HLTInfo( "Magnetic Field set to: %f", fSolenoidBz );
192       continue;
193     }
194
195     if ( argument.CompareTo( "-minNClustersOnTrack" ) == 0 ) {
196       if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
197       fMinNTrackClusters = ( ( TObjString* )pTokens->At( i ) )->GetString().Atoi();
198       HLTInfo( "minNClustersOnTrack set to: %d", fMinNTrackClusters );
199       continue;
200     }
201
202     if ( argument.CompareTo( "-clusterZCut" ) == 0 ) {
203       if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
204       fClusterZCut = TMath::Abs( ( ( TObjString* )pTokens->At( i ) )->GetString().Atof() );
205       HLTInfo( "ClusterZCut set to: %f", fClusterZCut );
206       continue;
207     }
208  
209    if ( argument.CompareTo( "-neighboursSearchArea" ) == 0 ) {
210       if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
211       fNeighboursSearchArea = TMath::Abs( ( ( TObjString* )pTokens->At( i ) )->GetString().Atof() );
212       HLTInfo( "NeighboursSearchArea set to: %f", fNeighboursSearchArea );
213       continue;
214     }
215
216    if ( argument.CompareTo( "-errorCorrectionY" ) == 0 ) {
217      if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
218      fClusterErrorCorrectionY = ( ( TObjString* )pTokens->At( i ) )->GetString().Atof();
219      HLTInfo( "Cluster Y error correction factor set to: %f", fClusterErrorCorrectionY );
220      continue;
221    }
222    
223    if ( argument.CompareTo( "-errorCorrectionZ" ) == 0 ) {
224      if ( ( bMissingParam = ( ++i >= pTokens->GetEntries() ) ) ) break;
225      fClusterErrorCorrectionZ = ( ( TObjString* )pTokens->At( i ) )->GetString().Atof();
226      HLTInfo( "Cluster Z error correction factor set to: %f", fClusterErrorCorrectionZ );
227      continue;
228    }
229
230    if ( argument.CompareTo( "-outputTRAKSEGS" ) == 0 ) {
231       fOutputTRAKSEGS = 1;
232       HLTInfo( "The special output type \"TRAKSEGS\" is set" );
233       continue;
234     }
235
236     HLTError( "Unknown option \"%s\"", argument.Data() );
237     iResult = -EINVAL;
238   }
239   delete pTokens;
240
241   if ( bMissingParam ) {
242     HLTError( "Specifier missed for parameter \"%s\"", argument.Data() );
243     iResult = -EINVAL;
244   }
245
246   return iResult;
247 }
248
249
250 int AliHLTTPCCATrackerComponent::ReadCDBEntry( const char* cdbEntry, const char* chainId )
251 {
252   // see header file for class documentation
253
254   const char* defaultNotify = "";
255
256   if ( !cdbEntry ) {
257     cdbEntry = "HLT/ConfigTPC/TPCCATracker";
258     defaultNotify = " (default)";
259     chainId = 0;
260   }
261
262   HLTInfo( "configure from entry \"%s\"%s, chain id %s", cdbEntry, defaultNotify, ( chainId != NULL && chainId[0] != 0 ) ? chainId : "<none>" );
263   AliCDBEntry *pEntry = AliCDBManager::Instance()->Get( cdbEntry );//,GetRunNo());
264
265   if ( !pEntry ) {
266     HLTError( "cannot fetch object \"%s\" from CDB", cdbEntry );
267     return -EINVAL;
268   }
269
270   TObjString* pString = dynamic_cast<TObjString*>( pEntry->GetObject() );
271
272   if ( !pString ) {
273     HLTError( "configuration object \"%s\" has wrong type, required TObjString", cdbEntry );
274     return -EINVAL;
275   }
276
277   HLTInfo( "received configuration object string: \"%s\"", pString->GetString().Data() );
278
279   return  ReadConfigurationString( pString->GetString().Data() );
280 }
281
282
283 int AliHLTTPCCATrackerComponent::Configure( const char* cdbEntry, const char* chainId, const char *commandLine )
284 {
285   // Configure the component
286   // There are few levels of configuration,
287   // parameters which are set on one step can be overwritten on the next step
288
289   //* read hard-coded values
290
291   SetDefaultConfiguration();
292
293   //* read the default CDB entry
294
295   int iResult1 = ReadCDBEntry( NULL, chainId );
296
297   //* read magnetic field
298
299   int iResult2 = ReadCDBEntry( kAliHLTCDBSolenoidBz, chainId );
300
301   //* read the actual CDB entry if required
302
303   int iResult3 = ( cdbEntry ) ? ReadCDBEntry( cdbEntry, chainId ) : 0;
304
305   //* read extra parameters from input (if they are)
306
307   int iResult4 = 0;
308
309   if ( commandLine && commandLine[0] != '\0' ) {
310     HLTInfo( "received configuration string from HLT framework: \"%s\"", commandLine );
311     iResult4 = ReadConfigurationString( commandLine );
312   }
313
314   // Initialise the tracker here
315
316   return iResult1 ? iResult1 : ( iResult2 ? iResult2 : ( iResult3 ? iResult3 : iResult4 ) );
317 }
318
319
320
321 int AliHLTTPCCATrackerComponent::DoInit( int argc, const char** argv )
322 {
323   // Configure the CA tracker component
324
325   if ( fTracker ) return EINPROGRESS;
326
327
328   fTracker = new AliHLTTPCCATrackerFramework();
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   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   AliHLTTPCClusterData* inPtrSP;
400
401   // Determine the slice number
402
403   //Find min and max slice number with now slice missing in between (for default output)
404   int minslice = -1, maxslice = -1;
405   int slice = -1;
406   {
407     std::vector<int> slices;
408     std::vector<int>::iterator slIter;
409     std::vector<unsigned> sliceCnts;
410     std::vector<unsigned>::iterator slCntIter;
411
412     for ( ndx = 0; ndx < evtData.fBlockCnt; ndx++ ) {
413       iter = blocks + ndx;
414       if ( iter->fDataType != AliHLTTPCDefinitions::fgkClustersDataType ) continue;
415
416       slice = AliHLTTPCDefinitions::GetMinSliceNr( *iter );
417           if (slice < minslice || minslice == -1) minslice = slice;
418           if (slice > maxslice) maxslice = slice;
419
420       bool found = 0;
421       slCntIter = sliceCnts.begin();
422       for ( slIter = slices.begin(); slIter != slices.end(); slIter++, slCntIter++ ) {
423         if ( *slIter == slice ) {
424           found = kTRUE;
425           break;
426         }
427       }
428       if ( !found ) {
429         slices.push_back( slice );
430         sliceCnts.push_back( 1 );
431       } else *slCntIter++;
432     }
433
434           if ( slices.size() == 0 ) {
435                 HLTWarning( "no slices found in event" );
436                 return 0;
437           }
438
439
440     // Determine slice number to really use. (for obsolete output)
441     if ( slices.size() > 1 ) {
442                 Logging( fOutputTRAKSEGS ? kHLTLogError : kHLTLogDebug, "HLT::TPCSliceTracker::DoEvent", "Multiple slices found in event",
443                "Multiple slice numbers found in event 0x%08lX (%lu). Determining maximum occuring slice number...",
444                evtData.fEventID, evtData.fEventID );
445       unsigned maxCntSlice = 0;
446       slCntIter = sliceCnts.begin();
447       for ( slIter = slices.begin(); slIter != slices.end(); slIter++, slCntIter++ ) {
448         Logging( fOutputTRAKSEGS ? kHLTLogError : kHLTLogDebug, "HLT::TPCSliceTracker::DoEvent", "Multiple slices found in event",
449                  "Slice %lu found %lu times.", *slIter, *slCntIter );
450         if ( fOutputTRAKSEGS && maxCntSlice < *slCntIter ) {
451           maxCntSlice = *slCntIter;
452           slice = *slIter;
453         }
454       }
455       if (fOutputTRAKSEGS)
456       {
457             Logging( kHLTLogError, "HLT::TPCSliceTracker::DoEvent", "Multiple slices found in event",
458                "Using slice %lu.", slice );
459         }
460     } else if ( slices.size() > 0 ) {
461       slice = *( slices.begin() );
462     }
463
464
465           if (fOutputTRAKSEGS)
466           {
467                   minslice = maxslice = slice;
468           }
469           else
470           {
471                   for (int islice = minslice;islice <= maxslice;islice++)
472                   {
473                           bool found = false;
474                           for(slIter = slices.begin(); slIter != slices.end();slIter++)
475                           {
476                                   if (*slIter == islice)
477                                   {
478                                           found = true;
479                                           break;
480                                   }
481                           }
482                           if (!found)
483                           {
484                                   maxslice = islice - 1;
485                                   break;
486                           }
487                   }
488          }
489   }
490
491   if ( !fTracker ) fTracker = new AliHLTTPCCATrackerFramework;
492   int slicecount = maxslice + 1 - minslice;
493   if (slicecount > fTracker->MaxSliceCount())
494   {
495         maxslice = minslice + (slicecount = fTracker->MaxSliceCount());
496   }
497   int nClustersTotalSum = 0;
498   AliHLTTPCCAClusterData* clusterData = new AliHLTTPCCAClusterData[slicecount];
499
500
501   // min and max patch numbers and row numbers
502   int* slicerow = new int[slicecount * 2];
503   int* sliceminPatch = new int[slicecount];
504   int* slicemaxPatch = new int[slicecount];
505   memset(slicerow, 0, slicecount * 2 * sizeof(int));
506   for (int i = 0;i < slicecount;i++)
507   {
508           sliceminPatch[i] = 100;
509           slicemaxPatch[i] = -1;
510   }
511
512   //Prepare everything for all slices
513
514   for (int islice = 0;islice < slicecount;islice++)
515   {
516           slice = minslice + islice;
517
518           // Initialize the tracker slice
519           {
520                 int iSec = slice;
521                 float inRmin = 83.65;
522                 //    float inRmax = 133.3;
523                 //    float outRmin = 133.5;
524                 float outRmax = 247.7;
525                 float plusZmin = 0.0529937;
526                 float plusZmax = 249.778;
527                 float minusZmin = -249.645;
528                 float minusZmax = -0.0799937;
529                 float dalpha = 0.349066;
530                 float alpha = 0.174533 + dalpha * iSec;
531
532                 bool zPlus = ( iSec < 18 );
533                 float zMin =  zPlus ? plusZmin : minusZmin;
534                 float zMax =  zPlus ? plusZmax : minusZmax;
535                 //TPCZmin = -249.645, ZMax = 249.778
536                 //    float rMin =  inRmin;
537                 //    float rMax =  outRmax;
538                 int nRows = AliHLTTPCTransform::GetNRows();
539
540                 float padPitch = 0.4;
541                 float sigmaZ = 0.228808;
542
543                 float *rowX = new float [nRows];
544                 for ( int irow = 0; irow < nRows; irow++ ) {
545                   rowX[irow] = AliHLTTPCTransform::Row2X( irow );
546                 }
547
548                 AliHLTTPCCAParam param;
549
550                 param.Initialize( iSec, nRows, rowX, alpha, dalpha,
551                                                   inRmin, outRmax, zMin, zMax, padPitch, sigmaZ, fSolenoidBz );
552                 param.SetHitPickUpFactor( 2 );
553                 if( fNeighboursSearchArea>0 ) param.SetNeighboursSearchArea( fNeighboursSearchArea );
554                 if( fClusterErrorCorrectionY>1.e-4 ) param.SetClusterError2CorrectionY( fClusterErrorCorrectionY*fClusterErrorCorrectionY );
555                 if( fClusterErrorCorrectionZ>1.e-4 ) param.SetClusterError2CorrectionZ( fClusterErrorCorrectionZ*fClusterErrorCorrectionZ );
556                 param.Update();
557                 fTracker->InitializeSliceParam( slice, param );
558                 delete[] rowX;
559           }
560
561           // total n Hits
562           int nClustersTotal = 0;
563
564           // sort patches
565           std::vector<unsigned long> patchIndices;
566
567           for ( ndx = 0; ndx < evtData.fBlockCnt; ndx++ ) {
568                 iter = blocks + ndx;
569                 if ( iter->fDataType != AliHLTTPCDefinitions::fgkClustersDataType ) continue;
570                 if ( slice != AliHLTTPCDefinitions::GetMinSliceNr( *iter ) ) continue;
571                 inPtrSP = ( AliHLTTPCClusterData* )( iter->fPtr );
572                 nClustersTotal += inPtrSP->fSpacePointCnt;
573                 int patch = AliHLTTPCDefinitions::GetMinPatchNr( *iter );
574                 if ( sliceminPatch[islice] > patch ) {
575                   sliceminPatch[islice] = patch;
576                   slicerow[2 * islice + 0] = AliHLTTPCTransform::GetFirstRow( patch );
577                 }
578                 if ( slicemaxPatch[islice] < patch ) {
579                   slicemaxPatch[islice] = patch;
580                   slicerow[2 * islice + 1] = AliHLTTPCTransform::GetLastRow( patch );
581                 }
582                 std::vector<unsigned long>::iterator pIter = patchIndices.begin();
583                 while ( pIter != patchIndices.end() && AliHLTTPCDefinitions::GetMinPatchNr( blocks[*pIter] ) < patch ) {
584                   pIter++;
585                 }
586                 patchIndices.insert( pIter, ndx );
587           }
588
589
590           // pass event to CA Tracker
591
592
593           Logging( kHLTLogDebug, "HLT::TPCCATracker::DoEvent", "Reading hits",
594                            "Total %d hits to read for slice %d", nClustersTotal, slice );
595
596
597           clusterData[islice].StartReading( slice, nClustersTotal );
598
599           for ( std::vector<unsigned long>::iterator pIter = patchIndices.begin(); pIter != patchIndices.end(); pIter++ ) {
600                 ndx = *pIter;
601                 iter = blocks + ndx;
602
603                 int patch = AliHLTTPCDefinitions::GetMinPatchNr( *iter );
604                 inPtrSP = ( AliHLTTPCClusterData* )( iter->fPtr );
605
606                 Logging( kHLTLogDebug, "HLT::TPCCATracker::DoEvent", "Reading hits",
607                                  "Reading %d hits for slice %d - patch %d", inPtrSP->fSpacePointCnt, slice, patch );
608
609                 for ( unsigned int i = 0; i < inPtrSP->fSpacePointCnt; i++ ) {
610                   AliHLTTPCSpacePointData *c = &( inPtrSP->fSpacePoints[i] );
611                   if ( CAMath::Abs( c->fZ ) > fClusterZCut ) continue;
612                   if ( c->fPadRow > 159 ) {
613                         HLTError( "Wrong TPC cluster with row number %d received", c->fPadRow );
614                         continue;
615                   }
616                   clusterData[islice].ReadCluster( c->fID, c->fPadRow, c->fX, c->fY, c->fZ, c->fCharge );
617                 }
618           }
619
620           clusterData[islice].FinishReading();
621           nClustersTotalSum += nClustersTotal;
622   }
623
624   //Prepare Output
625   AliHLTTPCCASliceOutput::outputControlStruct outputControl;
626   //Set tracker output so tracker does not have to output both formats!
627   outputControl.fObsoleteOutput = fOutputTRAKSEGS;
628   outputControl.fDefaultOutput = !fOutputTRAKSEGS;
629
630   //For new output we can write directly to output buffer
631   outputControl.fOutputPtr = fOutputTRAKSEGS ? NULL : (char*) outputPtr;
632   outputControl.fOutputMaxSize = maxBufferSize;
633
634   AliHLTTPCCASliceOutput** sliceOutput = new AliHLTTPCCASliceOutput*[slicecount];
635   memset(sliceOutput, 0, slicecount * sizeof(AliHLTTPCCASliceOutput*));
636
637   // reconstruct the event
638   TStopwatch timerReco;
639   fTracker->SetOutputControl(&outputControl);
640   fTracker->ProcessSlices(minslice, slicecount, clusterData, sliceOutput);
641   timerReco.Stop();
642   
643   int ret = 0;
644   unsigned int mySize = 0;
645   int ntracks = 0;
646   int error = 0;
647
648   for (int islice = 0;islice < slicecount;islice++)
649   {
650           slice = minslice + islice;
651
652           if (sliceOutput[islice])
653           {
654                   Logging( kHLTLogDebug, "HLT::TPCCATracker::DoEvent", "Reconstruct",
655                                    "%d tracks found for slice %d", sliceOutput[islice]->NOutTracks(), slice );
656
657
658                   // write reconstructed tracks
659
660                   if ( fOutputTRAKSEGS ) {
661
662                         ntracks = sliceOutput[islice]->NOutTracks();
663
664                         AliHLTTPCTrackletData* outPtr = ( AliHLTTPCTrackletData* )( outputPtr );
665
666                         AliHLTTPCTrackSegmentData* currOutTracklet = outPtr->fTracklets;
667
668                         mySize =   ( ( AliHLTUInt8_t * )currOutTracklet ) -  ( ( AliHLTUInt8_t * )outputPtr );
669
670                         outPtr->fTrackletCnt = 0;
671
672                         for ( int itr = 0; itr < ntracks; itr++ ) {
673
674                           AliHLTTPCCAOutTrack &t = sliceOutput[islice]->OutTracks()[itr];
675
676                           //Logging( kHLTLogDebug, "HLT::TPCCATracker::DoEvent", "Wrtite output","track %d with %d hits", itr, t.NHits());
677
678                           if ( t.NHits() < fMinNTrackClusters ) continue;
679
680                           // calculate output track size
681
682                           unsigned int dSize = sizeof( AliHLTTPCTrackSegmentData ) + t.NHits() * sizeof( unsigned int );
683
684                           if ( mySize + dSize > maxBufferSize ) {
685                                 HLTWarning( "Output buffer size exceed (buffer size %d, current size %d), %d tracks are not stored", maxBufferSize, mySize, ntracks - itr + 1 );
686                                 ret = -ENOSPC;
687                                 error = 1;
688                                 break;
689                           }
690
691                           // convert CA track parameters to HLT Track Segment
692
693                           int iFirstRow = 1000;
694                           int iLastRow = -1;
695                           int iFirstHit = sliceOutput[islice]->OutTrackHit(t.FirstHitRef());
696                           int iLastHit = iFirstHit;
697                           for ( int ih = 0; ih < t.NHits(); ih++ ) {
698                                 int hitID = sliceOutput[islice]->OutTrackHit(t.FirstHitRef() + ih);
699                                 int iRow = clusterData[islice].RowNumber( hitID );
700                                 if ( iRow < iFirstRow ) {  iFirstRow = iRow; iFirstHit = hitID; }
701                                 if ( iRow > iLastRow ) { iLastRow = iRow; iLastHit = hitID; }
702                           }
703
704                           AliHLTTPCCATrackParam par = t.StartPoint();
705
706                           par.TransportToX( clusterData[islice].X( iFirstHit ), .99 );
707
708                           AliExternalTrackParam tp;
709                           AliHLTTPCCATrackConvertor::GetExtParam( par, tp, 0 );
710
711                           currOutTracklet->fX = tp.GetX();
712                           currOutTracklet->fY = tp.GetY();
713                           currOutTracklet->fZ = tp.GetZ();
714                           currOutTracklet->fCharge = ( int ) tp.GetSign();
715                           currOutTracklet->fPt = TMath::Abs( tp.GetSignedPt() );
716                           float snp =  tp.GetSnp() ;
717                           if ( snp > .999 ) snp = .999;
718                           if ( snp < -.999 ) snp = -.999;
719                           currOutTracklet->fPsi = TMath::ASin( snp );
720                           currOutTracklet->fTgl = tp.GetTgl();
721
722                           currOutTracklet->fY0err = tp.GetSigmaY2();
723                           currOutTracklet->fZ0err = tp.GetSigmaZ2();
724                           float h = -currOutTracklet->fPt * currOutTracklet->fPt;
725                           currOutTracklet->fPterr = h * h * tp.GetSigma1Pt2();
726                           h = 1. / TMath::Sqrt( 1 - snp * snp );
727                           currOutTracklet->fPsierr = h * h * tp.GetSigmaSnp2();
728                           currOutTracklet->fTglerr = tp.GetSigmaTgl2();
729
730                           if ( par.TransportToX( clusterData[islice].X( iLastHit ), .99 ) ) {
731                                 currOutTracklet->fLastX = par.GetX();
732                                 currOutTracklet->fLastY = par.GetY();
733                                 currOutTracklet->fLastZ = par.GetZ();
734                           } else {
735                                 currOutTracklet->fLastX = clusterData[islice].X( iLastHit );
736                                 currOutTracklet->fLastY = clusterData[islice].Y( iLastHit );
737                                 currOutTracklet->fLastZ = clusterData[islice].Z( iLastHit );
738                           }
739                           //if( currOutTracklet->fLastX<10. ) {
740                           //HLTError("CA last point: hitxyz=%f,%f,%f, track=%f,%f,%f, tracklet=%f,%f,%f, nhits=%d",clusterData[islice].X( iLastHit ),clusterData[islice].Y( iLastHit],clusterData[islice].Z( iLastHit],
741                           //par.GetX(), par.GetY(),par.GetZ(),currOutTracklet->fLastX,currOutTracklet->fLastY ,currOutTracklet->fLastZ, t.NHits());
742                           //}
743                 #ifdef INCLUDE_TPC_HOUGH
744                 #ifdef ROWHOUGHPARAMS
745                           currOutTracklet->fTrackID = 0;
746                           currOutTracklet->fRowRange1 = clusterData[islice].RowNumber( iFirstHit );
747                           currOutTracklet->fRowRange2 = clusterData[islice].RowNumber( iLastHit );
748                           currOutTracklet->fSector = slice;
749                           currOutTracklet->fPID = 211;
750                 #endif
751                 #endif // INCLUDE_TPC_HOUGH
752
753
754                           currOutTracklet->fNPoints = t.NHits();
755
756                           for ( int i = 0; i < t.NHits(); i++ ) {
757                                 currOutTracklet->fPointIDs[i] = clusterData[islice].Id( sliceOutput[islice]->OutTrackHit(t.FirstHitRef()+i) );
758                           }
759
760                           currOutTracklet = ( AliHLTTPCTrackSegmentData* )( ( Byte_t * )currOutTracklet + dSize );
761                           mySize += dSize;
762                           outPtr->fTrackletCnt++;
763                         }
764
765                   } else { // default output type
766                           mySize += sliceOutput[islice]->OutputMemorySize();
767                           ntracks += sliceOutput[islice]->NTracks();
768                   }
769           }
770           else
771           {
772                   HLTWarning( "Output buffer size exceed (buffer size %d, current size %d), tracks are not stored", maxBufferSize, mySize );
773                   mySize = 0;
774                   ret = -ENOSPC;
775                   ntracks = 0;
776                   error = 1;
777                   break;
778           }
779   }
780
781   size = 0;
782   if (error == 0)
783   {
784           for (int islice = 0;islice < slicecount;islice++)
785           {
786                   slice = minslice + islice;
787                   if (!fOutputTRAKSEGS) mySize = sliceOutput[islice]->OutputMemorySize();
788                   if (mySize > 0)
789                   {
790                         AliHLTComponentBlockData bd;
791                         FillBlockData( bd );
792                         bd.fOffset = fOutputTRAKSEGS ? 0 : ((char*) sliceOutput[islice] - (char*) outputPtr);
793                         bd.fSize = mySize;
794                         bd.fSpecification = AliHLTTPCDefinitions::EncodeDataSpecification( slice, slice, sliceminPatch[islice], slicemaxPatch[islice] );
795                         bd.fDataType = GetOutputDataType();
796                         outputBlocks.push_back( bd );
797                         size += mySize;
798                   }
799           }
800   }
801
802   //No longer needed
803   delete[] clusterData;
804   //These are only temporary pointers to the output and no longer needed
805   delete[] sliceOutput;
806
807   timer.Stop();
808
809   fFullTime += timer.RealTime();
810   fRecoTime += timerReco.RealTime();
811   fNEvents++;
812
813   // Set log level to "Warning" for on-line system monitoring
814   int hz = ( int ) ( fFullTime > 1.e-10 ? fNEvents / fFullTime : 100000 );
815   int hz1 = ( int ) ( fRecoTime > 1.e-10 ? fNEvents / fRecoTime : 100000 );
816   //Min and Max Patch are taken for first slice processed...
817   HLTInfo( "CATracker slices %d-%d: output %d tracks;  input %d clusters, patches %d..%d, rows %d..%d; time: full %d / reco %d Hz",
818            minslice, maxslice, ntracks, nClustersTotalSum, sliceminPatch[0], slicemaxPatch[0], slicerow[0], slicerow[1], hz, hz1 );
819
820   return ret;
821 }
822
823