]> git.uio.no Git - u/mrichter/AliRoot.git/blob - HLT/TPCLib/tracking-ca/AliHLTTPCCATrackerComponent.cxx
TPC CA Global Merger component added
[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 "AliHLTTPCCATracker.h"
34 #include "AliHLTTPCCAOutTrack.h"
35 #include "AliHLTTPCCAParam.h"
36 #include "AliHLTTPCCATrackConvertor.h"
37
38 #include "AliHLTTPCSpacePointData.h"
39 #include "AliHLTTPCClusterDataFormat.h"
40 #include "AliHLTTPCTransform.h"
41 #include "AliHLTTPCTrackSegmentData.h"
42 #include "AliHLTTPCTrackArray.h"
43 #include "AliHLTTPCTrackletDataFormat.h"
44 #include "AliHLTTPCDefinitions.h"
45 #include "AliExternalTrackParam.h"
46 #include "TStopwatch.h"
47 #include "TMath.h"
48 #include "AliCDBEntry.h"
49 #include "AliCDBManager.h"
50 #include "TObjString.h"
51 #include "TObjArray.h"
52 #include "AliHLTTPCCASliceOutput.h"
53
54 const AliHLTComponentDataType AliHLTTPCCADefinitions::fgkTrackletsDataType = AliHLTComponentDataTypeInitializer( "CATRACKL", kAliHLTDataOriginTPC );
55
56 /** ROOT macro for the implementation of ROOT specific class methods */
57 ClassImp(AliHLTTPCCATrackerComponent)
58
59 /** global object for registration 
60  * Matthias 2009-01-13 temporarily using the global object approach again.
61  * CA cade had to be disabled because of various compilation problems, so
62  * the global object approach fits better for the moment.
63  */
64   
65 AliHLTTPCCATrackerComponent gAliHLTTPCCATrackerComponent;
66
67 AliHLTTPCCATrackerComponent::AliHLTTPCCATrackerComponent()
68   :
69   fTracker(NULL),
70   fSolenoidBz(0),
71   fMinNTrackClusters(0),
72   fClusterZCut(500.),
73   fFullTime(0),
74   fRecoTime(0),
75   fNEvents(0),
76   fNewOutputType(0)
77 {
78   // see header file for class documentation
79   // or
80   // refer to README to build package
81   // or
82   // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
83 }
84
85 AliHLTTPCCATrackerComponent::AliHLTTPCCATrackerComponent(const AliHLTTPCCATrackerComponent&)
86   :
87   AliHLTProcessor(),
88   fTracker(NULL),
89   fSolenoidBz(0),
90   fMinNTrackClusters(30),
91   fClusterZCut(500.),
92   fFullTime(0),
93   fRecoTime(0),
94   fNEvents(0),
95   fNewOutputType(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( fNewOutputType ) return AliHLTTPCCADefinitions::fgkTrackletsDataType;
136   else return AliHLTTPCDefinitions::fgkTrackSegmentsDataType;
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 Int_t AliHLTTPCCATrackerComponent::DoInit( Int_t argc, const char** argv )
153 {
154   // Configure the CA tracker component 
155
156   fSolenoidBz = 5;
157   fMinNTrackClusters = 0;
158   fClusterZCut = 500.;
159   fFullTime = 0;
160   fRecoTime = 0;
161   fNEvents = 0;
162   fNewOutputType = 0;
163
164   if ( fTracker ) return EINPROGRESS;
165   fTracker = new AliHLTTPCCATracker();
166
167   Int_t iResult = EINVAL;
168
169   TString arguments=""; 
170   for (int i=0; i<argc; i++) {
171     TString argument=argv[i];
172     if (!arguments.IsNull()) arguments+=" ";
173     arguments+=argument;
174   }
175   if (!arguments.IsNull()) {
176     iResult=Configure(arguments.Data());
177   } else {
178     iResult=Reconfigure(NULL, NULL);
179   }  
180   return iResult;
181 }
182
183
184 Int_t AliHLTTPCCATrackerComponent::DoDeinit()
185 {
186   // see header file for class documentation
187   if ( fTracker ) delete fTracker;
188   fTracker = NULL;  
189   return 0;
190 }
191
192 Int_t AliHLTTPCCATrackerComponent::Reconfigure(const char* /*cdbEntry*/, const char* /*chainId*/)
193 {
194   // see header file for class documentation
195  
196   HLTWarning("dummy Reconfigure() method called" );
197
198   return EINVAL;
199
200   /*
201   
202   Int_t iResult=EINVAL;
203   const char* path="HLT/ConfigTPC/CATrackerComponent";
204   const char* defaultNotify="";
205   if (cdbEntry) {
206     path=cdbEntry;
207     defaultNotify=" (default)";
208   }
209   if (path) {
210     HLTInfo("reconfigure from entry %s%s, chain id %s", path, defaultNotify,(chainId!=NULL && chainId[0]!=0)?chainId:"<none>");
211     AliCDBEntry *pEntry = AliCDBManager::Instance()->Get(path);//,GetRunNo());
212     if (pEntry) {
213       TObjString* pString=dynamic_cast<TObjString*>(pEntry->GetObject());
214       if (pString) {
215         HLTInfo("received configuration object string: \'%s\'", pString->GetString().Data());
216         iResult=Configure(pString->GetString().Data());
217       } else {
218         HLTError("configuration object \"%s\" has wrong type, required TObjString", path);
219       }
220     } else {
221       HLTError("cannot fetch object \"%s\" from CDB", path);
222     }
223   }
224   
225   const char* pathBField=kAliHLTCDBSolenoidBz;
226   
227   if (pathBField) {
228     HLTInfo("reconfigure B-Field from entry %s, chain id %s", path,(chainId!=NULL && chainId[0]!=0)?chainId:"<none>");
229     AliCDBEntry *pEntry = AliCDBManager::Instance()->Get(pathBField);//,GetRunNo());
230     if (pEntry) {
231       TObjString* pString=dynamic_cast<TObjString*>(pEntry->GetObject());
232       if (pString) {
233         HLTInfo("received configuration object string: \'%s\'", pString->GetString().Data());
234         iResult=Configure(pString->GetString().Data());
235       } else {
236         HLTError("configuration object \"%s\" has wrong type, required TObjString", path);
237       }
238     } else {
239       HLTError("cannot fetch object \"%s\" from CDB", path);
240     }
241   }  
242   return iResult;  
243 */
244 }
245
246
247 Bool_t AliHLTTPCCATrackerComponent::CompareClusters(AliHLTTPCSpacePointData *a, AliHLTTPCSpacePointData *b)
248 {
249   //* Comparison function for sorting clusters
250   if( a->fPadRow<b->fPadRow ) return 1;
251   if( a->fPadRow>b->fPadRow ) return 0;
252   return (a->fZ < b->fZ);
253 }
254
255
256 Int_t AliHLTTPCCATrackerComponent::Configure( const char* arguments )
257 {
258   //* Set parameters
259
260   Int_t iResult=EINVAL;
261   if (!arguments) return iResult;
262   
263   TString allArgs=arguments;
264   TString argument;
265   Int_t bMissingParam=0;
266   
267   TObjArray* pTokens=allArgs.Tokenize(" ");
268
269   Int_t nArgs =  pTokens ?pTokens->GetEntries() :0;
270
271   for (int i=0; i<nArgs; i++ ){
272     argument=((TObjString*)pTokens->At(i))->GetString();
273     if (argument.IsNull()){
274     }
275     else if (argument.CompareTo("-solenoidBz")==0 ){
276       if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;  
277       fSolenoidBz = ((TObjString*)pTokens->At(i))->GetString().Atof();
278       HLTInfo("Magnetic Field set to: %f", fSolenoidBz );
279     }
280     else if ( argument.CompareTo("-minNClustersOnTrack")==0 ||
281               argument.CompareTo("-minNTrackClusters")==0 ){
282       if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;  
283       fMinNTrackClusters = ((TObjString*)pTokens->At(i))->GetString().Atoi();
284       HLTInfo("minNClustersOnTrack set to: %d", fMinNTrackClusters );
285     }
286     else if ( argument.CompareTo("-clusterZCut")==0 ){
287       if ((bMissingParam=(++i>=pTokens->GetEntries()))) break;  
288       fClusterZCut = TMath::Abs( ((TObjString*)pTokens->At(i))->GetString().Atof());
289       HLTInfo("ClusterZCut set to: %f", fClusterZCut );
290     }
291     else if ( argument.CompareTo("-newOutputType")==0 ){
292       fNewOutputType = 1;
293       HLTInfo("NewOutputType is set");
294     }
295     else {
296       HLTError("Unknown option %s ", argument.Data());
297       iResult=-EINVAL;
298     }
299   }
300   delete pTokens;
301
302   if (bMissingParam) {
303     HLTError("Specifier missed for %s", argument.Data());    
304     iResult=-EINVAL;
305   }
306
307   return iResult;
308 }
309   
310
311
312
313 Int_t AliHLTTPCCATrackerComponent::DoEvent
314
315  const AliHLTComponentEventData& evtData, 
316  const AliHLTComponentBlockData* blocks, 
317  AliHLTComponentTriggerData& /*trigData*/, 
318  AliHLTUInt8_t* outputPtr, 
319  AliHLTUInt32_t& size, 
320  vector<AliHLTComponentBlockData>& outputBlocks )
321 {
322  //* process event
323   AliHLTUInt32_t maxBufferSize = size;
324   size = 0; // output size
325
326   if(GetFirstInputBlock( kAliHLTDataTypeSOR ) || GetFirstInputBlock( kAliHLTDataTypeEOR )){    
327     return 0;
328   }
329
330   TStopwatch timer;
331
332   // Event reconstruction in one TPC slice with CA Tracker
333  
334   //Logging( kHLTLogWarning, "HLT::TPCCATracker::DoEvent", "DoEvent", "CA::DoEvent()" );
335   if ( evtData.fBlockCnt<=0 )
336     {
337       HLTWarning("no blocks in event" );
338       return 0;
339     }
340   
341   const AliHLTComponentBlockData* iter = NULL;
342   unsigned long ndx;
343   AliHLTTPCClusterData* inPtrSP; 
344  
345   // Determine the slice number 
346   
347   Int_t slice=-1;
348   {
349     std::vector<Int_t> slices;
350     std::vector<Int_t>::iterator slIter;
351     std::vector<unsigned> sliceCnts;
352     std::vector<unsigned>::iterator slCntIter;
353   
354     for ( ndx = 0; ndx < evtData.fBlockCnt; ndx++ ){
355       iter = blocks+ndx;
356       if ( iter->fDataType != AliHLTTPCDefinitions::fgkClustersDataType ) continue;
357
358       slice = AliHLTTPCDefinitions::GetMinSliceNr( *iter );
359
360       Bool_t found = 0;
361       slCntIter = sliceCnts.begin();
362       for( slIter = slices.begin(); slIter!=slices.end(); slIter++, slCntIter++ ){
363         if ( *slIter == slice ){
364           found = kTRUE;
365           break;
366         }
367       }
368       if ( !found ){
369         slices.push_back( slice );
370         sliceCnts.push_back( 1 );
371       } else *slCntIter++;     
372     }
373   
374     
375     // Determine slice number to really use.
376     if ( slices.size()>1 )
377       {
378         Logging( kHLTLogError, "HLT::TPCSliceTracker::DoEvent", "Multiple slices found in event",
379                  "Multiple slice numbers found in event 0x%08lX (%lu). Determining maximum occuring slice number...",
380                  evtData.fEventID, evtData.fEventID );
381         unsigned maxCntSlice=0;
382         slCntIter = sliceCnts.begin();
383         for( slIter = slices.begin(); slIter != slices.end(); slIter++, slCntIter++ )
384           {
385             Logging( kHLTLogError, "HLT::TPCSliceTracker::DoEvent", "Multiple slices found in event",
386                      "Slice %lu found %lu times.", *slIter, *slCntIter );
387             if ( maxCntSlice<*slCntIter )
388               {
389                 maxCntSlice = *slCntIter;
390                 slice = *slIter;
391               }
392           }
393         Logging( kHLTLogError, "HLT::TPCSliceTracker::DoEvent", "Multiple slices found in event",
394                  "Using slice %lu.", slice );
395       }
396     else if ( slices.size()>0 )
397       {
398         slice = *(slices.begin());
399       }
400   }
401   
402   if( slice<0 ){
403     HLTWarning("no slices found in event" );
404     return 0;
405   }
406
407
408   // Initialize the tracker
409
410   
411   {
412     if( !fTracker ) fTracker = new AliHLTTPCCATracker;
413     Int_t iSec = slice;
414     Float_t inRmin = 83.65; 
415     //    Float_t inRmax = 133.3;
416     //    Float_t outRmin = 133.5; 
417     Float_t outRmax = 247.7;
418     Float_t plusZmin = 0.0529937; 
419     Float_t plusZmax = 249.778; 
420     Float_t minusZmin = -249.645; 
421     Float_t minusZmax = -0.0799937; 
422     Float_t dalpha = 0.349066;
423     Float_t alpha = 0.174533 + dalpha*iSec;
424     
425     Bool_t zPlus = (iSec<18 );
426     Float_t zMin =  zPlus ?plusZmin :minusZmin;
427     Float_t zMax =  zPlus ?plusZmax :minusZmax;
428     //TPCZmin = -249.645, ZMax = 249.778    
429     //    Float_t rMin =  inRmin;
430     //    Float_t rMax =  outRmax;
431     Int_t nRows = AliHLTTPCTransform::GetNRows();
432         
433     Float_t padPitch = 0.4;
434     Float_t sigmaZ = 0.228808;
435     
436     Float_t *rowX = new Float_t [nRows];
437     for( Int_t irow=0; irow<nRows; irow++){
438       rowX[irow] = AliHLTTPCTransform::Row2X( irow );
439     }     
440      
441     AliHLTTPCCAParam param;
442     param.Initialize( iSec, nRows, rowX, alpha, dalpha,
443                       inRmin, outRmax, zMin, zMax, padPitch, sigmaZ, fSolenoidBz );
444     param.SetHitPickUpFactor( 2 );
445     param.Update();
446     fTracker->Initialize( param ); 
447     delete[] rowX;
448   }
449
450     
451   // min and max patch numbers and row numbers
452
453   Int_t row[2] = {0,0};
454   Int_t minPatch=100, maxPatch = -1;
455
456   // total n Hits
457
458   Int_t nHitsTotal = 0;
459
460   // sort patches
461
462   std::vector<unsigned long> patchIndices;
463
464   for ( ndx = 0; ndx < evtData.fBlockCnt; ndx++ ){
465     iter = blocks+ndx;      
466     if( iter->fDataType != AliHLTTPCDefinitions::fgkClustersDataType ) continue;
467     if( slice!=AliHLTTPCDefinitions::GetMinSliceNr( *iter ) ) continue;
468     inPtrSP = (AliHLTTPCClusterData*)(iter->fPtr);
469     nHitsTotal+=inPtrSP->fSpacePointCnt;
470     Int_t patch = AliHLTTPCDefinitions::GetMinPatchNr( *iter );
471     if ( minPatch>patch ){
472       minPatch = patch;
473       row[0] = AliHLTTPCTransform::GetFirstRow( patch );
474     }
475     if ( maxPatch<patch ){
476       maxPatch = patch;
477       row[1] = AliHLTTPCTransform::GetLastRow( patch );
478     }
479     std::vector<unsigned long>::iterator pIter = patchIndices.begin(); 
480     while( pIter!=patchIndices.end() && AliHLTTPCDefinitions::GetMinPatchNr( blocks[*pIter] ) < patch ){
481       pIter++;
482     }
483     patchIndices.insert( pIter, ndx );
484   }
485            
486
487   // pass event to CA Tracker
488   
489   fTracker->StartEvent();
490
491   Logging( kHLTLogDebug, "HLT::TPCCATracker::DoEvent", "Reading hits",
492            "Total %d hits to read for slice %d", nHitsTotal, slice );
493
494
495   AliHLTTPCSpacePointData** vOrigClusters = new AliHLTTPCSpacePointData* [ nHitsTotal];
496
497   Int_t nClusters=0;
498
499   for( std::vector<unsigned long>::iterator pIter = patchIndices.begin(); pIter!=patchIndices.end(); pIter++ ){
500     ndx = *pIter;
501     iter = blocks+ndx;
502       
503     Int_t patch = AliHLTTPCDefinitions::GetMinPatchNr( *iter );
504     inPtrSP = (AliHLTTPCClusterData*)(iter->fPtr);
505       
506     Logging( kHLTLogDebug, "HLT::TPCCATracker::DoEvent", "Reading hits",
507              "Reading %d hits for slice %d - patch %d", inPtrSP->fSpacePointCnt, slice, patch );
508       
509     for (UInt_t i=0; i<inPtrSP->fSpacePointCnt; i++ ){  
510       vOrigClusters[nClusters++] = &(inPtrSP->fSpacePoints[i]);
511     }
512   }
513
514   // sort clusters since they are not sorted fore some reason
515
516   sort( vOrigClusters, vOrigClusters+nClusters, CompareClusters );
517
518   Float_t *vHitStoreX = new Float_t [nHitsTotal];       // hit X coordinates
519   Float_t *vHitStoreY = new Float_t [nHitsTotal];       // hit Y coordinates
520   Float_t *vHitStoreZ = new Float_t [nHitsTotal];       // hit Z coordinates
521   Int_t *vHitStoreIntID = new Int_t [nHitsTotal];            // hit ID's
522   Int_t *vHitStoreID = new Int_t [nHitsTotal];            // hit ID's
523   Int_t *vHitRowID = new Int_t [nHitsTotal];            // hit ID's
524
525   Int_t nHits = 0;
526
527   {
528     Int_t rowNHits[200];
529     Int_t rowFirstHits[200];
530     for( Int_t ir=0; ir<200; ir++ ) rowNHits[ir] = 0;
531     Int_t oldRow = -1;
532     for (Int_t i=0; i<nClusters; i++ ){
533       AliHLTTPCSpacePointData* pSP = vOrigClusters[i];
534       if( oldRow>=0 && pSP->fPadRow < oldRow )
535         HLTError("CA: clusters from row %d are readed twice",oldRow);      
536       
537       if( TMath::Abs(pSP->fZ)>fClusterZCut) continue;
538       
539       vHitStoreX[nHits] = pSP->fX;  
540       vHitStoreY[nHits] = pSP->fY;
541       vHitStoreZ[nHits] = pSP->fZ;
542       vHitStoreIntID[nHits] = nHits;
543       vHitStoreID[nHits] = pSP->fID;
544       vHitRowID[nHits] = pSP->fPadRow;
545       nHits++;  
546       rowNHits[pSP->fPadRow]++;
547     }   
548
549     Int_t firstRowHit = 0;
550     for( Int_t ir=0; ir<200; ir++ ){
551       rowFirstHits[ir] = firstRowHit;
552       firstRowHit+=rowNHits[ir];
553     }
554
555     fTracker->ReadEvent( rowFirstHits, rowNHits, vHitStoreY, vHitStoreZ, nHits );
556   }
557
558   if( vOrigClusters ) delete[] vOrigClusters;
559
560   // reconstruct the event  
561
562   TStopwatch timerReco;
563
564   fTracker->Reconstruct();
565
566   timerReco.Stop();
567
568   Int_t ret = 0;
569
570   Logging( kHLTLogDebug, "HLT::TPCCATracker::DoEvent", "Reconstruct",
571            "%d tracks found for slice %d",fTracker->NOutTracks(), slice);
572
573
574   // write reconstructed tracks
575
576   UInt_t mySize = 0;
577   Int_t ntracks = *fTracker->NOutTracks();
578
579   
580   if( !fNewOutputType ){
581
582     AliHLTTPCTrackletData* outPtr = (AliHLTTPCTrackletData*)(outputPtr);
583     
584     AliHLTTPCTrackSegmentData* currOutTracklet = outPtr->fTracklets;    
585     
586     mySize =   ((AliHLTUInt8_t *)currOutTracklet) -  ((AliHLTUInt8_t *)outputPtr);
587     
588     outPtr->fTrackletCnt = 0; 
589     
590     for( Int_t itr=0; itr<ntracks; itr++ ){
591       
592       AliHLTTPCCAOutTrack &t = fTracker->OutTracks()[itr];    
593       
594       //Logging( kHLTLogDebug, "HLT::TPCCATracker::DoEvent", "Wrtite output","track %d with %d hits", itr, t.NHits());
595       
596       if( t.NHits()<fMinNTrackClusters ) continue;
597       
598       // calculate output track size
599       
600       UInt_t dSize = sizeof(AliHLTTPCTrackSegmentData) + t.NHits()*sizeof(UInt_t);
601       
602       if( mySize + dSize > maxBufferSize ){
603         HLTWarning("Output buffer size exceed (buffer size %d, current size %d), %d tracks are not stored", maxBufferSize, mySize, ntracks-itr+1);
604         ret = -ENOSPC;
605         break;
606       }
607       
608       // convert CA track parameters to HLT Track Segment
609       
610       Int_t iFirstRow = 1000;
611       Int_t iLastRow = -1;
612       Int_t iFirstHit = fTracker->OutTrackHits()[t.FirstHitRef()];
613       Int_t iLastHit = iFirstHit;
614       for( Int_t ih=0; ih<t.NHits(); ih++ ){
615         Int_t hitID = fTracker->OutTrackHits()[t.FirstHitRef() + ih ];
616         Int_t iRow = vHitRowID[hitID];
617         if( iRow<iFirstRow ){  iFirstRow = iRow; iFirstHit = hitID; }
618         if( iRow>iLastRow ){ iLastRow = iRow; iLastHit = hitID; }
619       }   
620       
621       AliHLTTPCCATrackParam par = t.StartPoint();
622       
623       par.TransportToX( vHitStoreX[iFirstHit], .99 );
624       
625       AliExternalTrackParam tp;
626       AliHLTTPCCATrackConvertor::GetExtParam( par, tp, 0, fSolenoidBz );
627       
628       currOutTracklet->fX = tp.GetX();
629       currOutTracklet->fY = tp.GetY();
630       currOutTracklet->fZ = tp.GetZ();
631       currOutTracklet->fCharge = (Int_t ) tp.GetSign();
632       currOutTracklet->fPt = TMath::Abs(tp.GetSignedPt());
633       Float_t snp =  tp.GetSnp() ;
634       if( snp>.999 ) snp=.999;
635       if( snp<-.999 ) snp=-.999;
636       currOutTracklet->fPsi = TMath::ASin( snp );
637       currOutTracklet->fTgl = tp.GetTgl();
638       
639       currOutTracklet->fY0err = tp.GetSigmaY2();
640       currOutTracklet->fZ0err = tp.GetSigmaZ2();
641       Float_t h = -currOutTracklet->fPt*currOutTracklet->fPt;
642       currOutTracklet->fPterr = h*h*tp.GetSigma1Pt2();
643       h = 1./TMath::Sqrt(1-snp*snp);
644       currOutTracklet->fPsierr = h*h*tp.GetSigmaSnp2();
645       currOutTracklet->fTglerr = tp.GetSigmaTgl2();
646       
647       if( par.TransportToX( vHitStoreX[iLastHit],.99 ) ){     
648         currOutTracklet->fLastX = par.GetX();
649         currOutTracklet->fLastY = par.GetY();
650         currOutTracklet->fLastZ = par.GetZ();
651       } else {
652         currOutTracklet->fLastX = vHitStoreX[iLastHit];
653         currOutTracklet->fLastY = vHitStoreY[iLastHit];
654         currOutTracklet->fLastZ = vHitStoreZ[iLastHit];
655       }
656       //if( currOutTracklet->fLastX<10. ) {
657       //HLTError("CA last point: hitxyz=%f,%f,%f, track=%f,%f,%f, tracklet=%f,%f,%f, nhits=%d",vHitStoreX[iLastHit],vHitStoreY[iLastHit],vHitStoreZ[iLastHit],
658       //par.GetX(), par.GetY(),par.GetZ(),currOutTracklet->fLastX,currOutTracklet->fLastY ,currOutTracklet->fLastZ, t.NHits());
659       //}
660 #ifdef INCLUDE_TPC_HOUGH
661 #ifdef ROWHOUGHPARAMS
662       currOutTracklet->fTrackID = 0;
663       currOutTracklet->fRowRange1 = vHitRowID[iFirstHit];
664       currOutTracklet->fRowRange2 = vHitRowID[iLastHit];
665       currOutTracklet->fSector = slice;
666       currOutTracklet->fPID = 211;
667 #endif
668 #endif // INCLUDE_TPC_HOUGH
669       
670       
671       currOutTracklet->fNPoints = t.NHits();
672       
673       for( Int_t i=0; i<t.NHits(); i++ ){
674         currOutTracklet->fPointIDs[i] = vHitStoreID[fTracker->OutTrackHits()[t.FirstHitRef()+i]];
675       }
676       
677       currOutTracklet = (AliHLTTPCTrackSegmentData*)( (Byte_t *)currOutTracklet + dSize );
678       mySize+=dSize;
679       outPtr->fTrackletCnt++; 
680     }
681   } else { // new output type
682
683     mySize = fTracker->Output()->EstimateSize( fTracker->Output()->NTracks(), 
684                                                fTracker->Output()->NTrackClusters() );
685     if( mySize <= maxBufferSize ){
686       const AliHLTUInt8_t* outputevent = reinterpret_cast<const AliHLTUInt8_t*>(fTracker->Output());
687       for( UInt_t i=0; i<mySize; i++ ) outputPtr[i] = outputevent[i];
688     } else {    
689       HLTWarning("Output buffer size exceed (buffer size %d, current size %d), tracks are not stored", maxBufferSize, mySize );
690       mySize = 0;
691       ret = -ENOSPC;
692     }
693   }
694  
695   if( vHitStoreX ) delete[] vHitStoreX;
696   if( vHitStoreY ) delete[] vHitStoreY;
697   if( vHitStoreZ ) delete[] vHitStoreZ;
698   if( vHitStoreIntID ) delete[] vHitStoreIntID;
699   if( vHitStoreID ) delete[] vHitStoreID;
700   if( vHitRowID ) delete[] vHitRowID;
701
702   if( mySize>0 ){
703     AliHLTComponentBlockData bd;
704     FillBlockData( bd );
705     bd.fOffset = 0;
706     bd.fSize = mySize;
707     bd.fSpecification = AliHLTTPCDefinitions::EncodeDataSpecification( slice, slice, minPatch, maxPatch ); 
708     outputBlocks.push_back( bd );
709   }
710   size = mySize;
711   
712   timer.Stop();
713
714   fFullTime+= timer.RealTime();
715   fRecoTime+= timerReco.RealTime();
716   fNEvents++;
717
718   // Set log level to "Warning" for on-line system monitoring
719   Int_t hz = (Int_t) (fFullTime>1.e-10 ?fNEvents/fFullTime :100000);
720   Int_t hz1 = (Int_t) (fRecoTime>1.e-10 ?fNEvents/fRecoTime :100000);
721   HLTInfo( "CATracker slice %d: output %d tracks;  input %d clusters, patches %d..%d, rows %d..%d; reco time %d/%d Hz", 
722             slice, ntracks, nClusters, minPatch, maxPatch, row[0], row[1], hz, hz1 );
723
724   return ret;
725 }
726
727