]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - TRD/AliTRDtrack.cxx
Unicor is lower case now (Stefan)
[u/mrichter/AliRoot.git] / TRD / AliTRDtrack.cxx
index f5efc943eacb2d5c6405b3ec1b6680c13b56be37..d40b5996fa0b97b5a3e0b8d9b5765a4dffa1a51c 100644 (file)
 
 /* $Id$ */
 
-#include <Riostream.h>
-#include <TMath.h>
 #include <TVector2.h>
 
-#include "AliESDtrack.h"
+#include "AliTracker.h"
+
 #include "AliTRDgeometry.h" 
 #include "AliTRDcluster.h" 
 #include "AliTRDtrack.h"
-#include "AliTRDtracklet.h"
+#include "AliTRDcalibDB.h"
+#include "Cal/AliTRDCalPID.h"
 
 ClassImp(AliTRDtrack)
 
@@ -40,29 +40,10 @@ AliTRDtrack::AliTRDtrack()
   ,fSeedLab(-1)
   ,fdEdx(0)
   ,fDE(0)
-  ,fAlpha(0)
-  ,fX(0)
+  ,fPIDquality(0)
+  ,fClusterOwner(kFALSE)
+  ,fPIDmethod(kLQ)
   ,fStopped(kFALSE)
-  ,fY(0)
-  ,fZ(0)
-  ,fE(0)
-  ,fT(0)
-  ,fC(0)
-  ,fCyy(1e10)
-  ,fCzy(0)
-  ,fCzz(1e10)
-  ,fCey(0)
-  ,fCez(0)
-  ,fCee(1e10)
-  ,fCty(0)
-  ,fCtz(0)
-  ,fCte(0)
-  ,fCtt(1e10)
-  ,fCcy(0)
-  ,fCcz(0)
-  ,fCce(0)
-  ,fCct(0)
-  ,fCcc(1e10)
   ,fLhElectron(0)
   ,fNWrong(0)
   ,fNRotate(0)
@@ -78,61 +59,46 @@ AliTRDtrack::AliTRDtrack()
   // AliTRDtrack default constructor
   //
 
-  Int_t  i = 0;
-  Int_t  j = 0;
-  UInt_t k = 0;
-
-  for (i = 0; i < kNplane; i++) {
-    for (j = 0; j < kNslice; j++) {
-      fdEdxPlane[i][j] = 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;      
   }
 
-  for (k = 0; k < kMAXCLUSTERSPERTRACK; k++) {
-    fIndex[k]       = 0;
-    fIndexBackup[k] = 0;
-    fdQdl[k]        = 0;
+  for (UInt_t i = 0; i < kMAXCLUSTERSPERTRACK; i++) {
+    fIndex[i]       = 0;
+    fIndexBackup[i] = 0;
+    fdQdl[i]        = 0;
+    fClusters[i]    = 0x0;
   }
 
-  for (i = 0; i < 3; i++) {
-    fBudget[i]      = 0;
+  for (Int_t i = 0; i < 3; i++) {
+    fBudget[i] = 0;
   }
 
 }
 
 //_____________________________________________________________________________
-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() 
+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.0)
-  ,fDE(0.0)
-  ,fAlpha(alpha)
-  ,fX(xref)
+  ,fdEdx(0)
+  ,fDE(0)
+  ,fPIDquality(0)
+  ,fClusterOwner(kFALSE)
+  ,fPIDmethod(kLQ)
   ,fStopped(kFALSE)
-  ,fY(xx[0])
-  ,fZ(xx[1])
-  ,fE(xx[2])
-  ,fT(xx[3])
-  ,fC(xx[4])
-  ,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])  
-  ,fLhElectron(0.0)
+  ,fLhElectron(0)
   ,fNWrong(0)
   ,fNRotate(0)
   ,fNCross(0)
@@ -144,82 +110,80 @@ AliTRDtrack::AliTRDtrack(const AliTRDcluster *c, UInt_t index,
   ,fBackupTrack(0x0)
 {
   //
-  // AliTRDtrack main constructor
+  // The main AliTRDtrack constructor.
   //
 
-  Int_t  i = 0;
-  Int_t  j = 0;
-  UInt_t k = 0;
+  Double_t cnv   = 1.0 / (GetBz() * kB2C);
 
-  if (fAlpha <  -TMath::Pi()) {
-    fAlpha += 2.0 * TMath::Pi();
-  }
-  if (fAlpha >=  TMath::Pi()) {
-    fAlpha -= 2.0 * TMath::Pi();   
-  } 
+  Double_t pp[5] = { p[0]    
+                   , p[1]
+                   , x*p[4] - p[2]
+                   , p[3]
+                   , p[4]*cnv      };
 
-  SaveLocalConvConst();
+  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];
 
-  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;
 
-  for (i = 0; i < kNplane; i++) {
-    for (j = 0; j < kNslice; j++) {
-      fdEdxPlane[i][j] = 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;      
   }
 
   Double_t q = TMath::Abs(c->GetQ());
-  Double_t s = fX * fC - fE;
-  Double_t t = fT;
-  if (s*s < 1.0) {
+  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 (k = 1; k < kMAXCLUSTERSPERTRACK; k++) {
-    fdQdl[k]        = 0;
-    fIndex[k]       = 0;
-    fIndexBackup[k] = 0; 
+
+  fdQdl[0] = q;        
+  for (UInt_t i = 1; i < kMAXCLUSTERSPERTRACK; i++) {
+    fdQdl[i]        = 0;
+    fIndex[i]       = 0;
+    fIndexBackup[i] = 0;
+    fClusters[i]    = 0x0;
   }
 
-  for (i = 0; i < 3; i++) { 
+  for (Int_t i = 0; i < 3;i++) {
     fBudget[i]      = 0;
   }
 
 }                              
            
 //_____________________________________________________________________________
-AliTRDtrack::AliTRDtrack(const AliTRDtrack &t
+AliTRDtrack::AliTRDtrack(const AliTRDtrack &t/*, const Bool_t owner*/)
   :AliKalmanTrack(t) 
-  ,fSeedLab(t.fSeedLab)
+  ,fSeedLab(t.GetSeedLabel())
   ,fdEdx(t.fdEdx)
   ,fDE(t.fDE)
-  ,fAlpha(t.fAlpha)
-  ,fX(t.fX)
+  ,fPIDquality(t.fPIDquality)
+  ,fClusterOwner(kTRUE)
+  ,fPIDmethod(t.fPIDmethod)
   ,fStopped(t.fStopped)
-  ,fY(t.fY)
-  ,fZ(t.fZ)
-  ,fE(t.fE)
-  ,fT(t.fT)
-  ,fC(t.fC)
-  ,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)  
-  ,fLhElectron(0.0)
+  ,fLhElectron(0)
   ,fNWrong(t.fNWrong)
   ,fNRotate(t.fNRotate)
   ,fNCross(t.fNCross)
@@ -234,69 +198,57 @@ AliTRDtrack::AliTRDtrack(const AliTRDtrack &t)
   // Copy constructor.
   //
 
-  Int_t  i = 0;
-  Int_t  j = 0;
-  UInt_t k = 0;
-
-  for (i = 0; i < kNplane; i++) {
-    for (j = 0; j < kNslice; j++) {
+  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];
   }
 
   Int_t n = t.GetNumberOfClusters(); 
-  for (i = 0; i < n; i++) {
+  SetNumberOfClusters(n);
+
+  for (Int_t i = 0; i < n; i++) {
     fIndex[i]       = t.fIndex[i];
     fIndexBackup[i] = t.fIndex[i];
     fdQdl[i]        = t.fdQdl[i];
-  }
-  for (k = n; k < kMAXCLUSTERSPERTRACK; k++) {
-    fdQdl[k]        = 0;
-    fIndex[k]       = 0;
-    fIndexBackup[k] = 0; 
+    if (fClusterOwner && t.fClusters[i]) {
+      fClusters[i] = new AliTRDcluster(*(t.fClusters[i]));
+    }
+    else {
+      fClusters[i] = t.fClusters[i];
+    }
   }
 
-  for (i = 0; i < 6; i++) {
-    fTracklets[i] = t.fTracklets[i];
+  for (UInt_t i = n; i < kMAXCLUSTERSPERTRACK; i++) {
+    fdQdl[i]        = 0;
+    fIndex[i]       = 0;
+    fIndexBackup[i] = 0;
+    fClusters[i]    = 0x0;
   }
 
-  for (i = 0; i < 3; i++) { 
-    fBudget[i]    = t.fBudget[i];
+  for (Int_t i = 0; i < 3;i++) {
+    fBudget[i]      = t.fBudget[i];
   }
 
-}                                
+       for(Int_t ispec = 0; ispec<AliPID::kSPECIES; ispec++) fPID[ispec] = t.fPID[ispec];
+}
 
 //_____________________________________________________________________________
-AliTRDtrack::AliTRDtrack(const AliKalmanTrack &t, Double_t alpha
+AliTRDtrack::AliTRDtrack(const AliKalmanTrack &t, Double_t /*alpha*/
   :AliKalmanTrack(t) 
   ,fSeedLab(-1)
   ,fdEdx(t.GetPIDsignal())
   ,fDE(0)
-  ,fAlpha(alpha)
-  ,fX(0)
+  ,fPIDquality(0)
+  ,fClusterOwner(kFALSE)
+  ,fPIDmethod(kLQ)
   ,fStopped(kFALSE)
-  ,fY(0)
-  ,fZ(0)
-  ,fE(0)
-  ,fT(0)
-  ,fC(0)
-  ,fCyy(0)
-  ,fCzy(0)
-  ,fCzz(0)
-  ,fCey(0)
-  ,fCez(0)
-  ,fCee(0)
-  ,fCty(0)
-  ,fCtz(0)
-  ,fCte(0)
-  ,fCtt(0)
-  ,fCcy(0)
-  ,fCcz(0)
-  ,fCce(0)
-  ,fCct(0)
-  ,fCcc(0)
   ,fLhElectron(0.0)
   ,fNWrong(0)
   ,fNRotate(0)
@@ -309,104 +261,52 @@ AliTRDtrack::AliTRDtrack(const AliKalmanTrack &t, Double_t alpha)
   ,fBackupTrack(0x0)
 {
   //
-  // Constructor from AliTPCtrack or AliITStrack .
+  // Constructor from AliTPCtrack or AliITStrack
   //
 
-  Int_t  i = 0;
-  Int_t  j = 0;
-  UInt_t k = 0;
-
+  SetLabel(t.GetLabel());
   SetChi2(0.0);
+  SetMass(t.GetMass());
   SetNumberOfClusters(0);
 
-  for (i = 0; i < kNplane; i++) {
-    for (j = 0; j < kNslice; j++) {
+  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;
   }
-
-  if      (fAlpha < -TMath::Pi()) {
-    fAlpha += 2.0 * TMath::Pi();
-  }
-  else if (fAlpha >= TMath::Pi()) {
-    fAlpha -= 2.0 * TMath::Pi();
+  for(int ispec=0; ispec<AliPID::kSPECIES; ispec++) {
+    fPID[ispec] = 1.0 / AliPID::kSPECIES;      
   }
 
-  Double_t x;
-  Double_t p[5]; 
-  t.GetExternalParameters(x,p);
-  fX = x;
-  fY = p[0];
-  fZ = p[1];
-  fT = p[3]; 
-  x  = GetLocalConvConst();
-  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.0*fX*c[12] + c[ 5];
-  Double_t c32 = fX    * c[13] -        c[ 8];
-  Double_t c20 = fX    * c[10] -        c[ 3]; 
-  Double_t c21 = fX    * c[11] -        c[ 4];
-  Double_t 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 (k = 0; k < kMAXCLUSTERSPERTRACK; k++) {
-    fdQdl[k]        = 0;
-    fIndex[k]       = 0;
-    fIndexBackup[k] = 0;
+  for (UInt_t i = 0; i < kMAXCLUSTERSPERTRACK; i++) {
+    fdQdl[i]        = 0;
+    fIndex[i]       = 0;
+    fIndexBackup[i] = 0;
+    fClusters[i]    = 0x0;
   }
   
-  for (i = 0; i < 3; i++) { 
+  for (Int_t i = 0; i < 3; i++) { 
     fBudget[i]      = 0;
   }
 
-}              
+}
 
 //_____________________________________________________________________________
-AliTRDtrack::AliTRDtrack(const AliESDtrack &t) 
-  :AliKalmanTrack() 
+AliTRDtrack::AliTRDtrack(const AliESDtrack &t)
+  :AliKalmanTrack()
   ,fSeedLab(-1)
   ,fdEdx(t.GetTRDsignal())
   ,fDE(0)
-  ,fAlpha(t.GetAlpha())
-  ,fX(0)
+  ,fPIDquality(0)
+  ,fClusterOwner(kFALSE)
+  ,fPIDmethod(kLQ)
   ,fStopped(kFALSE)
-  ,fY(0)
-  ,fZ(0)
-  ,fE(0)
-  ,fT(0)
-  ,fC(0)
-  ,fCyy(1e10)
-  ,fCzy(0)
-  ,fCzz(1e10)
-  ,fCey(0)
-  ,fCez(0)
-  ,fCee(1e10)
-  ,fCty(0)
-  ,fCtz(0)
-  ,fCte(0)
-  ,fCtt(1e10)
-  ,fCcy(0)
-  ,fCcz(0)
-  ,fCce(0)
-  ,fCct(0)
-  ,fCcc(1e10)
-  ,fLhElectron(0.0)
+  ,fLhElectron(0)
   ,fNWrong(0)
   ,fNRotate(0)
   ,fNCross(0)
@@ -414,94 +314,60 @@ AliTRDtrack::AliTRDtrack(const AliESDtrack &t)
   ,fNLast(0)
   ,fNExpectedLast(0)
   ,fNdedx(0)
-  ,fChi2Last(0.0)
+  ,fChi2Last(1e10)
   ,fBackupTrack(0x0)
 {
   //
   // Constructor from AliESDtrack
   //
 
-  Int_t  i = 0;
-  Int_t  j = 0;
-  UInt_t k = 0;
-
   SetLabel(t.GetLabel());
-  SetChi2(0.);
+  SetChi2(0.0);
   SetMass(t.GetMass());
   SetNumberOfClusters(t.GetTRDclusters(fIndex)); 
 
   Int_t ncl = t.GetTRDclusters(fIndexBackup);
-  for (k = ncl; k < kMAXCLUSTERSPERTRACK; k++) {
-    fIndexBackup[k] = 0;
-    fIndex[k]       = 0;
+  for (UInt_t i = ncl; i < kMAXCLUSTERSPERTRACK; i++) {
+    fIndexBackup[i] = 0;
+    fIndex[i]       = 0;
   }
 
-  for (i = 0; i < kNplane; i++) {
-    for (j = 0; j < kNslice; j++) {
-      fdEdxPlane[i][j] = t.GetTRDsignals(i,j);
+  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);
-  }
-
-  if      (fAlpha <  -TMath::Pi()) {
-    fAlpha += 2.0 * TMath::Pi();
-  }
-  else if (fAlpha >=  TMath::Pi()) {
-    fAlpha -= 2.0 * TMath::Pi();
-  }
-
-  // Conversion of the covariance matrix
-  Double_t x;
-  Double_t p[5]; 
-  t.GetExternalParameters(x,p);
-  Double_t c[15]; 
-  t.GetExternalCovariance(c);
-  if (t.GetStatus() & AliESDtrack::kTRDbackup) {
-    t.GetOuterExternalParameters(fAlpha,x,p);
-    t.GetOuterExternalCovariance(c);
-    if      (fAlpha <  -TMath::Pi()) {
-      fAlpha += 2.0 * TMath::Pi();
-    }
-    else if (fAlpha >=  TMath::Pi()) {
-      fAlpha -= 2.0 * TMath::Pi();
+    fMom[i]         = -1.;
+    fSnp[i]         =  0.;
+    fTgl[i]         =  0.;
+    fTrackletIndex[i] = -1;
+  }
+
+  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());
 
-  fX = x;
-  fY = p[0];
-  fZ = p[1]; 
-  SaveLocalConvConst();
-  fT = p[3]; 
-  x  = GetLocalConvConst();
-  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.0*fX*c[12] + c[ 5];
-  Double_t c32 = fX    * c[13] - c[ 8];
-  Double_t c20 = fX    * c[10] - c[ 3];
-  Double_t c21 = fX    * c[11] - c[ 4];
-  Double_t 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 (k = 0; k < kMAXCLUSTERSPERTRACK; k++) {
-    fdQdl[k] = 0;
-    //fIndex[k] = 0; //MI store indexes
+  for (UInt_t i = 0; i < kMAXCLUSTERSPERTRACK; i++) {
+    fdQdl[i]     = 0;
+    fClusters[i] = 0x0;
   }
 
-  for (i = 0; i < 3; i++) { 
+  for (Int_t i = 0; i < 3; i++) {
     fBudget[i] = 0;
   }
+  for(int ispec=0; ispec<AliPID::kSPECIES; ispec++) {
+    fPID[ispec] = t.GetTRDpid(ispec);  
+  }
+
   if ((t.GetStatus() & AliESDtrack::kTIME) == 0) {
     return;
   }
@@ -524,39 +390,17 @@ AliTRDtrack::~AliTRDtrack()
   if (fBackupTrack) {
     delete fBackupTrack;
   }
-  fBackupTrack = 0;
+  fBackupTrack = 0x0;
 
-}
-
-//____________________________________________________________________________
-AliTRDtrack &AliTRDtrack::operator=(const AliTRDtrack &t)
-{
-  //
-  // Assignment operator
-  //
-
-  fLhElectron    = 0.0;
-  fNWrong        = 0;
-  fStopped       = 0;
-  fNRotate       = 0;
-  fNExpected     = 0;
-  fNExpectedLast = 0;
-  fNdedx         = 0;
-  fNCross        = 0;
-  fNLast         = 0;
-  fChi2Last      = 0;
-  fBackupTrack   = 0;
-
-  fAlpha = t.GetAlpha();
-  if      (fAlpha <  -TMath::Pi()) {
-    fAlpha += 2.0 * TMath::Pi();
-  }
-  else if (fAlpha >=  TMath::Pi()) {
-    fAlpha -= 2.0 * TMath::Pi();
+  if (fClusterOwner) {
+    UInt_t icluster = 0;
+    while ((icluster < kMAXCLUSTERSPERTRACK) && fClusters[icluster]) {
+      delete fClusters[icluster];
+      fClusters[icluster] = 0x0;
+      icluster++;
+    }
   }
 
-  return *this;
-
 }
 
 //____________________________________________________________________________
@@ -568,68 +412,11 @@ Float_t AliTRDtrack::StatusForTOF()
 
   // Definition of res ????
   Float_t res = (0.2 + 0.8 * (fN / (fNExpected + 5.0)))
-              * (0.4 + 0.6 * fTracklets[5].GetN() / 20.0);
+                     * (0.4 + 0.6 * fTracklets[5].GetN() / 20.0);
   res *= (0.25 + 0.8 * 40.0 / (40.0 + fBudget[2]));
   return res;
 
-  // This part of the function is never reached ????
-  // What defines these parameters ????
-  Int_t status = 0;
-  if (GetNumberOfClusters()                <  20)  return 0;
-  if ((fN                                  > 110) && 
-      (fChi2/(Float_t(fN))                 < 3.0)) return 3; // Gold
-  if ((fNLast                              >  30) && 
-      (fChi2Last/(Float_t(fNLast))         < 3.0)) return 3; // Gold
-  if ((fNLast                              >  20) && 
-      (fChi2Last/(Float_t(fNLast))         < 2.0)) return 3; // Gold
-  if ((fNLast/(fNExpectedLast+3.0)         > 0.8) && 
-      (fChi2Last/Float_t(fNLast)           < 5.0) &&
-      (fNLast                              >  20)) return 2; // Silver
-  if ((fNLast                              >   5) &&  
-      (((fNLast+1.0)/(fNExpectedLast+1.0)) > 0.8) &&
-      (fChi2Last/(fNLast-5.0)              < 6.0)) return 1; 
-  
-  return status;
-
 }
-            
-//_____________________________________________________________________________
-void AliTRDtrack::GetExternalCovariance(Double_t cc[15]) const 
-{
-  //
-  // This function returns external representation of the covriance matrix.
-  //
-
-  Double_t a   = GetLocalConvConst();
-
-  Double_t c22 = fX*fX*fCcc  - 2.0*fX*fCce+fCee;
-  Double_t c32 = fX*fCct-fCte;
-  Double_t c20 = fX*fCcy-fCey;
-  Double_t c21 = fX*fCcz-fCez;
-  Double_t c42 = fX*fCcc-fCce;
-
-  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; 
-  
-}               
-                       
-//_____________________________________________________________________________
-void AliTRDtrack::GetCovariance(Double_t cc[15]) const 
-{
-  //
-  // Returns the track covariance matrix
-  //
-
-  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;
-  
-}    
 
 //_____________________________________________________________________________
 Int_t AliTRDtrack::Compare(const TObject *o) const 
@@ -639,8 +426,6 @@ Int_t AliTRDtrack::Compare(const TObject *o) const
   //
 
   AliTRDtrack *t = (AliTRDtrack *) o;
-  //  Double_t co=t->GetSigmaY2();
-  //  Double_t c =GetSigmaY2();
 
   Double_t co = TMath::Abs(t->GetC());
   Double_t c  = TMath::Abs(GetC());  
@@ -651,6 +436,7 @@ Int_t AliTRDtrack::Compare(const TObject *o) const
   else if (c < co) {
     return -1;
   }
+
   return 0;
 
 }                
@@ -662,936 +448,537 @@ void AliTRDtrack::CookdEdx(Double_t low, Double_t up)
   // Calculates the truncated dE/dx within the "low" and "up" cuts.
   //
 
-  Int_t   i  = 0;
-
   // Array to sort the dEdx values according to amplitude
   Float_t sorted[kMAXCLUSTERSPERTRACK];
-
-  // Number of clusters used for dedx
-  Int_t   nc = fNdedx; 
-
+  fdEdx = 0.0;
+       
   // Require at least 10 clusters for a dedx measurement
-  if (nc < 10) {
-    SetdEdx(0);
+  if (fNdedx < 10) {
     return;
   }
 
-  // Lower and upper bound
-  Int_t nl = Int_t(low * nc);
-  Int_t nu = Int_t( up * nc);
-
   // Can fdQdl be negative ????
-  for (i = 0; i < nc; i++) {
+  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[nc];
-  TMath::Sort(nc,sorted,index,kFALSE);
+  Int_t *index = new Int_t[fNdedx];
+  TMath::Sort(fNdedx, sorted, index, kFALSE);
 
-  // Sum up the truncated charge between nl and nu  
-  Float_t dedx = 0.0;
-  for (i = nl; i <= nu; i++) {
-    dedx += sorted[index[i]];
+  // 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]];
   }
-  dedx /= (nu - nl + 1.0);
-  SetdEdx(dedx);
+  fdEdx /= (nu - nl + 1.0);
 
-  delete [] index;
+  delete[] index;
 
 }                     
 
 //_____________________________________________________________________________
-Int_t AliTRDtrack::PropagateTo(Double_t xk,Double_t x0,Double_t rho)
+void AliTRDtrack::CookdEdxTimBin(const Int_t/* tid*/)
 {
   //
-  // Propagates a track of particle with mass=pm to a reference plane 
-  // defined by x=xk through media of density=rho and radiationLength=x0
-  //
-
-  if (xk == fX) {
-    return 1;
+  // 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;
+    }
   }
 
-  if (TMath::Abs(fC*xk - fE) >= 0.9) {
-    return 0;
-  }
+  // Start looping over clusters attached to this track
+  for (Int_t iClus = 0; iClus < GetNumberOfClusters(); iClus++) {
 
-  Double_t lcc = GetLocalConvConst();
+    cluster = fClusters[iClus]; //(AliTRDcluster*)tracker->GetCluster(fIndex[iClus]);
+    if (!cluster) continue;
 
-  Double_t oldX = fX;
-  Double_t oldY = fY;
-  Double_t oldZ = fZ;  
+    // Read info from current cluster
+    plane  = AliTRDgeometry::GetLayer(cluster->GetDetector());
+    if (plane < 0 || plane >= kNplane) {
+      AliError(Form("Wrong plane %d", plane));
+      continue;
+    }
 
-  Double_t x1 = fX;
-  Double_t x2 = x1 + (xk - x1);
-  Double_t dx = x2 - x1;
-  Double_t y1 = fY;
-  Double_t z1 = fZ;
-  Double_t c1 = fC*x1 - fE;
-  if ((c1*c1) > 1) {
-    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;
 
-  Double_t r1 = TMath::Sqrt(1.0 - c1*c1);
-  Double_t c2 = fC*x2 - fE; 
-  if ((c2*c2) > 1) {
-    return 0;
-  }
+    fdEdxPlane[plane][slice] += fdQdl[iClus];
+    if (fdQdl[iClus] > maxcharge[plane]) {
+      maxcharge[plane]    = fdQdl[iClus];
+      fTimBinPlane[plane] = tb;
+    }
 
-  Double_t r2 = TMath::Sqrt(1.0 - 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;
-  Double_t cc  =  c1+c2;
-  Double_t 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;
-  Double_t b01 = f12*fCey + f14*fCcy + f13*fCty;
-  Double_t b10 = f02*fCez + f04*fCcz;
-  Double_t b11 = f12*fCez + f14*fCcz + f13*fCtz;
-  Double_t b20 = f02*fCee + f04*fCce;
-  Double_t b21 = f12*fCee + f14*fCce + f13*fCte;
-  Double_t b30 = f02*fCte + f04*fCct;
-  Double_t b31 = f12*fCte + f14*fCct + f13*fCtt;
-  Double_t b40 = f02*fCce + f04*fCcc;
-  Double_t b41 = f12*fCce + f14*fCcc + f13*fCct;
-
-  // a = f*b = f*C*ft
-  Double_t a00 = f02*b20 + f04*b40;
-  Double_t a01 = f02*b21 + f04*b41;
-  Double_t a11 = f12*b21 + f14*b41 + f13*b31;
-
-  // F*C*Ft = C + (a + b + bt)
-  fCyy += a00 + 2.0*b00;
-  fCzy += a01 + b01 + b10;
-  fCey += b20;
-  fCty += b30;
-  fCcy += b40;
-  fCzz += a11 + 2.0*b11;
-  fCez += b21;
-  fCtz += b31;
-  fCcz += b41;
-
-  fX = x2;                                                     
-
-  // Change of the magnetic field
-  SaveLocalConvConst();
-  cc =  fC;
-  fC *= lcc / GetLocalConvConst();
-  fE += fX  * (fC-cc);
-
-  // Multiple scattering
-  // What is 14.1 ????
-  Double_t d      = TMath::Sqrt((x1-fX)*(x1-fX) + (y1-fY)*(y1-fY) + (z1-fZ)*(z1-fZ));
-  Double_t p2     = (1.0 + 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;
-  Double_t ez     = fT;
-  Double_t xz     = fC*ez;
-  Double_t zz1    = ez*ez + 1.0;
-  Double_t xy     = fE + ey;
-  
-  fCee += (2.0*ey*ez*ez*fE + 1.0 - 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;
-
-  // Energy losses
-  // What is 5940.0 ???? and 0.153e-3 ????
-  if ((5940.0*beta2 / (1.0 - beta2 + 1e-10) - beta2) < 0.0) {
-    return 0;
-  }
-  Double_t dE     = 0.153e-3/beta2 * (TMath::Log(5940.0*beta2 / (1.0 - beta2 + 1e-10)) - beta2) 
-                  * d * rho;
-  Float_t  budget = d * rho;
-  fBudget[0] +=budget;
-  // Suspicious part - think about it ????
-  Double_t kinE =  TMath::Sqrt(p2);
-  if (dE > 0.8 * kinE) {
-    dE = 0.8 * kinE;
-  }
-  if (dE <        0.0) {
-    dE = 0.0;       // Not valid region for Bethe bloch 
-  }
-  fDE += dE;
-  if (x1 < x2) {
-    dE = -dE;
-  }
-  cc  = fC;
-  fC *= (1.0 - TMath::Sqrt(p2 + GetMass()*GetMass()) / p2 * dE);
-  fE += fX * (fC - cc);    
-
-  // Energy loss fluctuation 
-  // Why 0.07 ????
-  Double_t sigmade = 0.07 * TMath::Sqrt(TMath::Abs(dE));  
-  Double_t sigmac2 = sigmade*sigmade * fC*fC * (p2 + GetMass()*GetMass()) / (p2*p2);
-  fCcc += sigmac2;
-  fCee += fX*fX * sigmac2;  
-
-  // Track time measurement
-  if (x1 < x2) {
-    if (IsStartedTimeIntegral()) {
-      Double_t l2 = TMath::Sqrt((fX-oldX)*(fX-oldX) 
-                              + (fY-oldY)*(fY-oldY) 
-                              + (fZ-oldZ)*(fZ-oldZ));
-      if (TMath::Abs(l2*fC) > 0.0001){
-        // <ake correction for curvature if neccesary
-        l2 = 0.5 * TMath::Sqrt((fX-oldX)*(fX-oldX) 
-                             + (fY-oldY)*(fY-oldY));
-        l2 = 2.0 * TMath::ASin(l2 * fC) / fC;
-        l2 = TMath::Sqrt(l2*l2 + (fZ-oldZ)*(fZ-oldZ));
+    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];
       }
-      AddTimeStep(l2);
     }
   }
 
-  return 1;            
-
-}     
+}
 
 //_____________________________________________________________________________
-Int_t AliTRDtrack::Update(const AliTRDcluster *c, Double_t chisq
-                        , UInt_t index, Double_t h01)
+void AliTRDtrack::CookdEdxNN(Float_t *dedx)
 {
   //
-  // Assignes a found cluster to the track and updates track information
+  // This function calcuates the input for the neural networks 
+  // which are used for the PID. 
   //
-
-  Bool_t fNoTilt = kTRUE;
-  // What is 0.003 ????
-  if (TMath::Abs(h01) > 0.003) {
-    fNoTilt = kFALSE;
-  }
-
-  // Add angular effect to the error contribution
-  Float_t tangent2  = (fC*fX-fE) * (fC*fX-fE);
-  if (tangent2 < 0.90000){
-    tangent2 = tangent2 / (1.0 - tangent2);
-  }
-  // What is 0.04 ????
-  Float_t errang    = tangent2 * 0.04;
-  Float_t padlength = TMath::Sqrt(c->GetSigmaZ2() * 12.0);
-
-  Double_t r00 = c->GetSigmaY2() + errang;
-  Double_t r01 = 0.0;
-  Double_t r11 = c->GetSigmaZ2() * 100.0;
-  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;
-  Double_t k01 = fCyy*r01 + fCzy*r11;
-  Double_t k10 = fCzy*r00 + fCzz*r01;
-  Double_t k11 = fCzy*r01 + fCzz*r11;
-  Double_t k20 = fCey*r00 + fCez*r01; 
-  Double_t k21 = fCey*r01 + fCez*r11;
-  Double_t k30 = fCty*r00 + fCtz*r01;
-  Double_t k31 = fCty*r01 + fCtz*r11;
-  Double_t k40 = fCcy*r00 + fCcz*r01; 
-  Double_t k41 = fCcy*r01 + fCcz*r11;
-
-  Double_t dy  = c->GetY() - fY;
-  Double_t dz  = c->GetZ() - fZ;
-  Double_t cur = fC + k40*dy + k41*dz;
-  Double_t eta = fE + k20*dy + k21*dz;
-
-  if (fNoTilt) {
-
-    if (TMath::Abs(cur*fX-eta) >= 0.9) {
-      return 0;
-    }
-    fY += k00*dy + k01*dz;
-    fZ += k10*dy + k11*dz;
-    fE  = eta;
-    fC  = cur;
-
-  }
-  else {
-
-    // Empirical factor set by C.Xu in the first tilt version      
-    // Is this factor still ok ???? 
-    Double_t xuFactor = 100.0;  
-    dy   = c->GetY() - fY; 
-    dz   = c->GetZ() - fZ;     
-    dy   = dy + h01*dz;
-
-    Float_t add = 0.0;
-    if (TMath::Abs(dz) > padlength/2.0) {
-      Float_t dy2  = c->GetY() - fY;
-      Float_t sign = (dz > 0.0) ? -1.0 : 1.0;
-      dy2 += h01 * sign * padlength/2.0;       
-      dy   = dy2;
-      add  = 0.0;
+  //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;
     }
-  
-    r00  = c->GetSigmaY2() + errang + add;
-    r01  = 0.0;
-    r11  = c->GetSigmaZ2() * xuFactor; 
-    r00 += (fCyy + 2.0*h01*fCzy + h01*h01*fCzz);
-    r01 += (fCzy + h01*fCzz);
-    r11 += 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.9) {
-      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;
-  Double_t c02 = fCey;
-  Double_t c03 = fCty;
-  Double_t c04 = fCcy;
-  Double_t c12 = fCez;
-  Double_t c13 = fCtz;
-  Double_t 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;  
-  
-  fCcc -= k40*c04  + k41*c14;                 
+  // Start looping over clusters attached to this track
+  for (Int_t iClus = 0; iClus < GetNumberOfClusters(); iClus++) {
 
-  Int_t n = GetNumberOfClusters();
-  fIndex[n] = index;
-  SetNumberOfClusters(n+1);
+    cluster = fClusters[iClus]; //(AliTRDcluster*)tracker->GetCluster(fIndex[iClus]);
+    if (!cluster) {
+      continue;
+    }
+         
+    // Read info from current cluster
+    plane   = AliTRDgeometry::GetLayer(cluster->GetDetector());
+    if (plane < 0 || plane >= kNplane) {
+      AliError(Form("Wrong plane %d",plane));
+      continue;
+    }
 
-  SetChi2(GetChi2()+chisq);
+    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;
+    }
 
-  return 1;     
+    slice   = tb * kNMLPslice / ntb;
+         
+    *(dedx+(kNMLPslice * plane) + slice) += fdQdl[iClus]/kMLPscale;
+       
+  } // End of loop over cluster
 
-}                     
+}
 
 //_____________________________________________________________________________
-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;
+  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
   //
-  // Add angular effect to the error contribution and make correction
-  // Still needed ???? 
-  // AliTRDclusterCorrection *corrector = AliTRDclusterCorrection::GetCorrection();
-  // 
 
-  Double_t tangent2 = (fC*fX-fE) * (fC*fX-fE);
-  if (tangent2 < 0.9) {
-    tangent2 = tangent2 / (1.0 - tangent2);
-  }
-  Double_t tangent  = TMath::Sqrt(tangent2);
-  if ((fC*fX-fE) < 0.0) {
-    tangent *= -1.0;
+  if ((plane <        0) || 
+      (plane >= kNplane)) {
+    return 0.0;
   }
 
-  // Where are the parameters from ????
-  Double_t errang = tangent2 * 0.04;
-  Double_t errsys = 0.025*0.025 * 20.0;  // Systematic error part 
+  return (AliTRDgeometry::AmThick() + AliTRDgeometry::DrThick())
+        / TMath::Sqrt((1.0 - fSnp[plane]*fSnp[plane]) 
+                    / (1.0 + fTgl[plane]*fTgl[plane]));
 
-  Float_t  extend = 1.0;
-  if (c->GetNPads() == 4) extend = 2.0;
+}
 
-  /////////////////////////////////////////////////////////////////////////////
+//_____________________________________________________________________________
+Bool_t AliTRDtrack::CookPID(Int_t &pidQuality)
+{
   //
-  // Is this still needed or will it be needed ????
+  // This function calculates the PID probabilities based on TRD signals
   //
-  //if (c->GetNPads() == 5) extend = 3.0;
-  //if (c->GetNPads() == 6) extend = 3.0;
-  //if (c->GetQ() < 15) {
-  //  return 1;
-  //}
+  // 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
   //
-  // Will this be needed ????
-  /*
-  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;
-    }
-  }
-  */
-  //  
-  //  Double_t padlength = TMath::Sqrt(c->GetSigmaZ2()*12.);
-  /////////////////////////////////////////////////////////////////////////////
-
-  Double_t r00 = (c->GetSigmaY2() + errang + errsys) * extend;
-  Double_t r01 = 0.0;
-  Double_t r11 = c->GetSigmaZ2()*10000.0;
-  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;
-  Double_t k01 = fCyy*r01 + fCzy*r11;
-  Double_t k10 = fCzy*r00 + fCzz*r01;
-  Double_t k11 = fCzy*r01 + fCzz*r11;
-  Double_t k20 = fCey*r00 + fCez*r01;
-  Double_t k21 = fCey*r01 + fCez*r11;
-  Double_t k30 = fCty*r00 + fCtz*r01;
-  Double_t k31 = fCty*r01 + fCtz*r11;
-  Double_t k40 = fCcy*r00 + fCcz*r01;
-  Double_t k41 = fCcy*r01 + fCcz*r11;
-
-  Double_t dy  = c->GetY() - fY;
-  Double_t dz  = c->GetZ() - fZ;
-  Double_t cur = fC + k40*dy + k41*dz;
-  Double_t eta = fE + k20*dy + k21*dz;
-
-  if (fNoTilt) {
-
-    if (TMath::Abs(cur*fX - eta) >= 0.9) {
-      return 0;
-    }
-
-    fY += k00*dy + k01*dz;
-    fZ += k10*dy + k11*dz;
-    fE  = eta;
-    fC  = cur;
 
+  AliTRDcalibDB *calibration = AliTRDcalibDB::Instance();
+  if (!calibration) {
+    AliError("No access to calibration data");
+    return kFALSE;
   }
-  else {
-
-    Double_t padlength = TMath::Sqrt(c->GetSigmaZ2() * 12.0);
-    // Empirical factor set by C.Xu in the first tilt version 
-    Double_t xuFactor  = 1000.0;  
-
-    dy = c->GetY() - fY; 
-    dz = c->GetZ() - fZ;     
-    //dy = dy + h01*dz + correction; // Still needed ????
-    
-    Double_t tiltdz = dz;
-    if (TMath::Abs(tiltdz) > padlength/2.0) {
-      tiltdz = TMath::Sign(padlength/2.0,dz);
-    }
-    dy = dy + h01*tiltdz;
-
-    Double_t add = 0.0;
-    if (TMath::Abs(dz) > padlength/2.0) {
-      //Double_t dy2 = c->GetY() - fY;     // Still needed ????
-      //Double_t sign = (dz>0) ? -1.: 1.;
-      //dy2-=h01*sign*padlength/2.;    
-      //dy = dy2;
-      add = 1.0;
-    }
-
-    Double_t s00 = (c->GetSigmaY2() + errang) * extend + errsys + add;  // Error pad
-    Double_t s11 = c->GetSigmaZ2() * xuFactor;                          // 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.9) {
-      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;  
-    
+       
+  // Retrieve the CDB container class with the probability distributions
+  const AliTRDCalPID *pd = calibration->GetPIDObject(AliTRDpidUtil::kLQ);
+  if (!pd) {
+    AliError("No access to AliTRDCalPID");
+    return kFALSE;
   }
 
-  // Update the covariance matrix
-  Double_t oldyy = fCyy;
-  Double_t oldzz = fCzz; 
-  //Double_t oldee = fCee;
-  //Double_t oldcc = fCcc;
-  Double_t oldzy = fCzy;
-  Double_t oldey = fCey;
-  Double_t oldty = fCty;
-  Double_t oldcy = fCcy;
-  Double_t oldez = fCez;
-  Double_t oldtz = fCtz;
-  Double_t oldcz = fCcz;
-  //Double_t oldte = fCte;
-  //Double_t 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;                 
+  // Calculate the input for the NN if fPIDmethod is kNN
+  Float_t ldEdxNN[AliTRDgeometry::kNlayer * kNMLPslice], *dedx = 0x0;
+  if(fPIDmethod == kNN) {
+    CookdEdxNN(&ldEdxNN[0]);
+  }
 
-  Int_t n = GetNumberOfClusters();
-  fIndex[n] = index;
-  SetNumberOfClusters(n+1);
+  // Sets the a priori probabilities
+  for(int ispec=0; ispec<AliPID::kSPECIES; ispec++) {
+    fPID[ispec] = 1.0 / AliPID::kSPECIES;      
+  }
 
-  SetChi2(GetChi2() + chisq);
+  if(AliPID::kSPECIES != 5){
+    AliError("Probabilities array defined only for 5 values. Please modify !!");
+    return kFALSE;
+  }
 
-  return 1;      
+  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++) {
 
-//_____________________________________________________________________________
-Int_t AliTRDtrack::UpdateMI(const AliTRDtracklet &tracklet)
-{
-  //
-  // Assignes found tracklet to the track and updates track information
-  //
-  
-  Double_t r00 = (tracklet.GetTrackletSigma2());
-  Double_t r01 = 0.0;
-  Double_t r11 = 10000.0;
-  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 dy  = tracklet.GetY() - fY;
-  Double_t dz  = tracklet.GetZ() - fZ;
-
-  Double_t s00 = tracklet.GetTrackletSigma2();  // Error pad
-  Double_t s11 = 100000.0;                      // Error pad-row
-  Float_t  h01 = tracklet.GetTilt();
-  
-  r00 = fCyy + fCzz*h01*h01 + s00;
-  r01 = fCzy;
-  r11 = fCzz + s11;
-  det = r00*r11 - r01*r01;
-
-  // Inverse matrix
-  tmp =  r00; 
-  r00 =  r11 / det; 
-  r11 =  tmp / det; 
-  r01 = -r01 / det;
-
-  // K matrix
-  Double_t k00 = fCyy*r00 + fCzy*r01;
-  Double_t k01 = fCyy*r01 + fCzy*r11;
-  Double_t k10 = fCzy*r00 + fCzz*r01;
-  Double_t k11 = fCzy*r01 + fCzz*r11;
-  Double_t k20 = fCey*r00 + fCez*r01;
-  Double_t k21 = fCey*r01 + fCez*r11;
-  Double_t k30 = fCty*r00 + fCtz*r01;
-  Double_t k31 = fCty*r01 + fCtz*r11;
-  Double_t k40 = fCcy*r00 + fCcz*r01;
-  Double_t k41 = fCcy*r01 + fCcz*r11;
-  
-  // Update measurement
-  Double_t cur = fC + k40*dy + k41*dz;
-  Double_t eta = fE + k20*dy + k21*dz;  
-  if (TMath::Abs(cur*fX-eta) >= 0.9) {
-    return 0;
-  }                           
-
-  fY += k00*dy + k01*dz;
-  fZ += k10*dy + k11*dz;
-  fE  = eta;
-  fT += k30*dy + k31*dz;
-  fC  = cur;
-    
-  // Update the covariance matrix
-  Double_t oldyy = fCyy;
-  Double_t oldzz = fCzz; 
-  //Double_t oldee = fCee;
-  //Double_t oldcc = fCcc;
-  Double_t oldzy = fCzy;
-  Double_t oldey = fCey;
-  Double_t oldty = fCty;
-  Double_t oldcy = fCcy;
-  Double_t oldez = fCez;
-  Double_t oldtz = fCtz;
-  Double_t oldcz = fCcz;
-  //Double_t oldte = fCte;
-  //Double_t 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;                 
+    length = (AliTRDgeometry::AmThick() + AliTRDgeometry::DrThick())
+           / TMath::Sqrt((1.0 - fSnp[iPlane]*fSnp[iPlane]) 
+                       / (1.0 + fTgl[iPlane]*fTgl[iPlane]));
 
-  return 1;      
+    // 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++;
 
-//_____________________________________________________________________________
-Int_t AliTRDtrack::Rotate(Double_t alpha, Bool_t absolute)
-{
-  //
-  // Rotates the track parameters in the R*phi plane,
-  // if the absolute rotation alpha is in global system.
-  // Otherwise the rotation is relative to the current rotation angle
-  //  
+    // 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 (absolute) {
-    alpha -= fAlpha;
-  }
-  else{
-    fNRotate++;
   }
 
-  fAlpha += alpha;
-  if (fAlpha <  -TMath::Pi()) {
-    fAlpha += 2.0 * TMath::Pi();
+  if (pidQuality == 0) {
+    return kTRUE;
   }
-  if (fAlpha >=  TMath::Pi()) {
-    fAlpha -= 2.0 * TMath::Pi();
-  }
-
-  Double_t x1 = fX;
-  Double_t y1 = fY;
-  Double_t ca = TMath::Cos(alpha);
-  Double_t sa = TMath::Sin(alpha);
-  Double_t r1 = fC*fX - fE;
 
-  fX =  x1*ca + y1*sa;
-  fY = -x1*sa + y1*ca;
-  if ((r1*r1) > 1.0) {
-    return 0;
+  // normalize probabilities
+  Double_t probTotal = 0.0;
+  for (Int_t iSpecies = 0; iSpecies < AliPID::kSPECIES; iSpecies++) {
+    probTotal += fPID[iSpecies];
   }
-  fE = fE*ca + (fC*y1 + TMath::Sqrt(1.0 - r1*r1)) * sa;
 
-  Double_t r2 = fC*fX - fE;
-  if (TMath::Abs(r2) >= 0.9) {
-    Int_t n = GetNumberOfClusters();
-    if (n > 4) {
-      AliError(Form("Rotation failed N = %d !\n",n));
-    }
-    return 0;
+  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;
   }
 
-  if ((r2*r2) > 1.0) {
-    return 0;
-  }
-  Double_t y0 = fY + TMath::Sqrt(1.0 - r2*r2) / fC;
-  if ((fY-y0)*fC >= 0.0) {
-    Int_t n = GetNumberOfClusters();
-    if (n > 4) {
-      AliError(Form("Rotation failed N = %d !\n",n));
-    }
-    return 0;
+  for (Int_t iSpecies = 0; iSpecies < AliPID::kSPECIES; iSpecies++) {
+    fPID[iSpecies] /= probTotal;
   }
 
-  // f = F - 1
-  Double_t f00 = ca-1.0;
-  Double_t f24 = (y1 - r1*x1/TMath::Sqrt(1.0 - r1*r1)) * sa;
-  Double_t f20 = fC*sa; 
-  Double_t f22 = (ca + sa*r1/TMath::Sqrt(1.0 - r1*r1)) - 1.0;
-
-  // b = C*ft
-  Double_t b00 = fCyy*f00;
-  Double_t b02 = fCyy*f20 + fCcy*f24 + fCey*f22;
-  Double_t b10 = fCzy*f00;
-  Double_t b12 = fCzy*f20 + fCcz*f24 + fCez*f22;
-  Double_t b20 = fCey*f00;
-  Double_t b22 = fCey*f20 + fCce*f24 + fCee*f22;
-  Double_t b30 = fCty*f00;
-  Double_t b32 = fCty*f20 + fCct*f24 + fCte*f22;
-  Double_t b40 = fCcy*f00;
-  Double_t b42 = fCcy*f20 + fCcc*f24 + fCce*f22;
-
-  // a = f*b = f*C*ft
-  Double_t a00 = f00*b00;
-  Double_t a02 = f00*b02;
-  Double_t a22 = f20*b02  + f24*b42  + f22*b22;
-
-  // F*C*Ft = C + (a + b + bt)
-  fCyy += a00 + 2.0*b00;
-  fCzy += b10;
-  fCey += a02 +     b20 + b02;
-  fCty += b30;
-  fCcy += b40;
-  fCez += b12;
-  fCte += b32;
-  fCee += a22 + 2.0*b22;
-  fCce += b42;
-
-  return 1;                            
-
-}                         
+  return kTRUE;
+
+}
 
 //_____________________________________________________________________________
-Double_t AliTRDtrack::GetPredictedChi2(const AliTRDcluster *c, Double_t h01) const
+Bool_t AliTRDtrack::PropagateTo(Double_t xk, Double_t xx0, Double_t xrho)
 {
   //
-  // Returns the track chi2
-  //  
+  // 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] 
+  // 
 
-  Bool_t fNoTilt = kTRUE;
-  if (TMath::Abs(h01) > 0.003) {
-    fNoTilt = kFALSE;
+  if (xk == GetX()) {
+    return kTRUE;
   }
 
-  Double_t chi2;
-  Double_t dy;
-  Double_t r00;
-  Double_t r01;
-  Double_t r11;
+  Double_t oldX = GetX();
+  Double_t oldY = GetY();
+  Double_t oldZ = GetZ();
 
-  if (fNoTilt) {
-
-    dy   = c->GetY() - fY;
-    r00  = c->GetSigmaY2();    
-    chi2 = (dy*dy) / r00;    
+  Double_t bz   = GetBz();
 
+  if (!AliExternalTrackParam::PropagateTo(xk,bz)) {
+    return kFALSE;
   }
-  else {
-
-    Double_t padlength = TMath::Sqrt(c->GetSigmaZ2() * 12.0);
-
-    r00  = c->GetSigmaY2(); 
-    r01  = 0.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) {
-        AliError(Form("Singular matrix N = %d!\n",n));
+
+  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));
       }
-      return 1e10;
+      AddTimeStep(l2);
     }
+  }
+
+  if (!AliExternalTrackParam::CorrectForMeanMaterial(xx0,xrho,GetMass())) { 
+    return kFALSE;
+  }
 
-    Double_t tmp = r00; 
-    r00  =  r11; 
-    r11  =  tmp; 
-    r01  = -r01;
-    Double_t dy     = c->GetY() - fY;
-    Double_t dz     = c->GetZ() - fZ;
-    Double_t tiltdz = dz;
-    if (TMath::Abs(tiltdz) > padlength/2.0) {
-      tiltdz = TMath::Sign(padlength/2.0,dz);
+  {
+
+    // 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;
     }
-    dy = dy + h01*tiltdz;
 
-    chi2 = (dy*r00*dy + 2*r01*dy*dz + dz*r11*dz) / det; 
+    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 chi2;
+  return kTRUE;            
 
-}      
+}     
 
-//_________________________________________________________________________
-void AliTRDtrack::GetPxPyPz(Double_t& px, Double_t& py, Double_t& pz) const
+//_____________________________________________________________________________
+Bool_t AliTRDtrack::Update(const AliTRDcluster *c, Double_t chisq
+                         , Int_t index, Double_t h01)
 {
   //
-  // Returns reconstructed track momentum in the global system.
+  // Assignes the found cluster <c> to the track and updates 
+  // track information.
+  // <chisq> : predicted chi2
+  // <index> : ??
+  // <h01>   : Tilting factor
   //
 
-  Double_t pt = TMath::Abs(GetPt());
-  Double_t r  = fC*fX - fE;
+  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 y0; 
-  if      (r >  1) { 
-    py =  pt; 
-    px = 0.0;
-  }
-  else if (r < -1) { 
-    py = -pt; 
-    px = 0.0;
-  }
-  else {
-    y0 =  fY + TMath::Sqrt(1.0 - r*r) / fC;  
-    px = -pt * (fY - y0) * fC; //cos(phi);
-    py = -pt * (fE - fX*fC);   //sin(phi);
+  if (!AliExternalTrackParam::Update(p,cov)) {
+    return kFALSE;
   }
 
-  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;            
+  Int_t n   = GetNumberOfClusters();
+  fIndex[n] = index;
+  SetNumberOfClusters(n+1);
+
+  SetChi2(GetChi2()+chisq);
+
+  return kTRUE;
 
-}                                
+}        
 
-//_________________________________________________________________________
-void AliTRDtrack::GetGlobalXYZ(Double_t& x, Double_t& y, Double_t& z) const
+//_____________________________________________________________________________
+Int_t AliTRDtrack::UpdateMI(AliTRDcluster *c, Double_t chisq, Int_t index
+                         , Double_t h01, Int_t /*plane*/, Int_t /*tid*/)
 {
   //
-  // Returns reconstructed track coordinates in the global system.
+  // 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
   //
 
-  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;            
+  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;
+  }
+       
+       AliTracker::FillResiduals(this,p,cov,c->GetVolumeId());
 
-//_________________________________________________________________________
-void AliTRDtrack::ResetCovariance() 
+  // Register cluster to track
+  Int_t n      = GetNumberOfClusters();
+  fIndex[n]    = index;
+  fClusters[n] = c;
+  SetNumberOfClusters(n+1);
+  SetChi2(GetChi2() + chisq);
+
+  return kTRUE;
+
+}                     
+
+//_____________________________________________________________________________
+Bool_t AliTRDtrack::Update(const AliTRDtracklet &t, Double_t chisq, Int_t index)
 {
   //
-  // Resets covariance matrix
+  // Assignes the found tracklet <t> to the track
+  // and updates track information
+  // <chisq> : predicted chi2
+  // <index> : ??
   //
 
-  fCyy *= 10.0;
-  fCzy  =  0.0;  fCzz *= 10.0;
-  fCey  =  0.0;  fCez  =  0.0;  fCee *= 10.0;
-  fCty  =  0.0;  fCtz  =  0.0;  fCte  =  0.0;  fCtt *= 10.0;
-  fCcy  =  0.0;  fCcz  =  0.0;  fCce  =  0.0;  fCct  =  0.0;  fCcc *= 10.0;  
+  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;
+  }
 
-}                                                         
+  Int_t n   = GetNumberOfClusters();
+  fIndex[n] = index;
+  SetNumberOfClusters(n+1);
+  SetChi2(GetChi2()+chisq);
+
+  return kTRUE;
+
+}                     
 
 //_____________________________________________________________________________
-void AliTRDtrack::ResetCovariance(Float_t mult) 
+Bool_t AliTRDtrack::Rotate(Double_t alpha, Bool_t absolute)
 {
   //
-  // Resets covariance matrix
+  // 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
+  //  
+
+  if (absolute) {
+    alpha -= GetAlpha();
+  }
+  else{
+    fNRotate++;
+  }
+
+  return AliExternalTrackParam::Rotate(GetAlpha()+alpha);
+
+}           
+
+//_____________________________________________________________________________
+Double_t AliTRDtrack::GetPredictedChi2(const AliTRDcluster *c, Double_t h01) const
+{
   //
+  // Returns the track chi2
+  //  
 
-  fCyy *= mult;
-  fCzy *= 0.0;   fCzz *= 1.0;
-  fCey *= 0.0;   fCez *= 0.0;   fCee *= mult;
-  fCty *= 0.0;   fCtz *= 0.0;   fCte *= 0.0;   fCtt *= 1.0;
-  fCcy *= 0.0;   fCcz *= 0.0;   fCce *= 0.0;   fCct *= 0.0;   fCcc *= mult;  
+  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()
@@ -1603,7 +990,6 @@ void AliTRDtrack::MakeBackupTrack()
   if (fBackupTrack) {
     delete fBackupTrack;
   }
-
   fBackupTrack = new AliTRDtrack(*this);
   
 }
@@ -1612,71 +998,66 @@ void AliTRDtrack::MakeBackupTrack()
 Int_t AliTRDtrack::GetProlongation(Double_t xk, Double_t &y, Double_t &z)
 {
   //
-  // Find prolongation at given x
+  // Find prolongation at given x
   // Return 0 if it does not exist
-  //
-  
-  Double_t c1 = fC*fX - fE;
-  if (TMath::Abs(c1) > 1.0) {
+  //  
+
+  Double_t bz = GetBz();
+
+  if (!AliExternalTrackParam::GetYAt(xk,bz,y)) {
     return 0;
   }
-
-  Double_t r1 = TMath::Sqrt(1.0 - c1*c1);
-  Double_t c2 = fC*xk - fE;
-  if (TMath::Abs(c2) > 1.0) {
-    return 0;  
+  if (!AliExternalTrackParam::GetZAt(xk,bz,z)) {
+    return 0;
   }
 
-  Double_t r2 = TMath::Sqrt(1.0 - c2*c2);
-  y = fY + (xk-fX)*(c1+c2)/(r1+r2);
-  z = fZ + (xk-fX)*(c1+c2)/(c1*r2 + c2*r1)*fT;
+  return 1;  
 
-  return 1;
-  
 }
 
 //_____________________________________________________________________________
 Int_t AliTRDtrack::PropagateToX(Double_t xr, Double_t step)
 {
   //
-  // Propagate track to a given x position 
+  // Propagate track to given x  position 
   // Works inside of the 20 degree segmentation
   // (local cooordinate frame for TRD , TPC, TOF)
   // 
-  // The material budget is taken from the geo manager
-  //
-  Double_t  xyz0[3];
-  Double_t  xyz1[3];
-  Double_t  y;
-  Double_t  z;
+  // Material budget from geo manager
+  // 
+
+  Double_t xyz0[3];
+  Double_t xyz1[3];
+  Double_t y;
+  Double_t z;
 
-  // Critical alpha  - cross sector indication
   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 +-
-  Double_t dir = (fX > xr) ? -1.0 : 1.0;
+  for (Double_t x = GetX()+dir*step; dir*x < dir*xr; x += dir*step) {
 
-  for (Double_t x = fX + dir*step; dir*x < dir*xr; x += dir*step) {
-    
-    GetGlobalXYZ(xyz0[0],xyz0[1],xyz0[2]);     
+    GetXYZ(xyz0);      
     GetProlongation(x,y,z);
-    xyz1[0] = x * TMath::Cos(fAlpha) + y * TMath::Sin(fAlpha); 
-    xyz1[1] = x * TMath::Sin(fAlpha) - y * TMath::Cos(fAlpha);
+    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];
-    AliKalmanTrack::MeanMaterialBudget(xyz0,xyz1,param);
-    
-    if ((param[0] > 0) && 
+    AliTracker::MeanMaterialBudget(xyz0,xyz1,param);
+
+    if ((param[0] > 0) &&
         (param[1] > 0)) {
-      PropagateTo(x,param[1],param[0]);
+      PropagateTo(x,param[1],param[0]*param[4]);
     }
-    if (fY >  fX*kTalphac) {
+
+    if (GetY() >  GetX()*kTalphac) {
       Rotate(-kAlphac);
     }
-    if (fY < -fX*kTalphac) {
-      Rotate(kAlphac);
+    if (GetY() < -GetX()*kTalphac) {
+      Rotate( kAlphac);
     }
 
   }
@@ -1688,11 +1069,11 @@ Int_t AliTRDtrack::PropagateToX(Double_t xr, Double_t step)
 }
 
 //_____________________________________________________________________________
-Int_t AliTRDtrack::PropagateToR(Double_t r,Double_t step)
+Int_t   AliTRDtrack::PropagateToR(Double_t r,Double_t step)
 {
   //
-  // Propagate a track to a given radial position
-  // The rotation is always connected to the last track position
+  // Propagate track to the radial position
+  // Rotation always connected to the last track position
   //
 
   Double_t xyz0[3];
@@ -1700,42 +1081,44 @@ Int_t AliTRDtrack::PropagateToR(Double_t r,Double_t step)
   Double_t y;
   Double_t z; 
 
+  Double_t radius = TMath::Sqrt(GetX()*GetX() + GetY()*GetY());
   // Direction +-
-  Double_t radius = TMath::Sqrt(fX*fX + fY*fY);
   Double_t dir    = (radius > r) ? -1.0 : 1.0;   
-  
-  for (Double_t x = radius + dir*step; dir*x < dir*r; x += dir*step) {
-    GetGlobalXYZ(xyz0[0],xyz0[1],xyz0[2]);     
+
+  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);
-    GetGlobalXYZ(xyz0[0],xyz0[1],xyz0[2]);     
+    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];
-    AliKalmanTrack::MeanMaterialBudget(xyz0,xyz1,param);
-    if (param[1] <= 0.0) {
-      param[1] = 100000000.0;
+    AliTracker::MeanMaterialBudget(xyz0,xyz1,param);
+    if (param[1] <= 0) {
+      param[1] = 100000000;
     }
-    PropagateTo(x,param[1],param[0]);
+    PropagateTo(x,param[1],param[0]*param[4]);
+
   } 
 
-  GetGlobalXYZ(xyz0[0],xyz0[1],xyz0[2]);       
+  GetXYZ(xyz0);        
   Double_t alpha = TMath::ATan2(xyz0[1],xyz0[0]);
   Rotate(alpha,kTRUE);
-  GetGlobalXYZ(xyz0[0],xyz0[1],xyz0[2]);       
+  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];
-  AliKalmanTrack::MeanMaterialBudget(xyz0,xyz1,param);
-  
-  if (param[1] <= 0.0) {
-    param[1] = 100000000.0;
+  AliTracker::MeanMaterialBudget(xyz0,xyz1,param);
+
+  if (param[1] <= 0) {
+    param[1] = 100000000;
   }
-  PropagateTo(r,param[1],param[0]);
+  PropagateTo(r,param[1],param[0]*param[4]);
 
   return 0;
 
@@ -1748,55 +1131,8 @@ Int_t AliTRDtrack::GetSector() const
   // Return the current sector
   //
 
-  return Int_t(TVector2::Phi_0_2pi(fAlpha)
-             / AliTRDgeometry::GetAlpha())
-             % AliTRDgeometry::kNsect;
-
-}
-
-//_____________________________________________________________________________
-Double_t AliTRDtrack::Get1Pt() const                       
-{ 
-  //
-  // Returns the inverse Pt (1/GeV/c)
-  // (or 1/"most probable pt", if the field is too weak)
-  //
-
-  if (TMath::Abs(GetLocalConvConst()) > kVeryBigConvConst) {
-    return 1.0 / kMostProbableMomentum 
-               / TMath::Sqrt(1.0 + GetTgl()*GetTgl());
-  }
-
-  return (TMath::Sign(1.0e-9,fC) + fC) * GetLocalConvConst();
-
-}
-
-//_____________________________________________________________________________
-Double_t AliTRDtrack::GetP() const                         
-{ 
-  //
-  // Returns the total momentum
-  //
-
-  return TMath::Abs(GetPt()) * TMath::Sqrt(1.0 + GetTgl()*GetTgl());  
-
-}
-
-//_____________________________________________________________________________
-Double_t AliTRDtrack::GetYat(Double_t xk) const            
-{     
-  //
-  // This function calculates the Y-coordinate of a track at 
-  // the plane x = xk.
-  // Needed for matching with the TOF (I.Belikov)
-  //
-
-  Double_t c1 = fC*fX - fE;
-  Double_t r1 = TMath::Sqrt(1.0 - c1*c1);
-  Double_t c2 = fC*xk - fE;
-  Double_t r2 = TMath::Sqrt(1.0-  c2*c2);
-
-  return fY + (xk-fX)*(c1+c2)/(r1+r2);
+  return Int_t(TVector2::Phi_0_2pi(GetAlpha()) / AliTRDgeometry::GetAlpha())
+             % AliTRDgeometry::kNsector;
 
 }
 
@@ -1809,13 +1145,12 @@ void AliTRDtrack::SetSampledEdx(Float_t q, Int_t i)
 
   Double_t s = GetSnp();
   Double_t t = GetTgl();
-
   q *= TMath::Sqrt((1.0 - s*s) / (1.0 + t*t));
   fdQdl[i] = q;
 
 }     
 
- //_____________________________________________________________________________
+//_____________________________________________________________________________
 void AliTRDtrack::SetSampledEdx(Float_t q) 
 {
   //
@@ -1824,24 +1159,25 @@ void AliTRDtrack::SetSampledEdx(Float_t q)
 
   Double_t s = GetSnp();
   Double_t t = GetTgl();
-
-  q*= TMath::Sqrt((1.0 - s*s) / (1.0 + t*t));
+  q *= TMath::Sqrt((1.0 - s*s) / (1.0 + t*t));
   fdQdl[fNdedx] = q;
   fNdedx++;
 
 }     
 
 //_____________________________________________________________________________
-void AliTRDtrack::GetXYZ(Float_t r[3]) const 
+Double_t AliTRDtrack::GetBz() const 
 {
   //
-  // Returns the position of the track in the global coord. system 
+  // Returns Bz component of the magnetic field (kG)
   //
 
-  Double_t cs = TMath::Cos(fAlpha);
-  Double_t sn = TMath::Sin(fAlpha);
-  r[0] = fX*cs - fY*sn; 
-  r[1] = fX*sn + fY*cs; 
-  r[2] = fZ;
+  if (AliTracker::UniformField()) {
+    return AliTracker::GetBz();
+  }
+  Double_t r[3]; 
+  GetXYZ(r);
+
+  return AliTracker::GetBz(r);
 
 }