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