]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TOF/AliTOFtrackerV1.cxx
Cable length delays and time-of-flight measurements: added during the raw data writin...
[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
446     AliDebug(2, Form("%7i     %7i     %10i     %10i  %10i  %10i",
447                      iseed,
448                      fnmatch,
449                      TMath::Abs(trackTOFin->GetLabel()),
450                      bestCluster->GetLabel(0), 
451                      bestCluster->GetLabel(1), 
452                      bestCluster->GetLabel(2))); // AdC
453
454     bestCluster->Use(); 
455     if (
456         (bestCluster->GetLabel(0)==TMath::Abs(trackTOFin->GetLabel()))
457         ||
458         (bestCluster->GetLabel(1)==TMath::Abs(trackTOFin->GetLabel()))
459         ||
460         (bestCluster->GetLabel(2)==TMath::Abs(trackTOFin->GetLabel()))
461         ) {
462       fngoodmatch++;
463        AliDebug(2,Form(" track label good %5i",trackTOFin->GetLabel()));
464
465     }
466     else{
467       fnbadmatch++;
468       AliDebug(2,Form(" track label bad %5i",trackTOFin->GetLabel()));
469     }
470
471     //Propagate the track to the best matched cluster
472     trackTOFin->PropagateTo(bestCluster);
473
474
475     //now take the local distance in Z from the pad center for time walk correction
476     Float_t tiltangle = AliTOFGeometry::GetAngles(bestCluster->GetDetInd(1),bestCluster->GetDetInd(2))*TMath::DegToRad();
477     Double_t dzTW=trackTOFin->GetZ()-bestCluster->GetZ(); // in cm
478     dzTW/=TMath::Cos(tiltangle);
479
480     //update the ESD track and delete the TOFtrack
481     t->UpdateTrackParams(trackTOFin,AliESDtrack::kTOFout);    
482     delete trackTOFin;
483
484     //  Store quantities to be used in the TOF Calibration
485     Float_t tToT=AliTOFGeometry::ToTBinWidth()*bestCluster->GetToT()*1E-3; // in ns
486     t->SetTOFsignalToT(tToT);
487     Float_t rawTime=AliTOFGeometry::TdcBinWidth()*bestCluster->GetTDCRAW()+32; // RAW time,in ps
488     t->SetTOFsignalRaw(rawTime);
489     t->SetTOFsignalDz(dzTW);
490     AliDebug(2,Form(" Setting TOF raw time: %f  z distance: %f time: %f = ",rawTime,dzTW));    
491     Int_t ind[5];
492     ind[0]=bestCluster->GetDetInd(0);
493     ind[1]=bestCluster->GetDetInd(1);
494     ind[2]=bestCluster->GetDetInd(2);
495     ind[3]=bestCluster->GetDetInd(3);
496     ind[4]=bestCluster->GetDetInd(4);
497     Int_t calindex = AliTOFGeometry::GetIndex(ind);
498     t->SetTOFCalChannel(calindex);
499
500     // keep track of the track labels in the matched cluster
501     Int_t tlab[3];
502     tlab[0]=bestCluster->GetLabel(0);
503     tlab[1]=bestCluster->GetLabel(1);
504     tlab[2]=bestCluster->GetLabel(2);
505     AliDebug(2,Form(" tdc time of the matched track %i = ",bestCluster->GetTDC()));    
506     Double_t tof=AliTOFGeometry::TdcBinWidth()*bestCluster->GetTDC()+32; // in ps
507     AliDebug(2,Form(" tof time of the matched track: %f = ",tof));    
508     Double_t tofcorr=tof;
509     if(timeWalkCorr)tofcorr=CorrectTimeWalk(dzTW,tof);
510     AliDebug(2,Form(" tof time of the matched track, after TW corr: %f = ",tofcorr));    
511     //Set TOF time signal and pointer to the matched cluster
512     t->SetTOFsignal(tofcorr);
513     t->SetTOFcluster(idclus); // pointing to the recPoints tree
514     t->SetTOFLabel(tlab);
515
516     Double_t mom=t->GetP();
517     // Fill Reco-QA histos for Reconstruction
518     fHRecNClus->Fill(nc);
519     fHRecChi2->Fill(bestChi2);
520     fHRecDistZ->Fill(dzTW);
521     fHRecSigYVsP->Fill(mom,TMath::Sqrt(cov[0]));
522     fHRecSigZVsP->Fill(mom,TMath::Sqrt(cov[2]));
523     fHRecSigYVsPWin->Fill(mom,dphi*sensRadius);
524     fHRecSigZVsPWin->Fill(mom,dz);
525
526     // Fill Tree for on-the-fly offline Calibration
527     // no longer there - all info is in the ESDs now
528
529   }
530
531 }
532 //_________________________________________________________________________
533 Int_t AliTOFtrackerV1::LoadClusters(TTree *cTree) {
534   //--------------------------------------------------------------------
535   //This function loads the TOF clusters
536   //--------------------------------------------------------------------
537
538   Int_t npadX = AliTOFGeometry::NpadX();
539   Int_t npadZ = AliTOFGeometry::NpadZ();
540   Int_t nStripA = AliTOFGeometry::NStripA();
541   Int_t nStripB = AliTOFGeometry::NStripB();
542   Int_t nStripC = AliTOFGeometry::NStripC();
543
544   TBranch *branch=cTree->GetBranch("TOF");
545   if (!branch) { 
546     AliError("can't get the branch with the TOF clusters !");
547     return 1;
548   }
549
550   static TClonesArray dummy("AliTOFcluster",10000);
551   dummy.Clear();
552   TClonesArray *clusters=&dummy;
553   branch->SetAddress(&clusters);
554
555   cTree->GetEvent(0);
556   Int_t nc=clusters->GetEntriesFast();
557   fHDigNClus->Fill(nc);
558
559   AliInfo(Form("Number of clusters: %d",nc));
560
561   for (Int_t i=0; i<nc; i++) {
562     AliTOFcluster *c=(AliTOFcluster*)clusters->UncheckedAt(i);
563     fClusters[i]=new AliTOFcluster(*c); fN++;
564
565   // Fill Digits QA histos
566  
567     Int_t isector = c->GetDetInd(0);
568     Int_t iplate = c->GetDetInd(1);
569     Int_t istrip = c->GetDetInd(2);
570     Int_t ipadX = c->GetDetInd(4);
571     Int_t ipadZ = c->GetDetInd(3);
572
573     Float_t time =(AliTOFGeometry::TdcBinWidth()*c->GetTDC())*1E-3; // in ns
574     Float_t tot = (AliTOFGeometry::TdcBinWidth()*c->GetToT())*1E-3;//in ns
575  
576     Int_t stripOffset = 0;
577     switch (iplate) {
578     case 0:
579       stripOffset = 0;
580       break;
581     case 1:
582       stripOffset = nStripC;
583       break;
584     case 2:
585       stripOffset = nStripC+nStripB;
586       break;
587     case 3:
588       stripOffset = nStripC+nStripB+nStripA;
589       break;
590     case 4:
591       stripOffset = nStripC+nStripB+nStripA+nStripB;
592       break;
593     default:
594       AliError(Form("Wrong plate number in TOF (%d) !",iplate));
595       break;
596     };
597     Int_t zindex=npadZ*(istrip+stripOffset)+(ipadZ+1);
598     Int_t phiindex=npadX*isector+ipadX+1;
599     fHDigClusMap->Fill(zindex,phiindex);
600     fHDigClusTime->Fill(time);
601     fHDigClusToT->Fill(tot);
602   }
603
604
605   return 0;
606 }
607 //_________________________________________________________________________
608 void AliTOFtrackerV1::UnloadClusters() {
609   //--------------------------------------------------------------------
610   //This function unloads TOF clusters
611   //--------------------------------------------------------------------
612   for (Int_t i=0; i<fN; i++) {
613     delete fClusters[i];
614     fClusters[i] = 0x0;
615   }
616   fN=0;
617 }
618
619 //_________________________________________________________________________
620 Int_t AliTOFtrackerV1::FindClusterIndex(Double_t z) const {
621   //--------------------------------------------------------------------
622   // This function returns the index of the nearest cluster 
623   //--------------------------------------------------------------------
624   //MOD
625   //Here we need to get the Z in the tracking system
626
627   if (fN==0) return 0;
628   if (z <= fClusters[0]->GetZ()) return 0;
629   if (z > fClusters[fN-1]->GetZ()) return fN;
630   Int_t b=0, e=fN-1, m=(b+e)/2;
631   for (; b<e; m=(b+e)/2) {
632     if (z > fClusters[m]->GetZ()) b=m+1;
633     else e=m; 
634   }
635   return m;
636 }
637
638 //_________________________________________________________________________
639 Bool_t AliTOFtrackerV1::GetTrackPoint(Int_t index, AliTrackPoint& p) const
640 {
641   // Get track space point with index i
642   // Coordinates are in the global system
643   AliTOFcluster *cl = fClusters[index];
644   Float_t xyz[3];
645   cl->GetGlobalXYZ(xyz);
646   Float_t phi=TMath::ATan2(xyz[1],xyz[0]);
647   Float_t phiangle = (Int_t(phi*TMath::RadToDeg()/20.)+0.5)*20.*TMath::DegToRad();
648   Float_t sinphi = TMath::Sin(phiangle), cosphi = TMath::Cos(phiangle);
649   Float_t tiltangle = AliTOFGeometry::GetAngles(cl->GetDetInd(1),cl->GetDetInd(2))*TMath::DegToRad();
650   Float_t sinth = TMath::Sin(tiltangle), costh = TMath::Cos(tiltangle);
651   Float_t sigmay2 = AliTOFGeometry::XPad()*AliTOFGeometry::XPad()/12.;
652   Float_t sigmaz2 = AliTOFGeometry::ZPad()*AliTOFGeometry::ZPad()/12.;
653   Float_t cov[6];
654   cov[0] = sinphi*sinphi*sigmay2 + cosphi*cosphi*sinth*sinth*sigmaz2;
655   cov[1] = -sinphi*cosphi*sigmay2 + sinphi*cosphi*sinth*sinth*sigmaz2;
656   cov[2] = -cosphi*sinth*costh*sigmaz2;
657   cov[3] = cosphi*cosphi*sigmay2 + sinphi*sinphi*sinth*sinth*sigmaz2;
658   cov[4] = -sinphi*sinth*costh*sigmaz2;
659   cov[5] = costh*costh*sigmaz2;
660   p.SetXYZ(xyz[0],xyz[1],xyz[2],cov);
661
662   // Detector numbering scheme
663   Int_t nSector = AliTOFGeometry::NSectors();
664   Int_t nPlate  = AliTOFGeometry::NPlates();
665   Int_t nStripA = AliTOFGeometry::NStripA();
666   Int_t nStripB = AliTOFGeometry::NStripB();
667   Int_t nStripC = AliTOFGeometry::NStripC();
668
669   Int_t isector = cl->GetDetInd(0);
670   if (isector >= nSector)
671     AliError(Form("Wrong sector number in TOF (%d) !",isector));
672   Int_t iplate = cl->GetDetInd(1);
673   if (iplate >= nPlate)
674     AliError(Form("Wrong plate number in TOF (%d) !",iplate));
675   Int_t istrip = cl->GetDetInd(2);
676
677   Int_t stripOffset = 0;
678   switch (iplate) {
679   case 0:
680     stripOffset = 0;
681     break;
682   case 1:
683     stripOffset = nStripC;
684     break;
685   case 2:
686     stripOffset = nStripC+nStripB;
687     break;
688   case 3:
689     stripOffset = nStripC+nStripB+nStripA;
690     break;
691   case 4:
692     stripOffset = nStripC+nStripB+nStripA+nStripB;
693     break;
694   default:
695     AliError(Form("Wrong plate number in TOF (%d) !",iplate));
696     break;
697   };
698
699   Int_t idet = (2*(nStripC+nStripB)+nStripA)*isector +
700                stripOffset +
701                istrip;
702   UShort_t volid = AliGeomManager::LayerToVolUID(AliGeomManager::kTOF,idet);
703   p.SetVolumeID((UShort_t)volid);
704   return kTRUE;
705 }
706 //_________________________________________________________________________
707 void AliTOFtrackerV1::InitCheckHists() {
708
709   //Init histos for Digits/Reco QA and Calibration
710
711   //Digits "QA" 
712   fHDigClusMap = new TH2F("TOFDig_ClusMap", "",182,0.5,182.5,864, 0.5,864.5);  
713   fHDigNClus = new TH1F("TOFDig_NClus", "",200,0.5,200.5);  
714   fHDigClusTime = new TH1F("TOFDig_ClusTime", "",2000,0.,200.);  
715   fHDigClusToT = new TH1F("TOFDig_ClusToT", "",500,0.,100);  
716
717   //Reco "QA"
718   fHRecNClus =new TH1F("TOFRec_NClusW", "",50,0.5,50.5);
719   fHRecDistZ=new TH1F("TOFRec_DistZ", "",50,0.5,10.5);
720   fHRecChi2=new TH1F("TOFRec_Chi2", "",100,0.,10.);
721   fHRecSigYVsP=new TH2F("TOFDig_SigYVsP", "",40,0.,4.,100, 0.,5.);
722   fHRecSigZVsP=new TH2F("TOFDig_SigZVsP", "",40,0.,4.,100, 0.,5.);
723   fHRecSigYVsPWin=new TH2F("TOFDig_SigYVsPWin", "",40,0.,4.,100, 0.,50.);
724   fHRecSigZVsPWin=new TH2F("TOFDig_SigZVsPWin", "",40,0.,4.,100, 0.,50.);
725 }
726
727 //_________________________________________________________________________
728 void AliTOFtrackerV1::SaveCheckHists() {
729
730   //write histos for Digits/Reco QA and Calibration
731
732   TDirectory *dir = gDirectory;
733   TFile *logFile = 0;
734   TFile *logFileTOF = 0;
735
736   TSeqCollection *list = gROOT->GetListOfFiles();
737   int n = list->GetEntries();
738   for(int i=0; i<n; i++) {
739     logFile = (TFile*)list->At(i);
740     if (strstr(logFile->GetName(), "AliESDs.root")) break;
741   }
742
743   Bool_t isThere=kFALSE;
744   for(int i=0; i<n; i++) {
745     logFileTOF = (TFile*)list->At(i);
746     if (strstr(logFileTOF->GetName(), "TOFQA.root")){
747       isThere=kTRUE;
748       break;
749     } 
750   }
751    
752   logFile->cd();
753   fHDigClusMap->Write(fHDigClusMap->GetName(), TObject::kOverwrite);
754   fHDigNClus->Write(fHDigNClus->GetName(), TObject::kOverwrite);
755   fHDigClusTime->Write(fHDigClusTime->GetName(), TObject::kOverwrite);
756   fHDigClusToT->Write(fHDigClusToT->GetName(), TObject::kOverwrite);
757   fHRecNClus->Write(fHRecNClus->GetName(), TObject::kOverwrite);
758   fHRecChi2->Write(fHRecChi2->GetName(), TObject::kOverwrite);
759   fHRecDistZ->Write(fHRecDistZ->GetName(), TObject::kOverwrite);
760   fHRecSigYVsP->Write(fHRecSigYVsP->GetName(), TObject::kOverwrite);
761   fHRecSigZVsP->Write(fHRecSigZVsP->GetName(), TObject::kOverwrite);
762   fHRecSigYVsPWin->Write(fHRecSigYVsPWin->GetName(), TObject::kOverwrite);
763   fHRecSigZVsPWin->Write(fHRecSigZVsPWin->GetName(), TObject::kOverwrite);
764   logFile->Flush();  
765
766   if(!isThere)logFileTOF = new TFile( "TOFQA.root","RECREATE");
767   logFileTOF->cd(); 
768   fHDigClusMap->Write(fHDigClusMap->GetName(), TObject::kOverwrite);
769   fHDigNClus->Write(fHDigNClus->GetName(), TObject::kOverwrite);
770   fHDigClusTime->Write(fHDigClusTime->GetName(), TObject::kOverwrite);
771   fHDigClusToT->Write(fHDigClusToT->GetName(), TObject::kOverwrite);
772   fHRecNClus->Write(fHRecNClus->GetName(), TObject::kOverwrite);
773   fHRecChi2->Write(fHRecChi2->GetName(), TObject::kOverwrite);
774   fHRecDistZ->Write(fHRecDistZ->GetName(), TObject::kOverwrite);
775   fHRecSigYVsP->Write(fHRecSigYVsP->GetName(), TObject::kOverwrite);
776   fHRecSigZVsP->Write(fHRecSigZVsP->GetName(), TObject::kOverwrite);
777   fHRecSigYVsPWin->Write(fHRecSigYVsPWin->GetName(), TObject::kOverwrite);
778   fHRecSigZVsPWin->Write(fHRecSigZVsPWin->GetName(), TObject::kOverwrite);
779   logFileTOF->Flush();  
780
781   dir->cd();
782   }
783 //_________________________________________________________________________
784 Float_t AliTOFtrackerV1::CorrectTimeWalk( Float_t dist, Float_t tof) {
785
786   //dummy, for the moment
787   Float_t tofcorr=0.;
788   if(dist<AliTOFGeometry::ZPad()*0.5){
789     tofcorr=tof;
790     //place here the actual correction
791   }else{
792     tofcorr=tof; 
793   } 
794   return tofcorr;
795 }
796 //_________________________________________________________________________
797 Float_t AliTOFtrackerV1::GetTimeZerofromT0(AliESDEvent *event) const {
798
799   //Returns TimeZero as measured by T0 detector
800
801   return event->GetT0();
802 }
803 //_________________________________________________________________________
804 Float_t AliTOFtrackerV1::GetTimeZerofromTOF(AliESDEvent * /*event*/) const {
805
806   //dummy, for the moment. T0 algorithm using tracks on TOF
807   {
808     //place T0 algo here...
809   }
810   return 0.;
811 }
812 //_________________________________________________________________________
813
814 void AliTOFtrackerV1::FillClusterArray(TObjArray* arr) const
815 {
816   //
817   // Returns the TOF cluster array
818   //
819
820   if (fN==0)
821     arr = 0x0;
822   else
823     for (Int_t i=0; i<fN; ++i) arr->Add(fClusters[i]);
824
825 }