]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TOF/AliTOFtracker.cxx
4b853c9272ae030c2fcda1545199b99aaed176af
[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 <TObjArray.h>
35 #include <TGeoManager.h>
36 #include <TTree.h>
37 #include <TFile.h>
38 #include <TH2F.h>
39
40 #include "AliGeomManager.h"
41 #include "AliESDtrack.h"
42 #include "AliESDEvent.h"
43 #include "AliESDpid.h"
44 #include "AliLog.h"
45 #include "AliTrackPointArray.h"
46 #include "AliCDBManager.h"
47
48 //#include "AliTOFpidESD.h"
49 #include "AliTOFRecoParam.h"
50 #include "AliTOFReconstructor.h"
51 #include "AliTOFcluster.h"
52 #include "AliTOFGeometry.h"
53 #include "AliTOFtracker.h"
54 #include "AliTOFtrack.h"
55
56 extern TGeoManager *gGeoManager;
57 //extern TROOT *gROOT;
58
59
60 ClassImp(AliTOFtracker)
61
62 //_____________________________________________________________________________
63 AliTOFtracker::AliTOFtracker():
64   fkRecoParam(0x0),
65   fGeom(0x0),
66   fN(0),
67   fNseeds(0),
68   fNseedsTOF(0),
69   fngoodmatch(0),
70   fnbadmatch(0),
71   fnunmatch(0),
72   fnmatch(0),
73   fTracks(new TClonesArray("AliTOFtrack")),
74   fSeeds(new TObjArray(100)),
75   fTOFtrackPoints(new TObjArray(10)),
76   fHDigClusMap(0x0),
77   fHDigNClus(0x0),
78   fHDigClusTime(0x0),
79   fHDigClusToT(0x0),
80   fHRecNClus(0x0),
81   fHRecDist(0x0),
82   fHRecSigYVsP(0x0),
83   fHRecSigZVsP(0x0),
84   fHRecSigYVsPWin(0x0),
85   fHRecSigZVsPWin(0x0),
86   fCalTree(0x0),
87   fIch(-1),
88   fToT(-1.),
89   fTime(-1.),
90   fExpTimePi(-1.),
91   fExpTimeKa(-1.),
92   fExpTimePr(-1.),
93   fNTOFmatched(0)
94 {
95   //AliTOFtracker main Ctor
96
97   for (Int_t ii=0; ii<kMaxCluster; ii++) fClusters[ii]=0x0;
98
99   // Getting the geometry
100   fGeom = new AliTOFGeometry();
101
102   for(Int_t i=0; i< 20000;i++){
103     fClusterESD[i] = NULL;
104   }
105
106   InitCheckHists();
107
108 }
109 //_____________________________________________________________________________
110 AliTOFtracker::~AliTOFtracker() {
111   //
112   // Dtor
113   //
114
115   SaveCheckHists();
116
117   if(!(AliCDBManager::Instance()->GetCacheFlag())){
118     delete fkRecoParam;
119   }
120   delete fGeom; 
121   delete fHDigClusMap;
122   delete fHDigNClus;
123   delete fHDigClusTime;
124   delete fHDigClusToT;
125   delete fHRecNClus;
126   delete fHRecDist;
127   delete fHRecSigYVsP;
128   delete fHRecSigZVsP;
129   delete fHRecSigYVsPWin;
130   delete fHRecSigZVsPWin;
131   delete fCalTree;
132   if (fTracks){
133     fTracks->Delete();
134     delete fTracks;
135     fTracks=0x0;
136   }
137   if (fSeeds){
138     fSeeds->Delete();
139     delete fSeeds;
140     fSeeds=0x0;
141   }
142   if (fTOFtrackPoints){
143     fTOFtrackPoints->Delete();
144     delete fTOFtrackPoints;
145     fTOFtrackPoints=0x0;
146   }
147
148   for (Int_t ii=0; ii<kMaxCluster; ii++)
149     if (fClusters[ii]) fClusters[ii]->Delete();
150
151   for(Int_t i=0; i< 20000;i++){
152     if(fClusterESD[i]){
153       delete fClusterESD[i];
154       fClusterESD[i] = NULL;
155     }
156   }
157
158
159 }
160 //_____________________________________________________________________________
161 void AliTOFtracker::GetPidSettings(AliESDpid *esdPID) {
162   // 
163   // Sets TOF resolution from RecoParams
164   //
165   if (fkRecoParam)
166     esdPID->GetTOFResponse().SetTimeResolution(fkRecoParam->GetTimeResolution());
167   else
168     AliWarning("fkRecoParam not yet set; cannot set PID settings");
169
170 //_____________________________________________________________________________
171 Int_t AliTOFtracker::PropagateBack(AliESDEvent * const event) {
172   //
173   // Gets seeds from ESD event and Match with TOF Clusters
174   //
175
176   if(fNTOFmatched==0)
177     event->SetTOFcluster(1,fClusterESD);
178
179   if (fNTOFmatched==0) {
180     AliInfo("No TOF recPoints to be matched with reconstructed tracks");
181     return 0;
182   }
183
184   // initialize RecoParam for current event
185   AliDebug(1,"Initializing params for TOF");
186
187   fkRecoParam = AliTOFReconstructor::GetRecoParam();  // instantiate reco param from STEER...
188
189   if (fkRecoParam == 0x0) { 
190     AliFatal("No Reco Param found for TOF!!!");
191   }
192   //fkRecoParam->Dump();
193   //if(fkRecoParam->GetApplyPbPbCuts())fkRecoParam=fkRecoParam->GetPbPbparam();
194   //fkRecoParam->PrintParameters();
195
196   //Initialise some counters
197
198   fNseeds=0;
199   fNseedsTOF=0;
200   fngoodmatch=0;
201   fnbadmatch=0;
202   fnunmatch=0;
203   fnmatch=0;
204
205   Int_t ntrk=event->GetNumberOfTracks();
206   fNseeds = ntrk;
207
208
209   //Load ESD tracks into a local Array of ESD Seeds
210   for (Int_t i=0; i<fNseeds; i++){
211     fSeeds->AddLast(event->GetTrack(i));
212     event->GetTrack(i)->SetESDEvent(event);
213   }
214
215   //Prepare ESD tracks candidates for TOF Matching
216   CollectESD();
217
218   if (fNseeds==0 || fNseedsTOF==0) {
219     event->SetTOFcluster(1,fClusterESD);
220     AliInfo("No seeds to try TOF match");
221     return 0 ;
222   }
223
224   //First Step with Strict Matching Criterion
225   MatchTracks(0);
226
227   //Second Step with Looser Matching Criterion
228   MatchTracks(1);
229
230   //Third Step without kTOFout flag (just to update clusters)
231   MatchTracks(2);
232
233   event->SetTOFcluster(fNTOFmatched,fClusterESD); 
234  
235   if (fNTOFmatched==0) {
236     AliInfo("No TOF recPoints to be matched with reconstructed tracks");
237     return 0;
238   }
239
240   AliInfo(Form("Number of matched tracks = %d (good = %d, bad = %d)",fnmatch,fngoodmatch,fnbadmatch));
241
242   //Update the matched ESD tracks
243
244   for (Int_t i=0; i<ntrk; i++) {
245     AliESDtrack *t=event->GetTrack(i);
246     AliESDtrack *seed =(AliESDtrack*)fSeeds->At(i);
247
248     if ( (seed->GetStatus()&AliESDtrack::kTOFin)!=0 ) {
249       t->SetStatus(AliESDtrack::kTOFin);
250       //if(seed->GetTOFsignal()>0){
251       if ( (seed->GetStatus()&AliESDtrack::kTOFout)!=0 ) {
252         t->SetStatus(AliESDtrack::kTOFout);
253         t->SetTOFsignal(seed->GetTOFsignal());
254         t->SetTOFcluster(seed->GetTOFcluster());
255         t->SetTOFsignalToT(seed->GetTOFsignalToT());
256         t->SetTOFsignalRaw(seed->GetTOFsignalRaw());
257         t->SetTOFsignalDz(seed->GetTOFsignalDz());
258         t->SetTOFsignalDx(seed->GetTOFsignalDx());
259         t->SetTOFDeltaBC(seed->GetTOFDeltaBC());
260         t->SetTOFL0L1(seed->GetTOFL0L1());
261         t->SetTOFCalChannel(seed->GetTOFCalChannel());
262         Int_t tlab[3]; seed->GetTOFLabel(tlab);    
263         t->SetTOFLabel(tlab);
264
265         Double_t alphaA = (Double_t)t->GetAlpha();
266         Double_t xA = (Double_t)t->GetX();
267         Double_t yA = (Double_t)t->GetY();
268         Double_t zA = (Double_t)t->GetZ();
269         Double_t p1A = (Double_t)t->GetSnp();
270         Double_t p2A = (Double_t)t->GetTgl();
271         Double_t p3A = (Double_t)t->GetSigned1Pt();
272         const Double_t *covA = (Double_t*)t->GetCovariance();
273
274         // Make attention, please:
275         //      AliESDtrack::fTOFInfo array does not be stored in the AliESDs.root file
276         //      it is there only for a check during the reconstruction step.
277         Float_t info[10]; seed->GetTOFInfo(info);
278         t->SetTOFInfo(info);
279         AliDebug(3,Form(" distance=%f; residual in the pad reference frame: dX=%f, dZ=%f", info[0],info[1],info[2]));
280
281         // Check done:
282         //       by calling the AliESDtrack::UpdateTrackParams,
283         //       the current track parameters are changed
284         //       and it could cause refit problems.
285         //       We need to update only the following track parameters:
286         //            the track length and expected times.
287         //       Removed AliESDtrack::UpdateTrackParams call
288         //       Called AliESDtrack::SetIntegratedTimes(...) and
289         //       AliESDtrack::SetIntegratedLength() routines.
290         /*
291           AliTOFtrack *track = new AliTOFtrack(*seed);
292           t->UpdateTrackParams(track,AliESDtrack::kTOFout); // to be checked - AdC
293           delete track;
294           Double_t time[AliPID::kSPECIESC]; t->GetIntegratedTimes(time);
295         */
296
297         Double_t time[AliPID::kSPECIESC]; seed->GetIntegratedTimes(time);
298         t->SetIntegratedTimes(time);
299
300         Double_t length =  seed->GetIntegratedLength();
301         t->SetIntegratedLength(length);
302
303         Double_t alphaB = (Double_t)t->GetAlpha();
304         Double_t xB = (Double_t)t->GetX();
305         Double_t yB = (Double_t)t->GetY();
306         Double_t zB = (Double_t)t->GetZ();
307         Double_t p1B = (Double_t)t->GetSnp();
308         Double_t p2B = (Double_t)t->GetTgl();
309         Double_t p3B = (Double_t)t->GetSigned1Pt();
310         const Double_t *covB = (Double_t*)t->GetCovariance();
311         AliDebug(3,"Track params -now(before)-:");
312         AliDebug(3,Form("    X: %f(%f), Y: %f(%f), Z: %f(%f) --- alpha: %f(%f)",
313                         xB,xA,
314                         yB,yA,
315                         zB,zA,
316                         alphaB,alphaA));
317         AliDebug(3,Form("    p1: %f(%f), p2: %f(%f), p3: %f(%f)",
318                         p1B,p1A,
319                         p2B,p2A,
320                         p3B,p3A));
321         AliDebug(3,Form("    cov1: %f(%f), cov2: %f(%f), cov3: %f(%f)"
322                         " cov4: %f(%f), cov5: %f(%f), cov6: %f(%f)"
323                         " cov7: %f(%f), cov8: %f(%f), cov9: %f(%f)"
324                         " cov10: %f(%f), cov11: %f(%f), cov12: %f(%f)"
325                         " cov13: %f(%f), cov14: %f(%f), cov15: %f(%f)",
326                         covB[0],covA[0],
327                         covB[1],covA[1],
328                         covB[2],covA[2],
329                         covB[3],covA[3],
330                         covB[4],covA[4],
331                         covB[5],covA[5],
332                         covB[6],covA[6],
333                         covB[7],covA[7],
334                         covB[8],covA[8],
335                         covB[9],covA[9],
336                         covB[10],covA[10],
337                         covB[11],covA[11],
338                         covB[12],covA[12],
339                         covB[13],covA[13],
340                         covB[14],covA[14]
341                         ));
342         AliDebug(2,Form(" TOF params: %6d  %f %f %f %f %f %6d %3d  %f",
343                         i,
344                         t->GetTOFsignalRaw(),
345                         t->GetTOFsignal(),
346                         t->GetTOFsignalToT(),
347                         t->GetTOFsignalDz(),
348                         t->GetTOFsignalDx(),
349                         t->GetTOFCalChannel(),
350                         t->GetTOFcluster(),
351                         t->GetIntegratedLength()));
352         AliDebug(2,Form(" %f %f %f %f %f %f %f %f %f",
353                         time[0], time[1], time[2], time[3], time[4], time[5], time[6], time[7], time[8]));
354       }
355     }
356   }
357
358   if(fNTOFmatched){
359     Int_t *matchmap = new Int_t[fNTOFmatched];
360     event->SetTOFcluster(fNTOFmatched,fClusterESD,matchmap);
361     for (Int_t i=0; i<ntrk; i++) { // remapping after TOF matching selection
362       AliESDtrack *t=event->GetTrack(i);
363       t->ReMapTOFcluster(fNTOFmatched,matchmap);
364     }
365
366     delete[] matchmap;
367   }
368
369   //Make TOF PID
370   // Now done in AliESDpid
371   // fPid->MakePID(event,timeZero);
372
373   fSeeds->Clear();
374   //fTracks->Delete();
375   fTracks->Clear();
376   return 0;
377   
378 }
379 //_________________________________________________________________________
380 void AliTOFtracker::CollectESD() {
381    //prepare the set of ESD tracks to be matched to clusters in TOF
382
383   Int_t seedsTOF1=0;
384   Int_t seedsTOF3=0;
385   Int_t seedsTOF2=0;
386  
387   TClonesArray &aTOFTrack = *fTracks;
388   for (Int_t i=0; i<fNseeds; i++) {
389
390     AliESDtrack *t =(AliESDtrack*)fSeeds->At(i);
391     if ((t->GetStatus()&AliESDtrack::kTPCout)==0)continue;
392
393     AliTOFtrack *track = new AliTOFtrack(*t); // New
394     Float_t x = (Float_t)track->GetX(); //New
395
396     // TRD 'good' tracks
397     if ( ( (t->GetStatus()&AliESDtrack::kTRDout)!=0 ) ) {
398
399       AliDebug(1,Form(" Before propagation till inner TOF radius, ESDtrackLength=%f, TOFtrackLength=%f",t->GetIntegratedLength(),track->GetIntegratedLength()));
400
401       // TRD 'good' tracks, already propagated at 371 cm
402       if( x >= AliTOFGeometry::Rmin() ) {
403
404         if  ( track->PropagateToInnerTOF() ) {
405
406           AliDebug(1,Form(" TRD propagated track till rho = %fcm."
407                           " And then the track has been propagated till rho = %fcm.",
408                           x, (Float_t)track->GetX()));
409
410           track->SetSeedIndex(i);
411           t->UpdateTrackParams(track,AliESDtrack::kTOFin);
412           new(aTOFTrack[fNseedsTOF]) AliTOFtrack(*track);
413           fNseedsTOF++;
414           seedsTOF1++;
415
416           AliDebug(1,Form(" After propagation till inner TOF radius, ESDtrackLength=%f, TOFtrackLength=%f",t->GetIntegratedLength(),track->GetIntegratedLength()));
417         }
418         delete track;
419
420       }
421       else { // TRD 'good' tracks, propagated rho<371cm
422
423         if  ( track->PropagateToInnerTOF() ) {
424
425           AliDebug(1,Form(" TRD propagated track till rho = %fcm."
426                           " And then the track has been propagated till rho = %fcm.",
427                           x, (Float_t)track->GetX()));
428
429           track->SetSeedIndex(i);
430           t->UpdateTrackParams(track,AliESDtrack::kTOFin);
431           new(aTOFTrack[fNseedsTOF]) AliTOFtrack(*track);
432           fNseedsTOF++;
433           seedsTOF3++;
434
435           AliDebug(1,Form(" After propagation till inner TOF radius, ESDtrackLength=%f, TOFtrackLength=%f",t->GetIntegratedLength(),track->GetIntegratedLength()));
436         }
437         delete track;
438
439       }
440       //delete track;
441     }
442
443     else { // Propagate the rest of TPCbp
444
445       AliDebug(1,Form(" Before propagation till inner TOF radius, ESDtrackLength=%f, TOFtrackLength=%f",t->GetIntegratedLength(),track->GetIntegratedLength()));
446
447       if ( track->PropagateToInnerTOF() ) { 
448
449         AliDebug(1,Form(" TPC propagated track till rho = %fcm."
450                         " And then the track has been propagated till rho = %fcm.",
451                         x, (Float_t)track->GetX()));
452
453         track->SetSeedIndex(i);
454         t->UpdateTrackParams(track,AliESDtrack::kTOFin);
455         new(aTOFTrack[fNseedsTOF]) AliTOFtrack(*track);
456         fNseedsTOF++;
457         seedsTOF2++;
458
459         AliDebug(1,Form(" After propagation till inner TOF radius, ESDtrackLength=%f, TOFtrackLength=%f",t->GetIntegratedLength(),track->GetIntegratedLength()));
460       }
461       delete track;
462     }
463   }
464
465   AliInfo(Form("Number of TOF seeds = %d (kTRDout371 = %d, kTRDoutLess371 = %d, !kTRDout = %d)",fNseedsTOF,seedsTOF1,seedsTOF3,seedsTOF2));
466
467   // Sort according uncertainties on track position 
468   fTracks->Sort();
469
470 }
471
472 //_________________________________________________________________________
473 void AliTOFtracker::MatchTracks( Int_t mLastStep){
474
475   // Parameters used/regulating the reconstruction
476
477   //static Float_t corrLen=0.;//0.75;
478   static Float_t detDepth=18.;
479   static Float_t padDepth=0.5;
480
481   const Float_t kSpeedOfLight= 2.99792458e-2; // speed of light [cm/ps]
482   const Float_t kTimeOffset = 0.; // time offset for tracking algorithm [ps]
483
484   Float_t dY=AliTOFGeometry::XPad(); 
485   Float_t dZ=AliTOFGeometry::ZPad(); 
486
487   Float_t sensRadius = fkRecoParam->GetSensRadius();
488   Float_t stepSize   = fkRecoParam->GetStepSize();
489   Float_t scaleFact  = fkRecoParam->GetWindowScaleFact();
490   Float_t dyMax=fkRecoParam->GetWindowSizeMaxY(); 
491   Float_t dzMax=fkRecoParam->GetWindowSizeMaxZ();
492   Float_t dCut=fkRecoParam->GetDistanceCut();
493   if (dCut==3. && fNseedsTOF<=10) {
494     dCut=10.;
495     AliInfo(Form("Matching window=%f, since low multiplicity event (fNseedsTOF=%d)",
496                  dCut, fNseedsTOF));
497   }
498   if(mLastStep == 2)
499     dCut=10.;
500
501
502   Double_t maxChi2=fkRecoParam->GetMaxChi2TRD();
503   Bool_t timeWalkCorr    = fkRecoParam->GetTimeWalkCorr();
504   if(!mLastStep){
505     AliDebug(1,"++++++++++++++TOF Reconstruction Parameters:++++++++++++");
506     AliDebug(1,Form("TOF sens radius: %f",sensRadius));
507     AliDebug(1,Form("TOF step size: %f",stepSize));
508     AliDebug(1,Form("TOF Window scale factor: %f",scaleFact));
509     AliDebug(1,Form("TOF Window max dy: %f",dyMax));
510     AliDebug(1,Form("TOF Window max dz: %f",dzMax));
511     AliDebug(1,Form("TOF distance Cut: %f",dCut));
512     AliDebug(1,Form("TOF Max Chi2: %f",maxChi2));
513     AliDebug(1,Form("Time Walk Correction? : %d",timeWalkCorr));   
514   }
515
516   //Match ESD tracks to clusters in TOF
517
518   // Get the number of propagation steps
519   Int_t nSteps=(Int_t)(detDepth/stepSize);
520   AliDebug(1,Form(" Number of steps to be done %d",nSteps));
521
522   AliDebug(1,"++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
523
524   //PH Arrays (moved outside of the loop)
525   Float_t * trackPos[4];
526   for (Int_t ii=0; ii<4; ii++) trackPos[ii] = new Float_t[nSteps];
527   Int_t * clind = new Int_t[fN];
528   
529   // Some init
530   const Int_t kNclusterMax = 1000; // related to fN value
531   TGeoHMatrix global[kNclusterMax];
532
533   //The matching loop
534   for (Int_t iseed=0; iseed<fNseedsTOF; iseed++) {
535
536     fTOFtrackPoints->Delete();
537
538     for (Int_t ii=0; ii<kNclusterMax; ii++)
539       global[ii] = 0x0;
540     AliTOFtrack *track =(AliTOFtrack*)fTracks->UncheckedAt(iseed);
541     AliESDtrack *t =(AliESDtrack*)fSeeds->At(track->GetSeedIndex());
542     //if ( t->GetTOFsignal()>0. ) continue;
543     if ( ((t->GetStatus()&AliESDtrack::kTOFout)!=0 ) && mLastStep < 2) continue;
544     AliTOFtrack *trackTOFin = new AliTOFtrack(*track);
545
546     // Determine a window around the track
547     Double_t x,par[5]; 
548     trackTOFin->GetExternalParameters(x,par);
549     Double_t cov[15]; 
550     trackTOFin->GetExternalCovariance(cov);
551
552     if (cov[0]<0. || cov[2]<0.) {
553       AliWarning(Form("Very strange track (%d)! At least one of its covariance matrix diagonal elements is negative!",iseed));
554       //delete trackTOFin;
555       //continue;
556     }
557
558     Double_t dphi=
559       scaleFact*
560       ((5*TMath::Sqrt(TMath::Abs(cov[0])) + 0.5*dY + 2.5*TMath::Abs(par[2]))/sensRadius); 
561     Double_t dz=
562        scaleFact*
563        (5*TMath::Sqrt(TMath::Abs(cov[2])) + 0.5*dZ + 2.5*TMath::Abs(par[3]));
564
565     Double_t phi=TMath::ATan2(par[0],x) + trackTOFin->GetAlpha();
566     if (phi<-TMath::Pi())phi+=2*TMath::Pi();
567     if (phi>=TMath::Pi())phi-=2*TMath::Pi();
568     Double_t z=par[1];   
569
570     //upper limit on window's size.
571     if (dz> dzMax) dz=dzMax;
572     if (dphi*sensRadius> dyMax) dphi=dyMax/sensRadius;
573
574
575     // find the clusters in the window of the track
576     Int_t nc=0;
577     for (Int_t k=FindClusterIndex(z-dz); k<fN; k++) {
578
579       if (nc>=kNclusterMax) {
580         AliWarning("No more matchable clusters can be stored! Please, increase the corresponding vectors size.");
581         break;
582       }
583
584       AliTOFcluster *c=fClusters[k];
585       if (c->GetZ() > z+dz) break;
586       if (c->IsUsed() && mLastStep < 2) continue;
587       if (!c->GetStatus()) {
588         AliDebug(1,"Cluster in channel declared bad!");
589         continue; // skip bad channels as declared in OCDB
590       }
591
592       Double_t dph=TMath::Abs(c->GetPhi()-phi);
593       if (dph>TMath::Pi()) dph-=2.*TMath::Pi();
594       if (TMath::Abs(dph)>dphi) continue;
595
596       Double_t yc=(c->GetPhi() - trackTOFin->GetAlpha())*c->GetR();
597       Double_t p[2]={yc, c->GetZ()};
598       Double_t cov2[3]= {dY*dY/12., 0., dZ*dZ/12.};
599       if (trackTOFin->AliExternalTrackParam::GetPredictedChi2(p,cov2) > maxChi2)continue;
600
601       clind[nc] = k;      
602       Char_t path[200];
603       Int_t ind[5];
604       ind[0]=c->GetDetInd(0);
605       ind[1]=c->GetDetInd(1);
606       ind[2]=c->GetDetInd(2);
607       ind[3]=c->GetDetInd(3);
608       ind[4]=c->GetDetInd(4);
609       fGeom->GetVolumePath(ind,path);
610       gGeoManager->cd(path);
611       global[nc] = *gGeoManager->GetCurrentMatrix();
612       nc++;
613     }
614
615     if (nc == 0 ) {
616       AliDebug(1,Form("No available clusters for the track number %d",iseed));
617       fnunmatch++;
618       delete trackTOFin;
619       continue;
620     }
621
622     AliDebug(1,Form(" Number of available TOF clusters for the track number %d: %d",iseed,nc));
623
624     //start fine propagation 
625
626     Int_t nStepsDone = 0;
627     for( Int_t istep=0; istep<nSteps; istep++){ 
628
629       // First of all, propagate the track...
630       Float_t xs = AliTOFGeometry::RinTOF()+istep*stepSize;
631       if (!(trackTOFin->PropagateTo(xs))) break;
632
633       //  ...and then, if necessary, rotate the track
634       Double_t ymax = xs*TMath::Tan(0.5*AliTOFGeometry::GetAlpha());
635       Double_t ysect = trackTOFin->GetY();
636       if (ysect > ymax) {
637         if (!(trackTOFin->Rotate(AliTOFGeometry::GetAlpha()))) break;
638       } else if (ysect <-ymax) {
639         if (!(trackTOFin->Rotate(-AliTOFGeometry::GetAlpha()))) break;
640       }
641
642       nStepsDone++;
643       AliDebug(3,Form(" current step %d (%d) - nStepsDone=%d",istep,nSteps,nStepsDone));
644
645       // store the running point (Globalrf) - fine propagation     
646
647       Double_t r[3];
648       trackTOFin->GetXYZ(r);
649       trackPos[0][nStepsDone-1]= (Float_t) r[0];
650       trackPos[1][nStepsDone-1]= (Float_t) r[1];
651       trackPos[2][nStepsDone-1]= (Float_t) r[2];   
652       trackPos[3][nStepsDone-1]= trackTOFin->GetIntegratedLength();
653     }
654
655
656 #if 0
657     /*****************/
658     /**** OLD CODE ***/
659     /*****************/
660
661     Int_t nfound = 0;
662     Bool_t accept = kFALSE;
663     Bool_t isInside = kFALSE;
664     for (Int_t istep=0; istep<nStepsDone; istep++) {
665
666       Float_t ctrackPos[3];     
667       ctrackPos[0] = trackPos[0][istep];
668       ctrackPos[1] = trackPos[1][istep];
669       ctrackPos[2] = trackPos[2][istep];
670
671       //now see whether the track matches any of the TOF clusters            
672
673       Float_t dist3d[3];
674       accept = kFALSE;
675       for (Int_t i=0; i<nc; i++) {
676         isInside = fGeom->IsInsideThePad((TGeoHMatrix*)(&global[i]),ctrackPos,dist3d);
677
678         if ( mLastStep ) {
679           Float_t yLoc = dist3d[1];
680           Float_t rLoc = TMath::Sqrt(dist3d[0]*dist3d[0]+dist3d[2]*dist3d[2]);
681           accept = (TMath::Abs(yLoc)<padDepth*0.5 && rLoc<dCut);
682           AliDebug(3," I am in the case mLastStep==kTRUE ");
683         }
684         else {
685           accept = isInside;
686         }
687         if (accept) {
688
689           fTOFtrackPoints->AddLast(new AliTOFtrackPoint(clind[i],
690                                                         TMath::Sqrt(dist3d[0]*dist3d[0] + dist3d[1]*dist3d[1] + dist3d[2]*dist3d[2]),
691                                                         dist3d[2],dist3d[0],dist3d[1],
692                                                         AliTOFGeometry::RinTOF()+istep*stepSize,trackPos[3][istep]));
693
694           AliDebug(3,Form(" dist3dLoc[0] = %f, dist3dLoc[1] = %f, dist3dLoc[2] = %f ",dist3d[0],dist3d[1],dist3d[2]));
695           nfound++;
696           if(accept &&!mLastStep)break;
697         }//end if accept
698
699       } //end for on the clusters
700       if(accept &&!mLastStep)break;
701     } //end for on the steps     
702
703     /*****************/
704     /**** OLD CODE ***/
705     /*****************/
706 #endif
707
708     if ( nStepsDone == 0 ) {
709       AliDebug(1,Form(" No track points for the track number %d",iseed));
710       fnunmatch++;
711       delete trackTOFin;
712       continue;
713     }
714
715     AliDebug(2,Form(" Number of steps done for the track number %d: %d",iseed,nStepsDone));
716
717     /*****************/
718     /**** NEW CODE ***/
719     /*****************/
720
721     Int_t *isClusterMatchable = NULL;
722     if(nc){
723       isClusterMatchable = new Int_t[nc];
724       for (Int_t i=0; i<nc; i++) isClusterMatchable[i] = kFALSE;                
725     }
726
727     Int_t nfound = 0;
728     Bool_t accept = kFALSE;
729     Bool_t isInside = kFALSE;
730     for (Int_t istep=0; istep<nStepsDone; istep++) {
731
732       Bool_t gotInsideCluster = kFALSE;
733       Int_t trackInsideCluster = -1;
734
735       Float_t ctrackPos[3];     
736       ctrackPos[0] = trackPos[0][istep];
737       ctrackPos[1] = trackPos[1][istep];
738       ctrackPos[2] = trackPos[2][istep];
739
740       //now see whether the track matches any of the TOF clusters            
741
742       Float_t dist3d[3]={0.,0.,0.};
743       accept = kFALSE;
744       for (Int_t i=0; i<nc; i++) {
745
746         // ***** NEW *****
747         /* check whether track was inside another cluster
748          * and in case inhibit this cluster.
749          * this will allow to only go on and add track points for
750          * that cluster where the track got inside first */
751         if (gotInsideCluster && trackInsideCluster != i) {
752           AliDebug(3,Form(" A - istep=%d ~ %d %d ~ nfound=%d",istep,trackInsideCluster,i,nfound));
753           continue;
754         }
755         AliDebug(3,Form(" B - istep=%d ~ %d %d ~ nfound=%d",istep,trackInsideCluster,i,nfound));
756
757         /* check whether track is inside this cluster */
758         for (Int_t hh=0; hh<3; hh++) dist3d[hh]=0.;
759         isInside = fGeom->IsInsideThePad((TGeoHMatrix*)(&global[i]),ctrackPos,dist3d);
760
761         // ***** NEW *****
762         /* if track is inside this cluster set flags which will then
763          * inhibit to add track points for the other clusters */
764         if (isInside) {
765           gotInsideCluster = kTRUE;
766           trackInsideCluster = i;
767         }
768
769         if ( mLastStep ) {
770           Float_t yLoc = dist3d[1];
771           Float_t rLoc = TMath::Sqrt(dist3d[0]*dist3d[0]+dist3d[2]*dist3d[2]);
772           accept = (TMath::Abs(yLoc)<padDepth*0.5 && rLoc<dCut);
773           AliDebug(3," I am in the case mLastStep==kTRUE ");
774         }
775
776         //***** NEW *****
777         /* add point everytime that:
778          * - the track is inside the cluster
779          * - the track got inside the cluster, even when it eventually exited the cluster
780          * - the tracks is within dCut from the cluster
781          */
782         if (accept || isInside || gotInsideCluster) {
783
784           fTOFtrackPoints->AddLast(new AliTOFtrackPoint(clind[i],
785                                                         TMath::Sqrt(dist3d[0]*dist3d[0] + dist3d[1]*dist3d[1] + dist3d[2]*dist3d[2]),
786                                                         dist3d[2],dist3d[0],dist3d[1],
787                                                         AliTOFGeometry::RinTOF()+istep*stepSize,trackPos[3][istep]));
788
789           AliDebug(2,Form(" dist3dLoc[0] = %f, dist3dLoc[1] = %f, dist3dLoc[2] = %f ",dist3d[0],dist3d[1],dist3d[2]));
790           nfound++;
791
792           AliDebug(3,Form(" C - istep=%d ~ %d %d ~ nfound=%d",istep,trackInsideCluster,i,nfound));
793         
794
795           if(clind[i] < 20000 && mLastStep==2 && !isClusterMatchable[i]){ // add TOF clusters to the track
796             isClusterMatchable[i] = kTRUE;
797
798             //Tracking info
799             Double_t mom=t->GetP();
800             AliDebug(3,Form(" Momentum for track %d -> %f", iseed,mom));
801             Double_t time[AliPID::kSPECIESC];
802             // read from old structure (the one used by TPC in reco)
803             for(Int_t isp=0;isp<AliPID::kSPECIESC;isp++){
804               time[isp] = t->GetIntegratedTimesOld(isp); // in ps
805               Double_t mass=AliPID::ParticleMass(isp);
806               Double_t momz = mom*AliPID::ParticleCharge(isp);
807               time[isp]+=(trackPos[3][istep]-trackPos[3][0])/kSpeedOfLight*TMath::Sqrt(momz*momz+mass*mass)/momz;
808               //time[isp]+=(trackPos[3][istep]-trackPos[3][0])/kSpeedOfLight*TMath::Sqrt(mom*mom+mass*mass)/mom;
809             }
810
811             if(!fClusterESD[clind[i]]->Update(t->GetID(),dist3d[1],dist3d[0],dist3d[2],trackPos[3][istep],time))//x,y,z -> tracking RF
812               t->AddTOFcluster(clind[i]);
813           }
814
815           // ***** NEW *****
816           /* do not break loop in any case
817            * if the track got inside a cluster all other clusters
818            * are inhibited */
819           //      if(accept &&!mLastStep)break;
820           
821         }//end if accept
822         
823       } //end for on the clusters
824       
825       // ***** NEW *****
826       /* do not break loop in any case
827       * if the track got inside a cluster all other clusters
828       * are inhibited but we want to go on adding track points */
829       //      if(accept &&!mLastStep)break;
830       
831     } //end for on the steps     
832     if(nc) delete[] isClusterMatchable;
833
834     if (nfound == 0 ) {
835       AliDebug(1,Form("No track points for the track number %d",iseed));
836       fnunmatch++;
837       delete trackTOFin;
838       continue;
839     }
840     
841     AliDebug(1,Form(" Number of track points for the track number %d: %d",iseed,nfound));
842
843     // now choose the cluster to be matched with the track.
844
845     Int_t idclus=-1;
846     Float_t  recL = 0.;
847     Float_t  xpos=0.;
848     Float_t  mindist=1000.;
849     Float_t  mindistZ=0.;
850     Float_t  mindistY=0.;
851     Float_t  mindistX=stepSize;
852     for (Int_t iclus= 0; iclus<nfound;iclus++) {
853       AliTOFtrackPoint *matchableTOFcluster = (AliTOFtrackPoint*)fTOFtrackPoints->At(iclus);
854       //if ( matchableTOFcluster->Distance()<mindist ) {
855       if ( TMath::Abs(matchableTOFcluster->DistanceX())<TMath::Abs(mindistX) &&
856            TMath::Abs(matchableTOFcluster->DistanceX())<=stepSize ) {
857         mindist = matchableTOFcluster->Distance();
858         mindistZ = matchableTOFcluster->DistanceZ(); // Z distance in the
859                                                      // RF of the hit pad
860                                                      // closest to the
861                                                      // reconstructed
862                                                      // track
863         mindistY = matchableTOFcluster->DistanceY(); // Y distance in the
864                                                      // RF of the hit pad
865                                                      // closest to the
866                                                      // reconstructed
867                                                      // track
868         mindistX = matchableTOFcluster->DistanceX(); // X distance in the
869                                                      // RF of the hit pad
870                                                      // closest to the
871                                                      // reconstructed
872                                                      // track
873         xpos = matchableTOFcluster->PropRadius();
874         idclus = matchableTOFcluster->Index();
875         recL = matchableTOFcluster->Length();// + corrLen*0.5;
876
877         AliDebug(2,Form(" %d(%d) --- %f (%f, %f, %f), step=%f -- idclus=%d --- seed=%d, trackId=%d, trackLab=%d", iclus,nfound,
878                         mindist,mindistX,mindistY,mindistZ,stepSize,idclus,iseed,track->GetSeedIndex(),track->GetLabel()));
879
880       }
881     } // loop on found TOF track points
882
883     if (TMath::Abs(mindistX)>stepSize && idclus!=-1) {
884       AliInfo(Form(" %d - not matched --- but idclus=%d, trackId=%d, trackLab=%d",iseed,
885                    idclus,track->GetSeedIndex(),track->GetLabel()));
886       idclus=-1;
887     }
888
889     if (idclus==-1) {
890       AliDebug(1,Form("Reconstructed track %d doesn't match any TOF cluster", iseed));
891       fnunmatch++;
892       delete trackTOFin;
893       continue;
894     }
895
896     AliDebug(1,Form(" %d - matched",iseed));
897
898     fnmatch++;
899
900     AliTOFcluster *c=fClusters[idclus];
901
902     AliDebug(3, Form("%7d     %7d     %10d     %10d  %10d  %10d      %7d",
903                      iseed,
904                      fnmatch-1,
905                      TMath::Abs(trackTOFin->GetLabel()),
906                      c->GetLabel(0), c->GetLabel(1), c->GetLabel(2),
907                      idclus)); // AdC
908
909     c->Use(); 
910
911     // Track length correction for matching Step 2 
912     /*
913     if (mLastStep) {
914       Float_t rc = TMath::Sqrt(c->GetR()*c->GetR() + c->GetZ()*c->GetZ());
915       Float_t rt = TMath::Sqrt(trackPos[0][70]*trackPos[0][70]
916                                +trackPos[1][70]*trackPos[1][70]
917                                +trackPos[2][70]*trackPos[2][70]);
918       Float_t dlt=rc-rt;
919       recL=trackPos[3][70]+dlt;
920     }
921     */
922     if (
923         (c->GetLabel(0)==TMath::Abs(trackTOFin->GetLabel()))
924         ||
925         (c->GetLabel(1)==TMath::Abs(trackTOFin->GetLabel()))
926         ||
927         (c->GetLabel(2)==TMath::Abs(trackTOFin->GetLabel()))
928         ) {
929       fngoodmatch++;
930
931        AliDebug(2,Form(" track label good %5d",trackTOFin->GetLabel()));
932
933     }
934     else {
935       fnbadmatch++;
936
937       AliDebug(2,Form(" track label  bad %5d",trackTOFin->GetLabel()));
938
939     }
940
941     delete trackTOFin;
942
943     //  Store quantities to be used in the TOF Calibration
944     Float_t tToT=AliTOFGeometry::ToTBinWidth()*c->GetToT()*1E-3; // in ns
945     t->SetTOFsignalToT(tToT);
946     Float_t rawTime=AliTOFGeometry::TdcBinWidth()*c->GetTDCRAW()+kTimeOffset; // RAW time,in ps
947     t->SetTOFsignalRaw(rawTime);
948     t->SetTOFsignalDz(mindistZ);
949     t->SetTOFsignalDx(mindistY);
950     t->SetTOFDeltaBC(c->GetDeltaBC());
951     t->SetTOFL0L1(c->GetL0L1Latency());
952
953     Float_t info[10] = {mindist,mindistY,mindistZ,
954                         0.,0.,0.,0.,0.,0.,0.};
955     t->SetTOFInfo(info);
956     AliDebug(3,Form(" distance=%f; residual in the pad reference frame: dX=%f, dZ=%f", info[0],info[1],info[2]));
957
958
959     Int_t ind[5];
960     ind[0]=c->GetDetInd(0);
961     ind[1]=c->GetDetInd(1);
962     ind[2]=c->GetDetInd(2);
963     ind[3]=c->GetDetInd(3);
964     ind[4]=c->GetDetInd(4);
965     Int_t calindex = AliTOFGeometry::GetIndex(ind);
966     t->SetTOFCalChannel(calindex);
967
968     // keep track of the track labels in the matched cluster
969     Int_t tlab[3];
970     tlab[0]=c->GetLabel(0);
971     tlab[1]=c->GetLabel(1);
972     tlab[2]=c->GetLabel(2);
973     AliDebug(3,Form(" tdc time of the matched track %6d = ",c->GetTDC()));    
974     Double_t tof=AliTOFGeometry::TdcBinWidth()*c->GetTDC()+kTimeOffset; // in ps
975     AliDebug(3,Form(" tof time of the matched track: %f = ",tof));    
976     Double_t tofcorr=tof;
977     if(timeWalkCorr)tofcorr=CorrectTimeWalk(mindistZ,tof);
978     AliDebug(3,Form(" tof time of the matched track, after TW corr: %f = ",tofcorr));    
979     //Set TOF time signal and pointer to the matched cluster
980     t->SetTOFsignal(tofcorr);
981     t->SetTOFcluster(idclus); // pointing to the recPoints tree
982
983     AliDebug(3,Form(" Setting TOF raw time: %f, z distance: %f  corrected time: %f ",rawTime,mindistZ,tofcorr));
984
985     //Tracking info
986     Double_t time[AliPID::kSPECIESC];
987     // read from old structure (the one used by TPC in reco)
988     for(Int_t isp=0;isp<AliPID::kSPECIESC;isp++){
989       time[isp] = t->GetIntegratedTimesOld(isp); // in ps
990     }
991     Double_t mom=t->GetP();
992     AliDebug(3,Form(" Momentum for track %d -> %f", iseed,mom));
993     for (Int_t j=0;j<AliPID::kSPECIESC;j++) {
994       Double_t mass=AliPID::ParticleMass(j);
995       Double_t momz = mom*AliPID::ParticleCharge(j);
996       time[j]+=(recL-trackPos[3][0])/kSpeedOfLight*TMath::Sqrt(momz*momz+mass*mass)/momz;
997       //time[j]+=(recL-trackPos[3][0])/kSpeedOfLight*TMath::Sqrt(mom*mom+mass*mass)/mom;
998     }
999
1000     AliTOFtrack *trackTOFout = new AliTOFtrack(*t); 
1001     if (!(trackTOFout->PropagateTo(xpos))) {
1002       delete trackTOFout;
1003       continue;
1004     }
1005
1006     // If necessary, rotate the track
1007     Double_t yATxposMax=xpos*TMath::Tan(0.5*AliTOFGeometry::GetAlpha());
1008     Double_t yATxpos=trackTOFout->GetY();
1009     if (yATxpos > yATxposMax) {
1010       if (!(trackTOFout->Rotate(AliTOFGeometry::GetAlpha()))) {
1011         delete trackTOFout;
1012         continue;
1013       }
1014     } else if (yATxpos < -yATxposMax) {
1015       if (!(trackTOFout->Rotate(-AliTOFGeometry::GetAlpha()))) {
1016         delete trackTOFout;
1017         continue;
1018       }
1019     }
1020
1021     // Fill the track residual histograms and update track only if in the first two step (0 and 1)
1022     if(mLastStep < 2){
1023       FillResiduals(trackTOFout,c,kFALSE);
1024
1025       t->UpdateTrackParams(trackTOFout,AliESDtrack::kTOFout);
1026
1027 // don't update old structure with TOF info
1028 //       t->SetIntegratedLength(recL);
1029 //       t->SetIntegratedTimes(time);
1030 //       t->SetTOFLabel(tlab);
1031  
1032     // add tof cluster to the track also for step 2
1033       if(idclus < 20000){
1034         fClusterESD[idclus]->Update(t->GetID(),mindistY,mindist,mindistZ,recL,time);//x,y,z -> tracking RF
1035         
1036         t->AddTOFcluster(idclus);
1037       }
1038       else{
1039         AliInfo("Too many TOF clusters matched with tracks (> 20000)");
1040       }
1041       
1042     }
1043     // Fill Reco-QA histos for Reconstruction
1044     fHRecNClus->Fill(nc);
1045     fHRecDist->Fill(mindist);
1046     if (cov[0]>=0.)
1047       fHRecSigYVsP->Fill(mom,TMath::Sqrt(cov[0]));
1048     else
1049       fHRecSigYVsP->Fill(mom,-TMath::Sqrt(-cov[0]));
1050     if (cov[2]>=0.)
1051       fHRecSigZVsP->Fill(mom,TMath::Sqrt(cov[2]));
1052     else
1053       fHRecSigZVsP->Fill(mom,-TMath::Sqrt(-cov[2]));
1054     fHRecSigYVsPWin->Fill(mom,dphi*sensRadius);
1055     fHRecSigZVsPWin->Fill(mom,dz);
1056
1057     // Fill Tree for on-the-fly offline Calibration
1058
1059     if ( !((t->GetStatus() & AliESDtrack::kTIME)==0 ) ) {
1060       fIch=calindex;
1061       fToT=tToT;
1062       fTime=rawTime;
1063       fExpTimePi=time[2];
1064       fExpTimeKa=time[3];
1065       fExpTimePr=time[4];
1066       fCalTree->Fill();
1067     }
1068     delete trackTOFout;
1069   }
1070
1071
1072   for (Int_t ii=0; ii<4; ii++) delete [] trackPos[ii];
1073   delete [] clind;
1074  
1075 }
1076 //_________________________________________________________________________
1077 Int_t AliTOFtracker::LoadClusters(TTree *cTree) {
1078   //--------------------------------------------------------------------
1079   //This function loads the TOF clusters
1080   //--------------------------------------------------------------------
1081
1082   Int_t npadX = AliTOFGeometry::NpadX();
1083   Int_t npadZ = AliTOFGeometry::NpadZ();
1084   Int_t nStripA = AliTOFGeometry::NStripA();
1085   Int_t nStripB = AliTOFGeometry::NStripB();
1086   Int_t nStripC = AliTOFGeometry::NStripC();
1087
1088   TBranch *branch=cTree->GetBranch("TOF");
1089   if (!branch) { 
1090     AliError("can't get the branch with the TOF clusters !");
1091     return 1;
1092   }
1093
1094   static TClonesArray dummy("AliTOFcluster",10000);
1095   dummy.Clear();
1096   TClonesArray *clusters=&dummy;
1097   branch->SetAddress(&clusters);
1098
1099   cTree->GetEvent(0);
1100   Int_t nc=clusters->GetEntriesFast();
1101   fHDigNClus->Fill(nc);
1102
1103   AliInfo(Form("Number of clusters: %d",nc));
1104
1105   fN = 0;
1106   fNTOFmatched = 0;
1107   for(Int_t i=0; i< 20000;i++){
1108     if(fClusterESD[i]){
1109       delete fClusterESD[i];
1110       fClusterESD[i] = NULL;
1111     }
1112   }
1113
1114   for (Int_t i=0; i<nc; i++) {
1115     AliTOFcluster *c=(AliTOFcluster*)clusters->UncheckedAt(i);
1116 //PH    fClusters[i]=new AliTOFcluster(*c); fN++;
1117     fClusters[i]=c; fN++;
1118
1119   // Fill Digits QA histos
1120  
1121     Int_t isector = c->GetDetInd(0);
1122     Int_t iplate = c->GetDetInd(1);
1123     Int_t istrip = c->GetDetInd(2);
1124     Int_t ipadX = c->GetDetInd(4);
1125     Int_t ipadZ = c->GetDetInd(3);
1126
1127     Float_t time =(AliTOFGeometry::TdcBinWidth()*c->GetTDC())*1E-3; // in ns
1128     Float_t tot = (AliTOFGeometry::TdcBinWidth()*c->GetToT())*1E-3;//in ns
1129
1130     Int_t ind[5];
1131     ind[0]=isector;
1132     ind[1]=iplate;
1133     ind[2]=istrip;
1134     ind[3]=ipadX;
1135     ind[4]=ipadZ;
1136
1137     Int_t calindex = AliTOFGeometry::GetIndex(ind);
1138     Int_t tofLabels[3]={c->GetLabel(0),c->GetLabel(1),c->GetLabel(2)};
1139  
1140     Int_t stripOffset = 0;
1141     switch (iplate) {
1142     case 0:
1143       stripOffset = 0;
1144       break;
1145     case 1:
1146       stripOffset = nStripC;
1147       break;
1148     case 2:
1149       stripOffset = nStripC+nStripB;
1150       break;
1151     case 3:
1152       stripOffset = nStripC+nStripB+nStripA;
1153       break;
1154     case 4:
1155       stripOffset = nStripC+nStripB+nStripA+nStripB;
1156       break;
1157     default:
1158       AliError(Form("Wrong plate number in TOF (%d) !",iplate));
1159       break;
1160     };
1161     Int_t zindex=npadZ*(istrip+stripOffset)+(ipadZ+1);
1162     Int_t phiindex=npadX*isector+ipadX+1;
1163     fHDigClusMap->Fill(zindex,phiindex);
1164     fHDigClusTime->Fill(time);
1165     fHDigClusToT->Fill(tot);
1166
1167     if(fNTOFmatched < 20000){
1168       fClusterESD[fNTOFmatched] = new AliESDTOFcluster(i,calindex,
1169                                 AliTOFGeometry::TdcBinWidth()*c->GetTDC()/*ps*/,
1170                                 AliTOFGeometry::TdcBinWidth()*c->GetTDCRAW()/*ps*/,
1171                                 AliTOFGeometry::ToTBinWidth()*c->GetToT()*1E-3/*ns*/,
1172                                 tofLabels,
1173                                 c->GetDeltaBC(),c->GetL0L1Latency(),
1174                                 c->GetStatus(),c->GetZ(),c->GetPhi(),c->GetR());
1175       fNTOFmatched++;
1176     }
1177
1178   }
1179
1180
1181   if(fNTOFmatched == 0)
1182     fClusterESD[0] = new AliESDTOFcluster();
1183
1184   return 0;
1185 }
1186 //_________________________________________________________________________
1187 void AliTOFtracker::UnloadClusters() {
1188   //--------------------------------------------------------------------
1189   //This function unloads TOF clusters
1190   //--------------------------------------------------------------------
1191   for (Int_t i=0; i<fN; i++) {
1192 //PH    delete fClusters[i];
1193     fClusters[i] = 0x0;
1194   }
1195   fN=0;
1196 }
1197
1198 //_________________________________________________________________________
1199 Int_t AliTOFtracker::FindClusterIndex(Double_t z) const {
1200   //--------------------------------------------------------------------
1201   // This function returns the index of the nearest cluster 
1202   //--------------------------------------------------------------------
1203   if (fN==0) return 0;
1204   if (z <= fClusters[0]->GetZ()) return 0;
1205   if (z > fClusters[fN-1]->GetZ()) return fN;
1206   Int_t b=0, e=fN-1, m=(b+e)/2;
1207   for (; b<e; m=(b+e)/2) {
1208     if (z > fClusters[m]->GetZ()) b=m+1;
1209     else e=m; 
1210   }
1211   return m;
1212 }
1213
1214 //_________________________________________________________________________
1215 Bool_t AliTOFtracker::GetTrackPoint(Int_t index, AliTrackPoint& p) const
1216 {
1217   // Get track space point with index i
1218   // Coordinates are in the global system
1219   AliTOFcluster *cl = fClusters[index];
1220   Float_t xyz[3];
1221   xyz[0] = cl->GetR()*TMath::Cos(cl->GetPhi());
1222   xyz[1] = cl->GetR()*TMath::Sin(cl->GetPhi());
1223   xyz[2] = cl->GetZ();
1224   Float_t phiangle = (Int_t(cl->GetPhi()*TMath::RadToDeg()/20.)+0.5)*20.*TMath::DegToRad();
1225   Float_t sinphi = TMath::Sin(phiangle), cosphi = TMath::Cos(phiangle);
1226   Float_t tiltangle = AliTOFGeometry::GetAngles(cl->GetDetInd(1),cl->GetDetInd(2))*TMath::DegToRad();
1227   Float_t sinth = TMath::Sin(tiltangle), costh = TMath::Cos(tiltangle);
1228   Float_t sigmay2 = AliTOFGeometry::XPad()*AliTOFGeometry::XPad()/12.;
1229   Float_t sigmaz2 = AliTOFGeometry::ZPad()*AliTOFGeometry::ZPad()/12.;
1230   Float_t cov[6];
1231   cov[0] = sinphi*sinphi*sigmay2 + cosphi*cosphi*sinth*sinth*sigmaz2;
1232   cov[1] = -sinphi*cosphi*sigmay2 + sinphi*cosphi*sinth*sinth*sigmaz2;
1233   cov[2] = -cosphi*sinth*costh*sigmaz2;
1234   cov[3] = cosphi*cosphi*sigmay2 + sinphi*sinphi*sinth*sinth*sigmaz2;
1235   cov[4] = -sinphi*sinth*costh*sigmaz2;
1236   cov[5] = costh*costh*sigmaz2;
1237   p.SetXYZ(xyz[0],xyz[1],xyz[2],cov);
1238
1239   // Detector numbering scheme
1240   Int_t nSector = AliTOFGeometry::NSectors();
1241   Int_t nPlate  = AliTOFGeometry::NPlates();
1242   Int_t nStripA = AliTOFGeometry::NStripA();
1243   Int_t nStripB = AliTOFGeometry::NStripB();
1244   Int_t nStripC = AliTOFGeometry::NStripC();
1245
1246   Int_t isector = cl->GetDetInd(0);
1247   if (isector >= nSector)
1248     AliError(Form("Wrong sector number in TOF (%d) !",isector));
1249   Int_t iplate = cl->GetDetInd(1);
1250   if (iplate >= nPlate)
1251     AliError(Form("Wrong plate number in TOF (%d) !",iplate));
1252   Int_t istrip = cl->GetDetInd(2);
1253
1254   Int_t stripOffset = 0;
1255   switch (iplate) {
1256   case 0:
1257     stripOffset = 0;
1258     break;
1259   case 1:
1260     stripOffset = nStripC;
1261     break;
1262   case 2:
1263     stripOffset = nStripC+nStripB;
1264     break;
1265   case 3:
1266     stripOffset = nStripC+nStripB+nStripA;
1267     break;
1268   case 4:
1269     stripOffset = nStripC+nStripB+nStripA+nStripB;
1270     break;
1271   default:
1272     AliError(Form("Wrong plate number in TOF (%d) !",iplate));
1273     break;
1274   };
1275
1276   Int_t idet = (2*(nStripC+nStripB)+nStripA)*isector +
1277                stripOffset +
1278                istrip;
1279   UShort_t volid = AliGeomManager::LayerToVolUID(AliGeomManager::kTOF,idet);
1280   p.SetVolumeID((UShort_t)volid);
1281   return kTRUE;
1282 }
1283 //_________________________________________________________________________
1284 void AliTOFtracker::InitCheckHists() {
1285
1286   //Init histos for Digits/Reco QA and Calibration
1287
1288
1289   TDirectory *dir = gDirectory;
1290   TFile *logFileTOF = 0;
1291
1292   TSeqCollection *list = gROOT->GetListOfFiles();
1293   int n = list->GetEntries();
1294   Bool_t isThere=kFALSE;
1295   for(int i=0; i<n; i++) {
1296     logFileTOF = (TFile*)list->At(i);
1297     if (strstr(logFileTOF->GetName(), "TOFQA.root")){
1298       isThere=kTRUE;
1299       break;
1300     } 
1301   }
1302
1303   if(!isThere)logFileTOF = new TFile( "TOFQA.root","RECREATE");
1304   logFileTOF->cd(); 
1305
1306   fCalTree = new TTree("CalTree", "Tree for TOF calibration");
1307   fCalTree->Branch("TOFchannelindex",&fIch,"iTOFch/I");
1308   fCalTree->Branch("ToT",&fToT,"TOFToT/F");
1309   fCalTree->Branch("TOFtime",&fTime,"TOFtime/F");
1310   fCalTree->Branch("PionExpTime",&fExpTimePi,"PiExpTime/F");
1311   fCalTree->Branch("KaonExpTime",&fExpTimeKa,"KaExpTime/F");
1312   fCalTree->Branch("ProtonExpTime",&fExpTimePr,"PrExpTime/F");
1313
1314   //Digits "QA" 
1315   fHDigClusMap = new TH2F("TOFDig_ClusMap", "",182,0.5,182.5,864, 0.5,864.5);  
1316   fHDigNClus = new TH1F("TOFDig_NClus", "",200,0.5,200.5);  
1317   fHDigClusTime = new TH1F("TOFDig_ClusTime", "",2000,0.,200.);  
1318   fHDigClusToT = new TH1F("TOFDig_ClusToT", "",500,0.,100);  
1319
1320   //Reco "QA"
1321   fHRecNClus =new TH1F("TOFRec_NClusW", "",50,0.5,50.5);
1322   fHRecDist=new TH1F("TOFRec_Dist", "",50,0.5,10.5);
1323   fHRecSigYVsP=new TH2F("TOFDig_SigYVsP", "",40,0.,4.,100, 0.,5.);
1324   fHRecSigZVsP=new TH2F("TOFDig_SigZVsP", "",40,0.,4.,100, 0.,5.);
1325   fHRecSigYVsPWin=new TH2F("TOFDig_SigYVsPWin", "",40,0.,4.,100, 0.,50.);
1326   fHRecSigZVsPWin=new TH2F("TOFDig_SigZVsPWin", "",40,0.,4.,100, 0.,50.);
1327
1328   dir->cd();
1329
1330 }
1331
1332 //_________________________________________________________________________
1333 void AliTOFtracker::SaveCheckHists() {
1334
1335   //write histos for Digits/Reco QA and Calibration
1336
1337   TDirectory *dir = gDirectory;
1338   TFile *logFileTOF = 0;
1339
1340   TSeqCollection *list = gROOT->GetListOfFiles();
1341   int n = list->GetEntries();
1342   Bool_t isThere=kFALSE;
1343   for(int i=0; i<n; i++) {
1344     logFileTOF = (TFile*)list->At(i);
1345     if (strstr(logFileTOF->GetName(), "TOFQA.root")){
1346       isThere=kTRUE;
1347       break;
1348     } 
1349   }
1350    
1351   if(!isThere) {
1352           AliError(Form("File TOFQA.root not found!! not wring histograms...."));
1353           return;
1354   }
1355   logFileTOF->cd(); 
1356   fHDigClusMap->Write(fHDigClusMap->GetName(), TObject::kOverwrite);
1357   fHDigNClus->Write(fHDigNClus->GetName(), TObject::kOverwrite);
1358   fHDigClusTime->Write(fHDigClusTime->GetName(), TObject::kOverwrite);
1359   fHDigClusToT->Write(fHDigClusToT->GetName(), TObject::kOverwrite);
1360   fHRecNClus->Write(fHRecNClus->GetName(), TObject::kOverwrite);
1361   fHRecDist->Write(fHRecDist->GetName(), TObject::kOverwrite);
1362   fHRecSigYVsP->Write(fHRecSigYVsP->GetName(), TObject::kOverwrite);
1363   fHRecSigZVsP->Write(fHRecSigZVsP->GetName(), TObject::kOverwrite);
1364   fHRecSigYVsPWin->Write(fHRecSigYVsPWin->GetName(), TObject::kOverwrite);
1365   fHRecSigZVsPWin->Write(fHRecSigZVsPWin->GetName(), TObject::kOverwrite);
1366   fCalTree->Write(fCalTree->GetName(),TObject::kOverwrite);
1367   logFileTOF->Flush();  
1368
1369   dir->cd();
1370   }
1371 //_________________________________________________________________________
1372 Float_t AliTOFtracker::CorrectTimeWalk( Float_t dist, Float_t tof) const {
1373
1374   //dummy, for the moment
1375   Float_t tofcorr=0.;
1376   if(dist<AliTOFGeometry::ZPad()*0.5){
1377     tofcorr=tof;
1378     //place here the actual correction
1379   }else{
1380     tofcorr=tof; 
1381   } 
1382   return tofcorr;
1383 }
1384 //_________________________________________________________________________
1385
1386 void AliTOFtracker::FillClusterArray(TObjArray* arr) const
1387 {
1388   //
1389   // Returns the TOF cluster array
1390   //
1391
1392   if (fN==0)
1393     arr = 0x0;
1394   else
1395     for (Int_t i=0; i<fN; ++i) arr->Add(fClusters[i]);
1396
1397 }
1398 //_________________________________________________________________________
1399