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