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