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