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