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