]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TOF/AliTOFtracker.cxx
Common track parametrization in the barrel detectors (Yu.Belikov)
[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       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       //AliInfo(Form(" fClusters[k]->GetZ() (%f) z-dz (%f)   %4i ", fClusters[k]->GetZ(), z-dz, k));
349
350       Double_t dph=TMath::Abs(c->GetPhi()-phi);
351       if (dph>TMath::Pi()) dph-=2.*TMath::Pi();
352       if (TMath::Abs(dph)>dphi) continue;
353
354       {
355       Double_t maxChi2=150.; // "calibratin constant". Needs to be tuned.
356       Double_t yc=(c->GetPhi() - trackTOFin->GetAlpha())*c->GetR();
357       Double_t p[2]={yc, c->GetZ()};
358       Double_t cov[3]={fDy*fDy/12., 0., fDz*fDz/12.};
359       if (trackTOFin->AliExternalTrackParam::GetPredictedChi2(p,cov) > 150.) 
360          continue;
361       }
362
363       clind[0][nc] = c->GetDetInd(0);
364       clind[1][nc] = c->GetDetInd(1);
365       clind[2][nc] = c->GetDetInd(2);
366       clind[3][nc] = c->GetDetInd(3);
367       clind[4][nc] = c->GetDetInd(4);
368       clind[5][nc] = k;      
369       Char_t path[100];
370       Int_t ind[5];
371       ind[0]=clind[0][nc];
372       ind[1]=clind[1][nc];
373       ind[2]=clind[2][nc];
374       ind[3]=clind[3][nc];
375       ind[4]=clind[4][nc];
376       fGeom->GetVolumePath(ind,path);
377       gGeoManager->cd(path);
378       global[nc] = *gGeoManager->GetCurrentMatrix();
379       nc++;
380     }
381
382     //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));
383
384     //start fine propagation 
385
386     Int_t nStepsDone = 0;
387     for( Int_t istep=0; istep<nSteps; istep++){ 
388
389       Float_t xs=fGeom->RinTOF()+istep*0.1;
390       Double_t ymax=xs*TMath::Tan(0.5*AliTOFGeometry::GetAlpha());
391
392       Bool_t skip=kFALSE;
393       Double_t ysect=trackTOFin->GetYat(xs,skip);
394       if (skip) break;
395       if (ysect > ymax) {
396         if (!trackTOFin->Rotate(AliTOFGeometry::GetAlpha())) {
397           break;
398         }
399       } else if (ysect <-ymax) {
400         if (!trackTOFin->Rotate(-AliTOFGeometry::GetAlpha())) {
401           break;
402         }
403       }
404
405       if(!trackTOFin->PropagateTo(xs)) {
406         break;
407       }
408
409       nStepsDone++;
410
411       // store the running point (Globalrf) - fine propagation     
412
413       Double_t r[3];
414       trackTOFin->GetXYZ(r);
415       trackPos[0][istep]= (Float_t) r[0];
416       trackPos[1][istep]= (Float_t) r[1];
417       trackPos[2][istep]= (Float_t) r[2];   
418       trackPos[3][istep]= trackTOFin->GetIntegratedLength();
419     }
420
421
422     Int_t nfound = 0;
423     for (Int_t istep=0; istep<nStepsDone; istep++) {
424
425       Bool_t isInside =kFALSE;
426       Float_t ctrackPos[3];     
427
428       ctrackPos[0]= trackPos[0][istep];
429       ctrackPos[1]= trackPos[1][istep];
430       ctrackPos[2]= trackPos[2][istep];
431
432       //now see whether the track matches any of the TOF clusters            
433
434       for (Int_t i=0; i<nc; i++){
435         Int_t cind[5];
436         cind[0]= clind[0][i];
437         cind[1]= clind[1][i];
438         cind[2]= clind[2][i];
439         cind[3]= clind[3][i];
440         cind[4]= clind[4][i];
441         Bool_t accept = kFALSE;
442         if( mLastStep)accept = (fGeom->DistanceToPad(cind,global[i],ctrackPos)<fdCut);
443         if(!mLastStep)accept = (fGeom->IsInsideThePad(cind,global[i],ctrackPos));
444         if(accept){
445           if(!mLastStep)isInside=kTRUE;
446           dist[nfound]=fGeom->DistanceToPad(cind,global[i],ctrackPos);
447           crecL[nfound]=trackPos[3][istep];
448           index[nfound]=clind[5][i]; // store cluster id            
449           cxpos[nfound]=fGeom->RinTOF()+istep*0.1; //store prop.radius
450           nfound++;
451           if(isInside)break;
452         }//end if accept
453       } //end for on the clusters
454
455
456       if(isInside)break;
457     } //end for on the steps     
458
459
460
461     if (nfound == 0 ) {
462       fnunmatch++;
463       delete trackTOFin;
464       continue;
465     }
466     
467     fnmatch++;
468
469     // now choose the cluster to be matched with the track.
470
471     Int_t idclus=0;
472     Float_t  recL = 0.;
473     Float_t  xpos=0.;
474     Float_t  mindist=1000.;
475     for (Int_t iclus= 0; iclus<nfound;iclus++){
476       if (dist[iclus]< mindist){
477         mindist = dist[iclus];
478         xpos = cxpos[iclus];
479         idclus =index[iclus]; 
480         recL=crecL[iclus]+fDx*0.5;
481       }
482     }
483
484     AliTOFcluster *c=fClusters[idclus];
485     c->Use(); //AliInfo(Form("I am using the cluster"));
486
487     // Track length correction for matching Step 2 
488
489     if(mLastStep){
490       Float_t rc=TMath::Sqrt(c->GetR()*c->GetR() + c->GetZ()*c->GetZ());
491       Float_t rt=TMath::Sqrt(trackPos[0][70]*trackPos[0][70]
492                              +trackPos[1][70]*trackPos[1][70]
493                              +trackPos[2][70]*trackPos[2][70]);
494       Float_t dlt=rc-rt;      
495       recL=trackPos[3][70]+dlt;
496     }    
497
498     if (
499         (c->GetLabel(0)==TMath::Abs(trackTOFin->GetLabel()))
500         ||
501         (c->GetLabel(1)==TMath::Abs(trackTOFin->GetLabel()))
502         ||
503         (c->GetLabel(2)==TMath::Abs(trackTOFin->GetLabel()))
504         ) {
505       fngoodmatch++;
506
507       //AliInfo(Form(" track label good %5i",trackTOFin->GetLabel()));
508
509     }
510     else{
511       fnbadmatch++;
512
513       //AliInfo(Form(" track label  bad %5i",trackTOFin->GetLabel()));
514
515     }
516
517     delete trackTOFin;
518
519     //  Store quantities to be used in the TOF Calibration
520     Float_t tToT=c->GetToT(); // in ps
521     t->SetTOFsignalToT(tToT);
522     Int_t ind[5];
523     ind[0]=c->GetDetInd(0);
524     ind[1]=c->GetDetInd(1);
525     ind[2]=c->GetDetInd(2);
526     ind[3]=c->GetDetInd(3);
527     ind[4]=c->GetDetInd(4);
528     Int_t calindex = calib->GetIndex(ind);
529     t->SetTOFCalChannel(calindex);
530     
531     Double_t tof=AliTOFGeometry::TdcBinWidth()*c->GetTDC()+32; // in ps
532     t->SetTOFsignal(tof);
533     //t->SetTOFcluster(c->GetIndex()); // pointing to the digits tree
534     t->SetTOFcluster(idclus); // pointing to the recPoints tree
535     Double_t time[10]; t->GetIntegratedTimes(time);
536     Double_t mom=t->GetP();
537     for(Int_t j=0;j<=AliPID::kSPECIES;j++){
538       Double_t mass=AliPID::ParticleMass(j);
539       time[j]+=(recL-trackPos[3][0])/3e-2*TMath::Sqrt(mom*mom+mass*mass)/mom;
540     }
541
542     AliTOFtrack *trackTOFout = new AliTOFtrack(*t); 
543     trackTOFout->PropagateTo(xpos);
544     t->UpdateTrackParams(trackTOFout,AliESDtrack::kTOFout);    
545     t->SetIntegratedLength(recL);
546     t->SetIntegratedTimes(time);
547
548     delete trackTOFout;
549   }
550   for (Int_t ii=0; ii<4; ii++) delete [] trackPos[ii];
551   for (Int_t ii=0;ii<6;ii++) delete [] clind[ii];
552   delete calib;
553 }
554 //_________________________________________________________________________
555 Int_t AliTOFtracker::LoadClusters(TTree *cTree) {
556   //--------------------------------------------------------------------
557   //This function loads the TOF clusters
558   //--------------------------------------------------------------------
559
560   TBranch *branch=cTree->GetBranch("TOF");
561   if (!branch) { 
562     AliError("can't get the branch with the TOF clusters !");
563     return 1;
564   }
565
566   TClonesArray dummy("AliTOFcluster",10000), *clusters=&dummy;
567   branch->SetAddress(&clusters);
568
569   cTree->GetEvent(0);
570   Int_t nc=clusters->GetEntriesFast();
571   AliInfo(Form("Number of clusters: %d",nc));
572
573   for (Int_t i=0; i<nc; i++) {
574     AliTOFcluster *c=(AliTOFcluster*)clusters->UncheckedAt(i);
575     fClusters[i]=new AliTOFcluster(*c); fN++;
576     //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)));
577     //AliInfo(Form("%i %f",i, fClusters[i]->GetZ()));
578   }
579
580   //AliInfo(Form("Number of clusters: %d",fN));
581
582   return 0;
583 }
584 //_________________________________________________________________________
585 void AliTOFtracker::UnloadClusters() {
586   //--------------------------------------------------------------------
587   //This function unloads TOF clusters
588   //--------------------------------------------------------------------
589   for (Int_t i=0; i<fN; i++) {
590     delete fClusters[i];
591     fClusters[i] = 0x0;
592   }
593   fN=0;
594 }
595
596 //_________________________________________________________________________
597 Int_t AliTOFtracker::FindClusterIndex(Double_t z) const {
598   //--------------------------------------------------------------------
599   // This function returns the index of the nearest cluster 
600   //--------------------------------------------------------------------
601   if (fN==0) return 0;
602   if (z <= fClusters[0]->GetZ()) return 0;
603   if (z > fClusters[fN-1]->GetZ()) return fN;
604   Int_t b=0, e=fN-1, m=(b+e)/2;
605   for (; b<e; m=(b+e)/2) {
606     if (z > fClusters[m]->GetZ()) b=m+1;
607     else e=m; 
608   }
609   return m;
610 }
611
612 //_________________________________________________________________________
613 Bool_t AliTOFtracker::GetTrackPoint(Int_t index, AliTrackPoint& p) const
614 {
615   // Get track space point with index i
616   // Coordinates are in the global system
617   AliTOFcluster *cl = fClusters[index];
618   Float_t xyz[3];
619   xyz[0] = cl->GetR()*TMath::Cos(cl->GetPhi());
620   xyz[1] = cl->GetR()*TMath::Sin(cl->GetPhi());
621   xyz[2] = cl->GetZ();
622   Float_t phiangle = (Int_t(cl->GetPhi()*TMath::RadToDeg()/20.)+0.5)*20.*TMath::DegToRad();
623   Float_t sinphi = TMath::Sin(phiangle), cosphi = TMath::Cos(phiangle);
624   Float_t tiltangle = fGeom->GetAngles(cl->GetDetInd(1),cl->GetDetInd(2))*TMath::DegToRad();
625   Float_t sinth = TMath::Sin(tiltangle), costh = TMath::Cos(tiltangle);
626   Float_t sigmay2 = fGeom->XPad()*fGeom->XPad()/12.;
627   Float_t sigmaz2 = fGeom->ZPad()*fGeom->ZPad()/12.;
628   Float_t cov[6];
629   cov[0] = sinphi*sinphi*sigmay2 + cosphi*cosphi*sinth*sinth*sigmaz2;
630   cov[1] = -sinphi*cosphi*sigmay2 + sinphi*cosphi*sinth*sinth*sigmaz2;
631   cov[2] = -cosphi*sinth*costh*sigmaz2;
632   cov[3] = cosphi*cosphi*sigmay2 + sinphi*sinphi*sinth*sinth*sigmaz2;
633   cov[4] = -sinphi*sinth*costh*sigmaz2;
634   cov[5] = costh*costh*sigmaz2;
635   p.SetXYZ(xyz[0],xyz[1],xyz[2],cov);
636
637   // Detector numbering scheme
638   Int_t nSector = fGeom->NSectors();
639   Int_t nPlate  = fGeom->NPlates();
640   Int_t nStripA = fGeom->NStripA();
641   Int_t nStripB = fGeom->NStripB();
642   Int_t nStripC = fGeom->NStripC();
643
644   Int_t isector = cl->GetDetInd(0);
645   if (isector >= nSector)
646     AliError(Form("Wrong sector number in TOF (%d) !",isector));
647   Int_t iplate = cl->GetDetInd(1);
648   if (iplate >= nPlate)
649     AliError(Form("Wrong plate number in TOF (%d) !",iplate));
650   Int_t istrip = cl->GetDetInd(2);
651
652   Int_t stripOffset = 0;
653   switch (iplate) {
654   case 0:
655     stripOffset = 0;
656     break;
657   case 1:
658     stripOffset = nStripC;
659     break;
660   case 2:
661     stripOffset = nStripC+nStripB;
662     break;
663   case 3:
664     stripOffset = nStripC+nStripB+nStripA;
665     break;
666   case 4:
667     stripOffset = nStripC+nStripB+nStripA+nStripB;
668     break;
669   default:
670     AliError(Form("Wrong plate number in TOF (%d) !",iplate));
671     break;
672   };
673
674   Int_t idet = (2*(nStripC+nStripB)+nStripA)*isector +
675                stripOffset +
676                istrip;
677   UShort_t volid = AliAlignObj::LayerToVolUID(AliAlignObj::kTOF,idet);
678   p.SetVolumeID((UShort_t)volid);
679   return kTRUE;
680 }