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