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