#include <TMath.h>
#include <TParticle.h>
#include <TDatabasePDG.h>
+#include <TMatrixD.h>
#include "AliESDVertex.h"
#include "AliESDtrack.h"
#include "AliLog.h"
#include "AliTrackPointArray.h"
#include "TPolyMarker3D.h"
+#include "AliTrackerBase.h"
+#include "AliTPCdEdxInfo.h"
+#include "AliDetectorPID.h"
+#include "TTreeStream.h"
+#include "TObjArray.h"
ClassImp(AliESDtrack)
fOp(0),
fHMPIDp(0),
fFriendTrack(NULL),
+ fTPCFitMap(159),//number of padrows
fTPCClusterMap(159),//number of padrows
fTPCSharedMap(159),//number of padrows
fFlags(0),
fITSLabel(0),
fTPCLabel(0),
fTRDLabel(0),
+ fTOFLabel(NULL),
fTOFCalChannel(-1),
fTOFindex(-1),
fHMPIDqn(0),
fHMPIDcluIdx(-1),
fCaloIndex(kEMCALNoMatch),
+ fMassForTracking(0.13957),
fHMPIDtrkTheta(0),
fHMPIDtrkPhi(0),
fHMPIDsignal(0),
+ fTrackTime(0),
fTrackLength(0),
fdTPC(0),fzTPC(0),
fCddTPC(0),fCdzTPC(0),fCzzTPC(0),
fGlobalChi2(0),
fITSsignal(0),
fTPCsignal(0),
+ fTPCsignalTuned(0),
fTPCsignalS(0),
+ fTPCdEdxInfo(0),
fTRDsignal(0),
fTRDQuality(0),
fTRDBudget(0),
fTOFsignal(99999),
+ fTOFsignalTuned(99999),
fTOFsignalToT(99999),
fTOFsignalRaw(99999),
fTOFsignalDz(999),
fTRDncls(0),
fTRDncls0(0),
fTRDntracklets(0),
+ fTRDNchamberdEdx(0),
+ fTRDNclusterdEdx(0),
fTRDnSlices(0),
fTRDslices(0x0),
fVertexID(-2),// -2 means an orphan track
- fESDEvent(0)
+ fESDEvent(0),
+ fCacheNCrossedRows(-10),
+ fCacheChi2TPCConstrainedVsGlobal(-10),
+ fCacheChi2TPCConstrainedVsGlobalVertex(0),
+ fDetectorPID(0x0),
+ fTrackPhiOnEMCal(-999),
+ fTrackEtaOnEMCal(-999),
+ fTrackPtOnEMCal(-999),
+ fNtofClusters(0),
+ fTOFcluster(NULL)
{
//
// The default ESD constructor
Int_t i;
for (i=kNITSchi2Std;i--;) fITSchi2Std[i] = 0;
- for (i=0; i<AliPID::kSPECIES; i++) {
- fTrackTime[i]=0.;
- fR[i]=0.;
- fITSr[i]=0.;
- fTPCr[i]=0.;
- fTRDr[i]=0.;
- fTOFr[i]=0.;
- fHMPIDr[i]=0.;
- }
+ for (i=0; i<AliPID::kSPECIES; i++) fR[i]=fITSr[i]=fTPCr[i]=fTRDr[i]=fTOFr[i]=fHMPIDr[i]=0.;
for (i=0; i<3; i++) { fKinkIndexes[i]=0;}
for (i=0; i<3; i++) { fV0Indexes[i]=0;}
}
for (i=0;i<4;i++) {fITSdEdxSamples[i]=0.;}
for (i=0;i<4;i++) {fTPCPoints[i]=0;}
- for (i=0;i<3;i++) {fTOFLabel[i]=-1;}
for (i=0;i<10;i++) {fTOFInfo[i]=0;}
for (i=0;i<12;i++) {fITSModule[i]=-1;}
}
fOp(0),
fHMPIDp(0),
fFriendTrack(0),
+ fTPCFitMap(track.fTPCFitMap),
fTPCClusterMap(track.fTPCClusterMap),
fTPCSharedMap(track.fTPCSharedMap),
fFlags(track.fFlags),
fITSLabel(track.fITSLabel),
fTPCLabel(track.fTPCLabel),
fTRDLabel(track.fTRDLabel),
+ fTOFLabel(NULL),
fTOFCalChannel(track.fTOFCalChannel),
fTOFindex(track.fTOFindex),
fHMPIDqn(track.fHMPIDqn),
fHMPIDcluIdx(track.fHMPIDcluIdx),
fCaloIndex(track.fCaloIndex),
+ fMassForTracking(track.fMassForTracking),
fHMPIDtrkTheta(track.fHMPIDtrkTheta),
fHMPIDtrkPhi(track.fHMPIDtrkPhi),
fHMPIDsignal(track.fHMPIDsignal),
+ fTrackTime(NULL),
fTrackLength(track.fTrackLength),
fdTPC(track.fdTPC),fzTPC(track.fzTPC),
fCddTPC(track.fCddTPC),fCdzTPC(track.fCdzTPC),fCzzTPC(track.fCzzTPC),
fGlobalChi2(track.fGlobalChi2),
fITSsignal(track.fITSsignal),
fTPCsignal(track.fTPCsignal),
+ fTPCsignalTuned(track.fTPCsignalTuned),
fTPCsignalS(track.fTPCsignalS),
+ fTPCdEdxInfo(0),
fTRDsignal(track.fTRDsignal),
fTRDQuality(track.fTRDQuality),
fTRDBudget(track.fTRDBudget),
fTOFsignal(track.fTOFsignal),
+ fTOFsignalTuned(track.fTOFsignalTuned),
fTOFsignalToT(track.fTOFsignalToT),
fTOFsignalRaw(track.fTOFsignalRaw),
fTOFsignalDz(track.fTOFsignalDz),
fTRDncls(track.fTRDncls),
fTRDncls0(track.fTRDncls0),
fTRDntracklets(track.fTRDntracklets),
+ fTRDNchamberdEdx(track.fTRDNchamberdEdx),
+ fTRDNclusterdEdx(track.fTRDNclusterdEdx),
fTRDnSlices(track.fTRDnSlices),
fTRDslices(0x0),
fVertexID(track.fVertexID),
- fESDEvent(track.fESDEvent)
+ fESDEvent(track.fESDEvent),
+ fCacheNCrossedRows(track.fCacheNCrossedRows),
+ fCacheChi2TPCConstrainedVsGlobal(track.fCacheChi2TPCConstrainedVsGlobal),
+ fCacheChi2TPCConstrainedVsGlobalVertex(track.fCacheChi2TPCConstrainedVsGlobalVertex),
+ fDetectorPID(0x0),
+ fTrackPhiOnEMCal(track.fTrackPhiOnEMCal),
+ fTrackEtaOnEMCal(track.fTrackEtaOnEMCal),
+ fTrackPtOnEMCal(track.fTrackPtOnEMCal),
+ fNtofClusters(track.fNtofClusters),
+ fTOFcluster(NULL)
{
//
//copy constructor
//
- for (Int_t i=kNITSchi2Std;i--;) fITSchi2Std[i] = track.fTrackTime[i];
- for (Int_t i=0;i<AliPID::kSPECIES;i++) fTrackTime[i]=track.fTrackTime[i];
+ for (Int_t i=kNITSchi2Std;i--;) fITSchi2Std[i] = track.fITSchi2Std[i];
+
+ if(track.fTrackTime){
+ fTrackTime = new Double32_t[AliPID::kSPECIESC];
+ for (Int_t i=0;i<AliPID::kSPECIESC;i++) fTrackTime[i]=track.fTrackTime[i];
+ }
+
for (Int_t i=0;i<AliPID::kSPECIES;i++) fR[i]=track.fR[i];
//
for (Int_t i=0;i<AliPID::kSPECIES;i++) fITSr[i]=track.fITSr[i];
for (Int_t i=0; i<fTRDnSlices; i++) fTRDslices[i]=track.fTRDslices[i];
}
+ if (track.fDetectorPID) fDetectorPID = new AliDetectorPID(*track.fDetectorPID);
+
for (Int_t i=0;i<AliPID::kSPECIES;i++) fTRDr[i]=track.fTRDr[i];
for (Int_t i=0;i<AliPID::kSPECIES;i++) fTOFr[i]=track.fTOFr[i];
- for (Int_t i=0;i<3;i++) fTOFLabel[i]=track.fTOFLabel[i];
+ if(track.fTOFLabel){
+ if(!fTOFLabel) fTOFLabel = new Int_t[3];
+ for (Int_t i=0;i<3;i++) fTOFLabel[i]=track.fTOFLabel[i];
+ }
+
for (Int_t i=0;i<10;i++) fTOFInfo[i]=track.fTOFInfo[i];
for (Int_t i=0;i<12;i++) fITSModule[i]=track.fITSModule[i];
for (Int_t i=0;i<AliPID::kSPECIES;i++) fHMPIDr[i]=track.fHMPIDr[i];
if (track.fTPCInner) fTPCInner=new AliExternalTrackParam(*track.fTPCInner);
if (track.fOp) fOp=new AliExternalTrackParam(*track.fOp);
if (track.fHMPIDp) fHMPIDp=new AliExternalTrackParam(*track.fHMPIDp);
+ if (track.fTPCdEdxInfo) fTPCdEdxInfo = new AliTPCdEdxInfo(*track.fTPCdEdxInfo);
+
if (track.fFriendTrack) fFriendTrack=new AliESDfriendTrack(*(track.fFriendTrack));
+
+ if(fNtofClusters > 0){
+ fTOFcluster = new Int_t[fNtofClusters];
+ for(Int_t i=0;i < fNtofClusters;i++) fTOFcluster[i] = track.fTOFcluster[i];
+ }
}
//_______________________________________________________________________
fOp(0),
fHMPIDp(0),
fFriendTrack(0),
+ fTPCFitMap(159),//number of padrows
fTPCClusterMap(159),//number of padrows
fTPCSharedMap(159),//number of padrows
fFlags(0),
fITSLabel(0),
fTPCLabel(0),
fTRDLabel(0),
+ fTOFLabel(NULL),
fTOFCalChannel(-1),
fTOFindex(-1),
fHMPIDqn(0),
fHMPIDcluIdx(-1),
fCaloIndex(kEMCALNoMatch),
+ fMassForTracking(0.13957),
fHMPIDtrkTheta(0),
fHMPIDtrkPhi(0),
fHMPIDsignal(0),
+ fTrackTime(NULL),
fTrackLength(0),
fdTPC(0),fzTPC(0),
fCddTPC(0),fCdzTPC(0),fCzzTPC(0),
fGlobalChi2(0),
fITSsignal(0),
fTPCsignal(0),
+ fTPCsignalTuned(0),
fTPCsignalS(0),
+ fTPCdEdxInfo(0),
fTRDsignal(0),
fTRDQuality(0),
fTRDBudget(0),
fTOFsignal(99999),
+ fTOFsignalTuned(99999),
fTOFsignalToT(99999),
fTOFsignalRaw(99999),
fTOFsignalDz(999),
fTRDncls(0),
fTRDncls0(0),
fTRDntracklets(0),
+ fTRDNchamberdEdx(0),
+ fTRDNclusterdEdx(0),
fTRDnSlices(0),
fTRDslices(0x0),
fVertexID(-2), // -2 means an orphan track
- fESDEvent(0)
+ fESDEvent(0),
+ fCacheNCrossedRows(-10),
+ fCacheChi2TPCConstrainedVsGlobal(-10),
+ fCacheChi2TPCConstrainedVsGlobalVertex(0),
+ fDetectorPID(0x0),
+ fTrackPhiOnEMCal(-999),
+ fTrackEtaOnEMCal(-999),
+ fTrackPtOnEMCal(-999),
+ fNtofClusters(0),
+ fTOFcluster(NULL)
{
//
// ESD track from AliVTrack.
// Reset all the arrays
Int_t i;
for (i=kNITSchi2Std;i--;) fITSchi2Std[i] = 0;
- for (i=0; i<AliPID::kSPECIES; i++) {
- fTrackTime[i]=0.;
- fR[i]=0.;
- fITSr[i]=0.;
- fTPCr[i]=0.;
- fTRDr[i]=0.;
- fTOFr[i]=0.;
- fHMPIDr[i]=0.;
- }
+ for (i=0; i<AliPID::kSPECIES; i++) fR[i]=fITSr[i]=fTPCr[i]=fTRDr[i]=fTOFr[i]=fHMPIDr[i]=0.;
for (i=0; i<3; i++) { fKinkIndexes[i]=0;}
for (i=0; i<3; i++) { fV0Indexes[i]=-1;}
}
for (i=0;i<4;i++) {fITSdEdxSamples[i]=0.;}
for (i=0;i<4;i++) {fTPCPoints[i]=0;}
- for (i=0;i<3;i++) {fTOFLabel[i]=-1;}
for (i=0;i<10;i++) {fTOFInfo[i]=0;}
for (i=0;i<12;i++) {fITSModule[i]=-1;}
// Set TPC ncls
fTPCncls=track->GetTPCNcls();
-
-
+ fTPCnclsF=track->GetTPCNclsF();
+ // TPC cluster maps
+ const TBits* bmap = track->GetTPCClusterMapPtr();
+ if (bmap) SetTPCClusterMap(*bmap);
+ bmap = GetTPCFitMapPtr();
+ if (bmap) SetTPCFitMap(*bmap);
+ bmap = GetTPCSharedMapPtr();
+ if (bmap) SetTPCSharedMap(*bmap);
+ //
// Set the combined PID
const Double_t *pid = track->PID();
- if(pid){
- for (i=0; i<AliPID::kSPECIES; i++) fR[i]=pid[i];
- }
+ if(pid) for (i=0; i<AliPID::kSPECIES; i++) fR[i]=pid[i];
+ //
+ // calo matched cluster id
+ SetEMCALcluster(track->GetEMCALcluster());
// AliESD track label
+ //
+ // PID info
+ fITSsignal = track->GetITSsignal();
+ double itsdEdx[4];
+ track->GetITSdEdxSamples(itsdEdx);
+ SetITSdEdxSamples(itsdEdx);
+ //
+ SetTPCsignal(track->GetTPCsignal(),fTPCsignalS,track->GetTPCsignalN()); // No signalS in AODPi
+ AliTPCdEdxInfo * dEdxInfo = track->GetTPCdEdxInfo();
+ if (dEdxInfo) SetTPCdEdxInfo(new AliTPCdEdxInfo(*dEdxInfo));
+ //
+ SetTRDsignal(track->GetTRDsignal());
+ int ntrdsl = track->GetNumberOfTRDslices();
+ if (ntrdsl>0) {
+ SetNumberOfTRDslices((ntrdsl+2)*kTRDnPlanes);
+ for (int ipl=kTRDnPlanes;ipl--;){
+ for (int isl=ntrdsl;isl--;) SetTRDslice(track->GetTRDslice(ipl,isl),ipl,isl);
+ Double_t sp, p = track->GetTRDmomentum(ipl, &sp);
+ SetTRDmomentum(p, ipl, &sp);
+ }
+ }
+ //
+ fTRDncls = track->GetTRDncls();
+ fTRDntracklets &= 0xff & track->GetTRDntrackletsPID();
+ fTRDchi2 = track->GetTRDchi2();
+ //
+ SetTOFsignal(track->GetTOFsignal());
+ Double_t expt[AliPID::kSPECIESC];
+ track->GetIntegratedTimes(expt);
+ SetIntegratedTimes(expt);
+ //
+ SetTrackPhiEtaPtOnEMCal(track->GetTrackPhiOnEMCal(),track->GetTrackEtaOnEMCal(),track->GetTrackPtOnEMCal());
+ //
SetLabel(track->GetLabel());
// Set the status
SetStatus(track->GetStatus());
fOp(0),
fHMPIDp(0),
fFriendTrack(0),
+ fTPCFitMap(159),//number of padrows
fTPCClusterMap(159),//number of padrows
fTPCSharedMap(159),//number of padrows
fFlags(0),
fITSLabel(0),
fTPCLabel(0),
fTRDLabel(0),
+ fTOFLabel(NULL),
fTOFCalChannel(-1),
fTOFindex(-1),
fHMPIDqn(0),
fHMPIDcluIdx(-1),
fCaloIndex(kEMCALNoMatch),
+ fMassForTracking(0.13957),
fHMPIDtrkTheta(0),
fHMPIDtrkPhi(0),
fHMPIDsignal(0),
+ fTrackTime(NULL),
fTrackLength(0),
fdTPC(0),fzTPC(0),
fCddTPC(0),fCdzTPC(0),fCzzTPC(0),
fGlobalChi2(0),
fITSsignal(0),
fTPCsignal(0),
+ fTPCsignalTuned(0),
fTPCsignalS(0),
+ fTPCdEdxInfo(0),
fTRDsignal(0),
fTRDQuality(0),
fTRDBudget(0),
fTOFsignal(99999),
+ fTOFsignalTuned(99999),
fTOFsignalToT(99999),
fTOFsignalRaw(99999),
fTOFsignalDz(999),
fTRDncls(0),
fTRDncls0(0),
fTRDntracklets(0),
+ fTRDNchamberdEdx(0),
+ fTRDNclusterdEdx(0),
fTRDnSlices(0),
fTRDslices(0x0),
fVertexID(-2), // -2 means an orphan track
- fESDEvent(0)
+ fESDEvent(0),
+ fCacheNCrossedRows(-10),
+ fCacheChi2TPCConstrainedVsGlobal(-10),
+ fCacheChi2TPCConstrainedVsGlobalVertex(0),
+ fDetectorPID(0x0),
+ fTrackPhiOnEMCal(-999),
+ fTrackEtaOnEMCal(-999),
+ fTrackPtOnEMCal(-999),
+ fNtofClusters(0),
+ fTOFcluster(NULL)
{
//
// ESD track from TParticle
// Reset all the arrays
Int_t i;
for (i=kNITSchi2Std;i--;) fITSchi2Std[i] = 0;
- for (i=0; i<AliPID::kSPECIES; i++) {
- fTrackTime[i]=0.;
- fR[i]=0.;
- fITSr[i]=0.;
- fTPCr[i]=0.;
- fTRDr[i]=0.;
- fTOFr[i]=0.;
- fHMPIDr[i]=0.;
- }
+ for (i=0; i<AliPID::kSPECIES; i++) fR[i]=fITSr[i]=fTPCr[i]=fTRDr[i]=fTOFr[i]=fHMPIDr[i]=0.;
for (i=0; i<3; i++) { fKinkIndexes[i]=0;}
for (i=0; i<3; i++) { fV0Indexes[i]=-1;}
}
for (i=0;i<4;i++) {fITSdEdxSamples[i]=0.;}
for (i=0;i<4;i++) {fTPCPoints[i]=0;}
- for (i=0;i<3;i++) {fTOFLabel[i]=-1;}
for (i=0;i<10;i++) {fTOFInfo[i]=0;}
for (i=0;i<12;i++) {fITSModule[i]=-1;}
// Set the PID
Int_t indexPID = 99;
+ if (pdgCode<0) pdgCode = -pdgCode;
+ for (i=0;i<AliPID::kSPECIES;i++) if (pdgCode==AliPID::ParticleCode(i)) {indexPID = i; break;}
- switch (TMath::Abs(pdgCode)) {
-
- case 11: // electron
- indexPID = 0;
- break;
-
- case 13: // muon
- indexPID = 1;
- break;
-
- case 211: // pion
- indexPID = 2;
- break;
-
- case 321: // kaon
- indexPID = 3;
- break;
-
- case 2212: // proton
- indexPID = 4;
- break;
-
- default:
- break;
- }
-
- // If the particle is not e,mu,pi,K or p the PID probabilities are set to 0
+ // If the particle is not valid charged the PID probabilities are set to 0
if (indexPID < AliPID::kSPECIES) {
fR[indexPID]=1.;
fITSr[indexPID]=1.;
delete fOp;
delete fHMPIDp;
delete fCp;
- if (fFriendTrack) delete fFriendTrack;
- fFriendTrack=NULL;
+ delete fFriendTrack;
+ delete fTPCdEdxInfo;
if(fTRDnSlices)
delete[] fTRDslices;
+
+ //Reset cached values - needed for TClonesArray in AliESDInputHandler
+ fCacheNCrossedRows = -10.;
+ fCacheChi2TPCConstrainedVsGlobal = -10.;
+ if(fCacheChi2TPCConstrainedVsGlobalVertex) fCacheChi2TPCConstrainedVsGlobalVertex = 0;
+
+ if(fTOFcluster)
+ delete[] fTOFcluster;
+ fTOFcluster = NULL;
+ fNtofClusters=0;
+
+ delete fDetectorPID;
+
+ if(fTrackTime) delete[] fTrackTime;
+ if(fTOFLabel) delete[] fTOFLabel;
}
AliESDtrack &AliESDtrack::operator=(const AliESDtrack &source){
}
else{
// no track param delete the old one
- if(fCp)delete fCp;
+ delete fCp;
fCp = 0;
}
}
else{
// no track param delete the old one
- if(fIp)delete fIp;
+ delete fIp;
fIp = 0;
}
}
else{
// no track param delete the old one
- if(fTPCInner)delete fTPCInner;
+ delete fTPCInner;
fTPCInner = 0;
}
+ if(source.fTPCdEdxInfo) {
+ if(fTPCdEdxInfo) *fTPCdEdxInfo = *source.fTPCdEdxInfo;
+ fTPCdEdxInfo = new AliTPCdEdxInfo(*source.fTPCdEdxInfo);
+ }
if(source.fOp){
// we have the trackparam: assign or copy construct
}
else{
// no track param delete the old one
- if(fOp)delete fOp;
+ delete fOp;
fOp = 0;
}
}
else{
// no track param delete the old one
- if(fHMPIDp)delete fHMPIDp;
+ delete fHMPIDp;
fHMPIDp = 0;
}
-
// copy also the friend track
// use copy constructor
if(source.fFriendTrack){
delete fFriendTrack; fFriendTrack= 0;
}
+ fTPCFitMap = source.fTPCFitMap;
fTPCClusterMap = source.fTPCClusterMap;
fTPCSharedMap = source.fTPCSharedMap;
// the simple stuff
}
fTPCLabel = source.fTPCLabel;
fTRDLabel = source.fTRDLabel;
- for(int i = 0; i< 3;++i){
- fTOFLabel[i] = source.fTOFLabel[i];
+ if(source.fTOFLabel){
+ if(!fTOFLabel) fTOFLabel = new Int_t[3];
+ for(int i = 0; i< 3;++i){
+ fTOFLabel[i] = source.fTOFLabel[i];
+ }
}
fTOFCalChannel = source.fTOFCalChannel;
fTOFindex = source.fTOFindex;
fTRDr[i] = source.fTRDr[i];
fTOFr[i] = source.fTOFr[i];
fHMPIDr[i] = source.fHMPIDr[i];
- fTrackTime[i] = source.fTrackTime[i];
}
+
+ fMassForTracking = source.fMassForTracking;
fHMPIDtrkTheta = source.fHMPIDtrkTheta;
fHMPIDtrkPhi = source.fHMPIDtrkPhi;
fHMPIDsignal = source.fHMPIDsignal;
+ if(fTrackTime){
+ delete[] fTrackTime;
+ }
+ if(source.fTrackTime){
+ fTrackTime = new Double32_t[AliPID::kSPECIESC];
+ for(Int_t i=0;i < AliPID::kSPECIESC;i++)
+ fTrackTime[i] = source.fTrackTime[i];
+ }
+
fTrackLength = source. fTrackLength;
fdTPC = source.fdTPC;
fzTPC = source.fzTPC;
fITSsignal = source.fITSsignal;
for (Int_t i=0;i<4;i++) {fITSdEdxSamples[i]=source.fITSdEdxSamples[i];}
fTPCsignal = source.fTPCsignal;
+ fTPCsignalTuned = source.fTPCsignalTuned;
fTPCsignalS = source.fTPCsignalS;
for(int i = 0; i< 4;++i){
fTPCPoints[i] = source.fTPCPoints[i];
}
fTRDsignal = source.fTRDsignal;
+ fTRDNchamberdEdx = source.fTRDNchamberdEdx;
+ fTRDNclusterdEdx = source.fTRDNclusterdEdx;
for(int i = 0;i < kTRDnPlanes;++i){
fTRDTimBin[i] = source.fTRDTimBin[i];
fTRDQuality = source.fTRDQuality;
fTRDBudget = source.fTRDBudget;
fTOFsignal = source.fTOFsignal;
+ fTOFsignalTuned = source.fTOFsignalTuned;
fTOFsignalToT = source.fTOFsignalToT;
fTOFsignalRaw = source.fTOFsignalRaw;
fTOFsignalDz = source.fTOFsignalDz;
fTRDncls0 = source.fTRDncls0;
fTRDntracklets = source.fTRDntracklets;
fVertexID = source.fVertexID;
+
+ fCacheNCrossedRows = source.fCacheNCrossedRows;
+ fCacheChi2TPCConstrainedVsGlobal = source.fCacheChi2TPCConstrainedVsGlobal;
+ fCacheChi2TPCConstrainedVsGlobalVertex = source.fCacheChi2TPCConstrainedVsGlobalVertex;
+
+ delete fDetectorPID;
+ fDetectorPID=0x0;
+ if (source.fDetectorPID) fDetectorPID = new AliDetectorPID(*source.fDetectorPID);
+
+ fTrackPhiOnEMCal= source.fTrackPhiOnEMCal;
+ fTrackEtaOnEMCal= source.fTrackEtaOnEMCal;
+ fTrackPtOnEMCal= source.fTrackPtOnEMCal;
+
+ if(fTOFcluster){
+ delete[] fTOFcluster;
+ }
+ fNtofClusters = source.fNtofClusters;
+ if(fNtofClusters > 0){
+ fTOFcluster = new Int_t[fNtofClusters];
+ for(Int_t i=0;i < fNtofClusters;i++) fTOFcluster[i] = source.fTOFcluster[i];
+ }
+
return *this;
}
track.fTPCchi2 = fTPCchi2;
track.fTPCchi2Iter1 = fTPCchi2Iter1;
track.fTPCsignal = fTPCsignal;
+ track.fTPCsignalTuned = fTPCsignalTuned;
track.fTPCsignalS = fTPCsignalS;
for(int i = 0;i<4;++i)track.fTPCPoints[i] = fTPCPoints[i];
// combined PID is TPC only!
track.fR[i] = fTPCr[i];
}
+ track.fTPCFitMap = fTPCFitMap;
track.fTPCClusterMap = fTPCClusterMap;
track.fTPCSharedMap = fTPCSharedMap;
fTrackLength = 0;
- for (Int_t i=0;i<AliPID::kSPECIES;i++) fTrackTime[i] = 0;
+ if(fTrackTime)
+ for (Int_t i=0;i<AliPID::kSPECIESC;i++) fTrackTime[i] = 0;
// Reset track parameters constrained to the primary vertex
delete fCp;fCp = 0;
fTPCncls = 0;
fTPCnclsF = 0;
fTPCnclsIter1 = 0;
- fTPCnclsFIter1 = 0;
+ fTPCnclsFIter1 = 0;
+ fTPCFitMap = 0;
fTPCClusterMap = 0;
fTPCSharedMap = 0;
fTPCsignal= 0;
+ fTPCsignalTuned= 0;
fTPCsignalS= 0;
fTPCsignalN= 0;
for (Int_t i=0;i<AliPID::kSPECIES;i++) fTPCr[i]=0;
fTRDncls = 0;
fTRDncls0 = 0;
fTRDsignal = 0;
+ fTRDNchamberdEdx = 0;
+ fTRDNclusterdEdx = 0;
+
for (Int_t i=0;i<kTRDnPlanes;i++) {
fTRDTimBin[i] = 0;
}
fTOFdeltaBC = 999;
fTOFl0l1 = 999;
for (Int_t i=0;i<AliPID::kSPECIES;i++) fTOFr[i] = 0;
- for (Int_t i=0;i<3;i++) fTOFLabel[i] = -1;
for (Int_t i=0;i<10;i++) fTOFInfo[i] = 0;
// Reset HMPID related track information
fHMPIDcluIdx = -1;
fHMPIDsignal = 0;
for (Int_t i=0;i<AliPID::kSPECIES;i++) fHMPIDr[i] = 0;
+ fMassForTracking = 0.13957;
fHMPIDtrkTheta = 0;
fHMPIDtrkPhi = 0;
fHMPIDtrkX = 0;
}
//_______________________________________________________________________
-Int_t AliESDtrack::GetPID() const
+Int_t AliESDtrack::GetPID(Bool_t tpcOnly) const
{
// Returns the particle most probable id
Int_t i;
- for (i=0; i<AliPID::kSPECIES-1; i++) if (fR[i] != fR[i+1]) break;
- //
- if (i == AliPID::kSPECIES-1) return AliPID::kPion; // If all the probabilities are equal, return the pion mass
+ const Double32_t *prob = 0;
+ if (tpcOnly) { // check if TPCpid is valid
+ prob = fTPCr;
+ for (i=0; i<AliPID::kSPECIES-1; i++) if (prob[i] != prob[i+1]) break;
+ if (i == AliPID::kSPECIES-1) prob = 0; // not valid, try with combined pid
+ }
+ if (!prob) { // either requested TPCpid is not valid or comb.pid is requested
+ prob = fR;
+ for (i=0; i<AliPID::kSPECIES-1; i++) if (prob[i] != prob[i+1]) break;
+ if (i == AliPID::kSPECIES-1) return AliPID::kPion; // If all the probabilities are equal, return the pion mass
+ }
//
Float_t max=0.;
Int_t k=-1;
- for (i=0; i<AliPID::kSPECIES; i++) if (fR[i]>max) {k=i; max=fR[i];}
+ for (i=0; i<AliPID::kSPECIES; i++) if (prob[i]>max) {k=i; max=prob[i];}
//
if (k==0) { // dE/dx "crossing points" in the TPC
Double_t p=GetP();
if ((p>0.38)&&(p<0.48))
- if (fR[0]<fR[3]*10.) return AliPID::kKaon;
+ if (prob[0]<prob[3]*10.) return AliPID::kKaon;
if ((p>0.75)&&(p<0.85))
- if (fR[0]<fR[4]*10.) return AliPID::kProton;
+ if (prob[0]<prob[4]*10.) return AliPID::kProton;
return AliPID::kElectron;
}
if (k==1) return AliPID::kMuon;
}
//_______________________________________________________________________
-Int_t AliESDtrack::GetTOFBunchCrossing(Double_t b) const
+Int_t AliESDtrack::GetTOFBunchCrossing(Double_t b, Bool_t pidTPConly) const
{
// Returns the number of bunch crossings after trigger (assuming 25ns spacing)
const double kSpacing = 25e3; // min interbanch spacing
if (!IsOn(kTOFout) || !IsOn(kESDpid)) return bcid; // no info
//
double tdif = fTOFsignal;
+ Double_t times[AliPID::kSPECIESC];
+ GetIntegratedTimes(times);
if (IsOn(kTIME)) { // integrated time info is there
- int pid = GetPID();
- tdif -= fTrackTime[pid];
+ int pid = GetPID(pidTPConly);
+
+ tdif -= times[pid];
}
else { // assume integrated time info from TOF radius and momentum
const double kRTOF = 385.;
const double kCSpeed = 3.e-2; // cm/ps
double p = GetP();
if (p<0.01) return bcid;
- double m = GetMass();
+ double m = GetMass(pidTPConly);
double curv = GetC(b);
double path = TMath::Abs(curv)>kAlmost0 ? // account for curvature
2./curv*TMath::ASin(kRTOF*curv/2.)*TMath::Sqrt(1.+GetTgl()*GetTgl()) : kRTOF;
if (t->IsStartedTimeIntegral()) {
SetStatus(kTIME);
- Double_t times[10];t->GetIntegratedTimes(times); SetIntegratedTimes(times);
+ Double_t times[AliPID::kSPECIESC];t->GetIntegratedTimes(times); SetIntegratedTimes(times);
SetIntegratedLength(t->GetIntegratedLength());
}
delete [] indexTRD;
}
- fTRDsignal=t->GetPIDsignal();
+ //commented out by Xianguo
+ //fTRDsignal=t->GetPIDsignal();
}
break;
case kTRDbackup:
//_______________________________________________________________________
void AliESDtrack::GetIntegratedTimes(Double_t *times) const {
+ Int_t index = -1;
+
+ if(fNtofClusters>0 && GetESDEvent()){
+ TObjArray *tofclArray = GetESDEvent()->GetTOFcluster();
+ AliESDTOFcluster *tofcl = (AliESDTOFcluster *) tofclArray->At(fTOFcluster[0]);
+
+ for(Int_t i=0;i < tofcl->GetNMatchableTracks();i++){
+ if(tofcl->GetTrackIndex(i) == GetID()) index = i;
+ }
+ if(fNtofClusters>0 && index > -1){
+ for (Int_t i=0; i<AliPID::kSPECIESC; i++) times[i]=tofcl->GetIntegratedTime(i,index);
+ return;
+ }
+ }
+ else if(fNtofClusters>0)
+ AliInfo("No AliESDEvent available here!\n");
+
// Returns the array with integrated times for each particle hypothesis
- for (Int_t i=0; i<AliPID::kSPECIES; i++) times[i]=fTrackTime[i];
+ if(fTrackTime)
+ for (Int_t i=0; i<AliPID::kSPECIESC; i++) times[i]=fTrackTime[i];
+ else
+ for (Int_t i=0; i<AliPID::kSPECIESC; i++) times[i]=0.0;
+}
+//_______________________________________________________________________
+Double_t AliESDtrack::GetIntegratedLength() const{
+ Int_t index = -1;
+ if(fNtofClusters>0 && GetESDEvent()){
+ TObjArray *tofclArray = GetESDEvent()->GetTOFcluster();
+ AliESDTOFcluster *tofcl = (AliESDTOFcluster *) tofclArray->At(fTOFcluster[0]);
+
+ for(Int_t i=0;i < tofcl->GetNMatchableTracks();i++){
+ if(tofcl->GetTrackIndex(i) == GetID()) index = i;
+ }
+
+ if(fNtofClusters>0 && index > -1)
+ return tofcl->GetLength(index);
+ }
+ else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
+
+ return fTrackLength;
}
//_______________________________________________________________________
void AliESDtrack::SetIntegratedTimes(const Double_t *times) {
// Sets the array with integrated times for each particle hypotesis
- for (Int_t i=0; i<AliPID::kSPECIES; i++) fTrackTime[i]=times[i];
+ if(!fTrackTime)
+ fTrackTime = new Double32_t[AliPID::kSPECIESC];
+ for (Int_t i=0; i<AliPID::kSPECIESC; i++) fTrackTime[i]=times[i];
}
//_______________________________________________________________________
}
//_______________________________________________________________________
-Float_t AliESDtrack::GetTPCClusterInfo(Int_t nNeighbours/*=3*/, Int_t type/*=0*/, Int_t row0, Int_t row1) const
+Float_t AliESDtrack::GetTPCCrossedRows() const
+{
+ // This function calls GetTPCClusterInfo with some default parameters which are used in the track selection and caches the outcome
+ // because GetTPCClusterInfo is quite time-consuming
+
+ if (fCacheNCrossedRows > -1)
+ return fCacheNCrossedRows;
+
+ fCacheNCrossedRows = GetTPCClusterInfo(2, 1);
+ return fCacheNCrossedRows;
+}
+
+//_______________________________________________________________________
+Float_t AliESDtrack::GetTPCClusterInfo(Int_t nNeighbours/*=3*/, Int_t type/*=0*/, Int_t row0, Int_t row1, Int_t bitType ) const
{
//
// TPC cluster information
// type 0: get fraction of found/findable clusters with neighbourhood definition
// 1: findable clusters with neighbourhood definition
// 2: found clusters
- //
+ // bitType:
+ // 0 - all cluster used
+ // 1 - clusters used for the kalman update
// definition of findable clusters:
// a cluster is defined as findable if there is another cluster
// within +- nNeighbours pad rows. The idea is to overcome threshold
// effects with a very simple algorithm.
//
- if (type==2) return fTPCClusterMap.CountBits();
Int_t found=0;
Int_t findable=0;
Int_t last=-nNeighbours;
+ const TBits & clusterMap = (bitType%2==0) ? fTPCClusterMap : fTPCFitMap;
- Int_t upperBound=fTPCClusterMap.GetNbits();
+ Int_t upperBound=clusterMap.GetNbits();
if (upperBound>row1) upperBound=row1;
for (Int_t i=row0; i<upperBound; ++i){
//look to current row
- if (fTPCClusterMap[i]) {
+ if (clusterMap[i]) {
last=i;
++found;
++findable;
}
//look to nNeighbours after
for (Int_t j=i+1; j<i+1+nNeighbours; ++j){
- if (fTPCClusterMap[j]){
+ if (clusterMap[j]){
++findable;
break;
}
}
}
+ if (type==2) return found;
+ if (type==1) return findable;
+
+ if (type==0){
+ Float_t fraction=0;
+ if (findable>0)
+ fraction=(Float_t)found/(Float_t)findable;
+ else
+ fraction=0;
+ return fraction;
+ }
+ return 0; // undefined type - default value
+}
+
+//_______________________________________________________________________
+Float_t AliESDtrack::GetTPCClusterDensity(Int_t nNeighbours/*=3*/, Int_t type/*=0*/, Int_t row0, Int_t row1, Int_t bitType ) const
+{
+ //
+ // TPC cluster density - only rows where signal before and after given row are used
+ // - slower function
+ // type 0: get fraction of found/findable clusters with neighbourhood definition
+ // 1: findable clusters with neighbourhood definition
+ // 2: found clusters
+ // bitType:
+ // 0 - all cluster used
+ // 1 - clusters used for the kalman update
+ // definition of findable clusters:
+ // a cluster is defined as findable if there is another cluster
+ // within +- nNeighbours pad rows. The idea is to overcome threshold
+ // effects with a very simple algorithm.
+ //
+ Int_t found=0;
+ Int_t findable=0;
+ // Int_t last=-nNeighbours;
+ const TBits & clusterMap = (bitType%2==0) ? fTPCClusterMap : fTPCFitMap;
+ Int_t upperBound=clusterMap.GetNbits();
+ if (upperBound>row1) upperBound=row1;
+ for (Int_t i=row0; i<upperBound; ++i){
+ Bool_t isUp=kFALSE;
+ Bool_t isDown=kFALSE;
+ for (Int_t idelta=1; idelta<=nNeighbours; idelta++){
+ if (i-idelta>=0 && clusterMap[i-idelta]) isDown=kTRUE;
+ if (i+idelta<upperBound && clusterMap[i+idelta]) isUp=kTRUE;
+ }
+ if (isUp&&isDown){
+ ++findable;
+ if (clusterMap[i]) ++found;
+ }
+ }
+ if (type==2) return found;
if (type==1) return findable;
if (type==0){
return 0; // undefined type - default value
}
+
+
+
//_______________________________________________________________________
Double_t AliESDtrack::GetTPCdensity(Int_t row0, Int_t row1) const{
//
if (idx>0) found++;
}
Float_t density=0.5;
- if (good>(row1-row0)*0.5) density = Float_t(found)/Float_t(good);
+ if (good>TMath::Max((row1-row0)*0.5,0.0)) density = Float_t(found)/Float_t(good);
return density;
}
}
Int_t ns=GetNumberOfTRDslices();
if ((slice<0) || (slice>=ns)) {
- AliError("Wrong TRD slice !");
+ AliError(Form("Wrong TRD slice %d/%d, NSlices=%d",plane,slice,ns));
return;
}
Int_t n=plane*ns + slice;
//_______________________________________________________________________
void AliESDtrack::SetTOFLabel(const Int_t *p) {
// Sets (in TOF)
+ if(!fTOFLabel) fTOFLabel = new Int_t[3];
for (Int_t i=0; i<3; i++) fTOFLabel[i]=p[i];
}
//_______________________________________________________________________
void AliESDtrack::GetTOFLabel(Int_t *p) const {
// Gets (in TOF)
- for (Int_t i=0; i<3; i++) p[i]=fTOFLabel[i];
+ if(fNtofClusters>0){
+ TObjArray *tofclArray = GetESDEvent()->GetTOFcluster();
+ AliESDTOFcluster *tofcl = (AliESDTOFcluster *) tofclArray->At(fTOFcluster[0]);
+
+ for (Int_t i=0; i<3; i++) p[i]=tofcl->GetLabel(i);
+ }
+ else{
+ if(fTOFLabel)
+ for (Int_t i=0; i<3; i++) p[i]=fTOFLabel[i];
+ }
}
//_______________________________________________________________________
SetStatus(AliESDtrack::kHMPIDpid);
}
+//_______________________________________________________________________
+void AliESDtrack::SetTPCdEdxInfo(AliTPCdEdxInfo * dEdxInfo){
+ if(fTPCdEdxInfo) delete fTPCdEdxInfo;
+ fTPCdEdxInfo = dEdxInfo;
+}
+
//_______________________________________________________________________
void AliESDtrack::GetHMPIDpid(Double_t *p) const {
// Gets probabilities of each particle type (in HMPID)
// Prints info on the track
AliExternalTrackParam::Print();
printf("ESD track info\n") ;
- Double_t p[AliPID::kSPECIESN] ;
+ Double_t p[AliPID::kSPECIES] ;
Int_t index = 0 ;
if( IsOn(kITSpid) ){
printf("From ITS: ") ;
for(index = 0 ; index < AliPID::kSPECIES; index++)
printf("%f, ", p[index]) ;
printf("\n signal = %f\n", GetTRDsignal()) ;
+ printf("\n NchamberdEdx = %d\n", GetTRDNchamberdEdx()) ;
+ printf("\n NclusterdEdx = %d\n", GetTRDNclusterdEdx()) ;
}
if( IsOn(kTOFpid) ){
printf("From TOF: ") ;
}
//_______________________________________________________________________
-void AliESDtrack::GetITSdEdxSamples(Double_t *s) const {
+void AliESDtrack::GetITSdEdxSamples(Double_t s[4]) const {
//
// Get the dE/dx samples measured by the two SSD and two SDD layers.
// These samples are corrected for the track segment length.
//
return fTPCClusterMap.CountBits(i0)-fTPCClusterMap.CountBits(i1);
}
+
+//____________________________________________________________________
+Double_t AliESDtrack::GetChi2TPCConstrainedVsGlobal(const AliESDVertex* vtx) const
+{
+ // Calculates the chi2 between the TPC track (TPCinner) constrained to the primary vertex and the global track
+ //
+ // Returns -1 in case the calculation failed
+ //
+ // Value is cached as a non-persistent member.
+ //
+ // Code adapted from original code by GSI group (Jacek, Marian, Michael)
+
+ // cache, ignoring that a different vertex might be passed
+ if (fCacheChi2TPCConstrainedVsGlobalVertex == vtx)
+ return fCacheChi2TPCConstrainedVsGlobal;
+
+ fCacheChi2TPCConstrainedVsGlobal = -1;
+ fCacheChi2TPCConstrainedVsGlobalVertex = vtx;
+
+ Double_t x[3];
+ GetXYZ(x);
+ Double_t b[3];
+ AliTrackerBase::GetBxByBz(x,b);
+
+ if (!fTPCInner) {
+ AliWarning("Could not get TPC Inner Param.");
+ return fCacheChi2TPCConstrainedVsGlobal;
+ }
+
+ // clone for constraining
+ AliExternalTrackParam* tpcInnerC = new AliExternalTrackParam(*fTPCInner);
+ if (!tpcInnerC) {
+ AliWarning("Clone of TPCInnerParam failed.");
+ return fCacheChi2TPCConstrainedVsGlobal;
+ }
+
+ // transform to the track reference frame
+ Bool_t isOK = tpcInnerC->Rotate(GetAlpha());
+ isOK &= tpcInnerC->PropagateTo(GetX(), b[2]);
+ if (!isOK) {
+ delete tpcInnerC;
+ tpcInnerC = 0;
+ AliWarning("Rotation/Propagation of track failed.") ;
+ return fCacheChi2TPCConstrainedVsGlobal;
+ }
+
+ // constrain TPCinner
+ isOK = tpcInnerC->ConstrainToVertex(vtx, b);
+
+ // transform to the track reference frame
+ isOK &= tpcInnerC->Rotate(GetAlpha());
+ isOK &= tpcInnerC->PropagateTo(GetX(), b[2]);
+
+ if (!isOK) {
+ AliWarning("ConstrainTPCInner failed.") ;
+ delete tpcInnerC;
+ tpcInnerC = 0;
+ return fCacheChi2TPCConstrainedVsGlobal;
+ }
+
+ // calculate chi2 between vi and vj vectors
+ // with covi and covj covariance matrices
+ // chi2ij = (vi-vj)^(T)*(covi+covj)^(-1)*(vi-vj)
+ TMatrixD deltaT(5,1);
+ TMatrixD delta(1,5);
+ TMatrixD covarM(5,5);
+
+ for (Int_t ipar=0; ipar<5; ipar++) {
+ deltaT(ipar,0) = tpcInnerC->GetParameter()[ipar] - GetParameter()[ipar];
+ delta(0,ipar) = tpcInnerC->GetParameter()[ipar] - GetParameter()[ipar];
+
+ for (Int_t jpar=0; jpar<5; jpar++) {
+ Int_t index = GetIndex(ipar,jpar);
+ covarM(ipar,jpar) = GetCovariance()[index]+tpcInnerC->GetCovariance()[index];
+ }
+ }
+ // chi2 distance TPC constrained and TPC+ITS
+ TMatrixD covarMInv = covarM.Invert();
+ TMatrixD mat2 = covarMInv*deltaT;
+ TMatrixD chi2 = delta*mat2;
+
+ delete tpcInnerC;
+ tpcInnerC = 0;
+
+ fCacheChi2TPCConstrainedVsGlobal = chi2(0,0);
+ return fCacheChi2TPCConstrainedVsGlobal;
+}
+
+void AliESDtrack::SetDetectorPID(const AliDetectorPID *pid)
+{
+ //
+ // Set the detector PID
+ //
+ if (fDetectorPID) delete fDetectorPID;
+ fDetectorPID=pid;
+
+}
+
+Double_t AliESDtrack::GetLengthInActiveZone( Int_t mode, Double_t deltaY, Double_t deltaZ, Double_t bz, Double_t exbPhi , TTreeSRedirector * pcstream) const {
+ //
+ // Input parameters:
+ // mode - type of external track parameters
+ // deltaY - user defined "dead region" in cm
+ // deltaZ - user defined "active region" in cm (250 cm drift lenght - 14 cm L1 delay
+ // bz - magnetic field
+ // exbPhi - optional rotation due to the ExB effect
+ // return value:
+ // the length of the track in cm in "active volume" of the TPC
+ //
+ if (mode==0) return GetLengthInActiveZone(this, deltaY,deltaZ,bz, exbPhi,pcstream);
+ if (mode==1) return GetLengthInActiveZone(fIp, deltaY,deltaZ,bz, exbPhi,pcstream);
+ if (mode==2) return GetLengthInActiveZone(fOp, deltaY,deltaZ,bz, exbPhi,pcstream);
+ return 0;
+}
+
+Double_t AliESDtrack::GetLengthInActiveZone(const AliExternalTrackParam *paramT, Double_t deltaY, Double_t deltaZ, Double_t bz, Double_t exbPhi , TTreeSRedirector * pcstream) const {
+ //
+ // Numerical code to calculate the length of the track in active region of the TPC
+ // ( can be speed up if somebody wants to invest time - analysical version shoult be possible)
+ //
+ // Input parameters:
+ // paramT - external track parameters
+ // deltaY - user defined "dead region" in cm
+ // deltaZ - user defined "active region" in cm (250 cm drift lenght - 14 cm L1 delay
+ // bz - magnetic field
+ // exbPhi - optional rotation due to the ExB effect
+ // return value:
+ // the length of the track in cm in "active volume" of the TPC
+ //
+ const Double_t rIn=85;
+ const Double_t rOut=245;
+ Double_t xyz[3], pxyz[3];
+ if (paramT->GetXYZAt(rIn,bz,xyz)){
+ paramT->GetPxPyPzAt(rIn,bz,pxyz);
+ }else{
+ paramT->GetXYZ(xyz);
+ paramT->GetPxPyPz(pxyz);
+ }
+ //
+ Double_t dca = -paramT->GetD(0,0,bz); // get impact parameter distance to point (0,0)
+ Double_t radius= TMath::Abs(1/paramT->GetC(bz)); //
+ Double_t sign = paramT->GetSign();
+ Double_t R0 = TMath::Sqrt(xyz[0]*xyz[0]+xyz[1]*xyz[1]); // radius at current point
+ Double_t phiR0 = TMath::ATan2(xyz[1],xyz[0]); // angle of given point
+ Double_t dPhiR0= -TMath::ASin((dca*dca-2*dca*radius*sign+R0*R0)/(2*R0*(dca-radius*sign)));
+ Double_t phi0 = phiR0-(dPhiR0); // global phi offset to be added
+ //
+ //
+ AliExternalTrackParam paramR=(*paramT);
+ Double_t length=0;
+ for (Double_t R=rIn; R<=rOut; R++){
+ Double_t sinPhi=(dca*dca-2*dca*radius*sign+R*R)/(2*R*(dca-radius*sign));
+ if (TMath::Abs(sinPhi)>=1) continue;
+ Double_t dphi = -TMath::ASin(sinPhi);
+ Double_t phi = phi0+dphi; // global phi
+ Int_t sector = TMath::Nint(9*phi/(TMath::Pi()));
+ Double_t dPhiEdge = phi-(sector*TMath::Pi()/9)+exbPhi; // distance to sector boundary in rphi
+ Double_t dX = R*TMath::Cos(phi)-xyz[0];
+ Double_t dY = R*TMath::Sin(phi)-xyz[1];
+ Double_t deltaPhi = 2*TMath::ASin(0.5*TMath::Sqrt(dX*dX+dY*dY)/radius);
+ Double_t z = xyz[2]+deltaPhi*radius*paramT->GetTgl();
+ if (TMath::Abs(dPhiEdge*R)>deltaY && TMath::Abs(z)<deltaZ){
+ length++;
+ }
+ // Double_t deltaZ= dphi*radius;
+ if (pcstream){
+ //should we keep debug possibility ?
+ AliExternalTrackParam paramTcopy=(*paramT);
+ paramR.Rotate(phi);
+ paramR.PropagateTo(R,bz);
+ (*pcstream)<<"debugEdge"<<
+ "R="<<R<< // radius
+ "dphiEdge="<<dPhiEdge<< // distance to edge
+ "phi0="<<phi0<< // phi0 -phi at the track initial position
+ "phi="<<phi<< //
+ "z="<<z<<
+ "pT.="<<¶mTcopy<<
+ "pR.="<<¶mR<<
+ "\n";
+ }
+ }
+ return length;
+}
+
+void AliESDtrack::SetTOFclusterArray(Int_t ncluster,Int_t *TOFcluster){
+ AliInfo("Method has to be implemented!");
+// fNtofClusters=ncluster;
+// if(TOFcluster == fTOFcluster) return;
+// if(fTOFcluster){ // reset previous content
+// delete[] fTOFcluster;
+// fTOFcluster = NULL;
+// fNtofClusters=0;
+// }
+
+// if(ncluster){ // set new content
+// fTOFcluster = new Int_t[fNtofClusters];
+// for(Int_t i=0;i < fNtofClusters;i++) fTOFcluster[i] = TOFcluster[i];
+// }
+// else
+// fTOFcluster = 0;
+}
+
+void AliESDtrack::AddTOFcluster(Int_t icl){
+ fNtofClusters++;
+
+ Int_t *old = fTOFcluster;
+ fTOFcluster = new Int_t[fNtofClusters];
+
+ for(Int_t i=0;i < fNtofClusters-1;i++) fTOFcluster[i] = old[i];
+ fTOFcluster[fNtofClusters-1] = icl;
+
+ if(fNtofClusters-1){ // delete previous content
+ delete old;
+ old = NULL;
+ }
+
+}
+
+Double_t AliESDtrack::GetTOFsignal() const {
+ if(fNtofClusters>0 && GetESDEvent()){
+ TObjArray *tofclArray = GetESDEvent()->GetTOFcluster();
+ AliESDTOFcluster *tofcl = (AliESDTOFcluster *) tofclArray->At(fTOFcluster[0]);
+
+ return tofcl->GetTime();
+ }
+ else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
+
+ return fTOFsignal;
+}
+
+Double_t AliESDtrack::GetTOFsignalToT() const
+{
+ if(fNtofClusters>0 && GetESDEvent()){
+ TObjArray *tofclArray = GetESDEvent()->GetTOFcluster();
+ AliESDTOFcluster *tofcl = (AliESDTOFcluster *) tofclArray->At(fTOFcluster[0]);
+
+ return tofcl->GetTOT();
+ }
+ else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
+
+ return fTOFsignalToT;
+}
+
+Double_t AliESDtrack::GetTOFsignalRaw() const
+{
+ if(fNtofClusters>0 && GetESDEvent()){
+ TObjArray *tofclArray = GetESDEvent()->GetTOFcluster();
+ AliESDTOFcluster *tofcl = (AliESDTOFcluster *) tofclArray->At(fTOFcluster[0]);
+
+ return tofcl->GetTimeRaw();
+ }
+ else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
+
+ return fTOFsignalRaw;
+}
+
+Double_t AliESDtrack::GetTOFsignalDz() const
+{
+
+ AliESDTOFcluster *tofcl;
+
+ Int_t index = -1;
+ if(fNtofClusters>0 && GetESDEvent()){
+ TObjArray *tofclArray = GetESDEvent()->GetTOFcluster();
+ tofcl = (AliESDTOFcluster *) tofclArray->At(fTOFcluster[0]);
+
+ for(Int_t i=0;i < tofcl->GetNMatchableTracks();i++){
+ if(tofcl->GetTrackIndex(i) == GetID()) index = i;
+ }
+ }
+ else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
+
+ if(fNtofClusters>0 && index > -1){
+ return tofcl->GetDz(index);
+ }
+ return fTOFsignalDz;
+}
+
+Double_t AliESDtrack::GetTOFsignalDx() const
+{
+ AliESDTOFcluster *tofcl;
+
+ Int_t index = -1;
+ if(fNtofClusters>0 && GetESDEvent()){
+ TObjArray *tofclArray = GetESDEvent()->GetTOFcluster();
+ tofcl = (AliESDTOFcluster *) tofclArray->At(fTOFcluster[0]);
+ for(Int_t i=0;i < tofcl->GetNMatchableTracks();i++){
+ if(tofcl->GetTrackIndex(i) == GetID()) index = i;
+ }
+ }
+ else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
+ if(fNtofClusters>0 && index > -1){
+ return tofcl->GetDx(index);
+ }
+ return fTOFsignalDx;
+}
+
+Short_t AliESDtrack::GetTOFDeltaBC() const
+{
+ if(fNtofClusters>0 && GetESDEvent()){
+ TObjArray *tofclArray = GetESDEvent()->GetTOFcluster();
+ AliESDTOFcluster *tofcl = (AliESDTOFcluster *) tofclArray->At(fTOFcluster[0]);
+ return tofcl->GetDeltaBC();
+ }
+ else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
+
+ return fTOFdeltaBC;
+}
+
+Short_t AliESDtrack::GetTOFL0L1() const
+{
+ if(fNtofClusters>0 && GetESDEvent()){
+ TObjArray *tofclArray = GetESDEvent()->GetTOFcluster();
+ AliESDTOFcluster *tofcl = (AliESDTOFcluster *) tofclArray->At(fTOFcluster[0]);
+
+ return tofcl->GetL0L1Latency();
+ }
+ else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
+
+ return fTOFl0l1;
+}
+
+Int_t AliESDtrack::GetTOFCalChannel() const
+{
+ if(fNtofClusters>0 && GetESDEvent()){
+ TObjArray *tofclArray = GetESDEvent()->GetTOFcluster();
+ AliESDTOFcluster *tofcl = (AliESDTOFcluster *) tofclArray->At(fTOFcluster[0]);
+
+ tofcl->GetTOFchannel();
+ }
+ else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
+
+ return fTOFCalChannel;
+}
+
+Int_t AliESDtrack::GetTOFcluster() const
+{
+ if(fNtofClusters>0 && GetESDEvent()){
+ TObjArray *tofclArray = GetESDEvent()->GetTOFcluster();
+ AliESDTOFcluster *tofcl = (AliESDTOFcluster *) tofclArray->At(fTOFcluster[0]);
+
+ tofcl->GetClusterIndex();
+ }
+ else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
+
+ return fTOFindex;
+}
+
+Int_t AliESDtrack::GetTOFclusterN() const
+{
+ return fNtofClusters;
+}
+
+Bool_t AliESDtrack::IsTOFHitAlreadyMatched() const{
+ if(fNtofClusters>0 && GetESDEvent()){
+ TObjArray *tofclArray = GetESDEvent()->GetTOFcluster();
+ AliESDTOFcluster *tofcl = (AliESDTOFcluster *) tofclArray->At(fTOFcluster[0]);
+
+ if (tofcl->GetNMatchableTracks() > 1)
+ return kTRUE;
+ }
+ else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
+
+ return kFALSE;
+}
+
+void AliESDtrack::ReMapTOFcluster(Int_t ncl,Int_t *mapping){
+ for(Int_t i=0;i<fNtofClusters;i++){
+ if(fTOFcluster[i]<ncl && fTOFcluster[i]>-1)
+ fTOFcluster[i] = mapping[fTOFcluster[i]];
+ else
+ AliInfo(Form("TOF cluster re-mapping in AliESDtrack: out of range (%i > %i)\n",fTOFcluster[i],ncl));
+ }
+}
+
+void AliESDtrack::SortTOFcluster(){
+ TObjArray *tofclArray = GetESDEvent()->GetTOFcluster();
+
+ for(Int_t i=0;i<fNtofClusters-1;i++){
+ for(Int_t j=i+1;j<fNtofClusters;j++){
+ AliESDTOFcluster *tofcl = (AliESDTOFcluster *) tofclArray->At(fTOFcluster[i]);
+ Int_t index1 = -1;
+ for(Int_t it=0;it < tofcl->GetNMatchableTracks();it++){
+ if(tofcl->GetTrackIndex(it) == GetID()) index1 = it;
+ }
+ Double_t timedist1 = 10000;
+ for(Int_t isp=0; isp< AliPID::kSPECIESC;isp++){
+ Double_t timec = TMath::Abs(tofcl->GetTime() - tofcl->GetIntegratedTime(isp));
+ if(timec < timedist1) timedist1 = timec;
+ }
+ timedist1 *= 0.03; // in cm
+ Double_t radius1 = tofcl->GetDx(index1)*tofcl->GetDx(index1) + tofcl->GetDz(index1)*tofcl->GetDz(index1) + timedist1*timedist1;
+
+ AliESDTOFcluster *tofcl2 = (AliESDTOFcluster *) tofclArray->At(fTOFcluster[j]);
+ Int_t index2 = -1;
+ for(Int_t it=0;it < tofcl2->GetNMatchableTracks();it++){
+ if(tofcl2->GetTrackIndex(it) == GetID()) index2 = it;
+ }
+ if(index1 == -1 || index2 == -1){
+ }
+ Double_t timedist2 = 10000;
+ for(Int_t isp=0; isp< AliPID::kSPECIESC;isp++){
+ Double_t timec = TMath::Abs(tofcl2->GetTime() - tofcl2->GetIntegratedTime(isp));
+ if(timec < timedist2) timedist2 = timec;
+ }
+ timedist2 *= 0.03; // in cm
+ Double_t radius2 = tofcl2->GetDx(index2)*tofcl2->GetDx(index2) + tofcl2->GetDz(index2)*tofcl2->GetDz(index2) + timedist2*timedist2;
+
+ if(radius2 < radius1){
+ Int_t change = fTOFcluster[i];
+ fTOFcluster[i] = fTOFcluster[j];
+ fTOFcluster[j] = change;
+ }
+ }
+ }
+}