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