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