]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TOF/AliTOFtrackerV1.cxx
new TOF tracking schema
[u/mrichter/AliRoot.git] / TOF / AliTOFtrackerV1.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 // AliTOFtrackerV1 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 <TTree.h>
34 #include <TFile.h>
35 #include <TH1F.h>
36 #include <TH2F.h>
37
38 #include "AliAlignObj.h"
39 #include "AliESDtrack.h"
40 #include "AliESDEvent.h"
41 #include "AliLog.h"
42 #include "AliTrackPointArray.h"
43
44 #include "AliTOFcalib.h"
45 #include "AliTOFRecoParam.h"
46 #include "AliTOFcluster.h"
47 #include "AliTOFGeometryV5.h"
48 #include "AliTOFtrackerV1.h"
49 #include "AliTOFtrack.h"
50
51 extern TROOT *gROOT;
52
53 ClassImp(AliTOFtrackerV1)
54
55 //_____________________________________________________________________________
56 AliTOFtrackerV1::AliTOFtrackerV1():
57   fRecoParam(0x0),
58   fGeom(0x0),
59   fPid(0x0),
60   fN(0),
61   fNseeds(0),
62   fNseedsTOF(0),
63   fngoodmatch(0),
64   fnbadmatch(0),
65   fnunmatch(0),
66   fnmatch(0),
67   fTracks(0x0),
68   fSeeds(0x0),
69   fHDigClusMap(0x0),
70   fHDigNClus(0x0),
71   fHDigClusTime(0x0),
72   fHDigClusToT(0x0),
73   fHRecNClus(0x0),
74   fHRecChi2(0x0),
75   fHRecDistZ(0x0),
76   fHRecSigYVsP(0x0),
77   fHRecSigZVsP(0x0),
78   fHRecSigYVsPWin(0x0),
79   fHRecSigZVsPWin(0x0)
80  { 
81   //AliTOFtrackerV1 main Ctor
82    
83    // Getting the geometry 
84    fGeom=new AliTOFGeometryV5();
85    // Read the reconstruction parameters from the OCDB
86    AliTOFcalib *calib = new AliTOFcalib(fGeom);
87    fRecoParam = (AliTOFRecoParam*)calib->ReadRecParFromCDB("TOF/Calib",-1);
88    if(fRecoParam->GetApplyPbPbCuts())fRecoParam=fRecoParam->GetPbPbparam();
89    delete calib;
90    Double_t parPID[2];   
91    parPID[0]=fRecoParam->GetTimeResolution();
92    parPID[1]=fRecoParam->GetTimeNSigma();
93    fPid=new AliTOFpidESD(parPID);
94    InitCheckHists();
95
96 }
97 //_____________________________________________________________________________
98 AliTOFtrackerV1::AliTOFtrackerV1(const AliTOFtrackerV1 &t):
99   AliTracker(),
100   fRecoParam(0x0),
101   fGeom(0x0),
102   fPid(0x0),
103   fN(0),
104   fNseeds(0),
105   fNseedsTOF(0),
106   fngoodmatch(0),
107   fnbadmatch(0),
108   fnunmatch(0),
109   fnmatch(0),
110   fTracks(0x0),
111   fSeeds(0x0),
112   fHDigClusMap(0x0),
113   fHDigNClus(0x0),
114   fHDigClusTime(0x0),
115   fHDigClusToT(0x0),
116   fHRecNClus(0x0),
117   fHRecChi2(0x0),
118   fHRecDistZ(0x0),
119   fHRecSigYVsP(0x0),
120   fHRecSigZVsP(0x0),
121   fHRecSigYVsPWin(0x0),
122   fHRecSigZVsPWin(0x0)
123  { 
124   //AliTOFtrackerV1 copy Ctor
125
126   fNseeds=t.fNseeds;
127   fNseeds=t.fNseeds;
128   fNseedsTOF=t.fNseedsTOF;
129   fngoodmatch=t.fngoodmatch;
130   fnbadmatch=t.fnbadmatch;
131   fnunmatch=t.fnunmatch;
132   fnmatch=t.fnmatch;
133   fRecoParam=t.fRecoParam;
134   fGeom=t.fGeom;
135   fPid=t.fPid;
136   fSeeds=t.fSeeds;
137   fTracks=t.fTracks;
138   fN=t.fN;
139 }
140
141 //_____________________________________________________________________________
142 AliTOFtrackerV1& AliTOFtrackerV1::operator=(const AliTOFtrackerV1 &t)
143
144   //AliTOFtrackerV1 assignment operator
145
146   this->fNseeds=t.fNseeds;
147   this->fNseedsTOF=t.fNseedsTOF;
148   this->fngoodmatch=t.fngoodmatch;
149   this->fnbadmatch=t.fnbadmatch;
150   this->fnunmatch=t.fnunmatch;
151   this->fnmatch=t.fnmatch;
152   this->fRecoParam = t.fRecoParam;
153   this->fGeom = t.fGeom;
154   this->fPid = t.fPid;
155   this->fSeeds=t.fSeeds;
156   this->fTracks=t.fTracks;
157   this->fN=t.fN;
158   return *this;
159
160 }
161 //_____________________________________________________________________________
162 AliTOFtrackerV1::~AliTOFtrackerV1() {
163   //
164   // Dtor
165   //
166
167   SaveCheckHists();
168
169   delete fRecoParam; 
170   delete fGeom; 
171   delete fPid; 
172   delete fHDigClusMap;
173   delete fHDigNClus;
174   delete fHDigClusTime;
175   delete fHDigClusToT;
176   delete fHRecNClus;
177   delete fHRecChi2;
178   delete fHRecDistZ;
179   delete fHRecSigYVsP;
180   delete fHRecSigZVsP;
181   delete fHRecSigYVsPWin;
182   delete fHRecSigZVsPWin;
183 }
184 //_____________________________________________________________________________
185 Int_t AliTOFtrackerV1::PropagateBack(AliESDEvent* event) {
186   //
187   // Gets seeds from ESD event and Match with TOF Clusters
188   //
189
190
191   //Initialise some counters
192
193   fNseeds=0;
194   fNseedsTOF=0;
195   fngoodmatch=0;
196   fnbadmatch=0;
197   fnunmatch=0;
198   fnmatch=0;
199
200   Int_t ntrk=event->GetNumberOfTracks();
201   fNseeds = ntrk;
202   fSeeds= new TClonesArray("AliESDtrack",ntrk);
203   TClonesArray &aESDTrack = *fSeeds;
204
205
206   //Load ESD tracks into a local Array of ESD Seeds
207
208   for (Int_t i=0; i<fNseeds; i++) {
209     AliESDtrack *t=event->GetTrack(i);
210     new(aESDTrack[i]) AliESDtrack(*t);
211   }
212
213   //Prepare ESD tracks candidates for TOF Matching
214   CollectESD();
215
216   //Matching Step
217   MatchTracks();
218
219   AliInfo(Form("Number of matched tracks: %d",fnmatch));
220   AliInfo(Form("Number of good matched tracks: %d",fngoodmatch));
221   AliInfo(Form("Number of bad  matched tracks: %d",fnbadmatch));
222
223   //Update the matched ESD tracks
224
225   for (Int_t i=0; i<ntrk; i++) {
226     AliESDtrack *t=event->GetTrack(i);
227     AliESDtrack *seed =(AliESDtrack*)fSeeds->UncheckedAt(i);
228     if(seed->GetTOFsignal()>0){
229       t->SetTOFsignal(seed->GetTOFsignal());
230       t->SetTOFcluster(seed->GetTOFcluster());
231       t->SetTOFsignalToT(seed->GetTOFsignalToT());
232       t->SetTOFsignalRaw(seed->GetTOFsignalRaw());
233       t->SetTOFsignalDz(seed->GetTOFsignalDz());
234       t->SetTOFCalChannel(seed->GetTOFCalChannel());
235       Int_t tlab[3]; seed->GetTOFLabel(tlab);    
236       t->SetTOFLabel(tlab);
237       AliTOFtrack *track = new AliTOFtrack(*seed); 
238       t->UpdateTrackParams(track,AliESDtrack::kTOFout);   
239       delete track;
240     }
241   }
242
243   //Handle Time Zero information
244
245   Double_t timeZero=0.;
246   Double_t timeZeroMax=99999.;
247   Bool_t usetimeZero     = fRecoParam->UseTimeZero();
248   Bool_t timeZeroFromT0  = fRecoParam->GetTimeZerofromT0();
249   Bool_t timeZeroFromTOF = fRecoParam->GetTimeZerofromTOF();
250
251   AliDebug(1,Form("Use Time Zero?: %d",usetimeZero));
252   AliDebug(1,Form("Time Zero from T0? : %d",timeZeroFromT0));
253   AliDebug(1,Form("Time Zero From TOF? : %d",timeZeroFromTOF));
254
255   if(usetimeZero){
256     if(timeZeroFromT0){
257       timeZero=GetTimeZerofromT0(event); 
258     }
259     if(timeZeroFromTOF && (timeZero>timeZeroMax || !timeZeroFromT0)){
260       timeZero=GetTimeZerofromTOF(event); 
261     }
262   }
263   AliDebug(2,Form("time Zero used in PID: %f",timeZero));
264   //Make TOF PID
265   fPid->MakePID(event,timeZero);
266
267   if (fSeeds) {
268     fSeeds->Delete();
269     delete fSeeds;
270     fSeeds = 0x0;
271   }
272   if (fTracks) {
273     fTracks->Delete();
274     delete fTracks;
275     fTracks = 0x0;
276   }
277   return 0;
278   
279 }
280 //_________________________________________________________________________
281 void AliTOFtrackerV1::CollectESD() {
282    //prepare the set of ESD tracks to be matched to clusters in TOF
283
284   Int_t seedsTOF1=0;
285   Int_t seedsTOF2=0;
286  
287   fTracks= new TClonesArray("AliTOFtrack");
288   TClonesArray &aTOFTrack = *fTracks;
289   for (Int_t i=0; i<fNseeds; i++) {
290
291     AliESDtrack *t =(AliESDtrack*)fSeeds->UncheckedAt(i);
292     if ((t->GetStatus()&AliESDtrack::kTPCout)==0)continue;
293
294     // TRD 'good' tracks, already propagated at 371 cm
295
296     AliTOFtrack *track = new AliTOFtrack(*t); // New
297     Double_t x = track->GetX(); //New
298
299     if (((t->GetStatus()&AliESDtrack::kTRDout)!=0 ) && 
300          ( x >= fGeom->RinTOF()) ){
301       track->SetSeedIndex(i);
302       t->UpdateTrackParams(track,AliESDtrack::kTOFout);    
303       new(aTOFTrack[fNseedsTOF]) AliTOFtrack(*track);
304       fNseedsTOF++;
305       seedsTOF1++;
306       delete track;
307     }
308
309     // Propagate the rest of TPCbp  
310
311     else {
312       if(track->PropagateToInnerTOF()){ 
313         track->SetSeedIndex(i);
314         t->UpdateTrackParams(track,AliESDtrack::kTOFout);    
315         new(aTOFTrack[fNseedsTOF]) AliTOFtrack(*track);
316         fNseedsTOF++;
317         seedsTOF2++;
318       }
319       delete track;
320     }
321   }
322
323   AliInfo(Form("Number of TOF seeds %i",fNseedsTOF));
324   AliInfo(Form("Number of TOF seeds Type 1 %i",seedsTOF1));
325   AliInfo(Form("Number of TOF seeds Type 2 %i",seedsTOF2));
326
327   // Sort according uncertainties on track position 
328   fTracks->Sort();
329
330 }
331 //_________________________________________________________________________
332 void AliTOFtrackerV1::MatchTracks( ){
333   //
334   //Match ESD tracks to clusters in TOF
335   //
336
337
338   // Parameters regulating the reconstruction
339   Float_t dY=fGeom->XPad(); 
340   Float_t dZ=fGeom->ZPad(); 
341
342   const Int_t ncmax = 100;
343   Float_t sensRadius = fRecoParam->GetSensRadius();
344   Float_t scaleFact   = fRecoParam->GetWindowScaleFact();
345   Float_t dyMax=fRecoParam->GetWindowSizeMaxY(); 
346   Float_t dzMax=fRecoParam->GetWindowSizeMaxZ();
347   Double_t maxChi2=fRecoParam->GetMaxChi2();
348   Bool_t timeWalkCorr    = fRecoParam->GetTimeWalkCorr();
349   AliDebug(1,"++++++++++++++TOF Reconstruction Parameters:++++++++++++ \n");
350   AliDebug(1,Form("TOF sens radius: %f",sensRadius));
351   AliDebug(1,Form("TOF Window scale factor: %f",scaleFact));
352   AliDebug(1,Form("TOF Window max dy: %f",dyMax));
353   AliDebug(1,Form("TOF Window max dz: %f",dzMax));
354   AliDebug(1,Form("TOF Max Chi2: %f",maxChi2));
355   AliDebug(1,Form("Time Walk Correction? : %d",timeWalkCorr));   
356
357
358   //The matching loop
359
360   AliTOFcalib *calib = new AliTOFcalib(fGeom);
361   
362   for (Int_t iseed=0; iseed<fNseedsTOF; iseed++) {
363
364     AliTOFtrack *track =(AliTOFtrack*)fTracks->UncheckedAt(iseed);
365     AliESDtrack *t =(AliESDtrack*)fSeeds->UncheckedAt(track->GetSeedIndex());
366     if(t->GetTOFsignal()>0. ) continue;
367     AliTOFtrack *trackTOFin =new AliTOFtrack(*track);
368      
369     // Determine a window around the track
370     Double_t x,par[5]; trackTOFin->GetExternalParameters(x,par);
371     Double_t cov[15]; trackTOFin->GetExternalCovariance(cov);
372
373     Double_t z    = par[1];   
374     Double_t dz   =  scaleFact*3.*TMath::Sqrt(cov[2]+dZ*dZ/12);
375     Double_t dphi =  scaleFact*3.*TMath::Sqrt(cov[0]+dY*dY/12.)/sensRadius; 
376
377     Double_t phi=TMath::ATan2(par[0],x) + trackTOFin->GetAlpha();
378     if (phi<-TMath::Pi())phi+=2*TMath::Pi();
379     if (phi>=TMath::Pi())phi-=2*TMath::Pi();
380
381     //upper limit on window's size.
382     if(dz> dzMax) dz=dzMax;
383     if(dphi*sensRadius> dyMax) dphi=dyMax/sensRadius;
384
385
386     // find the clusters inside the selected window 
387     Int_t nc=0;
388     AliTOFcluster *clusters[ncmax]; // pointers to the clusters in the window
389     Int_t index[ncmax];//to keep track of the cluster index
390     for (Int_t k=FindClusterIndex(z-dz); k<fN; k++) {  
391       AliTOFcluster *c=fClusters[k];
392       if(nc>ncmax)break;
393       if(c->GetZ() > z+dz) break;
394       if(c->IsUsed()) continue;      
395       if(!c->GetStatus()) continue; // skip bad channels as declared in OCDB  
396       Float_t xyz[3]; c->GetGlobalXYZ(xyz);
397       Double_t clPhi=TMath::ATan2(xyz[1],xyz[0]);
398       Double_t dph=TMath::Abs(clPhi-phi);
399       if (dph>TMath::Pi()) dph-=2.*TMath::Pi();
400       if (TMath::Abs(dph)>dphi) continue;
401       clusters[nc]=c;
402       index[nc] = k;      
403       nc++;  
404     }
405
406     //start propagation: go to the average TOF pad middle plane at ~378.5 cm
407
408     Float_t  xTOF = sensRadius;
409     Double_t ymax = xTOF*TMath::Tan(0.5*fGeom->GetAlpha());
410     Bool_t skip = kFALSE;
411     Double_t ysect = trackTOFin->GetYat(xTOF,skip);
412     if (skip) break;
413     if (ysect > ymax) {
414       if (!trackTOFin->Rotate(fGeom->GetAlpha())) {
415         break;
416       }
417     } else if (ysect <-ymax) {
418       if (!trackTOFin->Rotate(fGeom->GetAlpha())) {
419         break;
420       }
421     }
422     if(!trackTOFin->PropagateTo(xTOF)) {
423       break;
424     }
425
426
427     AliTOFcluster *bestCluster=0;
428     Double_t bestChi2=maxChi2; 
429     Int_t idclus=-1;
430     for (Int_t i=0; i<nc; i++){
431       AliTOFcluster *c=clusters[i];  // one of the preselected clusters     
432       Double_t chi2=trackTOFin->GetPredictedChi2((AliCluster3D*)c); 
433       if (chi2 >= bestChi2) continue;
434       bestChi2=chi2;
435       bestCluster=c;
436       idclus=index[i];
437     }
438     
439     if (!bestCluster) {  // no matching , go to the next track 
440       fnunmatch++;
441       delete trackTOFin;
442       continue;
443     }
444
445     fnmatch++;
446     bestCluster->Use(); 
447     if (
448         (bestCluster->GetLabel(0)==TMath::Abs(trackTOFin->GetLabel()))
449         ||
450         (bestCluster->GetLabel(1)==TMath::Abs(trackTOFin->GetLabel()))
451         ||
452         (bestCluster->GetLabel(2)==TMath::Abs(trackTOFin->GetLabel()))
453         ) {
454       fngoodmatch++;
455        AliDebug(2,Form(" track label good %5i",trackTOFin->GetLabel()));
456
457     }
458     else{
459       fnbadmatch++;
460       AliDebug(2,Form(" track label bad %5i",trackTOFin->GetLabel()));
461     }
462
463     //Propagate the track to the best matched cluster
464     trackTOFin->PropagateTo(bestCluster);
465
466
467     //now take the local distance in Z from the pad center for time walk correction
468     Float_t tiltangle = fGeom->GetAngles(bestCluster->GetDetInd(1),bestCluster->GetDetInd(2))*TMath::DegToRad();
469     Double_t dzTW=trackTOFin->GetZ()-bestCluster->GetZ(); // in cm
470     dzTW/=TMath::Cos(tiltangle);
471
472     //update the ESD track and delete the TOFtrack
473     t->UpdateTrackParams(trackTOFin,AliESDtrack::kTOFout);    
474     delete trackTOFin;
475
476     //  Store quantities to be used in the TOF Calibration
477     Float_t tToT=fGeom->ToTBinWidth()*bestCluster->GetToT()*1E-3; // in ns
478     t->SetTOFsignalToT(tToT);
479     Float_t rawTime=fGeom->TdcBinWidth()*bestCluster->GetTDCRAW()+32; // RAW time,in ps
480     t->SetTOFsignalRaw(rawTime);
481     t->SetTOFsignalDz(dzTW);
482     AliDebug(2,Form(" Setting TOF raw time: %f  z distance: %f time: %f = ",rawTime,dzTW));    
483     Int_t ind[5];
484     ind[0]=bestCluster->GetDetInd(0);
485     ind[1]=bestCluster->GetDetInd(1);
486     ind[2]=bestCluster->GetDetInd(2);
487     ind[3]=bestCluster->GetDetInd(3);
488     ind[4]=bestCluster->GetDetInd(4);
489     Int_t calindex = calib->GetIndex(ind);
490     t->SetTOFCalChannel(calindex);
491
492     // keep track of the track labels in the matched cluster
493     Int_t tlab[3];
494     tlab[0]=bestCluster->GetLabel(0);
495     tlab[1]=bestCluster->GetLabel(1);
496     tlab[2]=bestCluster->GetLabel(2);
497     AliDebug(2,Form(" tdc time of the matched track %i = ",bestCluster->GetTDC()));    
498     Double_t tof=fGeom->TdcBinWidth()*bestCluster->GetTDC()+32; // in ps
499     AliDebug(2,Form(" tof time of the matched track: %f = ",tof));    
500     Double_t tofcorr=tof;
501     if(timeWalkCorr)tofcorr=CorrectTimeWalk(dzTW,tof);
502     AliDebug(2,Form(" tof time of the matched track, after TW corr: %f = ",tofcorr));    
503     //Set TOF time signal and pointer to the matched cluster
504     t->SetTOFsignal(tofcorr);
505     t->SetTOFcluster(idclus); // pointing to the recPoints tree
506     t->SetTOFLabel(tlab);
507
508     Double_t mom=t->GetP();
509     // Fill Reco-QA histos for Reconstruction
510     fHRecNClus->Fill(nc);
511     fHRecChi2->Fill(bestChi2);
512     fHRecDistZ->Fill(dzTW);
513     fHRecSigYVsP->Fill(mom,TMath::Sqrt(cov[0]));
514     fHRecSigZVsP->Fill(mom,TMath::Sqrt(cov[2]));
515     fHRecSigYVsPWin->Fill(mom,dphi*sensRadius);
516     fHRecSigZVsPWin->Fill(mom,dz);
517
518     // Fill Tree for on-the-fly offline Calibration
519     // no longer there - all info is in the ESDs now
520
521   }
522   delete calib;
523
524 }
525 //_________________________________________________________________________
526 Int_t AliTOFtrackerV1::LoadClusters(TTree *cTree) {
527   //--------------------------------------------------------------------
528   //This function loads the TOF clusters
529   //--------------------------------------------------------------------
530
531   Int_t npadX = fGeom->NpadX();
532   Int_t npadZ = fGeom->NpadZ();
533   Int_t nStripA = fGeom->NStripA();
534   Int_t nStripB = fGeom->NStripB();
535   Int_t nStripC = fGeom->NStripC();
536
537   TBranch *branch=cTree->GetBranch("TOF");
538   if (!branch) { 
539     AliError("can't get the branch with the TOF clusters !");
540     return 1;
541   }
542
543   TClonesArray dummy("AliTOFcluster",10000), *clusters=&dummy;
544   branch->SetAddress(&clusters);
545
546   cTree->GetEvent(0);
547   Int_t nc=clusters->GetEntriesFast();
548   fHDigNClus->Fill(nc);
549
550   for (Int_t i=0; i<nc; i++) {
551     AliTOFcluster *c=(AliTOFcluster*)clusters->UncheckedAt(i);
552     fClusters[i]=new AliTOFcluster(*c); fN++;
553
554   // Fill Digits QA histos
555  
556     Int_t isector = c->GetDetInd(0);
557     Int_t iplate = c->GetDetInd(1);
558     Int_t istrip = c->GetDetInd(2);
559     Int_t ipadX = c->GetDetInd(4);
560     Int_t ipadZ = c->GetDetInd(3);
561
562     Float_t time =(fGeom->TdcBinWidth()*c->GetTDC())*1E-3; // in ns
563     Float_t tot = (fGeom->TdcBinWidth()*c->GetToT())*1E-3;//in ns
564  
565     Int_t stripOffset = 0;
566     switch (iplate) {
567     case 0:
568       stripOffset = 0;
569       break;
570     case 1:
571       stripOffset = nStripC;
572       break;
573     case 2:
574       stripOffset = nStripC+nStripB;
575       break;
576     case 3:
577       stripOffset = nStripC+nStripB+nStripA;
578       break;
579     case 4:
580       stripOffset = nStripC+nStripB+nStripA+nStripB;
581       break;
582     default:
583       AliError(Form("Wrong plate number in TOF (%d) !",iplate));
584       break;
585     };
586     Int_t zindex=npadZ*(istrip+stripOffset)+(ipadZ+1);
587     Int_t phiindex=npadX*isector+ipadX+1;
588     fHDigClusMap->Fill(zindex,phiindex);
589     fHDigClusTime->Fill(time);
590     fHDigClusToT->Fill(tot);
591   }
592
593
594   return 0;
595 }
596 //_________________________________________________________________________
597 void AliTOFtrackerV1::UnloadClusters() {
598   //--------------------------------------------------------------------
599   //This function unloads TOF clusters
600   //--------------------------------------------------------------------
601   for (Int_t i=0; i<fN; i++) {
602     delete fClusters[i];
603     fClusters[i] = 0x0;
604   }
605   fN=0;
606 }
607
608 //_________________________________________________________________________
609 Int_t AliTOFtrackerV1::FindClusterIndex(Double_t z) const {
610   //--------------------------------------------------------------------
611   // This function returns the index of the nearest cluster 
612   //--------------------------------------------------------------------
613   //MOD
614   //Here we need to get the Z in the tracking system
615
616   if (fN==0) return 0;
617   if (z <= fClusters[0]->GetZ()) return 0;
618   if (z > fClusters[fN-1]->GetZ()) return fN;
619   Int_t b=0, e=fN-1, m=(b+e)/2;
620   for (; b<e; m=(b+e)/2) {
621     if (z > fClusters[m]->GetZ()) b=m+1;
622     else e=m; 
623   }
624   return m;
625 }
626
627 //_________________________________________________________________________
628 Bool_t AliTOFtrackerV1::GetTrackPoint(Int_t index, AliTrackPoint& p) const
629 {
630   // Get track space point with index i
631   // Coordinates are in the global system
632   AliTOFcluster *cl = fClusters[index];
633   Float_t xyz[3];
634   cl->GetGlobalXYZ(xyz);
635   Float_t phi=TMath::ATan2(xyz[1],xyz[0]);
636   Float_t phiangle = (Int_t(phi*TMath::RadToDeg()/20.)+0.5)*20.*TMath::DegToRad();
637   Float_t sinphi = TMath::Sin(phiangle), cosphi = TMath::Cos(phiangle);
638   Float_t tiltangle = fGeom->GetAngles(cl->GetDetInd(1),cl->GetDetInd(2))*TMath::DegToRad();
639   Float_t sinth = TMath::Sin(tiltangle), costh = TMath::Cos(tiltangle);
640   Float_t sigmay2 = fGeom->XPad()*fGeom->XPad()/12.;
641   Float_t sigmaz2 = fGeom->ZPad()*fGeom->ZPad()/12.;
642   Float_t cov[6];
643   cov[0] = sinphi*sinphi*sigmay2 + cosphi*cosphi*sinth*sinth*sigmaz2;
644   cov[1] = -sinphi*cosphi*sigmay2 + sinphi*cosphi*sinth*sinth*sigmaz2;
645   cov[2] = -cosphi*sinth*costh*sigmaz2;
646   cov[3] = cosphi*cosphi*sigmay2 + sinphi*sinphi*sinth*sinth*sigmaz2;
647   cov[4] = -sinphi*sinth*costh*sigmaz2;
648   cov[5] = costh*costh*sigmaz2;
649   p.SetXYZ(xyz[0],xyz[1],xyz[2],cov);
650
651   // Detector numbering scheme
652   Int_t nSector = fGeom->NSectors();
653   Int_t nPlate  = fGeom->NPlates();
654   Int_t nStripA = fGeom->NStripA();
655   Int_t nStripB = fGeom->NStripB();
656   Int_t nStripC = fGeom->NStripC();
657
658   Int_t isector = cl->GetDetInd(0);
659   if (isector >= nSector)
660     AliError(Form("Wrong sector number in TOF (%d) !",isector));
661   Int_t iplate = cl->GetDetInd(1);
662   if (iplate >= nPlate)
663     AliError(Form("Wrong plate number in TOF (%d) !",iplate));
664   Int_t istrip = cl->GetDetInd(2);
665
666   Int_t stripOffset = 0;
667   switch (iplate) {
668   case 0:
669     stripOffset = 0;
670     break;
671   case 1:
672     stripOffset = nStripC;
673     break;
674   case 2:
675     stripOffset = nStripC+nStripB;
676     break;
677   case 3:
678     stripOffset = nStripC+nStripB+nStripA;
679     break;
680   case 4:
681     stripOffset = nStripC+nStripB+nStripA+nStripB;
682     break;
683   default:
684     AliError(Form("Wrong plate number in TOF (%d) !",iplate));
685     break;
686   };
687
688   Int_t idet = (2*(nStripC+nStripB)+nStripA)*isector +
689                stripOffset +
690                istrip;
691   UShort_t volid = AliGeomManager::LayerToVolUID(AliGeomManager::kTOF,idet);
692   p.SetVolumeID((UShort_t)volid);
693   return kTRUE;
694 }
695 //_________________________________________________________________________
696 void AliTOFtrackerV1::InitCheckHists() {
697
698   //Init histos for Digits/Reco QA and Calibration
699
700   //Digits "QA" 
701   fHDigClusMap = new TH2F("TOFDig_ClusMap", "",182,0.5,182.5,864, 0.5,864.5);  
702   fHDigNClus = new TH1F("TOFDig_NClus", "",200,0.5,200.5);  
703   fHDigClusTime = new TH1F("TOFDig_ClusTime", "",2000,0.,200.);  
704   fHDigClusToT = new TH1F("TOFDig_ClusToT", "",500,0.,100);  
705
706   //Reco "QA"
707   fHRecNClus =new TH1F("TOFRec_NClusW", "",50,0.5,50.5);
708   fHRecDistZ=new TH1F("TOFRec_DistZ", "",50,0.5,10.5);
709   fHRecChi2=new TH1F("TOFRec_Chi2", "",100,0.,10.);
710   fHRecSigYVsP=new TH2F("TOFDig_SigYVsP", "",40,0.,4.,100, 0.,5.);
711   fHRecSigZVsP=new TH2F("TOFDig_SigZVsP", "",40,0.,4.,100, 0.,5.);
712   fHRecSigYVsPWin=new TH2F("TOFDig_SigYVsPWin", "",40,0.,4.,100, 0.,50.);
713   fHRecSigZVsPWin=new TH2F("TOFDig_SigZVsPWin", "",40,0.,4.,100, 0.,50.);
714 }
715
716 //_________________________________________________________________________
717 void AliTOFtrackerV1::SaveCheckHists() {
718
719   //write histos for Digits/Reco QA and Calibration
720
721   TDirectory *dir = gDirectory;
722   TFile *logFile = 0;
723   TFile *logFileTOF = 0;
724
725   TSeqCollection *list = gROOT->GetListOfFiles();
726   int n = list->GetEntries();
727   for(int i=0; i<n; i++) {
728     logFile = (TFile*)list->At(i);
729     if (strstr(logFile->GetName(), "AliESDs.root")) break;
730   }
731
732   Bool_t isThere=kFALSE;
733   for(int i=0; i<n; i++) {
734     logFileTOF = (TFile*)list->At(i);
735     if (strstr(logFileTOF->GetName(), "TOFQA.root")){
736       isThere=kTRUE;
737       break;
738     } 
739   }
740    
741   logFile->cd();
742   fHDigClusMap->Write(fHDigClusMap->GetName(), TObject::kOverwrite);
743   fHDigNClus->Write(fHDigNClus->GetName(), TObject::kOverwrite);
744   fHDigClusTime->Write(fHDigClusTime->GetName(), TObject::kOverwrite);
745   fHDigClusToT->Write(fHDigClusToT->GetName(), TObject::kOverwrite);
746   fHRecNClus->Write(fHRecNClus->GetName(), TObject::kOverwrite);
747   fHRecChi2->Write(fHRecChi2->GetName(), TObject::kOverwrite);
748   fHRecDistZ->Write(fHRecDistZ->GetName(), TObject::kOverwrite);
749   fHRecSigYVsP->Write(fHRecSigYVsP->GetName(), TObject::kOverwrite);
750   fHRecSigZVsP->Write(fHRecSigZVsP->GetName(), TObject::kOverwrite);
751   fHRecSigYVsPWin->Write(fHRecSigYVsPWin->GetName(), TObject::kOverwrite);
752   fHRecSigZVsPWin->Write(fHRecSigZVsPWin->GetName(), TObject::kOverwrite);
753   logFile->Flush();  
754
755   if(!isThere)logFileTOF = new TFile( "TOFQA.root","RECREATE");
756   logFileTOF->cd(); 
757   fHDigClusMap->Write(fHDigClusMap->GetName(), TObject::kOverwrite);
758   fHDigNClus->Write(fHDigNClus->GetName(), TObject::kOverwrite);
759   fHDigClusTime->Write(fHDigClusTime->GetName(), TObject::kOverwrite);
760   fHDigClusToT->Write(fHDigClusToT->GetName(), TObject::kOverwrite);
761   fHRecNClus->Write(fHRecNClus->GetName(), TObject::kOverwrite);
762   fHRecChi2->Write(fHRecChi2->GetName(), TObject::kOverwrite);
763   fHRecDistZ->Write(fHRecDistZ->GetName(), TObject::kOverwrite);
764   fHRecSigYVsP->Write(fHRecSigYVsP->GetName(), TObject::kOverwrite);
765   fHRecSigZVsP->Write(fHRecSigZVsP->GetName(), TObject::kOverwrite);
766   fHRecSigYVsPWin->Write(fHRecSigYVsPWin->GetName(), TObject::kOverwrite);
767   fHRecSigZVsPWin->Write(fHRecSigZVsPWin->GetName(), TObject::kOverwrite);
768   logFileTOF->Flush();  
769
770   dir->cd();
771   }
772 //_________________________________________________________________________
773 Float_t AliTOFtrackerV1::CorrectTimeWalk( Float_t dist, Float_t tof) {
774
775   //dummy, for the moment
776   Float_t tofcorr=0.;
777   if(dist<fGeom->ZPad()*0.5){
778     tofcorr=tof;
779     //place here the actual correction
780   }else{
781     tofcorr=tof; 
782   } 
783   return tofcorr;
784 }
785 //_________________________________________________________________________
786 Float_t AliTOFtrackerV1::GetTimeZerofromT0(AliESDEvent *event) const {
787
788   //Returns TimeZero as measured by T0 detector
789
790   return event->GetT0();
791 }
792 //_________________________________________________________________________
793 Float_t AliTOFtrackerV1::GetTimeZerofromTOF(AliESDEvent * /*event*/) const {
794
795   //dummy, for the moment. T0 algorithm using tracks on TOF
796   {
797     //place T0 algo here...
798   }
799   return 0.;
800 }