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