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