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()
221 if (fPID) {delete[] fPID; fPID = 0;}
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 Int_t AliAODTrack::GetMuonTrigDevSign() const
640 /// Return the sign of the MTR deviation
642 Int_t signInfo = (Int_t)((fMUONtrigHitsMapTrg>>30)&0x3);
643 // Dummy value for old AODs which do not have the info
644 if ( signInfo == 0 ) return -999;
648 //______________________________________________________________________________
649 Bool_t AliAODTrack::PropagateToDCA(const AliVVertex *vtx,
650 Double_t b, Double_t maxd, Double_t dz[2], Double_t covar[3])
652 // compute impact parameters to the vertex vtx and their covariance matrix
653 // b is the Bz, needed to propagate correctly the track to vertex
654 // only the track parameters are update after the propagation (pos and mom),
655 // not the covariance matrix. This is OK for propagation over short distance
656 // inside the beam pipe.
657 // return kFALSE is something went wrong
659 // allowed only for tracks inside the beam pipe
660 Float_t xstart2 = fPosition[0]*fPosition[0]+fPosition[1]*fPosition[1];
661 if(xstart2 > 3.*3.) { // outside beampipe radius
662 AliError("This method can be used only for propagation inside the beam pipe");
666 // convert to AliExternalTrackParam
667 AliExternalTrackParam etp; etp.CopyFromVTrack(this);
670 if(!etp.PropagateToDCA(vtx,b,maxd,dz,covar)) return kFALSE;
672 // update track position and momentum
677 SetPosition(mom,kFALSE);
683 //______________________________________________________________________________
684 Bool_t AliAODTrack::GetPxPyPz(Double_t p[3]) const
686 //---------------------------------------------------------------------
687 // This function returns the global track momentum components
688 //---------------------------------------------------------------------
689 p[0]=Px(); p[1]=Py(); p[2]=Pz();
694 //_______________________________________________________________________
695 Float_t AliAODTrack::GetTPCClusterInfo(Int_t nNeighbours/*=3*/, Int_t type/*=0*/, Int_t row0, Int_t row1, Int_t bitType ) const
698 // TPC cluster information
699 // type 0: get fraction of found/findable clusters with neighbourhood definition
700 // 1: findable clusters with neighbourhood definition
703 // 0 - all cluster used
704 // 1 - clusters used for the kalman update
705 // definition of findable clusters:
706 // a cluster is defined as findable if there is another cluster
707 // within +- nNeighbours pad rows. The idea is to overcome threshold
708 // effects with a very simple algorithm.
714 Int_t last=-nNeighbours;
715 const TBits & clusterMap = (bitType%2==0) ? fTPCClusterMap : fTPCFitMap;
717 Int_t upperBound=clusterMap.GetNbits();
718 if (upperBound>row1) upperBound=row1;
719 for (Int_t i=row0; i<upperBound; ++i){
720 //look to current row
727 //look to nNeighbours before
728 if ((i-last)<=nNeighbours) {
732 //look to nNeighbours after
733 for (Int_t j=i+1; j<i+1+nNeighbours; ++j){
740 if (type==2) return found;
741 if (type==1) return findable;
746 fraction=(Float_t)found/(Float_t)findable;
751 return 0; // undefined type - default value
755 //______________________________________________________________________________
756 Double_t AliAODTrack::GetTRDslice(Int_t plane, Int_t slice) const {
758 // return TRD Pid information
760 if (!fDetPid) return -1;
761 Double32_t *trdSlices=fDetPid->GetTRDslices();
762 if (!trdSlices) return -1;
763 if ((plane<0) || (plane>=kTRDnPlanes)) {
767 Int_t ns=fDetPid->GetTRDnSlices();
768 if ((slice<-1) || (slice>=ns)) {
772 if(slice>=0) return trdSlices[plane*ns + slice];
774 // return average of the dEdx measurements
775 Double_t q=0.; Double32_t *s = &trdSlices[plane*ns];
776 for (Int_t i=0; i<ns; i++, s++) if((*s)>0.) q+=(*s);
780 //______________________________________________________________________________
781 UChar_t AliAODTrack::GetTRDntrackletsPID() const{
783 // return number of tracklets calculated from the slices
785 if(!fDetPid) return -1;
786 return fDetPid->GetTRDntrackletsPID();
789 //______________________________________________________________________________
790 UChar_t AliAODTrack::GetTRDncls(Int_t layer) const {
792 // return number of TRD clusters
794 if(!fDetPid || layer > 5) return -1;
795 if(layer < 0) return fDetPid->GetTRDncls();
796 else return fDetPid->GetTRDncls(layer);
799 //______________________________________________________________________________
800 Double_t AliAODTrack::GetTRDmomentum(Int_t plane, Double_t */*sp*/) const
802 //Returns momentum estimation
803 // in TRD layer "plane".
805 if (!fDetPid) return -1;
806 const Double_t *trdMomentum=fDetPid->GetTRDmomentum();
811 if ((plane<0) || (plane>=kTRDnPlanes)) {
815 return trdMomentum[plane];
818 //_______________________________________________________________________
819 Int_t AliAODTrack::GetTOFBunchCrossing(Double_t b, Bool_t) const
821 // Returns the number of bunch crossings after trigger (assuming 25ns spacing)
822 const double kSpacing = 25e3; // min interbanch spacing
823 const double kShift = 0;
824 Int_t bcid = kTOFBCNA; // defualt one
825 if (!IsOn(kTOFout) || !IsOn(kESDpid)) return bcid; // no info
827 double tdif = GetTOFsignal();
828 if (IsOn(kTIME)) { // integrated time info is there
829 int pid = (int)GetMostProbablePID();
831 GetIntegratedTimes(ttimes, pid>=AliPID::kSPECIES ? AliPID::kSPECIESC : AliPID::kSPECIES);
834 else { // assume integrated time info from TOF radius and momentum
835 const double kRTOF = 385.;
836 const double kCSpeed = 3.e-2; // cm/ps
838 if (p<0.001) p = 1.0;
840 double path = kRTOF; // mean TOF radius
841 if (TMath::Abs(b)>kAlmost0) { // account for curvature
842 double curv = Pt()/(b*kB2C);
844 double tgl = Pz()/Pt();
845 path = 2./curv*TMath::ASin(kRTOF*curv/2.)*TMath::Sqrt(1.+tgl*tgl);
848 tdif -= path/kCSpeed*TMath::Sqrt(1.+m*m/(p*p));
850 bcid = TMath::Nint((tdif - kShift)/kSpacing);
854 void AliAODTrack::SetDetectorPID(const AliDetectorPID *pid)
857 // Set the detector PID
859 if (fDetectorPID) delete fDetectorPID;
864 //_____________________________________________________________________________
865 Double_t AliAODTrack::GetHMPIDsignal() const
867 if(fAODEvent->GetHMPIDringForTrackID(fID)) return fAODEvent->GetHMPIDringForTrackID(fID)->GetHmpSignal();
871 //_____________________________________________________________________________
872 Double_t AliAODTrack::GetHMPIDoccupancy() const
874 if(fAODEvent->GetHMPIDringForTrackID(fID)) return fAODEvent->GetHMPIDringForTrackID(fID)->GetHmpOccupancy();
878 //_____________________________________________________________________________
879 Int_t AliAODTrack::GetHMPIDcluIdx() const
881 if(fAODEvent->GetHMPIDringForTrackID(fID)) return fAODEvent->GetHMPIDringForTrackID(fID)->GetHmpCluIdx();
885 //_____________________________________________________________________________
886 void AliAODTrack::GetHMPIDtrk(Float_t &x, Float_t &y, Float_t &th, Float_t &ph) const
888 x = -999; y = -999.; th = -999.; ph = -999.;
890 const AliAODHMPIDrings *ring=fAODEvent->GetHMPIDringForTrackID(fID);
892 x = ring->GetHmpTrackX();
893 y = ring->GetHmpTrackY();
894 th = ring->GetHmpTrackTheta();
895 ph = ring->GetHmpTrackPhi();
899 //_____________________________________________________________________________
900 void AliAODTrack::GetHMPIDmip(Float_t &x,Float_t &y,Int_t &q, Int_t &nph) const
902 x = -999; y = -999.; q = -999; nph = -999;
904 const AliAODHMPIDrings *ring=fAODEvent->GetHMPIDringForTrackID(fID);
906 x = ring->GetHmpMipX();
907 y = ring->GetHmpMipY();
908 q = (Int_t)ring->GetHmpMipCharge();
909 nph = (Int_t)ring->GetHmpNumOfPhotonClusters();
913 //_____________________________________________________________________________
914 Bool_t AliAODTrack::GetOuterHmpPxPyPz(Double_t *p) const
916 if(fAODEvent->GetHMPIDringForTrackID(fID)) {fAODEvent->GetHMPIDringForTrackID(fID)->GetHmpMom(p); return kTRUE;}
920 //_____________________________________________________________________________
921 Bool_t AliAODTrack::GetXYZAt(Double_t x, Double_t b, Double_t *r) const
923 //---------------------------------------------------------------------
924 // This function returns the global track position extrapolated to
925 // the radial position "x" (cm) in the magnetic field "b" (kG)
926 //---------------------------------------------------------------------
928 //conversion of track parameter representation is
929 //based on the implementation of AliExternalTrackParam::Set(...)
930 //maybe some of this code can be moved to AliVTrack to avoid code duplication
932 Double_t radPos2 = fPosition[0]*fPosition[0]+fPosition[1]*fPosition[1];
933 Double_t radMax = 45.; // approximately ITS outer radius
934 if (radPos2 < radMax*radMax) { // inside the ITS
935 alpha = fMomentum[1]; //TMath::ATan2(fMomentum[1],fMomentum[0]); // fMom is pt,phi,theta!
936 } else { // outside the ITS
937 Float_t phiPos = TMath::Pi()+TMath::ATan2(-fPosition[1], -fPosition[0]);
939 TMath::DegToRad()*(20*((((Int_t)(phiPos*TMath::RadToDeg()))/20))+10);
942 // Get the vertex of origin and the momentum
943 TVector3 ver(fPosition[0],fPosition[1],fPosition[2]);
944 TVector3 mom(Px(),Py(),Pz());
946 // Rotate to the local coordinate system
950 Double_t param0 = ver.Y();
951 Double_t param1 = ver.Z();
952 Double_t param2 = TMath::Sin(mom.Phi());
953 Double_t param3 = mom.Pz()/mom.Pt();
954 Double_t param4 = TMath::Sign(1/mom.Pt(),(Double_t)fCharge);
956 //calculate the propagated coordinates
957 //this is based on AliExternalTrackParam::GetXYZAt(Double_t x, Double_t b, Double_t *r)
958 Double_t dx=x-ver.X();
959 if(TMath::Abs(dx)<=kAlmost0) return GetXYZ(r);
962 Double_t f2=f1 + dx*param4*b*kB2C;
964 if (TMath::Abs(f1) >= kAlmost1) return kFALSE;
965 if (TMath::Abs(f2) >= kAlmost1) return kFALSE;
967 Double_t r1=TMath::Sqrt((1.-f1)*(1.+f1)), r2=TMath::Sqrt((1.-f2)*(1.+f2));
969 r[1] = param0 + dx*(f1+f2)/(r1+r2);
970 r[2] = param1 + dx*(r2 + f2*(f1+f2)/(r1+r2))*param3;//Thanks to Andrea & Peter
971 return Local2GlobalPosition(r,alpha);
974 //_____________________________________________________________________________
975 Bool_t AliAODTrack::GetXYZatR(Double_t xr,Double_t bz, Double_t *xyz, Double_t* alpSect) const
977 // This method has 3 modes of behaviour
978 // 1) xyz[3] array is provided but alpSect pointer is 0: calculate the position of track intersection
979 // with circle of radius xr and fill it in xyz array
980 // 2) alpSect pointer is provided: find alpha of the sector where the track reaches local coordinate xr
981 // Note that in this case xr is NOT the radius but the local coordinate.
982 // If the xyz array is provided, it will be filled by track lab coordinates at local X in this sector
983 // 3) Neither alpSect nor xyz pointers are provided: just check if the track reaches radius xr
987 Double_t radPos2 = fPosition[0]*fPosition[0]+fPosition[1]*fPosition[1];
988 Double_t radMax = 45.; // approximately ITS outer radius
989 if (radPos2 < radMax*radMax) { // inside the ITS
990 alpha = fMomentum[1]; //TMath::ATan2(fMomentum[1],fMomentum[0]); // fMom is pt,phi,theta!
991 } else { // outside the ITS
992 Float_t phiPos = TMath::Pi()+TMath::ATan2(-fPosition[1], -fPosition[0]);
994 TMath::DegToRad()*(20*((((Int_t)(phiPos*TMath::RadToDeg()))/20))+10);
997 // Get the vertex of origin and the momentum
998 TVector3 ver(fPosition[0],fPosition[1],fPosition[2]);
999 TVector3 mom(Px(),Py(),Pz());
1001 // Rotate to the local coordinate system
1002 ver.RotateZ(-alpha);
1003 mom.RotateZ(-alpha);
1005 Double_t fx = ver.X();
1006 Double_t fy = ver.Y();
1007 Double_t fz = ver.Z();
1008 Double_t sn = TMath::Sin(mom.Phi());
1009 Double_t tgl = mom.Pz()/mom.Pt();
1010 Double_t crv = TMath::Sign(1/mom.Pt(),(Double_t)fCharge)*bz*kB2C;
1012 if ( (TMath::Abs(bz))<kAlmost0Field ) crv=0.;
1014 // general circle parameterization:
1015 // x = (r0+tR)cos(phi0) - tR cos(t+phi0)
1016 // y = (r0+tR)sin(phi0) - tR sin(t+phi0)
1017 // where qb is the sign of the curvature, tR is the track's signed radius and r0
1018 // is the DCA of helix to origin
1020 double tR = 1./crv; // track radius signed
1021 double cs = TMath::Sqrt((1-sn)*(1+sn));
1022 double x0 = fx - sn*tR; // helix center coordinates
1023 double y0 = fy + cs*tR;
1024 double phi0 = TMath::ATan2(y0,x0); // angle of PCA wrt to the origin
1025 if (tR<0) phi0 += TMath::Pi();
1026 if (phi0 > TMath::Pi()) phi0 -= 2.*TMath::Pi();
1027 else if (phi0 <-TMath::Pi()) phi0 += 2.*TMath::Pi();
1028 double cs0 = TMath::Cos(phi0);
1029 double sn0 = TMath::Sin(phi0);
1030 double r0 = x0*cs0 + y0*sn0 - tR; // DCA to origin
1031 double r2R = 1.+r0/tR;
1034 if (r2R<kAlmost0) return kFALSE; // helix is centered at the origin, no specific intersection with other concetric circle
1035 if (!xyz && !alpSect) return kTRUE;
1036 double xr2R = xr/tR;
1037 double r2Ri = 1./r2R;
1038 // the intersection cos(t) = [1 + (r0/tR+1)^2 - (r0/tR)^2]/[2(1+r0/tR)]
1039 double cosT = 0.5*(r2R + (1-xr2R*xr2R)*r2Ri);
1040 if ( TMath::Abs(cosT)>kAlmost1 ) {
1041 // printf("Does not reach : %f %f\n",r0,tR);
1042 return kFALSE; // track does not reach the radius xr
1045 double t = TMath::ACos(cosT);
1047 // intersection point
1049 xyzi[0] = x0 - tR*TMath::Cos(t+phi0);
1050 xyzi[1] = y0 - tR*TMath::Sin(t+phi0);
1051 if (xyz) { // if postition is requested, then z is needed:
1052 double t0 = TMath::ATan2(cs,-sn) - phi0;
1053 double z0 = fz - t0*tR*tgl;
1054 xyzi[2] = z0 + tR*t*tgl;
1058 Local2GlobalPosition(xyzi,alpha);
1067 double &alp = *alpSect;
1068 // determine the sector of crossing
1069 double phiPos = TMath::Pi()+TMath::ATan2(-xyzi[1],-xyzi[0]);
1070 int sect = ((Int_t)(phiPos*TMath::RadToDeg()))/20;
1071 alp = TMath::DegToRad()*(20*sect+10);
1072 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
1075 Double_t ca=TMath::Cos(alp-alpha), sa=TMath::Sin(alp-alpha);
1076 if ((cs*ca+sn*sa)<0) {
1077 AliDebug(1,Form("Rotation to target sector impossible: local cos(phi) would become %.2f",cs*ca+sn*sa));
1082 if (TMath::Abs(f1) >= kAlmost1) {
1083 AliDebug(1,Form("Rotation to target sector impossible: local sin(phi) would become %.2f",f1));
1087 double tmpX = fx*ca + fy*sa;
1088 double tmpY = -fx*sa + fy*ca;
1090 // estimate Y at X=xr
1094 if (TMath::Abs(f2) >= kAlmost1) {
1095 AliDebug(1,Form("Propagation in target sector failed ! %.10e",f2));
1098 r1 = TMath::Sqrt((1.-f1)*(1.+f1));
1099 r2 = TMath::Sqrt((1.-f2)*(1.+f2));
1100 dy2dx = (f1+f2)/(r1+r2);
1101 yloc = tmpY + dx*dy2dx;
1102 if (yloc>ylocMax) {alp += 2*TMath::Pi()/18; sect++;}
1103 else if (yloc<-ylocMax) {alp -= 2*TMath::Pi()/18; sect--;}
1105 if (alp >= TMath::Pi()) alp -= 2*TMath::Pi();
1106 else if (alp < -TMath::Pi()) alp += 2*TMath::Pi();
1107 // if (sect>=18) sect = 0;
1108 // if (sect<=0) sect = 17;
1111 // if alpha was requested, then recalculate the position at intersection in sector
1115 if (TMath::Abs(x2r)<0.05) xyz[2] = fz + dx*(r2 + f2*dy2dx)*tgl;
1117 // for small dx/R the linear apporximation of the arc by the segment is OK,
1118 // but at large dx/R the error is very large and leads to incorrect Z propagation
1119 // angle traversed delta = 2*asin(dist_start_end / R / 2), hence the arc is: R*deltaPhi
1120 // The dist_start_end is obtained from sqrt(dx^2+dy^2) = x/(r1+r2)*sqrt(2+f1*f2+r1*r2)
1121 // Similarly, the rotation angle in linear in dx only for dx<<R
1122 double chord = dx*TMath::Sqrt(1+dy2dx*dy2dx); // distance from old position to new one
1123 double rot = 2*TMath::ASin(0.5*chord*crv); // angular difference seen from the circle center
1124 xyz[2] = fz + rot/crv*tgl;
1126 Local2GlobalPosition(xyz,alp);
1133 //_______________________________________________________
1134 void AliAODTrack::GetITSdEdxSamples(Double_t s[4]) const
1136 // get ITS dedx samples
1137 if (!fDetPid) for (int i=4;i--;) s[i]=0;
1138 else for (int i=4;i--;) s[i] = fDetPid->GetITSdEdxSample(i);
1141 //_____________________________________________
1142 Double_t AliAODTrack::GetMassForTracking() const
1144 int pid = fPIDForTracking;
1145 if (pid<AliPID::kPion) pid = AliPID::kPion;
1146 double m = AliPID::ParticleMass(fPIDForTracking);
1147 return (fPIDForTracking==AliPID::kHe3 || fPIDForTracking==AliPID::kAlpha) ? -m : m;
1149 //_______________________________________________________
1150 const AliTOFHeader* AliAODTrack::GetTOFHeader() const {
1151 return fAODEvent->GetTOFHeader();
1153 //_______________________________________________________
1154 Int_t AliAODTrack::GetNcls(Int_t idet) const
1156 // Get number of clusters by subdetector index
1161 ncls = GetITSNcls();
1164 ncls = (Int_t)GetTPCNcls();
1167 ncls = (Int_t)GetTRDncls();
1171 /*if (fTOFindex != -1)
1178 if ((GetHMPIDcluIdx() >= 0) && (GetHMPIDcluIdx() < 7000000)) {
1179 if ((GetHMPIDcluIdx()%1000000 != 9999) && (GetHMPIDcluIdx()%1000000 != 99999)) {