]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - STEER/ESD/AliESDtrack.cxx
STEER CMakeList files
[u/mrichter/AliRoot.git] / STEER / ESD / AliESDtrack.cxx
index 527695e3b7e7eb72c7cc73421959db71faae423d..65988e8261e7ca38aa4c3f4db5aca6ad4598b4a1 100644 (file)
 //
 //   1.AliESDtrack is the container of the information about the track/particle
 //     reconstructed during Barrel Tracking.
+//     Content:
+//        a.) Track parameters and covariance - AliExternalTrackParam  - snapshots along trajectory at differnt tracking steps 
+//            current, fIp, fTPCinner, fCp, fOp, fHMPIDp, + friendTrack (fITSout, fTPCout, fTRDin) 
+//        b.) Flags - per detector status bits
+//        c.) Track fit quality -chi2, number of clusters
+//        d.) Detector PID information
+//        d.) Different detector specific information (e.g number of tracklets in TRD, TOF cluster descriptor ...)
+//
+//
 //     The track information is propagated from one tracking detector to 
-//     other using the functionality of AliESDtrack - Current parameters.  
+//     other using the functionality of AliESDtrack (AliExternalTrackParam - current parameters)  
 //
-//     No global fit model is used.
-//     Barrel tracking use Kalman filtering technique, it gives optimal local 
-//     track parameters at given point under certian assumptions.
+//     Barrel tracking uses Kalman filtering technique (no global fit model is used). Kalman provides optimal local 
+//     track parameters estimate at given position under certian assumptions. 
+//     Following approximations were used:  
+//           a.) gaussian Multiple scattering
+//           b.) gaussian energy loss
+//           c.) gaussian error of the space point residuals  
 //             
-//     Kalman filter take into account additional effect which are 
-//     difficult to handle using global fit.
-//     Effects:
+//     Kalman filter take into account following effects which are 
+//     difficult to handle using global fit:
 //        a.) Multiple scattering
 //        b.) Energy loss
 //        c.) Non homogenous magnetic field
 //         b. ITS
 //         c. TRD
 //
-//      In general 3 reconstruction itteration are performed:
-//         1. Find tracks   - sequence TPC->ITS
-//         2. PropagateBack - sequence ITS->TPC->TRD -> Outer PID detectors
-//         3. Refit invward - sequence TRD->TPC->ITS
-//      The current tracks are updated after each detector (see bellow).
-//      In specical cases a track  sanpshots are stored.   
+//      Track findind/fitting procedure is done in 3 steps:
+//         1. Cluster2Track(in)   - inward sequence TPC->ITS    
+//         2. PropagateBack(out)   - outward sequence ITS->TPC->TRD -> Outer PID detectors
+//         3. RefitInward(refit)     - inward sequence TRD->TPC->ITS
+//      After each recosntruction step detector status is updated in the data member fFlags
+//      fFlags|=k<DetectorName><step> where step={1:in,2:out,3:refit,}
+//      For some of detectors a special flags were implemented. Declaration of list of all flags can be find in $ALICE_ROOT/STEER/STEERBase/AliVTrack.h
+//
+//  
+//      The current track parameter is updated after each detector (see bellow).
+//      In specical cases a track  snapshots (AliExternalTrackParam) are stored
+//
 // 
 //
 //      For some type of analysis (+visualization) track local parameters at 
 //      different position are neccesary. A snapshots during the track 
-//      propagation are created.
-//      (See AliExternalTrackParam class for desctiption of variables and 
-//      functionality)
+//      propagation are created and stored either in track itself (for analysis purposes) or assiciated friend track (for calibration and debugging purposes)
+//      (See AliExternalTrackParam class for desctiption of variables and functionality)
 //      Snapshots:
-//      a. Current parameters - class itself (AliExternalTrackParam)
-//         Contributors: general case TRD->TPC->ITS
-//         Preferable usage:  Decission  - primary or secondary track
-//         NOTICE - By default the track parameters are stored at the DCA point
-//                  to the primary vertex. optimal for primary tracks, 
-//                  far from optimal for secondary tracks.
-//      b. Constrained parameters - Kalman information updated with 
-//         the Primary vertex information 
-//         Contributors: general case TRD->TPC->ITS
-//         Preferable usage: Use only for tracks selected as primary
-//         NOTICE - not real constrain - taken as additional measurement 
-//         with corresponding error
+//      a.)  Current parameters (AliESDtrack itself) 
+//         Description:  as obtained in the last succesfull tracking step
+//         Contributors: best case TRD->TPC->ITS after RefitInward
+//         Recomended way to get track parameters. It includes all of the information.
+//         NOTICE - By default the track parameters are stored at the DCA point to the primary vertex. 
+//                  Optimal for primary tracks, far from optimal for deeply secondary tracks.
+//                  To get optimal track parameters at the secondary vertex, OnTheFly V0s with associated track parameters should be used
+//
+//      b.) Constrained parameters (fCp)
+//         Description: 
+//            Kalman track  updated with the Primary vertex information with corresponding error (soft  constraint - see http://en.wikipedia.org/wiki/Constraint_(mathematics)#Hard_and_soft_constraints) 
 //         Function:  
-//       const AliExternalTrackParam *GetConstrainedParam() const {return fCp;}
-//      c. Inner parameters -  Track parameters at inner wall of the TPC 
-//         Contributors: general case TRD->TPC
-//         function:
+//            const AliExternalTrackParam *GetConstrainedParam() const {return fCp;}
+//         Contributors: best case TRD->TPC->ITS after RefitInward
+//         Recommended usage: Use only for tracks selected as primary (check GetConstrainedChi2())
+//         NOTICE - not real constraint only soft constraint
+//
+//      c.) Inner parameters (fIp) -  
+//         Description: Track parameters at inner wall of the TPC 
+//         Function:
 //           const AliExternalTrackParam *GetInnerParam() const { return fIp;}
+//         Contributors: general case TRD->TPC (during RefitInward)
+//         Recomended usage: To provide momenta for the TPC PID and to estimate quality of the track determination for further 
 //
-//      d. TPCinnerparam  - contributors - TPC only
-//         Contributors:  TPC
-//         Preferable usage: Requested for HBT study 
-//                         (smaller correlations as using also ITS information)
-//         NOTICE - the track parameters are propagated to the DCA to  
-//         to primary vertex
-//         Optimal for primary, far from optimal for secondary tracks
+//      d.)  TPCinnerParam (fTPCinner):
+//         Description: TPC only parameters at DCA to the primary vertex (corrected for the material between TPC and vertex)
 //         Function:
-//    const AliExternalTrackParam *GetTPCInnerParam() const {return fTPCInner;}
-//     
-//      e. Outer parameters - 
-//           Contributors-  general case - ITS-> TPC -> TRD
-//           The last point - Outer parameters radius is determined
-//           e.a) Local inclination angle bigger than threshold - 
-//                Low momenta tracks 
-//           e.a) Catastrofic energy losss in material
-//           e.b) Not further improvement (no space points)
-//           Usage:             
+//                const AliExternalTrackParam *GetTPCInnerParam() const {return fTPCInner;}
+//         Contributors:  TPC only from in step  1 (Cluster2Tracks)
+//         Recomended usage: Requested for HBT study 
+//                           (smaller correlations as using also ITS information)
+//         NOTICE: Optimal for primary, far from optimal for secondary tracks (similar to track parameters a.) 
+//                 ! We should always use the c.) fIp in case of the TPC PID analysis, or undo material budget correction!
+//
+//      e.) Outer parameters - (fOp)
+//         Description: track parameters during PropagateBack in the last sucessfull propagation  
+//                  Reason to generate backup  OuterParameters
+//                        a.) Local inclination angle bigger than threshold - 
+//                            Low momenta tracks 
+//                        b.) Catastrofic (large relative>~20 %)energy loss in material outside of the TPC
+//                        c.) No additional  space points contributing to track 
+//         Function:
+//            const AliExternalTrackParam *GetOuterParam() const { return fOp;}
+//         Contributors:  general case - ITS-> TPC -> TRD ( during PropagateBack )
+//         Recomended usage:             
 //              a.) Tracking: Starting parameter for Refit inward 
 //              b.) Visualization
 //              c.) QA
 #include "AliTrackerBase.h"
 #include "AliTPCdEdxInfo.h"
 #include "AliDetectorPID.h"
+#include "TTreeStream.h"
+#include "TObjArray.h"
 
 ClassImp(AliESDtrack)
 
@@ -177,14 +203,22 @@ AliESDtrack::AliESDtrack() :
   fITSLabel(0),
   fTPCLabel(0),
   fTRDLabel(0),
+  fTOFLabel(NULL),
   fTOFCalChannel(-1),
   fTOFindex(-1),
   fHMPIDqn(0),
   fHMPIDcluIdx(-1),
   fCaloIndex(kEMCALNoMatch),
+  fR(0),
+  fITSr(0),
+  fTPCr(0),
+  fTRDr(0),
+  fTOFr(0),
+  fHMPIDr(0),
   fHMPIDtrkTheta(0),
   fHMPIDtrkPhi(0),
   fHMPIDsignal(0),
+  fTrackTime(0),
   fTrackLength(0),
   fdTPC(0),fzTPC(0),
   fCddTPC(0),fCdzTPC(0),fCzzTPC(0),
@@ -237,6 +271,7 @@ AliESDtrack::AliESDtrack() :
   fTRDnSlices(0),
   fTRDslices(0x0),
   fVertexID(-2),// -2 means an orphan track 
+  fPIDForTracking(AliPID::kPion),
   fESDEvent(0),
   fCacheNCrossedRows(-10),
   fCacheChi2TPCConstrainedVsGlobal(-10),
@@ -244,7 +279,9 @@ AliESDtrack::AliESDtrack() :
   fDetectorPID(0x0),
   fTrackPhiOnEMCal(-999),
   fTrackEtaOnEMCal(-999),
-  fTrackPtOnEMCal(-999)
+  fTrackPtOnEMCal(-999),
+  fNtofClusters(0),
+  fTOFcluster(NULL)
 {
   //
   // The default ESD constructor 
@@ -253,15 +290,6 @@ AliESDtrack::AliESDtrack() :
 
   Int_t i;
   for (i=kNITSchi2Std;i--;) fITSchi2Std[i] = 0;
-  for (i=0; i<AliPID::kSPECIES; i++) {
-    fTrackTime[i]=0.;
-    fR[i]=0.;
-    fITSr[i]=0.;
-    fTPCr[i]=0.;
-    fTRDr[i]=0.;
-    fTOFr[i]=0.;
-    fHMPIDr[i]=0.;
-  }
   
   for (i=0; i<3; i++)   { fKinkIndexes[i]=0;}
   for (i=0; i<3; i++)   { fV0Indexes[i]=0;}
@@ -270,7 +298,6 @@ AliESDtrack::AliESDtrack() :
   }
   for (i=0;i<4;i++) {fITSdEdxSamples[i]=0.;}
   for (i=0;i<4;i++) {fTPCPoints[i]=0;}
-  for (i=0;i<3;i++) {fTOFLabel[i]=-1;}
   for (i=0;i<10;i++) {fTOFInfo[i]=0;}
   for (i=0;i<12;i++) {fITSModule[i]=-1;}
 }
@@ -295,14 +322,22 @@ AliESDtrack::AliESDtrack(const AliESDtrack& track):
   fITSLabel(track.fITSLabel),
   fTPCLabel(track.fTPCLabel),
   fTRDLabel(track.fTRDLabel),
+  fTOFLabel(NULL),
   fTOFCalChannel(track.fTOFCalChannel),
   fTOFindex(track.fTOFindex),
   fHMPIDqn(track.fHMPIDqn),
   fHMPIDcluIdx(track.fHMPIDcluIdx),
   fCaloIndex(track.fCaloIndex),
+  fR(0),
+  fITSr(0),
+  fTPCr(0),
+  fTRDr(0),
+  fTOFr(0),
+  fHMPIDr(0),
   fHMPIDtrkTheta(track.fHMPIDtrkTheta),
   fHMPIDtrkPhi(track.fHMPIDtrkPhi),
   fHMPIDsignal(track.fHMPIDsignal),
+  fTrackTime(NULL),
   fTrackLength(track.fTrackLength),
   fdTPC(track.fdTPC),fzTPC(track.fzTPC),
   fCddTPC(track.fCddTPC),fCdzTPC(track.fCdzTPC),fCzzTPC(track.fCzzTPC),
@@ -355,6 +390,7 @@ AliESDtrack::AliESDtrack(const AliESDtrack& track):
   fTRDnSlices(track.fTRDnSlices),
   fTRDslices(0x0),
   fVertexID(track.fVertexID),
+  fPIDForTracking(AliPID::kPion),
   fESDEvent(track.fESDEvent),
   fCacheNCrossedRows(track.fCacheNCrossedRows),
   fCacheChi2TPCConstrainedVsGlobal(track.fCacheChi2TPCConstrainedVsGlobal),
@@ -362,18 +398,34 @@ AliESDtrack::AliESDtrack(const AliESDtrack& track):
   fDetectorPID(0x0),
   fTrackPhiOnEMCal(track.fTrackPhiOnEMCal),
   fTrackEtaOnEMCal(track.fTrackEtaOnEMCal),
-  fTrackPtOnEMCal(track.fTrackPtOnEMCal)
+  fTrackPtOnEMCal(track.fTrackPtOnEMCal),
+  fNtofClusters(track.fNtofClusters),
+  fTOFcluster(NULL)
 {
   //
   //copy constructor
   //
   for (Int_t i=kNITSchi2Std;i--;) fITSchi2Std[i] = track.fITSchi2Std[i];
-  for (Int_t i=0;i<AliPID::kSPECIES;i++) fTrackTime[i]=track.fTrackTime[i];
-  for (Int_t i=0;i<AliPID::kSPECIES;i++)  fR[i]=track.fR[i];
-  //
-  for (Int_t i=0;i<AliPID::kSPECIES;i++) fITSr[i]=track.fITSr[i]; 
+
+  if(track.fTrackTime){
+    fTrackTime = new Double32_t[AliPID::kSPECIESC];
+    for (Int_t i=0;i<AliPID::kSPECIESC;i++) fTrackTime[i]=track.fTrackTime[i];
+  }
+
+  if (track.fR) {
+    fR = new Double32_t[AliPID::kSPECIES]; 
+    for (Int_t i=AliPID::kSPECIES;i--;)  fR[i]=track.fR[i];
+  }
+  if (track.fITSr) {
+    fITSr = new Double32_t[AliPID::kSPECIES]; 
+    for (Int_t i=AliPID::kSPECIES;i--;)  fITSr[i]=track.fITSr[i]; 
+  }
   //
-  for (Int_t i=0;i<AliPID::kSPECIES;i++) fTPCr[i]=track.fTPCr[i]; 
+  if (track.fTPCr) {
+    fTPCr = new Double32_t[AliPID::kSPECIES]; 
+    for (Int_t i=AliPID::kSPECIES;i--;) fTPCr[i]=track.fTPCr[i]; 
+  }
+
   for (Int_t i=0;i<4;i++) {fITSdEdxSamples[i]=track.fITSdEdxSamples[i];}
   for (Int_t i=0;i<4;i++) {fTPCPoints[i]=track.fTPCPoints[i];}
   for (Int_t i=0; i<3;i++)   { fKinkIndexes[i]=track.fKinkIndexes[i];}
@@ -390,12 +442,28 @@ AliESDtrack::AliESDtrack(const AliESDtrack& track):
 
   if (track.fDetectorPID) fDetectorPID = new AliDetectorPID(*track.fDetectorPID);
 
-  for (Int_t i=0;i<AliPID::kSPECIES;i++) fTRDr[i]=track.fTRDr[i]; 
-  for (Int_t i=0;i<AliPID::kSPECIES;i++) fTOFr[i]=track.fTOFr[i];
-  for (Int_t i=0;i<3;i++) fTOFLabel[i]=track.fTOFLabel[i];
+  if (track.fTRDr) {
+    fTRDr  = new Double32_t[AliPID::kSPECIES];
+    for (Int_t i=AliPID::kSPECIES;i--;) fTRDr[i]=track.fTRDr[i]; 
+  }
+
+  if (track.fTOFr) {
+    fTOFr = new Double32_t[AliPID::kSPECIES];
+    for (Int_t i=AliPID::kSPECIES;i--;) fTOFr[i]=track.fTOFr[i];
+  }
+
+  if(track.fTOFLabel){
+    if(!fTOFLabel) fTOFLabel = new Int_t[3];
+    for (Int_t i=0;i<3;i++) fTOFLabel[i]=track.fTOFLabel[i];
+  }
+
   for (Int_t i=0;i<10;i++) fTOFInfo[i]=track.fTOFInfo[i];
   for (Int_t i=0;i<12;i++) fITSModule[i]=track.fITSModule[i];
-  for (Int_t i=0;i<AliPID::kSPECIES;i++) fHMPIDr[i]=track.fHMPIDr[i];
+  
+  if (track.fHMPIDr) {
+    fHMPIDr = new Double32_t[AliPID::kSPECIES];
+    for (Int_t i=AliPID::kSPECIES;i--;) fHMPIDr[i]=track.fHMPIDr[i];
+  }
 
   if (track.fCp) fCp=new AliExternalTrackParam(*track.fCp);
   if (track.fIp) fIp=new AliExternalTrackParam(*track.fIp);
@@ -406,6 +474,11 @@ AliESDtrack::AliESDtrack(const AliESDtrack& track):
 
   
   if (track.fFriendTrack) fFriendTrack=new AliESDfriendTrack(*(track.fFriendTrack));
+
+  if(fNtofClusters > 0){
+    fTOFcluster = new Int_t[fNtofClusters];
+        for(Int_t i=0;i < fNtofClusters;i++) fTOFcluster[i] = track.fTOFcluster[i];
+  }
 }
 
 //_______________________________________________________________________
@@ -426,14 +499,22 @@ AliESDtrack::AliESDtrack(const AliVTrack *track) :
   fITSLabel(0),
   fTPCLabel(0),
   fTRDLabel(0),
+  fTOFLabel(NULL),
   fTOFCalChannel(-1),
   fTOFindex(-1),
   fHMPIDqn(0),
   fHMPIDcluIdx(-1),
   fCaloIndex(kEMCALNoMatch),
+  fR(0),
+  fITSr(0),
+  fTPCr(0),
+  fTRDr(0),
+  fTOFr(0),
+  fHMPIDr(0),
   fHMPIDtrkTheta(0),
   fHMPIDtrkPhi(0),
   fHMPIDsignal(0),
+  fTrackTime(NULL),
   fTrackLength(0),
   fdTPC(0),fzTPC(0),
   fCddTPC(0),fCdzTPC(0),fCzzTPC(0),
@@ -486,6 +567,7 @@ AliESDtrack::AliESDtrack(const AliVTrack *track) :
   fTRDnSlices(0),
   fTRDslices(0x0),
   fVertexID(-2),  // -2 means an orphan track
+  fPIDForTracking(track->GetPIDForTracking()),
   fESDEvent(0),
   fCacheNCrossedRows(-10),
   fCacheChi2TPCConstrainedVsGlobal(-10),
@@ -493,7 +575,9 @@ AliESDtrack::AliESDtrack(const AliVTrack *track) :
   fDetectorPID(0x0),
   fTrackPhiOnEMCal(-999),
   fTrackEtaOnEMCal(-999),
-  fTrackPtOnEMCal(-999)
+  fTrackPtOnEMCal(-999),
+  fNtofClusters(0),
+  fTOFcluster(NULL)
 {
   //
   // ESD track from AliVTrack.
@@ -510,15 +594,6 @@ AliESDtrack::AliESDtrack(const AliVTrack *track) :
   // Reset all the arrays
   Int_t i;
   for (i=kNITSchi2Std;i--;) fITSchi2Std[i] = 0;
-  for (i=0; i<AliPID::kSPECIES; i++) {
-    fTrackTime[i]=0.;
-    fR[i]=0.;
-    fITSr[i]=0.;
-    fTPCr[i]=0.;
-    fTRDr[i]=0.;
-    fTOFr[i]=0.;
-    fHMPIDr[i]=0.;
-  }
   
   for (i=0; i<3; i++)   { fKinkIndexes[i]=0;}
   for (i=0; i<3; i++)   { fV0Indexes[i]=-1;}
@@ -527,12 +602,9 @@ AliESDtrack::AliESDtrack(const AliVTrack *track) :
   }
   for (i=0;i<4;i++) {fITSdEdxSamples[i]=0.;}
   for (i=0;i<4;i++) {fTPCPoints[i]=0;}
-  for (i=0;i<3;i++) {fTOFLabel[i]=-1;}
   for (i=0;i<10;i++) {fTOFInfo[i]=0;}
   for (i=0;i<12;i++) {fITSModule[i]=-1;}
 
-  // Set the ID
-  SetID(track->GetID());
 
   // Set ITS cluster map
   fITSClusterMap=track->GetITSClusterMap();
@@ -556,7 +628,10 @@ AliESDtrack::AliESDtrack(const AliVTrack *track) :
   //
   // Set the combined PID
   const Double_t *pid = track->PID();
-  if(pid) for (i=0; i<AliPID::kSPECIES; i++) fR[i]=pid[i];
+  if(pid) {
+    fR = new Double32_t[AliPID::kSPECIES];
+    for (i=AliPID::kSPECIES; i--;) fR[i]=pid[i];
+  }
   //
   // calo matched cluster id
   SetEMCALcluster(track->GetEMCALcluster());
@@ -588,8 +663,8 @@ AliESDtrack::AliESDtrack(const AliVTrack *track) :
   fTRDchi2 = track->GetTRDchi2();
   //
   SetTOFsignal(track->GetTOFsignal());
-  Double_t expt[AliPID::kSPECIES];
-  track->GetIntegratedTimes(expt);
+  Double_t expt[AliPID::kSPECIESC];
+  track->GetIntegratedTimes(expt,AliPID::kSPECIESC);
   SetIntegratedTimes(expt);
   //
   SetTrackPhiEtaPtOnEMCal(track->GetTrackPhiOnEMCal(),track->GetTrackEtaOnEMCal(),track->GetTrackPtOnEMCal());
@@ -597,6 +672,10 @@ AliESDtrack::AliESDtrack(const AliVTrack *track) :
   SetLabel(track->GetLabel());
   // Set the status
   SetStatus(track->GetStatus());
+  //
+  // Set the ID
+  SetID(track->GetID());
+  //
 }
 
 //_______________________________________________________________________
@@ -617,14 +696,22 @@ AliESDtrack::AliESDtrack(TParticle * part) :
   fITSLabel(0),
   fTPCLabel(0),
   fTRDLabel(0),
+  fTOFLabel(NULL),
   fTOFCalChannel(-1),
   fTOFindex(-1),
   fHMPIDqn(0),
   fHMPIDcluIdx(-1),
   fCaloIndex(kEMCALNoMatch),
+  fR(0),
+  fITSr(0),
+  fTPCr(0),
+  fTRDr(0),
+  fTOFr(0),
+  fHMPIDr(0),
   fHMPIDtrkTheta(0),
   fHMPIDtrkPhi(0),
   fHMPIDsignal(0),
+  fTrackTime(NULL),
   fTrackLength(0),
   fdTPC(0),fzTPC(0),
   fCddTPC(0),fCdzTPC(0),fCzzTPC(0),
@@ -677,6 +764,7 @@ AliESDtrack::AliESDtrack(TParticle * part) :
   fTRDnSlices(0),
   fTRDslices(0x0),
   fVertexID(-2),  // -2 means an orphan track
+  fPIDForTracking(AliPID::kPion),
   fESDEvent(0),
   fCacheNCrossedRows(-10),
   fCacheChi2TPCConstrainedVsGlobal(-10),
@@ -684,7 +772,9 @@ AliESDtrack::AliESDtrack(TParticle * part) :
   fDetectorPID(0x0),
   fTrackPhiOnEMCal(-999),
   fTrackEtaOnEMCal(-999),
-  fTrackPtOnEMCal(-999)
+  fTrackPtOnEMCal(-999),
+  fNtofClusters(0),
+  fTOFcluster(NULL)
 {
   //
   // ESD track from TParticle
@@ -693,15 +783,6 @@ AliESDtrack::AliESDtrack(TParticle * part) :
   // Reset all the arrays
   Int_t i;
   for (i=kNITSchi2Std;i--;) fITSchi2Std[i] = 0;
-  for (i=0; i<AliPID::kSPECIES; i++) {
-    fTrackTime[i]=0.;
-    fR[i]=0.;
-    fITSr[i]=0.;
-    fTPCr[i]=0.;
-    fTRDr[i]=0.;
-    fTOFr[i]=0.;
-    fHMPIDr[i]=0.;
-  }
   
   for (i=0; i<3; i++)   { fKinkIndexes[i]=0;}
   for (i=0; i<3; i++)   { fV0Indexes[i]=-1;}
@@ -710,7 +791,6 @@ AliESDtrack::AliESDtrack(TParticle * part) :
   }
   for (i=0;i<4;i++) {fITSdEdxSamples[i]=0.;}
   for (i=0;i<4;i++) {fTPCPoints[i]=0;}
-  for (i=0;i<3;i++) {fTOFLabel[i]=-1;}
   for (i=0;i<10;i++) {fTOFInfo[i]=0;}
   for (i=0;i<12;i++) {fITSModule[i]=-1;}
 
@@ -761,43 +841,11 @@ AliESDtrack::AliESDtrack(TParticle * part) :
 
   // Set the PID
   Int_t indexPID = 99;
+  if (pdgCode<0) pdgCode = -pdgCode;
+  for (i=0;i<AliPID::kSPECIESC;i++) if (pdgCode==AliPID::ParticleCode(i)) {indexPID = i; break;}
 
-  switch (TMath::Abs(pdgCode)) {
-
-  case  11: // electron
-    indexPID = 0;
-    break;
-
-  case 13: // muon
-    indexPID = 1;
-    break;
-
-  case 211: // pion
-    indexPID = 2;
-    break;
+  if (indexPID < AliPID::kSPECIESC) fPIDForTracking = indexPID;
 
-  case 321: // kaon
-    indexPID = 3;
-    break;
-
-  case 2212: // proton
-    indexPID = 4;
-    break;
-
-  default:
-    break;
-  }
-
-  // If the particle is not e,mu,pi,K or p the PID probabilities are set to 0
-  if (indexPID < AliPID::kSPECIES) {
-    fR[indexPID]=1.;
-    fITSr[indexPID]=1.;
-    fTPCr[indexPID]=1.;
-    fTRDr[indexPID]=1.;
-    fTOFr[indexPID]=1.;
-    fHMPIDr[indexPID]=1.;
-
-  }
   // AliESD track label
   SetLabel(part->GetUniqueID());
 
@@ -824,11 +872,28 @@ AliESDtrack::~AliESDtrack(){
   fCacheChi2TPCConstrainedVsGlobal = -10.;
   if(fCacheChi2TPCConstrainedVsGlobalVertex) fCacheChi2TPCConstrainedVsGlobalVertex = 0;
 
+  if(fTOFcluster)
+    delete[] fTOFcluster;
+  fTOFcluster = NULL;
+  fNtofClusters=0;
+
   delete fDetectorPID;
+
+  delete[] fR;
+  delete[] fITSr;
+  delete[] fTPCr;
+  delete[] fTRDr;
+  delete[] fTOFr;
+  delete[] fHMPIDr;
+  //
+  if(fTrackTime) delete[] fTrackTime; 
+  if(fTOFLabel) delete[] fTOFLabel;
 }
 
-AliESDtrack &AliESDtrack::operator=(const AliESDtrack &source){
-  
+//_______________________________________________________________________
+AliESDtrack &AliESDtrack::operator=(const AliESDtrack &source)
+{
+  // == operator
 
   if(&source == this) return *this;
   AliExternalTrackParam::operator=(source);
@@ -920,8 +985,11 @@ AliESDtrack &AliESDtrack::operator=(const AliESDtrack &source){
   }
   fTPCLabel = source.fTPCLabel; 
   fTRDLabel = source.fTRDLabel;
-  for(int i = 0; i< 3;++i){
-    fTOFLabel[i] = source.fTOFLabel[i];    
+  if(source.fTOFLabel){
+    if(!fTOFLabel) fTOFLabel = new Int_t[3];
+    for(int i = 0; i< 3;++i){
+      fTOFLabel[i] = source.fTOFLabel[i];    
+    }
   }
   fTOFCalChannel = source.fTOFCalChannel;
   fTOFindex      = source.fTOFindex;
@@ -934,21 +1002,58 @@ AliESDtrack &AliESDtrack::operator=(const AliESDtrack &source){
     fV0Indexes[i]   = source.fV0Indexes[i]; 
   }
 
-  for(int i = 0; i< AliPID::kSPECIES;++i){
-    fR[i]     = source.fR[i];
-    fITSr[i]  = source.fITSr[i];
-    fTPCr[i]  = source.fTPCr[i];
-    fTRDr[i]  = source.fTRDr[i];
-    fTOFr[i]  = source.fTOFr[i];
-    fHMPIDr[i] = source.fHMPIDr[i];
-    fTrackTime[i] = source.fTrackTime[i];  
+  if (source.fR) {
+    if (!fR) fR = new Double32_t[AliPID::kSPECIES]; 
+    for (Int_t i=AliPID::kSPECIES;i--;)  fR[i]=source.fR[i];
+  }
+  else {delete[] fR; fR = 0;}
+
+  if (source.fITSr) {
+    if (!fITSr) fITSr = new Double32_t[AliPID::kSPECIES]; 
+    for (Int_t i=AliPID::kSPECIES;i--;)  fITSr[i]=source.fITSr[i]; 
+  }
+  else {delete[] fITSr; fITSr = 0;}
+  //
+  if (source.fTPCr) {
+    if (!fTPCr) fTPCr = new Double32_t[AliPID::kSPECIES]; 
+    for (Int_t i=AliPID::kSPECIES;i--;) fTPCr[i]=source.fTPCr[i]; 
+  }
+  else {delete[] fTPCr; fTPCr = 0;}
+
+  if (source.fTRDr) {
+    if (!fTRDr) fTRDr  = new Double32_t[AliPID::kSPECIES];
+    for (Int_t i=AliPID::kSPECIES;i--;) fTRDr[i]=source.fTRDr[i]; 
+  }
+  else {delete[] fTRDr; fTRDr = 0;}
+
+  if (source.fTOFr) {
+    if (!fTOFr) fTOFr = new Double32_t[AliPID::kSPECIES];
+    for (Int_t i=AliPID::kSPECIES;i--;) fTOFr[i]=source.fTOFr[i];
   }
+  else {delete[] fTOFr; fTOFr = 0;}
+
+  if (source.fHMPIDr) {
+    if (!fHMPIDr) fHMPIDr = new Double32_t[AliPID::kSPECIES];
+    for (Int_t i=AliPID::kSPECIES;i--;) fHMPIDr[i]=source.fHMPIDr[i];
+  }
+  else {delete[] fHMPIDr; fHMPIDr = 0;}
+  
+  fPIDForTracking = source.fPIDForTracking;
 
   fHMPIDtrkTheta = source.fHMPIDtrkTheta;
   fHMPIDtrkPhi   = source.fHMPIDtrkPhi;
   fHMPIDsignal   = source.fHMPIDsignal; 
 
   
+  if(fTrackTime){
+    delete[] fTrackTime;
+  }
+  if(source.fTrackTime){
+    fTrackTime = new Double32_t[AliPID::kSPECIESC];
+    for(Int_t i=0;i < AliPID::kSPECIESC;i++)
+      fTrackTime[i] = source.fTrackTime[i];  
+  }
+
   fTrackLength   = source. fTrackLength;
   fdTPC  = source.fdTPC; 
   fzTPC  = source.fzTPC; 
@@ -1031,6 +1136,7 @@ AliESDtrack &AliESDtrack::operator=(const AliESDtrack &source){
   fTRDncls0  = source.fTRDncls0;      
   fTRDntracklets  = source.fTRDntracklets; 
   fVertexID = source.fVertexID;
+  fPIDForTracking = source.fPIDForTracking;
 
   fCacheNCrossedRows = source.fCacheNCrossedRows;
   fCacheChi2TPCConstrainedVsGlobal = source.fCacheChi2TPCConstrainedVsGlobal;
@@ -1044,6 +1150,15 @@ AliESDtrack &AliESDtrack::operator=(const AliESDtrack &source){
   fTrackEtaOnEMCal= source.fTrackEtaOnEMCal;
   fTrackPtOnEMCal= source.fTrackPtOnEMCal;
 
+  if(fTOFcluster){
+    delete[] fTOFcluster;
+  }
+  fNtofClusters = source.fNtofClusters;
+  if(fNtofClusters > 0){
+    fTOFcluster = new Int_t[fNtofClusters];
+        for(Int_t i=0;i < fNtofClusters;i++) fTOFcluster[i] = source.fTOFcluster[i];
+  }
+
   return *this;
 }
 
@@ -1143,11 +1258,16 @@ Bool_t AliESDtrack::FillTPCOnlyTrack(AliESDtrack &track){
   track.fTPCnclsFIter1   = fTPCnclsFIter1;     
 
   // PID 
-  for(int i=0;i<AliPID::kSPECIES;++i){
-    track.fTPCr[i] = fTPCr[i];
-    // combined PID is TPC only!
-    track.fR[i] = fTPCr[i];
+  if (fTPCr) {
+    if (!track.fTPCr) track.fTPCr = new Double32_t[AliPID::kSPECIES];
+    for(int i=AliPID::kSPECIES;i--;) track.fTPCr[i] = fTPCr[i];
   }
+  //
+  if (fR) {
+    if (!track.fR) track.fR = new Double32_t[AliPID::kSPECIES];
+    for(int i=AliPID::kSPECIES;i--;) track.fR[i] = fR[i];
+  }
+    
   track.fTPCFitMap = fTPCFitMap;
   track.fTPCClusterMap = fTPCClusterMap;
   track.fTPCSharedMap = fTPCSharedMap;
@@ -1177,7 +1297,8 @@ void AliESDtrack::MakeMiniESDtrack(){
   
   fTrackLength = 0;
 
-  for (Int_t i=0;i<AliPID::kSPECIES;i++) fTrackTime[i] = 0;
+  if(fTrackTime)
+    for (Int_t i=0;i<AliPID::kSPECIESC;i++) fTrackTime[i] = 0;
 
   // Reset track parameters constrained to the primary vertex
   delete fCp;fCp = 0;
@@ -1198,7 +1319,7 @@ void AliESDtrack::MakeMiniESDtrack(){
   fITSSharedMap=0;
   fITSsignal = 0;     
   for (Int_t i=0;i<4;i++) fITSdEdxSamples[i] = 0.;
-  for (Int_t i=0;i<AliPID::kSPECIES;i++) fITSr[i]=0; 
+  if (fITSr) for (Int_t i=0;i<AliPID::kSPECIES;i++) fITSr[i]=0; 
   fITSLabel = 0;       
 
   // Reset TPC related track information
@@ -1215,7 +1336,7 @@ void AliESDtrack::MakeMiniESDtrack(){
   fTPCsignalTuned= 0;
   fTPCsignalS= 0;      
   fTPCsignalN= 0;      
-  for (Int_t i=0;i<AliPID::kSPECIES;i++) fTPCr[i]=0; 
+  if (fTPCr) for (Int_t i=0;i<AliPID::kSPECIES;i++) fTPCr[i] = 0; 
   fTPCLabel=0;       
   for (Int_t i=0;i<4;i++) fTPCPoints[i] = 0;
   for (Int_t i=0; i<3;i++)   fKinkIndexes[i] = 0;
@@ -1232,7 +1353,7 @@ void AliESDtrack::MakeMiniESDtrack(){
   for (Int_t i=0;i<kTRDnPlanes;i++) {
     fTRDTimBin[i]  = 0;
   }
-  for (Int_t i=0;i<AliPID::kSPECIES;i++) fTRDr[i] = 0; 
+  if (fTRDr) for (Int_t i=0;i<AliPID::kSPECIES;i++) fTRDr[i] = 0; 
   fTRDLabel = 0;       
   fTRDQuality  = 0;
   fTRDntracklets = 0;
@@ -1253,8 +1374,7 @@ void AliESDtrack::MakeMiniESDtrack(){
   fTOFsignalDx = 999;
   fTOFdeltaBC = 999;
   fTOFl0l1 = 999;
-  for (Int_t i=0;i<AliPID::kSPECIES;i++) fTOFr[i] = 0;
-  for (Int_t i=0;i<3;i++) fTOFLabel[i] = -1;
+  if (fTOFr) for (Int_t i=0;i<AliPID::kSPECIES;i++) fTOFr[i] = 0;
   for (Int_t i=0;i<10;i++) fTOFInfo[i] = 0;
 
   // Reset HMPID related track information
@@ -1262,7 +1382,7 @@ void AliESDtrack::MakeMiniESDtrack(){
   fHMPIDqn = 0;     
   fHMPIDcluIdx = -1;     
   fHMPIDsignal = 0;     
-  for (Int_t i=0;i<AliPID::kSPECIES;i++) fHMPIDr[i] = 0;
+  if (fHMPIDr) for (Int_t i=0;i<AliPID::kSPECIES;i++) fHMPIDr[i] = 0;
   fHMPIDtrkTheta = 0;     
   fHMPIDtrkPhi = 0;      
   fHMPIDtrkX = 0;     
@@ -1275,25 +1395,29 @@ void AliESDtrack::MakeMiniESDtrack(){
   fGlobalChi2 = 0;
 
   fVertexID = -2; // an orphan track
-
+  fPIDForTracking = AliPID::kPion;
+  //
   delete fFriendTrack; fFriendTrack = 0;
 } 
 
 //_______________________________________________________________________
 Int_t AliESDtrack::GetPID(Bool_t tpcOnly) const 
 {
-  // Returns the particle most probable id
+  // Returns the particle most probable id. For backward compatibility first the prob. arrays
+  // will be checked, but normally the GetPIDForTracking will be returned
   Int_t i;
   const Double32_t *prob = 0;
   if (tpcOnly) { // check if TPCpid is valid
+    if (!fTPCr) return GetPIDForTracking();
     prob = fTPCr;
     for (i=0; i<AliPID::kSPECIES-1; i++) if (prob[i] != prob[i+1]) break;
     if (i == AliPID::kSPECIES-1) prob = 0; // not valid, try with combined pid
   }
   if (!prob) { // either requested TPCpid is not valid or comb.pid is requested 
+    if (!fR) return GetPIDForTracking();
     prob = fR;
     for (i=0; i<AliPID::kSPECIES-1; i++) if (prob[i] != prob[i+1]) break;
-    if (i == AliPID::kSPECIES-1) return AliPID::kPion;  // If all the probabilities are equal, return the pion mass
+    if (i == AliPID::kSPECIES-1) return GetPIDForTracking();  // If all the probabilities are equal, return the pion mass
   }
   //
   Float_t max=0.;
@@ -1301,19 +1425,21 @@ Int_t AliESDtrack::GetPID(Bool_t tpcOnly) const
   for (i=0; i<AliPID::kSPECIES; i++) if (prob[i]>max) {k=i; max=prob[i];}
   //
   if (k==0) { // dE/dx "crossing points" in the TPC
+    /*
     Double_t p=GetP();
     if ((p>0.38)&&(p<0.48))
       if (prob[0]<prob[3]*10.) return AliPID::kKaon;
     if ((p>0.75)&&(p<0.85))
       if (prob[0]<prob[4]*10.) return AliPID::kProton;
+    */
     return AliPID::kElectron;
   }
   if (k==1) return AliPID::kMuon; 
   if (k==2||k==-1) return AliPID::kPion;
   if (k==3) return AliPID::kKaon;
   if (k==4) return AliPID::kProton;
-  AliWarning("Undefined PID !");
-  return AliPID::kPion;
+  //  AliWarning("Undefined PID !");
+  return GetPIDForTracking();
 }
 
 //_______________________________________________________________________
@@ -1323,12 +1449,15 @@ Int_t AliESDtrack::GetTOFBunchCrossing(Double_t b, Bool_t pidTPConly) const
   const double kSpacing = 25e3; // min interbanch spacing
   const double kShift = 0;
   Int_t bcid = kTOFBCNA; // defualt one
-  if (!IsOn(kTOFout) || !IsOn(kESDpid)) return bcid; // no info
+  if (!IsOn(kTOFout)/* || !IsOn(kESDpid)*/) return bcid; // no info
   //
-  double tdif = fTOFsignal;
+  double tdif = GetTOFsignal();
   if (IsOn(kTIME)) { // integrated time info is there
     int pid = GetPID(pidTPConly);
-    tdif -= fTrackTime[pid];
+    Double_t times[AliPID::kSPECIESC];
+    // old esd has only AliPID::kSPECIES times
+    GetIntegratedTimes(times,pid>=AliPID::kSPECIES ? AliPID::kSPECIESC : AliPID::kSPECIES); 
+    tdif -= times[pid];
   }
   else { // assume integrated time info from TOF radius and momentum
     const double kRTOF = 385.;
@@ -1397,7 +1526,9 @@ Bool_t AliESDtrack::UpdateTrackParams(const AliKalmanTrack *t, ULong_t flags){
 
   if (t->IsStartedTimeIntegral()) {
     SetStatus(kTIME);
-    Double_t times[10];t->GetIntegratedTimes(times); SetIntegratedTimes(times);
+    Double_t times[AliPID::kSPECIESC];
+    t->GetIntegratedTimes(times); 
+    SetIntegratedTimes(times);
     SetIntegratedLength(t->GetIntegratedLength());
   }
 
@@ -1734,20 +1865,63 @@ Int_t AliESDtrack::GetClusters(Int_t idet, Int_t *idx) const
 }
 
 //_______________________________________________________________________
-void AliESDtrack::GetIntegratedTimes(Double_t *times) const {
+void AliESDtrack::GetIntegratedTimes(Double_t *times, Int_t nspec) const 
+{
+  // get integrated time for requested N species
+  if (nspec<1) return;
+  if(fNtofClusters>0 && GetESDEvent()){
+    TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
+    AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
+    //
+    for(int i=tofcl->GetNMatchableTracks();i--;){
+      if(tofcl->GetTrackIndex(i) == GetID()) {
+       for (int j=nspec; j--;) times[j]=tofcl->GetIntegratedTime(j,i);
+       return;
+      }
+    }
+  }
+  else if(fNtofClusters>0) 
+    AliInfo("No AliESDEvent available here!\n");
+
   // Returns the array with integrated times for each particle hypothesis
-  for (Int_t i=0; i<AliPID::kSPECIES; i++) times[i]=fTrackTime[i];
+  if(fTrackTime)
+    for (int i=nspec; i--;) times[i]=fTrackTime[i];
+  else
+    for (int i=AliPID::kSPECIESC; i--;) times[i]=0.0;
+  //
+}
+//_______________________________________________________________________
+Double_t AliESDtrack::GetIntegratedLength() const{
+  Int_t index = -1;
+  if(fNtofClusters>0 && GetESDEvent()){
+    TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
+    AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
+
+    for(Int_t i=0;i < tofcl->GetNMatchableTracks();i++){
+      if(tofcl->GetTrackIndex(i) == GetID()) index = i;
+    }
+    
+    if(fNtofClusters>0 && index > -1)
+      return tofcl->GetLength(index);
+  }
+  else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
+
+  return fTrackLength;
 }
 
 //_______________________________________________________________________
-void AliESDtrack::SetIntegratedTimes(const Double_t *times) {
+void AliESDtrack::SetIntegratedTimes(const Double_t *times) 
+{
   // Sets the array with integrated times for each particle hypotesis
-  for (Int_t i=0; i<AliPID::kSPECIES; i++) fTrackTime[i]=times[i];
+  if(!fTrackTime) fTrackTime = new Double32_t[AliPID::kSPECIESC];
+  for (int i=AliPID::kSPECIESC; i--;) fTrackTime[i]=times[i];
 }
 
 //_______________________________________________________________________
-void AliESDtrack::SetITSpid(const Double_t *p) {
+void AliESDtrack::SetITSpid(const Double_t *p) 
+{
   // Sets values for the probability of each particle type (in ITS)
+  if (!fITSr) fITSr = new Double32_t[AliPID::kSPECIESC];
   SetPIDValues(fITSr,p,AliPID::kSPECIES);
   SetStatus(AliESDtrack::kITSpid);
 }
@@ -1755,7 +1929,7 @@ void AliESDtrack::SetITSpid(const Double_t *p) {
 //_______________________________________________________________________
 void AliESDtrack::GetITSpid(Double_t *p) const {
   // Gets the probability of each particle type (in ITS)
-  for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i]=fITSr[i];
+  for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i] = fITSr ? fITSr[i] : 0;
 }
 
 //_______________________________________________________________________
@@ -2002,6 +2176,7 @@ Double_t AliESDtrack::GetTPCdensity(Int_t row0, Int_t row1) const{
 //_______________________________________________________________________
 void AliESDtrack::SetTPCpid(const Double_t *p) {  
   // Sets values for the probability of each particle type (in TPC)
+  if (!fTPCr) fTPCr = new Double32_t[AliPID::kSPECIES];
   SetPIDValues(fTPCr,p,AliPID::kSPECIES);
   SetStatus(AliESDtrack::kTPCpid);
 }
@@ -2009,7 +2184,7 @@ void AliESDtrack::SetTPCpid(const Double_t *p) {
 //_______________________________________________________________________
 void AliESDtrack::GetTPCpid(Double_t *p) const {
   // Gets the probability of each particle type (in TPC)
-  for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i]=fTPCr[i];
+  for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i] = fTPCr ? fTPCr[i] : 0;
 }
 
 //_______________________________________________________________________
@@ -2059,6 +2234,7 @@ UChar_t AliESDtrack::GetTRDtracklets(Int_t *idx) const {
 //_______________________________________________________________________
 void AliESDtrack::SetTRDpid(const Double_t *p) {  
   // Sets values for the probability of each particle type (in TRD)
+  if (!fTRDr) fTRDr = new Double32_t[AliPID::kSPECIES];
   SetPIDValues(fTRDr,p,AliPID::kSPECIES);
   SetStatus(AliESDtrack::kTRDpid);
 }
@@ -2066,20 +2242,24 @@ void AliESDtrack::SetTRDpid(const Double_t *p) {
 //_______________________________________________________________________
 void AliESDtrack::GetTRDpid(Double_t *p) const {
   // Gets the probability of each particle type (in TRD)
-  for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i]=fTRDr[i];
+  for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i] = fTRDr ? fTRDr[i]:0;
 }
 
 //_______________________________________________________________________
 void    AliESDtrack::SetTRDpid(Int_t iSpecies, Float_t p)
 {
   // Sets the probability of particle type iSpecies to p (in TRD)
+  if (!fTRDr) {
+    fTRDr = new Double32_t[AliPID::kSPECIES];
+    for (Int_t i=AliPID::kSPECIES; i--;) fTRDr[i] = 0;
+  }
   fTRDr[iSpecies] = p;
 }
 
 Double_t AliESDtrack::GetTRDpid(Int_t iSpecies) const
 {
   // Returns the probability of particle type iSpecies (in TRD)
-  return fTRDr[iSpecies];
+  return fTRDr ? fTRDr[iSpecies] : 0;
 }
 
 //____________________________________________________
@@ -2197,26 +2377,47 @@ void AliESDtrack::SetTRDmomentum(Double_t p, Int_t plane, Double_t *sp)
 //_______________________________________________________________________
 void AliESDtrack::SetTOFpid(const Double_t *p) {  
   // Sets the probability of each particle type (in TOF)
+  if (!fTOFr) fTOFr = new Double32_t[AliPID::kSPECIES];
   SetPIDValues(fTOFr,p,AliPID::kSPECIES);
   SetStatus(AliESDtrack::kTOFpid);
 }
 
 //_______________________________________________________________________
 void AliESDtrack::SetTOFLabel(const Int_t *p) {  
-  // Sets  (in TOF)
-  for (Int_t i=0; i<3; i++) fTOFLabel[i]=p[i];
+
+  if(fNtofClusters>0){
+    TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
+    AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
+    AliESDTOFHit* hit = tofcl->GetTOFHit(0);
+
+    if(hit) hit->SetTOFLabel(p);
+  }
+  else{
+    // Sets  (in TOF)
+    if(!fTOFLabel) fTOFLabel = new Int_t[3]; 
+    for (Int_t i=0; i<3; i++) fTOFLabel[i]=p[i];
+  }
 }
 
 //_______________________________________________________________________
 void AliESDtrack::GetTOFpid(Double_t *p) const {
   // Gets probabilities of each particle type (in TOF)
-  for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i]=fTOFr[i];
+  for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i] = fTOFr ? fTOFr[i]:0;
 }
 
 //_______________________________________________________________________
 void AliESDtrack::GetTOFLabel(Int_t *p) const {
   // Gets (in TOF)
-  for (Int_t i=0; i<3; i++) p[i]=fTOFLabel[i];
+  if(fNtofClusters>0){
+    TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
+    AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
+
+    for (Int_t i=0; i<3; i++) p[i]=tofcl->GetLabel(i);
+  }
+  else{
+    if(fTOFLabel) for (Int_t i=0; i<3; i++) p[i]=fTOFLabel[i];
+    else for (int i=3;i--;) p[i] = -1;
+  }
 }
 
 //_______________________________________________________________________
@@ -2236,6 +2437,7 @@ void AliESDtrack::SetTOFInfo(Float_t*info) {
 //_______________________________________________________________________
 void AliESDtrack::SetHMPIDpid(const Double_t *p) {  
   // Sets the probability of each particle type (in HMPID)
+  if (!fHMPIDr) fHMPIDr = new Double32_t[AliPID::kSPECIES];
   SetPIDValues(fHMPIDr,p,AliPID::kSPECIES);
   SetStatus(AliESDtrack::kHMPIDpid);
 }
@@ -2249,7 +2451,7 @@ void  AliESDtrack::SetTPCdEdxInfo(AliTPCdEdxInfo * dEdxInfo){
 //_______________________________________________________________________
 void AliESDtrack::GetHMPIDpid(Double_t *p) const {
   // Gets probabilities of each particle type (in HMPID)
-  for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i]=fHMPIDr[i];
+  for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i] = fHMPIDr ? fHMPIDr[i]:0;
 }
 
 
@@ -2257,6 +2459,7 @@ void AliESDtrack::GetHMPIDpid(Double_t *p) const {
 //_______________________________________________________________________
 void AliESDtrack::SetESDpid(const Double_t *p) {  
   // Sets the probability of each particle type for the ESD track
+  if (!fR) fR = new Double32_t[AliPID::kSPECIES];
   SetPIDValues(fR,p,AliPID::kSPECIES);
   SetStatus(AliESDtrack::kESDpid);
 }
@@ -2264,7 +2467,7 @@ void AliESDtrack::SetESDpid(const Double_t *p) {
 //_______________________________________________________________________
 void AliESDtrack::GetESDpid(Double_t *p) const {
   // Gets probability of each particle type for the ESD track
-  for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i]=fR[i];
+  for (Int_t i=0; i<AliPID::kSPECIES; i++) p[i] = fR ? fR[i]:0;
 }
 
 //_______________________________________________________________________
@@ -2704,3 +2907,613 @@ void AliESDtrack::SetDetectorPID(const AliDetectorPID *pid)
   fDetectorPID=pid;
   
 }
+
+Double_t AliESDtrack::GetLengthInActiveZone( Int_t mode, Double_t deltaY, Double_t deltaZ, Double_t bz, Double_t exbPhi , TTreeSRedirector * pcstream) const {
+  //
+  // Input parameters:
+  //   mode  - type of external track parameters 
+  //   deltaY - user defined "dead region" in cm
+  //   deltaZ - user defined "active region" in cm (250 cm drift lenght - 14 cm L1 delay
+  //   bz     - magnetic field 
+  //   exbPhi - optional rotation due to the ExB effect
+  // return value:
+  //   the length of the track in cm in "active volume" of the TPC
+  //
+  if (mode==0) return GetLengthInActiveZone(this, deltaY,deltaZ,bz, exbPhi,pcstream);
+  if (mode==1) return GetLengthInActiveZone(fIp, deltaY,deltaZ,bz, exbPhi,pcstream);
+  if (mode==2) return GetLengthInActiveZone(fOp, deltaY,deltaZ,bz, exbPhi,pcstream);
+  return 0;
+}
+
+Double_t AliESDtrack::GetLengthInActiveZone(const AliExternalTrackParam  *paramT, Double_t deltaY, Double_t deltaZ, Double_t bz, Double_t exbPhi , TTreeSRedirector * pcstream) {
+  //
+  // Numerical code to calculate the length of the track in active region of the TPC
+  // ( can be speed up if somebody wants to invest time - analysical version shoult be possible) 
+  //
+  // Input parameters:
+  //   paramT - external track parameters 
+  //   deltaY - user defined "dead region" in cm
+  //   deltaZ - user defined "active region" in cm (250 cm drift lenght - 14 cm L1 delay
+  //   bz     - magnetic field 
+  //   exbPhi - optional rotation due to the ExB effect
+  // return value:
+  //   the length of the track in cm in "active volume" of the TPC
+  //
+  const Double_t rIn=85;
+  const Double_t rOut=245;
+  Double_t xyz[3], pxyz[3];
+  if (paramT->GetXYZAt(rIn,bz,xyz)){
+    paramT->GetPxPyPzAt(rIn,bz,pxyz);
+  }else{
+    paramT->GetXYZ(xyz);
+    paramT->GetPxPyPz(pxyz);
+  }
+  //
+  Double_t dca   = -paramT->GetD(0,0,bz);  // get impact parameter distance to point (0,0)
+  Double_t radius= TMath::Abs(1/paramT->GetC(bz));  //
+  Double_t sign  = paramT->GetSign();
+  Double_t R0    = TMath::Sqrt(xyz[0]*xyz[0]+xyz[1]*xyz[1]);   // radius at current point
+  Double_t phiR0 = TMath::ATan2(xyz[1],xyz[0]);                // angle of given point
+  Double_t dPhiR0= -TMath::ASin((dca*dca-2*dca*radius*sign+R0*R0)/(2*R0*(dca-radius*sign)));
+  Double_t phi0  = phiR0-(dPhiR0);  // global phi offset to be added
+  //
+  //
+  AliExternalTrackParam paramR=(*paramT);
+  Double_t length=0;
+  for (Double_t R=rIn; R<=rOut; R++){
+    Double_t sinPhi=(dca*dca-2*dca*radius*sign+R*R)/(2*R*(dca-radius*sign));
+    if (TMath::Abs(sinPhi)>=1) continue;
+    Double_t dphi     = -TMath::ASin(sinPhi);
+    Double_t phi      = phi0+dphi;                           // global phi
+    Int_t    sector   = TMath::Nint(9*phi/(TMath::Pi()));
+    Double_t dPhiEdge = phi-(sector*TMath::Pi()/9)+exbPhi;   // distance to sector boundary in rphi
+    Double_t dX   = R*TMath::Cos(phi)-xyz[0];
+    Double_t dY   = R*TMath::Sin(phi)-xyz[1];
+    Double_t deltaPhi = 2*TMath::ASin(0.5*TMath::Sqrt(dX*dX+dY*dY)/radius);
+    Double_t z = xyz[2]+deltaPhi*radius*paramT->GetTgl();
+    if (TMath::Abs(dPhiEdge*R)>deltaY && TMath::Abs(z)<deltaZ){
+      length++;
+    }
+    //    Double_t deltaZ= dphi*radius; 
+    if (pcstream){
+      //should we keep debug possibility ?
+      AliExternalTrackParam paramTcopy=(*paramT);
+      paramR.Rotate(phi);
+      paramR.PropagateTo(R,bz);
+      (*pcstream)<<"debugEdge"<<
+       "R="<<R<<                   // radius
+       "dphiEdge="<<dPhiEdge<<     // distance to edge 
+       "phi0="<<phi0<<             // phi0 -phi at the track initial position
+       "phi="<<phi<<               // 
+       "z="<<z<<
+       "pT.="<<&paramTcopy<<
+       "pR.="<<&paramR<<
+       "\n";
+    }
+  }
+  return length;
+}
+
+Double_t AliESDtrack::GetMassForTracking() const
+{
+  int pid = fPIDForTracking;
+  if (pid<AliPID::kPion) pid = AliPID::kPion;
+  double m = AliPID::ParticleMass(pid);
+  return (fPIDForTracking==AliPID::kHe3 || fPIDForTracking==AliPID::kAlpha) ? -m : m;
+}
+
+
+void    AliESDtrack::SetTOFclusterArray(Int_t /*ncluster*/,Int_t */*TOFcluster*/){
+  AliInfo("Method has to be implemented!");
+//   fNtofClusters=ncluster;
+//   if(TOFcluster == fTOFcluster) return;
+//   if(fTOFcluster){ // reset previous content    
+//     delete[] fTOFcluster;
+//     fTOFcluster = NULL;
+//     fNtofClusters=0;
+//   }
+
+//   if(ncluster){ // set new content
+//     fTOFcluster = new Int_t[fNtofClusters];
+//     for(Int_t i=0;i < fNtofClusters;i++) fTOFcluster[i] = TOFcluster[i];
+//   }
+//   else
+//     fTOFcluster = 0;
+}
+
+//____________________________________________
+void  AliESDtrack::SuppressTOFMatches()
+{
+  // remove reference to this track from TOF clusters
+  if (!fNtofClusters || !GetESDEvent()) return;
+  TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
+  for (;fNtofClusters--;) {
+    AliESDTOFCluster* clTOF = (AliESDTOFCluster*)tofclArray->At(fTOFcluster[fNtofClusters]);
+    clTOF->SuppressMatchedTrack(GetID());
+    if (!clTOF->GetNMatchableTracks()) { // remove this cluster
+      int last = tofclArray->GetEntriesFast()-1;
+      AliESDTOFCluster* clTOFL = (AliESDTOFCluster*)tofclArray->At(last);
+      if (last != fTOFcluster[fNtofClusters]) {
+       *clTOF = *clTOFL; // move last cluster to the place of eliminated one
+       // fix the references on this cluster
+       clTOF->FixSelfReferences(last,fTOFcluster[fNtofClusters]);
+      }
+      tofclArray->RemoveAt(last);
+    }
+  }
+}
+
+//____________________________________________
+void  AliESDtrack::ReplaceTOFTrackID(int oldID, int newID)
+{
+  // replace the ID in TOF clusters references to this track
+  if (!fNtofClusters || !GetESDEvent()) return;
+  TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
+  for (int it=fNtofClusters;it--;) {
+    AliESDTOFCluster* clTOF = (AliESDTOFCluster*)tofclArray->At(fTOFcluster[it]);
+    clTOF->ReplaceMatchedTrackID(oldID,newID);
+  }
+}
+
+//____________________________________________
+void  AliESDtrack::ReplaceTOFClusterID(int oldID, int newID)
+{
+  // replace the referenc on TOF cluster oldID by newID
+  if (!fNtofClusters || !GetESDEvent()) return;
+  for (int it=fNtofClusters;it--;) {
+    if (fTOFcluster[it] == oldID) {
+      fTOFcluster[it] = newID;
+      return;
+    }
+  }
+}
+
+//____________________________________________
+void  AliESDtrack::ReplaceTOFMatchID(int oldID, int newID)
+{
+  // replace in the ESDTOFCluster associated with this track the id of the corresponding
+  // ESDTOFMatch from oldID to newID
+  if (!fNtofClusters || !GetESDEvent()) return;
+  TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
+  for (int it=fNtofClusters;it--;) {
+    AliESDTOFCluster* clTOF = (AliESDTOFCluster*)tofclArray->At(fTOFcluster[it]);
+    clTOF->ReplaceMatchID(oldID,newID);
+  }
+}
+
+//____________________________________________
+void AliESDtrack::AddTOFcluster(Int_t icl)
+{
+  fNtofClusters++;
+  
+  Int_t *old = fTOFcluster;
+  fTOFcluster = new Int_t[fNtofClusters];
+
+  for(Int_t i=0;i < fNtofClusters-1;i++) fTOFcluster[i] = old[i];
+  fTOFcluster[fNtofClusters-1] = icl;
+
+  if(fNtofClusters-1)  delete[] old; // delete previous content    
+}
+
+//____________________________________________
+void AliESDtrack::SetTOFsignal(Double_t tof)
+{
+  if(fNtofClusters>0 && GetESDEvent()){
+    TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
+    AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
+    AliESDTOFHit* hit = tofcl->GetTOFHit(0);
+    if(hit) hit->SetTime(tof);
+  }
+  else{
+    if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
+    fTOFsignal=tof;
+  }
+}
+//____________________________________________
+void AliESDtrack::SetTOFCalChannel(Int_t index){
+  if(fNtofClusters>0 && GetESDEvent()){
+    TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
+    AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
+    AliESDTOFHit* hit = tofcl->GetTOFHit(0);
+    if(hit) hit->SetTOFchannel(index);
+  }
+  else{
+    if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
+    fTOFCalChannel=index;
+  }
+}
+//____________________________________________
+void AliESDtrack::SetTOFsignalToT(Double_t ToT){
+  if(fNtofClusters>0 && GetESDEvent()){
+    TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
+    AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
+    AliESDTOFHit* hit = tofcl->GetTOFHit(0);
+    if(hit) hit->SetTOT(ToT);
+  }
+  else{
+    if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
+    fTOFsignalToT=ToT;
+  }
+}
+//____________________________________________
+void AliESDtrack::SetTOFsignalRaw(Double_t tof){
+  if(fNtofClusters>0 && GetESDEvent()){
+    TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
+    AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
+    AliESDTOFHit* hit = tofcl->GetTOFHit(0);
+    if(hit) hit->SetTimeRaw(tof);
+  }
+  else{
+    if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
+    fTOFsignalRaw=tof;
+  }
+}
+//____________________________________________
+void AliESDtrack::SetTOFsignalDz(Double_t dz){
+  Int_t index = -1;
+  AliESDTOFCluster *tofcl;
+
+  if(fNtofClusters>0 && GetESDEvent()){
+    TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
+    tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
+
+    for(Int_t i=0;i < tofcl->GetNMatchableTracks();i++){
+      if(tofcl->GetTrackIndex(i) == GetID()) index = i;
+    }
+
+  }
+  if(index > -1){
+    AliESDTOFMatch* match = tofcl->GetTOFMatch(index);
+    if(match){
+      match->SetDz(dz);
+    }
+  }
+  else{
+    if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
+    fTOFsignalDz=dz;
+  }
+
+
+}
+//____________________________________________
+void AliESDtrack::SetTOFsignalDx(Double_t dx){
+  Int_t index = -1;
+  AliESDTOFCluster *tofcl;
+
+  if(fNtofClusters>0 && GetESDEvent()){
+    TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
+    tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
+
+    for(Int_t i=0;i < tofcl->GetNMatchableTracks();i++){
+      if(tofcl->GetTrackIndex(i) == GetID()) index = i;
+    }
+
+  }
+  if(index > -1){
+    AliESDTOFMatch* match = tofcl->GetTOFMatch(index);
+    if(match){
+      match->SetDx(dx);
+    }
+  }
+  else{
+    if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
+    fTOFsignalDx=dx;
+  }
+}
+//____________________________________________
+void AliESDtrack::SetTOFDeltaBC(Short_t deltaBC){
+  if(fNtofClusters>0 && GetESDEvent()){
+    TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
+    AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
+    AliESDTOFHit* hit = tofcl->GetTOFHit(0);
+    if(hit) hit->SetDeltaBC(deltaBC);
+  }
+  else{
+    if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
+    fTOFdeltaBC=deltaBC;
+  }
+}
+//____________________________________________
+void AliESDtrack::SetTOFL0L1(Short_t l0l1){
+  if(fNtofClusters>0 && GetESDEvent()){
+    TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
+    AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
+    AliESDTOFHit* hit = tofcl->GetTOFHit(0);
+    if(hit) hit->SetL0L1Latency(l0l1);
+  }
+  else{
+    if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
+    fTOFl0l1=l0l1;
+  }
+}
+//____________________________________________
+Double_t AliESDtrack::GetTOFsignal() const 
+{
+  if(fNtofClusters>0 && GetESDEvent()){
+    TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
+    AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
+
+    return tofcl->GetTime();
+  }
+  else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
+
+  return fTOFsignal;
+}
+
+//____________________________________________
+Double_t AliESDtrack::GetTOFsignalToT() const 
+{
+  if(fNtofClusters>0 && GetESDEvent()){
+    TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
+    AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
+
+    return tofcl->GetTOT();
+  }
+  else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
+
+  return fTOFsignalToT;
+}
+
+//____________________________________________
+Double_t AliESDtrack::GetTOFsignalRaw() const 
+{
+  if(fNtofClusters>0 && GetESDEvent()){
+    TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
+    AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
+
+    return tofcl->GetTimeRaw();
+  }
+  else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
+
+  return fTOFsignalRaw;
+}
+
+//____________________________________________
+Double_t AliESDtrack::GetTOFsignalDz() const 
+{
+
+  AliESDTOFCluster *tofcl;
+
+  Int_t index = -1;
+  if(fNtofClusters>0 && GetESDEvent()){
+    TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
+    tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
+
+    for(Int_t i=0;i < tofcl->GetNMatchableTracks();i++){
+      if(tofcl->GetTrackIndex(i) == GetID()) index = i;
+    }
+  }
+  else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
+
+  if(fNtofClusters>0 && index > -1){
+    return tofcl->GetDz(index);
+  }
+  return fTOFsignalDz;
+}
+
+//____________________________________________
+Double_t AliESDtrack::GetTOFsignalDx() const 
+{
+  AliESDTOFCluster *tofcl;
+
+  Int_t index = -1;
+  if(fNtofClusters>0 && GetESDEvent()){
+    TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
+    tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
+    for(Int_t i=0;i < tofcl->GetNMatchableTracks();i++){
+      if(tofcl->GetTrackIndex(i) == GetID()) index = i;
+    }
+  }
+  else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
+  if(fNtofClusters>0 && index > -1){
+    return tofcl->GetDx(index);
+  }
+  return fTOFsignalDx;
+}
+
+//____________________________________________
+Short_t  AliESDtrack::GetTOFDeltaBC() const 
+{
+  if(fNtofClusters>0 && GetESDEvent()){
+    TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
+    AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
+    return tofcl->GetDeltaBC();
+  }
+  else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
+
+  return fTOFdeltaBC;
+}
+
+//____________________________________________
+Short_t  AliESDtrack::GetTOFL0L1() const 
+{
+  if(fNtofClusters>0 && GetESDEvent()){
+    TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
+    AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
+
+    return tofcl->GetL0L1Latency();
+  }
+  else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
+
+  return fTOFl0l1;
+}
+
+//____________________________________________
+Int_t   AliESDtrack::GetTOFCalChannel() const 
+{
+  if(fNtofClusters>0 && GetESDEvent()){
+    TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
+    AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
+
+    return tofcl->GetTOFchannel();
+  }
+  else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
+
+  return fTOFCalChannel;
+}
+
+//____________________________________________
+Int_t   AliESDtrack::GetTOFcluster() const 
+{
+  if(fNtofClusters>0 && GetESDEvent()){
+    TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
+    AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
+
+    return tofcl->GetClusterIndex();
+  }
+  else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
+
+  return fTOFindex;
+}
+
+//____________________________________________
+Int_t   AliESDtrack::GetTOFclusterN() const
+{
+  return fNtofClusters;
+}
+
+//____________________________________________
+Bool_t  AliESDtrack::IsTOFHitAlreadyMatched() const{
+  if(fNtofClusters>0 && GetESDEvent()){
+    TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
+    AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[0]);
+
+    if (tofcl->GetNMatchableTracks() > 1)
+      return kTRUE;
+  }
+  else if(fNtofClusters>0) AliInfo("No AliESDEvent available here!\n");
+
+  return kFALSE;
+}
+
+//____________________________________________
+void AliESDtrack::ReMapTOFcluster(Int_t ncl,Int_t *mapping){
+  for(Int_t i=0;i<fNtofClusters;i++){
+    if(fTOFcluster[i]<ncl && fTOFcluster[i]>-1)
+      fTOFcluster[i] = mapping[fTOFcluster[i]];
+    else
+      AliInfo(Form("TOF cluster re-mapping in AliESDtrack: out of range (%i > %i)\n",fTOFcluster[i],ncl));
+  }
+}
+
+//____________________________________________
+void AliESDtrack::SortTOFcluster(){
+  TClonesArray *tofclArray = GetESDEvent()->GetESDTOFClusters();
+
+  for(Int_t i=0;i<fNtofClusters-1;i++){
+    for(Int_t j=i+1;j<fNtofClusters;j++){
+      AliESDTOFCluster *tofcl = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[i]);
+      Int_t index1 = -1;
+      for(Int_t it=0;it < tofcl->GetNMatchableTracks();it++){
+         if(tofcl->GetTrackIndex(it) == GetID()) index1 = it;
+      }
+      Double_t timedist1 = 10000;
+      for(Int_t isp=0; isp< AliPID::kSPECIESC;isp++){
+       Double_t timec = TMath::Abs(tofcl->GetTime() - tofcl->GetIntegratedTime(isp));
+       if(timec < timedist1) timedist1 = timec;
+      }
+      timedist1 *= 0.03; // in cm
+      Double_t radius1 = tofcl->GetDx(index1)*tofcl->GetDx(index1) + tofcl->GetDz(index1)*tofcl->GetDz(index1) + timedist1*timedist1;
+
+      AliESDTOFCluster *tofcl2 = (AliESDTOFCluster *) tofclArray->At(fTOFcluster[j]);
+      Int_t index2 = -1;
+      for(Int_t it=0;it < tofcl2->GetNMatchableTracks();it++){
+         if(tofcl2->GetTrackIndex(it) == GetID()) index2 = it;
+      }
+      if(index1 == -1 || index2 == -1){
+      }
+      Double_t timedist2 = 10000;
+      for(Int_t isp=0; isp< AliPID::kSPECIESC;isp++){
+       Double_t timec = TMath::Abs(tofcl2->GetTime() - tofcl2->GetIntegratedTime(isp));
+       if(timec < timedist2) timedist2 = timec;
+      }
+      timedist2 *= 0.03; // in cm
+      Double_t radius2 = tofcl2->GetDx(index2)*tofcl2->GetDx(index2) + tofcl2->GetDz(index2)*tofcl2->GetDz(index2) + timedist2*timedist2;
+
+      if(radius2 < radius1){
+        Int_t change = fTOFcluster[i];
+        fTOFcluster[i] = fTOFcluster[j];
+        fTOFcluster[j] = change;
+      }
+    }
+  }
+}
+
+//____________________________________________
+const AliTOFHeader* AliESDtrack::GetTOFHeader() const {
+  return fESDEvent->GetTOFHeader();
+}
+
+//___________________________________________
+void AliESDtrack::SetID(Short_t id) 
+{
+  // set track ID taking care about dependencies
+  if (fNtofClusters) ReplaceTOFTrackID(fID,id); 
+  fID=id;
+}
+
+
+Double_t  AliESDtrack::GetdEdxInfo(Int_t regionID, Int_t calibID, Int_t qID, Int_t valueID){
+  //
+  // Interface to get the calibrated dEdx information 
+  // For details of arguments and return values see 
+  //     AliTPCdEdxInfo::GetdEdxInfo(Int_t regionID, Int_t calibID, Int_t valueID)
+  //
+  if (!fTPCdEdxInfo) return 0;
+  if (!fIp) return 0;
+  return fTPCdEdxInfo->GetdEdxInfo(fIp, regionID, calibID, qID, valueID);
+}
+
+
+Double_t AliESDtrack::GetdEdxInfoTRD(Int_t method, Double_t p0, Double_t p1, Double_t p2){
+  //
+  // Methods
+  // mean values:
+  //     0.)   linear
+  //     1.)   logarithmic
+  //     2.)   1/sqrt
+  //     3.)   power()
+  // time COG:
+  //     4.)   linear
+  //     5.)   logarithmic
+  //     6.)   square
+  Int_t nSlicesPerLayer=GetNumberOfTRDslices();
+  Int_t nSlicesAll=GetNumberOfTRDslices()*kTRDnPlanes;
+
+  if (method<=3){
+    Double_t sumAmp=0;
+    Int_t    sumW=0;
+    for (Int_t ibin=0; ibin<nSlicesAll; ibin++){
+      if (fTRDslices[ibin]<=0) continue; 
+      sumW++;
+      if (method==0) sumAmp+=fTRDslices[ibin];
+      if (method==1) sumAmp+=TMath::Log(TMath::Abs(fTRDslices[ibin])+p0);
+      if (method==2) sumAmp+=1/TMath::Sqrt(TMath::Abs(fTRDslices[ibin])+p0);
+      if (method==3) sumAmp+=TMath::Power(TMath::Abs(fTRDslices[ibin])+p0,p1);
+    }
+    if (sumW==0) return 0;
+    Double_t dEdx=sumAmp/sumW;
+    if (method==1) dEdx= TMath::Exp(dEdx);
+    if (method==2) dEdx= 1/(dEdx*dEdx);
+    if (method==3) dEdx= TMath::Power(dEdx,1/p1);
+    return dEdx;
+  }
+  if (method>3){
+    Double_t sumWT=0;
+    Double_t sumW=0;
+    for (Int_t ibin=0; ibin<nSlicesAll; ibin++){
+      if (fTRDslices[ibin]<=0) continue; 
+      Double_t time=(ibin%nSlicesPerLayer);
+      Double_t weight=fTRDslices[ibin];
+      if (method==5) weight=TMath::Log((weight+p0)/p0);
+      if (method==6) weight=TMath::Power(weight+p0,p1);
+      sumWT+=time*weight;
+      sumW+=weight;
+    }
+    if (sumW<=0) return 0;
+    Double_t meanTime=sumWT/sumW;
+    return meanTime;
+  }
+  return 0;
+}