/* $Id$ */
-#include <Riostream.h>
-#include <TObject.h>
+#include <TVector2.h>
+
+#include "AliTracker.h"
#include "AliTRDgeometry.h"
#include "AliTRDcluster.h"
#include "AliTRDtrack.h"
-#include "AliTRDclusterCorrection.h"
+#include "AliTRDcalibDB.h"
+#include "Cal/AliTRDCalPID.h"
ClassImp(AliTRDtrack)
+///////////////////////////////////////////////////////////////////////////////
+// //
+// Represents a reconstructed TRD track //
+// Local TRD Kalman track //
+// //
+///////////////////////////////////////////////////////////////////////////////
+
//_____________________________________________________________________________
+AliTRDtrack::AliTRDtrack()
+ :AliKalmanTrack()
+ ,fSeedLab(-1)
+ ,fdEdx(0)
+ ,fDE(0)
+ ,fPIDquality(0)
+ ,fClusterOwner(kFALSE)
+ ,fPIDmethod(kLQ)
+ ,fStopped(kFALSE)
+ ,fLhElectron(0)
+ ,fNWrong(0)
+ ,fNRotate(0)
+ ,fNCross(0)
+ ,fNExpected(0)
+ ,fNLast(0)
+ ,fNExpectedLast(0)
+ ,fNdedx(0)
+ ,fChi2Last(1e10)
+ ,fBackupTrack(0x0)
+{
+ //
+ // AliTRDtrack default constructor
+ //
+
+ for (Int_t i = 0; i < kNplane; i++) {
+ for (Int_t j = 0; j < kNslice; j++) {
+ fdEdxPlane[i][j] = 0.0;
+ }
+ fTimBinPlane[i] = -1;
+ fMom[i] = -1.;
+ fSnp[i] = 0.;
+ fTgl[i] = 0.;
+ fTrackletIndex[i] = -1;
+ }
+ for(int ispec=0; ispec<AliPID::kSPECIES; ispec++) {
+ fPID[ispec] = 1.0 / AliPID::kSPECIES;
+ }
-AliTRDtrack::AliTRDtrack(const AliTRDcluster *c, UInt_t index,
- const Double_t xx[5], const Double_t cc[15],
- Double_t xref, Double_t alpha) : AliKalmanTrack() {
- //-----------------------------------------------------------------
- // This is the main track constructor.
- //-----------------------------------------------------------------
+ for (UInt_t i = 0; i < kMAXCLUSTERSPERTRACK; i++) {
+ fIndex[i] = 0;
+ fIndexBackup[i] = 0;
+ fdQdl[i] = 0;
+ fClusters[i] = 0x0;
+ }
+
+ for (Int_t i = 0; i < 3; i++) {
+ fBudget[i] = 0;
+ }
+
+}
- fSeedLab = -1;
+//_____________________________________________________________________________
+AliTRDtrack::AliTRDtrack(AliTRDcluster *c, Int_t index
+ , const Double_t p[5], const Double_t cov[15]
+ , Double_t x, Double_t alpha)
+ :AliKalmanTrack()
+ ,fSeedLab(-1)
+ ,fdEdx(0)
+ ,fDE(0)
+ ,fPIDquality(0)
+ ,fClusterOwner(kFALSE)
+ ,fPIDmethod(kLQ)
+ ,fStopped(kFALSE)
+ ,fLhElectron(0)
+ ,fNWrong(0)
+ ,fNRotate(0)
+ ,fNCross(0)
+ ,fNExpected(0)
+ ,fNLast(0)
+ ,fNExpectedLast(0)
+ ,fNdedx(0)
+ ,fChi2Last(1e10)
+ ,fBackupTrack(0x0)
+{
+ //
+ // The main AliTRDtrack constructor.
+ //
- fAlpha=alpha;
- if (fAlpha<-TMath::Pi()) fAlpha += 2*TMath::Pi();
- if (fAlpha>=TMath::Pi()) fAlpha -= 2*TMath::Pi();
+ Double_t cnv = 1.0 / (GetBz() * kB2C);
- fX=xref;
+ Double_t pp[5] = { p[0]
+ , p[1]
+ , x*p[4] - p[2]
+ , p[3]
+ , p[4]*cnv };
- fY=xx[0]; fZ=xx[1]; fE=xx[2]; fT=xx[3]; fC=xx[4];
+ Double_t c22 = x*x*cov[14] - 2*x*cov[12] + cov[ 5];
+ Double_t c32 = x*cov[13] - cov[ 8];
+ Double_t c20 = x*cov[10] - cov[ 3];
+ Double_t c21 = x*cov[11] - cov[ 4];
+ Double_t c42 = x*cov[14] - cov[12];
- fCyy=cc[0];
- fCzy=cc[1]; fCzz=cc[2];
- fCey=cc[3]; fCez=cc[4]; fCee=cc[5];
- fCty=cc[6]; fCtz=cc[7]; fCte=cc[8]; fCtt=cc[9];
- fCcy=cc[10]; fCcz=cc[11]; fCce=cc[12]; fCct=cc[13]; fCcc=cc[14];
-
- fIndex[0]=index;
+ Double_t cc[15] = { cov[ 0]
+ , cov[ 1], cov[ 2]
+ , c20, c21, c22
+ , cov[ 6], cov[ 7], c32, cov[ 9]
+ , cov[10]*cnv, cov[11]*cnv, c42*cnv, cov[13]*cnv, cov[14]*cnv*cnv };
+
+ Set(x,alpha,pp,cc);
SetNumberOfClusters(1);
+ fIndex[0] = index;
+ fClusters[0] = c;
- fdEdx=0.;
- for (Int_t i=0;i<kNPlane;i++){
- fdEdxPlane[i] = 0.;
- fTimBinPlane[i] = -1;
+ for (Int_t i = 0; i < kNplane; i++) {
+ for (Int_t j = 0; j < kNslice; j++) {
+ fdEdxPlane[i][j] = 0.0;
+ }
+ fTimBinPlane[i] = -1;
+ fMom[i] = -1.;
+ fSnp[i] = 0.;
+ fTgl[i] = 0.;
+ fTrackletIndex[i] = -1;
+ }
+ for(int ispec=0; ispec<AliPID::kSPECIES; ispec++) {
+ fPID[ispec] = 1.0 / AliPID::kSPECIES;
}
- fLhElectron = 0.0;
- fNWrong = 0;
- fNRotate = 0;
- fStopped = 0;
Double_t q = TMath::Abs(c->GetQ());
- Double_t s = fX*fC - fE, t=fT;
- if(s*s < 1) q *= TMath::Sqrt((1-s*s)/(1+t*t));
+ Double_t s = GetSnp();
+ Double_t t = GetTgl();
+ if (s*s < 1) {
+ q *= TMath::Sqrt((1-s*s)/(1+t*t));
+ }
+
+ fdQdl[0] = q;
+ for (UInt_t i = 1; i < kMAXCLUSTERSPERTRACK; i++) {
+ fdQdl[i] = 0;
+ fIndex[i] = 0;
+ fIndexBackup[i] = 0;
+ fClusters[i] = 0x0;
+ }
+
+ for (Int_t i = 0; i < 3;i++) {
+ fBudget[i] = 0;
+ }
- fdQdl[0] = q;
-
- // initialisation [SR, GSI 18.02.2003] (i startd for 1)
- for(UInt_t i=1; i<kMAX_CLUSTERS_PER_TRACK; i++) {
- fdQdl[i] = 0;
- fIndex[i] = 0;
- fIndexBackup[i] = 0; //bacup indexes MI
- }
- fNCross =0;
- fBackupTrack =0;
}
//_____________________________________________________________________________
-AliTRDtrack::AliTRDtrack(const AliTRDtrack& t) : AliKalmanTrack(t) {
+AliTRDtrack::AliTRDtrack(const AliTRDtrack &t/*, const Bool_t owner*/)
+ :AliKalmanTrack(t)
+ ,fSeedLab(t.GetSeedLabel())
+ ,fdEdx(t.fdEdx)
+ ,fDE(t.fDE)
+ ,fPIDquality(t.fPIDquality)
+ ,fClusterOwner(kTRUE)
+ ,fPIDmethod(t.fPIDmethod)
+ ,fStopped(t.fStopped)
+ ,fLhElectron(0)
+ ,fNWrong(t.fNWrong)
+ ,fNRotate(t.fNRotate)
+ ,fNCross(t.fNCross)
+ ,fNExpected(t.fNExpected)
+ ,fNLast(t.fNLast)
+ ,fNExpectedLast(t.fNExpectedLast)
+ ,fNdedx(t.fNdedx)
+ ,fChi2Last(t.fChi2Last)
+ ,fBackupTrack(0x0)
+{
//
// Copy constructor.
//
-
- SetLabel(t.GetLabel());
- fSeedLab=t.GetSeedLabel();
- SetChi2(t.GetChi2());
- fdEdx=t.fdEdx;
- for (Int_t i=0;i<kNPlane;i++){
- fdEdxPlane[i] = t.fdEdxPlane[i];
- fTimBinPlane[i] = t.fTimBinPlane[i];
+ for (Int_t i = 0; i < kNplane; i++) {
+ for (Int_t j = 0; j < kNslice; j++) {
+ fdEdxPlane[i][j] = t.fdEdxPlane[i][j];
+ }
+ fTimBinPlane[i] = t.fTimBinPlane[i];
+ fTracklets[i] = t.fTracklets[i];
+ fMom[i] = t.fMom[i];
+ fSnp[i] = t.fSnp[i];
+ fTgl[i] = t.fTgl[i];
+ fTrackletIndex[i] = t.fTrackletIndex[i];
}
- fLhElectron = 0.0;
- fNWrong = t.fNWrong;
- fNRotate = t.fNRotate;
- fStopped = t.fStopped;
- fAlpha=t.fAlpha;
- fX=t.fX;
-
- fY=t.fY; fZ=t.fZ; fE=t.fE; fT=t.fT; fC=t.fC;
+ Int_t n = t.GetNumberOfClusters();
+ SetNumberOfClusters(n);
- fCyy=t.fCyy;
- fCzy=t.fCzy; fCzz=t.fCzz;
- fCey=t.fCey; fCez=t.fCez; fCee=t.fCee;
- fCty=t.fCty; fCtz=t.fCtz; fCte=t.fCte; fCtt=t.fCtt;
- fCcy=t.fCcy; fCcz=t.fCcz; fCce=t.fCce; fCct=t.fCct; fCcc=t.fCcc;
+ for (Int_t i = 0; i < n; i++) {
+ fIndex[i] = t.fIndex[i];
+ fIndexBackup[i] = t.fIndex[i];
+ fdQdl[i] = t.fdQdl[i];
+ if (fClusterOwner && t.fClusters[i]) {
+ fClusters[i] = new AliTRDcluster(*(t.fClusters[i]));
+ }
+ else {
+ fClusters[i] = t.fClusters[i];
+ }
+ }
- Int_t n=t.GetNumberOfClusters();
- SetNumberOfClusters(n);
- for (Int_t i=0; i<n; i++) {
- fIndex[i]=t.fIndex[i];
- fIndexBackup[i]=t.fIndex[i]; // MI - backup indexes
- fdQdl[i]=t.fdQdl[i];
+ for (UInt_t i = n; i < kMAXCLUSTERSPERTRACK; i++) {
+ fdQdl[i] = 0;
+ fIndex[i] = 0;
+ fIndexBackup[i] = 0;
+ fClusters[i] = 0x0;
}
- // initialisation (i starts from n) [SR, GSI, 18.02.2003]
- for(UInt_t i=n; i<kMAX_CLUSTERS_PER_TRACK; i++) {
- fdQdl[i] = 0;
- fIndex[i] = 0;
- fIndexBackup[i] = 0; //MI backup indexes
+ for (Int_t i = 0; i < 3;i++) {
+ fBudget[i] = t.fBudget[i];
}
- fNCross =0;
- fBackupTrack =0;
-}
+
+ for(Int_t ispec = 0; ispec<AliPID::kSPECIES; ispec++) fPID[ispec] = t.fPID[ispec];
+}
//_____________________________________________________________________________
-AliTRDtrack::AliTRDtrack(const AliKalmanTrack& t, Double_t alpha)
- :AliKalmanTrack(t) {
+AliTRDtrack::AliTRDtrack(const AliKalmanTrack &t, Double_t /*alpha*/)
+ :AliKalmanTrack(t)
+ ,fSeedLab(-1)
+ ,fdEdx(t.GetPIDsignal())
+ ,fDE(0)
+ ,fPIDquality(0)
+ ,fClusterOwner(kFALSE)
+ ,fPIDmethod(kLQ)
+ ,fStopped(kFALSE)
+ ,fLhElectron(0.0)
+ ,fNWrong(0)
+ ,fNRotate(0)
+ ,fNCross(0)
+ ,fNExpected(0)
+ ,fNLast(0)
+ ,fNExpectedLast(0)
+ ,fNdedx(0)
+ ,fChi2Last(0.0)
+ ,fBackupTrack(0x0)
+{
//
- // Constructor from AliTPCtrack or AliITStrack .
+ // Constructor from AliTPCtrack or AliITStrack
//
SetLabel(t.GetLabel());
- SetChi2(0.);
+ SetChi2(0.0);
SetMass(t.GetMass());
SetNumberOfClusters(0);
- fdEdx=t.GetPIDsignal();
- for (Int_t i=0;i<kNPlane;i++){
- fdEdxPlane[i] = 0.0;
+ for (Int_t i = 0; i < kNplane; i++) {
+ for (Int_t j = 0; j < kNslice; j++) {
+ fdEdxPlane[i][j] = 0.0;
+ }
fTimBinPlane[i] = -1;
+ fMom[i] = -1.;
+ fSnp[i] = 0.;
+ fTgl[i] = 0.;
+ fTrackletIndex[i] = -1;
+ }
+ for(int ispec=0; ispec<AliPID::kSPECIES; ispec++) {
+ fPID[ispec] = 1.0 / AliPID::kSPECIES;
}
- fLhElectron = 0.0;
- fNWrong = 0;
- fNRotate = 0;
- fStopped = 0;
-
- fAlpha = alpha;
- if (fAlpha < -TMath::Pi()) fAlpha += 2*TMath::Pi();
- else if (fAlpha >= TMath::Pi()) fAlpha -= 2*TMath::Pi();
-
- Double_t x, p[5]; t.GetExternalParameters(x,p);
-
- fX=x;
-
- x = GetConvConst();
-
- fY=p[0];
- fZ=p[1];
- fT=p[3];
- fC=p[4]/x;
- fE=fC*fX - p[2];
-
- //Conversion of the covariance matrix
- Double_t c[15]; t.GetExternalCovariance(c);
-
- c[10]/=x; c[11]/=x; c[12]/=x; c[13]/=x; c[14]/=x*x;
-
- Double_t c22=fX*fX*c[14] - 2*fX*c[12] + c[5];
- Double_t c32=fX*c[13] - c[8];
- Double_t c20=fX*c[10] - c[3], c21=fX*c[11] - c[4], c42=fX*c[14] - c[12];
+ for (UInt_t i = 0; i < kMAXCLUSTERSPERTRACK; i++) {
+ fdQdl[i] = 0;
+ fIndex[i] = 0;
+ fIndexBackup[i] = 0;
+ fClusters[i] = 0x0;
+ }
+
+ for (Int_t i = 0; i < 3; i++) {
+ fBudget[i] = 0;
+ }
- fCyy=c[0 ];
- fCzy=c[1 ]; fCzz=c[2 ];
- fCey=c20; fCez=c21; fCee=c22;
- fCty=c[6 ]; fCtz=c[7 ]; fCte=c32; fCtt=c[9 ];
- fCcy=c[10]; fCcz=c[11]; fCce=c42; fCct=c[13]; fCcc=c[14];
+}
- // Initialization [SR, GSI, 18.02.2003]
- for(UInt_t i=0; i<kMAX_CLUSTERS_PER_TRACK; i++) {
- fdQdl[i] = 0;
- fIndex[i] = 0;
- fIndexBackup[i] = 0; // MI backup indexes
- }
- fNCross =0;
- fBackupTrack =0;
-}
//_____________________________________________________________________________
-AliTRDtrack::AliTRDtrack(const AliESDtrack& t)
- :AliKalmanTrack() {
+AliTRDtrack::AliTRDtrack(const AliESDtrack &t)
+ :AliKalmanTrack()
+ ,fSeedLab(-1)
+ ,fdEdx(t.GetTRDsignal())
+ ,fDE(0)
+ ,fPIDquality(0)
+ ,fClusterOwner(kFALSE)
+ ,fPIDmethod(kLQ)
+ ,fStopped(kFALSE)
+ ,fLhElectron(0)
+ ,fNWrong(0)
+ ,fNRotate(0)
+ ,fNCross(0)
+ ,fNExpected(0)
+ ,fNLast(0)
+ ,fNExpectedLast(0)
+ ,fNdedx(0)
+ ,fChi2Last(1e10)
+ ,fBackupTrack(0x0)
+{
//
// Constructor from AliESDtrack
//
SetLabel(t.GetLabel());
- SetChi2(0.);
+ SetChi2(0.0);
SetMass(t.GetMass());
SetNumberOfClusters(t.GetTRDclusters(fIndex));
+
Int_t ncl = t.GetTRDclusters(fIndexBackup);
- for (UInt_t i=ncl;i<kMAX_CLUSTERS_PER_TRACK;i++) {
- fIndexBackup[i]=0;
- fIndex[i] = 0; //MI store indexes
+ for (UInt_t i = ncl; i < kMAXCLUSTERSPERTRACK; i++) {
+ fIndexBackup[i] = 0;
+ fIndex[i] = 0;
}
- fdEdx=t.GetTRDsignal();
- for (Int_t i=0;i<kNPlane;i++){
- fdEdxPlane[i] = t.GetTRDsignals(i);
+
+ for (Int_t i = 0; i < kNplane; i++) {
+ for (Int_t j = 0; j < kNslice; j++) {
+ fdEdxPlane[i][j] = t.GetTRDslice(i,j);
+ }
fTimBinPlane[i] = t.GetTRDTimBin(i);
+ fMom[i] = -1.;
+ fSnp[i] = 0.;
+ fTgl[i] = 0.;
+ fTrackletIndex[i] = -1;
}
- fLhElectron = 0.0;
- fNWrong = 0;
- fStopped = 0;
- fNRotate = 0;
-
- fAlpha = t.GetAlpha();
- if (fAlpha < -TMath::Pi()) fAlpha += 2*TMath::Pi();
- else if (fAlpha >= TMath::Pi()) fAlpha -= 2*TMath::Pi();
-
- Double_t x, p[5]; t.GetExternalParameters(x,p);
- //Conversion of the covariance matrix
- Double_t c[15]; t.GetExternalCovariance(c);
- if (t.GetStatus()&AliESDtrack::kTRDbackup){
- t.GetTRDExternalParameters(x,fAlpha,p,c);
- if (fAlpha < -TMath::Pi()) fAlpha += 2*TMath::Pi();
- else if (fAlpha >= TMath::Pi()) fAlpha -= 2*TMath::Pi();
+ const AliExternalTrackParam *par = &t;
+ if (t.GetStatus() & AliESDtrack::kTRDbackup) {
+ par = t.GetOuterParam();
+ if (!par) {
+ AliError("No backup info!");
+ par = &t;
+ }
+ }
+ Set(par->GetX()
+ ,par->GetAlpha()
+ ,par->GetParameter()
+ ,par->GetCovariance());
+
+ for (UInt_t i = 0; i < kMAXCLUSTERSPERTRACK; i++) {
+ fdQdl[i] = 0;
+ fClusters[i] = 0x0;
}
- fX=x;
-
- x = GetConvConst();
-
- fY=p[0];
- fZ=p[1];
- fT=p[3];
- fC=p[4]/x;
- fE=fC*fX - p[2];
-
-
- c[10]/=x; c[11]/=x; c[12]/=x; c[13]/=x; c[14]/=x*x;
-
- Double_t c22=fX*fX*c[14] - 2*fX*c[12] + c[5];
- Double_t c32=fX*c[13] - c[8];
- Double_t c20=fX*c[10] - c[3], c21=fX*c[11] - c[4], c42=fX*c[14] - c[12];
-
- fCyy=c[0 ];
- fCzy=c[1 ]; fCzz=c[2 ];
- fCey=c20; fCez=c21; fCee=c22;
- fCty=c[6 ]; fCtz=c[7 ]; fCte=c32; fCtt=c[9 ];
- fCcy=c[10]; fCcz=c[11]; fCce=c42; fCct=c[13]; fCcc=c[14];
+ for (Int_t i = 0; i < 3; i++) {
+ fBudget[i] = 0;
+ }
+ for(int ispec=0; ispec<AliPID::kSPECIES; ispec++) {
+ fPID[ispec] = t.GetTRDpid(ispec);
+ }
- // Initialization [SR, GSI, 18.02.2003]
- for(UInt_t i=0; i<kMAX_CLUSTERS_PER_TRACK; i++) {
- fdQdl[i] = 0;
- // fIndex[i] = 0; //MI store indexes
+ if ((t.GetStatus() & AliESDtrack::kTIME) == 0) {
+ return;
}
- fNCross =0;
- fBackupTrack =0;
- if ((t.GetStatus()&AliESDtrack::kTIME) == 0) return;
StartTimeIntegral();
- Double_t times[10]; t.GetIntegratedTimes(times); SetIntegratedTimes(times);
+ Double_t times[10];
+ t.GetIntegratedTimes(times);
+ SetIntegratedTimes(times);
SetIntegratedLength(t.GetIntegratedLength());
}
+//____________________________________________________________________________
AliTRDtrack::~AliTRDtrack()
{
//
+ // Destructor
//
- if (fBackupTrack) delete fBackupTrack;
- fBackupTrack=0;
+ if (fBackupTrack) {
+ delete fBackupTrack;
+ }
+ fBackupTrack = 0x0;
+
+ if (fClusterOwner) {
+ UInt_t icluster = 0;
+ while ((icluster < kMAXCLUSTERSPERTRACK) && fClusters[icluster]) {
+ delete fClusters[icluster];
+ fClusters[icluster] = 0x0;
+ icluster++;
+ }
+ }
}
//____________________________________________________________________________
-void AliTRDtrack::GetExternalParameters(Double_t& xr, Double_t x[5]) const {
+Float_t AliTRDtrack::StatusForTOF()
+{
//
- // This function returns external TRD track representation
+ // Defines the status of the TOF extrapolation
//
- xr=fX;
- x[0]=GetY();
- x[1]=GetZ();
- x[2]=GetSnp();
- x[3]=GetTgl();
- x[4]=Get1Pt();
-}
+
+ // Definition of res ????
+ Float_t res = (0.2 + 0.8 * (fN / (fNExpected + 5.0)))
+ * (0.4 + 0.6 * fTracklets[5].GetN() / 20.0);
+ res *= (0.25 + 0.8 * 40.0 / (40.0 + fBudget[2]));
+ return res;
+
+}
//_____________________________________________________________________________
-void AliTRDtrack::GetExternalCovariance(Double_t cc[15]) const {
+Int_t AliTRDtrack::Compare(const TObject *o) const
+{
//
- // This function returns external representation of the covriance matrix.
+ // Compares tracks according to their Y2 or curvature
//
- Double_t a=GetConvConst();
- Double_t c22=fX*fX*fCcc-2*fX*fCce+fCee;
- Double_t c32=fX*fCct-fCte;
- Double_t c20=fX*fCcy-fCey, c21=fX*fCcz-fCez, c42=fX*fCcc-fCce;
+ AliTRDtrack *t = (AliTRDtrack *) o;
- cc[0 ]=fCyy;
- cc[1 ]=fCzy; cc[2 ]=fCzz;
- cc[3 ]=c20; cc[4 ]=c21; cc[5 ]=c22;
- cc[6 ]=fCty; cc[7 ]=fCtz; cc[8 ]=c32; cc[9 ]=fCtt;
- cc[10]=fCcy*a; cc[11]=fCcz*a; cc[12]=c42*a; cc[13]=fCct*a; cc[14]=fCcc*a*a;
-
-}
-
+ Double_t co = TMath::Abs(t->GetC());
+ Double_t c = TMath::Abs(GetC());
-//_____________________________________________________________________________
-void AliTRDtrack::GetCovariance(Double_t cc[15]) const {
+ if (c > co) {
+ return 1;
+ }
+ else if (c < co) {
+ return -1;
+ }
- cc[0]=fCyy;
- cc[1]=fCzy; cc[2]=fCzz;
- cc[3]=fCey; cc[4]=fCez; cc[5]=fCee;
- cc[6]=fCcy; cc[7]=fCcz; cc[8]=fCce; cc[9]=fCcc;
- cc[10]=fCty; cc[11]=fCtz; cc[12]=fCte; cc[13]=fCct; cc[14]=fCtt;
-
-}
+ return 0;
+
+}
//_____________________________________________________________________________
-Int_t AliTRDtrack::Compare(const TObject *o) const {
+void AliTRDtrack::CookdEdx(Double_t low, Double_t up)
+{
+ //
+ // Calculates the truncated dE/dx within the "low" and "up" cuts.
+ //
-// Compares tracks according to their Y2 or curvature
+ // Array to sort the dEdx values according to amplitude
+ Float_t sorted[kMAXCLUSTERSPERTRACK];
+ fdEdx = 0.0;
+
+ // Require at least 10 clusters for a dedx measurement
+ if (fNdedx < 10) {
+ return;
+ }
- AliTRDtrack *t=(AliTRDtrack*)o;
- // Double_t co=t->GetSigmaY2();
- // Double_t c =GetSigmaY2();
+ // Can fdQdl be negative ????
+ for (Int_t i = 0; i < fNdedx; i++) {
+ sorted[i] = TMath::Abs(fdQdl[i]);
+ }
+ // Sort the dedx values by amplitude
+ Int_t *index = new Int_t[fNdedx];
+ TMath::Sort(fNdedx, sorted, index, kFALSE);
+
+ // Sum up the truncated charge between lower and upper bounds
+ Int_t nl = Int_t(low * fNdedx);
+ Int_t nu = Int_t( up * fNdedx);
+ for (Int_t i = nl; i <= nu; i++) {
+ fdEdx += sorted[index[i]];
+ }
+ fdEdx /= (nu - nl + 1.0);
- Double_t co=TMath::Abs(t->GetC());
- Double_t c =TMath::Abs(GetC());
+ delete[] index;
- if (c>co) return 1;
- else if (c<co) return -1;
- return 0;
-}
+}
//_____________________________________________________________________________
-void AliTRDtrack::CookdEdx(Double_t low, Double_t up) {
- //-----------------------------------------------------------------
- // Calculates dE/dX within the "low" and "up" cuts.
- //-----------------------------------------------------------------
-
- Int_t i;
- Int_t nc=GetNumberOfClusters();
-
- Float_t sorted[kMAX_CLUSTERS_PER_TRACK];
- for (i=0; i < nc; i++) {
- sorted[i]=fdQdl[i];
- }
- /*
- Int_t swap;
-
- do {
- swap=0;
- for (i=0; i<nc-1; i++) {
- if (sorted[i]<=sorted[i+1]) continue;
- Float_t tmp=sorted[i];
- sorted[i]=sorted[i+1]; sorted[i+1]=tmp;
- swap++;
+void AliTRDtrack::CookdEdxTimBin(const Int_t/* tid*/)
+{
+ //
+ // Set fdEdxPlane and fTimBinPlane and also get the
+ // Time bin for Max. Cluster
+ //
+ // Authors:
+ // Prashant Shukla (shukla@physi.uni-heidelberg.de)
+ // Alexandru Bercuci (A.Bercuci@gsi.de)
+ //
+
+ // Max charge in chamber
+ Double_t maxcharge[kNplane];
+ // Number of clusters attached to track per chamber and slice
+ Int_t nCluster[kNplane][kNslice];
+ // Number of time bins in chamber
+ Int_t ntb = AliTRDcalibDB::Instance()->GetNumberOfTimeBins();
+ Int_t plane; // Plane of current cluster
+ Int_t tb; // Time bin of current cluster
+ Int_t slice; // Current slice
+ AliTRDcluster *cluster = 0x0; // Pointer to current cluster
+
+ // Reset class and local counters/variables
+ for (Int_t iPlane = 0; iPlane < kNplane; iPlane++) {
+ fTimBinPlane[iPlane] = -1;
+ maxcharge[iPlane] = 0.0;
+ for (Int_t iSlice = 0; iSlice < kNslice; iSlice++) {
+ fdEdxPlane[iPlane][iSlice] = 0.0;
+ nCluster[iPlane][iSlice] = 0;
}
- } while (swap);
- */
- Int_t nl=Int_t(low*nc), nu=Int_t(up*nc);
- Float_t dedx=0;
- //for (i=nl; i<=nu; i++) dedx += sorted[i];
- //dedx /= (nu-nl+1);
- for (i=0; i<nc; i++) dedx += sorted[i]; // ADDED by PS
- if((nu-nl)) dedx /= (nu-nl); // ADDED by PS
-
- SetdEdx(dedx);
-}
+ }
+ // Start looping over clusters attached to this track
+ for (Int_t iClus = 0; iClus < GetNumberOfClusters(); iClus++) {
-//_____________________________________________________________________________
-Int_t AliTRDtrack::PropagateTo(Double_t xk,Double_t x0,Double_t rho)
-{
- // Propagates a track of particle with mass=pm to a reference plane
- // defined by x=xk through media of density=rho and radiationLength=x0
+ cluster = fClusters[iClus]; //(AliTRDcluster*)tracker->GetCluster(fIndex[iClus]);
+ if (!cluster) continue;
- if (xk == fX) return 1;
+ // Read info from current cluster
+ plane = AliTRDgeometry::GetLayer(cluster->GetDetector());
+ if (plane < 0 || plane >= kNplane) {
+ AliError(Form("Wrong plane %d", plane));
+ continue;
+ }
- if (TMath::Abs(fC*xk - fE) >= 0.90000) {
- // Int_t n=GetNumberOfClusters();
- //if (n>4) cerr << n << " AliTRDtrack: Propagation failed, \tPt = "
- // << GetPt() << "\t" << GetLabel() << "\t" << GetMass() << endl;
- return 0;
- }
+ tb = cluster->GetLocalTimeBin();
+ if ((tb < 0) || (tb >= ntb)) {
+ AliWarning(Form("time bin < 0 or > %d in cluster %d", ntb, iClus));
+ AliInfo(Form("dQ/dl %f", fdQdl[iClus]));
+ continue;
+ }
+
+ slice = tb * kNslice / ntb;
- // track Length measurement [SR, GSI, 17.02.2003]
- Double_t oldX = fX, oldY = fY, oldZ = fZ;
-
- Double_t x1=fX, x2=x1+(xk-x1), dx=x2-x1, y1=fY, z1=fZ;
- Double_t c1=fC*x1 - fE;
- if((c1*c1) > 1) return 0;
- Double_t r1=sqrt(1.- c1*c1);
- Double_t c2=fC*x2 - fE;
- if((c2*c2) > 1) return 0;
- Double_t r2=sqrt(1.- c2*c2);
-
- fY += dx*(c1+c2)/(r1+r2);
- fZ += dx*(c1+c2)/(c1*r2 + c2*r1)*fT;
-
- //f = F - 1
- Double_t rr=r1+r2, cc=c1+c2, xx=x1+x2;
- Double_t f02=-dx*(2*rr + cc*(c1/r1 + c2/r2))/(rr*rr);
- Double_t f04= dx*(rr*xx + cc*(c1*x1/r1+c2*x2/r2))/(rr*rr);
- Double_t cr=c1*r2+c2*r1;
- Double_t f12=-dx*fT*(2*cr + cc*(c2*c1/r1-r1 + c1*c2/r2-r2))/(cr*cr);
- Double_t f13= dx*cc/cr;
- Double_t f14=dx*fT*(cr*xx-cc*(r1*x2-c2*c1*x1/r1+r2*x1-c1*c2*x2/r2))/(cr*cr);
-
- //b = C*ft
- Double_t b00=f02*fCey + f04*fCcy, b01=f12*fCey + f14*fCcy + f13*fCty;
- Double_t b10=f02*fCez + f04*fCcz, b11=f12*fCez + f14*fCcz + f13*fCtz;
- Double_t b20=f02*fCee + f04*fCce, b21=f12*fCee + f14*fCce + f13*fCte;
- Double_t b30=f02*fCte + f04*fCct, b31=f12*fCte + f14*fCct + f13*fCtt;
- Double_t b40=f02*fCce + f04*fCcc, b41=f12*fCce + f14*fCcc + f13*fCct;
-
- //a = f*b = f*C*ft
- Double_t a00=f02*b20+f04*b40,a01=f02*b21+f04*b41,a11=f12*b21+f14*b41+f13*b31;
-
- //F*C*Ft = C + (a + b + bt)
- fCyy += a00 + 2*b00;
- fCzy += a01 + b01 + b10;
- fCey += b20;
- fCty += b30;
- fCcy += b40;
- fCzz += a11 + 2*b11;
- fCez += b21;
- fCtz += b31;
- fCcz += b41;
-
- fX=x2;
-
- //Multiple scattering ******************
- Double_t d=sqrt((x1-fX)*(x1-fX)+(y1-fY)*(y1-fY)+(z1-fZ)*(z1-fZ));
- Double_t p2=(1.+ GetTgl()*GetTgl())/(Get1Pt()*Get1Pt());
- Double_t beta2=p2/(p2 + GetMass()*GetMass());
- Double_t theta2=14.1*14.1/(beta2*p2*1e6)*d/x0*rho;
-
- Double_t ey=fC*fX - fE, ez=fT;
- Double_t xz=fC*ez, zz1=ez*ez+1, xy=fE+ey;
-
- fCee += (2*ey*ez*ez*fE+1-ey*ey+ez*ez+fE*fE*ez*ez)*theta2;
- fCte += ez*zz1*xy*theta2;
- fCtt += zz1*zz1*theta2;
- fCce += xz*ez*xy*theta2;
- fCct += xz*zz1*theta2;
- fCcc += xz*xz*theta2;
- /*
- Double_t dc22 = (1-ey*ey+xz*xz*fX*fX)*theta2;
- Double_t dc32 = (xz*fX*zz1)*theta2;
- Double_t dc33 = (zz1*zz1)*theta2;
- Double_t dc42 = (xz*fX*xz)*theta2;
- Double_t dc43 = (zz1*xz)*theta2;
- Double_t dc44 = (xz*xz)*theta2;
- fCee += dc22;
- fCte += dc32;
- fCtt += dc33;
- fCce += dc42;
- fCct += dc43;
- fCcc += dc44;
- */
- //Energy losses************************
- if((5940*beta2/(1-beta2+1e-10) - beta2) < 0) return 0;
-
- Double_t dE=0.153e-3/beta2*(log(5940*beta2/(1-beta2+1e-10)) - beta2)*d*rho;
- if (x1 < x2) dE=-dE;
- cc=fC;
- fC*=(1.- sqrt(p2+GetMass()*GetMass())/p2*dE);
- fE+=fX*(fC-cc);
-
- // track time measurement [SR, GSI 17.02.2002]
- if (x1 < x2)
- if (IsStartedTimeIntegral()) {
- Double_t l2 = (fX-oldX)*(fX-oldX) + (fY-oldY)*(fY-oldY) + (fZ-oldZ)*(fZ-oldZ);
- AddTimeStep(TMath::Sqrt(l2));
- }
-
- return 1;
-}
+ fdEdxPlane[plane][slice] += fdQdl[iClus];
+ if (fdQdl[iClus] > maxcharge[plane]) {
+ maxcharge[plane] = fdQdl[iClus];
+ fTimBinPlane[plane] = tb;
+ }
+ nCluster[plane][slice]++;
+
+ } // End of loop over cluster
+
+ // Normalize fdEdxPlane to number of clusters and set track segments
+ for (Int_t iPlane = 0; iPlane < kNplane; iPlane++) {
+ for (Int_t iSlice = 0; iSlice < kNslice; iSlice++) {
+ if (nCluster[iPlane][iSlice]) {
+ fdEdxPlane[iPlane][iSlice] /= nCluster[iPlane][iSlice];
+ }
+ }
+ }
+
+}
//_____________________________________________________________________________
-Int_t AliTRDtrack::Update(const AliTRDcluster *c, Double_t chisq, UInt_t index, Double_t h01)
+void AliTRDtrack::CookdEdxNN(Float_t *dedx)
{
- // Assignes found cluster to the track and updates track information
-
- Bool_t fNoTilt = kTRUE;
- if(TMath::Abs(h01) > 0.003) fNoTilt = kFALSE;
- // add angular effect to the error contribution - MI
- Float_t tangent2 = (fC*fX-fE)*(fC*fX-fE);
- if (tangent2 < 0.90000){
- tangent2 = tangent2/(1.-tangent2);
- }
- Float_t errang = tangent2*0.04; //
- Float_t padlength = TMath::Sqrt(c->GetSigmaZ2()*12.);
-
- Double_t r00=c->GetSigmaY2() +errang, r01=0., r11=c->GetSigmaZ2()*100.;
- r00+=fCyy; r01+=fCzy; r11+=fCzz;
- Double_t det=r00*r11 - r01*r01;
- Double_t tmp=r00; r00=r11/det; r11=tmp/det; r01=-r01/det;
-
- Double_t k00=fCyy*r00+fCzy*r01, k01=fCyy*r01+fCzy*r11;
- Double_t k10=fCzy*r00+fCzz*r01, k11=fCzy*r01+fCzz*r11;
- Double_t k20=fCey*r00+fCez*r01, k21=fCey*r01+fCez*r11;
- Double_t k30=fCty*r00+fCtz*r01, k31=fCty*r01+fCtz*r11;
- Double_t k40=fCcy*r00+fCcz*r01, k41=fCcy*r01+fCcz*r11;
-
- Double_t dy=c->GetY() - fY, dz=c->GetZ() - fZ;
- Double_t cur=fC + k40*dy + k41*dz, eta=fE + k20*dy + k21*dz;
-
-
- if(fNoTilt) {
- if (TMath::Abs(cur*fX-eta) >= 0.90000) {
- // Int_t n=GetNumberOfClusters();
- //if (n>4) cerr<<n<<" AliTRDtrack warning: Filtering failed !\n";
- return 0;
+ //
+ // This function calcuates the input for the neural networks
+ // which are used for the PID.
+ //
+
+ //number of time bins in chamber
+ Int_t ntb = AliTRDcalibDB::Instance()->GetNumberOfTimeBins();
+
+ Int_t plane; // plane of current cluster
+ Int_t tb; // time bin of current cluster
+ Int_t slice; // curent slice
+ AliTRDcluster *cluster = 0x0; // pointer to current cluster
+ const Int_t kMLPscale = 16000; // scaling of the MLP input to be smaller than 1
+
+ // Reset class and local contors/variables
+ for (Int_t iPlane = 0; iPlane < kNplane; iPlane++){
+ for (Int_t iSlice = 0; iSlice < kNMLPslice; iSlice++) {
+ *(dedx + (kNMLPslice * iPlane) + iSlice) = 0.0;
+ }
+ }
+
+ // Start looping over clusters attached to this track
+ for (Int_t iClus = 0; iClus < GetNumberOfClusters(); iClus++) {
+
+ cluster = fClusters[iClus]; //(AliTRDcluster*)tracker->GetCluster(fIndex[iClus]);
+ if (!cluster) {
+ continue;
}
- fY += k00*dy + k01*dz;
- fZ += k10*dy + k11*dz;
- fE = eta;
- //fT += k30*dy + k31*dz;
- fC = cur;
- }
- else {
- Double_t xu_factor = 100.; // empirical factor set by C.Xu
- // in the first tilt version
- dy=c->GetY() - fY; dz=c->GetZ() - fZ;
- dy=dy+h01*dz;
- Float_t add=0;
- if (TMath::Abs(dz)>padlength/2.){
- Float_t dy2 = c->GetY() - fY;
- Float_t sign = (dz>0) ? -1.: 1.;
- dy2+=h01*sign*padlength/2.;
- dy = dy2;
- add = 0;
+
+ // Read info from current cluster
+ plane = AliTRDgeometry::GetLayer(cluster->GetDetector());
+ if (plane < 0 || plane >= kNplane) {
+ AliError(Form("Wrong plane %d",plane));
+ continue;
}
-
-
-
- r00=c->GetSigmaY2()+errang+add, r01=0., r11=c->GetSigmaZ2()*xu_factor;
- r00+=(fCyy+2.0*h01*fCzy+h01*h01*fCzz);
-
- r01+=(fCzy+h01*fCzz);
- det=r00*r11 - r01*r01;
- tmp=r00; r00=r11/det; r11=tmp/det; r01=-r01/det;
-
- k00=fCyy*r00+fCzy*(r01+h01*r00),k01=fCyy*r01+fCzy*(r11+h01*r01);
- k10=fCzy*r00+fCzz*(r01+h01*r00),k11=fCzy*r01+fCzz*(r11+h01*r01);
- k20=fCey*r00+fCez*(r01+h01*r00),k21=fCey*r01+fCez*(r11+h01*r01);
- k30=fCty*r00+fCtz*(r01+h01*r00),k31=fCty*r01+fCtz*(r11+h01*r01);
- k40=fCcy*r00+fCcz*(r01+h01*r00),k41=fCcy*r01+fCcz*(r11+h01*r01);
-
-
- cur=fC + k40*dy + k41*dz; eta=fE + k20*dy + k21*dz;
- if (TMath::Abs(cur*fX-eta) >= 0.90000) {
- // Int_t n=GetNumberOfClusters();
- //if (n>4) cerr<<n<<" AliTRDtrack warning: Filtering failed !\n";
- return 0;
- }
- fY += k00*dy + k01*dz;
- fZ += k10*dy + k11*dz;
- fE = eta;
- fT += k30*dy + k31*dz;
- fC = cur;
-
- k01+=h01*k00;
- k11+=h01*k10;
- k21+=h01*k20;
- k31+=h01*k30;
- k41+=h01*k40;
-
- }
- Double_t c01=fCzy, c02=fCey, c03=fCty, c04=fCcy;
- Double_t c12=fCez, c13=fCtz, c14=fCcz;
-
-
- fCyy-=k00*fCyy+k01*fCzy; fCzy-=k00*c01+k01*fCzz;
- fCey-=k00*c02+k01*c12; fCty-=k00*c03+k01*c13;
- fCcy-=k00*c04+k01*c14;
-
- fCzz-=k10*c01+k11*fCzz;
- fCez-=k10*c02+k11*c12; fCtz-=k10*c03+k11*c13;
- fCcz-=k10*c04+k11*c14;
-
- fCee-=k20*c02+k21*c12; fCte-=k20*c03+k21*c13;
- fCce-=k20*c04+k21*c14;
-
- fCtt-=k30*c03+k31*c13;
- fCct-=k40*c03+k41*c13;
- //fCct-=k30*c04+k31*c14; // symmetric formula MI
-
- fCcc-=k40*c04+k41*c14;
- Int_t n=GetNumberOfClusters();
- fIndex[n]=index;
- SetNumberOfClusters(n+1);
+ tb = cluster->GetLocalTimeBin();
+ if (tb == 0 || tb >= ntb) {
+ AliWarning(Form("time bin 0 or > %d in cluster %d",ntb,iClus));
+ AliInfo(Form("dQ/dl %f",fdQdl[iClus]));
+ continue;
+ }
- SetChi2(GetChi2()+chisq);
- // cerr<<"in update: fIndex["<<fN<<"] = "<<index<<endl;
+ slice = tb * kNMLPslice / ntb;
+
+ *(dedx+(kNMLPslice * plane) + slice) += fdQdl[iClus]/kMLPscale;
+
+ } // End of loop over cluster
+
+}
- return 1;
-}
//_____________________________________________________________________________
-Int_t AliTRDtrack::UpdateMI(const AliTRDcluster *c, Double_t chisq, UInt_t index, Double_t h01,
- Int_t plane)
+void AliTRDtrack::SetTrackSegmentDirMom(const Int_t plane)
{
- // Assignes found cluster to the track and updates track information
+ //
+ // Set the momenta for a track segment in a given plane
+ //
- Bool_t fNoTilt = kTRUE;
- if(TMath::Abs(h01) > 0.003) fNoTilt = kFALSE;
- // add angular effect to the error contribution and make correction - MI
- //AliTRDclusterCorrection *corrector = AliTRDclusterCorrection::GetCorrection();
- //
- Double_t tangent2 = (fC*fX-fE)*(fC*fX-fE);
- if (tangent2 < 0.90000){
- tangent2 = tangent2/(1.-tangent2);
- }
- Double_t tangent = TMath::Sqrt(tangent2);
- if ((fC*fX-fE)<0) tangent*=-1;
- Double_t correction = 0*plane;
- Double_t errang = tangent2*0.04; //
- /*
- if (corrector!=0){
- //if (0){
- correction = corrector->GetCorrection(plane,c->GetLocalTimeBin(),tangent);
- if (TMath::Abs(correction)>0){
- //if we have info
- errang = corrector->GetSigma(plane,c->GetLocalTimeBin(),tangent);
- errang *= errang;
- errang += tangent2*0.04;
+ if ((plane < 0) ||
+ (plane>= kNplane)) {
+ AliError(Form("Trying to access out of range plane (%d)", plane));
+ return;
+ }
+
+ fSnp[plane] = GetSnp();
+ fTgl[plane] = GetTgl();
+ Double_t p[3];
+ GetPxPyPz(p);
+ fMom[plane] = TMath::Sqrt(p[0]*p[0] + p[1]*p[1] + p[2]*p[2]);
+
+}
+
+//_____________________________________________________________________________
+Float_t AliTRDtrack::GetTrackLengthPlane(Int_t plane) const
+{
+ //
+ // Calculate the track length of a track segment in a given plane
+ //
+
+ if ((plane < 0) ||
+ (plane >= kNplane)) {
+ return 0.0;
+ }
+
+ return (AliTRDgeometry::AmThick() + AliTRDgeometry::DrThick())
+ / TMath::Sqrt((1.0 - fSnp[plane]*fSnp[plane])
+ / (1.0 + fTgl[plane]*fTgl[plane]));
+
+}
+
+//_____________________________________________________________________________
+Bool_t AliTRDtrack::CookPID(Int_t &pidQuality)
+{
+ //
+ // This function calculates the PID probabilities based on TRD signals
+ //
+ // The method produces probabilities based on the charge
+ // and the position of the maximum time bin in each layer.
+ // The dE/dx information can be used as global charge or 2 to 3
+ // slices. Check AliTRDCalPID and AliTRDCalPIDRefMaker for the actual
+ // implementation.
+ //
+ // Author
+ // Alex Bercuci (A.Bercuci@gsi.de) 2nd May 2007
+ //
+
+ AliTRDcalibDB *calibration = AliTRDcalibDB::Instance();
+ if (!calibration) {
+ AliError("No access to calibration data");
+ return kFALSE;
+ }
+
+ // Retrieve the CDB container class with the probability distributions
+ const AliTRDCalPID *pd = calibration->GetPIDObject(AliTRDReconstructor::kLQPID);
+ if (!pd) {
+ AliError("No access to AliTRDCalPID");
+ return kFALSE;
+ }
+
+ // Calculate the input for the NN if fPIDmethod is kNN
+ Float_t ldEdxNN[AliTRDCalPID::kNPlane * kNMLPslice], *dedx = 0x0;
+ if(fPIDmethod == kNN) {
+ CookdEdxNN(&ldEdxNN[0]);
+ }
+
+ // Sets the a priori probabilities
+ for(int ispec=0; ispec<AliPID::kSPECIES; ispec++) {
+ fPID[ispec] = 1.0 / AliPID::kSPECIES;
+ }
+
+ if(AliPID::kSPECIES != 5){
+ AliError("Probabilities array defined only for 5 values. Please modify !!");
+ return kFALSE;
+ }
+
+ pidQuality = 0;
+ Float_t length; // track segment length in chamber
+
+ // Skip tracks which have no TRD signal at all
+ if (fdEdx == 0.) return kFALSE;
+
+ for (Int_t iPlane = 0; iPlane < AliTRDgeometry::kNlayer; iPlane++) {
+
+ length = (AliTRDgeometry::AmThick() + AliTRDgeometry::DrThick())
+ / TMath::Sqrt((1.0 - fSnp[iPlane]*fSnp[iPlane])
+ / (1.0 + fTgl[iPlane]*fTgl[iPlane]));
+
+ // check data
+ if((fdEdxPlane[iPlane][0] + fdEdxPlane[iPlane][1] + fdEdxPlane[iPlane][2]) <= 0.
+ || fTimBinPlane[iPlane] == -1.) continue;
+
+ // this track segment has fulfilled all requierments
+ pidQuality++;
+
+ // Get the probabilities for the different particle species
+ for (Int_t iSpecies = 0; iSpecies < AliPID::kSPECIES; iSpecies++) {
+ switch(fPIDmethod){
+ case kLQ:
+ dedx = fdEdxPlane[iPlane];
+ break;
+ case kNN:
+ dedx = &ldEdxNN[iPlane*kNMLPslice];
+ break;
+ }
+ fPID[iSpecies] *= pd->GetProbability(iSpecies, fMom[iPlane], dedx, length, iPlane);
}
+
+ }
+
+ if (pidQuality == 0) {
+ return kTRUE;
+ }
+
+ // normalize probabilities
+ Double_t probTotal = 0.0;
+ for (Int_t iSpecies = 0; iSpecies < AliPID::kSPECIES; iSpecies++) {
+ probTotal += fPID[iSpecies];
}
- */
+
+ if (probTotal <= 0.0) {
+ AliWarning("The total probability over all species <= 0.");
+ AliWarning("This may be caused by some error in the reference histograms.");
+ return kFALSE;
+ }
+
+ for (Int_t iSpecies = 0; iSpecies < AliPID::kSPECIES; iSpecies++) {
+ fPID[iSpecies] /= probTotal;
+ }
+
+ return kTRUE;
+
+}
+
+//_____________________________________________________________________________
+Bool_t AliTRDtrack::PropagateTo(Double_t xk, Double_t xx0, Double_t xrho)
+{
//
- Double_t padlength = TMath::Sqrt(c->GetSigmaZ2()*12.);
+ // Propagates this track to a reference plane defined by "xk" [cm]
+ // correcting for the mean crossed material.
+ //
+ // "xx0" - thickness/rad.length [units of the radiation length]
+ // "xrho" - thickness*density [g/cm^2]
+ //
- Double_t r00=c->GetSigmaY2() +errang, r01=0., r11=c->GetSigmaZ2()*10000.;
- r00+=fCyy; r01+=fCzy; r11+=fCzz;
- Double_t det=r00*r11 - r01*r01;
- Double_t tmp=r00; r00=r11/det; r11=tmp/det; r01=-r01/det;
+ if (xk == GetX()) {
+ return kTRUE;
+ }
- Double_t k00=fCyy*r00+fCzy*r01, k01=fCyy*r01+fCzy*r11;
- Double_t k10=fCzy*r00+fCzz*r01, k11=fCzy*r01+fCzz*r11;
- Double_t k20=fCey*r00+fCez*r01, k21=fCey*r01+fCez*r11;
- Double_t k30=fCty*r00+fCtz*r01, k31=fCty*r01+fCtz*r11;
- Double_t k40=fCcy*r00+fCcz*r01, k41=fCcy*r01+fCcz*r11;
+ Double_t oldX = GetX();
+ Double_t oldY = GetY();
+ Double_t oldZ = GetZ();
- Double_t dy=c->GetY() - fY, dz=c->GetZ() - fZ;
- Double_t cur=fC + k40*dy + k41*dz, eta=fE + k20*dy + k21*dz;
+ Double_t bz = GetBz();
+ if (!AliExternalTrackParam::PropagateTo(xk,bz)) {
+ return kFALSE;
+ }
- if(fNoTilt) {
- if (TMath::Abs(cur*fX-eta) >= 0.90000) {
- // Int_t n=GetNumberOfClusters();
- //if (n>4) cerr<<n<<" AliTRDtrack warning: Filtering failed !\n";
- return 0;
+ Double_t x = GetX();
+ Double_t y = GetY();
+ Double_t z = GetZ();
+
+ if (oldX < xk) {
+ xrho = -xrho;
+ if (IsStartedTimeIntegral()) {
+ Double_t l2 = TMath::Sqrt((x-oldX)*(x-oldX)
+ + (y-oldY)*(y-oldY)
+ + (z-oldZ)*(z-oldZ));
+ Double_t crv = GetC();
+ if (TMath::Abs(l2*crv) > 0.0001) {
+ // Make correction for curvature if neccesary
+ l2 = 0.5 * TMath::Sqrt((x-oldX)*(x-oldX)
+ + (y-oldY)*(y-oldY));
+ l2 = 2.0 * TMath::ASin(l2 * crv) / crv;
+ l2 = TMath::Sqrt(l2*l2 + (z-oldZ)*(z-oldZ));
+ }
+ AddTimeStep(l2);
}
- fY += k00*dy + k01*dz;
- fZ += k10*dy + k11*dz;
- fE = eta;
- //fT += k30*dy + k31*dz;
- fC = cur;
- }
- else {
- Double_t xu_factor = 1000.; // empirical factor set by C.Xu
- // in the first tilt version
- dy=c->GetY() - fY; dz=c->GetZ() - fZ;
- dy=dy+h01*dz+correction;
- Double_t add=0;
- if (TMath::Abs(dz)>padlength/2.){
- //Double_t dy2 = c->GetY() - fY;
- //Double_t sign = (dz>0) ? -1.: 1.;
- //dy2-=h01*sign*padlength/2.;
- //dy = dy2;
- add =1.;
+ }
+
+ if (!AliExternalTrackParam::CorrectForMeanMaterial(xx0,xrho,GetMass())) {
+ return kFALSE;
+ }
+
+ {
+
+ // Energy losses
+ Double_t p2 = (1.0 + GetTgl()*GetTgl()) / (GetSigned1Pt()*GetSigned1Pt());
+ Double_t beta2 = p2 / (p2 + GetMass()*GetMass());
+ if ((beta2 < 1.0e-10) ||
+ ((5940.0 * beta2/(1.0 - beta2 + 1.0e-10) - beta2) < 0.0)) {
+ return kFALSE;
}
- Double_t s00 = c->GetSigmaY2()+errang+add; // error pad
- Double_t s11 = c->GetSigmaZ2()*xu_factor; // error pad-row
- //
- r00 = fCyy + 2*fCzy*h01 + fCzz*h01*h01+s00;
- r01 = fCzy + fCzz*h01;
- r11 = fCzz + s11;
- det = r00*r11 - r01*r01;
- // inverse matrix
- tmp=r00; r00=r11/det; r11=tmp/det; r01=-r01/det;
-
- // K matrix
- k00=fCyy*r00+fCzy*(r01+h01*r00),k01=fCyy*r01+fCzy*(r11+h01*r01);
- k10=fCzy*r00+fCzz*(r01+h01*r00),k11=fCzy*r01+fCzz*(r11+h01*r01);
- k20=fCey*r00+fCez*(r01+h01*r00),k21=fCey*r01+fCez*(r11+h01*r01);
- k30=fCty*r00+fCtz*(r01+h01*r00),k31=fCty*r01+fCtz*(r11+h01*r01);
- k40=fCcy*r00+fCcz*(r01+h01*r00),k41=fCcy*r01+fCcz*(r11+h01*r01);
- //
- //Update measurement
- cur=fC + k40*dy + k41*dz; eta=fE + k20*dy + k21*dz;
- if (TMath::Abs(cur*fX-eta) >= 0.90000) {
- //Int_t n=GetNumberOfClusters();
- // if (n>4) cerr<<n<<" AliTRDtrack warning: Filtering failed !\n";
- return 0;
- }
- fY += k00*dy + k01*dz;
- fZ += k10*dy + k11*dz;
- fE = eta;
- fT += k30*dy + k31*dz;
- fC = cur;
-
- k01+=h01*k00;
- k11+=h01*k10;
- k21+=h01*k20;
- k31+=h01*k30;
- k41+=h01*k40;
-
- }
- //Update covariance
- //
- //
- Double_t oldyy = fCyy, oldzz = fCzz; //, oldee=fCee, oldcc =fCcc;
- Double_t oldzy = fCzy, oldey = fCey, oldty=fCty, oldcy =fCcy;
- Double_t oldez = fCez, oldtz = fCtz, oldcz=fCcz;
- //Double_t oldte = fCte, oldce = fCce;
- //Double_t oldct = fCct;
-
- fCyy-=k00*oldyy+k01*oldzy;
- fCzy-=k10*oldyy+k11*oldzy;
- fCey-=k20*oldyy+k21*oldzy;
- fCty-=k30*oldyy+k31*oldzy;
- fCcy-=k40*oldyy+k41*oldzy;
- //
- fCzz-=k10*oldzy+k11*oldzz;
- fCez-=k20*oldzy+k21*oldzz;
- fCtz-=k30*oldzy+k31*oldzz;
- fCcz-=k40*oldzy+k41*oldzz;
- //
- fCee-=k20*oldey+k21*oldez;
- fCte-=k30*oldey+k31*oldez;
- fCce-=k40*oldey+k41*oldez;
- //
- fCtt-=k30*oldty+k31*oldtz;
- fCct-=k40*oldty+k41*oldtz;
- //
- fCcc-=k40*oldcy+k41*oldcz;
- //
-
- Int_t n=GetNumberOfClusters();
- fIndex[n]=index;
+
+ Double_t dE = 0.153e-3 / beta2
+ * (TMath::Log(5940.0 * beta2/(1.0 - beta2 + 1.0e-10)) - beta2)
+ * xrho;
+ fBudget[0] += xrho;
+
+ /*
+ // Suspicious part - think about it ?
+ Double_t kinE = TMath::Sqrt(p2);
+ if (dE > 0.8*kinE) dE = 0.8 * kinE; //
+ if (dE < 0) dE = 0.0; // Not valid region for Bethe bloch
+ */
+
+ fDE += dE;
+
+ /*
+ // Suspicious ! I.B.
+ Double_t sigmade = 0.07 * TMath::Sqrt(TMath::Abs(dE)); // Energy loss fluctuation
+ Double_t sigmac2 = sigmade*sigmade*fC*fC*(p2+GetMass()*GetMass())/(p2*p2);
+ fCcc += sigmac2;
+ fCee += fX*fX * sigmac2;
+ */
+
+ }
+
+ return kTRUE;
+
+}
+
+//_____________________________________________________________________________
+Bool_t AliTRDtrack::Update(const AliTRDcluster *c, Double_t chisq
+ , Int_t index, Double_t h01)
+{
+ //
+ // Assignes the found cluster <c> to the track and updates
+ // track information.
+ // <chisq> : predicted chi2
+ // <index> : ??
+ // <h01> : Tilting factor
+ //
+
+ Double_t p[2] = { c->GetY()
+ , c->GetZ() };
+ Double_t sy2 = c->GetSigmaY2() * 4.0;
+ Double_t sz2 = c->GetSigmaZ2() * 4.0;
+ Double_t cov[3] = { sy2 + h01*h01*sz2
+ , h01 * (sy2-sz2)
+ , sz2 + h01*h01*sy2 };
+
+ if (!AliExternalTrackParam::Update(p,cov)) {
+ return kFALSE;
+ }
+
+ Int_t n = GetNumberOfClusters();
+ fIndex[n] = index;
SetNumberOfClusters(n+1);
SetChi2(GetChi2()+chisq);
- // cerr<<"in update: fIndex["<<fN<<"] = "<<index<<endl;
- return 1;
-}
+ return kTRUE;
+}
//_____________________________________________________________________________
-Int_t AliTRDtrack::Rotate(Double_t alpha)
+Int_t AliTRDtrack::UpdateMI(AliTRDcluster *c, Double_t chisq, Int_t index
+ , Double_t h01, Int_t /*plane*/, Int_t /*tid*/)
{
- // Rotates track parameters in R*phi plane
-
- fNRotate++;
+ //
+ // Assignes the found cluster <c> to the track and
+ // updates track information
+ // <chisq> : predicted chi2
+ // <index> : ??
+ // <h01> : Tilting factor
+ //
+ // Difference to Update(AliTRDcluster *c): cluster is added to fClusters
+ //
- fAlpha += alpha;
- if (fAlpha<-TMath::Pi()) fAlpha += 2*TMath::Pi();
- if (fAlpha>=TMath::Pi()) fAlpha -= 2*TMath::Pi();
+ Double_t p[2] = { c->GetY()
+ , c->GetZ() };
+ Double_t sy2 = c->GetSigmaY2() * 4.0;
+ Double_t sz2 = c->GetSigmaZ2() * 4.0;
+ Double_t cov[3] = { sy2 + h01*h01*sz2
+ , h01 * (sy2-sz2)
+ , sz2 + h01*h01*sy2 };
- Double_t x1=fX, y1=fY;
- Double_t ca=cos(alpha), sa=sin(alpha);
- Double_t r1=fC*fX - fE;
+ if (!AliExternalTrackParam::Update(p,cov)) {
+ return kFALSE;
+ }
+
+ AliTracker::FillResiduals(this,p,cov,c->GetVolumeId());
- fX = x1*ca + y1*sa;
- fY =-x1*sa + y1*ca;
- if((r1*r1) > 1) return 0;
- fE=fE*ca + (fC*y1 + sqrt(1.- r1*r1))*sa;
+ // Register cluster to track
+ Int_t n = GetNumberOfClusters();
+ fIndex[n] = index;
+ fClusters[n] = c;
+ SetNumberOfClusters(n+1);
+ SetChi2(GetChi2() + chisq);
- Double_t r2=fC*fX - fE;
- if (TMath::Abs(r2) >= 0.90000) {
- Int_t n=GetNumberOfClusters();
- if (n>4) cerr<<n<<" AliTRDtrack warning: Rotation failed !\n";
- return 0;
- }
+ return kTRUE;
- if((r2*r2) > 1) return 0;
- Double_t y0=fY + sqrt(1.- r2*r2)/fC;
- if ((fY-y0)*fC >= 0.) {
- Int_t n=GetNumberOfClusters();
- if (n>4) cerr<<n<<" AliTRDtrack warning: Rotation failed !!!\n";
- return 0;
+}
+
+//_____________________________________________________________________________
+Bool_t AliTRDtrack::Update(const AliTRDtracklet &t, Double_t chisq, Int_t index)
+{
+ //
+ // Assignes the found tracklet <t> to the track
+ // and updates track information
+ // <chisq> : predicted chi2
+ // <index> : ??
+ //
+
+ Double_t h01 = t.GetTilt(); // Is this correct????
+ Double_t p[2] = { t.GetY(), t.GetZ() };
+ Double_t sy2 = t.GetTrackletSigma2(); // Error pad-column
+ Double_t sz2 = 100000.0; // Error pad-row (????)
+ Double_t cov[3] = { sy2 + h01*h01*sz2 // Does this have any sense????
+ , h01 * (sy2 - sz2)
+ , sz2 + h01*h01*sy2 };
+ if (!AliExternalTrackParam::Update(p,cov)) {
+ return kFALSE;
}
- //f = F - 1
- Double_t f00=ca-1, f24=(y1 - r1*x1/sqrt(1.- r1*r1))*sa,
- f20=fC*sa, f22=(ca + sa*r1/sqrt(1.- r1*r1))-1;
+ Int_t n = GetNumberOfClusters();
+ fIndex[n] = index;
+ SetNumberOfClusters(n+1);
+ SetChi2(GetChi2()+chisq);
- //b = C*ft
- Double_t b00=fCyy*f00, b02=fCyy*f20+fCcy*f24+fCey*f22;
- Double_t b10=fCzy*f00, b12=fCzy*f20+fCcz*f24+fCez*f22;
- Double_t b20=fCey*f00, b22=fCey*f20+fCce*f24+fCee*f22;
- Double_t b30=fCty*f00, b32=fCty*f20+fCct*f24+fCte*f22;
- Double_t b40=fCcy*f00, b42=fCcy*f20+fCcc*f24+fCce*f22;
+ return kTRUE;
- //a = f*b = f*C*ft
- Double_t a00=f00*b00, a02=f00*b02, a22=f20*b02+f24*b42+f22*b22;
+}
+
+//_____________________________________________________________________________
+Bool_t AliTRDtrack::Rotate(Double_t alpha, Bool_t absolute)
+{
+ //
+ // Rotates track parameters in R*phi plane
+ // if absolute rotation alpha is in global system
+ // otherwise alpha rotation is relative to the current rotation angle
+ //
- //F*C*Ft = C + (a + b + bt)
- fCyy += a00 + 2*b00;
- fCzy += b10;
- fCey += a02+b20+b02;
- fCty += b30;
- fCcy += b40;
- fCez += b12;
- fCte += b32;
- fCee += a22 + 2*b22;
- fCce += b42;
+ if (absolute) {
+ alpha -= GetAlpha();
+ }
+ else{
+ fNRotate++;
+ }
- return 1;
-}
+ return AliExternalTrackParam::Rotate(GetAlpha()+alpha);
+}
//_____________________________________________________________________________
Double_t AliTRDtrack::GetPredictedChi2(const AliTRDcluster *c, Double_t h01) const
{
+ //
+ // Returns the track chi2
+ //
+
+ Double_t p[2] = { c->GetY()
+ , c->GetZ() };
+ Double_t sy2 = c->GetSigmaY2() * 4.0;
+ Double_t sz2 = c->GetSigmaZ2() * 4.0;
+ Double_t cov[3] = { sy2 + h01*h01*sz2
+ , h01*(sy2-sz2)
+ , sz2 + h01*h01*sy2 };
+
+ return AliExternalTrackParam::GetPredictedChi2(p,cov);
+
+}
+
+//_____________________________________________________________________________
+void AliTRDtrack::MakeBackupTrack()
+{
+ //
+ // Creates a backup track
+ //
+
+ if (fBackupTrack) {
+ delete fBackupTrack;
+ }
+ fBackupTrack = new AliTRDtrack(*this);
- Bool_t fNoTilt = kTRUE;
- if(TMath::Abs(h01) > 0.003) fNoTilt = kFALSE;
- Double_t chi2, dy, r00, r01, r11;
-
- if(fNoTilt) {
- dy=c->GetY() - fY;
- r00=c->GetSigmaY2();
- chi2 = (dy*dy)/r00;
- }
- else {
- r00=c->GetSigmaY2(); r01=0.; r11=c->GetSigmaZ2();
- r00+=fCyy; r01+=fCzy; r11+=fCzz;
-
- Double_t det=r00*r11 - r01*r01;
- if (TMath::Abs(det) < 1.e-10) {
- Int_t n=GetNumberOfClusters();
- if (n>4) cerr<<n<<" AliTRDtrack warning: Singular matrix !\n";
- return 1e10;
- }
- Double_t tmp=r00; r00=r11; r11=tmp; r01=-r01;
- Double_t dy=c->GetY() - fY, dz=c->GetZ() - fZ;
- dy=dy+h01*dz;
+}
+
+//_____________________________________________________________________________
+Int_t AliTRDtrack::GetProlongation(Double_t xk, Double_t &y, Double_t &z)
+{
+ //
+ // Find a prolongation at given x
+ // Return 0 if it does not exist
+ //
- chi2 = (dy*r00*dy + 2*r01*dy*dz + dz*r11*dz)/det;
+ Double_t bz = GetBz();
+
+ if (!AliExternalTrackParam::GetYAt(xk,bz,y)) {
+ return 0;
+ }
+ if (!AliExternalTrackParam::GetZAt(xk,bz,z)) {
+ return 0;
}
- return chi2;
-}
+ return 1;
-//_________________________________________________________________________
-void AliTRDtrack::GetPxPyPz(Double_t& px, Double_t& py, Double_t& pz) const
+}
+
+//_____________________________________________________________________________
+Int_t AliTRDtrack::PropagateToX(Double_t xr, Double_t step)
{
- // Returns reconstructed track momentum in the global system.
+ //
+ // Propagate track to given x position
+ // Works inside of the 20 degree segmentation
+ // (local cooordinate frame for TRD , TPC, TOF)
+ //
+ // Material budget from geo manager
+ //
+
+ Double_t xyz0[3];
+ Double_t xyz1[3];
+ Double_t y;
+ Double_t z;
+
+ const Double_t kAlphac = TMath::Pi()/9.0;
+ const Double_t kTalphac = TMath::Tan(kAlphac*0.5);
+
+ // Critical alpha - cross sector indication
+ Double_t dir = (GetX() > xr) ? -1.0 : 1.0;
+
+ // Direction +-
+ for (Double_t x = GetX()+dir*step; dir*x < dir*xr; x += dir*step) {
- Double_t pt=TMath::Abs(GetPt()); // GeV/c
- Double_t r=fC*fX-fE;
+ GetXYZ(xyz0);
+ GetProlongation(x,y,z);
+ xyz1[0] = x * TMath::Cos(GetAlpha()) + y * TMath::Sin(GetAlpha());
+ xyz1[1] = x * TMath::Sin(GetAlpha()) - y * TMath::Cos(GetAlpha());
+ xyz1[2] = z;
+ Double_t param[7];
+ AliTracker::MeanMaterialBudget(xyz0,xyz1,param);
+
+ if ((param[0] > 0) &&
+ (param[1] > 0)) {
+ PropagateTo(x,param[1],param[0]*param[4]);
+ }
+
+ if (GetY() > GetX()*kTalphac) {
+ Rotate(-kAlphac);
+ }
+ if (GetY() < -GetX()*kTalphac) {
+ Rotate( kAlphac);
+ }
- Double_t y0;
- if(r > 1) { py = pt; px = 0; }
- else if(r < -1) { py = -pt; px = 0; }
- else {
- y0=fY + sqrt(1.- r*r)/fC;
- px=-pt*(fY-y0)*fC; //cos(phi);
- py=-pt*(fE-fX*fC); //sin(phi);
}
- pz=pt*fT;
- Double_t tmp=px*TMath::Cos(fAlpha) - py*TMath::Sin(fAlpha);
- py=px*TMath::Sin(fAlpha) + py*TMath::Cos(fAlpha);
- px=tmp;
-}
+ PropagateTo(xr);
-//_________________________________________________________________________
-void AliTRDtrack::GetGlobalXYZ(Double_t& x, Double_t& y, Double_t& z) const
+ return 0;
+
+}
+
+//_____________________________________________________________________________
+Int_t AliTRDtrack::PropagateToR(Double_t r,Double_t step)
{
- // Returns reconstructed track coordinates in the global system.
+ //
+ // Propagate track to the radial position
+ // Rotation always connected to the last track position
+ //
+
+ Double_t xyz0[3];
+ Double_t xyz1[3];
+ Double_t y;
+ Double_t z;
+
+ Double_t radius = TMath::Sqrt(GetX()*GetX() + GetY()*GetY());
+ // Direction +-
+ Double_t dir = (radius > r) ? -1.0 : 1.0;
+
+ for (Double_t x = radius+dir*step; dir*x < dir*r; x += dir*step) {
+
+ GetXYZ(xyz0);
+ Double_t alpha = TMath::ATan2(xyz0[1],xyz0[0]);
+ Rotate(alpha,kTRUE);
+ GetXYZ(xyz0);
+ GetProlongation(x,y,z);
+ xyz1[0] = x * TMath::Cos(alpha) + y * TMath::Sin(alpha);
+ xyz1[1] = x * TMath::Sin(alpha) - y * TMath::Cos(alpha);
+ xyz1[2] = z;
+ Double_t param[7];
+ AliTracker::MeanMaterialBudget(xyz0,xyz1,param);
+ if (param[1] <= 0) {
+ param[1] = 100000000;
+ }
+ PropagateTo(x,param[1],param[0]*param[4]);
+
+ }
+
+ GetXYZ(xyz0);
+ Double_t alpha = TMath::ATan2(xyz0[1],xyz0[0]);
+ Rotate(alpha,kTRUE);
+ GetXYZ(xyz0);
+ GetProlongation(r,y,z);
+ xyz1[0] = r * TMath::Cos(alpha) + y * TMath::Sin(alpha);
+ xyz1[1] = r * TMath::Sin(alpha) - y * TMath::Cos(alpha);
+ xyz1[2] = z;
+ Double_t param[7];
+ AliTracker::MeanMaterialBudget(xyz0,xyz1,param);
+
+ if (param[1] <= 0) {
+ param[1] = 100000000;
+ }
+ PropagateTo(r,param[1],param[0]*param[4]);
- x = fX; y = fY; z = fZ;
- Double_t tmp=x*TMath::Cos(fAlpha) - y*TMath::Sin(fAlpha);
- y=x*TMath::Sin(fAlpha) + y*TMath::Cos(fAlpha);
- x=tmp;
+ return 0;
-}
+}
-//_________________________________________________________________________
-void AliTRDtrack::ResetCovariance() {
+//_____________________________________________________________________________
+Int_t AliTRDtrack::GetSector() const
+{
//
- // Resets covariance matrix
+ // Return the current sector
//
- fCyy*=10.;
- fCzy=0.; fCzz*=10.;
- fCey=0.; fCez=0.; fCee*=10.;
- fCty=0.; fCtz=0.; fCte=0.; fCtt*=10.;
- fCcy=0.; fCcz=0.; fCce=0.; fCct=0.; fCcc*=10.;
-}
+ return Int_t(TVector2::Phi_0_2pi(GetAlpha()) / AliTRDgeometry::GetAlpha())
+ % AliTRDgeometry::kNsector;
-void AliTRDtrack::ResetCovariance(Float_t mult) {
+}
+
+//_____________________________________________________________________________
+void AliTRDtrack::SetSampledEdx(Float_t q, Int_t i)
+{
//
- // Resets covariance matrix
+ // The sampled energy loss
//
- fCyy*=mult;
- fCzy*=0.; fCzz*=mult;
- fCey*=0.; fCez*=0.; fCee*=mult;
- fCty*=0.; fCtz*=0.; fCte*=0.; fCtt*=mult;
- fCcy*=0.; fCcz*=0.; fCce*=0.; fCct*=0.; fCcc*=mult;
-}
+ Double_t s = GetSnp();
+ Double_t t = GetTgl();
+ q *= TMath::Sqrt((1.0 - s*s) / (1.0 + t*t));
+ fdQdl[i] = q;
+}
-void AliTRDtrack::MakeBackupTrack()
+//_____________________________________________________________________________
+void AliTRDtrack::SetSampledEdx(Float_t q)
{
//
+ // The sampled energy loss
//
- if (fBackupTrack) delete fBackupTrack;
- fBackupTrack = new AliTRDtrack(*this);
+
+ Double_t s = GetSnp();
+ Double_t t = GetTgl();
+ q *= TMath::Sqrt((1.0 - s*s) / (1.0 + t*t));
+ fdQdl[fNdedx] = q;
+ fNdedx++;
+
+}
+
+//_____________________________________________________________________________
+Double_t AliTRDtrack::GetBz() const
+{
+ //
+ // Returns Bz component of the magnetic field (kG)
+ //
+
+ if (AliTracker::UniformField()) {
+ return AliTracker::GetBz();
+ }
+ Double_t r[3];
+ GetXYZ(r);
+
+ return AliTracker::GetBz(r);
+
}