1 /**************************************************************************
2 * Copyright(c) 1998-2007, 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 **************************************************************************/
18 //-------------------------------------------------------------------------
19 // AOD track implementation of AliVTrack
20 // Author: Markus Oldenburg, CERN
21 // Markus.Oldenburg@cern.ch
22 //-------------------------------------------------------------------------
26 #include "AliExternalTrackParam.h"
27 #include "AliVVertex.h"
28 #include "AliDetectorPID.h"
29 #include "AliAODEvent.h"
30 #include "AliAODHMPIDrings.h"
31 #include "AliTOFHeader.h"
33 #include "AliAODTrack.h"
37 //______________________________________________________________________________
38 AliAODTrack::AliAODTrack() :
42 fChi2MatchTrigger(0.),
48 fITSMuonClusterMap(0),
49 fMUONtrigHitsMapTrg(0),
50 fMUONtrigHitsMapTrk(0),
60 fPIDForTracking(AliPID::kPion),
61 fCaloIndex(kEMCALNoMatch),
66 fTrackPhiOnEMCal(-999),
67 fTrackEtaOnEMCal(-999),
68 fTrackPtOnEMCal(-999),
69 fIsMuonGlobalTrack(kFALSE), // AU
71 fTOFsignalTuned(99999),
72 fMFTClusterPattern(0), // AU
75 // default constructor
78 SetPosition((Float_t*)NULL);
79 SetXYAtDCA(-999., -999.);
80 SetPxPyPzAtDCA(-999., -999., -999.);
81 for (Int_t i = 0; i < 3; i++) {fTOFLabel[i] = -1;}
84 //______________________________________________________________________________
85 AliAODTrack::AliAODTrack(Short_t id,
91 Double_t covMatrix[21],
94 AliAODVertex *prodVertex,
96 Bool_t usedForPrimVtxFit,
102 fChi2perNDF(chi2perNDF),
103 fChi2MatchTrigger(0.),
109 fITSMuonClusterMap(0),
110 fMUONtrigHitsMapTrg(0),
111 fMUONtrigHitsMapTrk(0),
112 fFilterMap(selectInfo),
121 fPIDForTracking(AliPID::kPion),
122 fCaloIndex(kEMCALNoMatch),
126 fProdVertex(prodVertex),
127 fTrackPhiOnEMCal(-999),
128 fTrackEtaOnEMCal(-999),
129 fTrackPtOnEMCal(-999),
130 fIsMuonGlobalTrack(kFALSE), // AU
132 fTOFsignalTuned(99999),
133 fMFTClusterPattern(0), // AU
139 SetPosition(x, isDCA);
140 SetXYAtDCA(-999., -999.);
141 SetPxPyPzAtDCA(-999., -999., -999.);
142 SetUsedForVtxFit(usedForVtxFit);
143 SetUsedForPrimVtxFit(usedForPrimVtxFit);
144 if(covMatrix) SetCovMatrix(covMatrix);
145 SetITSClusterMap(itsClusMap);
146 for (Int_t i=0;i<3;i++) {fTOFLabel[i]=-1;}
149 //______________________________________________________________________________
150 AliAODTrack::AliAODTrack(Short_t id,
156 Float_t covMatrix[21],
159 AliAODVertex *prodVertex,
160 Bool_t usedForVtxFit,
161 Bool_t usedForPrimVtxFit,
164 Float_t chi2perNDF ) :
167 fChi2perNDF(chi2perNDF),
168 fChi2MatchTrigger(0.),
174 fITSMuonClusterMap(0),
175 fMUONtrigHitsMapTrg(0),
176 fMUONtrigHitsMapTrk(0),
177 fFilterMap(selectInfo),
186 fPIDForTracking(AliPID::kPion),
187 fCaloIndex(kEMCALNoMatch),
191 fProdVertex(prodVertex),
192 fTrackPhiOnEMCal(-999),
193 fTrackEtaOnEMCal(-999),
194 fTrackPtOnEMCal(-999),
195 fIsMuonGlobalTrack(kFALSE), // AU
197 fTOFsignalTuned(99999),
198 fMFTClusterPattern(0), // AU
204 SetPosition(x, isDCA);
205 SetXYAtDCA(-999., -999.);
206 SetPxPyPzAtDCA(-999., -999., -999.);
207 SetUsedForVtxFit(usedForVtxFit);
208 SetUsedForPrimVtxFit(usedForPrimVtxFit);
209 if(covMatrix) SetCovMatrix(covMatrix);
210 SetITSClusterMap(itsClusMap);
211 for (Int_t i=0;i<3;i++) {fTOFLabel[i]=-1;}
214 //______________________________________________________________________________
215 AliAODTrack::~AliAODTrack()
225 //______________________________________________________________________________
226 AliAODTrack::AliAODTrack(const AliAODTrack& trk) :
228 fRAtAbsorberEnd(trk.fRAtAbsorberEnd),
229 fChi2perNDF(trk.fChi2perNDF),
230 fChi2MatchTrigger(trk.fChi2MatchTrigger),
235 fTrackLength(trk.fTrackLength),
236 fITSMuonClusterMap(trk.fITSMuonClusterMap),
237 fMUONtrigHitsMapTrg(trk.fMUONtrigHitsMapTrg),
238 fMUONtrigHitsMapTrk(trk.fMUONtrigHitsMapTrk),
239 fFilterMap(trk.fFilterMap),
240 fTPCFitMap(trk.fTPCFitMap),
241 fTPCClusterMap(trk.fTPCClusterMap),
242 fTPCSharedMap(trk.fTPCSharedMap),
243 fTPCnclsF(trk.fTPCnclsF),
244 fTPCNCrossedRows(trk.fTPCNCrossedRows),
246 fCharge(trk.fCharge),
248 fPIDForTracking(trk.fPIDForTracking),
249 fCaloIndex(trk.fCaloIndex),
253 fProdVertex(trk.fProdVertex),
254 fTrackPhiOnEMCal(trk.fTrackPhiOnEMCal),
255 fTrackEtaOnEMCal(trk.fTrackEtaOnEMCal),
256 fTrackPtOnEMCal(trk.fTrackPtOnEMCal),
257 fIsMuonGlobalTrack(trk.fIsMuonGlobalTrack), // AU
258 fTPCsignalTuned(trk.fTPCsignalTuned),
259 fTOFsignalTuned(trk.fTOFsignalTuned),
260 fMFTClusterPattern(trk.fMFTClusterPattern), // AU
261 fAODEvent(trk.fAODEvent)
266 trk.GetPosition(fPosition);
267 SetXYAtDCA(trk.XAtDCA(), trk.YAtDCA());
268 SetPxPyPzAtDCA(trk.PxAtDCA(), trk.PyAtDCA(), trk.PzAtDCA());
269 SetUsedForVtxFit(trk.GetUsedForVtxFit());
270 SetUsedForPrimVtxFit(trk.GetUsedForPrimVtxFit());
271 if(trk.fCovMatrix) fCovMatrix=new AliAODRedCov<6>(*trk.fCovMatrix);
272 if(trk.fDetPid) fDetPid=new AliAODPid(*trk.fDetPid);
274 if (trk.fDetectorPID) fDetectorPID = new AliDetectorPID(*trk.fDetectorPID);
275 for (Int_t i = 0; i < 3; i++) {fTOFLabel[i] = trk.fTOFLabel[i];}
278 //______________________________________________________________________________
279 AliAODTrack& AliAODTrack::operator=(const AliAODTrack& trk)
281 // Assignment operator
284 AliVTrack::operator=(trk);
287 trk.GetPosition(fPosition);
288 SetXYAtDCA(trk.XAtDCA(), trk.YAtDCA());
289 SetPxPyPzAtDCA(trk.PxAtDCA(), trk.PyAtDCA(), trk.PzAtDCA());
290 fRAtAbsorberEnd = trk.fRAtAbsorberEnd;
291 fChi2perNDF = trk.fChi2perNDF;
292 fChi2MatchTrigger = trk.fChi2MatchTrigger;
296 fTrackLength = trk.fTrackLength;
297 fITSMuonClusterMap = trk.fITSMuonClusterMap;
298 fMUONtrigHitsMapTrg = trk.fMUONtrigHitsMapTrg;
299 fMUONtrigHitsMapTrk = trk.fMUONtrigHitsMapTrk;
300 fFilterMap = trk.fFilterMap;
301 fTPCFitMap = trk.fTPCFitMap;
302 fTPCClusterMap = trk.fTPCClusterMap;
303 fTPCSharedMap = trk.fTPCSharedMap;
304 fTPCnclsF = trk.fTPCnclsF;
305 fTPCNCrossedRows = trk.fTPCNCrossedRows;
307 fCharge = trk.fCharge;
309 fPIDForTracking = trk.fPIDForTracking;
310 fCaloIndex = trk.fCaloIndex;
311 fTrackPhiOnEMCal = trk.fTrackPhiOnEMCal;
312 fTrackEtaOnEMCal = trk.fTrackEtaOnEMCal;
313 fTrackPtOnEMCal = trk.fTrackPtOnEMCal;
314 fIsMuonGlobalTrack = trk.fIsMuonGlobalTrack; // AU
315 fTPCsignalTuned = trk.fTPCsignalTuned;
316 fTOFsignalTuned = trk.fTOFsignalTuned;
317 fMFTClusterPattern = trk.fMFTClusterPattern; // AU
320 if(trk.fCovMatrix) fCovMatrix=new AliAODRedCov<6>(*trk.fCovMatrix);
321 else fCovMatrix=NULL;
324 fProdVertex = trk.fProdVertex;
325 SetUsedForVtxFit(trk.GetUsedForVtxFit());
326 SetUsedForPrimVtxFit(trk.GetUsedForPrimVtxFit());
328 //detector raw signals
330 if(trk.fDetPid) fDetPid=new AliAODPid(*trk.fDetPid);
333 //calibrated PID cache
336 if (trk.fDetectorPID) fDetectorPID = new AliDetectorPID(*trk.fDetectorPID);
337 for (Int_t i = 0; i < 3; i++) {fTOFLabel[i] = trk.fTOFLabel[i];}
343 //______________________________________________________________________________
344 Double_t AliAODTrack::M(AODTrkPID_t pid) const
347 // Masses for nuclei don't exist in the PDG tables, therefore they were put by hand.
352 return 0.000510999; //TDatabasePDG::Instance()->GetParticle(11/*::kElectron*/)->Mass();
356 return 0.1056584; //TDatabasePDG::Instance()->GetParticle(13/*::kMuonMinus*/)->Mass();
360 return 0.13957; //TDatabasePDG::Instance()->GetParticle(211/*::kPiPlus*/)->Mass();
364 return 0.4937; //TDatabasePDG::Instance()->GetParticle(321/*::kKPlus*/)->Mass();
368 return 0.9382720; //TDatabasePDG::Instance()->GetParticle(2212/*::kProton*/)->Mass();
372 return 1.8756; //TDatabasePDG::Instance()->GetParticle(1000010020)->Mass();
376 return 2.8089; //TDatabasePDG::Instance()->GetParticle(1000010030)->Mass();
380 return 2.8084; //TDatabasePDG::Instance()->GetParticle(1000020030)->Mass();
384 return 3.7274; //TDatabasePDG::Instance()->GetParticle(1000020040)->Mass();
396 //______________________________________________________________________________
397 Double_t AliAODTrack::E(AODTrkPID_t pid) const
399 // Returns the energy of the particle of a given pid.
401 if (pid != kUnknown) { // particle was identified
403 return TMath::Sqrt(P()*P() + m*m);
404 } else { // pid unknown
409 //______________________________________________________________________________
410 Double_t AliAODTrack::Y(AODTrkPID_t pid) const
412 // Returns the rapidity of a particle of a given pid.
414 if (pid != kUnknown) { // particle was identified
417 if (e>=0 && e!=pz) { // energy was positive (e.g. not -999.) and not equal to pz
418 return 0.5*TMath::Log((e+pz)/(e-pz));
419 } else { // energy not known or equal to pz
422 } else { // pid unknown
427 //______________________________________________________________________________
428 Double_t AliAODTrack::Y(Double_t m) const
430 // Returns the rapidity of a particle of a given mass.
432 if (m >= 0.) { // mass makes sense
435 if (e>=0 && e!=pz) { // energy was positive (e.g. not -999.) and not equal to pz
436 return 0.5*TMath::Log((e+pz)/(e-pz));
437 } else { // energy not known or equal to pz
440 } else { // pid unknown
445 void AliAODTrack::SetTOFLabel(const Int_t *p) {
447 for (Int_t i = 0; i < 3; i++) fTOFLabel[i]=p[i];
450 //_______________________________________________________________________
451 void AliAODTrack::GetTOFLabel(Int_t *p) const {
453 for (Int_t i=0; i<3; i++) p[i]=fTOFLabel[i];
456 //______________________________________________________________________________
457 AliAODTrack::AODTrkPID_t AliAODTrack::GetMostProbablePID() const
459 // Returns the most probable PID array element.
462 AODTrkPID_t loc = kUnknown;
463 Bool_t allTheSame = kTRUE;
466 for (Int_t iPID = 0; iPID < nPID; iPID++) {
467 if (fPID[iPID] >= max) {
468 if (fPID[iPID] > max) {
471 loc = (AODTrkPID_t)iPID;
478 return allTheSame ? AODTrkPID_t(GetPIDForTracking()) : loc;
481 //______________________________________________________________________________
482 void AliAODTrack::ConvertAliPIDtoAODPID()
484 // Converts AliPID array.
485 // The numbering scheme is the same for electrons, muons, pions, kaons, and protons.
486 // Everything else has to be set to zero.
488 fPID[kDeuteron] = 0.;
498 //______________________________________________________________________________
499 template <typename T> void AliAODTrack::SetP(const T *p, const Bool_t cartesian)
505 Double_t pt2 = p[0]*p[0] + p[1]*p[1];
506 Double_t pp = TMath::Sqrt(pt2 + p[2]*p[2]);
508 fMomentum[0] = TMath::Sqrt(pt2); // pt
509 fMomentum[1] = (pt2 != 0.) ? TMath::Pi()+TMath::ATan2(-p[1], -p[0]) : -999; // phi
510 fMomentum[2] = (pp != 0.) ? TMath::ACos(p[2] / pp) : -999.; // theta
512 fMomentum[0] = p[0]; // pt
513 fMomentum[1] = p[1]; // phi
514 fMomentum[2] = p[2]; // theta
517 fMomentum[0] = -999.;
518 fMomentum[1] = -999.;
519 fMomentum[2] = -999.;
524 //______________________________________________________________________________
525 template <typename T> void AliAODTrack::SetPosition(const T *x, const Bool_t dca)
538 // don't know any better yet
539 fPosition[0] = -999.;
540 fPosition[1] = -999.;
541 fPosition[2] = -999.;
546 fPosition[0] = -999.;
547 fPosition[1] = -999.;
548 fPosition[2] = -999.;
552 //______________________________________________________________________________
553 void AliAODTrack::SetDCA(Double_t d, Double_t z)
562 //______________________________________________________________________________
563 void AliAODTrack::Print(Option_t* /* option */) const
565 // prints information about AliAODTrack
567 printf("Object name: %s Track type: %s\n", GetName(), GetTitle());
568 printf(" px = %f\n", Px());
569 printf(" py = %f\n", Py());
570 printf(" pz = %f\n", Pz());
571 printf(" pt = %f\n", Pt());
572 printf(" 1/pt = %f\n", OneOverPt());
573 printf(" theta = %f\n", Theta());
574 printf(" phi = %f\n", Phi());
575 printf(" chi2/NDF = %f\n", Chi2perNDF());
576 printf(" charge = %d\n", Charge());
579 //______________________________________________________________________________
580 void AliAODTrack::SetMatchTrigger(Int_t matchTrig)
582 // Set the MUON trigger information
584 case 0: // 0 track does not match trigger
585 fITSMuonClusterMap=fITSMuonClusterMap&0x3fffffff;
587 case 1: // 1 track match but does not pass pt cut
588 fITSMuonClusterMap=(fITSMuonClusterMap&0x3fffffff)|0x40000000;
590 case 2: // 2 track match Low pt cut
591 fITSMuonClusterMap=(fITSMuonClusterMap&0x3fffffff)|0x80000000;
593 case 3: // 3 track match High pt cut
594 fITSMuonClusterMap=fITSMuonClusterMap|0xc0000000;
597 fITSMuonClusterMap=fITSMuonClusterMap&0x3fffffff;
598 AliWarning(Form("unknown case for matchTrig: %d\n",matchTrig));
602 //______________________________________________________________________________
603 Bool_t AliAODTrack::HitsMuonChamber(Int_t MuonChamber, Int_t cathode) const
605 // return kTRUE if the track fires the given tracking or trigger chamber.
606 // If the chamber is a trigger one:
607 // - if cathode = 0 or 1, the track matches the corresponding cathode
608 // - if cathode = -1, the track matches both cathodes
610 if (MuonChamber < 0) return kFALSE;
612 if (MuonChamber < 10) return TESTBIT(GetMUONClusterMap(), MuonChamber);
614 if (MuonChamber < 14) {
616 if (cathode < 0) return TESTBIT(GetHitsPatternInTrigCh(), 13-MuonChamber) &&
617 TESTBIT(GetHitsPatternInTrigCh(), 13-MuonChamber+4);
619 if (cathode < 2) return TESTBIT(GetHitsPatternInTrigCh(), 13-MuonChamber+(1-cathode)*4);
626 //______________________________________________________________________________
627 Bool_t AliAODTrack::MatchTriggerDigits() const
629 // return kTRUE if the track matches a digit on both planes of at least 2 trigger chambers
631 Int_t nMatchedChambers = 0;
632 for (Int_t ich=10; ich<14; ich++) if (HitsMuonChamber(ich)) nMatchedChambers++;
634 return (nMatchedChambers >= 2);
637 //______________________________________________________________________________
638 Bool_t AliAODTrack::PropagateToDCA(const AliVVertex *vtx,
639 Double_t b, Double_t maxd, Double_t dz[2], Double_t covar[3])
641 // compute impact parameters to the vertex vtx and their covariance matrix
642 // b is the Bz, needed to propagate correctly the track to vertex
643 // only the track parameters are update after the propagation (pos and mom),
644 // not the covariance matrix. This is OK for propagation over short distance
645 // inside the beam pipe.
646 // return kFALSE is something went wrong
648 // allowed only for tracks inside the beam pipe
649 Float_t xstart2 = fPosition[0]*fPosition[0]+fPosition[1]*fPosition[1];
650 if(xstart2 > 3.*3.) { // outside beampipe radius
651 AliError("This method can be used only for propagation inside the beam pipe");
655 // convert to AliExternalTrackParam
656 AliExternalTrackParam etp; etp.CopyFromVTrack(this);
659 if(!etp.PropagateToDCA(vtx,b,maxd,dz,covar)) return kFALSE;
661 // update track position and momentum
666 SetPosition(mom,kFALSE);
672 //______________________________________________________________________________
673 Bool_t AliAODTrack::GetPxPyPz(Double_t p[3]) const
675 //---------------------------------------------------------------------
676 // This function returns the global track momentum components
677 //---------------------------------------------------------------------
678 p[0]=Px(); p[1]=Py(); p[2]=Pz();
683 //_______________________________________________________________________
684 Float_t AliAODTrack::GetTPCClusterInfo(Int_t nNeighbours/*=3*/, Int_t type/*=0*/, Int_t row0, Int_t row1, Int_t bitType ) const
687 // TPC cluster information
688 // type 0: get fraction of found/findable clusters with neighbourhood definition
689 // 1: findable clusters with neighbourhood definition
692 // 0 - all cluster used
693 // 1 - clusters used for the kalman update
694 // definition of findable clusters:
695 // a cluster is defined as findable if there is another cluster
696 // within +- nNeighbours pad rows. The idea is to overcome threshold
697 // effects with a very simple algorithm.
703 Int_t last=-nNeighbours;
704 const TBits & clusterMap = (bitType%2==0) ? fTPCClusterMap : fTPCFitMap;
706 Int_t upperBound=clusterMap.GetNbits();
707 if (upperBound>row1) upperBound=row1;
708 for (Int_t i=row0; i<upperBound; ++i){
709 //look to current row
716 //look to nNeighbours before
717 if ((i-last)<=nNeighbours) {
721 //look to nNeighbours after
722 for (Int_t j=i+1; j<i+1+nNeighbours; ++j){
729 if (type==2) return found;
730 if (type==1) return findable;
735 fraction=(Float_t)found/(Float_t)findable;
740 return 0; // undefined type - default value
744 //______________________________________________________________________________
745 Double_t AliAODTrack::GetTRDslice(Int_t plane, Int_t slice) const {
747 // return TRD Pid information
749 if (!fDetPid) return -1;
750 Double32_t *trdSlices=fDetPid->GetTRDslices();
751 if (!trdSlices) return -1;
752 if ((plane<0) || (plane>=kTRDnPlanes)) {
756 Int_t ns=fDetPid->GetTRDnSlices();
757 if ((slice<-1) || (slice>=ns)) {
761 if(slice>=0) return trdSlices[plane*ns + slice];
763 // return average of the dEdx measurements
764 Double_t q=0.; Double32_t *s = &trdSlices[plane*ns];
765 for (Int_t i=0; i<ns; i++, s++) if((*s)>0.) q+=(*s);
769 //______________________________________________________________________________
770 UChar_t AliAODTrack::GetTRDntrackletsPID() const{
772 // return number of tracklets calculated from the slices
774 if(!fDetPid) return -1;
775 return fDetPid->GetTRDntrackletsPID();
778 //______________________________________________________________________________
779 UChar_t AliAODTrack::GetTRDncls(Int_t layer) const {
781 // return number of TRD clusters
783 if(!fDetPid || layer > 5) return -1;
784 if(layer < 0) return fDetPid->GetTRDncls();
785 else return fDetPid->GetTRDncls(layer);
788 //______________________________________________________________________________
789 Double_t AliAODTrack::GetTRDmomentum(Int_t plane, Double_t */*sp*/) const
791 //Returns momentum estimation
792 // in TRD layer "plane".
794 if (!fDetPid) return -1;
795 const Double_t *trdMomentum=fDetPid->GetTRDmomentum();
800 if ((plane<0) || (plane>=kTRDnPlanes)) {
804 return trdMomentum[plane];
807 //_______________________________________________________________________
808 Int_t AliAODTrack::GetTOFBunchCrossing(Double_t b, Bool_t) const
810 // Returns the number of bunch crossings after trigger (assuming 25ns spacing)
811 const double kSpacing = 25e3; // min interbanch spacing
812 const double kShift = 0;
813 Int_t bcid = kTOFBCNA; // defualt one
814 if (!IsOn(kTOFout) || !IsOn(kESDpid)) return bcid; // no info
816 double tdif = GetTOFsignal();
817 if (IsOn(kTIME)) { // integrated time info is there
818 int pid = (int)GetMostProbablePID();
820 GetIntegratedTimes(ttimes, pid>=AliPID::kSPECIES ? AliPID::kSPECIESC : AliPID::kSPECIES);
823 else { // assume integrated time info from TOF radius and momentum
824 const double kRTOF = 385.;
825 const double kCSpeed = 3.e-2; // cm/ps
827 if (p<0.001) p = 1.0;
829 double path = kRTOF; // mean TOF radius
830 if (TMath::Abs(b)>kAlmost0) { // account for curvature
831 double curv = Pt()/(b*kB2C);
833 double tgl = Pz()/Pt();
834 path = 2./curv*TMath::ASin(kRTOF*curv/2.)*TMath::Sqrt(1.+tgl*tgl);
837 tdif -= path/kCSpeed*TMath::Sqrt(1.+m*m/(p*p));
839 bcid = TMath::Nint((tdif - kShift)/kSpacing);
843 void AliAODTrack::SetDetectorPID(const AliDetectorPID *pid)
846 // Set the detector PID
848 if (fDetectorPID) delete fDetectorPID;
853 //_____________________________________________________________________________
854 Double_t AliAODTrack::GetHMPIDsignal() const
856 if(fAODEvent->GetHMPIDringForTrackID(fID)) return fAODEvent->GetHMPIDringForTrackID(fID)->GetHmpSignal();
860 //_____________________________________________________________________________
861 Double_t AliAODTrack::GetHMPIDoccupancy() const
863 if(fAODEvent->GetHMPIDringForTrackID(fID)) return fAODEvent->GetHMPIDringForTrackID(fID)->GetHmpOccupancy();
867 //_____________________________________________________________________________
868 Int_t AliAODTrack::GetHMPIDcluIdx() const
870 if(fAODEvent->GetHMPIDringForTrackID(fID)) return fAODEvent->GetHMPIDringForTrackID(fID)->GetHmpCluIdx();
874 //_____________________________________________________________________________
875 void AliAODTrack::GetHMPIDtrk(Float_t &x, Float_t &y, Float_t &th, Float_t &ph) const
877 x = -999; y = -999.; th = -999.; ph = -999.;
879 const AliAODHMPIDrings *ring=fAODEvent->GetHMPIDringForTrackID(fID);
881 x = ring->GetHmpTrackX();
882 y = ring->GetHmpTrackY();
883 th = ring->GetHmpTrackTheta();
884 ph = ring->GetHmpTrackPhi();
888 //_____________________________________________________________________________
889 void AliAODTrack::GetHMPIDmip(Float_t &x,Float_t &y,Int_t &q, Int_t &nph) const
891 x = -999; y = -999.; q = -999; nph = -999;
893 const AliAODHMPIDrings *ring=fAODEvent->GetHMPIDringForTrackID(fID);
895 x = ring->GetHmpMipX();
896 y = ring->GetHmpMipY();
897 q = (Int_t)ring->GetHmpMipCharge();
898 nph = (Int_t)ring->GetHmpNumOfPhotonClusters();
902 //_____________________________________________________________________________
903 Bool_t AliAODTrack::GetOuterHmpPxPyPz(Double_t *p) const
905 if(fAODEvent->GetHMPIDringForTrackID(fID)) {fAODEvent->GetHMPIDringForTrackID(fID)->GetHmpMom(p); return kTRUE;}
909 //_____________________________________________________________________________
910 Bool_t AliAODTrack::GetXYZAt(Double_t x, Double_t b, Double_t *r) const
912 //---------------------------------------------------------------------
913 // This function returns the global track position extrapolated to
914 // the radial position "x" (cm) in the magnetic field "b" (kG)
915 //---------------------------------------------------------------------
917 //conversion of track parameter representation is
918 //based on the implementation of AliExternalTrackParam::Set(...)
919 //maybe some of this code can be moved to AliVTrack to avoid code duplication
921 Double_t radPos2 = fPosition[0]*fPosition[0]+fPosition[1]*fPosition[1];
922 Double_t radMax = 45.; // approximately ITS outer radius
923 if (radPos2 < radMax*radMax) { // inside the ITS
924 alpha = fMomentum[1]; //TMath::ATan2(fMomentum[1],fMomentum[0]); // fMom is pt,phi,theta!
925 } else { // outside the ITS
926 Float_t phiPos = TMath::Pi()+TMath::ATan2(-fPosition[1], -fPosition[0]);
928 TMath::DegToRad()*(20*((((Int_t)(phiPos*TMath::RadToDeg()))/20))+10);
931 // Get the vertex of origin and the momentum
932 TVector3 ver(fPosition[0],fPosition[1],fPosition[2]);
933 TVector3 mom(Px(),Py(),Pz());
935 // Rotate to the local coordinate system
939 Double_t param0 = ver.Y();
940 Double_t param1 = ver.Z();
941 Double_t param2 = TMath::Sin(mom.Phi());
942 Double_t param3 = mom.Pz()/mom.Pt();
943 Double_t param4 = TMath::Sign(1/mom.Pt(),(Double_t)fCharge);
945 //calculate the propagated coordinates
946 //this is based on AliExternalTrackParam::GetXYZAt(Double_t x, Double_t b, Double_t *r)
947 Double_t dx=x-ver.X();
948 if(TMath::Abs(dx)<=kAlmost0) return GetXYZ(r);
951 Double_t f2=f1 + dx*param4*b*kB2C;
953 if (TMath::Abs(f1) >= kAlmost1) return kFALSE;
954 if (TMath::Abs(f2) >= kAlmost1) return kFALSE;
956 Double_t r1=TMath::Sqrt((1.-f1)*(1.+f1)), r2=TMath::Sqrt((1.-f2)*(1.+f2));
958 r[1] = param0 + dx*(f1+f2)/(r1+r2);
959 r[2] = param1 + dx*(r2 + f2*(f1+f2)/(r1+r2))*param3;//Thanks to Andrea & Peter
960 return Local2GlobalPosition(r,alpha);
963 //_____________________________________________________________________________
964 Bool_t AliAODTrack::GetXYZatR(Double_t xr,Double_t bz, Double_t *xyz, Double_t* alpSect) const
966 // This method has 3 modes of behaviour
967 // 1) xyz[3] array is provided but alpSect pointer is 0: calculate the position of track intersection
968 // with circle of radius xr and fill it in xyz array
969 // 2) alpSect pointer is provided: find alpha of the sector where the track reaches local coordinate xr
970 // Note that in this case xr is NOT the radius but the local coordinate.
971 // If the xyz array is provided, it will be filled by track lab coordinates at local X in this sector
972 // 3) Neither alpSect nor xyz pointers are provided: just check if the track reaches radius xr
976 Double_t radPos2 = fPosition[0]*fPosition[0]+fPosition[1]*fPosition[1];
977 Double_t radMax = 45.; // approximately ITS outer radius
978 if (radPos2 < radMax*radMax) { // inside the ITS
979 alpha = fMomentum[1]; //TMath::ATan2(fMomentum[1],fMomentum[0]); // fMom is pt,phi,theta!
980 } else { // outside the ITS
981 Float_t phiPos = TMath::Pi()+TMath::ATan2(-fPosition[1], -fPosition[0]);
983 TMath::DegToRad()*(20*((((Int_t)(phiPos*TMath::RadToDeg()))/20))+10);
986 // Get the vertex of origin and the momentum
987 TVector3 ver(fPosition[0],fPosition[1],fPosition[2]);
988 TVector3 mom(Px(),Py(),Pz());
990 // Rotate to the local coordinate system
994 Double_t fx = ver.X();
995 Double_t fy = ver.Y();
996 Double_t fz = ver.Z();
997 Double_t sn = TMath::Sin(mom.Phi());
998 Double_t tgl = mom.Pz()/mom.Pt();
999 Double_t crv = TMath::Sign(1/mom.Pt(),(Double_t)fCharge)*bz*kB2C;
1001 if ( (TMath::Abs(bz))<kAlmost0Field ) crv=0.;
1003 // general circle parameterization:
1004 // x = (r0+tR)cos(phi0) - tR cos(t+phi0)
1005 // y = (r0+tR)sin(phi0) - tR sin(t+phi0)
1006 // where qb is the sign of the curvature, tR is the track's signed radius and r0
1007 // is the DCA of helix to origin
1009 double tR = 1./crv; // track radius signed
1010 double cs = TMath::Sqrt((1-sn)*(1+sn));
1011 double x0 = fx - sn*tR; // helix center coordinates
1012 double y0 = fy + cs*tR;
1013 double phi0 = TMath::ATan2(y0,x0); // angle of PCA wrt to the origin
1014 if (tR<0) phi0 += TMath::Pi();
1015 if (phi0 > TMath::Pi()) phi0 -= 2.*TMath::Pi();
1016 else if (phi0 <-TMath::Pi()) phi0 += 2.*TMath::Pi();
1017 double cs0 = TMath::Cos(phi0);
1018 double sn0 = TMath::Sin(phi0);
1019 double r0 = x0*cs0 + y0*sn0 - tR; // DCA to origin
1020 double r2R = 1.+r0/tR;
1023 if (r2R<kAlmost0) return kFALSE; // helix is centered at the origin, no specific intersection with other concetric circle
1024 if (!xyz && !alpSect) return kTRUE;
1025 double xr2R = xr/tR;
1026 double r2Ri = 1./r2R;
1027 // the intersection cos(t) = [1 + (r0/tR+1)^2 - (r0/tR)^2]/[2(1+r0/tR)]
1028 double cosT = 0.5*(r2R + (1-xr2R*xr2R)*r2Ri);
1029 if ( TMath::Abs(cosT)>kAlmost1 ) {
1030 // printf("Does not reach : %f %f\n",r0,tR);
1031 return kFALSE; // track does not reach the radius xr
1034 double t = TMath::ACos(cosT);
1036 // intersection point
1038 xyzi[0] = x0 - tR*TMath::Cos(t+phi0);
1039 xyzi[1] = y0 - tR*TMath::Sin(t+phi0);
1040 if (xyz) { // if postition is requested, then z is needed:
1041 double t0 = TMath::ATan2(cs,-sn) - phi0;
1042 double z0 = fz - t0*tR*tgl;
1043 xyzi[2] = z0 + tR*t*tgl;
1047 Local2GlobalPosition(xyzi,alpha);
1056 double &alp = *alpSect;
1057 // determine the sector of crossing
1058 double phiPos = TMath::Pi()+TMath::ATan2(-xyzi[1],-xyzi[0]);
1059 int sect = ((Int_t)(phiPos*TMath::RadToDeg()))/20;
1060 alp = TMath::DegToRad()*(20*sect+10);
1061 double x2r,f1,f2,r1,r2,dx,dy2dx,yloc=0, ylocMax = xr*TMath::Tan(TMath::Pi()/18); // min max Y within sector at given X
1064 Double_t ca=TMath::Cos(alp-alpha), sa=TMath::Sin(alp-alpha);
1065 if ((cs*ca+sn*sa)<0) {
1066 AliDebug(1,Form("Rotation to target sector impossible: local cos(phi) would become %.2f",cs*ca+sn*sa));
1071 if (TMath::Abs(f1) >= kAlmost1) {
1072 AliDebug(1,Form("Rotation to target sector impossible: local sin(phi) would become %.2f",f1));
1076 double tmpX = fx*ca + fy*sa;
1077 double tmpY = -fx*sa + fy*ca;
1079 // estimate Y at X=xr
1083 if (TMath::Abs(f2) >= kAlmost1) {
1084 AliDebug(1,Form("Propagation in target sector failed ! %.10e",f2));
1087 r1 = TMath::Sqrt((1.-f1)*(1.+f1));
1088 r2 = TMath::Sqrt((1.-f2)*(1.+f2));
1089 dy2dx = (f1+f2)/(r1+r2);
1090 yloc = tmpY + dx*dy2dx;
1091 if (yloc>ylocMax) {alp += 2*TMath::Pi()/18; sect++;}
1092 else if (yloc<-ylocMax) {alp -= 2*TMath::Pi()/18; sect--;}
1094 if (alp >= TMath::Pi()) alp -= 2*TMath::Pi();
1095 else if (alp < -TMath::Pi()) alp += 2*TMath::Pi();
1096 // if (sect>=18) sect = 0;
1097 // if (sect<=0) sect = 17;
1100 // if alpha was requested, then recalculate the position at intersection in sector
1104 if (TMath::Abs(x2r)<0.05) xyz[2] = fz + dx*(r2 + f2*dy2dx)*tgl;
1106 // for small dx/R the linear apporximation of the arc by the segment is OK,
1107 // but at large dx/R the error is very large and leads to incorrect Z propagation
1108 // angle traversed delta = 2*asin(dist_start_end / R / 2), hence the arc is: R*deltaPhi
1109 // The dist_start_end is obtained from sqrt(dx^2+dy^2) = x/(r1+r2)*sqrt(2+f1*f2+r1*r2)
1110 // Similarly, the rotation angle in linear in dx only for dx<<R
1111 double chord = dx*TMath::Sqrt(1+dy2dx*dy2dx); // distance from old position to new one
1112 double rot = 2*TMath::ASin(0.5*chord*crv); // angular difference seen from the circle center
1113 xyz[2] = fz + rot/crv*tgl;
1115 Local2GlobalPosition(xyz,alp);
1122 //_______________________________________________________
1123 void AliAODTrack::GetITSdEdxSamples(Double_t s[4]) const
1125 // get ITS dedx samples
1126 if (!fDetPid) for (int i=4;i--;) s[i]=0;
1127 else for (int i=4;i--;) s[i] = fDetPid->GetITSdEdxSample(i);
1130 //_____________________________________________
1131 Double_t AliAODTrack::GetMassForTracking() const
1133 int pid = fPIDForTracking;
1134 if (pid<AliPID::kPion) pid = AliPID::kPion;
1135 double m = AliPID::ParticleMass(fPIDForTracking);
1136 return (fPIDForTracking==AliPID::kHe3 || fPIDForTracking==AliPID::kAlpha) ? -m : m;
1138 //_______________________________________________________
1139 const AliTOFHeader* AliAODTrack::GetTOFHeader() const {
1140 return fAODEvent->GetTOFHeader();