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