]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TOF/AliTOFtracker.cxx
updates to comply with AliTOFGeometryV5 becoming AliTOFGeometry and Calibration objects
[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 #include <TROOT.h>
31
32 #include <TClonesArray.h>
33 #include <TGeoManager.h>
34 #include <TTree.h>
35 #include <TFile.h>
36 #include <TH2F.h>
37
38 #include "AliAlignObj.h"
39 #include "AliESDtrack.h"
40 #include "AliESDEvent.h"
41 #include "AliLog.h"
42 #include "AliTrackPointArray.h"
43
44 #include "AliTOFcalib.h"
45 #include "AliTOFRecoParam.h"
46 #include "AliTOFcluster.h"
47 #include "AliTOFGeometry.h"
48 #include "AliTOFtracker.h"
49 #include "AliTOFtrack.h"
50
51 extern TGeoManager *gGeoManager;
52 extern TROOT *gROOT;
53
54 ClassImp(AliTOFtracker)
55
56 //_____________________________________________________________________________
57 AliTOFtracker::AliTOFtracker():
58   fRecoParam(0x0),
59   fGeom(0x0),
60   fPid(0x0),
61   fN(0),
62   fNseeds(0),
63   fNseedsTOF(0),
64   fngoodmatch(0),
65   fnbadmatch(0),
66   fnunmatch(0),
67   fnmatch(0),
68   fTracks(0x0),
69   fSeeds(0x0),
70   fHDigClusMap(0x0),
71   fHDigNClus(0x0),
72   fHDigClusTime(0x0),
73   fHDigClusToT(0x0),
74   fHRecNClus(0x0),
75   fHRecDist(0x0),
76   fHRecSigYVsP(0x0),
77   fHRecSigZVsP(0x0),
78   fHRecSigYVsPWin(0x0),
79   fHRecSigZVsPWin(0x0),
80   fCalTree(0x0),
81   fIch(-1),
82   fToT(-1.),
83   fTime(-1.),
84   fExpTimePi(-1.),
85   fExpTimeKa(-1.),
86   fExpTimePr(-1.)
87  { 
88   //AliTOFtracker main Ctor
89    
90    // Gettimg the geometry 
91    fGeom= new AliTOFGeometry();
92    // Read the reconstruction parameters from the OCDB
93    AliTOFcalib* calib=new AliTOFcalib();
94    fRecoParam = (AliTOFRecoParam*)calib->ReadRecParFromCDB("TOF/Calib",-1);
95    if(fRecoParam->GetApplyPbPbCuts())fRecoParam=fRecoParam->GetPbPbparam();
96    Double_t parPID[2];   
97    parPID[0]=fRecoParam->GetTimeResolution();
98    parPID[1]=fRecoParam->GetTimeNSigma();
99    fPid=new AliTOFpidESD(parPID);
100    InitCheckHists();
101    delete calib;
102 }
103 //_____________________________________________________________________________
104 AliTOFtracker::AliTOFtracker(const AliTOFtracker &t):
105   AliTracker(),
106   fRecoParam(0x0),
107   fGeom(0x0),
108   fPid(0x0),
109   fN(0),
110   fNseeds(0),
111   fNseedsTOF(0),
112   fngoodmatch(0),
113   fnbadmatch(0),
114   fnunmatch(0),
115   fnmatch(0),
116   fTracks(0x0),
117   fSeeds(0x0),
118   fHDigClusMap(0x0),
119   fHDigNClus(0x0),
120   fHDigClusTime(0x0),
121   fHDigClusToT(0x0),
122   fHRecNClus(0x0),
123   fHRecDist(0x0),
124   fHRecSigYVsP(0x0),
125   fHRecSigZVsP(0x0),
126   fHRecSigYVsPWin(0x0),
127   fHRecSigZVsPWin(0x0),
128   fCalTree(0x0),
129   fIch(-1),
130   fToT(-1.),
131   fTime(-1.),
132   fExpTimePi(-1.),
133   fExpTimeKa(-1.),
134   fExpTimePr(-1.)
135  { 
136   //AliTOFtracker copy Ctor
137
138   fNseeds=t.fNseeds;
139   fNseeds=t.fNseeds;
140   fNseedsTOF=t.fNseedsTOF;
141   fngoodmatch=t.fngoodmatch;
142   fnbadmatch=t.fnbadmatch;
143   fnunmatch=t.fnunmatch;
144   fnmatch=t.fnmatch;
145   fRecoParam=t.fRecoParam;
146   fPid=t.fPid;
147   fSeeds=t.fSeeds;
148   fTracks=t.fTracks;
149   fN=t.fN;
150 }
151
152 //_____________________________________________________________________________
153 AliTOFtracker& AliTOFtracker::operator=(const AliTOFtracker &t)
154
155   //AliTOFtracker assignment operator
156
157   this->fNseeds=t.fNseeds;
158   this->fNseedsTOF=t.fNseedsTOF;
159   this->fngoodmatch=t.fngoodmatch;
160   this->fnbadmatch=t.fnbadmatch;
161   this->fnunmatch=t.fnunmatch;
162   this->fnmatch=t.fnmatch;
163   this->fRecoParam = t.fRecoParam;
164   this->fGeom=t.fGeom;
165   this->fPid = t.fPid;
166   this->fSeeds=t.fSeeds;
167   this->fTracks=t.fTracks;
168   this->fN=t.fN;
169   return *this;
170
171 }
172 //_____________________________________________________________________________
173 AliTOFtracker::~AliTOFtracker() {
174   //
175   // Dtor
176   //
177
178   SaveCheckHists();
179
180   delete fRecoParam; 
181   delete fGeom; 
182   delete fPid; 
183   delete fHDigClusMap;
184   delete fHDigNClus;
185   delete fHDigClusTime;
186   delete fHDigClusToT;
187   delete fHRecNClus;
188   delete fHRecDist;
189   delete fHRecSigYVsP;
190   delete fHRecSigZVsP;
191   delete fHRecSigYVsPWin;
192   delete fHRecSigZVsPWin;
193   delete fCalTree;
194 }
195 //_____________________________________________________________________________
196 Int_t AliTOFtracker::PropagateBack(AliESDEvent* event) {
197   //
198   // Gets seeds from ESD event and Match with TOF Clusters
199   //
200
201
202   //Initialise some counters
203
204   fNseeds=0;
205   fNseedsTOF=0;
206   fngoodmatch=0;
207   fnbadmatch=0;
208   fnunmatch=0;
209   fnmatch=0;
210
211   Int_t ntrk=event->GetNumberOfTracks();
212   fNseeds = ntrk;
213   fSeeds= new TClonesArray("AliESDtrack",ntrk);
214   TClonesArray &aESDTrack = *fSeeds;
215
216
217   //Load ESD tracks into a local Array of ESD Seeds
218
219   for (Int_t i=0; i<fNseeds; i++) {
220     AliESDtrack *t=event->GetTrack(i);
221     new(aESDTrack[i]) AliESDtrack(*t);
222   }
223
224   //Prepare ESD tracks candidates for TOF Matching
225   CollectESD();
226
227   //First Step with Strict Matching Criterion
228   MatchTracks(kFALSE);
229
230   //Second Step with Looser Matching Criterion
231   MatchTracks(kTRUE);
232
233   AliInfo(Form("Number of matched tracks: %d",fnmatch));
234   AliInfo(Form("Number of good matched tracks: %d",fngoodmatch));
235   AliInfo(Form("Number of bad  matched tracks: %d",fnbadmatch));
236
237   //Update the matched ESD tracks
238
239   for (Int_t i=0; i<ntrk; i++) {
240     AliESDtrack *t=event->GetTrack(i);
241     AliESDtrack *seed =(AliESDtrack*)fSeeds->UncheckedAt(i);
242     if(seed->GetTOFsignal()>0){
243       t->SetTOFsignal(seed->GetTOFsignal());
244       t->SetTOFcluster(seed->GetTOFcluster());
245       t->SetTOFsignalToT(seed->GetTOFsignalToT());
246       t->SetTOFsignalRaw(seed->GetTOFsignalRaw());
247       t->SetTOFsignalDz(seed->GetTOFsignalDz());
248       t->SetTOFCalChannel(seed->GetTOFCalChannel());
249       Int_t tlab[3]; seed->GetTOFLabel(tlab);    
250       t->SetTOFLabel(tlab);
251       AliTOFtrack *track = new AliTOFtrack(*seed); 
252       t->UpdateTrackParams(track,AliESDtrack::kTOFout);   
253       delete track;
254     }
255   }
256
257   //Handle Time Zero information
258
259   Double_t timeZero=0.;
260   Double_t timeZeroMax=99999.;
261   Bool_t usetimeZero     = fRecoParam->UseTimeZero();
262   Bool_t timeZeroFromT0  = fRecoParam->GetTimeZerofromT0();
263   Bool_t timeZeroFromTOF = fRecoParam->GetTimeZerofromTOF();
264
265   AliDebug(1,Form("Use Time Zero?: %d",usetimeZero));
266   AliDebug(1,Form("Time Zero from T0? : %d",timeZeroFromT0));
267   AliDebug(1,Form("Time Zero From TOF? : %d",timeZeroFromTOF));
268
269   if(usetimeZero){
270     if(timeZeroFromT0){
271       timeZero=GetTimeZerofromT0(event); 
272     }
273     if(timeZeroFromTOF && (timeZero>timeZeroMax || !timeZeroFromT0)){
274       timeZero=GetTimeZerofromTOF(event); 
275     }
276   }
277   AliDebug(2,Form("time Zero used in PID: %f",timeZero));
278   //Make TOF PID
279   fPid->MakePID(event,timeZero);
280
281   if (fSeeds) {
282     fSeeds->Delete();
283     delete fSeeds;
284     fSeeds = 0x0;
285   }
286   if (fTracks) {
287     fTracks->Delete();
288     delete fTracks;
289     fTracks = 0x0;
290   }
291   return 0;
292   
293 }
294 //_________________________________________________________________________
295 void AliTOFtracker::CollectESD() {
296    //prepare the set of ESD tracks to be matched to clusters in TOF
297
298   Int_t seedsTOF1=0;
299   Int_t seedsTOF2=0;
300  
301   fTracks= new TClonesArray("AliTOFtrack");
302   TClonesArray &aTOFTrack = *fTracks;
303   for (Int_t i=0; i<fNseeds; i++) {
304
305     AliESDtrack *t =(AliESDtrack*)fSeeds->UncheckedAt(i);
306     if ((t->GetStatus()&AliESDtrack::kTPCout)==0)continue;
307
308     // TRD 'good' tracks, already propagated at 371 cm
309
310     AliTOFtrack *track = new AliTOFtrack(*t); // New
311     Double_t x = track->GetX(); //New
312     if (((t->GetStatus()&AliESDtrack::kTRDout)!=0 ) && 
313          ( x >= AliTOFGeometry::RinTOF()) ){
314       track->SetSeedIndex(i);
315       t->UpdateTrackParams(track,AliESDtrack::kTOFout);    
316       new(aTOFTrack[fNseedsTOF]) AliTOFtrack(*track);
317       fNseedsTOF++;
318       seedsTOF1++;
319       delete track;
320     }
321
322     // Propagate the rest of TPCbp  
323
324     else {
325       if(track->PropagateToInnerTOF()){ 
326         track->SetSeedIndex(i);
327         t->UpdateTrackParams(track,AliESDtrack::kTOFout);    
328         new(aTOFTrack[fNseedsTOF]) AliTOFtrack(*track);
329         fNseedsTOF++;
330         seedsTOF2++;
331       }
332       delete track;
333     }
334   }
335
336   AliInfo(Form("Number of TOF seeds %i",fNseedsTOF));
337   AliInfo(Form("Number of TOF seeds Type 1 %i",seedsTOF1));
338   AliInfo(Form("Number of TOF seeds Type 2 %i",seedsTOF2));
339
340   // Sort according uncertainties on track position 
341   fTracks->Sort();
342
343 }
344 //_________________________________________________________________________
345 void AliTOFtracker::MatchTracks( Bool_t mLastStep){
346
347
348   // Parameters used/regulating the reconstruction
349
350   static Float_t corrLen=0.75;
351   static Float_t detDepth=15.3;
352   static Float_t padDepth=0.5;
353
354   Float_t dY=AliTOFGeometry::XPad(); 
355   Float_t dZ=AliTOFGeometry::ZPad(); 
356
357   Float_t sensRadius = fRecoParam->GetSensRadius();
358   Float_t stepSize   = fRecoParam->GetStepSize();
359   Float_t scaleFact   = fRecoParam->GetWindowScaleFact();
360   Float_t dyMax=fRecoParam->GetWindowSizeMaxY(); 
361   Float_t dzMax=fRecoParam->GetWindowSizeMaxZ();
362   Float_t dCut=fRecoParam->GetDistanceCut();
363   Double_t maxChi2=fRecoParam->GetMaxChi2TRD();
364   Bool_t timeWalkCorr    = fRecoParam->GetTimeWalkCorr();
365   if(!mLastStep){
366     AliDebug(1,"++++++++++++++TOF Reconstruction Parameters:++++++++++++ \n");
367     AliDebug(1,Form("TOF sens radius: %f",sensRadius));
368     AliDebug(1,Form("TOF step size: %f",stepSize));
369     AliDebug(1,Form("TOF Window scale factor: %f",scaleFact));
370     AliDebug(1,Form("TOF Window max dy: %f",dyMax));
371     AliDebug(1,Form("TOF Window max dz: %f",dzMax));
372     AliDebug(1,Form("TOF distance Cut: %f",dCut));
373     AliDebug(1,Form("TOF Max Chi2: %f",maxChi2));
374     AliDebug(1,Form("Time Walk Correction? : %d",timeWalkCorr));   
375   }
376   //Match ESD tracks to clusters in TOF
377
378
379   // Get the number of propagation steps
380
381   Int_t nSteps=(Int_t)(detDepth/stepSize);
382
383   //PH Arrays (moved outside of the loop)
384
385   Float_t * trackPos[4];
386   for (Int_t ii=0; ii<4; ii++) trackPos[ii] = new Float_t[nSteps];
387   Int_t * clind[6];
388   for (Int_t ii=0;ii<6;ii++) clind[ii] = new Int_t[fN];
389   
390   for (Int_t iseed=0; iseed<fNseedsTOF; iseed++) {
391
392     AliTOFtrack *track =(AliTOFtrack*)fTracks->UncheckedAt(iseed);
393     AliESDtrack *t =(AliESDtrack*)fSeeds->UncheckedAt(track->GetSeedIndex());
394     if(t->GetTOFsignal()>0. ) continue;
395     AliTOFtrack *trackTOFin =new AliTOFtrack(*track);
396
397     // Some init
398
399     Int_t         index[10000];
400     Float_t        dist[10000];
401     Float_t       distZ[10000];
402     Float_t       cxpos[10000];
403     Float_t       crecL[10000];
404     TGeoHMatrix   global[1000];
405      
406     // Determine a window around the track
407
408     Double_t x,par[5]; 
409     trackTOFin->GetExternalParameters(x,par);
410     Double_t cov[15]; 
411     trackTOFin->GetExternalCovariance(cov);
412
413     Double_t dphi=
414       scaleFact*
415       ((5*TMath::Sqrt(cov[0]) + 0.5*dY + 2.5*TMath::Abs(par[2]))/sensRadius); 
416     Double_t dz=
417        scaleFact*
418        (5*TMath::Sqrt(cov[2]) + 0.5*dZ + 2.5*TMath::Abs(par[3]));
419
420     Double_t phi=TMath::ATan2(par[0],x) + trackTOFin->GetAlpha();
421     if (phi<-TMath::Pi())phi+=2*TMath::Pi();
422     if (phi>=TMath::Pi())phi-=2*TMath::Pi();
423     Double_t z=par[1];   
424
425     //upper limit on window's size.
426
427     if(dz> dzMax) dz=dzMax;
428     if(dphi*sensRadius> dyMax) dphi=dyMax/sensRadius;
429
430
431     Int_t nc=0;
432
433     // find the clusters in the window of the track
434
435     for (Int_t k=FindClusterIndex(z-dz); k<fN; k++) {
436
437       AliTOFcluster *c=fClusters[k];
438       if (c->GetZ() > z+dz) break;
439       if (c->IsUsed()) continue;
440
441       if (!c->GetStatus()) continue; // skip bad channels as declared in OCDB
442
443       Double_t dph=TMath::Abs(c->GetPhi()-phi);
444       if (dph>TMath::Pi()) dph-=2.*TMath::Pi();
445       if (TMath::Abs(dph)>dphi) continue;
446
447       Double_t yc=(c->GetPhi() - trackTOFin->GetAlpha())*c->GetR();
448       Double_t p[2]={yc, c->GetZ()};
449       Double_t cov[3]= {dY*dY/12., 0., dZ*dZ/12.};
450       if (trackTOFin->AliExternalTrackParam::GetPredictedChi2(p,cov) > maxChi2)continue;
451
452       clind[0][nc] = c->GetDetInd(0);
453       clind[1][nc] = c->GetDetInd(1);
454       clind[2][nc] = c->GetDetInd(2);
455       clind[3][nc] = c->GetDetInd(3);
456       clind[4][nc] = c->GetDetInd(4);
457       clind[5][nc] = k;      
458       Char_t path[100];
459       Int_t ind[5];
460       ind[0]=clind[0][nc];
461       ind[1]=clind[1][nc];
462       ind[2]=clind[2][nc];
463       ind[3]=clind[3][nc];
464       ind[4]=clind[4][nc];
465       fGeom->GetVolumePath(ind,path);
466       gGeoManager->cd(path);
467       global[nc] = *gGeoManager->GetCurrentMatrix();
468       nc++;
469     }
470
471     //start fine propagation 
472
473     Int_t nStepsDone = 0;
474     for( Int_t istep=0; istep<nSteps; istep++){ 
475
476       Float_t xs=AliTOFGeometry::RinTOF()+istep*0.1;
477       Double_t ymax=xs*TMath::Tan(0.5*AliTOFGeometry::GetAlpha());
478
479       Bool_t skip=kFALSE;
480       Double_t ysect=trackTOFin->GetYat(xs,skip);
481       if (skip) break;
482       if (ysect > ymax) {
483         if (!trackTOFin->Rotate(AliTOFGeometry::GetAlpha())) {
484           break;
485         }
486       } else if (ysect <-ymax) {
487         if (!trackTOFin->Rotate(AliTOFGeometry::GetAlpha())) {
488           break;
489         }
490       }
491
492       if(!trackTOFin->PropagateTo(xs)) {
493         break;
494       }
495
496       nStepsDone++;
497
498       // store the running point (Globalrf) - fine propagation     
499
500       Double_t r[3];
501       trackTOFin->GetXYZ(r);
502       trackPos[0][istep]= (Float_t) r[0];
503       trackPos[1][istep]= (Float_t) r[1];
504       trackPos[2][istep]= (Float_t) r[2];   
505       trackPos[3][istep]= trackTOFin->GetIntegratedLength();
506     }
507
508
509     Int_t nfound = 0;
510     Bool_t accept = kFALSE;
511     Bool_t isInside =kFALSE;
512     for (Int_t istep=0; istep<nStepsDone; istep++) {
513
514       Float_t ctrackPos[3];     
515
516       ctrackPos[0]= trackPos[0][istep];
517       ctrackPos[1]= trackPos[1][istep];
518       ctrackPos[2]= trackPos[2][istep];
519
520       //now see whether the track matches any of the TOF clusters            
521
522       Float_t dist3d[3];
523       accept=kFALSE;
524       for (Int_t i=0; i<nc; i++){
525         Int_t cind[5];
526         cind[0]= clind[0][i];
527         cind[1]= clind[1][i];
528         cind[2]= clind[2][i];
529         cind[3]= clind[3][i];
530         cind[4]= clind[4][i];
531         isInside=fGeom->IsInsideThePad(global[i],ctrackPos,dist3d);
532
533         if( mLastStep){
534           Float_t xLoc=dist3d[0];
535           Float_t rLoc=TMath::Sqrt(dist3d[1]*dist3d[1]+dist3d[2]*dist3d[2]);
536           accept = (TMath::Abs(xLoc)<padDepth*0.5 && rLoc<dCut);
537         }
538         else{
539           accept = isInside;
540         }
541         if(accept){
542           dist[nfound]=TMath::Sqrt(dist3d[0]*dist3d[0]+dist3d[1]*dist3d[1]+dist3d[2]*dist3d[2]);
543           distZ[nfound]=dist3d[2];
544           crecL[nfound]=trackPos[3][istep];
545           index[nfound]=clind[5][i]; // store cluster id            
546           cxpos[nfound]=AliTOFGeometry::RinTOF()+istep*0.1; //store prop.radius
547           nfound++;
548           if(accept &&!mLastStep)break;
549         }//end if accept
550       } //end for on the clusters
551       if(accept &&!mLastStep)break;
552     } //end for on the steps     
553
554
555
556     if (nfound == 0 ) {
557       fnunmatch++;
558       delete trackTOFin;
559       continue;
560     }
561     
562     fnmatch++;
563
564     // now choose the cluster to be matched with the track.
565
566     Int_t idclus=0;
567     Float_t  recL = 0.;
568     Float_t  xpos=0.;
569     Float_t  mindist=1000.;
570     Float_t  mindistZ=0.;
571     for (Int_t iclus= 0; iclus<nfound;iclus++){
572       if (dist[iclus]< mindist){
573         mindist = dist[iclus];
574         mindistZ = distZ[iclus];
575         xpos = cxpos[iclus];
576         idclus =index[iclus]; 
577         recL=crecL[iclus]+corrLen*0.5;
578       }
579     }
580
581
582     AliTOFcluster *c=fClusters[idclus];
583     c->Use(); 
584
585     // Track length correction for matching Step 2 
586
587     if(mLastStep){
588       Float_t rc=TMath::Sqrt(c->GetR()*c->GetR() + c->GetZ()*c->GetZ());
589       Float_t rt=TMath::Sqrt(trackPos[0][70]*trackPos[0][70]
590                              +trackPos[1][70]*trackPos[1][70]
591                              +trackPos[2][70]*trackPos[2][70]);
592       Float_t dlt=rc-rt;      
593       recL=trackPos[3][70]+dlt;
594     }    
595
596     if (
597         (c->GetLabel(0)==TMath::Abs(trackTOFin->GetLabel()))
598         ||
599         (c->GetLabel(1)==TMath::Abs(trackTOFin->GetLabel()))
600         ||
601         (c->GetLabel(2)==TMath::Abs(trackTOFin->GetLabel()))
602         ) {
603       fngoodmatch++;
604
605        AliDebug(2,Form(" track label good %5i",trackTOFin->GetLabel()));
606
607     }
608     else{
609       fnbadmatch++;
610
611       AliDebug(2,Form(" track label  bad %5i",trackTOFin->GetLabel()));
612
613     }
614
615     delete trackTOFin;
616
617     //  Store quantities to be used in the TOF Calibration
618     Float_t tToT=AliTOFGeometry::ToTBinWidth()*c->GetToT()*1E-3; // in ns
619     t->SetTOFsignalToT(tToT);
620     Float_t rawTime=AliTOFGeometry::TdcBinWidth()*c->GetTDCRAW()+32; // RAW time,in ps
621     t->SetTOFsignalRaw(rawTime);
622     t->SetTOFsignalDz(mindistZ);
623     AliDebug(2,Form(" Setting TOF raw time: %f, z distance: %f time: %f = ",rawTime,mindistZ));    
624     Int_t ind[5];
625     ind[0]=c->GetDetInd(0);
626     ind[1]=c->GetDetInd(1);
627     ind[2]=c->GetDetInd(2);
628     ind[3]=c->GetDetInd(3);
629     ind[4]=c->GetDetInd(4);
630     Int_t calindex = AliTOFGeometry::GetIndex(ind);
631     t->SetTOFCalChannel(calindex);
632
633     // keep track of the track labels in the matched cluster
634     Int_t tlab[3];
635     tlab[0]=c->GetLabel(0);
636     tlab[1]=c->GetLabel(1);
637     tlab[2]=c->GetLabel(2);
638     AliDebug(2,Form(" tdc time of the matched track %i = ",c->GetTDC()));    
639     Double_t tof=AliTOFGeometry::TdcBinWidth()*c->GetTDC()+32; // in ps
640     AliDebug(2,Form(" tof time of the matched track: %f = ",tof));    
641     Double_t tofcorr=tof;
642     if(timeWalkCorr)tofcorr=CorrectTimeWalk(mindistZ,tof);
643     AliDebug(2,Form(" tof time of the matched track, after TW corr: %f = ",tofcorr));    
644     //Set TOF time signal and pointer to the matched cluster
645     t->SetTOFsignal(tofcorr);
646     t->SetTOFcluster(idclus); // pointing to the recPoints tree
647
648     //Tracking info
649     Double_t time[AliPID::kSPECIES]; t->GetIntegratedTimes(time);
650     Double_t mom=t->GetP();
651     for(Int_t j=0;j<AliPID::kSPECIES;j++){
652       Double_t mass=AliPID::ParticleMass(j);
653       time[j]+=(recL-trackPos[3][0])/3e-2*TMath::Sqrt(mom*mom+mass*mass)/mom;
654     }
655
656     AliTOFtrack *trackTOFout = new AliTOFtrack(*t); 
657     trackTOFout->PropagateTo(xpos);
658     t->UpdateTrackParams(trackTOFout,AliESDtrack::kTOFout);    
659     t->SetIntegratedLength(recL);
660     t->SetIntegratedTimes(time);
661     t->SetTOFLabel(tlab);
662
663  
664     // Fill Reco-QA histos for Reconstruction
665     fHRecNClus->Fill(nc);
666     fHRecDist->Fill(mindist);
667     fHRecSigYVsP->Fill(mom,TMath::Sqrt(cov[0]));
668     fHRecSigZVsP->Fill(mom,TMath::Sqrt(cov[2]));
669     fHRecSigYVsPWin->Fill(mom,dphi*sensRadius);
670     fHRecSigZVsPWin->Fill(mom,dz);
671
672     // Fill Tree for on-the-fly offline Calibration
673
674     if ( !((t->GetStatus() & AliESDtrack::kTIME)==0 )){    
675       fIch=calindex;
676       fToT=tToT;
677       fTime=rawTime;
678       fExpTimePi=time[2];
679       fExpTimeKa=time[3];
680       fExpTimePr=time[4];
681       fCalTree->Fill();
682     }
683     delete trackTOFout;
684   }
685   for (Int_t ii=0; ii<4; ii++) delete [] trackPos[ii];
686   for (Int_t ii=0;ii<6;ii++) delete [] clind[ii];
687  
688 }
689 //_________________________________________________________________________
690 Int_t AliTOFtracker::LoadClusters(TTree *cTree) {
691   //--------------------------------------------------------------------
692   //This function loads the TOF clusters
693   //--------------------------------------------------------------------
694
695   Int_t npadX = AliTOFGeometry::NpadX();
696   Int_t npadZ = AliTOFGeometry::NpadZ();
697   Int_t nStripA = AliTOFGeometry::NStripA();
698   Int_t nStripB = AliTOFGeometry::NStripB();
699   Int_t nStripC = AliTOFGeometry::NStripC();
700
701   TBranch *branch=cTree->GetBranch("TOF");
702   if (!branch) { 
703     AliError("can't get the branch with the TOF clusters !");
704     return 1;
705   }
706
707   TClonesArray dummy("AliTOFcluster",10000), *clusters=&dummy;
708   branch->SetAddress(&clusters);
709
710   cTree->GetEvent(0);
711   Int_t nc=clusters->GetEntriesFast();
712   fHDigNClus->Fill(nc);
713
714   AliInfo(Form("Number of clusters: %d",nc));
715
716   for (Int_t i=0; i<nc; i++) {
717     AliTOFcluster *c=(AliTOFcluster*)clusters->UncheckedAt(i);
718     fClusters[i]=new AliTOFcluster(*c); fN++;
719
720   // Fill Digits QA histos
721  
722     Int_t isector = c->GetDetInd(0);
723     Int_t iplate = c->GetDetInd(1);
724     Int_t istrip = c->GetDetInd(2);
725     Int_t ipadX = c->GetDetInd(4);
726     Int_t ipadZ = c->GetDetInd(3);
727
728     Float_t time =(AliTOFGeometry::TdcBinWidth()*c->GetTDC())*1E-3; // in ns
729     Float_t tot = (AliTOFGeometry::TdcBinWidth()*c->GetToT())*1E-3;//in ns
730  
731     Int_t stripOffset = 0;
732     switch (iplate) {
733     case 0:
734       stripOffset = 0;
735       break;
736     case 1:
737       stripOffset = nStripC;
738       break;
739     case 2:
740       stripOffset = nStripC+nStripB;
741       break;
742     case 3:
743       stripOffset = nStripC+nStripB+nStripA;
744       break;
745     case 4:
746       stripOffset = nStripC+nStripB+nStripA+nStripB;
747       break;
748     default:
749       AliError(Form("Wrong plate number in TOF (%d) !",iplate));
750       break;
751     };
752     Int_t zindex=npadZ*(istrip+stripOffset)+(ipadZ+1);
753     Int_t phiindex=npadX*isector+ipadX+1;
754     fHDigClusMap->Fill(zindex,phiindex);
755     fHDigClusTime->Fill(time);
756     fHDigClusToT->Fill(tot);
757
758   }
759
760
761   return 0;
762 }
763 //_________________________________________________________________________
764 void AliTOFtracker::UnloadClusters() {
765   //--------------------------------------------------------------------
766   //This function unloads TOF clusters
767   //--------------------------------------------------------------------
768   for (Int_t i=0; i<fN; i++) {
769     delete fClusters[i];
770     fClusters[i] = 0x0;
771   }
772   fN=0;
773 }
774
775 //_________________________________________________________________________
776 Int_t AliTOFtracker::FindClusterIndex(Double_t z) const {
777   //--------------------------------------------------------------------
778   // This function returns the index of the nearest cluster 
779   //--------------------------------------------------------------------
780   if (fN==0) return 0;
781   if (z <= fClusters[0]->GetZ()) return 0;
782   if (z > fClusters[fN-1]->GetZ()) return fN;
783   Int_t b=0, e=fN-1, m=(b+e)/2;
784   for (; b<e; m=(b+e)/2) {
785     if (z > fClusters[m]->GetZ()) b=m+1;
786     else e=m; 
787   }
788   return m;
789 }
790
791 //_________________________________________________________________________
792 Bool_t AliTOFtracker::GetTrackPoint(Int_t index, AliTrackPoint& p) const
793 {
794   // Get track space point with index i
795   // Coordinates are in the global system
796   AliTOFcluster *cl = fClusters[index];
797   Float_t xyz[3];
798   xyz[0] = cl->GetR()*TMath::Cos(cl->GetPhi());
799   xyz[1] = cl->GetR()*TMath::Sin(cl->GetPhi());
800   xyz[2] = cl->GetZ();
801   Float_t phiangle = (Int_t(cl->GetPhi()*TMath::RadToDeg()/20.)+0.5)*20.*TMath::DegToRad();
802   Float_t sinphi = TMath::Sin(phiangle), cosphi = TMath::Cos(phiangle);
803   Float_t tiltangle = AliTOFGeometry::GetAngles(cl->GetDetInd(1),cl->GetDetInd(2))*TMath::DegToRad();
804   Float_t sinth = TMath::Sin(tiltangle), costh = TMath::Cos(tiltangle);
805   Float_t sigmay2 = AliTOFGeometry::XPad()*AliTOFGeometry::XPad()/12.;
806   Float_t sigmaz2 = AliTOFGeometry::ZPad()*AliTOFGeometry::ZPad()/12.;
807   Float_t cov[6];
808   cov[0] = sinphi*sinphi*sigmay2 + cosphi*cosphi*sinth*sinth*sigmaz2;
809   cov[1] = -sinphi*cosphi*sigmay2 + sinphi*cosphi*sinth*sinth*sigmaz2;
810   cov[2] = -cosphi*sinth*costh*sigmaz2;
811   cov[3] = cosphi*cosphi*sigmay2 + sinphi*sinphi*sinth*sinth*sigmaz2;
812   cov[4] = -sinphi*sinth*costh*sigmaz2;
813   cov[5] = costh*costh*sigmaz2;
814   p.SetXYZ(xyz[0],xyz[1],xyz[2],cov);
815
816   // Detector numbering scheme
817   Int_t nSector = AliTOFGeometry::NSectors();
818   Int_t nPlate  = AliTOFGeometry::NPlates();
819   Int_t nStripA = AliTOFGeometry::NStripA();
820   Int_t nStripB = AliTOFGeometry::NStripB();
821   Int_t nStripC = AliTOFGeometry::NStripC();
822
823   Int_t isector = cl->GetDetInd(0);
824   if (isector >= nSector)
825     AliError(Form("Wrong sector number in TOF (%d) !",isector));
826   Int_t iplate = cl->GetDetInd(1);
827   if (iplate >= nPlate)
828     AliError(Form("Wrong plate number in TOF (%d) !",iplate));
829   Int_t istrip = cl->GetDetInd(2);
830
831   Int_t stripOffset = 0;
832   switch (iplate) {
833   case 0:
834     stripOffset = 0;
835     break;
836   case 1:
837     stripOffset = nStripC;
838     break;
839   case 2:
840     stripOffset = nStripC+nStripB;
841     break;
842   case 3:
843     stripOffset = nStripC+nStripB+nStripA;
844     break;
845   case 4:
846     stripOffset = nStripC+nStripB+nStripA+nStripB;
847     break;
848   default:
849     AliError(Form("Wrong plate number in TOF (%d) !",iplate));
850     break;
851   };
852
853   Int_t idet = (2*(nStripC+nStripB)+nStripA)*isector +
854                stripOffset +
855                istrip;
856   UShort_t volid = AliGeomManager::LayerToVolUID(AliGeomManager::kTOF,idet);
857   p.SetVolumeID((UShort_t)volid);
858   return kTRUE;
859 }
860 //_________________________________________________________________________
861 void AliTOFtracker::InitCheckHists() {
862
863   //Init histos for Digits/Reco QA and Calibration
864
865
866   fCalTree = new TTree("CalTree", "Tree for TOF calibration");
867   fCalTree->Branch("TOFchannelindex",&fIch,"iTOFch/I");
868   fCalTree->Branch("ToT",&fToT,"TOFToT/F");
869   fCalTree->Branch("TOFtime",&fTime,"TOFtime/F");
870   fCalTree->Branch("PionExpTime",&fExpTimePi,"PiExpTime/F");
871   fCalTree->Branch("KaonExpTime",&fExpTimeKa,"KaExpTime/F");
872   fCalTree->Branch("ProtonExpTime",&fExpTimePr,"PrExpTime/F");
873
874   //Digits "QA" 
875   fHDigClusMap = new TH2F("TOFDig_ClusMap", "",182,0.5,182.5,864, 0.5,864.5);  
876   fHDigNClus = new TH1F("TOFDig_NClus", "",200,0.5,200.5);  
877   fHDigClusTime = new TH1F("TOFDig_ClusTime", "",2000,0.,200.);  
878   fHDigClusToT = new TH1F("TOFDig_ClusToT", "",500,0.,100);  
879
880   //Reco "QA"
881   fHRecNClus =new TH1F("TOFRec_NClusW", "",50,0.5,50.5);
882   fHRecDist=new TH1F("TOFRec_Dist", "",50,0.5,10.5);
883   fHRecSigYVsP=new TH2F("TOFDig_SigYVsP", "",40,0.,4.,100, 0.,5.);
884   fHRecSigZVsP=new TH2F("TOFDig_SigZVsP", "",40,0.,4.,100, 0.,5.);
885   fHRecSigYVsPWin=new TH2F("TOFDig_SigYVsPWin", "",40,0.,4.,100, 0.,50.);
886   fHRecSigZVsPWin=new TH2F("TOFDig_SigZVsPWin", "",40,0.,4.,100, 0.,50.);
887 }
888
889 //_________________________________________________________________________
890 void AliTOFtracker::SaveCheckHists() {
891
892   //write histos for Digits/Reco QA and Calibration
893
894   TDirectory *dir = gDirectory;
895   TFile *logFile = 0;
896   TFile *logFileTOF = 0;
897
898   TSeqCollection *list = gROOT->GetListOfFiles();
899   int n = list->GetEntries();
900   for(int i=0; i<n; i++) {
901     logFile = (TFile*)list->At(i);
902     if (strstr(logFile->GetName(), "AliESDs.root")) break;
903   }
904
905   Bool_t isThere=kFALSE;
906   for(int i=0; i<n; i++) {
907     logFileTOF = (TFile*)list->At(i);
908     if (strstr(logFileTOF->GetName(), "TOFQA.root")){
909       isThere=kTRUE;
910       break;
911     } 
912   }
913    
914   logFile->cd();
915   fHDigClusMap->Write(fHDigClusMap->GetName(), TObject::kOverwrite);
916   fHDigNClus->Write(fHDigNClus->GetName(), TObject::kOverwrite);
917   fHDigClusTime->Write(fHDigClusTime->GetName(), TObject::kOverwrite);
918   fHDigClusToT->Write(fHDigClusToT->GetName(), TObject::kOverwrite);
919   fHRecNClus->Write(fHRecNClus->GetName(), TObject::kOverwrite);
920   fHRecDist->Write(fHRecDist->GetName(), TObject::kOverwrite);
921   fHRecSigYVsP->Write(fHRecSigYVsP->GetName(), TObject::kOverwrite);
922   fHRecSigZVsP->Write(fHRecSigZVsP->GetName(), TObject::kOverwrite);
923   fHRecSigYVsPWin->Write(fHRecSigYVsPWin->GetName(), TObject::kOverwrite);
924   fHRecSigZVsPWin->Write(fHRecSigZVsPWin->GetName(), TObject::kOverwrite);
925   //fCalTree->Write(fCalTree->GetName(),TObject::kOverwrite);
926   logFile->Flush();  
927
928   if(!isThere)logFileTOF = new TFile( "TOFQA.root","RECREATE");
929   logFileTOF->cd(); 
930   fHDigClusMap->Write(fHDigClusMap->GetName(), TObject::kOverwrite);
931   fHDigNClus->Write(fHDigNClus->GetName(), TObject::kOverwrite);
932   fHDigClusTime->Write(fHDigClusTime->GetName(), TObject::kOverwrite);
933   fHDigClusToT->Write(fHDigClusToT->GetName(), TObject::kOverwrite);
934   fHRecNClus->Write(fHRecNClus->GetName(), TObject::kOverwrite);
935   fHRecDist->Write(fHRecDist->GetName(), TObject::kOverwrite);
936   fHRecSigYVsP->Write(fHRecSigYVsP->GetName(), TObject::kOverwrite);
937   fHRecSigZVsP->Write(fHRecSigZVsP->GetName(), TObject::kOverwrite);
938   fHRecSigYVsPWin->Write(fHRecSigYVsPWin->GetName(), TObject::kOverwrite);
939   fHRecSigZVsPWin->Write(fHRecSigZVsPWin->GetName(), TObject::kOverwrite);
940   fCalTree->Write(fCalTree->GetName(),TObject::kOverwrite);
941   logFileTOF->Flush();  
942
943   dir->cd();
944   }
945 //_________________________________________________________________________
946 Float_t AliTOFtracker::CorrectTimeWalk( Float_t dist, Float_t tof) {
947
948   //dummy, for the moment
949   Float_t tofcorr=0.;
950   if(dist<AliTOFGeometry::ZPad()*0.5){
951     tofcorr=tof;
952     //place here the actual correction
953   }else{
954     tofcorr=tof; 
955   } 
956   return tofcorr;
957 }
958 //_________________________________________________________________________
959 Float_t AliTOFtracker::GetTimeZerofromT0(AliESDEvent *event) const {
960
961   //Returns TimeZero as measured by T0 detector
962
963   return event->GetT0();
964 }
965 //_________________________________________________________________________
966 Float_t AliTOFtracker::GetTimeZerofromTOF(AliESDEvent * /*event*/) const {
967
968   //dummy, for the moment. T0 algorithm using tracks on TOF
969   {
970     //place T0 algo here...
971   }
972   return 0.;
973 }