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