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