1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 // Implementation of the ESD track class
17 // ESD = Event Summary Data
18 // This is the class to deal with during the phisics analysis of data
19 // Origin: Iouri Belikov, CERN
20 // e-mail: Jouri.Belikov@cern.ch
24 // What do you need to know before starting analysis
25 // (by Marian Ivanov: marian.ivanov@cern.ch)
29 // 1. What is the AliESDtrack
30 // 2. What informations do we store
31 // 3. How to use the information for analysis
34 // 1.AliESDtrack is the container of the information about the track/particle
35 // reconstructed during Barrel Tracking.
36 // The track information is propagated from one tracking detector to
37 // other using the functionality of AliESDtrack - Current parameters.
39 // No global fit model is used.
40 // Barrel tracking use Kalman filtering technique, it gives optimal local
41 // track parameters at given point under certian assumptions.
43 // Kalman filter take into account additional effect which are
44 // difficult to handle using global fit.
46 // a.) Multiple scattering
48 // c.) Non homogenous magnetic field
50 // In general case, following barrel detectors are contributing to
51 // the Kalman track information:
56 // In general 3 reconstruction itteration are performed:
57 // 1. Find tracks - sequence TPC->ITS
58 // 2. PropagateBack - sequence ITS->TPC->TRD -> Outer PID detectors
59 // 3. Refit invward - sequence TRD->TPC->ITS
60 // The current tracks are updated after each detector (see bellow).
61 // In specical cases a track sanpshots are stored.
64 // For some type of analysis (+visualization) track local parameters at
65 // different position are neccesary. A snapshots during the track
66 // propagation are created.
67 // (See AliExternalTrackParam class for desctiption of variables and
70 // a. Current parameters - class itself (AliExternalTrackParam)
71 // Contributors: general case TRD->TPC->ITS
72 // Preferable usage: Decission - primary or secondary track
73 // NOTICE - By default the track parameters are stored at the DCA point
74 // to the primary vertex. optimal for primary tracks,
75 // far from optimal for secondary tracks.
76 // b. Constrained parameters - Kalman information updated with
77 // the Primary vertex information
78 // Contributors: general case TRD->TPC->ITS
79 // Preferable usage: Use only for tracks selected as primary
80 // NOTICE - not real constrain - taken as additional measurement
81 // with corresponding error
83 // const AliExternalTrackParam *GetConstrainedParam() const {return fCp;}
84 // c. Inner parameters - Track parameters at inner wall of the TPC
85 // Contributors: general case TRD->TPC
87 // const AliExternalTrackParam *GetInnerParam() const { return fIp;}
89 // d. TPCinnerparam - contributors - TPC only
91 // Preferable usage: Requested for HBT study
92 // (smaller correlations as using also ITS information)
93 // NOTICE - the track parameters are propagated to the DCA to
95 // Optimal for primary, far from optimal for secondary tracks
97 // const AliExternalTrackParam *GetTPCInnerParam() const {return fTPCInner;}
99 // e. Outer parameters -
100 // Contributors- general case - ITS-> TPC -> TRD
101 // The last point - Outer parameters radius is determined
102 // e.a) Local inclination angle bigger than threshold -
103 // Low momenta tracks
104 // e.a) Catastrofic energy losss in material
105 // e.b) Not further improvement (no space points)
107 // a.) Tracking: Starting parameter for Refit inward
110 // NOTICE: Should be not used for the physic analysis
112 // const AliExternalTrackParam *GetOuterParam() const { return fOp;}
114 //-----------------------------------------------------------------
117 #include <TParticle.h>
118 #include <TDatabasePDG.h>
119 #include <TMatrixD.h>
121 #include "AliESDVertex.h"
122 #include "AliESDtrack.h"
123 #include "AliESDEvent.h"
124 #include "AliKalmanTrack.h"
125 #include "AliVTrack.h"
127 #include "AliTrackPointArray.h"
128 #include "TPolyMarker3D.h"
129 #include "AliTrackerBase.h"
130 #include "AliTPCdEdxInfo.h"
131 #include "AliDetectorPID.h"
132 #include "TTreeStream.h"
133 #include "TObjArray.h"
135 ClassImp(AliESDtrack)
137 void SetPIDValues(Double_t * dest, const Double_t * src, Int_t n) {
138 // This function copies "n" PID weights from "scr" to "dest"
139 // and normalizes their sum to 1 thus producing conditional probabilities.
140 // The negative weights are set to 0.
141 // In case all the weights are non-positive they are replaced by
142 // uniform probabilities
146 Float_t uniform = 1./(Float_t)n;
149 for (Int_t i=0; i<n; i++)
159 for (Int_t i=0; i<n; i++) dest[i] /= sum;
161 for (Int_t i=0; i<n; i++) dest[i] = uniform;
164 //_______________________________________________________________________
165 AliESDtrack::AliESDtrack() :
166 AliExternalTrackParam(),
173 fTPCFitMap(159),//number of padrows
174 fTPCClusterMap(159),//number of padrows
175 fTPCSharedMap(159),//number of padrows
187 fCaloIndex(kEMCALNoMatch),
200 fCddTPC(0),fCdzTPC(0),fCzzTPC(0),
203 fCdd(0),fCdz(0),fCzz(0),
221 fTOFsignalTuned(99999),
222 fTOFsignalToT(99999),
223 fTOFsignalRaw(99999),
249 fVertexID(-2),// -2 means an orphan track
250 fPIDForTracking(AliPID::kPion),
252 fCacheNCrossedRows(-10),
253 fCacheChi2TPCConstrainedVsGlobal(-10),
254 fCacheChi2TPCConstrainedVsGlobalVertex(0),
256 fTrackPhiOnEMCal(-999),
257 fTrackEtaOnEMCal(-999),
258 fTrackPtOnEMCal(-999),
263 // The default ESD constructor
265 if (!OnlineMode()) fFriendTrack=new AliESDfriendTrack();
268 for (i=kNITSchi2Std;i--;) fITSchi2Std[i] = 0;
270 for (i=0; i<3; i++) { fKinkIndexes[i]=0;}
271 for (i=0; i<3; i++) { fV0Indexes[i]=0;}
272 for (i=0;i<kTRDnPlanes;i++) {
275 for (i=0;i<4;i++) {fITSdEdxSamples[i]=0.;}
276 for (i=0;i<4;i++) {fTPCPoints[i]=0;}
277 for (i=0;i<10;i++) {fTOFInfo[i]=0;}
278 for (i=0;i<12;i++) {fITSModule[i]=-1;}
281 bool AliESDtrack::fgkOnlineMode=false;
283 //_______________________________________________________________________
284 AliESDtrack::AliESDtrack(const AliESDtrack& track):
285 AliExternalTrackParam(track),
292 fTPCFitMap(track.fTPCFitMap),
293 fTPCClusterMap(track.fTPCClusterMap),
294 fTPCSharedMap(track.fTPCSharedMap),
295 fFlags(track.fFlags),
297 fLabel(track.fLabel),
298 fITSLabel(track.fITSLabel),
299 fTPCLabel(track.fTPCLabel),
300 fTRDLabel(track.fTRDLabel),
302 fTOFCalChannel(track.fTOFCalChannel),
303 fTOFindex(track.fTOFindex),
304 fHMPIDqn(track.fHMPIDqn),
305 fHMPIDcluIdx(track.fHMPIDcluIdx),
306 fCaloIndex(track.fCaloIndex),
313 fHMPIDtrkTheta(track.fHMPIDtrkTheta),
314 fHMPIDtrkPhi(track.fHMPIDtrkPhi),
315 fHMPIDsignal(track.fHMPIDsignal),
317 fTrackLength(track.fTrackLength),
318 fdTPC(track.fdTPC),fzTPC(track.fzTPC),
319 fCddTPC(track.fCddTPC),fCdzTPC(track.fCdzTPC),fCzzTPC(track.fCzzTPC),
320 fCchi2TPC(track.fCchi2TPC),
321 fD(track.fD),fZ(track.fZ),
322 fCdd(track.fCdd),fCdz(track.fCdz),fCzz(track.fCzz),
323 fCchi2(track.fCchi2),
324 fITSchi2(track.fITSchi2),
325 fTPCchi2(track.fTPCchi2),
326 fTPCchi2Iter1(track.fTPCchi2Iter1),
327 fTRDchi2(track.fTRDchi2),
328 fTOFchi2(track.fTOFchi2),
329 fHMPIDchi2(track.fHMPIDchi2),
330 fGlobalChi2(track.fGlobalChi2),
331 fITSsignal(track.fITSsignal),
332 fTPCsignal(track.fTPCsignal),
333 fTPCsignalTuned(track.fTPCsignalTuned),
334 fTPCsignalS(track.fTPCsignalS),
336 fTRDsignal(track.fTRDsignal),
337 fTRDQuality(track.fTRDQuality),
338 fTRDBudget(track.fTRDBudget),
339 fTOFsignal(track.fTOFsignal),
340 fTOFsignalTuned(track.fTOFsignalTuned),
341 fTOFsignalToT(track.fTOFsignalToT),
342 fTOFsignalRaw(track.fTOFsignalRaw),
343 fTOFsignalDz(track.fTOFsignalDz),
344 fTOFsignalDx(track.fTOFsignalDx),
345 fTOFdeltaBC(track.fTOFdeltaBC),
346 fTOFl0l1(track.fTOFl0l1),
347 fCaloDx(track.fCaloDx),
348 fCaloDz(track.fCaloDz),
349 fHMPIDtrkX(track.fHMPIDtrkX),
350 fHMPIDtrkY(track.fHMPIDtrkY),
351 fHMPIDmipX(track.fHMPIDmipX),
352 fHMPIDmipY(track.fHMPIDmipY),
353 fTPCncls(track.fTPCncls),
354 fTPCnclsF(track.fTPCnclsF),
355 fTPCsignalN(track.fTPCsignalN),
356 fTPCnclsIter1(track.fTPCnclsIter1),
357 fTPCnclsFIter1(track.fTPCnclsIter1),
358 fITSncls(track.fITSncls),
359 fITSClusterMap(track.fITSClusterMap),
360 fITSSharedMap(track.fITSSharedMap),
361 fTRDncls(track.fTRDncls),
362 fTRDncls0(track.fTRDncls0),
363 fTRDntracklets(track.fTRDntracklets),
364 fTRDNchamberdEdx(track.fTRDNchamberdEdx),
365 fTRDNclusterdEdx(track.fTRDNclusterdEdx),
366 fTRDnSlices(track.fTRDnSlices),
368 fVertexID(track.fVertexID),
369 fPIDForTracking(AliPID::kPion),
370 fESDEvent(track.fESDEvent),
371 fCacheNCrossedRows(track.fCacheNCrossedRows),
372 fCacheChi2TPCConstrainedVsGlobal(track.fCacheChi2TPCConstrainedVsGlobal),
373 fCacheChi2TPCConstrainedVsGlobalVertex(track.fCacheChi2TPCConstrainedVsGlobalVertex),
375 fTrackPhiOnEMCal(track.fTrackPhiOnEMCal),
376 fTrackEtaOnEMCal(track.fTrackEtaOnEMCal),
377 fTrackPtOnEMCal(track.fTrackPtOnEMCal),
378 fNtofClusters(track.fNtofClusters),
384 for (Int_t i=kNITSchi2Std;i--;) fITSchi2Std[i] = track.fITSchi2Std[i];
386 if(track.fTrackTime){
387 fTrackTime = new Double32_t[AliPID::kSPECIESC];
388 for (Int_t i=0;i<AliPID::kSPECIESC;i++) fTrackTime[i]=track.fTrackTime[i];
392 fR = new Double32_t[AliPID::kSPECIES];
393 for (Int_t i=AliPID::kSPECIES;i--;) fR[i]=track.fR[i];
396 fITSr = new Double32_t[AliPID::kSPECIES];
397 for (Int_t i=AliPID::kSPECIES;i--;) fITSr[i]=track.fITSr[i];
401 fTPCr = new Double32_t[AliPID::kSPECIES];
402 for (Int_t i=AliPID::kSPECIES;i--;) fTPCr[i]=track.fTPCr[i];
405 for (Int_t i=0;i<4;i++) {fITSdEdxSamples[i]=track.fITSdEdxSamples[i];}
406 for (Int_t i=0;i<4;i++) {fTPCPoints[i]=track.fTPCPoints[i];}
407 for (Int_t i=0; i<3;i++) { fKinkIndexes[i]=track.fKinkIndexes[i];}
408 for (Int_t i=0; i<3;i++) { fV0Indexes[i]=track.fV0Indexes[i];}
410 for (Int_t i=0;i<kTRDnPlanes;i++) {
411 fTRDTimBin[i]=track.fTRDTimBin[i];
415 fTRDslices=new Double32_t[fTRDnSlices];
416 for (Int_t i=0; i<fTRDnSlices; i++) fTRDslices[i]=track.fTRDslices[i];
419 if (track.fDetectorPID) fDetectorPID = new AliDetectorPID(*track.fDetectorPID);
422 fTRDr = new Double32_t[AliPID::kSPECIES];
423 for (Int_t i=AliPID::kSPECIES;i--;) fTRDr[i]=track.fTRDr[i];
427 fTOFr = new Double32_t[AliPID::kSPECIES];
428 for (Int_t i=AliPID::kSPECIES;i--;) fTOFr[i]=track.fTOFr[i];
432 if(!fTOFLabel) fTOFLabel = new Int_t[3];
433 for (Int_t i=0;i<3;i++) fTOFLabel[i]=track.fTOFLabel[i];
436 for (Int_t i=0;i<10;i++) fTOFInfo[i]=track.fTOFInfo[i];
437 for (Int_t i=0;i<12;i++) fITSModule[i]=track.fITSModule[i];
440 fHMPIDr = new Double32_t[AliPID::kSPECIES];
441 for (Int_t i=AliPID::kSPECIES;i--;) fHMPIDr[i]=track.fHMPIDr[i];
444 if (track.fCp) fCp=new AliExternalTrackParam(*track.fCp);
445 if (track.fIp) fIp=new AliExternalTrackParam(*track.fIp);
446 if (track.fTPCInner) fTPCInner=new AliExternalTrackParam(*track.fTPCInner);
447 if (track.fOp) fOp=new AliExternalTrackParam(*track.fOp);
448 if (track.fHMPIDp) fHMPIDp=new AliExternalTrackParam(*track.fHMPIDp);
449 if (track.fTPCdEdxInfo) fTPCdEdxInfo = new AliTPCdEdxInfo(*track.fTPCdEdxInfo);
452 if (track.fFriendTrack) fFriendTrack=new AliESDfriendTrack(*(track.fFriendTrack));
454 if(fNtofClusters > 0){
455 fTOFcluster = new Int_t[fNtofClusters];
456 for(Int_t i=0;i < fNtofClusters;i++) fTOFcluster[i] = track.fTOFcluster[i];
460 //_______________________________________________________________________
461 AliESDtrack::AliESDtrack(const AliVTrack *track) :
462 AliExternalTrackParam(track),
469 fTPCFitMap(159),//number of padrows
470 fTPCClusterMap(159),//number of padrows
471 fTPCSharedMap(159),//number of padrows
483 fCaloIndex(kEMCALNoMatch),
496 fCddTPC(0),fCdzTPC(0),fCzzTPC(0),
499 fCdd(0),fCdz(0),fCzz(0),
517 fTOFsignalTuned(99999),
518 fTOFsignalToT(99999),
519 fTOFsignalRaw(99999),
545 fVertexID(-2), // -2 means an orphan track
546 fPIDForTracking(track->GetPIDForTracking()),
548 fCacheNCrossedRows(-10),
549 fCacheChi2TPCConstrainedVsGlobal(-10),
550 fCacheChi2TPCConstrainedVsGlobalVertex(0),
552 fTrackPhiOnEMCal(-999),
553 fTrackEtaOnEMCal(-999),
554 fTrackPtOnEMCal(-999),
559 // ESD track from AliVTrack.
560 // This is not a copy constructor !
563 if (track->InheritsFrom("AliExternalTrackParam")) {
564 AliError("This is not a copy constructor. Use AliESDtrack(const AliESDtrack &) !");
565 AliWarning("Calling the default constructor...");
570 // Reset all the arrays
572 for (i=kNITSchi2Std;i--;) fITSchi2Std[i] = 0;
574 for (i=0; i<3; i++) { fKinkIndexes[i]=0;}
575 for (i=0; i<3; i++) { fV0Indexes[i]=-1;}
576 for (i=0;i<kTRDnPlanes;i++) {
579 for (i=0;i<4;i++) {fITSdEdxSamples[i]=0.;}
580 for (i=0;i<4;i++) {fTPCPoints[i]=0;}
581 for (i=0;i<10;i++) {fTOFInfo[i]=0;}
582 for (i=0;i<12;i++) {fITSModule[i]=-1;}
585 // Set ITS cluster map
586 fITSClusterMap=track->GetITSClusterMap();
591 if(HasPointOnITSLayer(i)) fITSncls++;
595 fTPCncls=track->GetTPCNcls();
596 fTPCnclsF=track->GetTPCNclsF();
598 const TBits* bmap = track->GetTPCClusterMapPtr();
599 if (bmap) SetTPCClusterMap(*bmap);
600 bmap = GetTPCFitMapPtr();
601 if (bmap) SetTPCFitMap(*bmap);
602 bmap = GetTPCSharedMapPtr();
603 if (bmap) SetTPCSharedMap(*bmap);
605 // Set the combined PID
606 const Double_t *pid = track->PID();
608 fR = new Double32_t[AliPID::kSPECIES];
609 for (i=AliPID::kSPECIES; i--;) fR[i]=pid[i];
612 // calo matched cluster id
613 SetEMCALcluster(track->GetEMCALcluster());
614 // AliESD track label
617 fITSsignal = track->GetITSsignal();
619 track->GetITSdEdxSamples(itsdEdx);
620 SetITSdEdxSamples(itsdEdx);
622 SetTPCsignal(track->GetTPCsignal(),fTPCsignalS,track->GetTPCsignalN()); // No signalS in AODPi
623 AliTPCdEdxInfo * dEdxInfo = track->GetTPCdEdxInfo();
624 if (dEdxInfo) SetTPCdEdxInfo(new AliTPCdEdxInfo(*dEdxInfo));
626 SetTRDsignal(track->GetTRDsignal());
627 int ntrdsl = track->GetNumberOfTRDslices();
629 SetNumberOfTRDslices((ntrdsl+2)*kTRDnPlanes);
630 for (int ipl=kTRDnPlanes;ipl--;){
631 for (int isl=ntrdsl;isl--;) SetTRDslice(track->GetTRDslice(ipl,isl),ipl,isl);
632 Double_t sp, p = track->GetTRDmomentum(ipl, &sp);
633 SetTRDmomentum(p, ipl, &sp);
637 fTRDncls = track->GetTRDncls();
638 fTRDntracklets &= 0xff & track->GetTRDntrackletsPID();
639 fTRDchi2 = track->GetTRDchi2();
641 SetTOFsignal(track->GetTOFsignal());
642 Double_t expt[AliPID::kSPECIESC];
643 track->GetIntegratedTimes(expt,AliPID::kSPECIESC);
644 SetIntegratedTimes(expt);
646 SetTrackPhiEtaPtOnEMCal(track->GetTrackPhiOnEMCal(),track->GetTrackEtaOnEMCal(),track->GetTrackPtOnEMCal());
648 SetLabel(track->GetLabel());
650 SetStatus(track->GetStatus());
653 SetID(track->GetID());
657 //_______________________________________________________________________
658 AliESDtrack::AliESDtrack(TParticle * part) :
659 AliExternalTrackParam(),
666 fTPCFitMap(159),//number of padrows
667 fTPCClusterMap(159),//number of padrows
668 fTPCSharedMap(159),//number of padrows
680 fCaloIndex(kEMCALNoMatch),
693 fCddTPC(0),fCdzTPC(0),fCzzTPC(0),
696 fCdd(0),fCdz(0),fCzz(0),
714 fTOFsignalTuned(99999),
715 fTOFsignalToT(99999),
716 fTOFsignalRaw(99999),
742 fVertexID(-2), // -2 means an orphan track
743 fPIDForTracking(AliPID::kPion),
745 fCacheNCrossedRows(-10),
746 fCacheChi2TPCConstrainedVsGlobal(-10),
747 fCacheChi2TPCConstrainedVsGlobalVertex(0),
749 fTrackPhiOnEMCal(-999),
750 fTrackEtaOnEMCal(-999),
751 fTrackPtOnEMCal(-999),
756 // ESD track from TParticle
759 // Reset all the arrays
761 for (i=kNITSchi2Std;i--;) fITSchi2Std[i] = 0;
763 for (i=0; i<3; i++) { fKinkIndexes[i]=0;}
764 for (i=0; i<3; i++) { fV0Indexes[i]=-1;}
765 for (i=0;i<kTRDnPlanes;i++) {
768 for (i=0;i<4;i++) {fITSdEdxSamples[i]=0.;}
769 for (i=0;i<4;i++) {fTPCPoints[i]=0;}
770 for (i=0;i<10;i++) {fTOFInfo[i]=0;}
771 for (i=0;i<12;i++) {fITSModule[i]=-1;}
773 // Calculate the AliExternalTrackParam content
780 // Calculate alpha: the rotation angle of the corresponding local system (TPC sector)
781 alpha = part->Phi()*180./TMath::Pi();
782 if (alpha<0) alpha+= 360.;
783 if (alpha>360) alpha -= 360.;
785 Int_t sector = (Int_t)(alpha/20.);
786 alpha = 10. + 20.*sector;
788 alpha *= TMath::Pi();
790 // Covariance matrix: no errors, the parameters are exact
791 for (i=0; i<15; i++) covar[i]=0.;
793 // Get the vertex of origin and the momentum
794 TVector3 ver(part->Vx(),part->Vy(),part->Vz());
795 TVector3 mom(part->Px(),part->Py(),part->Pz());
797 // Rotate to the local coordinate system (TPC sector)
801 // X of the referense plane
804 Int_t pdgCode = part->GetPdgCode();
807 TDatabasePDG::Instance()->GetParticle(pdgCode)->Charge();
811 param[2] = TMath::Sin(mom.Phi());
812 param[3] = mom.Pz()/mom.Pt();
813 param[4] = TMath::Sign(1/mom.Pt(),charge);
815 // Set AliExternalTrackParam
816 Set(xref, alpha, param, covar);
820 if (pdgCode<0) pdgCode = -pdgCode;
821 for (i=0;i<AliPID::kSPECIESC;i++) if (pdgCode==AliPID::ParticleCode(i)) {indexPID = i; break;}
823 if (indexPID < AliPID::kSPECIESC) fPIDForTracking = indexPID;
825 // AliESD track label
826 SetLabel(part->GetUniqueID());
830 //_______________________________________________________________________
831 AliESDtrack::~AliESDtrack(){
833 // This is destructor according Coding Conventrions
835 //printf("Delete track\n");
846 //Reset cached values - needed for TClonesArray in AliESDInputHandler
847 fCacheNCrossedRows = -10.;
848 fCacheChi2TPCConstrainedVsGlobal = -10.;
849 if(fCacheChi2TPCConstrainedVsGlobalVertex) fCacheChi2TPCConstrainedVsGlobalVertex = 0;
852 delete[] fTOFcluster;
865 if(fTrackTime) delete[] fTrackTime;
866 if(fTOFLabel) delete[] fTOFLabel;
869 //_______________________________________________________________________
870 AliESDtrack &AliESDtrack::operator=(const AliESDtrack &source)
874 if(&source == this) return *this;
875 AliExternalTrackParam::operator=(source);
879 // we have the trackparam: assign or copy construct
880 if(fCp)*fCp = *source.fCp;
881 else fCp = new AliExternalTrackParam(*source.fCp);
884 // no track param delete the old one
890 // we have the trackparam: assign or copy construct
891 if(fIp)*fIp = *source.fIp;
892 else fIp = new AliExternalTrackParam(*source.fIp);
895 // no track param delete the old one
901 if(source.fTPCInner){
902 // we have the trackparam: assign or copy construct
903 if(fTPCInner) *fTPCInner = *source.fTPCInner;
904 else fTPCInner = new AliExternalTrackParam(*source.fTPCInner);
907 // no track param delete the old one
912 if(source.fTPCdEdxInfo) {
913 if(fTPCdEdxInfo) *fTPCdEdxInfo = *source.fTPCdEdxInfo;
914 fTPCdEdxInfo = new AliTPCdEdxInfo(*source.fTPCdEdxInfo);
918 // we have the trackparam: assign or copy construct
919 if(fOp) *fOp = *source.fOp;
920 else fOp = new AliExternalTrackParam(*source.fOp);
923 // no track param delete the old one
930 // we have the trackparam: assign or copy construct
931 if(fHMPIDp) *fHMPIDp = *source.fHMPIDp;
932 else fHMPIDp = new AliExternalTrackParam(*source.fHMPIDp);
935 // no track param delete the old one
940 // copy also the friend track
941 // use copy constructor
942 if(source.fFriendTrack){
943 // we have the trackparam: assign or copy construct
944 delete fFriendTrack; fFriendTrack=new AliESDfriendTrack(*source.fFriendTrack);
947 // no track param delete the old one
948 delete fFriendTrack; fFriendTrack= 0;
951 fTPCFitMap = source.fTPCFitMap;
952 fTPCClusterMap = source.fTPCClusterMap;
953 fTPCSharedMap = source.fTPCSharedMap;
955 fFlags = source.fFlags;
957 fLabel = source.fLabel;
958 fITSLabel = source.fITSLabel;
959 for(int i = 0; i< 12;++i){
960 fITSModule[i] = source.fITSModule[i];
962 fTPCLabel = source.fTPCLabel;
963 fTRDLabel = source.fTRDLabel;
964 if(source.fTOFLabel){
965 if(!fTOFLabel) fTOFLabel = new Int_t[3];
966 for(int i = 0; i< 3;++i){
967 fTOFLabel[i] = source.fTOFLabel[i];
970 fTOFCalChannel = source.fTOFCalChannel;
971 fTOFindex = source.fTOFindex;
972 fHMPIDqn = source.fHMPIDqn;
973 fHMPIDcluIdx = source.fHMPIDcluIdx;
974 fCaloIndex = source.fCaloIndex;
975 for (int i=kNITSchi2Std;i--;) fITSchi2Std[i] = source.fITSchi2Std[i];
976 for(int i = 0; i< 3;++i){
977 fKinkIndexes[i] = source.fKinkIndexes[i];
978 fV0Indexes[i] = source.fV0Indexes[i];
982 if (!fR) fR = new Double32_t[AliPID::kSPECIES];
983 for (Int_t i=AliPID::kSPECIES;i--;) fR[i]=source.fR[i];
985 else {delete[] fR; fR = 0;}
988 if (!fITSr) fITSr = new Double32_t[AliPID::kSPECIES];
989 for (Int_t i=AliPID::kSPECIES;i--;) fITSr[i]=source.fITSr[i];
991 else {delete[] fITSr; fITSr = 0;}
994 if (!fTPCr) fTPCr = new Double32_t[AliPID::kSPECIES];
995 for (Int_t i=AliPID::kSPECIES;i--;) fTPCr[i]=source.fTPCr[i];
997 else {delete[] fTPCr; fTPCr = 0;}
1000 if (!fTRDr) fTRDr = new Double32_t[AliPID::kSPECIES];
1001 for (Int_t i=AliPID::kSPECIES;i--;) fTRDr[i]=source.fTRDr[i];
1003 else {delete[] fTRDr; fTRDr = 0;}
1006 if (!fTOFr) fTOFr = new Double32_t[AliPID::kSPECIES];
1007 for (Int_t i=AliPID::kSPECIES;i--;) fTOFr[i]=source.fTOFr[i];
1009 else {delete[] fTOFr; fTOFr = 0;}
1011 if (source.fHMPIDr) {
1012 if (!fHMPIDr) fHMPIDr = new Double32_t[AliPID::kSPECIES];
1013 for (Int_t i=AliPID::kSPECIES;i--;) fHMPIDr[i]=source.fHMPIDr[i];
1015 else {delete[] fHMPIDr; fHMPIDr = 0;}
1017 fPIDForTracking = source.fPIDForTracking;
1019 fHMPIDtrkTheta = source.fHMPIDtrkTheta;
1020 fHMPIDtrkPhi = source.fHMPIDtrkPhi;
1021 fHMPIDsignal = source.fHMPIDsignal;
1025 delete[] fTrackTime;
1027 if(source.fTrackTime){
1028 fTrackTime = new Double32_t[AliPID::kSPECIESC];
1029 for(Int_t i=0;i < AliPID::kSPECIESC;i++)
1030 fTrackTime[i] = source.fTrackTime[i];
1033 fTrackLength = source. fTrackLength;
1034 fdTPC = source.fdTPC;
1035 fzTPC = source.fzTPC;
1036 fCddTPC = source.fCddTPC;
1037 fCdzTPC = source.fCdzTPC;
1038 fCzzTPC = source.fCzzTPC;
1039 fCchi2TPC = source.fCchi2TPC;
1046 fCchi2 = source.fCchi2;
1048 fITSchi2 = source.fITSchi2;
1049 fTPCchi2 = source.fTPCchi2;
1050 fTPCchi2Iter1 = source.fTPCchi2Iter1;
1051 fTRDchi2 = source.fTRDchi2;
1052 fTOFchi2 = source.fTOFchi2;
1053 fHMPIDchi2 = source.fHMPIDchi2;
1055 fGlobalChi2 = source.fGlobalChi2;
1057 fITSsignal = source.fITSsignal;
1058 for (Int_t i=0;i<4;i++) {fITSdEdxSamples[i]=source.fITSdEdxSamples[i];}
1059 fTPCsignal = source.fTPCsignal;
1060 fTPCsignalTuned = source.fTPCsignalTuned;
1061 fTPCsignalS = source.fTPCsignalS;
1062 for(int i = 0; i< 4;++i){
1063 fTPCPoints[i] = source.fTPCPoints[i];
1065 fTRDsignal = source.fTRDsignal;
1066 fTRDNchamberdEdx = source.fTRDNchamberdEdx;
1067 fTRDNclusterdEdx = source.fTRDNclusterdEdx;
1069 for(int i = 0;i < kTRDnPlanes;++i){
1070 fTRDTimBin[i] = source.fTRDTimBin[i];
1074 delete[] fTRDslices;
1076 fTRDnSlices=source.fTRDnSlices;
1078 fTRDslices=new Double32_t[fTRDnSlices];
1079 for(int j = 0;j < fTRDnSlices;++j) fTRDslices[j] = source.fTRDslices[j];
1082 fTRDQuality = source.fTRDQuality;
1083 fTRDBudget = source.fTRDBudget;
1084 fTOFsignal = source.fTOFsignal;
1085 fTOFsignalTuned = source.fTOFsignalTuned;
1086 fTOFsignalToT = source.fTOFsignalToT;
1087 fTOFsignalRaw = source.fTOFsignalRaw;
1088 fTOFsignalDz = source.fTOFsignalDz;
1089 fTOFsignalDx = source.fTOFsignalDx;
1090 fTOFdeltaBC = source.fTOFdeltaBC;
1091 fTOFl0l1 = source.fTOFl0l1;
1093 for(int i = 0;i<10;++i){
1094 fTOFInfo[i] = source.fTOFInfo[i];
1097 fHMPIDtrkX = source.fHMPIDtrkX;
1098 fHMPIDtrkY = source.fHMPIDtrkY;
1099 fHMPIDmipX = source.fHMPIDmipX;
1100 fHMPIDmipY = source.fHMPIDmipY;
1102 fTPCncls = source.fTPCncls;
1103 fTPCnclsF = source.fTPCnclsF;
1104 fTPCsignalN = source.fTPCsignalN;
1105 fTPCnclsIter1 = source.fTPCnclsIter1;
1106 fTPCnclsFIter1 = source.fTPCnclsFIter1;
1108 fITSncls = source.fITSncls;
1109 fITSClusterMap = source.fITSClusterMap;
1110 fITSSharedMap = source.fITSSharedMap;
1111 fTRDncls = source.fTRDncls;
1112 fTRDncls0 = source.fTRDncls0;
1113 fTRDntracklets = source.fTRDntracklets;
1114 fVertexID = source.fVertexID;
1115 fPIDForTracking = source.fPIDForTracking;
1117 fCacheNCrossedRows = source.fCacheNCrossedRows;
1118 fCacheChi2TPCConstrainedVsGlobal = source.fCacheChi2TPCConstrainedVsGlobal;
1119 fCacheChi2TPCConstrainedVsGlobalVertex = source.fCacheChi2TPCConstrainedVsGlobalVertex;
1121 delete fDetectorPID;
1123 if (source.fDetectorPID) fDetectorPID = new AliDetectorPID(*source.fDetectorPID);
1125 fTrackPhiOnEMCal= source.fTrackPhiOnEMCal;
1126 fTrackEtaOnEMCal= source.fTrackEtaOnEMCal;
1127 fTrackPtOnEMCal= source.fTrackPtOnEMCal;
1130 delete[] fTOFcluster;
1132 fNtofClusters = source.fNtofClusters;
1133 if(fNtofClusters > 0){
1134 fTOFcluster = new Int_t[fNtofClusters];
1135 for(Int_t i=0;i < fNtofClusters;i++) fTOFcluster[i] = source.fTOFcluster[i];
1143 void AliESDtrack::Copy(TObject &obj) const {
1145 // this overwrites the virtual TOBject::Copy()
1146 // to allow run time copying without casting
1149 if(this==&obj)return;
1150 AliESDtrack *robj = dynamic_cast<AliESDtrack*>(&obj);
1151 if(!robj)return; // not an AliESDtrack
1158 void AliESDtrack::AddCalibObject(TObject * object){
1160 // add calib object to the list
1162 if (!fFriendTrack) fFriendTrack = new AliESDfriendTrack;
1163 if (!fFriendTrack) return;
1164 fFriendTrack->AddCalibObject(object);
1167 TObject * AliESDtrack::GetCalibObject(Int_t index){
1169 // return calib objct at given position
1171 if (!fFriendTrack) return 0;
1172 return fFriendTrack->GetCalibObject(index);
1176 Bool_t AliESDtrack::FillTPCOnlyTrack(AliESDtrack &track){
1178 // Fills the information of the TPC-only first reconstruction pass
1179 // into the passed ESDtrack object. For consistency fTPCInner is also filled
1184 // For data produced before r26675
1185 // RelateToVertexTPC was not properly called during reco
1186 // so you'll have to call it again, before FillTPCOnlyTrack
1187 // Float_t p[2],cov[3];
1188 // track->GetImpactParametersTPC(p,cov);
1189 // if(p[0]==0&&p[1]==0) // <- Default values
1190 // track->RelateToVertexTPC(esd->GetPrimaryVertexTPC(),esd->GetMagneticField(),kVeryBig);
1193 if(!fTPCInner)return kFALSE;
1195 // fill the TPC track params to the global track parameters
1196 track.Set(fTPCInner->GetX(),fTPCInner->GetAlpha(),fTPCInner->GetParameter(),fTPCInner->GetCovariance());
1199 track.fCdd = fCddTPC;
1200 track.fCdz = fCdzTPC;
1201 track.fCzz = fCzzTPC;
1203 // copy the inner params
1204 if(track.fIp) *track.fIp = *fIp;
1205 else track.fIp = new AliExternalTrackParam(*fIp);
1207 // copy the TPCinner parameters
1208 if(track.fTPCInner) *track.fTPCInner = *fTPCInner;
1209 else track.fTPCInner = new AliExternalTrackParam(*fTPCInner);
1210 track.fdTPC = fdTPC;
1211 track.fzTPC = fzTPC;
1212 track.fCddTPC = fCddTPC;
1213 track.fCdzTPC = fCdzTPC;
1214 track.fCzzTPC = fCzzTPC;
1215 track.fCchi2TPC = fCchi2TPC;
1217 // copy all other TPC specific parameters
1219 // replace label by TPC label
1220 track.fLabel = fTPCLabel;
1221 track.fTPCLabel = fTPCLabel;
1223 track.fTPCchi2 = fTPCchi2;
1224 track.fTPCchi2Iter1 = fTPCchi2Iter1;
1225 track.fTPCsignal = fTPCsignal;
1226 track.fTPCsignalTuned = fTPCsignalTuned;
1227 track.fTPCsignalS = fTPCsignalS;
1228 for(int i = 0;i<4;++i)track.fTPCPoints[i] = fTPCPoints[i];
1230 track.fTPCncls = fTPCncls;
1231 track.fTPCnclsF = fTPCnclsF;
1232 track.fTPCsignalN = fTPCsignalN;
1233 track.fTPCnclsIter1 = fTPCnclsIter1;
1234 track.fTPCnclsFIter1 = fTPCnclsFIter1;
1238 if (!track.fTPCr) track.fTPCr = new Double32_t[AliPID::kSPECIES];
1239 for(int i=AliPID::kSPECIES;i--;) track.fTPCr[i] = fTPCr[i];
1243 if (!track.fR) track.fR = new Double32_t[AliPID::kSPECIES];
1244 for(int i=AliPID::kSPECIES;i--;) track.fR[i] = fR[i];
1247 track.fTPCFitMap = fTPCFitMap;
1248 track.fTPCClusterMap = fTPCClusterMap;
1249 track.fTPCSharedMap = fTPCSharedMap;
1253 track.fFlags = kTPCin;
1256 track.fFlags |= fFlags & kTPCpid; //copy the TPCpid status flag
1258 for (Int_t i=0;i<3;i++) track.fKinkIndexes[i] = fKinkIndexes[i];
1264 //_______________________________________________________________________
1265 void AliESDtrack::MakeMiniESDtrack(){
1266 // Resets everything except
1267 // fFlags: Reconstruction status flags
1268 // fLabel: Track label
1269 // fID: Unique ID of the track
1270 // Impact parameter information
1271 // fR[AliPID::kSPECIES]: combined "detector response probability"
1272 // Running track parameters in the base class (AliExternalTrackParam)
1277 for (Int_t i=0;i<AliPID::kSPECIESC;i++) fTrackTime[i] = 0;
1279 // Reset track parameters constrained to the primary vertex
1282 // Reset track parameters at the inner wall of TPC
1284 delete fTPCInner;fTPCInner=0;
1285 // Reset track parameters at the inner wall of the TRD
1287 // Reset track parameters at the HMPID
1288 delete fHMPIDp;fHMPIDp = 0;
1291 // Reset ITS track related information
1297 for (Int_t i=0;i<4;i++) fITSdEdxSamples[i] = 0.;
1298 if (fITSr) for (Int_t i=0;i<AliPID::kSPECIES;i++) fITSr[i]=0;
1301 // Reset TPC related track information
1315 if (fTPCr) for (Int_t i=0;i<AliPID::kSPECIES;i++) fTPCr[i] = 0;
1317 for (Int_t i=0;i<4;i++) fTPCPoints[i] = 0;
1318 for (Int_t i=0; i<3;i++) fKinkIndexes[i] = 0;
1319 for (Int_t i=0; i<3;i++) fV0Indexes[i] = 0;
1321 // Reset TRD related track information
1326 fTRDNchamberdEdx = 0;
1327 fTRDNclusterdEdx = 0;
1329 for (Int_t i=0;i<kTRDnPlanes;i++) {
1332 if (fTRDr) for (Int_t i=0;i<AliPID::kSPECIES;i++) fTRDr[i] = 0;
1337 delete[] fTRDslices;
1342 // Reset TOF related track information
1346 fTOFCalChannel = -1;
1347 fTOFsignalToT = 99999;
1348 fTOFsignalRaw = 99999;
1353 if (fTOFr) for (Int_t i=0;i<AliPID::kSPECIES;i++) fTOFr[i] = 0;
1354 for (Int_t i=0;i<10;i++) fTOFInfo[i] = 0;
1356 // Reset HMPID related track information
1361 if (fHMPIDr) for (Int_t i=0;i<AliPID::kSPECIES;i++) fHMPIDr[i] = 0;
1368 fCaloIndex = kEMCALNoMatch;
1370 // reset global track chi2
1373 fVertexID = -2; // an orphan track
1374 fPIDForTracking = AliPID::kPion;
1376 delete fFriendTrack; fFriendTrack = 0;
1379 //_______________________________________________________________________
1380 Int_t AliESDtrack::GetPID(Bool_t tpcOnly) const
1382 // Returns the particle most probable id. For backward compatibility first the prob. arrays
1383 // will be checked, but normally the GetPIDForTracking will be returned
1385 const Double32_t *prob = 0;
1386 if (tpcOnly) { // check if TPCpid is valid
1387 if (!fTPCr) return GetPIDForTracking();
1389 for (i=0; i<AliPID::kSPECIES-1; i++) if (prob[i] != prob[i+1]) break;
1390 if (i == AliPID::kSPECIES-1) prob = 0; // not valid, try with combined pid
1392 if (!prob) { // either requested TPCpid is not valid or comb.pid is requested
1393 if (!fR) return GetPIDForTracking();
1395 for (i=0; i<AliPID::kSPECIES-1; i++) if (prob[i] != prob[i+1]) break;
1396 if (i == AliPID::kSPECIES-1) return GetPIDForTracking(); // If all the probabilities are equal, return the pion mass
1401 for (i=0; i<AliPID::kSPECIES; i++) if (prob[i]>max) {k=i; max=prob[i];}
1403 if (k==0) { // dE/dx "crossing points" in the TPC
1406 if ((p>0.38)&&(p<0.48))
1407 if (prob[0]<prob[3]*10.) return AliPID::kKaon;
1408 if ((p>0.75)&&(p<0.85))
1409 if (prob[0]<prob[4]*10.) return AliPID::kProton;
1411 return AliPID::kElectron;
1413 if (k==1) return AliPID::kMuon;
1414 if (k==2||k==-1) return AliPID::kPion;
1415 if (k==3) return AliPID::kKaon;
1416 if (k==4) return AliPID::kProton;
1417 // AliWarning("Undefined PID !");
1418 return GetPIDForTracking();
1421 //_______________________________________________________________________
1422 Int_t AliESDtrack::GetTOFBunchCrossing(Double_t b, Bool_t pidTPConly) const
1424 // Returns the number of bunch crossings after trigger (assuming 25ns spacing)
1425 const double kSpacing = 25e3; // min interbanch spacing
1426 const double kShift = 0;
1427 Int_t bcid = kTOFBCNA; // defualt one
1428 if (!IsOn(kTOFout)/* || !IsOn(kESDpid)*/) return bcid; // no info
1430 double tdif = GetTOFsignal();
1431 if (IsOn(kTIME)) { // integrated time info is there
1432 int pid = GetPID(pidTPConly);
1433 Double_t times[AliPID::kSPECIESC];
1434 // old esd has only AliPID::kSPECIES times
1435 GetIntegratedTimes(times,pid>=AliPID::kSPECIES ? AliPID::kSPECIESC : AliPID::kSPECIES);
1438 else { // assume integrated time info from TOF radius and momentum
1439 const double kRTOF = 385.;
1440 const double kCSpeed = 3.e-2; // cm/ps
1442 if (p<0.01) return bcid;
1443 double m = GetMass(pidTPConly);
1444 double curv = GetC(b);
1445 double path = TMath::Abs(curv)>kAlmost0 ? // account for curvature
1446 2./curv*TMath::ASin(kRTOF*curv/2.)*TMath::Sqrt(1.+GetTgl()*GetTgl()) : kRTOF;
1447 tdif -= path/kCSpeed*TMath::Sqrt(1.+m*m/(p*p));
1449 bcid = TMath::Nint((tdif - kShift)/kSpacing);
1453 //______________________________________________________________________________
1454 Double_t AliESDtrack::M() const
1456 // Returns the assumed mass
1457 // (the pion mass, if the particle can't be identified properly).
1458 static Bool_t printerr=kTRUE;
1460 AliWarning("WARNING !!! ... THIS WILL BE PRINTED JUST ONCE !!!");
1462 AliWarning("This is the ESD mass. Use it with care !");
1467 //______________________________________________________________________________
1468 Double_t AliESDtrack::E() const
1470 // Returns the energy of the particle given its assumed mass.
1471 // Assumes the pion mass if the particle can't be identified properly.
1475 return TMath::Sqrt(p*p + m*m);
1478 //______________________________________________________________________________
1479 Double_t AliESDtrack::Y() const
1481 // Returns the rapidity of a particle given its assumed mass.
1482 // Assumes the pion mass if the particle can't be identified properly.
1486 if (e != TMath::Abs(pz)) { // energy was not equal to pz
1487 return 0.5*TMath::Log((e+pz)/(e-pz));
1488 } else { // energy was equal to pz
1493 //_______________________________________________________________________
1494 Bool_t AliESDtrack::UpdateTrackParams(const AliKalmanTrack *t, ULong_t flags){
1496 // This function updates track's running parameters
1501 fLabel=t->GetLabel();
1503 if (t->IsStartedTimeIntegral()) {
1505 Double_t times[AliPID::kSPECIESC];
1506 t->GetIntegratedTimes(times);
1507 SetIntegratedTimes(times);
1508 SetIntegratedLength(t->GetIntegratedLength());
1511 Set(t->GetX(),t->GetAlpha(),t->GetParameter(),t->GetCovariance());
1513 if (flags==kITSout) fFriendTrack->SetITSOut(*t);
1514 if (flags==kTPCout) fFriendTrack->SetTPCOut(*t);
1515 if (flags==kTRDrefit) fFriendTrack->SetTRDIn(*t);
1521 fITSchi2Std[0] = t->GetChi2();
1524 fITSchi2Std[1] = t->GetChi2();
1527 fITSchi2Std[2] = t->GetChi2();
1529 fITSncls=t->GetNumberOfClusters();
1531 Int_t* indexITS = new Int_t[AliESDfriendTrack::kMaxITScluster];
1532 for (Int_t i=0;i<AliESDfriendTrack::kMaxITScluster;i++) {
1533 indexITS[i]=t->GetClusterIndex(i);
1536 Int_t l=(indexITS[i] & 0xf0000000) >> 28;
1537 SETBIT(fITSClusterMap,l);
1540 fFriendTrack->SetITSIndices(indexITS,AliESDfriendTrack::kMaxITScluster);
1544 fITSchi2=t->GetChi2();
1545 fITSsignal=t->GetPIDsignal();
1546 fITSLabel = t->GetLabel();
1547 // keep in fOp the parameters outside ITS for ITS stand-alone tracks
1548 if (flags==kITSout) {
1549 if (!fOp) fOp=new AliExternalTrackParam(*t);
1551 fOp->Set(t->GetX(),t->GetAlpha(),t->GetParameter(),t->GetCovariance());
1556 case kTPCin: case kTPCrefit:
1558 fTPCLabel = t->GetLabel();
1559 if (flags==kTPCin) {
1560 fTPCInner=new AliExternalTrackParam(*t);
1561 fTPCnclsIter1=t->GetNumberOfClusters();
1562 fTPCchi2Iter1=t->GetChi2();
1564 if (!fIp) fIp=new AliExternalTrackParam(*t);
1566 fIp->Set(t->GetX(),t->GetAlpha(),t->GetParameter(),t->GetCovariance());
1568 // Intentionally no break statement; need to set general TPC variables as well
1571 if (flags & kTPCout){
1572 if (!fOp) fOp=new AliExternalTrackParam(*t);
1574 fOp->Set(t->GetX(),t->GetAlpha(),t->GetParameter(),t->GetCovariance());
1576 fTPCncls=t->GetNumberOfClusters();
1577 fTPCchi2=t->GetChi2();
1579 if (fFriendTrack) { // Copy cluster indices
1580 Int_t* indexTPC = new Int_t[AliESDfriendTrack::kMaxTPCcluster];
1581 for (Int_t i=0;i<AliESDfriendTrack::kMaxTPCcluster;i++)
1582 indexTPC[i]=t->GetClusterIndex(i);
1583 fFriendTrack->SetTPCIndices(indexTPC,AliESDfriendTrack::kMaxTPCcluster);
1586 fTPCsignal=t->GetPIDsignal();
1590 case kTRDin: case kTRDrefit:
1594 fTRDLabel = t->GetLabel();
1595 fTRDchi2 = t->GetChi2();
1596 fTRDncls = t->GetNumberOfClusters();
1598 Int_t* indexTRD = new Int_t[AliESDfriendTrack::kMaxTRDcluster];
1599 for (Int_t i=0;i<AliESDfriendTrack::kMaxTRDcluster;i++) indexTRD[i]=-2;
1600 for (Int_t i=0;i<6;i++) indexTRD[i]=t->GetTrackletIndex(i);
1601 fFriendTrack->SetTRDIndices(indexTRD,AliESDfriendTrack::kMaxTRDcluster);
1605 //commented out by Xianguo
1606 //fTRDsignal=t->GetPIDsignal();
1610 if (!fOp) fOp=new AliExternalTrackParam(*t);
1612 fOp->Set(t->GetX(),t->GetAlpha(),t->GetParameter(),t->GetCovariance());
1613 fTRDncls0 = t->GetNumberOfClusters();
1622 if (!fHMPIDp) fHMPIDp=new AliExternalTrackParam(*t);
1624 fHMPIDp->Set(t->GetX(),t->GetAlpha(),t->GetParameter(),t->GetCovariance());
1627 AliError("Wrong flag !");
1634 //_______________________________________________________________________
1635 void AliESDtrack::GetExternalParameters(Double_t &x, Double_t p[5]) const {
1636 //---------------------------------------------------------------------
1637 // This function returns external representation of the track parameters
1638 //---------------------------------------------------------------------
1640 for (Int_t i=0; i<5; i++) p[i]=GetParameter()[i];
1643 //_______________________________________________________________________
1644 void AliESDtrack::GetExternalCovariance(Double_t cov[15]) const {
1645 //---------------------------------------------------------------------
1646 // This function returns external representation of the cov. matrix
1647 //---------------------------------------------------------------------
1648 for (Int_t i=0; i<15; i++) cov[i]=AliExternalTrackParam::GetCovariance()[i];
1651 //_______________________________________________________________________
1652 Bool_t AliESDtrack::GetConstrainedExternalParameters
1653 (Double_t &alpha, Double_t &x, Double_t p[5]) const {
1654 //---------------------------------------------------------------------
1655 // This function returns the constrained external track parameters
1656 //---------------------------------------------------------------------
1657 if (!fCp) return kFALSE;
1658 alpha=fCp->GetAlpha();
1660 for (Int_t i=0; i<5; i++) p[i]=fCp->GetParameter()[i];
1664 //_______________________________________________________________________
1666 AliESDtrack::GetConstrainedExternalCovariance(Double_t c[15]) const {
1667 //---------------------------------------------------------------------
1668 // This function returns the constrained external cov. matrix
1669 //---------------------------------------------------------------------
1670 if (!fCp) return kFALSE;
1671 for (Int_t i=0; i<15; i++) c[i]=fCp->GetCovariance()[i];
1676 AliESDtrack::GetInnerExternalParameters
1677 (Double_t &alpha, Double_t &x, Double_t p[5]) const {
1678 //---------------------------------------------------------------------
1679 // This function returns external representation of the track parameters
1680 // at the inner layer of TPC
1681 //---------------------------------------------------------------------
1682 if (!fIp) return kFALSE;
1683 alpha=fIp->GetAlpha();
1685 for (Int_t i=0; i<5; i++) p[i]=fIp->GetParameter()[i];
1690 AliESDtrack::GetInnerExternalCovariance(Double_t cov[15]) const {
1691 //---------------------------------------------------------------------
1692 // This function returns external representation of the cov. matrix
1693 // at the inner layer of TPC
1694 //---------------------------------------------------------------------
1695 if (!fIp) return kFALSE;
1696 for (Int_t i=0; i<15; i++) cov[i]=fIp->GetCovariance()[i];
1701 AliESDtrack::SetOuterParam(const AliExternalTrackParam *p, ULong_t flags) {
1703 // This is a direct setter for the outer track parameters
1706 if (fOp) delete fOp;
1707 fOp=new AliExternalTrackParam(*p);
1711 AliESDtrack::SetOuterHmpParam(const AliExternalTrackParam *p, ULong_t flags) {
1713 // This is a direct setter for the outer track parameters
1716 if (fHMPIDp) delete fHMPIDp;
1717 fHMPIDp=new AliExternalTrackParam(*p);
1721 AliESDtrack::GetOuterExternalParameters
1722 (Double_t &alpha, Double_t &x, Double_t p[5]) const {
1723 //---------------------------------------------------------------------
1724 // This function returns external representation of the track parameters
1725 // at the inner layer of TRD
1726 //---------------------------------------------------------------------
1727 if (!fOp) return kFALSE;
1728 alpha=fOp->GetAlpha();
1730 for (Int_t i=0; i<5; i++) p[i]=fOp->GetParameter()[i];
1735 AliESDtrack::GetOuterHmpExternalParameters
1736 (Double_t &alpha, Double_t &x, Double_t p[5]) const {
1737 //---------------------------------------------------------------------
1738 // This function returns external representation of the track parameters
1739 // at the inner layer of TRD
1740 //---------------------------------------------------------------------
1741 if (!fHMPIDp) return kFALSE;
1742 alpha=fHMPIDp->GetAlpha();
1744 for (Int_t i=0; i<5; i++) p[i]=fHMPIDp->GetParameter()[i];
1749 AliESDtrack::GetOuterExternalCovariance(Double_t cov[15]) const {
1750 //---------------------------------------------------------------------
1751 // This function returns external representation of the cov. matrix
1752 // at the inner layer of TRD
1753 //---------------------------------------------------------------------
1754 if (!fOp) return kFALSE;
1755 for (Int_t i=0; i<15; i++) cov[i]=fOp->GetCovariance()[i];
1760 AliESDtrack::GetOuterHmpExternalCovariance(Double_t cov[15]) const {
1761 //---------------------------------------------------------------------
1762 // This function returns external representation of the cov. matrix
1763 // at the inner layer of TRD
1764 //---------------------------------------------------------------------
1765 if (!fHMPIDp) return kFALSE;
1766 for (Int_t i=0; i<15; i++) cov[i]=fHMPIDp->GetCovariance()[i];
1770 Int_t AliESDtrack::GetNcls(Int_t idet) const
1772 // Get number of clusters by subdetector index
1786 if (fTOFindex != -1)
1792 if ((fHMPIDcluIdx >= 0) && (fHMPIDcluIdx < 7000000)) {
1793 if ((fHMPIDcluIdx%1000000 != 9999) && (fHMPIDcluIdx%1000000 != 99999)) {
1804 Int_t AliESDtrack::GetClusters(Int_t idet, Int_t *idx) const
1806 // Get cluster index array by subdetector index
1811 ncls = GetITSclusters(idx);
1814 ncls = GetTPCclusters(idx);
1817 ncls = GetTRDclusters(idx);
1820 if (fTOFindex != -1) {
1828 if ((fHMPIDcluIdx >= 0) && (fHMPIDcluIdx < 7000000)) {
1829 if ((fHMPIDcluIdx%1000000 != 9999) && (fHMPIDcluIdx%1000000 != 99999)) {
1830 idx[0] = GetHMPIDcluIdx();
1843 //_______________________________________________________________________
1844 void AliESDtrack::GetIntegratedTimes(Double_t *times, Int_t nspec) const
1846 // get integrated time for requested N species
1847 if (nspec<1) return;
1848 if(fNtofClusters>0 && GetESDEvent()){
1849 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
1850 AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
1852 for(int i=tofcl->GetNMatchableTracks();i--;){
1853 if(tofcl->GetTrackIndex(i) == GetID()) {
1854 for (int j=nspec; j--;) times[j]=tofcl->GetIntegratedTime(j,i);
1859 else if(fNtofClusters>0)
1860 AliInfo("No AliESDEvent available here!\n");
1862 // Returns the array with integrated times for each particle hypothesis
1864 for (int i=nspec; i--;) times[i]=fTrackTime[i];
1866 for (int i=AliPID::kSPECIESC; i--;) times[i]=0.0;
1869 //_______________________________________________________________________
1870 Double_t AliESDtrack::GetIntegratedLength() const{
1872 if(fNtofClusters>0 && GetESDEvent()){
1873 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
1874 AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
1876 for(Int_t i=0;i < tofcl->GetNMatchableTracks();i++){
1877 if(tofcl->GetTrackIndex(i) == GetID()) index = i;
1880 if(fNtofClusters>0 && index > -1)
1881 return tofcl->GetLength(index);
1883 else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
1885 return fTrackLength;
1888 //_______________________________________________________________________
1889 void AliESDtrack::SetIntegratedTimes(const Double_t *times)
1891 // Sets the array with integrated times for each particle hypotesis
1892 if(!fTrackTime) fTrackTime = new Double32_t[AliPID::kSPECIESC];
1893 for (int i=AliPID::kSPECIESC; i--;) fTrackTime[i]=times[i];
1896 //_______________________________________________________________________
1897 void AliESDtrack::SetITSpid(const Double_t *p)
1899 // Sets values for the probability of each particle type (in ITS)
1900 if (!fITSr) fITSr = new Double32_t[AliPID::kSPECIESC];
1901 SetPIDValues(fITSr,p,AliPID::kSPECIES);
1902 SetStatus(AliESDtrack::kITSpid);
1905 //_______________________________________________________________________
1906 void AliESDtrack::GetITSpid(Double_t *p) const {
1907 // Gets the probability of each particle type (in ITS)
1908 for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i] = fITSr ? fITSr[i] : 0;
1911 //_______________________________________________________________________
1912 Char_t AliESDtrack::GetITSclusters(Int_t *idx) const {
1913 //---------------------------------------------------------------------
1914 // This function returns indices of the assgined ITS clusters
1915 //---------------------------------------------------------------------
1916 if (idx && fFriendTrack) {
1917 Int_t *index=fFriendTrack->GetITSindices();
1918 for (Int_t i=0; i<AliESDfriendTrack::kMaxITScluster; i++) {
1919 if ( (i>=fITSncls) && (i<6) ) idx[i]=-1;
1931 //_______________________________________________________________________
1932 Bool_t AliESDtrack::GetITSModuleIndexInfo(Int_t ilayer,Int_t &idet,Int_t &status,
1933 Float_t &xloc,Float_t &zloc) const {
1934 //----------------------------------------------------------------------
1935 // This function encodes in the module number also the status of cluster association
1936 // "status" can have the following values:
1937 // 1 "found" (cluster is associated),
1938 // 2 "dead" (module is dead from OCDB),
1939 // 3 "skipped" (module or layer forced to be skipped),
1940 // 4 "outinz" (track out of z acceptance),
1941 // 5 "nocls" (no clusters in the road),
1942 // 6 "norefit" (cluster rejected during refit),
1943 // 7 "deadzspd" (holes in z in SPD)
1944 // Also given are the coordinates of the crossing point of track and module
1945 // (in the local module ref. system)
1946 // WARNING: THIS METHOD HAS TO BE SYNCHRONIZED WITH AliITStrackV2::GetModuleIndexInfo()!
1947 //----------------------------------------------------------------------
1949 if(fITSModule[ilayer]==-1) {
1952 xloc=-99.; zloc=-99.;
1956 Int_t module = fITSModule[ilayer];
1958 idet = Int_t(module/1000000);
1960 module -= idet*1000000;
1962 status = Int_t(module/100000);
1964 module -= status*100000;
1966 Int_t signs = Int_t(module/10000);
1968 module-=signs*10000;
1970 Int_t xInt = Int_t(module/100);
1973 Int_t zInt = module;
1975 if(signs==1) { xInt*=1; zInt*=1; }
1976 if(signs==2) { xInt*=1; zInt*=-1; }
1977 if(signs==3) { xInt*=-1; zInt*=1; }
1978 if(signs==4) { xInt*=-1; zInt*=-1; }
1980 xloc = 0.1*(Float_t)xInt;
1981 zloc = 0.1*(Float_t)zInt;
1983 if(status==4) idet = -1;
1988 //_______________________________________________________________________
1989 UShort_t AliESDtrack::GetTPCclusters(Int_t *idx) const {
1990 //---------------------------------------------------------------------
1991 // This function returns indices of the assgined ITS clusters
1992 //---------------------------------------------------------------------
1993 if (idx && fFriendTrack) {
1994 Int_t *index=fFriendTrack->GetTPCindices();
1997 for (Int_t i=0; i<AliESDfriendTrack::kMaxTPCcluster; i++) idx[i]=index[i];
2000 for (Int_t i=0; i<AliESDfriendTrack::kMaxTPCcluster; i++) idx[i]=-2;
2006 //_______________________________________________________________________
2007 Float_t AliESDtrack::GetTPCCrossedRows() const
2009 // This function calls GetTPCClusterInfo with some default parameters which are used in the track selection and caches the outcome
2010 // because GetTPCClusterInfo is quite time-consuming
2012 if (fCacheNCrossedRows > -1)
2013 return fCacheNCrossedRows;
2015 fCacheNCrossedRows = GetTPCClusterInfo(2, 1);
2016 return fCacheNCrossedRows;
2019 //_______________________________________________________________________
2020 Float_t AliESDtrack::GetTPCClusterInfo(Int_t nNeighbours/*=3*/, Int_t type/*=0*/, Int_t row0, Int_t row1, Int_t bitType ) const
2023 // TPC cluster information
2024 // type 0: get fraction of found/findable clusters with neighbourhood definition
2025 // 1: findable clusters with neighbourhood definition
2026 // 2: found clusters
2028 // 0 - all cluster used
2029 // 1 - clusters used for the kalman update
2030 // definition of findable clusters:
2031 // a cluster is defined as findable if there is another cluster
2032 // within +- nNeighbours pad rows. The idea is to overcome threshold
2033 // effects with a very simple algorithm.
2039 Int_t last=-nNeighbours;
2040 const TBits & clusterMap = (bitType%2==0) ? fTPCClusterMap : fTPCFitMap;
2042 Int_t upperBound=clusterMap.GetNbits();
2043 if (upperBound>row1) upperBound=row1;
2044 for (Int_t i=row0; i<upperBound; ++i){
2045 //look to current row
2046 if (clusterMap[i]) {
2052 //look to nNeighbours before
2053 if ((i-last)<=nNeighbours) {
2057 //look to nNeighbours after
2058 for (Int_t j=i+1; j<i+1+nNeighbours; ++j){
2065 if (type==2) return found;
2066 if (type==1) return findable;
2071 fraction=(Float_t)found/(Float_t)findable;
2076 return 0; // undefined type - default value
2079 //_______________________________________________________________________
2080 Float_t AliESDtrack::GetTPCClusterDensity(Int_t nNeighbours/*=3*/, Int_t type/*=0*/, Int_t row0, Int_t row1, Int_t bitType ) const
2083 // TPC cluster density - only rows where signal before and after given row are used
2084 // - slower function
2085 // type 0: get fraction of found/findable clusters with neighbourhood definition
2086 // 1: findable clusters with neighbourhood definition
2087 // 2: found clusters
2089 // 0 - all cluster used
2090 // 1 - clusters used for the kalman update
2091 // definition of findable clusters:
2092 // a cluster is defined as findable if there is another cluster
2093 // within +- nNeighbours pad rows. The idea is to overcome threshold
2094 // effects with a very simple algorithm.
2098 // Int_t last=-nNeighbours;
2099 const TBits & clusterMap = (bitType%2==0) ? fTPCClusterMap : fTPCFitMap;
2100 Int_t upperBound=clusterMap.GetNbits();
2101 if (upperBound>row1) upperBound=row1;
2102 for (Int_t i=row0; i<upperBound; ++i){
2104 Bool_t isDown=kFALSE;
2105 for (Int_t idelta=1; idelta<=nNeighbours; idelta++){
2106 if (i-idelta>=0 && clusterMap[i-idelta]) isDown=kTRUE;
2107 if (i+idelta<upperBound && clusterMap[i+idelta]) isUp=kTRUE;
2111 if (clusterMap[i]) ++found;
2114 if (type==2) return found;
2115 if (type==1) return findable;
2120 fraction=(Float_t)found/(Float_t)findable;
2125 return 0; // undefined type - default value
2131 //_______________________________________________________________________
2132 Double_t AliESDtrack::GetTPCdensity(Int_t row0, Int_t row1) const{
2134 // GetDensity of the clusters on given region between row0 and row1
2135 // Dead zone effect takin into acoount
2137 if (!fFriendTrack) return 0.0;
2141 Int_t *index=fFriendTrack->GetTPCindices();
2142 for (Int_t i=row0;i<=row1;i++){
2143 Int_t idx = index[i];
2144 if (idx!=-1) good++; // track outside of dead zone
2147 Float_t density=0.5;
2148 if (good>TMath::Max((row1-row0)*0.5,0.0)) density = Float_t(found)/Float_t(good);
2152 //_______________________________________________________________________
2153 void AliESDtrack::SetTPCpid(const Double_t *p) {
2154 // Sets values for the probability of each particle type (in TPC)
2155 if (!fTPCr) fTPCr = new Double32_t[AliPID::kSPECIES];
2156 SetPIDValues(fTPCr,p,AliPID::kSPECIES);
2157 SetStatus(AliESDtrack::kTPCpid);
2160 //_______________________________________________________________________
2161 void AliESDtrack::GetTPCpid(Double_t *p) const {
2162 // Gets the probability of each particle type (in TPC)
2163 for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i] = fTPCr ? fTPCr[i] : 0;
2166 //_______________________________________________________________________
2167 UChar_t AliESDtrack::GetTRDclusters(Int_t *idx) const {
2168 //---------------------------------------------------------------------
2169 // This function returns indices of the assgined TRD clusters
2170 //---------------------------------------------------------------------
2171 if (idx && fFriendTrack) {
2172 Int_t *index=fFriendTrack->GetTRDindices();
2175 for (Int_t i=0; i<AliESDfriendTrack::kMaxTRDcluster; i++) idx[i]=index[i];
2178 for (Int_t i=0; i<AliESDfriendTrack::kMaxTRDcluster; i++) idx[i]=-2;
2184 //_______________________________________________________________________
2185 UChar_t AliESDtrack::GetTRDtracklets(Int_t *idx) const {
2187 // This function returns the number of TRD tracklets used in tracking
2188 // and it fills the indices of these tracklets in the array "idx" as they
2189 // are registered in the TRD track list.
2192 // 1. The idx array has to be allocated with a size >= AliESDtrack::kTRDnPlanes
2193 // 2. The idx array store not only the index but also the layer of the tracklet.
2194 // Therefore tracks with TRD gaps contain default values for indices [-1]
2196 if (!fFriendTrack) return 0;
2197 if (!idx) return GetTRDntracklets();
2198 Int_t *index=fFriendTrack->GetTRDindices();
2200 for (Int_t i=0; i<kTRDnPlanes; i++){
2202 if(index[i]>=0) n++;
2210 //_______________________________________________________________________
2211 void AliESDtrack::SetTRDpid(const Double_t *p) {
2212 // Sets values for the probability of each particle type (in TRD)
2213 if (!fTRDr) fTRDr = new Double32_t[AliPID::kSPECIES];
2214 SetPIDValues(fTRDr,p,AliPID::kSPECIES);
2215 SetStatus(AliESDtrack::kTRDpid);
2218 //_______________________________________________________________________
2219 void AliESDtrack::GetTRDpid(Double_t *p) const {
2220 // Gets the probability of each particle type (in TRD)
2221 for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i] = fTRDr ? fTRDr[i]:0;
2224 //_______________________________________________________________________
2225 void AliESDtrack::SetTRDpid(Int_t iSpecies, Float_t p)
2227 // Sets the probability of particle type iSpecies to p (in TRD)
2229 fTRDr = new Double32_t[AliPID::kSPECIES];
2230 for (Int_t i=AliPID::kSPECIES; i--;) fTRDr[i] = 0;
2232 fTRDr[iSpecies] = p;
2235 Double_t AliESDtrack::GetTRDpid(Int_t iSpecies) const
2237 // Returns the probability of particle type iSpecies (in TRD)
2238 return fTRDr ? fTRDr[iSpecies] : 0;
2241 //____________________________________________________
2242 Int_t AliESDtrack::GetNumberOfTRDslices() const
2244 // built in backward compatibility
2245 Int_t idx = fTRDnSlices - (kTRDnPlanes<<1);
2246 return idx<18 ? fTRDnSlices/kTRDnPlanes : idx/kTRDnPlanes;
2249 //____________________________________________________
2250 Double_t AliESDtrack::GetTRDmomentum(Int_t plane, Double_t *sp) const
2252 //Returns momentum estimation and optional its error (sp)
2253 // in TRD layer "plane".
2256 AliDebug(2, "No TRD info allocated for this track.");
2259 if ((plane<0) || (plane>=kTRDnPlanes)) {
2260 AliWarning(Form("Request for TRD plane[%d] outside range.", plane));
2264 Int_t idx = fTRDnSlices-(kTRDnPlanes<<1)+plane;
2265 // Protection for backward compatibility
2266 if(idx<(GetNumberOfTRDslices()*kTRDnPlanes)) return -1.;
2268 if(sp) (*sp) = fTRDslices[idx+kTRDnPlanes];
2269 return fTRDslices[idx];
2272 //____________________________________________________
2273 Double_t AliESDtrack::GetTRDslice(Int_t plane, Int_t slice) const {
2274 //Gets the charge from the slice of the plane
2277 //AliError("No TRD slices allocated for this track !");
2280 if ((plane<0) || (plane>=kTRDnPlanes)) {
2281 AliError("Info for TRD plane not available !");
2284 Int_t ns=GetNumberOfTRDslices();
2285 if ((slice<-1) || (slice>=ns)) {
2286 //AliError("Wrong TRD slice !");
2290 if(slice>=0) return fTRDslices[plane*ns + slice];
2292 // return average of the dEdx measurements
2293 Double_t q=0.; Double32_t *s = &fTRDslices[plane*ns];
2294 for (Int_t i=0; i<ns; i++, s++) if((*s)>0.) q+=(*s);
2298 //____________________________________________________
2299 void AliESDtrack::SetNumberOfTRDslices(Int_t n) {
2300 //Sets the number of slices used for PID
2301 if (fTRDnSlices) return;
2304 fTRDslices=new Double32_t[fTRDnSlices];
2306 // set-up correctly the allocated memory
2307 memset(fTRDslices, 0, n*sizeof(Double32_t));
2308 for (Int_t i=GetNumberOfTRDslices(); i--;) fTRDslices[i]=-1.;
2311 //____________________________________________________
2312 void AliESDtrack::SetTRDslice(Double_t q, Int_t plane, Int_t slice) {
2313 //Sets the charge q in the slice of the plane
2315 AliError("No TRD slices allocated for this track !");
2318 if ((plane<0) || (plane>=kTRDnPlanes)) {
2319 AliError("Info for TRD plane not allocated !");
2322 Int_t ns=GetNumberOfTRDslices();
2323 if ((slice<0) || (slice>=ns)) {
2324 AliError(Form("Wrong TRD slice %d/%d, NSlices=%d",plane,slice,ns));
2327 Int_t n=plane*ns + slice;
2332 //____________________________________________________
2333 void AliESDtrack::SetTRDmomentum(Double_t p, Int_t plane, Double_t *sp)
2336 AliError("No TRD slices allocated for this track !");
2339 if ((plane<0) || (plane>=kTRDnPlanes)) {
2340 AliError("Info for TRD plane not allocated !");
2344 Int_t idx = fTRDnSlices-(kTRDnPlanes<<1)+plane;
2345 // Protection for backward compatibility
2346 if(idx<GetNumberOfTRDslices()*kTRDnPlanes) return;
2348 if(sp) fTRDslices[idx+kTRDnPlanes] = (*sp);
2349 fTRDslices[idx] = p;
2353 //_______________________________________________________________________
2354 void AliESDtrack::SetTOFpid(const Double_t *p) {
2355 // Sets the probability of each particle type (in TOF)
2356 if (!fTOFr) fTOFr = new Double32_t[AliPID::kSPECIES];
2357 SetPIDValues(fTOFr,p,AliPID::kSPECIES);
2358 SetStatus(AliESDtrack::kTOFpid);
2361 //_______________________________________________________________________
2362 void AliESDtrack::SetTOFLabel(const Int_t *p) {
2364 if(fNtofClusters>0){
2365 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
2366 AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
2367 AliESDTOFHit* hit = tofcl->GetTOFHit(0);
2369 if(hit) hit->SetTOFLabel(p);
2373 if(!fTOFLabel) fTOFLabel = new Int_t[3];
2374 for (Int_t i=0; i<3; i++) fTOFLabel[i]=p[i];
2378 //_______________________________________________________________________
2379 void AliESDtrack::GetTOFpid(Double_t *p) const {
2380 // Gets probabilities of each particle type (in TOF)
2381 for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i] = fTOFr ? fTOFr[i]:0;
2384 //_______________________________________________________________________
2385 void AliESDtrack::GetTOFLabel(Int_t *p) const {
2387 if(fNtofClusters>0){
2388 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
2389 AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
2391 for (Int_t i=0; i<3; i++) p[i]=tofcl->GetLabel(i);
2394 if(fTOFLabel) for (Int_t i=0; i<3; i++) p[i]=fTOFLabel[i];
2395 else for (int i=3;i--;) p[i] = -1;
2399 //_______________________________________________________________________
2400 void AliESDtrack::GetTOFInfo(Float_t *info) const {
2402 for (Int_t i=0; i<10; i++) info[i]=fTOFInfo[i];
2405 //_______________________________________________________________________
2406 void AliESDtrack::SetTOFInfo(Float_t*info) {
2408 for (Int_t i=0; i<10; i++) fTOFInfo[i]=info[i];
2413 //_______________________________________________________________________
2414 void AliESDtrack::SetHMPIDpid(const Double_t *p) {
2415 // Sets the probability of each particle type (in HMPID)
2416 if (!fHMPIDr) fHMPIDr = new Double32_t[AliPID::kSPECIES];
2417 SetPIDValues(fHMPIDr,p,AliPID::kSPECIES);
2418 SetStatus(AliESDtrack::kHMPIDpid);
2421 //_______________________________________________________________________
2422 void AliESDtrack::SetTPCdEdxInfo(AliTPCdEdxInfo * dEdxInfo){
2423 if(fTPCdEdxInfo) delete fTPCdEdxInfo;
2424 fTPCdEdxInfo = dEdxInfo;
2427 //_______________________________________________________________________
2428 void AliESDtrack::GetHMPIDpid(Double_t *p) const {
2429 // Gets probabilities of each particle type (in HMPID)
2430 for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i] = fHMPIDr ? fHMPIDr[i]:0;
2435 //_______________________________________________________________________
2436 void AliESDtrack::SetESDpid(const Double_t *p) {
2437 // Sets the probability of each particle type for the ESD track
2438 if (!fR) fR = new Double32_t[AliPID::kSPECIES];
2439 SetPIDValues(fR,p,AliPID::kSPECIES);
2440 SetStatus(AliESDtrack::kESDpid);
2443 //_______________________________________________________________________
2444 void AliESDtrack::GetESDpid(Double_t *p) const {
2445 // Gets probability of each particle type for the ESD track
2446 for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i] = fR ? fR[i]:0;
2449 //_______________________________________________________________________
2450 Bool_t AliESDtrack::RelateToVertexTPC(const AliESDVertex *vtx,
2451 Double_t b, Double_t maxd, AliExternalTrackParam *cParam) {
2453 // Try to relate the TPC-only track parameters to the vertex "vtx",
2454 // if the (rough) transverse impact parameter is not bigger then "maxd".
2455 // Magnetic field is "b" (kG).
2457 // a) The TPC-only paramters are extapolated to the DCA to the vertex.
2458 // b) The impact parameters and their covariance matrix are calculated.
2459 // c) An attempt to constrain the TPC-only params to the vertex is done.
2460 // The constrained params are returned via "cParam".
2462 // In the case of success, the returned value is kTRUE
2463 // otherwise, it's kFALSE)
2466 if (!fTPCInner) return kFALSE;
2467 if (!vtx) return kFALSE;
2469 Double_t dz[2],cov[3];
2470 if (!fTPCInner->PropagateToDCA(vtx, b, maxd, dz, cov)) return kFALSE;
2478 Double_t covar[6]; vtx->GetCovMatrix(covar);
2479 Double_t p[2]={GetParameter()[0]-dz[0],GetParameter()[1]-dz[1]};
2480 Double_t c[3]={covar[2],0.,covar[5]};
2482 Double_t chi2=GetPredictedChi2(p,c);
2483 if (chi2>kVeryBig) return kFALSE;
2487 if (!cParam) return kTRUE;
2489 *cParam = *fTPCInner;
2490 if (!cParam->Update(p,c)) return kFALSE;
2495 //_______________________________________________________________________
2496 Bool_t AliESDtrack::RelateToVertexTPCBxByBz(const AliESDVertex *vtx,
2497 Double_t b[3], Double_t maxd, AliExternalTrackParam *cParam) {
2499 // Try to relate the TPC-only track parameters to the vertex "vtx",
2500 // if the (rough) transverse impact parameter is not bigger then "maxd".
2502 // All three components of the magnetic field ,"b[3]" (kG),
2503 // are taken into account.
2505 // a) The TPC-only paramters are extapolated to the DCA to the vertex.
2506 // b) The impact parameters and their covariance matrix are calculated.
2507 // c) An attempt to constrain the TPC-only params to the vertex is done.
2508 // The constrained params are returned via "cParam".
2510 // In the case of success, the returned value is kTRUE
2511 // otherwise, it's kFALSE)
2514 if (!fTPCInner) return kFALSE;
2515 if (!vtx) return kFALSE;
2517 Double_t dz[2],cov[3];
2518 if (!fTPCInner->PropagateToDCABxByBz(vtx, b, maxd, dz, cov)) return kFALSE;
2526 Double_t covar[6]; vtx->GetCovMatrix(covar);
2527 Double_t p[2]={GetParameter()[0]-dz[0],GetParameter()[1]-dz[1]};
2528 Double_t c[3]={covar[2],0.,covar[5]};
2530 Double_t chi2=GetPredictedChi2(p,c);
2531 if (chi2>kVeryBig) return kFALSE;
2535 if (!cParam) return kTRUE;
2537 *cParam = *fTPCInner;
2538 if (!cParam->Update(p,c)) return kFALSE;
2543 //_______________________________________________________________________
2544 Bool_t AliESDtrack::RelateToVertex(const AliESDVertex *vtx,
2545 Double_t b, Double_t maxd, AliExternalTrackParam *cParam) {
2547 // Try to relate this track to the vertex "vtx",
2548 // if the (rough) transverse impact parameter is not bigger then "maxd".
2549 // Magnetic field is "b" (kG).
2551 // a) The track gets extapolated to the DCA to the vertex.
2552 // b) The impact parameters and their covariance matrix are calculated.
2553 // c) An attempt to constrain this track to the vertex is done.
2554 // The constrained params are returned via "cParam".
2556 // In the case of success, the returned value is kTRUE
2557 // (otherwise, it's kFALSE)
2560 if (!vtx) return kFALSE;
2562 Double_t dz[2],cov[3];
2563 if (!PropagateToDCA(vtx, b, maxd, dz, cov)) return kFALSE;
2571 Double_t covar[6]; vtx->GetCovMatrix(covar);
2572 Double_t p[2]={GetParameter()[0]-dz[0],GetParameter()[1]-dz[1]};
2573 Double_t c[3]={covar[2],0.,covar[5]};
2575 Double_t chi2=GetPredictedChi2(p,c);
2576 if (chi2>kVeryBig) return kFALSE;
2581 //--- Could now these lines be removed ? ---
2583 fCp=new AliExternalTrackParam(*this);
2585 if (!fCp->Update(p,c)) {delete fCp; fCp=0; return kFALSE;}
2586 //----------------------------------------
2588 fVertexID = vtx->GetID();
2590 if (!cParam) return kTRUE;
2593 if (!cParam->Update(p,c)) return kFALSE;
2598 //_______________________________________________________________________
2599 Bool_t AliESDtrack::RelateToVertexBxByBz(const AliESDVertex *vtx,
2600 Double_t b[3], Double_t maxd, AliExternalTrackParam *cParam) {
2602 // Try to relate this track to the vertex "vtx",
2603 // if the (rough) transverse impact parameter is not bigger then "maxd".
2604 // Magnetic field is "b" (kG).
2606 // a) The track gets extapolated to the DCA to the vertex.
2607 // b) The impact parameters and their covariance matrix are calculated.
2608 // c) An attempt to constrain this track to the vertex is done.
2609 // The constrained params are returned via "cParam".
2611 // In the case of success, the returned value is kTRUE
2612 // (otherwise, it's kFALSE)
2615 if (!vtx) return kFALSE;
2617 Double_t dz[2],cov[3];
2618 if (!PropagateToDCABxByBz(vtx, b, maxd, dz, cov)) return kFALSE;
2626 Double_t covar[6]; vtx->GetCovMatrix(covar);
2627 Double_t p[2]={GetParameter()[0]-dz[0],GetParameter()[1]-dz[1]};
2628 Double_t c[3]={covar[2],0.,covar[5]};
2630 Double_t chi2=GetPredictedChi2(p,c);
2631 if (chi2>kVeryBig) return kFALSE;
2636 //--- Could now these lines be removed ? ---
2638 fCp=new AliExternalTrackParam(*this);
2640 if (!fCp->Update(p,c)) {delete fCp; fCp=0; return kFALSE;}
2641 //----------------------------------------
2643 fVertexID = vtx->GetID();
2645 if (!cParam) return kTRUE;
2648 if (!cParam->Update(p,c)) return kFALSE;
2653 //_______________________________________________________________________
2654 void AliESDtrack::Print(Option_t *) const {
2655 // Prints info on the track
2656 AliExternalTrackParam::Print();
2657 printf("ESD track info\n") ;
2658 Double_t p[AliPID::kSPECIES] ;
2660 if( IsOn(kITSpid) ){
2661 printf("From ITS: ") ;
2663 for(index = 0 ; index < AliPID::kSPECIES; index++)
2664 printf("%f, ", p[index]) ;
2665 printf("\n signal = %f\n", GetITSsignal()) ;
2667 if( IsOn(kTPCpid) ){
2668 printf("From TPC: ") ;
2670 for(index = 0 ; index < AliPID::kSPECIES; index++)
2671 printf("%f, ", p[index]) ;
2672 printf("\n signal = %f\n", GetTPCsignal()) ;
2674 if( IsOn(kTRDpid) ){
2675 printf("From TRD: ") ;
2677 for(index = 0 ; index < AliPID::kSPECIES; index++)
2678 printf("%f, ", p[index]) ;
2679 printf("\n signal = %f\n", GetTRDsignal()) ;
2680 printf("\n NchamberdEdx = %d\n", GetTRDNchamberdEdx()) ;
2681 printf("\n NclusterdEdx = %d\n", GetTRDNclusterdEdx()) ;
2683 if( IsOn(kTOFpid) ){
2684 printf("From TOF: ") ;
2686 for(index = 0 ; index < AliPID::kSPECIES; index++)
2687 printf("%f, ", p[index]) ;
2688 printf("\n signal = %f\n", GetTOFsignal()) ;
2690 if( IsOn(kHMPIDpid) ){
2691 printf("From HMPID: ") ;
2693 for(index = 0 ; index < AliPID::kSPECIES; index++)
2694 printf("%f, ", p[index]) ;
2695 printf("\n signal = %f\n", GetHMPIDsignal()) ;
2701 // Draw functionality
2702 // Origin: Marian Ivanov, Marian.Ivanov@cern.ch
2704 void AliESDtrack::FillPolymarker(TPolyMarker3D *pol, Float_t magF, Float_t minR, Float_t maxR, Float_t stepR){
2706 // Fill points in the polymarker
2709 arrayRef.AddLast(new AliExternalTrackParam(*this));
2710 if (fIp) arrayRef.AddLast(new AliExternalTrackParam(*fIp));
2711 if (fOp) arrayRef.AddLast(new AliExternalTrackParam(*fOp));
2712 if (fHMPIDp) arrayRef.AddLast(new AliExternalTrackParam(*fHMPIDp));
2714 Double_t mpos[3]={0,0,0};
2715 Int_t entries=arrayRef.GetEntries();
2716 for (Int_t i=0;i<entries;i++){
2718 ((AliExternalTrackParam*)arrayRef.At(i))->GetXYZ(pos);
2719 mpos[0]+=pos[0]/entries;
2720 mpos[1]+=pos[1]/entries;
2721 mpos[2]+=pos[2]/entries;
2723 // Rotate to the mean position
2725 Float_t fi= TMath::ATan2(mpos[1],mpos[0]);
2726 for (Int_t i=0;i<entries;i++){
2727 Bool_t res = ((AliExternalTrackParam*)arrayRef.At(i))->Rotate(fi);
2728 if (!res) delete arrayRef.RemoveAt(i);
2731 for (Double_t r=minR; r<maxR; r+=stepR){
2733 Double_t mlpos[3]={0,0,0};
2734 for (Int_t i=0;i<entries;i++){
2735 Double_t point[3]={0,0,0};
2736 AliExternalTrackParam *param = ((AliExternalTrackParam*)arrayRef.At(i));
2737 if (!param) continue;
2738 if (param->GetXYZAt(r,magF,point)){
2739 Double_t weight = 1./(10.+(r-param->GetX())*(r-param->GetX()));
2741 mlpos[0]+=point[0]*weight;
2742 mlpos[1]+=point[1]*weight;
2743 mlpos[2]+=point[2]*weight;
2750 pol->SetPoint(counter,mlpos[0],mlpos[1], mlpos[2]);
2751 // printf("xyz\t%f\t%f\t%f\n",mlpos[0], mlpos[1],mlpos[2]);
2757 //_______________________________________________________________________
2758 void AliESDtrack::SetITSdEdxSamples(const Double_t s[4]) {
2760 // Store the dE/dx samples measured by the two SSD and two SDD layers.
2761 // These samples are corrected for the track segment length.
2763 for (Int_t i=0; i<4; i++) fITSdEdxSamples[i]=s[i];
2766 //_______________________________________________________________________
2767 void AliESDtrack::GetITSdEdxSamples(Double_t s[4]) const {
2769 // Get the dE/dx samples measured by the two SSD and two SDD layers.
2770 // These samples are corrected for the track segment length.
2772 for (Int_t i=0; i<4; i++) s[i]=fITSdEdxSamples[i];
2776 UShort_t AliESDtrack::GetTPCnclsS(Int_t i0,Int_t i1) const{
2778 // get number of shared TPC clusters
2780 return fTPCSharedMap.CountBits(i0)-fTPCSharedMap.CountBits(i1);
2783 UShort_t AliESDtrack::GetTPCncls(Int_t i0,Int_t i1) const{
2785 // get number of TPC clusters
2787 return fTPCClusterMap.CountBits(i0)-fTPCClusterMap.CountBits(i1);
2790 //____________________________________________________________________
2791 Double_t AliESDtrack::GetChi2TPCConstrainedVsGlobal(const AliESDVertex* vtx) const
2793 // Calculates the chi2 between the TPC track (TPCinner) constrained to the primary vertex and the global track
2795 // Returns -1 in case the calculation failed
2797 // Value is cached as a non-persistent member.
2799 // Code adapted from original code by GSI group (Jacek, Marian, Michael)
2801 // cache, ignoring that a different vertex might be passed
2802 if (fCacheChi2TPCConstrainedVsGlobalVertex == vtx)
2803 return fCacheChi2TPCConstrainedVsGlobal;
2805 fCacheChi2TPCConstrainedVsGlobal = -1;
2806 fCacheChi2TPCConstrainedVsGlobalVertex = vtx;
2811 AliTrackerBase::GetBxByBz(x,b);
2814 AliWarning("Could not get TPC Inner Param.");
2815 return fCacheChi2TPCConstrainedVsGlobal;
2818 // clone for constraining
2819 AliExternalTrackParam* tpcInnerC = new AliExternalTrackParam(*fTPCInner);
2821 AliWarning("Clone of TPCInnerParam failed.");
2822 return fCacheChi2TPCConstrainedVsGlobal;
2825 // transform to the track reference frame
2826 Bool_t isOK = tpcInnerC->Rotate(GetAlpha());
2827 isOK &= tpcInnerC->PropagateTo(GetX(), b[2]);
2831 AliWarning("Rotation/Propagation of track failed.") ;
2832 return fCacheChi2TPCConstrainedVsGlobal;
2835 // constrain TPCinner
2836 isOK = tpcInnerC->ConstrainToVertex(vtx, b);
2838 // transform to the track reference frame
2839 isOK &= tpcInnerC->Rotate(GetAlpha());
2840 isOK &= tpcInnerC->PropagateTo(GetX(), b[2]);
2843 AliWarning("ConstrainTPCInner failed.") ;
2846 return fCacheChi2TPCConstrainedVsGlobal;
2849 // calculate chi2 between vi and vj vectors
2850 // with covi and covj covariance matrices
2851 // chi2ij = (vi-vj)^(T)*(covi+covj)^(-1)*(vi-vj)
2852 TMatrixD deltaT(5,1);
2853 TMatrixD delta(1,5);
2854 TMatrixD covarM(5,5);
2856 for (Int_t ipar=0; ipar<5; ipar++) {
2857 deltaT(ipar,0) = tpcInnerC->GetParameter()[ipar] - GetParameter()[ipar];
2858 delta(0,ipar) = tpcInnerC->GetParameter()[ipar] - GetParameter()[ipar];
2860 for (Int_t jpar=0; jpar<5; jpar++) {
2861 Int_t index = GetIndex(ipar,jpar);
2862 covarM(ipar,jpar) = GetCovariance()[index]+tpcInnerC->GetCovariance()[index];
2865 // chi2 distance TPC constrained and TPC+ITS
2866 TMatrixD covarMInv = covarM.Invert();
2867 TMatrixD mat2 = covarMInv*deltaT;
2868 TMatrixD chi2 = delta*mat2;
2873 fCacheChi2TPCConstrainedVsGlobal = chi2(0,0);
2874 return fCacheChi2TPCConstrainedVsGlobal;
2877 void AliESDtrack::SetDetectorPID(const AliDetectorPID *pid)
2880 // Set the detector PID
2882 if (fDetectorPID) delete fDetectorPID;
2887 Double_t AliESDtrack::GetLengthInActiveZone( Int_t mode, Double_t deltaY, Double_t deltaZ, Double_t bz, Double_t exbPhi , TTreeSRedirector * pcstream) const {
2889 // Input parameters:
2890 // mode - type of external track parameters
2891 // deltaY - user defined "dead region" in cm
2892 // deltaZ - user defined "active region" in cm (250 cm drift lenght - 14 cm L1 delay
2893 // bz - magnetic field
2894 // exbPhi - optional rotation due to the ExB effect
2896 // the length of the track in cm in "active volume" of the TPC
2898 if (mode==0) return GetLengthInActiveZone(this, deltaY,deltaZ,bz, exbPhi,pcstream);
2899 if (mode==1) return GetLengthInActiveZone(fIp, deltaY,deltaZ,bz, exbPhi,pcstream);
2900 if (mode==2) return GetLengthInActiveZone(fOp, deltaY,deltaZ,bz, exbPhi,pcstream);
2904 Double_t AliESDtrack::GetLengthInActiveZone(const AliExternalTrackParam *paramT, Double_t deltaY, Double_t deltaZ, Double_t bz, Double_t exbPhi , TTreeSRedirector * pcstream) {
2906 // Numerical code to calculate the length of the track in active region of the TPC
2907 // ( can be speed up if somebody wants to invest time - analysical version shoult be possible)
2909 // Input parameters:
2910 // paramT - external track parameters
2911 // deltaY - user defined "dead region" in cm
2912 // deltaZ - user defined "active region" in cm (250 cm drift lenght - 14 cm L1 delay
2913 // bz - magnetic field
2914 // exbPhi - optional rotation due to the ExB effect
2916 // the length of the track in cm in "active volume" of the TPC
2918 const Double_t rIn=85;
2919 const Double_t rOut=245;
2920 Double_t xyz[3], pxyz[3];
2921 if (paramT->GetXYZAt(rIn,bz,xyz)){
2922 paramT->GetPxPyPzAt(rIn,bz,pxyz);
2924 paramT->GetXYZ(xyz);
2925 paramT->GetPxPyPz(pxyz);
2928 Double_t dca = -paramT->GetD(0,0,bz); // get impact parameter distance to point (0,0)
2929 Double_t radius= TMath::Abs(1/paramT->GetC(bz)); //
2930 Double_t sign = paramT->GetSign();
2931 Double_t R0 = TMath::Sqrt(xyz[0]*xyz[0]+xyz[1]*xyz[1]); // radius at current point
2932 Double_t phiR0 = TMath::ATan2(xyz[1],xyz[0]); // angle of given point
2933 Double_t dPhiR0= -TMath::ASin((dca*dca-2*dca*radius*sign+R0*R0)/(2*R0*(dca-radius*sign)));
2934 Double_t phi0 = phiR0-(dPhiR0); // global phi offset to be added
2937 AliExternalTrackParam paramR=(*paramT);
2939 for (Double_t R=rIn; R<=rOut; R++){
2940 Double_t sinPhi=(dca*dca-2*dca*radius*sign+R*R)/(2*R*(dca-radius*sign));
2941 if (TMath::Abs(sinPhi)>=1) continue;
2942 Double_t dphi = -TMath::ASin(sinPhi);
2943 Double_t phi = phi0+dphi; // global phi
2944 Int_t sector = TMath::Nint(9*phi/(TMath::Pi()));
2945 Double_t dPhiEdge = phi-(sector*TMath::Pi()/9)+exbPhi; // distance to sector boundary in rphi
2946 Double_t dX = R*TMath::Cos(phi)-xyz[0];
2947 Double_t dY = R*TMath::Sin(phi)-xyz[1];
2948 Double_t deltaPhi = 2*TMath::ASin(0.5*TMath::Sqrt(dX*dX+dY*dY)/radius);
2949 Double_t z = xyz[2]+deltaPhi*radius*paramT->GetTgl();
2950 if (TMath::Abs(dPhiEdge*R)>deltaY && TMath::Abs(z)<deltaZ){
2953 // Double_t deltaZ= dphi*radius;
2955 //should we keep debug possibility ?
2956 AliExternalTrackParam paramTcopy=(*paramT);
2958 paramR.PropagateTo(R,bz);
2959 (*pcstream)<<"debugEdge"<<
2961 "dphiEdge="<<dPhiEdge<< // distance to edge
2962 "phi0="<<phi0<< // phi0 -phi at the track initial position
2965 "pT.="<<¶mTcopy<<
2973 Double_t AliESDtrack::GetMassForTracking() const
2975 int pid = fPIDForTracking;
2976 if (pid<AliPID::kPion) pid = AliPID::kPion;
2977 double m = AliPID::ParticleMass(pid);
2978 return (fPIDForTracking==AliPID::kHe3 || fPIDForTracking==AliPID::kAlpha) ? -m : m;
2982 void AliESDtrack::SetTOFclusterArray(Int_t /*ncluster*/,Int_t */*TOFcluster*/){
2983 AliInfo("Method has to be implemented!");
2984 // fNtofClusters=ncluster;
2985 // if(TOFcluster == fTOFcluster) return;
2986 // if(fTOFcluster){ // reset previous content
2987 // delete[] fTOFcluster;
2988 // fTOFcluster = NULL;
2992 // if(ncluster){ // set new content
2993 // fTOFcluster = new Int_t[fNtofClusters];
2994 // for(Int_t i=0;i < fNtofClusters;i++) fTOFcluster[i] = TOFcluster[i];
3000 //____________________________________________
3001 void AliESDtrack::SuppressTOFMatches()
3003 // remove reference to this track from TOF clusters
3004 if (!fNtofClusters || !GetESDEvent()) return;
3005 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3006 for (;fNtofClusters--;) {
3007 AliESDTOFCluster* clTOF = (AliESDTOFCluster*)tofclArray->At(fTOFcluster[fNtofClusters]);
3008 clTOF->SuppressMatchedTrack(GetID());
3009 if (!clTOF->GetNMatchableTracks()) { // remove this cluster
3010 int last = tofclArray->GetEntriesFast()-1;
3011 AliESDTOFCluster* clTOFL = (AliESDTOFCluster*)tofclArray->At(last);
3012 if (last != fTOFcluster[fNtofClusters]) {
3013 *clTOF = *clTOFL; // move last cluster to the place of eliminated one
3014 // fix the references on this cluster
3015 clTOF->FixSelfReferences(last,fTOFcluster[fNtofClusters]);
3017 tofclArray->RemoveAt(last);
3022 //____________________________________________
3023 void AliESDtrack::ReplaceTOFTrackID(int oldID, int newID)
3025 // replace the ID in TOF clusters references to this track
3026 if (!fNtofClusters || !GetESDEvent()) return;
3027 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3028 for (int it=fNtofClusters;it--;) {
3029 AliESDTOFCluster* clTOF = (AliESDTOFCluster*)tofclArray->At(fTOFcluster[it]);
3030 clTOF->ReplaceMatchedTrackID(oldID,newID);
3034 //____________________________________________
3035 void AliESDtrack::ReplaceTOFClusterID(int oldID, int newID)
3037 // replace the referenc on TOF cluster oldID by newID
3038 if (!fNtofClusters || !GetESDEvent()) return;
3039 for (int it=fNtofClusters;it--;) {
3040 if (fTOFcluster[it] == oldID) {
3041 fTOFcluster[it] = newID;
3047 //____________________________________________
3048 void AliESDtrack::ReplaceTOFMatchID(int oldID, int newID)
3050 // replace in the ESDTOFCluster associated with this track the id of the corresponding
3051 // ESDTOFMatch from oldID to newID
3052 if (!fNtofClusters || !GetESDEvent()) return;
3053 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3054 for (int it=fNtofClusters;it--;) {
3055 AliESDTOFCluster* clTOF = (AliESDTOFCluster*)tofclArray->At(fTOFcluster[it]);
3056 clTOF->ReplaceMatchID(oldID,newID);
3060 //____________________________________________
3061 void AliESDtrack::AddTOFcluster(Int_t icl)
3065 Int_t *old = fTOFcluster;
3066 fTOFcluster = new Int_t[fNtofClusters];
3068 for(Int_t i=0;i < fNtofClusters-1;i++) fTOFcluster[i] = old[i];
3069 fTOFcluster[fNtofClusters-1] = icl;
3071 if(fNtofClusters-1) delete[] old; // delete previous content
3075 //____________________________________________
3076 void AliESDtrack::SetTOFsignal(Double_t tof)
3078 if(fNtofClusters>0 && GetESDEvent()){
3079 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3080 AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3081 AliESDTOFHit* hit = tofcl->GetTOFHit(0);
3082 if(hit) hit->SetTime(tof);
3085 if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3089 //____________________________________________
3090 void AliESDtrack::SetTOFCalChannel(Int_t index){
3091 if(fNtofClusters>0 && GetESDEvent()){
3092 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3093 AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3094 AliESDTOFHit* hit = tofcl->GetTOFHit(0);
3095 if(hit) hit->SetTOFchannel(index);
3098 if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3099 fTOFCalChannel=index;
3102 //____________________________________________
3103 void AliESDtrack::SetTOFsignalToT(Double_t ToT){
3104 if(fNtofClusters>0 && GetESDEvent()){
3105 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3106 AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3107 AliESDTOFHit* hit = tofcl->GetTOFHit(0);
3108 if(hit) hit->SetTOT(ToT);
3111 if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3115 //____________________________________________
3116 void AliESDtrack::SetTOFsignalRaw(Double_t tof){
3117 if(fNtofClusters>0 && GetESDEvent()){
3118 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3119 AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3120 AliESDTOFHit* hit = tofcl->GetTOFHit(0);
3121 if(hit) hit->SetTimeRaw(tof);
3124 if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3128 //____________________________________________
3129 void AliESDtrack::SetTOFsignalDz(Double_t dz){
3131 AliESDTOFCluster *tofcl;
3133 if(fNtofClusters>0 && GetESDEvent()){
3134 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3135 tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3137 for(Int_t i=0;i < tofcl->GetNMatchableTracks();i++){
3138 if(tofcl->GetTrackIndex(i) == GetID()) index = i;
3143 AliESDTOFMatch* match = tofcl->GetTOFMatch(index);
3149 if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3155 //____________________________________________
3156 void AliESDtrack::SetTOFsignalDx(Double_t dx){
3158 AliESDTOFCluster *tofcl;
3160 if(fNtofClusters>0 && GetESDEvent()){
3161 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3162 tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3164 for(Int_t i=0;i < tofcl->GetNMatchableTracks();i++){
3165 if(tofcl->GetTrackIndex(i) == GetID()) index = i;
3170 AliESDTOFMatch* match = tofcl->GetTOFMatch(index);
3176 if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3180 //____________________________________________
3181 void AliESDtrack::SetTOFDeltaBC(Short_t deltaBC){
3182 if(fNtofClusters>0 && GetESDEvent()){
3183 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3184 AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3185 AliESDTOFHit* hit = tofcl->GetTOFHit(0);
3186 if(hit) hit->SetDeltaBC(deltaBC);
3189 if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3190 fTOFdeltaBC=deltaBC;
3193 //____________________________________________
3194 void AliESDtrack::SetTOFL0L1(Short_t l0l1){
3195 if(fNtofClusters>0 && GetESDEvent()){
3196 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3197 AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3198 AliESDTOFHit* hit = tofcl->GetTOFHit(0);
3199 if(hit) hit->SetL0L1Latency(l0l1);
3202 if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3206 //____________________________________________
3207 Double_t AliESDtrack::GetTOFsignal() const
3209 if(fNtofClusters>0 && GetESDEvent()){
3210 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3211 AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3213 return tofcl->GetTime();
3215 else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3220 //____________________________________________
3221 Double_t AliESDtrack::GetTOFsignalToT() const
3223 if(fNtofClusters>0 && GetESDEvent()){
3224 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3225 AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3227 return tofcl->GetTOT();
3229 else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3231 return fTOFsignalToT;
3234 //____________________________________________
3235 Double_t AliESDtrack::GetTOFsignalRaw() const
3237 if(fNtofClusters>0 && GetESDEvent()){
3238 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3239 AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3241 return tofcl->GetTimeRaw();
3243 else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3245 return fTOFsignalRaw;
3248 //____________________________________________
3249 Double_t AliESDtrack::GetTOFsignalDz() const
3252 AliESDTOFCluster *tofcl;
3255 if(fNtofClusters>0 && GetESDEvent()){
3256 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3257 tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3259 for(Int_t i=0;i < tofcl->GetNMatchableTracks();i++){
3260 if(tofcl->GetTrackIndex(i) == GetID()) index = i;
3263 else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3265 if(fNtofClusters>0 && index > -1){
3266 return tofcl->GetDz(index);
3268 return fTOFsignalDz;
3271 //____________________________________________
3272 Double_t AliESDtrack::GetTOFsignalDx() const
3274 AliESDTOFCluster *tofcl;
3277 if(fNtofClusters>0 && GetESDEvent()){
3278 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3279 tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3280 for(Int_t i=0;i < tofcl->GetNMatchableTracks();i++){
3281 if(tofcl->GetTrackIndex(i) == GetID()) index = i;
3284 else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3285 if(fNtofClusters>0 && index > -1){
3286 return tofcl->GetDx(index);
3288 return fTOFsignalDx;
3291 //____________________________________________
3292 Short_t AliESDtrack::GetTOFDeltaBC() const
3294 if(fNtofClusters>0 && GetESDEvent()){
3295 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3296 AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3297 return tofcl->GetDeltaBC();
3299 else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3304 //____________________________________________
3305 Short_t AliESDtrack::GetTOFL0L1() const
3307 if(fNtofClusters>0 && GetESDEvent()){
3308 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3309 AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3311 return tofcl->GetL0L1Latency();
3313 else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3318 //____________________________________________
3319 Int_t AliESDtrack::GetTOFCalChannel() const
3321 if(fNtofClusters>0 && GetESDEvent()){
3322 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3323 AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3325 return tofcl->GetTOFchannel();
3327 else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3329 return fTOFCalChannel;
3332 //____________________________________________
3333 Int_t AliESDtrack::GetTOFcluster() const
3335 if(fNtofClusters>0 && GetESDEvent()){
3336 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3337 AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3339 return tofcl->GetClusterIndex();
3341 else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3346 //____________________________________________
3347 Int_t AliESDtrack::GetTOFclusterN() const
3349 return fNtofClusters;
3352 //____________________________________________
3353 Bool_t AliESDtrack::IsTOFHitAlreadyMatched() const{
3354 if(fNtofClusters>0 && GetESDEvent()){
3355 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3356 AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
3358 if (tofcl->GetNMatchableTracks() > 1)
3361 else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
3366 //____________________________________________
3367 void AliESDtrack::ReMapTOFcluster(Int_t ncl,Int_t *mapping){
3368 for(Int_t i=0;i<fNtofClusters;i++){
3369 if(fTOFcluster[i]<ncl && fTOFcluster[i]>-1)
3370 fTOFcluster[i] = mapping[fTOFcluster[i]];
3372 AliInfo(Form("TOF cluster re-mapping in AliESDtrack: out of range (%i > %i)\n",fTOFcluster[i],ncl));
3376 //____________________________________________
3377 void AliESDtrack::SortTOFcluster(){
3378 TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
3380 for(Int_t i=0;i<fNtofClusters-1;i++){
3381 for(Int_t j=i+1;j<fNtofClusters;j++){
3382 AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[i]);
3384 for(Int_t it=0;it < tofcl->GetNMatchableTracks();it++){
3385 if(tofcl->GetTrackIndex(it) == GetID()) index1 = it;
3387 Double_t timedist1 = 10000;
3388 for(Int_t isp=0; isp< AliPID::kSPECIESC;isp++){
3389 Double_t timec = TMath::Abs(tofcl->GetTime() - tofcl->GetIntegratedTime(isp));
3390 if(timec < timedist1) timedist1 = timec;
3392 timedist1 *= 0.03; // in cm
3393 Double_t radius1 = tofcl->GetDx(index1)*tofcl->GetDx(index1) + tofcl->GetDz(index1)*tofcl->GetDz(index1) + timedist1*timedist1;
3395 AliESDTOFCluster *tofcl2 = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[j]);
3397 for(Int_t it=0;it < tofcl2->GetNMatchableTracks();it++){
3398 if(tofcl2->GetTrackIndex(it) == GetID()) index2 = it;
3400 if(index1 == -1 || index2 == -1){
3402 Double_t timedist2 = 10000;
3403 for(Int_t isp=0; isp< AliPID::kSPECIESC;isp++){
3404 Double_t timec = TMath::Abs(tofcl2->GetTime() - tofcl2->GetIntegratedTime(isp));
3405 if(timec < timedist2) timedist2 = timec;
3407 timedist2 *= 0.03; // in cm
3408 Double_t radius2 = tofcl2->GetDx(index2)*tofcl2->GetDx(index2) + tofcl2->GetDz(index2)*tofcl2->GetDz(index2) + timedist2*timedist2;
3410 if(radius2 < radius1){
3411 Int_t change = fTOFcluster[i];
3412 fTOFcluster[i] = fTOFcluster[j];
3413 fTOFcluster[j] = change;
3419 //____________________________________________
3420 const AliTOFHeader* AliESDtrack::GetTOFHeader() const {
3421 return fESDEvent->GetTOFHeader();
3424 //___________________________________________
3425 void AliESDtrack::SetID(Short_t id)
3427 // set track ID taking care about dependencies
3428 if (fNtofClusters) ReplaceTOFTrackID(fID,id);
3433 Double_t AliESDtrack::GetdEdxInfo(Int_t regionID, Int_t calibID, Int_t qID, Int_t valueID){
3435 // Interface to get the calibrated dEdx information
3436 // For details of arguments and return values see
3437 // AliTPCdEdxInfo::GetdEdxInfo(Int_t regionID, Int_t calibID, Int_t valueID)
3439 if (!fTPCdEdxInfo) return 0;
3441 return fTPCdEdxInfo->GetdEdxInfo(fIp, regionID, calibID, qID, valueID);