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),
70 fTOFsignalTuned(99999),
73 // default constructor
76 SetPosition((Float_t*)NULL);
77 SetXYAtDCA(-999., -999.);
78 SetPxPyPzAtDCA(-999., -999., -999.);
79 for (Int_t i = 0; i < 3; i++) {fTOFLabel[i] = -1;}
82 //______________________________________________________________________________
83 AliAODTrack::AliAODTrack(Short_t id,
89 Double_t covMatrix[21],
92 AliAODVertex *prodVertex,
94 Bool_t usedForPrimVtxFit,
100 fChi2perNDF(chi2perNDF),
101 fChi2MatchTrigger(0.),
107 fITSMuonClusterMap(0),
108 fMUONtrigHitsMapTrg(0),
109 fMUONtrigHitsMapTrk(0),
110 fFilterMap(selectInfo),
119 fPIDForTracking(AliPID::kPion),
120 fCaloIndex(kEMCALNoMatch),
124 fProdVertex(prodVertex),
125 fTrackPhiOnEMCal(-999),
126 fTrackEtaOnEMCal(-999),
127 fTrackPtOnEMCal(-999),
129 fTOFsignalTuned(99999),
135 SetPosition(x, isDCA);
136 SetXYAtDCA(-999., -999.);
137 SetPxPyPzAtDCA(-999., -999., -999.);
138 SetUsedForVtxFit(usedForVtxFit);
139 SetUsedForPrimVtxFit(usedForPrimVtxFit);
140 if(covMatrix) SetCovMatrix(covMatrix);
141 SetITSClusterMap(itsClusMap);
142 for (Int_t i=0;i<3;i++) {fTOFLabel[i]=-1;}
145 //______________________________________________________________________________
146 AliAODTrack::AliAODTrack(Short_t id,
152 Float_t covMatrix[21],
155 AliAODVertex *prodVertex,
156 Bool_t usedForVtxFit,
157 Bool_t usedForPrimVtxFit,
160 Float_t chi2perNDF ) :
163 fChi2perNDF(chi2perNDF),
164 fChi2MatchTrigger(0.),
170 fITSMuonClusterMap(0),
171 fMUONtrigHitsMapTrg(0),
172 fMUONtrigHitsMapTrk(0),
173 fFilterMap(selectInfo),
182 fPIDForTracking(AliPID::kPion),
183 fCaloIndex(kEMCALNoMatch),
187 fProdVertex(prodVertex),
188 fTrackPhiOnEMCal(-999),
189 fTrackEtaOnEMCal(-999),
190 fTrackPtOnEMCal(-999),
192 fTOFsignalTuned(99999),
198 SetPosition(x, isDCA);
199 SetXYAtDCA(-999., -999.);
200 SetPxPyPzAtDCA(-999., -999., -999.);
201 SetUsedForVtxFit(usedForVtxFit);
202 SetUsedForPrimVtxFit(usedForPrimVtxFit);
203 if(covMatrix) SetCovMatrix(covMatrix);
204 SetITSClusterMap(itsClusMap);
205 for (Int_t i=0;i<3;i++) {fTOFLabel[i]=-1;}
208 //______________________________________________________________________________
209 AliAODTrack::~AliAODTrack()
219 //______________________________________________________________________________
220 AliAODTrack::AliAODTrack(const AliAODTrack& trk) :
222 fRAtAbsorberEnd(trk.fRAtAbsorberEnd),
223 fChi2perNDF(trk.fChi2perNDF),
224 fChi2MatchTrigger(trk.fChi2MatchTrigger),
229 fTrackLength(trk.fTrackLength),
230 fITSMuonClusterMap(trk.fITSMuonClusterMap),
231 fMUONtrigHitsMapTrg(trk.fMUONtrigHitsMapTrg),
232 fMUONtrigHitsMapTrk(trk.fMUONtrigHitsMapTrk),
233 fFilterMap(trk.fFilterMap),
234 fTPCFitMap(trk.fTPCFitMap),
235 fTPCClusterMap(trk.fTPCClusterMap),
236 fTPCSharedMap(trk.fTPCSharedMap),
237 fTPCnclsF(trk.fTPCnclsF),
238 fTPCNCrossedRows(trk.fTPCNCrossedRows),
240 fCharge(trk.fCharge),
242 fPIDForTracking(trk.fPIDForTracking),
243 fCaloIndex(trk.fCaloIndex),
247 fProdVertex(trk.fProdVertex),
248 fTrackPhiOnEMCal(trk.fTrackPhiOnEMCal),
249 fTrackEtaOnEMCal(trk.fTrackEtaOnEMCal),
250 fTrackPtOnEMCal(trk.fTrackPtOnEMCal),
251 fTPCsignalTuned(trk.fTPCsignalTuned),
252 fTOFsignalTuned(trk.fTOFsignalTuned),
253 fAODEvent(trk.fAODEvent)
258 trk.GetPosition(fPosition);
259 SetXYAtDCA(trk.XAtDCA(), trk.YAtDCA());
260 SetPxPyPzAtDCA(trk.PxAtDCA(), trk.PyAtDCA(), trk.PzAtDCA());
261 SetUsedForVtxFit(trk.GetUsedForVtxFit());
262 SetUsedForPrimVtxFit(trk.GetUsedForPrimVtxFit());
263 if(trk.fCovMatrix) fCovMatrix=new AliAODRedCov<6>(*trk.fCovMatrix);
264 if(trk.fDetPid) fDetPid=new AliAODPid(*trk.fDetPid);
266 if (trk.fDetectorPID) fDetectorPID = new AliDetectorPID(*trk.fDetectorPID);
267 for (Int_t i = 0; i < 3; i++) {fTOFLabel[i] = trk.fTOFLabel[i];}
270 //______________________________________________________________________________
271 AliAODTrack& AliAODTrack::operator=(const AliAODTrack& trk)
273 // Assignment operator
276 AliVTrack::operator=(trk);
279 trk.GetPosition(fPosition);
280 SetXYAtDCA(trk.XAtDCA(), trk.YAtDCA());
281 SetPxPyPzAtDCA(trk.PxAtDCA(), trk.PyAtDCA(), trk.PzAtDCA());
282 fRAtAbsorberEnd = trk.fRAtAbsorberEnd;
283 fChi2perNDF = trk.fChi2perNDF;
284 fChi2MatchTrigger = trk.fChi2MatchTrigger;
288 fTrackLength = trk.fTrackLength;
289 fITSMuonClusterMap = trk.fITSMuonClusterMap;
290 fMUONtrigHitsMapTrg = trk.fMUONtrigHitsMapTrg;
291 fMUONtrigHitsMapTrk = trk.fMUONtrigHitsMapTrk;
292 fFilterMap = trk.fFilterMap;
293 fTPCFitMap = trk.fTPCFitMap;
294 fTPCClusterMap = trk.fTPCClusterMap;
295 fTPCSharedMap = trk.fTPCSharedMap;
296 fTPCnclsF = trk.fTPCnclsF;
297 fTPCNCrossedRows = trk.fTPCNCrossedRows;
299 fCharge = trk.fCharge;
301 fPIDForTracking = trk.fPIDForTracking;
302 fCaloIndex = trk.fCaloIndex;
303 fTrackPhiOnEMCal = trk.fTrackPhiOnEMCal;
304 fTrackEtaOnEMCal = trk.fTrackEtaOnEMCal;
305 fTrackPtOnEMCal = trk.fTrackPtOnEMCal;
306 fTPCsignalTuned = trk.fTPCsignalTuned;
307 fTOFsignalTuned = trk.fTOFsignalTuned;
310 if(trk.fCovMatrix) fCovMatrix=new AliAODRedCov<6>(*trk.fCovMatrix);
311 else fCovMatrix=NULL;
314 fProdVertex = trk.fProdVertex;
315 SetUsedForVtxFit(trk.GetUsedForVtxFit());
316 SetUsedForPrimVtxFit(trk.GetUsedForPrimVtxFit());
318 //detector raw signals
320 if(trk.fDetPid) fDetPid=new AliAODPid(*trk.fDetPid);
323 //calibrated PID cache
326 if (trk.fDetectorPID) fDetectorPID = new AliDetectorPID(*trk.fDetectorPID);
327 for (Int_t i = 0; i < 3; i++) {fTOFLabel[i] = trk.fTOFLabel[i];}
333 //______________________________________________________________________________
334 Double_t AliAODTrack::M(AODTrkPID_t pid) const
337 // Masses for nuclei don't exist in the PDG tables, therefore they were put by hand.
342 return 0.000510999; //TDatabasePDG::Instance()->GetParticle(11/*::kElectron*/)->Mass();
346 return 0.1056584; //TDatabasePDG::Instance()->GetParticle(13/*::kMuonMinus*/)->Mass();
350 return 0.13957; //TDatabasePDG::Instance()->GetParticle(211/*::kPiPlus*/)->Mass();
354 return 0.4937; //TDatabasePDG::Instance()->GetParticle(321/*::kKPlus*/)->Mass();
358 return 0.9382720; //TDatabasePDG::Instance()->GetParticle(2212/*::kProton*/)->Mass();
362 return 1.8756; //TDatabasePDG::Instance()->GetParticle(1000010020)->Mass();
366 return 2.8089; //TDatabasePDG::Instance()->GetParticle(1000010030)->Mass();
370 return 2.8084; //TDatabasePDG::Instance()->GetParticle(1000020030)->Mass();
374 return 3.7274; //TDatabasePDG::Instance()->GetParticle(1000020040)->Mass();
386 //______________________________________________________________________________
387 Double_t AliAODTrack::E(AODTrkPID_t pid) const
389 // Returns the energy of the particle of a given pid.
391 if (pid != kUnknown) { // particle was identified
393 return TMath::Sqrt(P()*P() + m*m);
394 } else { // pid unknown
399 //______________________________________________________________________________
400 Double_t AliAODTrack::Y(AODTrkPID_t pid) const
402 // Returns the rapidity of a particle of a given pid.
404 if (pid != kUnknown) { // particle was identified
407 if (e>=0 && e!=pz) { // energy was positive (e.g. not -999.) and not equal to pz
408 return 0.5*TMath::Log((e+pz)/(e-pz));
409 } else { // energy not known or equal to pz
412 } else { // pid unknown
417 //______________________________________________________________________________
418 Double_t AliAODTrack::Y(Double_t m) const
420 // Returns the rapidity of a particle of a given mass.
422 if (m >= 0.) { // mass makes sense
425 if (e>=0 && e!=pz) { // energy was positive (e.g. not -999.) and not equal to pz
426 return 0.5*TMath::Log((e+pz)/(e-pz));
427 } else { // energy not known or equal to pz
430 } else { // pid unknown
435 void AliAODTrack::SetTOFLabel(const Int_t *p) {
437 for (Int_t i = 0; i < 3; i++) fTOFLabel[i]=p[i];
440 //_______________________________________________________________________
441 void AliAODTrack::GetTOFLabel(Int_t *p) const {
443 for (Int_t i=0; i<3; i++) p[i]=fTOFLabel[i];
446 //______________________________________________________________________________
447 AliAODTrack::AODTrkPID_t AliAODTrack::GetMostProbablePID() const
449 // Returns the most probable PID array element.
452 AODTrkPID_t loc = kUnknown;
453 Bool_t allTheSame = kTRUE;
456 for (Int_t iPID = 0; iPID < nPID; iPID++) {
457 if (fPID[iPID] >= max) {
458 if (fPID[iPID] > max) {
461 loc = (AODTrkPID_t)iPID;
468 return allTheSame ? AODTrkPID_t(GetPIDForTracking()) : loc;
471 //______________________________________________________________________________
472 void AliAODTrack::ConvertAliPIDtoAODPID()
474 // Converts AliPID array.
475 // The numbering scheme is the same for electrons, muons, pions, kaons, and protons.
476 // Everything else has to be set to zero.
478 fPID[kDeuteron] = 0.;
488 //______________________________________________________________________________
489 template <typename T> void AliAODTrack::SetP(const T *p, const Bool_t cartesian)
495 Double_t pt2 = p[0]*p[0] + p[1]*p[1];
496 Double_t pp = TMath::Sqrt(pt2 + p[2]*p[2]);
498 fMomentum[0] = TMath::Sqrt(pt2); // pt
499 fMomentum[1] = (pt2 != 0.) ? TMath::Pi()+TMath::ATan2(-p[1], -p[0]) : -999; // phi
500 fMomentum[2] = (pp != 0.) ? TMath::ACos(p[2] / pp) : -999.; // theta
502 fMomentum[0] = p[0]; // pt
503 fMomentum[1] = p[1]; // phi
504 fMomentum[2] = p[2]; // theta
507 fMomentum[0] = -999.;
508 fMomentum[1] = -999.;
509 fMomentum[2] = -999.;
514 //______________________________________________________________________________
515 template <typename T> void AliAODTrack::SetPosition(const T *x, const Bool_t dca)
528 // don't know any better yet
529 fPosition[0] = -999.;
530 fPosition[1] = -999.;
531 fPosition[2] = -999.;
536 fPosition[0] = -999.;
537 fPosition[1] = -999.;
538 fPosition[2] = -999.;
542 //______________________________________________________________________________
543 void AliAODTrack::SetDCA(Double_t d, Double_t z)
552 //______________________________________________________________________________
553 void AliAODTrack::Print(Option_t* /* option */) const
555 // prints information about AliAODTrack
557 printf("Object name: %s Track type: %s\n", GetName(), GetTitle());
558 printf(" px = %f\n", Px());
559 printf(" py = %f\n", Py());
560 printf(" pz = %f\n", Pz());
561 printf(" pt = %f\n", Pt());
562 printf(" 1/pt = %f\n", OneOverPt());
563 printf(" theta = %f\n", Theta());
564 printf(" phi = %f\n", Phi());
565 printf(" chi2/NDF = %f\n", Chi2perNDF());
566 printf(" charge = %d\n", Charge());
569 //______________________________________________________________________________
570 void AliAODTrack::SetMatchTrigger(Int_t matchTrig)
572 // Set the MUON trigger information
574 case 0: // 0 track does not match trigger
575 fITSMuonClusterMap=fITSMuonClusterMap&0x3fffffff;
577 case 1: // 1 track match but does not pass pt cut
578 fITSMuonClusterMap=(fITSMuonClusterMap&0x3fffffff)|0x40000000;
580 case 2: // 2 track match Low pt cut
581 fITSMuonClusterMap=(fITSMuonClusterMap&0x3fffffff)|0x80000000;
583 case 3: // 3 track match High pt cut
584 fITSMuonClusterMap=fITSMuonClusterMap|0xc0000000;
587 fITSMuonClusterMap=fITSMuonClusterMap&0x3fffffff;
588 AliWarning(Form("unknown case for matchTrig: %d\n",matchTrig));
592 //______________________________________________________________________________
593 Bool_t AliAODTrack::HitsMuonChamber(Int_t MuonChamber, Int_t cathode) const
595 // return kTRUE if the track fires the given tracking or trigger chamber.
596 // If the chamber is a trigger one:
597 // - if cathode = 0 or 1, the track matches the corresponding cathode
598 // - if cathode = -1, the track matches both cathodes
600 if (MuonChamber < 0) return kFALSE;
602 if (MuonChamber < 10) return TESTBIT(GetMUONClusterMap(), MuonChamber);
604 if (MuonChamber < 14) {
606 if (cathode < 0) return TESTBIT(GetHitsPatternInTrigCh(), 13-MuonChamber) &&
607 TESTBIT(GetHitsPatternInTrigCh(), 13-MuonChamber+4);
609 if (cathode < 2) return TESTBIT(GetHitsPatternInTrigCh(), 13-MuonChamber+(1-cathode)*4);
616 //______________________________________________________________________________
617 Bool_t AliAODTrack::MatchTriggerDigits() const
619 // return kTRUE if the track matches a digit on both planes of at least 2 trigger chambers
621 Int_t nMatchedChambers = 0;
622 for (Int_t ich=10; ich<14; ich++) if (HitsMuonChamber(ich)) nMatchedChambers++;
624 return (nMatchedChambers >= 2);
627 //______________________________________________________________________________
628 Bool_t AliAODTrack::PropagateToDCA(const AliVVertex *vtx,
629 Double_t b, Double_t maxd, Double_t dz[2], Double_t covar[3])
631 // compute impact parameters to the vertex vtx and their covariance matrix
632 // b is the Bz, needed to propagate correctly the track to vertex
633 // only the track parameters are update after the propagation (pos and mom),
634 // not the covariance matrix. This is OK for propagation over short distance
635 // inside the beam pipe.
636 // return kFALSE is something went wrong
638 // allowed only for tracks inside the beam pipe
639 Float_t xstart2 = fPosition[0]*fPosition[0]+fPosition[1]*fPosition[1];
640 if(xstart2 > 3.*3.) { // outside beampipe radius
641 AliError("This method can be used only for propagation inside the beam pipe");
645 // convert to AliExternalTrackParam
646 AliExternalTrackParam etp; etp.CopyFromVTrack(this);
649 if(!etp.PropagateToDCA(vtx,b,maxd,dz,covar)) return kFALSE;
651 // update track position and momentum
656 SetPosition(mom,kFALSE);
662 //______________________________________________________________________________
663 Bool_t AliAODTrack::GetPxPyPz(Double_t p[3]) const
665 //---------------------------------------------------------------------
666 // This function returns the global track momentum components
667 //---------------------------------------------------------------------
668 p[0]=Px(); p[1]=Py(); p[2]=Pz();
673 //_______________________________________________________________________
674 Float_t AliAODTrack::GetTPCClusterInfo(Int_t nNeighbours/*=3*/, Int_t type/*=0*/, Int_t row0, Int_t row1, Int_t bitType ) const
677 // TPC cluster information
678 // type 0: get fraction of found/findable clusters with neighbourhood definition
679 // 1: findable clusters with neighbourhood definition
682 // 0 - all cluster used
683 // 1 - clusters used for the kalman update
684 // definition of findable clusters:
685 // a cluster is defined as findable if there is another cluster
686 // within +- nNeighbours pad rows. The idea is to overcome threshold
687 // effects with a very simple algorithm.
693 Int_t last=-nNeighbours;
694 const TBits & clusterMap = (bitType%2==0) ? fTPCClusterMap : fTPCFitMap;
696 Int_t upperBound=clusterMap.GetNbits();
697 if (upperBound>row1) upperBound=row1;
698 for (Int_t i=row0; i<upperBound; ++i){
699 //look to current row
706 //look to nNeighbours before
707 if ((i-last)<=nNeighbours) {
711 //look to nNeighbours after
712 for (Int_t j=i+1; j<i+1+nNeighbours; ++j){
719 if (type==2) return found;
720 if (type==1) return findable;
725 fraction=(Float_t)found/(Float_t)findable;
730 return 0; // undefined type - default value
734 //______________________________________________________________________________
735 Double_t AliAODTrack::GetTRDslice(Int_t plane, Int_t slice) const {
737 // return TRD Pid information
739 if (!fDetPid) return -1;
740 Double32_t *trdSlices=fDetPid->GetTRDslices();
741 if (!trdSlices) return -1;
742 if ((plane<0) || (plane>=kTRDnPlanes)) {
746 Int_t ns=fDetPid->GetTRDnSlices();
747 if ((slice<-1) || (slice>=ns)) {
751 if(slice>=0) return trdSlices[plane*ns + slice];
753 // return average of the dEdx measurements
754 Double_t q=0.; Double32_t *s = &trdSlices[plane*ns];
755 for (Int_t i=0; i<ns; i++, s++) if((*s)>0.) q+=(*s);
759 //______________________________________________________________________________
760 UChar_t AliAODTrack::GetTRDntrackletsPID() const{
762 // return number of tracklets calculated from the slices
764 if(!fDetPid) return -1;
765 return fDetPid->GetTRDntrackletsPID();
768 //______________________________________________________________________________
769 UChar_t AliAODTrack::GetTRDncls(Int_t layer) const {
771 // return number of TRD clusters
773 if(!fDetPid || layer > 5) return -1;
774 if(layer < 0) return fDetPid->GetTRDncls();
775 else return fDetPid->GetTRDncls(layer);
778 //______________________________________________________________________________
779 Double_t AliAODTrack::GetTRDmomentum(Int_t plane, Double_t */*sp*/) const
781 //Returns momentum estimation
782 // in TRD layer "plane".
784 if (!fDetPid) return -1;
785 const Double_t *trdMomentum=fDetPid->GetTRDmomentum();
790 if ((plane<0) || (plane>=kTRDnPlanes)) {
794 return trdMomentum[plane];
797 //_______________________________________________________________________
798 Int_t AliAODTrack::GetTOFBunchCrossing(Double_t b, Bool_t) const
800 // Returns the number of bunch crossings after trigger (assuming 25ns spacing)
801 const double kSpacing = 25e3; // min interbanch spacing
802 const double kShift = 0;
803 Int_t bcid = kTOFBCNA; // defualt one
804 if (!IsOn(kTOFout) || !IsOn(kESDpid)) return bcid; // no info
806 double tdif = GetTOFsignal();
807 if (IsOn(kTIME)) { // integrated time info is there
808 int pid = (int)GetMostProbablePID();
810 GetIntegratedTimes(ttimes);
813 else { // assume integrated time info from TOF radius and momentum
814 const double kRTOF = 385.;
815 const double kCSpeed = 3.e-2; // cm/ps
817 if (p<0.001) p = 1.0;
819 double path = kRTOF; // mean TOF radius
820 if (TMath::Abs(b)>kAlmost0) { // account for curvature
821 double curv = Pt()/(b*kB2C);
823 double tgl = Pz()/Pt();
824 path = 2./curv*TMath::ASin(kRTOF*curv/2.)*TMath::Sqrt(1.+tgl*tgl);
827 tdif -= path/kCSpeed*TMath::Sqrt(1.+m*m/(p*p));
829 bcid = TMath::Nint((tdif - kShift)/kSpacing);
833 void AliAODTrack::SetDetectorPID(const AliDetectorPID *pid)
836 // Set the detector PID
838 if (fDetectorPID) delete fDetectorPID;
843 //_____________________________________________________________________________
844 Double_t AliAODTrack::GetHMPIDsignal() const
846 if(fAODEvent->GetHMPIDringForTrackID(fID)) return fAODEvent->GetHMPIDringForTrackID(fID)->GetHmpSignal();
850 //_____________________________________________________________________________
851 Double_t AliAODTrack::GetHMPIDoccupancy() const
853 if(fAODEvent->GetHMPIDringForTrackID(fID)) return fAODEvent->GetHMPIDringForTrackID(fID)->GetHmpOccupancy();
857 //_____________________________________________________________________________
858 Int_t AliAODTrack::GetHMPIDcluIdx() const
860 if(fAODEvent->GetHMPIDringForTrackID(fID)) return fAODEvent->GetHMPIDringForTrackID(fID)->GetHmpCluIdx();
864 //_____________________________________________________________________________
865 void AliAODTrack::GetHMPIDtrk(Float_t &x, Float_t &y, Float_t &th, Float_t &ph) const
867 x = -999; y = -999.; th = -999.; ph = -999.;
869 const AliAODHMPIDrings *ring=fAODEvent->GetHMPIDringForTrackID(fID);
871 x = ring->GetHmpTrackX();
872 y = ring->GetHmpTrackY();
873 th = ring->GetHmpTrackTheta();
874 ph = ring->GetHmpTrackPhi();
878 //_____________________________________________________________________________
879 void AliAODTrack::GetHMPIDmip(Float_t &x,Float_t &y,Int_t &q, Int_t &nph) const
881 x = -999; y = -999.; q = -999; nph = -999;
883 const AliAODHMPIDrings *ring=fAODEvent->GetHMPIDringForTrackID(fID);
885 x = ring->GetHmpMipX();
886 y = ring->GetHmpMipY();
887 q = (Int_t)ring->GetHmpMipCharge();
888 nph = (Int_t)ring->GetHmpNumOfPhotonClusters();
892 //_____________________________________________________________________________
893 Bool_t AliAODTrack::GetOuterHmpPxPyPz(Double_t *p) const
895 if(fAODEvent->GetHMPIDringForTrackID(fID)) {fAODEvent->GetHMPIDringForTrackID(fID)->GetHmpMom(p); return kTRUE;}
899 //_____________________________________________________________________________
900 Bool_t AliAODTrack::GetXYZAt(Double_t x, Double_t b, Double_t *r) const
902 //---------------------------------------------------------------------
903 // This function returns the global track position extrapolated to
904 // the radial position "x" (cm) in the magnetic field "b" (kG)
905 //---------------------------------------------------------------------
907 //conversion of track parameter representation is
908 //based on the implementation of AliExternalTrackParam::Set(...)
909 //maybe some of this code can be moved to AliVTrack to avoid code duplication
911 Double_t radPos2 = fPosition[0]*fPosition[0]+fPosition[1]*fPosition[1];
912 Double_t radMax = 45.; // approximately ITS outer radius
913 if (radPos2 < radMax*radMax) { // inside the ITS
914 alpha = fMomentum[1]; //TMath::ATan2(fMomentum[1],fMomentum[0]); // fMom is pt,phi,theta!
915 } else { // outside the ITS
916 Float_t phiPos = TMath::Pi()+TMath::ATan2(-fPosition[1], -fPosition[0]);
918 TMath::DegToRad()*(20*((((Int_t)(phiPos*TMath::RadToDeg()))/20))+10);
921 // Get the vertex of origin and the momentum
922 TVector3 ver(fPosition[0],fPosition[1],fPosition[2]);
923 TVector3 mom(Px(),Py(),Pz());
925 // Rotate to the local coordinate system
929 Double_t param0 = ver.Y();
930 Double_t param1 = ver.Z();
931 Double_t param2 = TMath::Sin(mom.Phi());
932 Double_t param3 = mom.Pz()/mom.Pt();
933 Double_t param4 = TMath::Sign(1/mom.Pt(),(Double_t)fCharge);
935 //calculate the propagated coordinates
936 //this is based on AliExternalTrackParam::GetXYZAt(Double_t x, Double_t b, Double_t *r)
937 Double_t dx=x-ver.X();
938 if(TMath::Abs(dx)<=kAlmost0) return GetXYZ(r);
941 Double_t f2=f1 + dx*param4*b*kB2C;
943 if (TMath::Abs(f1) >= kAlmost1) return kFALSE;
944 if (TMath::Abs(f2) >= kAlmost1) return kFALSE;
946 Double_t r1=TMath::Sqrt((1.-f1)*(1.+f1)), r2=TMath::Sqrt((1.-f2)*(1.+f2));
948 r[1] = param0 + dx*(f1+f2)/(r1+r2);
949 r[2] = param1 + dx*(r2 + f2*(f1+f2)/(r1+r2))*param3;//Thanks to Andrea & Peter
950 return Local2GlobalPosition(r,alpha);
953 //_____________________________________________________________________________
954 Bool_t AliAODTrack::GetXYZatR(Double_t xr,Double_t bz, Double_t *xyz, Double_t* alpSect) const
956 // This method has 3 modes of behaviour
957 // 1) xyz[3] array is provided but alpSect pointer is 0: calculate the position of track intersection
958 // with circle of radius xr and fill it in xyz array
959 // 2) alpSect pointer is provided: find alpha of the sector where the track reaches local coordinate xr
960 // Note that in this case xr is NOT the radius but the local coordinate.
961 // If the xyz array is provided, it will be filled by track lab coordinates at local X in this sector
962 // 3) Neither alpSect nor xyz pointers are provided: just check if the track reaches radius xr
966 Double_t radPos2 = fPosition[0]*fPosition[0]+fPosition[1]*fPosition[1];
967 Double_t radMax = 45.; // approximately ITS outer radius
968 if (radPos2 < radMax*radMax) { // inside the ITS
969 alpha = fMomentum[1]; //TMath::ATan2(fMomentum[1],fMomentum[0]); // fMom is pt,phi,theta!
970 } else { // outside the ITS
971 Float_t phiPos = TMath::Pi()+TMath::ATan2(-fPosition[1], -fPosition[0]);
973 TMath::DegToRad()*(20*((((Int_t)(phiPos*TMath::RadToDeg()))/20))+10);
976 // Get the vertex of origin and the momentum
977 TVector3 ver(fPosition[0],fPosition[1],fPosition[2]);
978 TVector3 mom(Px(),Py(),Pz());
980 // Rotate to the local coordinate system
984 Double_t fx = ver.X();
985 Double_t fy = ver.Y();
986 Double_t fz = ver.Z();
987 Double_t sn = TMath::Sin(mom.Phi());
988 Double_t tgl = mom.Pz()/mom.Pt();
989 Double_t crv = TMath::Sign(1/mom.Pt(),(Double_t)fCharge)*bz*kB2C;
991 if ( (TMath::Abs(bz))<kAlmost0Field ) crv=0.;
993 // general circle parameterization:
994 // x = (r0+tR)cos(phi0) - tR cos(t+phi0)
995 // y = (r0+tR)sin(phi0) - tR sin(t+phi0)
996 // where qb is the sign of the curvature, tR is the track's signed radius and r0
997 // is the DCA of helix to origin
999 double tR = 1./crv; // track radius signed
1000 double cs = TMath::Sqrt((1-sn)*(1+sn));
1001 double x0 = fx - sn*tR; // helix center coordinates
1002 double y0 = fy + cs*tR;
1003 double phi0 = TMath::ATan2(y0,x0); // angle of PCA wrt to the origin
1004 if (tR<0) phi0 += TMath::Pi();
1005 if (phi0 > TMath::Pi()) phi0 -= 2.*TMath::Pi();
1006 else if (phi0 <-TMath::Pi()) phi0 += 2.*TMath::Pi();
1007 double cs0 = TMath::Cos(phi0);
1008 double sn0 = TMath::Sin(phi0);
1009 double r0 = x0*cs0 + y0*sn0 - tR; // DCA to origin
1010 double r2R = 1.+r0/tR;
1013 if (r2R<kAlmost0) return kFALSE; // helix is centered at the origin, no specific intersection with other concetric circle
1014 if (!xyz && !alpSect) return kTRUE;
1015 double xr2R = xr/tR;
1016 double r2Ri = 1./r2R;
1017 // the intersection cos(t) = [1 + (r0/tR+1)^2 - (r0/tR)^2]/[2(1+r0/tR)]
1018 double cosT = 0.5*(r2R + (1-xr2R*xr2R)*r2Ri);
1019 if ( TMath::Abs(cosT)>kAlmost1 ) {
1020 // printf("Does not reach : %f %f\n",r0,tR);
1021 return kFALSE; // track does not reach the radius xr
1024 double t = TMath::ACos(cosT);
1026 // intersection point
1028 xyzi[0] = x0 - tR*TMath::Cos(t+phi0);
1029 xyzi[1] = y0 - tR*TMath::Sin(t+phi0);
1030 if (xyz) { // if postition is requested, then z is needed:
1031 double t0 = TMath::ATan2(cs,-sn) - phi0;
1032 double z0 = fz - t0*tR*tgl;
1033 xyzi[2] = z0 + tR*t*tgl;
1037 Local2GlobalPosition(xyzi,alpha);
1046 double &alp = *alpSect;
1047 // determine the sector of crossing
1048 double phiPos = TMath::Pi()+TMath::ATan2(-xyzi[1],-xyzi[0]);
1049 int sect = ((Int_t)(phiPos*TMath::RadToDeg()))/20;
1050 alp = TMath::DegToRad()*(20*sect+10);
1051 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
1054 Double_t ca=TMath::Cos(alp-alpha), sa=TMath::Sin(alp-alpha);
1055 if ((cs*ca+sn*sa)<0) {
1056 AliDebug(1,Form("Rotation to target sector impossible: local cos(phi) would become %.2f",cs*ca+sn*sa));
1061 if (TMath::Abs(f1) >= kAlmost1) {
1062 AliDebug(1,Form("Rotation to target sector impossible: local sin(phi) would become %.2f",f1));
1066 double tmpX = fx*ca + fy*sa;
1067 double tmpY = -fx*sa + fy*ca;
1069 // estimate Y at X=xr
1073 if (TMath::Abs(f2) >= kAlmost1) {
1074 AliDebug(1,Form("Propagation in target sector failed ! %.10e",f2));
1077 r1 = TMath::Sqrt((1.-f1)*(1.+f1));
1078 r2 = TMath::Sqrt((1.-f2)*(1.+f2));
1079 dy2dx = (f1+f2)/(r1+r2);
1080 yloc = tmpY + dx*dy2dx;
1081 if (yloc>ylocMax) {alp += 2*TMath::Pi()/18; sect++;}
1082 else if (yloc<-ylocMax) {alp -= 2*TMath::Pi()/18; sect--;}
1084 if (alp >= TMath::Pi()) alp -= 2*TMath::Pi();
1085 else if (alp < -TMath::Pi()) alp += 2*TMath::Pi();
1086 // if (sect>=18) sect = 0;
1087 // if (sect<=0) sect = 17;
1090 // if alpha was requested, then recalculate the position at intersection in sector
1094 if (TMath::Abs(x2r)<0.05) xyz[2] = fz + dx*(r2 + f2*dy2dx)*tgl;
1096 // for small dx/R the linear apporximation of the arc by the segment is OK,
1097 // but at large dx/R the error is very large and leads to incorrect Z propagation
1098 // angle traversed delta = 2*asin(dist_start_end / R / 2), hence the arc is: R*deltaPhi
1099 // The dist_start_end is obtained from sqrt(dx^2+dy^2) = x/(r1+r2)*sqrt(2+f1*f2+r1*r2)
1100 // Similarly, the rotation angle in linear in dx only for dx<<R
1101 double chord = dx*TMath::Sqrt(1+dy2dx*dy2dx); // distance from old position to new one
1102 double rot = 2*TMath::ASin(0.5*chord*crv); // angular difference seen from the circle center
1103 xyz[2] = fz + rot/crv*tgl;
1105 Local2GlobalPosition(xyz,alp);
1112 //_______________________________________________________
1113 void AliAODTrack::GetITSdEdxSamples(Double_t s[4]) const
1115 // get ITS dedx samples
1116 if (!fDetPid) for (int i=4;i--;) s[i]=0;
1117 else for (int i=4;i--;) s[i] = fDetPid->GetITSdEdxSample(i);
1120 //_____________________________________________
1121 Double_t AliAODTrack::GetMassForTracking() const
1123 double m = AliPID::ParticleMass(fPIDForTracking);
1124 return (fPIDForTracking==AliPID::kHe3 || fPIDForTracking==AliPID::kAlpha) ? -m : m;
1126 //_______________________________________________________
1127 const AliTOFHeader* AliAODTrack::GetTOFHeader() const {
1128 return fAODEvent->GetTOFHeader();