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