]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TOF/AliTOFtracker.cxx
c7f31d195e8e1954b201b6b8c7c462a4fffece40
[u/mrichter/AliRoot.git] / TOF / AliTOFtracker.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 //--------------------------------------------------------------------//
17 //                                                                    //
18 // AliTOFtracker Class                                                //
19 // Task: Perform association of the ESD tracks to TOF Clusters        //
20 // and Update ESD track with associated TOF Cluster parameters        //
21 //                                                                    //
22 // -- Authors : S. Arcelli, C. Zampolli (Bologna University and INFN) //
23 // -- Contacts: Annalisa.De.Caro@cern.ch                              //
24 // --         : Chiara.Zampolli@bo.infn.it                            //
25 // --         : Silvia.Arcelli@bo.infn.it                             //
26 //                                                                    //
27 //--------------------------------------------------------------------//
28
29 #include "Rtypes.h"
30
31 #include "TClonesArray.h"
32 #include "TGeoManager.h"
33 #include "TTree.h"
34
35 #include "AliAlignObj.h"
36 #include "AliESDtrack.h"
37 #include "AliESD.h"
38 #include "AliLog.h"
39 #include "AliTrackPointArray.h"
40
41 #include "AliTOFcalib.h"
42 #include "AliTOFcluster.h"
43 #include "AliTOFGeometry.h"
44 #include "AliTOFtracker.h"
45 #include "AliTOFtrack.h"
46
47 extern TGeoManager *gGeoManager;
48
49 ClassImp(AliTOFtracker)
50
51 //_____________________________________________________________________________
52 AliTOFtracker::AliTOFtracker(AliTOFGeometry * geom, Double_t parPID[2]):
53   fGeom(geom),
54   fTOFpid(new AliTOFpidESD(parPID)),
55   fHoles(kFALSE),
56   fN(0),
57   fNseeds(0),
58   fNseedsTOF(0),
59   fngoodmatch(0),
60   fnbadmatch(0),
61   fnunmatch(0),
62   fnmatch(0),
63   fR(378.), 
64   fTOFHeigth(15.3),  
65   fdCut(3.), 
66   fDx(1.5), 
67   fDy(0), 
68   fDz(0), 
69   fDzMax(35.), 
70   fDyMax(50.), 
71   fTracks(0x0),
72   fSeeds(0x0)
73  { 
74   //AliTOFtracker main Ctor
75
76   fDy=AliTOFGeometry::XPad(); 
77   fDz=AliTOFGeometry::ZPad(); 
78 }
79 //_____________________________________________________________________________
80 AliTOFtracker::AliTOFtracker(const AliTOFtracker &t):
81   AliTracker(),
82   fGeom(0x0),
83   fTOFpid(0x0),
84   fHoles(kFALSE),
85   fN(0),
86   fNseeds(0),
87   fNseedsTOF(0),
88   fngoodmatch(0),
89   fnbadmatch(0),
90   fnunmatch(0),
91   fnmatch(0),
92   fR(378.), 
93   fTOFHeigth(15.3),  
94   fdCut(3.), 
95   fDx(1.5), 
96   fDy(0), 
97   fDz(0), 
98   fDzMax(35.), 
99   fDyMax(50.), 
100   fTracks(0x0),
101   fSeeds(0x0)
102  { 
103   //AliTOFtracker copy Ctor
104
105   fHoles=t.fHoles;
106   fNseeds=t.fNseeds;
107   fNseedsTOF=t.fNseedsTOF;
108   fngoodmatch=t.fngoodmatch;
109   fnbadmatch=t.fnbadmatch;
110   fnunmatch=t.fnunmatch;
111   fnmatch=t.fnmatch;
112   fGeom = t.fGeom;
113   fTOFpid = t.fTOFpid;
114   fR=t.fR; 
115   fTOFHeigth=t.fTOFHeigth;  
116   fdCut=t.fdCut; 
117   fDy=t.fDy; 
118   fDz=t.fDz; 
119   fDx=t.fDx; 
120   fDzMax=t.fDzMax; 
121   fDyMax=t.fDyMax; 
122   fSeeds=t.fSeeds;
123   fTracks=t.fTracks;
124   fN=t.fN;
125 }
126
127 //_____________________________________________________________________________
128 AliTOFtracker& AliTOFtracker::operator=(const AliTOFtracker &t)
129
130   //AliTOFtracker assignment operator
131
132   this->fHoles=t.fHoles;
133   this->fNseeds=t.fNseeds;
134   this->fNseedsTOF=t.fNseedsTOF;
135   this->fngoodmatch=t.fngoodmatch;
136   this->fnbadmatch=t.fnbadmatch;
137   this->fnunmatch=t.fnunmatch;
138   this->fnmatch=t.fnmatch;
139   this->fGeom = t.fGeom;
140   this->fTOFpid = t.fTOFpid;
141   this->fR=t.fR; 
142   this->fTOFHeigth=t.fTOFHeigth;  
143   this->fdCut=t.fdCut; 
144   this->fDy=t.fDy; 
145   this->fDz=t.fDz; 
146   this->fDx=t.fDx; 
147   this->fDzMax=t.fDzMax; 
148   this->fDyMax=t.fDyMax; 
149   this->fSeeds=t.fSeeds;
150   this->fTracks=t.fTracks;
151   this->fN=t.fN;
152   return *this;
153
154 }
155
156 //_____________________________________________________________________________
157 Int_t AliTOFtracker::PropagateBack(AliESD* event) {
158   //
159   // Gets seeds from ESD event and Match with TOF Clusters
160   //
161
162
163   //Initialise some counters
164
165   fNseeds=0;
166   fNseedsTOF=0;
167   fngoodmatch=0;
168   fnbadmatch=0;
169   fnunmatch=0;
170   fnmatch=0;
171
172   Int_t ntrk=event->GetNumberOfTracks();
173   fNseeds = ntrk;
174   fSeeds= new TClonesArray("AliESDtrack",ntrk);
175   TClonesArray &aESDTrack = *fSeeds;
176
177
178   //Load ESD tracks into a local Array of ESD Seeds
179
180   for (Int_t i=0; i<fNseeds; i++) {
181     AliESDtrack *t=event->GetTrack(i);
182     new(aESDTrack[i]) AliESDtrack(*t);
183   }
184
185   //Prepare ESD tracks candidates for TOF Matching
186   CollectESD();
187
188   //First Step with Strict Matching Criterion
189   MatchTracks(kFALSE);
190   /*
191   for (Int_t ijk=0; ijk<fN; ijk++) {
192     AliInfo(Form("%4i %4i  %f %f %f  %f %f   %2i %1i %2i %1i %2i",ijk, fClusters[ijk]->GetIndex(),fClusters[ijk]->GetZ(),fClusters[ijk]->GetR(),fClusters[ijk]->GetPhi(), fClusters[ijk]->GetTDC(),fClusters[ijk]->GetADC(),fClusters[ijk]->GetDetInd(0),fClusters[ijk]->GetDetInd(1),fClusters[ijk]->GetDetInd(2),fClusters[ijk]->GetDetInd(3),fClusters[ijk]->GetDetInd(4)));
193   }
194   */
195
196   //Second Step with Looser Matching Criterion
197   MatchTracks(kTRUE);
198
199   AliInfo(Form("Number of matched tracks: %d",fnmatch));
200   AliInfo(Form("Number of good matched tracks: %d",fngoodmatch));
201   AliInfo(Form("Number of bad  matched tracks: %d",fnbadmatch));
202
203   //Update the matched ESD tracks
204
205   for (Int_t i=0; i<ntrk; i++) {
206     AliESDtrack *t=event->GetTrack(i);
207     AliESDtrack *seed =(AliESDtrack*)fSeeds->UncheckedAt(i);
208     if(seed->GetTOFsignal()>0){
209       t->SetTOFsignal(seed->GetTOFsignal());
210       t->SetTOFcluster(seed->GetTOFcluster());
211       t->SetTOFsignalToT(seed->GetTOFsignalToT());
212       t->SetTOFCalChannel(seed->GetTOFCalChannel());
213       Int_t tlab[3]; seed->GetTOFLabel(tlab);    
214       t->SetTOFLabel(tlab);
215       AliTOFtrack *track = new AliTOFtrack(*seed); 
216       t->UpdateTrackParams(track,AliESDtrack::kTOFout);   
217       delete track;
218     }
219   }
220
221
222   //Make TOF PID
223   fTOFpid->MakePID(event);
224
225   if (fSeeds) {
226     fSeeds->Delete();
227     delete fSeeds;
228     fSeeds = 0x0;
229   }
230   if (fTracks) {
231     fTracks->Delete();
232     delete fTracks;
233     fTracks = 0x0;
234   }
235   return 0;
236   
237 }
238 //_________________________________________________________________________
239 void AliTOFtracker::CollectESD() {
240    //prepare the set of ESD tracks to be matched to clusters in TOF
241  
242   fTracks= new TClonesArray("AliTOFtrack");
243   TClonesArray &aTOFTrack = *fTracks;
244   for (Int_t i=0; i<fNseeds; i++) {
245
246     AliESDtrack *t =(AliESDtrack*)fSeeds->UncheckedAt(i);
247     if ((t->GetStatus()&AliESDtrack::kTPCout)==0)continue;
248
249     // TRD good tracks, already propagated at 371 cm
250
251     AliTOFtrack *track = new AliTOFtrack(*t); // New
252     Double_t x = track->GetX(); //New
253
254     if (((t->GetStatus()&AliESDtrack::kTRDout)!=0 ) && 
255          ( x >= fGeom->RinTOF()) ){
256       track->SetSeedIndex(i);
257       t->UpdateTrackParams(track,AliESDtrack::kTOFout);    
258       new(aTOFTrack[fNseedsTOF]) AliTOFtrack(*track);
259       fNseedsTOF++;
260       delete track;
261     }
262
263     // Propagate the rest of TPCbp  
264
265     else {
266       if(track->PropagateToInnerTOF(fHoles)){ // temporary solution
267         //      if(track->PropagateToInnerTOF(fGeom->GetHoles())){
268         track->SetSeedIndex(i);
269         t->UpdateTrackParams(track,AliESDtrack::kTOFout);    
270         new(aTOFTrack[fNseedsTOF]) AliTOFtrack(*track);
271         fNseedsTOF++;
272       }
273       delete track;
274     }
275   }
276
277   AliInfo(Form("Number of TOF seedds %i",fNseedsTOF));
278
279   // Sort according uncertainties on track position 
280   fTracks->Sort();
281
282 }
283 //_________________________________________________________________________
284 void AliTOFtracker::MatchTracks( Bool_t mLastStep){
285
286   //Match ESD tracks to clusters in TOF
287
288
289   Int_t nSteps=(Int_t)(fTOFHeigth/0.1);
290
291   AliTOFcalib *calib = new AliTOFcalib(fGeom);
292   //PH Arrays (moved outside of the loop)
293   Float_t * trackPos[4];
294   for (Int_t ii=0; ii<4; ii++) trackPos[ii] = new Float_t[nSteps];
295   Int_t * clind[6];
296   for (Int_t ii=0;ii<6;ii++) clind[ii] = new Int_t[fN];
297   
298   for (Int_t iseed=0; iseed<fNseedsTOF; iseed++) {
299
300     AliTOFtrack *track =(AliTOFtrack*)fTracks->UncheckedAt(iseed);
301     AliESDtrack *t =(AliESDtrack*)fSeeds->UncheckedAt(track->GetSeedIndex());
302     if(t->GetTOFsignal()>0. ) continue;
303     AliTOFtrack *trackTOFin =new AliTOFtrack(*track);
304
305     // Some init
306
307     Int_t         index[10000];
308     Float_t        dist[10000];
309     Float_t       cxpos[10000];
310     Float_t       crecL[10000];
311     TGeoHMatrix   global[1000];
312      
313     // Determine a window around the track
314
315     Double_t x,par[5]; 
316     trackTOFin->GetExternalParameters(x,par);
317     Double_t cov[15]; 
318     trackTOFin->GetExternalCovariance(cov);
319
320     Float_t scalefact=3.;    
321     Double_t dphi=
322       scalefact*
323       ((5*TMath::Sqrt(cov[0]) + 0.5*fDy + 2.5*TMath::Abs(par[2]))/fR); 
324     Double_t dz=
325       scalefact*
326       (5*TMath::Sqrt(cov[2]) + 0.5*fDz + 2.5*TMath::Abs(par[3]));
327
328     Double_t phi=TMath::ATan2(par[0],x) + trackTOFin->GetAlpha();
329     if (phi<-TMath::Pi())phi+=2*TMath::Pi();
330     if (phi>=TMath::Pi())phi-=2*TMath::Pi();
331     Double_t z=par[1];   
332
333     //upper limit on window's size.
334
335     if(dz> fDzMax) dz=fDzMax;
336     if(dphi*fR>fDyMax) dphi=fDyMax/fR;
337
338
339     Int_t nc=0;
340
341     // find the clusters in the window of the track
342
343     for (Int_t k=FindClusterIndex(z-dz); k<fN; k++) {
344
345       AliTOFcluster *c=fClusters[k];
346       if (c->GetZ() > z+dz) break;
347       if (c->IsUsed()) continue;
348
349       if (!c->GetStatus()) continue; // skip bad channels as declared in OCDB
350       
351       //AliInfo(Form(" fClusters[k]->GetZ() (%f) z-dz (%f)   %4i ", fClusters[k]->GetZ(), z-dz, k));
352
353       Double_t dph=TMath::Abs(c->GetPhi()-phi);
354       if (dph>TMath::Pi()) dph-=2.*TMath::Pi();
355       if (TMath::Abs(dph)>dphi) continue;
356
357       {
358         //Double_t maxChi2=150.; // "calibration constant". Needs to be tuned.
359       Double_t yc=(c->GetPhi() - trackTOFin->GetAlpha())*c->GetR();
360       Double_t p[2]={yc, c->GetZ()};
361       Double_t cov[3]={fDy*fDy/12., 0., fDz*fDz/12.};
362       if (trackTOFin->AliExternalTrackParam::GetPredictedChi2(p,cov) > 150.) 
363          continue;
364       }
365
366       clind[0][nc] = c->GetDetInd(0);
367       clind[1][nc] = c->GetDetInd(1);
368       clind[2][nc] = c->GetDetInd(2);
369       clind[3][nc] = c->GetDetInd(3);
370       clind[4][nc] = c->GetDetInd(4);
371       clind[5][nc] = k;      
372       Char_t path[100];
373       Int_t ind[5];
374       ind[0]=clind[0][nc];
375       ind[1]=clind[1][nc];
376       ind[2]=clind[2][nc];
377       ind[3]=clind[3][nc];
378       ind[4]=clind[4][nc];
379       fGeom->GetVolumePath(ind,path);
380       gGeoManager->cd(path);
381       global[nc] = *gGeoManager->GetCurrentMatrix();
382       nc++;
383     }
384
385     //if (nc) AliInfo(Form("seed for TOF %4i and number of clusters in the track window %4i (cluster index %4i)     %4i",i,nc, clind[5][0], fN));
386
387     //start fine propagation 
388
389     Int_t nStepsDone = 0;
390     for( Int_t istep=0; istep<nSteps; istep++){ 
391
392       Float_t xs=fGeom->RinTOF()+istep*0.1;
393       Double_t ymax=xs*TMath::Tan(0.5*AliTOFGeometry::GetAlpha());
394
395       Bool_t skip=kFALSE;
396       Double_t ysect=trackTOFin->GetYat(xs,skip);
397       if (skip) break;
398       if (ysect > ymax) {
399         if (!trackTOFin->Rotate(AliTOFGeometry::GetAlpha())) {
400           break;
401         }
402       } else if (ysect <-ymax) {
403         if (!trackTOFin->Rotate(-AliTOFGeometry::GetAlpha())) {
404           break;
405         }
406       }
407
408       if(!trackTOFin->PropagateTo(xs)) {
409         break;
410       }
411
412       nStepsDone++;
413
414       // store the running point (Globalrf) - fine propagation     
415
416       Double_t r[3];
417       trackTOFin->GetXYZ(r);
418       trackPos[0][istep]= (Float_t) r[0];
419       trackPos[1][istep]= (Float_t) r[1];
420       trackPos[2][istep]= (Float_t) r[2];   
421       trackPos[3][istep]= trackTOFin->GetIntegratedLength();
422     }
423
424
425     Int_t nfound = 0;
426     for (Int_t istep=0; istep<nStepsDone; istep++) {
427
428       Bool_t isInside =kFALSE;
429       Float_t ctrackPos[3];     
430
431       ctrackPos[0]= trackPos[0][istep];
432       ctrackPos[1]= trackPos[1][istep];
433       ctrackPos[2]= trackPos[2][istep];
434
435       //now see whether the track matches any of the TOF clusters            
436
437       for (Int_t i=0; i<nc; i++){
438         Int_t cind[5];
439         cind[0]= clind[0][i];
440         cind[1]= clind[1][i];
441         cind[2]= clind[2][i];
442         cind[3]= clind[3][i];
443         cind[4]= clind[4][i];
444         Bool_t accept = kFALSE;
445         if( mLastStep)accept = (fGeom->DistanceToPad(cind,global[i],ctrackPos)<fdCut);
446         if(!mLastStep)accept = (fGeom->IsInsideThePad(cind,global[i],ctrackPos));
447         if(accept){
448           if(!mLastStep)isInside=kTRUE;
449           dist[nfound]=fGeom->DistanceToPad(cind,global[i],ctrackPos);
450           crecL[nfound]=trackPos[3][istep];
451           index[nfound]=clind[5][i]; // store cluster id            
452           cxpos[nfound]=fGeom->RinTOF()+istep*0.1; //store prop.radius
453           nfound++;
454           if(isInside)break;
455         }//end if accept
456       } //end for on the clusters
457
458
459       if(isInside)break;
460     } //end for on the steps     
461
462
463
464     if (nfound == 0 ) {
465       fnunmatch++;
466       delete trackTOFin;
467       continue;
468     }
469     
470     fnmatch++;
471
472     // now choose the cluster to be matched with the track.
473
474     Int_t idclus=0;
475     Float_t  recL = 0.;
476     Float_t  xpos=0.;
477     Float_t  mindist=1000.;
478     for (Int_t iclus= 0; iclus<nfound;iclus++){
479       if (dist[iclus]< mindist){
480         mindist = dist[iclus];
481         xpos = cxpos[iclus];
482         idclus =index[iclus]; 
483         recL=crecL[iclus]+fDx*0.5;
484       }
485     }
486
487     AliTOFcluster *c=fClusters[idclus];
488     c->Use(); //AliInfo(Form("I am using the cluster"));
489
490     // Track length correction for matching Step 2 
491
492     if(mLastStep){
493       Float_t rc=TMath::Sqrt(c->GetR()*c->GetR() + c->GetZ()*c->GetZ());
494       Float_t rt=TMath::Sqrt(trackPos[0][70]*trackPos[0][70]
495                              +trackPos[1][70]*trackPos[1][70]
496                              +trackPos[2][70]*trackPos[2][70]);
497       Float_t dlt=rc-rt;      
498       recL=trackPos[3][70]+dlt;
499     }    
500
501     if (
502         (c->GetLabel(0)==TMath::Abs(trackTOFin->GetLabel()))
503         ||
504         (c->GetLabel(1)==TMath::Abs(trackTOFin->GetLabel()))
505         ||
506         (c->GetLabel(2)==TMath::Abs(trackTOFin->GetLabel()))
507         ) {
508       fngoodmatch++;
509
510       //AliInfo(Form(" track label good %5i",trackTOFin->GetLabel()));
511
512     }
513     else{
514       fnbadmatch++;
515
516       //AliInfo(Form(" track label  bad %5i",trackTOFin->GetLabel()));
517
518     }
519
520     delete trackTOFin;
521
522     //  Store quantities to be used in the TOF Calibration
523     Float_t tToT=c->GetToT(); // in ps
524     t->SetTOFsignalToT(tToT);
525     Int_t ind[5];
526     ind[0]=c->GetDetInd(0);
527     ind[1]=c->GetDetInd(1);
528     ind[2]=c->GetDetInd(2);
529     ind[3]=c->GetDetInd(3);
530     ind[4]=c->GetDetInd(4);
531     Int_t calindex = calib->GetIndex(ind);
532     t->SetTOFCalChannel(calindex);
533
534     // keep track of the track labels in the matched cluster
535     Int_t tlab[3];
536     tlab[0]=c->GetLabel(0);
537     tlab[1]=c->GetLabel(1);
538     tlab[2]=c->GetLabel(2);
539     
540     Double_t tof=AliTOFGeometry::TdcBinWidth()*c->GetTDC()+32; // in ps
541     t->SetTOFsignal(tof);
542     //t->SetTOFcluster(c->GetIndex()); // pointing to the digits tree
543     t->SetTOFcluster(idclus); // pointing to the recPoints tree
544     Double_t time[10]; t->GetIntegratedTimes(time);
545     Double_t mom=t->GetP();
546     for(Int_t j=0;j<=AliPID::kSPECIES;j++){
547       Double_t mass=AliPID::ParticleMass(j);
548       time[j]+=(recL-trackPos[3][0])/3e-2*TMath::Sqrt(mom*mom+mass*mass)/mom;
549     }
550
551     AliTOFtrack *trackTOFout = new AliTOFtrack(*t); 
552     trackTOFout->PropagateTo(xpos);
553     t->UpdateTrackParams(trackTOFout,AliESDtrack::kTOFout);    
554     t->SetIntegratedLength(recL);
555     t->SetIntegratedTimes(time);
556     t->SetTOFLabel(tlab);
557
558     delete trackTOFout;
559   }
560   for (Int_t ii=0; ii<4; ii++) delete [] trackPos[ii];
561   for (Int_t ii=0;ii<6;ii++) delete [] clind[ii];
562   delete calib;
563 }
564 //_________________________________________________________________________
565 Int_t AliTOFtracker::LoadClusters(TTree *cTree) {
566   //--------------------------------------------------------------------
567   //This function loads the TOF clusters
568   //--------------------------------------------------------------------
569
570   TBranch *branch=cTree->GetBranch("TOF");
571   if (!branch) { 
572     AliError("can't get the branch with the TOF clusters !");
573     return 1;
574   }
575
576   TClonesArray dummy("AliTOFcluster",10000), *clusters=&dummy;
577   branch->SetAddress(&clusters);
578
579   cTree->GetEvent(0);
580   Int_t nc=clusters->GetEntriesFast();
581   AliInfo(Form("Number of clusters: %d",nc));
582
583   for (Int_t i=0; i<nc; i++) {
584     AliTOFcluster *c=(AliTOFcluster*)clusters->UncheckedAt(i);
585     fClusters[i]=new AliTOFcluster(*c); fN++;
586     //AliInfo(Form("%4i %4i  %f %f %f  %f %f   %2i %1i %2i %1i %2i",i, fClusters[i]->GetIndex(),fClusters[i]->GetZ(),fClusters[i]->GetR(),fClusters[i]->GetPhi(), fClusters[i]->GetTDC(),fClusters[i]->GetADC(),fClusters[i]->GetDetInd(0),fClusters[i]->GetDetInd(1),fClusters[i]->GetDetInd(2),fClusters[i]->GetDetInd(3),fClusters[i]->GetDetInd(4)));
587     //AliInfo(Form("%i %f",i, fClusters[i]->GetZ()));
588   }
589
590   //AliInfo(Form("Number of clusters: %d",fN));
591
592   return 0;
593 }
594 //_________________________________________________________________________
595 void AliTOFtracker::UnloadClusters() {
596   //--------------------------------------------------------------------
597   //This function unloads TOF clusters
598   //--------------------------------------------------------------------
599   for (Int_t i=0; i<fN; i++) {
600     delete fClusters[i];
601     fClusters[i] = 0x0;
602   }
603   fN=0;
604 }
605
606 //_________________________________________________________________________
607 Int_t AliTOFtracker::FindClusterIndex(Double_t z) const {
608   //--------------------------------------------------------------------
609   // This function returns the index of the nearest cluster 
610   //--------------------------------------------------------------------
611   if (fN==0) return 0;
612   if (z <= fClusters[0]->GetZ()) return 0;
613   if (z > fClusters[fN-1]->GetZ()) return fN;
614   Int_t b=0, e=fN-1, m=(b+e)/2;
615   for (; b<e; m=(b+e)/2) {
616     if (z > fClusters[m]->GetZ()) b=m+1;
617     else e=m; 
618   }
619   return m;
620 }
621
622 //_________________________________________________________________________
623 Bool_t AliTOFtracker::GetTrackPoint(Int_t index, AliTrackPoint& p) const
624 {
625   // Get track space point with index i
626   // Coordinates are in the global system
627   AliTOFcluster *cl = fClusters[index];
628   Float_t xyz[3];
629   xyz[0] = cl->GetR()*TMath::Cos(cl->GetPhi());
630   xyz[1] = cl->GetR()*TMath::Sin(cl->GetPhi());
631   xyz[2] = cl->GetZ();
632   Float_t phiangle = (Int_t(cl->GetPhi()*TMath::RadToDeg()/20.)+0.5)*20.*TMath::DegToRad();
633   Float_t sinphi = TMath::Sin(phiangle), cosphi = TMath::Cos(phiangle);
634   Float_t tiltangle = fGeom->GetAngles(cl->GetDetInd(1),cl->GetDetInd(2))*TMath::DegToRad();
635   Float_t sinth = TMath::Sin(tiltangle), costh = TMath::Cos(tiltangle);
636   Float_t sigmay2 = fGeom->XPad()*fGeom->XPad()/12.;
637   Float_t sigmaz2 = fGeom->ZPad()*fGeom->ZPad()/12.;
638   Float_t cov[6];
639   cov[0] = sinphi*sinphi*sigmay2 + cosphi*cosphi*sinth*sinth*sigmaz2;
640   cov[1] = -sinphi*cosphi*sigmay2 + sinphi*cosphi*sinth*sinth*sigmaz2;
641   cov[2] = -cosphi*sinth*costh*sigmaz2;
642   cov[3] = cosphi*cosphi*sigmay2 + sinphi*sinphi*sinth*sinth*sigmaz2;
643   cov[4] = -sinphi*sinth*costh*sigmaz2;
644   cov[5] = costh*costh*sigmaz2;
645   p.SetXYZ(xyz[0],xyz[1],xyz[2],cov);
646
647   // Detector numbering scheme
648   Int_t nSector = fGeom->NSectors();
649   Int_t nPlate  = fGeom->NPlates();
650   Int_t nStripA = fGeom->NStripA();
651   Int_t nStripB = fGeom->NStripB();
652   Int_t nStripC = fGeom->NStripC();
653
654   Int_t isector = cl->GetDetInd(0);
655   if (isector >= nSector)
656     AliError(Form("Wrong sector number in TOF (%d) !",isector));
657   Int_t iplate = cl->GetDetInd(1);
658   if (iplate >= nPlate)
659     AliError(Form("Wrong plate number in TOF (%d) !",iplate));
660   Int_t istrip = cl->GetDetInd(2);
661
662   Int_t stripOffset = 0;
663   switch (iplate) {
664   case 0:
665     stripOffset = 0;
666     break;
667   case 1:
668     stripOffset = nStripC;
669     break;
670   case 2:
671     stripOffset = nStripC+nStripB;
672     break;
673   case 3:
674     stripOffset = nStripC+nStripB+nStripA;
675     break;
676   case 4:
677     stripOffset = nStripC+nStripB+nStripA+nStripB;
678     break;
679   default:
680     AliError(Form("Wrong plate number in TOF (%d) !",iplate));
681     break;
682   };
683
684   Int_t idet = (2*(nStripC+nStripB)+nStripA)*isector +
685                stripOffset +
686                istrip;
687   UShort_t volid = AliAlignObj::LayerToVolUID(AliAlignObj::kTOF,idet);
688   p.SetVolumeID((UShort_t)volid);
689   return kTRUE;
690 }