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