changes from Matthias
[u/mrichter/AliRoot.git] / HLT / TPCLib / tracking-ca / AliTPCtrackerCA.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 #include "AliTPCtrackerCA.h"
21
22 #include "TTree.h"
23 #include "Riostream.h"
24 //#include "AliCluster.h"
25 #include "AliTPCClustersRow.h"
26 #include "AliTPCParam.h"
27 #include "AliTPCClusterParam.h"
28
29 #include "AliRun.h"
30 #include "AliRunLoader.h"
31 #include "AliStack.h"
32
33 #include "AliHLTTPCCAGBTracker.h"
34 #include "AliHLTTPCCAGBHit.h"
35 #include "AliHLTTPCCAGBTrack.h"
36 #include "AliHLTTPCCAPerformance.h"
37 #include "AliHLTTPCCAParam.h"
38 #include "AliHLTTPCCATrackConvertor.h"
39 #include "AliHLTTPCCATracker.h"
40
41 #include "TMath.h"
42 #include "AliTPCLoader.h"
43 #include "AliTPC.h"
44 #include "AliTPCclusterMI.h"
45 #include "AliTPCTransform.h"
46 #include "AliTPCcalibDB.h"
47 #include "AliTPCtrack.h"
48 #include "AliTPCseed.h"
49 #include "AliESDtrack.h"
50 #include "AliESDEvent.h"
51 #include "AliTrackReference.h"
52 #include "TStopwatch.h"
53 #include "AliTPCReconstructor.h"
54
55 //#include <fstream.h>
56
57 ClassImp( AliTPCtrackerCA )
58
59 AliTPCtrackerCA::AliTPCtrackerCA()
60     : AliTracker(), fkParam( 0 ), fClusters( 0 ), fNClusters( 0 ), fHLTTracker( 0 ), fDoHLTPerformance( 0 ), fDoHLTPerformanceClusters( 0 ), fStatNEvents( 0 )
61 {
62   //* default constructor
63 }
64
65 AliTPCtrackerCA::AliTPCtrackerCA( const AliTPCtrackerCA & ):
66     AliTracker(), fkParam( 0 ), fClusters( 0 ), fNClusters( 0 ), fHLTTracker( 0 ), fDoHLTPerformance( 0 ), fDoHLTPerformanceClusters( 0 ), fStatNEvents( 0 )
67 {
68   //* dummy
69 }
70
71 const AliTPCtrackerCA & AliTPCtrackerCA::operator=( const AliTPCtrackerCA& ) const
72 {
73   //* dummy
74   return *this;
75 }
76
77
78 AliTPCtrackerCA::~AliTPCtrackerCA()
79 {
80   //* destructor
81   if ( fClusters ) delete[] fClusters;
82   if ( fHLTTracker ) delete fHLTTracker;
83 }
84
85 //#include "AliHLTTPCCADisplay.h"
86
87 AliTPCtrackerCA::AliTPCtrackerCA( const AliTPCParam *par ):
88     AliTracker(), fkParam( par ), fClusters( 0 ), fNClusters( 0 ), fHLTTracker( 0 ), fDoHLTPerformance( 0 ), fDoHLTPerformanceClusters( 0 ), fStatNEvents( 0 )
89 {
90   //* constructor
91
92   fDoHLTPerformance = 0;
93   fDoHLTPerformanceClusters = 0;
94
95   fHLTTracker = new AliHLTTPCCAGBTracker;
96   fHLTTracker->SetNSlices( fkParam->GetNSector() / 2 );
97
98   if ( fDoHLTPerformance ) {
99     AliHLTTPCCAPerformance::Instance().SetTracker( fHLTTracker );
100   }
101
102   for ( int iSlice = 0; iSlice < fHLTTracker->NSlices(); iSlice++ ) {
103
104     const double kCLight = 0.000299792458;
105
106     float bz = AliTracker::GetBz() * kCLight;
107
108     float inRmin = fkParam->GetInnerRadiusLow();
109     //float inRmax = fkParam->GetInnerRadiusUp();
110     //float outRmin = fkParam->GetOuterRadiusLow();
111     float outRmax = fkParam->GetOuterRadiusUp();
112     float plusZmin = 0.0529937;
113     float plusZmax = 249.778;
114     float minusZmin = -249.645;
115     float minusZmax = -0.0799937;
116     float dalpha = 0.349066;
117     float alpha = 0.174533 + dalpha * iSlice;
118
119     bool zPlus = ( iSlice < 18 );
120     float zMin =  zPlus ? plusZmin : minusZmin;
121     float zMax =  zPlus ? plusZmax : minusZmax;
122     //TPCZmin = -249.645, ZMax = 249.778
123     //float rMin =  inRmin;
124     //float rMax =  outRmax;
125
126     float padPitch = 0.4;
127     float sigmaZ = 0.228808;
128
129     int nRows = fkParam->GetNRowLow() + fkParam->GetNRowUp();
130     float rowX[200];
131     for ( int irow = 0; irow < fkParam->GetNRowLow(); irow++ ) {
132       rowX[irow] = fkParam->GetPadRowRadiiLow( irow );
133     }
134     for ( int irow = 0; irow < fkParam->GetNRowUp(); irow++ ) {
135       rowX[fkParam->GetNRowLow()+irow] = fkParam->GetPadRowRadiiUp( irow );
136     }
137     AliHLTTPCCAParam param;
138     param.Initialize( iSlice, nRows, rowX, alpha, dalpha,
139                       inRmin, outRmax, zMin, zMax, padPitch, sigmaZ, bz );
140     param.SetHitPickUpFactor( 1. );
141     param.SetMaxTrackMatchDRow( 5 );
142     param.SetTrackConnectionFactor( 3.5 );
143
144     AliTPCClusterParam * clparam = AliTPCcalibDB::Instance()->GetClusterParam();
145     for ( int iRow = 0; iRow < nRows; iRow++ ) {
146       int    type = ( iRow < 63 ) ? 0 : ( ( iRow > 126 ) ? 1 : 2 );
147       for ( int iyz = 0; iyz < 2; iyz++ ) {
148         for ( int k = 0; k < 7; k++ ) {
149           //std::cout<<param.fParamS0Par[iyz][type][k]<<" "<<clparam->fParamS0Par[iyz][type][k] - param.fParamS0Par[iyz][type][k]<<std::endl;
150           param.SetParamS0Par( iyz, type, k, clparam->fParamS0Par[iyz][type][k] );
151         }
152       }
153     }
154     fHLTTracker->Slices()[iSlice].Initialize( param );
155   }
156 }
157
158
159
160 int AliTPCtrackerCA::LoadClusters ( TTree * fromTree )
161 {
162   // load clusters to the local arrays
163   fNClusters = 0;
164   if ( fClusters ) delete[] fClusters;
165
166   fHLTTracker->StartEvent();
167   if ( fDoHLTPerformance ) AliHLTTPCCAPerformance::Instance().StartEvent();
168
169   if ( !fkParam ) return 1;
170
171   // load mc tracks
172   while ( fDoHLTPerformance ) {
173     if ( !gAlice ) break;
174     AliRunLoader *rl = AliRunLoader::Instance();//gAlice->GetRunLoader();
175     if ( !rl ) break;
176     rl->LoadKinematics();
177     AliStack *stack = rl->Stack();
178     if ( !stack ) break;
179
180     AliHLTTPCCAPerformance::Instance().SetNMCTracks( stack->GetNtrack() );
181
182     for ( int itr = 0; itr < stack->GetNtrack(); itr++ ) {
183       TParticle *part = stack->Particle( itr );
184       AliHLTTPCCAPerformance::Instance().ReadMCTrack( itr, part );
185     }
186
187     { // check for MC tracks at the TPC entrance
188
189       bool *isTPC = 0;
190       isTPC = new bool [stack->GetNtrack()];
191       for ( int i = 0; i < stack->GetNtrack(); i++ ) isTPC[i] = 0;
192       rl->LoadTrackRefs();
193       TTree *mcTree = rl->TreeTR();
194       if ( !mcTree ) break;
195       TBranch *branch = mcTree->GetBranch( "TrackReferences" );
196       if ( !branch ) break;
197       TClonesArray tpcdummy( "AliTrackReference", 1000 ), *tpcRefs = &tpcdummy;
198       branch->SetAddress( &tpcRefs );
199       int nr = ( int )mcTree->GetEntries();
200       for ( int r = 0; r < nr; r++ ) {
201         mcTree->GetEvent( r );
202         int nref = tpcRefs->GetEntriesFast();
203         if ( !nref ) continue;
204         AliTrackReference *tpcRef = 0x0;
205         for ( int iref = 0; iref < nref; ++iref ) {
206           tpcRef = ( AliTrackReference* )tpcRefs->UncheckedAt( iref );
207           if ( tpcRef->DetectorId() == AliTrackReference::kTPC ) break;
208           tpcRef = 0x0;
209         }
210         if ( !tpcRef ) continue;
211
212         if ( isTPC[tpcRef->Label()] ) continue;
213
214         AliHLTTPCCAPerformance::Instance().ReadMCTPCTrack( tpcRef->Label(),
215             tpcRef->X(), tpcRef->Y(), tpcRef->Z(),
216             tpcRef->Px(), tpcRef->Py(), tpcRef->Pz() );
217         isTPC[tpcRef->Label()] = 1;
218         tpcRefs->Clear();
219       }
220       if ( isTPC ) delete[] isTPC;
221     }
222
223     while ( fDoHLTPerformanceClusters ) {
224       AliTPCLoader *tpcl = ( AliTPCLoader* ) rl->GetDetectorLoader( "TPC" );
225       if ( !tpcl ) break;
226       if ( tpcl->TreeH() == 0x0 ) {
227         if ( tpcl->LoadHits() ) break;
228       }
229       if ( tpcl->TreeH() == 0x0 ) break;
230
231       AliTPC *tpc = ( AliTPC* ) gAlice->GetDetector( "TPC" );
232       int nEnt = ( int )tpcl->TreeH()->GetEntries();
233       int nPoints = 0;
234       for ( int iEnt = 0; iEnt < nEnt; iEnt++ ) {
235         tpc->ResetHits();
236         tpcl->TreeH()->GetEvent( iEnt );
237         AliTPChit *phit = ( AliTPChit* )tpc->FirstHit( -1 );
238         for ( ; phit; phit = ( AliTPChit* )tpc->NextHit() ) nPoints++;
239       }
240       AliHLTTPCCAPerformance::Instance().SetNMCPoints( nPoints );
241
242       for ( int iEnt = 0; iEnt < nEnt; iEnt++ ) {
243         tpc->ResetHits();
244         tpcl->TreeH()->GetEvent( iEnt );
245         AliTPChit *phit = ( AliTPChit* )tpc->FirstHit( -1 );
246         for ( ; phit; phit = ( AliTPChit* )tpc->NextHit() ) {
247           AliHLTTPCCAPerformance::Instance().ReadMCPoint( phit->GetTrack(), phit->X(), phit->Y(), phit->Z(), phit->Time(), phit->fSector % 36 );
248         }
249       }
250       break;
251     }
252     break;
253   }
254
255   TBranch * br = fromTree->GetBranch( "Segment" );
256   if ( !br ) return 1;
257
258   AliTPCClustersRow *clrow = new AliTPCClustersRow;
259   clrow->SetClass( "AliTPCclusterMI" );
260   clrow->SetArray( 0 );
261   clrow->GetArray()->ExpandCreateFast( 10000 );
262
263   br->SetAddress( &clrow );
264
265   //
266   int nEnt = int( fromTree->GetEntries() );
267
268   fNClusters = 0;
269   for ( int i = 0; i < nEnt; i++ ) {
270     br->GetEntry( i );
271     int sec, row;
272     fkParam->AdjustSectorRow( clrow->GetID(), sec, row );
273     fNClusters += clrow->GetArray()->GetEntriesFast();
274   }
275
276   fClusters = new AliTPCclusterMI [fNClusters];
277   fHLTTracker->SetNHits( fNClusters );
278   if ( fDoHLTPerformance ) AliHLTTPCCAPerformance::Instance().SetNHits( fNClusters );
279   int ind = 0;
280   for ( int i = 0; i < nEnt; i++ ) {
281     br->GetEntry( i );
282     int sec, row;
283     fkParam->AdjustSectorRow( clrow->GetID(), sec, row );
284     int nClu = clrow->GetArray()->GetEntriesFast();
285     float x = fkParam->GetPadRowRadii( sec, row );
286     for ( int icl = 0; icl < nClu; icl++ ) {
287       int lab0 = -1;
288       int lab1 = -1;
289       int lab2 = -1;
290       AliTPCclusterMI* cluster = ( AliTPCclusterMI* )( clrow->GetArray()->At( icl ) );
291       if ( !cluster ) continue;
292       lab0 = cluster->GetLabel( 0 );
293       lab1 = cluster->GetLabel( 1 );
294       lab2 = cluster->GetLabel( 2 );
295
296       AliTPCTransform *transform = AliTPCcalibDB::Instance()->GetTransform() ;
297       if ( !transform ) {
298         AliFatal( "Tranformations not in calibDB" );
299       }
300       double xx[3] = {cluster->GetRow(), cluster->GetPad(), cluster->GetTimeBin()};
301       int id[1] = {cluster->GetDetector()};
302       transform->Transform( xx, id, 0, 1 );
303       //if (!AliTPCReconstructor::GetRecoParam()->GetBYMirror()){
304       //if (cluster->GetDetector()%36>17){
305       //xx[1]*=-1;
306       //}
307       //}
308
309       cluster->SetX( xx[0] );
310       cluster->SetY( xx[1] );
311       cluster->SetZ( xx[2] );
312
313       TGeoHMatrix  *mat = fkParam->GetClusterMatrix( cluster->GetDetector() );
314       double pos[3] = {cluster->GetX(), cluster->GetY(), cluster->GetZ()};
315       double posC[3] = {cluster->GetX(), cluster->GetY(), cluster->GetZ()};
316       if ( mat ) mat->LocalToMaster( pos, posC );
317       else {
318         // chack Loading of Geo matrices from GeoManager - TEMPORARY FIX
319       }
320       cluster->SetX( posC[0] );
321       cluster->SetY( posC[1] );
322       cluster->SetZ( posC[2] );
323
324       x = cluster->GetX();
325       float y = cluster->GetY();
326       float z = cluster->GetZ();
327
328       if ( sec >= 36 ) {
329         sec = sec - 36;
330         row = row + fkParam->GetNRowLow();
331       }
332
333       int index = ind++;
334       fClusters[index] = *cluster;
335       fHLTTracker->ReadHit( x, y, z,
336                             TMath::Sqrt( cluster->GetSigmaY2() ), TMath::Sqrt( cluster->GetSigmaZ2() ),
337                             cluster->GetMax(), index, sec, row );
338       if ( fDoHLTPerformance ) AliHLTTPCCAPerformance::Instance().ReadHitLabel( index, lab0, lab1, lab2 );
339     }
340   }
341   delete clrow;
342   return 0;
343 }
344
345 AliCluster * AliTPCtrackerCA::GetCluster( int index ) const
346 {
347   return &( fClusters[index] );
348 }
349
350 int AliTPCtrackerCA::Clusters2Tracks( AliESDEvent *event )
351 {
352   // reconstruction
353   //cout<<"Start of AliTPCtrackerCA"<<endl;
354   TStopwatch timer;
355
356   fHLTTracker->FindTracks();
357   //cout<<"Do performance.."<<endl;
358   if ( fDoHLTPerformance ) AliHLTTPCCAPerformance::Instance().Performance();
359
360   if ( 0 ) {// Write Event
361     if ( fStatNEvents == 0 ) {
362       fstream geo;
363       geo.open( "CAEvents/settings.dat", ios::out );
364       if ( geo.is_open() ) {
365         fHLTTracker->WriteSettings( geo );
366       }
367       geo.close();
368     }
369
370     fstream hits;
371     char name[255];
372     sprintf( name, "CAEvents/%i.event.dat", fStatNEvents );
373     hits.open( name, ios::out );
374     if ( hits.is_open() ) {
375       fHLTTracker->WriteEvent( hits );
376       fstream tracks;
377       sprintf( name, "CAEvents/%i.tracks.dat", fStatNEvents );
378       tracks.open( name, ios::out );
379       fHLTTracker->WriteTracks( tracks );
380     }
381     hits.close();
382     if ( fDoHLTPerformance ) {
383       fstream mcevent, mcpoints;
384       char mcname[255];
385       sprintf( mcname, "CAEvents/%i.mcevent.dat", fStatNEvents );
386       mcevent.open( mcname, ios::out );
387       if ( mcevent.is_open() ) {
388         AliHLTTPCCAPerformance::Instance().WriteMCEvent( mcevent );
389       }
390       if ( 1 && fDoHLTPerformanceClusters ) {
391         sprintf( mcname, "CAEvents/%i.mcpoints.dat", fStatNEvents );
392         mcpoints.open( mcname, ios::out );
393         if ( mcpoints.is_open() ) {
394           AliHLTTPCCAPerformance::Instance().WriteMCPoints( mcpoints );
395         }
396         mcpoints.close();
397       }
398       mcevent.close();
399     }
400   }
401   fStatNEvents++;
402
403   if ( event ) {
404
405     for ( int itr = 0; itr < fHLTTracker->NTracks(); itr++ ) {
406       //AliTPCtrack tTPC;
407       AliTPCseed tTPC;
408       AliHLTTPCCAGBTrack &tCA = fHLTTracker->Tracks()[itr];
409       AliHLTTPCCATrackParam par = tCA.Param();
410       AliHLTTPCCATrackConvertor::GetExtParam( par, tTPC, tCA.Alpha() );
411       tTPC.SetMass( 0.13957 );
412       tTPC.SetdEdx( tCA.DeDx() );
413       if ( TMath::Abs( tTPC.GetSigned1Pt() ) > 1. / 0.02 ) continue;
414       int nhits = tCA.NHits();
415       int firstHit = 0;
416       if ( nhits > 160 ) {
417         firstHit = nhits - 160;
418         nhits = 160;
419       }
420
421       tTPC.SetNumberOfClusters( nhits );
422
423       float alpha = tCA.Alpha();
424       AliHLTTPCCATrackParam t0 = par;
425       for ( int ih = 0; ih < nhits; ih++ ) {
426         int index = fHLTTracker->TrackHits()[tCA.FirstHitRef()+firstHit+ih];
427         const AliHLTTPCCAGBHit &h = fHLTTracker->Hits()[index];
428         int extIndex = h.ID();
429         tTPC.SetClusterIndex( ih, extIndex );
430
431         AliTPCclusterMI *c = &( fClusters[extIndex] );
432         tTPC.SetClusterPointer( h.IRow(), c );
433         AliTPCTrackerPoint &point = *( tTPC.GetTrackPoint( h.IRow() ) );
434         {
435           int iSlice = h.ISlice();
436           AliHLTTPCCATracker &slice = fHLTTracker->Slices()[iSlice];
437           if ( slice.Param().Alpha() != alpha ) {
438             if ( ! t0.Rotate(  slice.Param().Alpha() - alpha, .999 ) ) continue;
439             alpha = slice.Param().Alpha();
440           }
441           float x = slice.Row( h.IRow() ).X();
442           if ( !t0.TransportToX( x, fHLTTracker->Slices()[0].Param().GetBz( t0 ), .999 ) ) continue;
443           float sy2, sz2;
444           slice.GetErrors2( h.IRow(), t0, sy2, sz2 );
445           point.SetSigmaY( c->GetSigmaY2() / sy2 );
446           point.SetSigmaZ( c->GetSigmaZ2() / sz2 );
447           point.SetAngleY( TMath::Abs( t0.GetSinPhi() / t0.GetCosPhi() ) );
448           point.SetAngleZ( TMath::Abs( t0.GetDzDs() ) );
449         }
450       }
451       tTPC.CookdEdx( 0.02, 0.6 );
452
453       CookLabel( &tTPC, 0.1 );
454
455       if ( 1 ) { // correction like in off-line --- Adding systematic error
456
457         const double *param = AliTPCReconstructor::GetRecoParam()->GetSystematicError();
458         double covar[15];
459         for ( int i = 0; i < 15; i++ ) covar[i] = 0;
460         covar[0] = param[0] * param[0];
461         covar[2] = param[1] * param[1];
462         covar[5] = param[2] * param[2];
463         covar[9] = param[3] * param[3];
464         double facC =  AliTracker::GetBz() * kB2C;
465         covar[14] = param[4] * param[4] * facC * facC;
466         tTPC.AddCovariance( covar );
467       }
468
469       AliESDtrack tESD;
470       tESD.UpdateTrackParams( &( tTPC ), AliESDtrack::kTPCin );
471       //tESD.SetStatus( AliESDtrack::kTPCrefit );
472       //tESD.SetTPCPoints(tTPC.GetPoints());
473       int   ndedx = tTPC.GetNCDEDX( 0 );
474       float sdedx = tTPC.GetSDEDX( 0 );
475       float dedx  = tTPC.GetdEdx();
476       tESD.SetTPCsignal( dedx, sdedx, ndedx );
477       //tESD.myTPC = tTPC;
478
479       event->AddTrack( &tESD );
480     }
481   }
482   timer.Stop();
483   static double time = 0, time1 = 0;
484   static int ncalls = 0;
485   time += timer.CpuTime();
486   time1 += timer.RealTime();
487   ncalls++;
488   //cout<<"\n\nCA tracker speed: cpu = "<<time/ncalls*1.e3<<" [ms/ev], real = "<<time1/ncalls*1.e3<<" [ms/ev], n calls = "<<ncalls<<endl<<endl;
489
490   //cout<<"End of AliTPCtrackerCA"<<endl;
491   return 0;
492 }
493
494
495 int AliTPCtrackerCA::RefitInward ( AliESDEvent *event )
496 {
497   //* forward propagation of ESD tracks
498
499   //float bz = fHLTTracker->Slices()[0].Param().Bz();
500   float xTPC = fkParam->GetInnerRadiusLow();
501   float dAlpha = fkParam->GetInnerAngle() / 180.*TMath::Pi();
502   float yMax = xTPC * TMath::Tan( dAlpha / 2. );
503
504   int nentr = event->GetNumberOfTracks();
505
506   for ( int itr = 0; itr < nentr; itr++ ) {
507     AliESDtrack *esd = event->GetTrack( itr );
508     ULong_t status = esd->GetStatus();
509     if ( !( status&AliESDtrack::kTPCin ) ) continue;
510     AliHLTTPCCATrackParam t0;
511     AliHLTTPCCATrackConvertor::SetExtParam( t0, *esd );
512     AliHLTTPCCATrackParam t = t0;
513     float alpha = esd->GetAlpha();
514     //float dEdX=0;
515     int hits[1000];
516     int nHits = esd->GetTPCclusters( hits );
517
518     // convert clluster indices to AliHLTTPCCAGBHit indices
519
520     for ( int i = 0; i < nHits; i++ ) hits[i] = fHLTTracker->Ext2IntHitID( hits[i] );
521
522     bool ok = fHLTTracker->FitTrack( t, t0, alpha, hits, nHits, 0 );
523     if ( ok &&  nHits > 15 ) {
524       if ( t.TransportToXWithMaterial( xTPC, fHLTTracker->Slices()[0].Param().GetBz( t ) ) ) {
525         if ( t.GetY() > yMax ) {
526           if ( t.Rotate( dAlpha ) ) {
527             alpha += dAlpha;
528             t.TransportToXWithMaterial( xTPC, fHLTTracker->Slices()[0].Param().GetBz( t ) );
529           }
530         } else if ( t.GetY() < -yMax ) {
531           if ( t.Rotate( -dAlpha ) ) {
532             alpha += -dAlpha;
533             t.TransportToXWithMaterial( xTPC, fHLTTracker->Slices()[0].Param().GetBz( t ) );
534           }
535         }
536       }
537
538       AliTPCtrack tt( *esd );
539       if ( AliHLTTPCCATrackConvertor::GetExtParam( t, tt, alpha ) ) {
540         if ( t.X() > 50 ) esd->UpdateTrackParams( &tt, AliESDtrack::kTPCrefit );
541       }
542     }
543   }
544   return 0;
545 }
546
547 int AliTPCtrackerCA::PropagateBack( AliESDEvent *event )
548 {
549
550   //* backward propagation of ESD tracks
551
552   //float bz = fHLTTracker->Slices()[0].Param().Bz();
553   int nentr = event->GetNumberOfTracks();
554
555   for ( int itr = 0; itr < nentr; itr++ ) {
556
557     AliESDtrack *esd = event->GetTrack( itr );
558     ULong_t status = esd->GetStatus();
559     if ( !( status&AliESDtrack::kTPCin ) ) continue;
560
561     AliHLTTPCCATrackParam t0;
562     AliHLTTPCCATrackConvertor::SetExtParam( t0, *esd  );
563     AliHLTTPCCATrackParam t = t0;
564     float alpha = esd->GetAlpha();
565     //float dEdX=0;
566     int hits[1000];
567     int nHits = esd->GetTPCclusters( hits );
568
569     // convert clluster indices to AliHLTTPCCAGBHit indices
570
571     for ( int i = 0; i < nHits; i++ ) hits[i] = fHLTTracker->Ext2IntHitID( hits[i] );
572
573     bool ok = fHLTTracker->FitTrack( t, t0, alpha, hits, nHits, 1 );
574     if ( ok &&  nHits > 15 ) {
575       AliTPCtrack tt( *esd );
576       if ( AliHLTTPCCATrackConvertor::GetExtParam( t, tt, alpha ) ) {
577         if ( t.X() > 50 ) esd->UpdateTrackParams( &tt, AliESDtrack::kTPCout );
578       }
579     }
580   }
581   return 0;
582 }