]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - TPC/AliTPCtracker.cxx
- Pass (p,E) with PushTrack.
[u/mrichter/AliRoot.git] / TPC / AliTPCtracker.cxx
index fd39eb1876d1ae50fbb634acfb6c34973c02aaeb..cb351146a1c309c597a3cb6a23f592a11518cff6 100644 (file)
 
 /*
 $Log$
+Revision 1.37  2003/07/22 15:56:14  hristov
+Implementing ESD functionality in the NewIO (Yu.Belikov)
+
+Revision 1.35.2.3  2003/07/15 09:58:03  hristov
+Corrected back-propagation (Yu.Belikov)
+
+Revision 1.35.2.2  2003/07/14 09:19:33  hristov
+TOF included in the combined PID (Yu.Belikov)
+
+Revision 1.35.2.1  2003/07/11 10:53:01  hristov
+Inward refit for TPC and TRD in the ESD schema (T.Kuhr)
+
+Revision 1.35  2003/05/23 10:08:51  hristov
+SetLabel replaced by SetNumber (Yu.Belikov)
+
+Revision 1.34  2003/05/22 13:57:48  hristov
+First implementation of ESD classes (Yu.Belikov)
+
+Revision 1.32  2003/04/10 10:36:54  hristov
+Code for unified TPC/TRD tracking (S.Radomski)
+
+Revision 1.31  2003/03/19 17:14:11  hristov
+Load/UnloadClusters added to the base class and the derived classes changed correspondingly. Possibility to give 2 input files for ITS and TPC tracks in PropagateBack. TRD tracker uses fEventN from the base class (T.Kuhr)
+
+Revision 1.30  2003/02/28 16:13:32  hristov
+Typos corrected
+
+Revision 1.29  2003/02/28 15:18:16  hristov
+Corrections suggested by J.Chudoba
+
+Revision 1.28  2003/02/27 16:15:52  hristov
+Code for inward refitting (S.Radomski)
+
+Revision 1.27  2003/02/25 16:47:58  hristov
+allow back propagation for more than 1 event (J.Chudoba)
+
+Revision 1.26  2003/02/19 08:49:46  hristov
+Track time measurement (S.Radomski)
+
+Revision 1.25  2003/01/28 16:43:35  hristov
+Additional protection: to be discussed with the Root team (M.Ivanov)
+
+Revision 1.24  2002/11/19 16:13:24  hristov
+stdlib.h included to declare exit() on HP
+
+Revision 1.23  2002/11/19 11:50:08  hristov
+Removing CONTAINERS (Yu.Belikov)
+
+Revision 1.19  2002/07/19 07:31:40  kowal2
+Improvement in tracking by J. Belikov
+
+Revision 1.18  2002/05/13 07:33:52  kowal2
+Added protection in Int_t AliTPCtracker::AliTPCRow::Find(Double_t y) const
+in the case of defined region of interests.
+
+Revision 1.17  2002/03/18 17:59:13  kowal2
+Chnges in the pad geometry - 3 pad lengths introduced.
+
+Revision 1.16  2001/11/08 16:39:03  hristov
+Additional protection (M.Masera)
+
+Revision 1.15  2001/11/08 16:36:33  hristov
+Updated V2 stream of tracking (Yu.Belikov). The new long waited features are: 1) Possibility to pass the primary vertex position to the trackers (both for the TPC and the ITS) 2) Possibility to specify the number of tracking passes together with applying (or not applying) the vertex constraint (ITS only) 3) Possibility to make some use of partial PID provided by the TPC when doing tracking in the ITS (ITS only) 4) V0 reconstruction with a helix minimisation of the DCA. (new macros: AliV0FindVertices.C and AliV0Comparison.C) 4a) ( Consequence of the 4) )  All the efficiencies and resolutions are from now on calculated including *secondary*particles* too. (Don't be surprised by the drop in efficiency etc)
+
+Revision 1.14  2001/10/21 19:04:55  hristov
+Several patches were done to adapt the barel reconstruction to the multi-event case. Some memory leaks were corrected. (Yu.Belikov)
+
+Revision 1.13  2001/07/23 12:01:30  hristov
+Initialisation added
+
+Revision 1.12  2001/07/20 14:32:44  kowal2
+Processing of many events possible now
+
+Revision 1.11  2001/05/23 08:50:10  hristov
+Weird inline removed
+
 Revision 1.10  2001/05/16 14:57:25  alibrary
 New files for folders and Stack
 
@@ -44,21 +120,24 @@ Splitted from AliTPCtracking
 //
 //   Origin: Iouri Belikov, CERN, Jouri.Belikov@cern.ch 
 //-------------------------------------------------------
-
 #include <TObjArray.h>
+#include <TError.h>
 #include <TFile.h>
 #include <TTree.h>
-#include <iostream.h>
+#include <stdlib.h>
+
+#include "AliESD.h"
 
 #include "AliTPCtracker.h"
 #include "AliTPCcluster.h"
 #include "AliTPCParam.h"
-#include "AliTPCClustersRow.h"
+#include "AliClusters.h"
+
+ClassImp(AliTPCtracker)
 
 //_____________________________________________________________________________
 AliTPCtracker::AliTPCtracker(const AliTPCParam *par): 
-fkNIS(par->GetNInnerSector()/2), 
-fkNOS(par->GetNOuterSector()/2)
+AliTracker(), fkNIS(par->GetNInnerSector()/2), fkNOS(par->GetNOuterSector()/2)
 {
   //---------------------------------------------------------------------
   // The main TPC tracker constructor
@@ -70,13 +149,16 @@ fkNOS(par->GetNOuterSector()/2)
   for (i=0; i<fkNIS; i++) fInnerSec[i].Setup(par,0);
   for (i=0; i<fkNOS; i++) fOuterSec[i].Setup(par,1);
 
-  fN=0;  fSectors=0;
-
-  fClustersArray.Setup(par);
-  fClustersArray.SetClusterType("AliTPCcluster");
-  fClustersArray.ConnectTree("Segment Tree");
-
+  fParam = (AliTPCParam*) par;
   fSeeds=0;
+
+  // [SR 17.03.2003]
+  
+  fBarrelFile = 0;
+  fBarrelTree = 0;
+  fBarrelArray = 0;
+  fBarrelTrack = 0;
+  
 }
 
 //_____________________________________________________________________________
@@ -86,7 +168,100 @@ AliTPCtracker::~AliTPCtracker() {
   //------------------------------------------------------------------
   delete[] fInnerSec;
   delete[] fOuterSec;
-  delete fSeeds;
+  if (fSeeds) {
+    fSeeds->Delete(); 
+    delete fSeeds;
+  }
+
+  // [SR, 01.04.2003]
+  if (fBarrelFile) {
+    fBarrelFile->Close();
+    delete fBarrelFile;
+  }
+}
+
+//_____________________________________________________________________________
+void AliTPCtracker::SetBarrelTree(const char *mode) {
+  //
+  // Creates a tree for BarrelTracks
+  // mode = "back" or "refit"
+  //
+  // [SR, 01.04.2003]
+  //
+  
+  if (!IsStoringBarrel()) return;
+  
+  TDirectory *sav = gDirectory;
+  if (!fBarrelFile) fBarrelFile = new TFile("AliBarrelTracks.root", "UPDATE");
+
+  char buff[40];
+  sprintf(buff, "BarrelTPC_%d_%s", GetEventNumber(), mode);
+
+  fBarrelFile->cd();
+  fBarrelTree = new TTree(buff, "Barrel TPC tracks");
+  
+  if (!fBarrelArray) fBarrelArray = new TClonesArray("AliBarrelTrack", 4);
+  for(Int_t i=0; i<4; i++) new((*fBarrelArray)[i]) AliBarrelTrack();
+  
+  fBarrelTree->Branch("tracks", &fBarrelArray);
+  
+  sav->cd();
+}
+//_____________________________________________________________________________
+
+void AliTPCtracker::StoreBarrelTrack(AliTPCtrack *ps, Int_t refPlane, Int_t isIn) {
+  //
+  // Stores Track at a given reference plane
+  // 
+  // refPlane: 1-4
+  // isIn: 1 - backward, 2 - refit
+  //
+  
+  if (!IsStoringBarrel()) return;
+  if (refPlane < 0 || refPlane > 4) return;
+  if (isIn > 2) return;
+
+  static Int_t nClusters;
+  static Int_t nWrong;
+  static Double_t chi2;
+  static Int_t index;
+
+  Int_t newClusters, newWrong;
+  Double_t newChi2;
+
+  if ( (refPlane == 1 && isIn == kTrackBack) || 
+       (refPlane == 4 && isIn == kTrackRefit) ) {
+    
+    fBarrelArray->Clear();
+    nClusters = nWrong = 0;
+    chi2 = 0.0;
+    index = 0;
+  }
+
+  // propagate
+  Double_t refX = 0;
+  if (refPlane == 1) refX = fParam->GetInnerRadiusLow();
+  if (refPlane == 2) refX = fParam->GetInnerRadiusUp();
+  if (refPlane == 3) refX = fParam->GetOuterRadiusLow();
+  if (refPlane == 4) refX = fParam->GetOuterRadiusUp();
+
+  ps->PropagateTo(refX);
+
+  fBarrelTrack = (AliBarrelTrack*)(*fBarrelArray)[index++];
+  ps->GetBarrelTrack(fBarrelTrack);
+  
+  newClusters = ps->GetNumberOfClusters() - nClusters; 
+  newWrong = ps->GetNWrong() - nWrong;
+  newChi2 = ps->GetChi2() - chi2;
+
+  nClusters =  ps->GetNumberOfClusters();
+  nWrong = ps->GetNWrong();
+  chi2 = ps->GetChi2();
+
+  fBarrelTrack->SetNClusters(newClusters, newChi2);
+  fBarrelTrack->SetNWrongClusters(newWrong);
+  fBarrelTrack->SetRefPlane(refPlane, isIn);
 }
 
 //_____________________________________________________________________________
@@ -182,91 +357,75 @@ Double_t f3(Double_t x1,Double_t y1,
 }
 
 //_____________________________________________________________________________
-void AliTPCtracker::LoadOuterSectors() {
+Int_t AliTPCtracker::LoadClusters(TTree *cTree) {
   //-----------------------------------------------------------------
-  // This function fills outer TPC sectors with clusters.
+  // This function loads TPC clusters.
   //-----------------------------------------------------------------
-  UInt_t index;
-  Int_t j=Int_t(fClustersArray.GetTree()->GetEntries());
-  for (Int_t i=0; i<j; i++) {
-      AliSegmentID *s=fClustersArray.LoadEntry(i);
-      Int_t sec,row;
-      AliTPCParam *par=(AliTPCParam*)fClustersArray.GetParam();
-      par->AdjustSectorRow(s->GetID(),sec,row);
-      if (sec<fkNIS*2) continue;
-      AliTPCClustersRow *clrow=fClustersArray.GetRow(sec,row);
-      Int_t ncl=clrow->GetArray()->GetEntriesFast();
-      while (ncl--) {
-         AliTPCcluster *c=(AliTPCcluster*)(*clrow)[ncl];
-         index=(((sec<<8)+row)<<16)+ncl;
-         fOuterSec[(sec-fkNIS*2)%fkNOS][row].InsertCluster(c,index);
-      }
+  TBranch *branch=cTree->GetBranch("Segment");
+  if (!branch) {
+     Error("LoadClusters","Can't get the branch !");
+     return 1;
   }
 
-  fN=fkNOS;
-  fSectors=fOuterSec;
-}
+  AliClusters carray, *addr=&carray;
+  carray.SetClass("AliTPCcluster");
+  carray.SetArray(0);
+  branch->SetAddress(&addr);
 
-//_____________________________________________________________________________
-void AliTPCtracker::UnloadOuterSectors() {
-  //-----------------------------------------------------------------
-  // This function clears outer TPC sectors.
-  //-----------------------------------------------------------------
-  Int_t nup=fOuterSec->GetNRows();
-  for (Int_t i=0; i<fkNOS; i++) {
-    for (Int_t j=0; j<nup; j++) {
-      if (fClustersArray.GetRow(i+fkNIS*2,j)) 
-          fClustersArray.ClearRow(i+fkNIS*2,j);
-      if (fClustersArray.GetRow(i+fkNIS*2+fkNOS,j)) 
-          fClustersArray.ClearRow(i+fkNIS*2+fkNOS,j);
-    }
-  }
+  Int_t nentr=(Int_t)cTree->GetEntries();
 
-  fN=0;
-  fSectors=0;
-}
+  for (Int_t i=0; i<nentr; i++) {
+      cTree->GetEvent(i);
 
-//_____________________________________________________________________________
-void AliTPCtracker::LoadInnerSectors() {
-  //-----------------------------------------------------------------
-  // This function fills inner TPC sectors with clusters.
-  //-----------------------------------------------------------------
-  UInt_t index;
-  Int_t j=Int_t(fClustersArray.GetTree()->GetEntries());
-  for (Int_t i=0; i<j; i++) {
-      AliSegmentID *s=fClustersArray.LoadEntry(i);
-      Int_t sec,row;
-      AliTPCParam *par=(AliTPCParam*)fClustersArray.GetParam();
-      par->AdjustSectorRow(s->GetID(),sec,row);
-      if (sec>=fkNIS*2) continue;
-      AliTPCClustersRow *clrow=fClustersArray.GetRow(sec,row);
-      Int_t ncl=clrow->GetArray()->GetEntriesFast();
-      while (ncl--) {
-         AliTPCcluster *c=(AliTPCcluster*)(*clrow)[ncl];
-         index=(((sec<<8)+row)<<16)+ncl;
-         fInnerSec[sec%fkNIS][row].InsertCluster(c,index);
+      Int_t ncl=carray.GetArray()->GetEntriesFast();
+
+      Int_t nir=fInnerSec->GetNRows(), nor=fOuterSec->GetNRows();
+      Int_t id=carray.GetID();
+      if ((id<0) || (id>2*(fkNIS*nir + fkNOS*nor))) {
+        Error("LoadClusters","Wrong index !");
+         exit(1);
+      }
+      Int_t outindex = 2*fkNIS*nir;
+      if (id<outindex) {
+         Int_t sec = id/nir;
+         Int_t row = id - sec*nir;
+         sec %= fkNIS;
+         AliTPCRow &padrow=fInnerSec[sec][row];
+         while (ncl--) {
+           AliTPCcluster *c=(AliTPCcluster*)carray[ncl];
+           padrow.InsertCluster(c,sec,row);
+         }
+      } else {
+         id -= outindex;
+         Int_t sec = id/nor;
+         Int_t row = id - sec*nor;
+         sec %= fkNOS;
+         AliTPCRow &padrow=fOuterSec[sec][row];
+         while (ncl--) {
+           AliTPCcluster *c=(AliTPCcluster*)carray[ncl];
+           padrow.InsertCluster(c,sec+fkNIS,row);
+         }
       }
+      carray.GetArray()->Clear();
   }
 
-  fN=fkNIS;
-  fSectors=fInnerSec;
+  return 0;
 }
 
 //_____________________________________________________________________________
-void AliTPCtracker::UnloadInnerSectors() {
+void AliTPCtracker::UnloadClusters() {
   //-----------------------------------------------------------------
-  // This function clears inner TPC sectors.
+  // This function unloads TPC clusters.
   //-----------------------------------------------------------------
-  Int_t nlow=fInnerSec->GetNRows();
-  for (Int_t i=0; i<fkNIS; i++) {
-    for (Int_t j=0; j<nlow; j++) {
-      if (fClustersArray.GetRow(i,j)) fClustersArray.ClearRow(i,j);
-      if (fClustersArray.GetRow(i+fkNIS,j)) fClustersArray.ClearRow(i+fkNIS,j);
-    }
+  Int_t i;
+  for (i=0; i<fkNIS; i++) {
+    Int_t nr=fInnerSec->GetNRows();
+    for (Int_t n=0; n<nr; n++) fInnerSec[i][n].ResetClusters();
+  }
+  for (i=0; i<fkNOS; i++) {
+    Int_t nr=fOuterSec->GetNRows();
+    for (Int_t n=0; n<nr; n++) fOuterSec[i][n].ResetClusters();
   }
-
-  fN=0;
-  fSectors=0;
 }
 
 //_____________________________________________________________________________
@@ -284,7 +443,8 @@ Int_t AliTPCtracker::FollowProlongation(AliTPCseed& t, Int_t rf) {
   if (alpha < 0.            ) alpha += 2.*TMath::Pi();  
   Int_t s=Int_t(alpha/fSectors->GetAlpha())%fN;
 
-  for (Int_t nr=fSectors->GetRowNumber(xt)-1; nr>=rf; nr--) {
+  Int_t nrows=fSectors->GetRowNumber(xt)-1;
+  for (Int_t nr=nrows; nr>=rf; nr--) {
     Double_t x=fSectors->GetX(nr), ymax=fSectors->GetMaxY(nr);
     if (!t.PropagateTo(x)) return 0;
 
@@ -299,8 +459,7 @@ Int_t AliTPCtracker::FollowProlongation(AliTPCseed& t, Int_t rf) {
 
     if (road>kMaxROAD) {
       if (t.GetNumberOfClusters()>4) 
-        cerr<<t.GetNumberOfClusters()
-        <<"FindProlongation warning: Too broad road !\n"; 
+         Warning("FindProlongation","Too broad road !"); 
       return 0;
     }
 
@@ -319,7 +478,8 @@ Int_t AliTPCtracker::FollowProlongation(AliTPCseed& t, Int_t rf) {
     }
     if (cl) {
       Float_t l=fSectors->GetPadPitchWidth();
-      t.SetSampledEdx(cl->GetQ()/l,t.GetNumberOfClusters());
+      Float_t corr=1.; if (nr>63) corr=0.67; // new (third) pad response !
+      t.SetSampledEdx(cl->GetQ()/l*corr,t.GetNumberOfClusters());
       if (!t.Update(cl,maxchi2,index)) {
          if (!tryAgain--) return 0;
       } else tryAgain=kSKIP;
@@ -338,6 +498,57 @@ Int_t AliTPCtracker::FollowProlongation(AliTPCseed& t, Int_t rf) {
 
   return 1;
 }
+//_____________________________________________________________________________
+
+Int_t AliTPCtracker::FollowRefitInward(AliTPCseed *seed, AliTPCtrack *track) {
+  //
+  // This function propagates seed inward TPC using old clusters
+  // from the track.
+  // 
+  // Sylwester Radomski, GSI
+  // 26.02.2003
+  //
+
+  // loop over rows
+
+  Int_t nRows = fSectors->GetNRows();
+  for (Int_t iRow = nRows; iRow >= 0; iRow--) {
+
+    Double_t x = fSectors->GetX(iRow);
+    if (!seed->PropagateTo(x)) return 0;
+
+    // try to find an assigned cluster in this row
+
+    AliTPCcluster* cluster = NULL;
+    Int_t idx = -1;
+    Int_t sec = -1;
+    for (Int_t iCluster = 0; iCluster < track->GetNumberOfClusters(); iCluster++) {
+      idx = track->GetClusterIndex(iCluster); 
+      sec = (idx&0xff000000)>>24; 
+      Int_t row = (idx&0x00ff0000)>>16;
+      if (((fSectors == fInnerSec) && (sec >= fkNIS)) ||
+         ((fSectors == fOuterSec) && (sec < fkNIS))) continue;
+      if (row == iRow) {
+       cluster = (AliTPCcluster*) GetCluster(idx);
+       break;
+      }
+    }
+
+    // update the track seed with the found cluster
+
+    if (cluster) {
+      Double_t dAlpha = fParam->GetAngle(sec) - seed->GetAlpha();
+      if (TMath::Abs(dAlpha) > 0.0001) {
+       if (!seed->Rotate(dAlpha)) return 0;
+       if (!seed->PropagateTo(x)) return 0;
+      }
+
+      seed->Update(cluster, seed->GetPredictedChi2(cluster), idx);
+    }
+  }
+
+  return 1;
+}
 
 //_____________________________________________________________________________
 Int_t AliTPCtracker::FollowBackProlongation
@@ -351,21 +562,20 @@ Int_t AliTPCtracker::FollowBackProlongation
   Int_t s=Int_t(alpha/fSectors->GetAlpha())%fN;
 
   Int_t idx=-1, sec=-1, row=-1;
-  Int_t nc=seed.GetLabel(); //index of the cluster to start with
+  Int_t nc=seed.GetNumber();
+
   if (nc--) {
      idx=track.GetClusterIndex(nc);
      sec=(idx&0xff000000)>>24; row=(idx&0x00ff0000)>>16;
   }
-  if (fSectors==fInnerSec) { if (sec >= 2*fkNIS) row=-1; } 
-  else { if (sec <  2*fkNIS) row=-1; }   
+  if (fSectors==fInnerSec) { if (sec >= fkNIS) row=-1; } 
+  else { if (sec <  fkNIS) row=-1; }   
 
   Int_t nr=fSectors->GetNRows();
   for (Int_t i=0; i<nr; i++) {
     Double_t x=fSectors->GetX(i), ymax=fSectors->GetMaxY(i);
-
-    if (!seed.PropagateTo(x)) return 0;
-
-    Double_t y=seed.GetY();
+    Double_t y=seed.GetYat(x);
     if (y > ymax) {
        s = (s+1) % fN;
        if (!seed.Rotate(fSectors->GetAlpha())) return 0;
@@ -374,6 +584,8 @@ Int_t AliTPCtracker::FollowBackProlongation
        if (!seed.Rotate(-fSectors->GetAlpha())) return 0;
     }
 
+    if (!seed.PropagateTo(x)) return 0;
+
     AliTPCcluster *cl=0;
     Int_t index=0;
     Double_t maxchi2=kMaxCHI2;
@@ -382,12 +594,10 @@ Int_t AliTPCtracker::FollowBackProlongation
     Double_t sz2=SigmaZ2(seed.GetX(),seed.GetTgl());
     Double_t road=4.*sqrt(seed.GetSigmaY2() + sy2), z=seed.GetZ();
     if (road>kMaxROAD) {
-      cerr<<seed.GetNumberOfClusters()
-          <<"AliTPCtracker::FollowBackProlongation: Too broad road !\n"; 
+      Warning("FollowBackProlongation","Too broad road !"); 
       return 0;
     }
 
-
     Int_t accepted=seed.GetNumberOfClusters();
     if (row==i) {
        //try to accept already found cluster
@@ -401,8 +611,8 @@ Int_t AliTPCtracker::FollowBackProlongation
           idx=track.GetClusterIndex(nc); 
           sec=(idx&0xff000000)>>24; row=(idx&0x00ff0000)>>16;
        } 
-       if (fSectors==fInnerSec) { if (sec >= 2*fkNIS) row=-1; }
-       else { if (sec <  2*fkNIS) row=-1; }   
+       if (fSectors==fInnerSec) { if (sec >= fkNIS) row=-1; }
+       else { if (sec < fkNIS) row=-1; }   
 
     }
     if (!cl) {
@@ -426,13 +636,14 @@ Int_t AliTPCtracker::FollowBackProlongation
 
     if (cl) {
       Float_t l=fSectors->GetPadPitchWidth();
-      seed.SetSampledEdx(cl->GetQ()/l,seed.GetNumberOfClusters());
+      Float_t corr=1.; if (i>63) corr=0.67; // new (third) pad response !
+      seed.SetSampledEdx(cl->GetQ()/l*corr,seed.GetNumberOfClusters());
       seed.Update(cl,maxchi2,index);
     }
 
   }
 
-  seed.SetLabel(nc);
+  seed.SetNumber(nc);
 
   return 1;
 }
@@ -442,53 +653,53 @@ void AliTPCtracker::MakeSeeds(Int_t i1, Int_t i2) {
   //-----------------------------------------------------------------
   // This function creates track seeds.
   //-----------------------------------------------------------------
-  if (fSeeds==0) fSeeds=new TObjArray(15000);
-
   Double_t x[5], c[15];
 
-  Double_t alpha=fOuterSec->GetAlpha(), shift=fOuterSec->GetAlphaShift();
+  Double_t alpha=fSectors->GetAlpha(), shift=fSectors->GetAlphaShift();
   Double_t cs=cos(alpha), sn=sin(alpha);
 
-  Double_t x1 =fOuterSec->GetX(i1);
-  Double_t xx2=fOuterSec->GetX(i2);
+  Double_t x1 =fSectors->GetX(i1);
+  Double_t xx2=fSectors->GetX(i2);
 
-  for (Int_t ns=0; ns<fkNOS; ns++) {
-    Int_t nl=fOuterSec[(ns-1+fkNOS)%fkNOS][i2];
-    Int_t nm=fOuterSec[ns][i2];
-    Int_t nu=fOuterSec[(ns+1)%fkNOS][i2];
-    const AliTPCRow& kr1=fOuterSec[ns][i1];
+  for (Int_t ns=0; ns<fN; ns++) {
+    Int_t nl=fSectors[(ns-1+fN)%fN][i2];
+    Int_t nm=fSectors[ns][i2];
+    Int_t nu=fSectors[(ns+1)%fN][i2];
+    const AliTPCRow& kr1=fSectors[ns][i1];
     for (Int_t is=0; is < kr1; is++) {
       Double_t y1=kr1[is]->GetY(), z1=kr1[is]->GetZ();
       for (Int_t js=0; js < nl+nm+nu; js++) {
        const AliTPCcluster *kcl;
         Double_t x2,   y2,   z2;
-        Double_t x3=0.,y3=0.;
+        Double_t x3=GetX(), y3=GetY(), z3=GetZ();
 
        if (js<nl) {
-         const AliTPCRow& kr2=fOuterSec[(ns-1+fkNOS)%fkNOS][i2];
+         const AliTPCRow& kr2=fSectors[(ns-1+fN)%fN][i2];
          kcl=kr2[js];
           y2=kcl->GetY(); z2=kcl->GetZ();
           x2= xx2*cs+y2*sn;
           y2=-xx2*sn+y2*cs;
        } else 
          if (js<nl+nm) {
-           const AliTPCRow& kr2=fOuterSec[ns][i2];
+           const AliTPCRow& kr2=fSectors[ns][i2];
            kcl=kr2[js-nl];
             x2=xx2; y2=kcl->GetY(); z2=kcl->GetZ();
          } else {
-           const AliTPCRow& kr2=fOuterSec[(ns+1)%fkNOS][i2];
+           const AliTPCRow& kr2=fSectors[(ns+1)%fN][i2];
            kcl=kr2[js-nl-nm];
             y2=kcl->GetY(); z2=kcl->GetZ();
             x2=xx2*cs-y2*sn;
             y2=xx2*sn+y2*cs;
          }
 
-        Double_t zz=z1 - z1/x1*(x1-x2); 
+        Double_t zz=z1 - (z1-z3)/(x1-x3)*(x1-x2); 
         if (TMath::Abs(zz-z2)>5.) continue;
 
         Double_t d=(x2-x1)*(0.-y2)-(0.-x2)*(y2-y1);
-        if (d==0.) {cerr<<"MakeSeeds warning: Straight seed !\n"; continue;}
-
+        if (d==0.) {
+           Warning("MakeSeeds","Straight seed !"); 
+           continue;
+        }
        x[0]=y1;
        x[1]=z1;
        x[4]=f1(x1,y1,x2,y2,x3,y3);
@@ -499,11 +710,12 @@ void AliTPCtracker::MakeSeeds(Int_t i1, Int_t i2) {
        if (TMath::Abs(x[3]) > 1.2) continue;
        Double_t a=asin(x[2]);
        Double_t zv=z1 - x[3]/x[4]*(a+asin(x[4]*x1-x[2]));
-       if (TMath::Abs(zv)>10.) continue; 
+       if (TMath::Abs(zv-z3)>10.) continue; 
 
         Double_t sy1=kr1[is]->GetSigmaY2(), sz1=kr1[is]->GetSigmaZ2();
         Double_t sy2=kcl->GetSigmaY2(),     sz2=kcl->GetSigmaZ2();
-       Double_t sy3=100*0.025, sy=0.1, sz=0.1;
+       //Double_t sy3=400*3./12., sy=0.1, sz=0.1;
+        Double_t sy3=25000*x[4]*x[4]+0.1, sy=0.1, sz=0.1;
 
        Double_t f40=(f1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
        Double_t f42=(f1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
@@ -527,7 +739,7 @@ void AliTPCtracker::MakeSeeds(Int_t i1, Int_t i2) {
 
         UInt_t index=kr1.GetIndex(is);
        AliTPCseed *track=new AliTPCseed(index, x, c, x1, ns*alpha+shift);
-        Float_t l=fOuterSec->GetPadPitchWidth();
+        Float_t l=fSectors->GetPadPitchWidth();
         track->SetSampledEdx(kr1[is]->GetQ()/l,0);
 
         Int_t rc=FollowProlongation(*track, i2);
@@ -547,15 +759,14 @@ Int_t AliTPCtracker::ReadSeeds(const TFile *inp) {
 
   TFile *in=(TFile*)inp;
   if (!in->IsOpen()) {
-     cerr<<"AliTPCtracker::ReadSeeds(): input file is not open !\n";
+     Error("ReadSeeds","Input file has not been open !");
      return 1;
   }
 
   in->cd();
   TTree *seedTree=(TTree*)in->Get("Seeds");
   if (!seedTree) {
-     cerr<<"AliTPCtracker::ReadSeeds(): ";
-     cerr<<"can't get a tree with track seeds !\n";
+     Error("ReadSeeds","Can't get a tree with track seeds !");
      return 2;
   }
   AliTPCtrack *seed=new AliTPCtrack; 
@@ -570,113 +781,434 @@ Int_t AliTPCtracker::ReadSeeds(const TFile *inp) {
   }
   
   delete seed;
+
+  delete seedTree; //Thanks to Mariana Bondila
+
   savedir->cd();
 
   return 0;
 }
 
 //_____________________________________________________________________________
-Int_t AliTPCtracker::Clusters2Tracks(const TFile *inp, TFile *out) {
+Int_t AliTPCtracker::Clusters2Tracks(AliESD *event) {
   //-----------------------------------------------------------------
   // This is a track finder.
+  // The clusters must be already loaded ! 
   //-----------------------------------------------------------------
-  TDirectory *savedir=gDirectory; 
 
-  if (inp) {
-     TFile *in=(TFile*)inp;
-     if (!in->IsOpen()) {
-        cerr<<"AliTPCtracker::Clusters2Tracks(): input file is not open !\n";
-        return 1;
-     }
+  //find track seeds
+  Int_t nup=fOuterSec->GetNRows(), nlow=fInnerSec->GetNRows();
+  Int_t nrows=nlow+nup;
+  if (fSeeds==0) {
+     Int_t gap=Int_t(0.125*nrows), shift=Int_t(0.5*gap);
+     fSectors=fOuterSec; fN=fkNOS;
+     fSeeds=new TObjArray(15000);
+     MakeSeeds(nup-1, nup-1-gap);
+     MakeSeeds(nup-1-shift, nup-1-shift-gap);
+  }
+  fSeeds->Sort();
+
+  Int_t nseed=fSeeds->GetEntriesFast();
+  for (Int_t i=0; i<nseed; i++) {
+    //tracking in the outer sectors
+    fSectors=fOuterSec; fN=fkNOS;
+
+    AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
+    if (!FollowProlongation(t)) {
+       delete fSeeds->RemoveAt(i);
+       continue;
+    }
+
+    //tracking in the inner sectors
+    fSectors=fInnerSec; fN=fkNIS;
+
+    Double_t alpha=t.GetAlpha() - fInnerSec->GetAlphaShift();
+    if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
+    if (alpha < 0.            ) alpha += 2.*TMath::Pi();
+    Int_t ns=Int_t(alpha/fInnerSec->GetAlpha())%fkNIS;
+
+    alpha=ns*fInnerSec->GetAlpha()+fInnerSec->GetAlphaShift()-t.GetAlpha();
+
+    if (t.Rotate(alpha)) {
+      if (FollowProlongation(t)) {
+        if (t.GetNumberOfClusters() >= Int_t(0.4*nrows)) {
+          t.CookdEdx();
+          CookLabel(pt,0.1); //For comparison only
+          pt->PropagateTo(fParam->GetInnerRadiusLow());
+          AliESDtrack iotrack;
+          iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
+
+          event->AddTrack(&iotrack);
+
+          UseClusters(&t);
+        }
+      }
+    }
+    delete fSeeds->RemoveAt(i);
   }
 
-  if (!out->IsOpen()) {
-     cerr<<"AliTPCtracker::Clusters2Tracks(): output file is not open !\n";
-     return 2;
+  Info("Clusters2Tracks","Number of found tracks : %d",
+       event->GetNumberOfTracks());
+
+  fSeeds->Clear(); delete fSeeds; fSeeds=0;
+
+  return 0;
+}
+
+//_____________________________________________________________________________
+Int_t AliTPCtracker::Clusters2Tracks(TTree *cTree, TTree *tTree) {
+  //-----------------------------------------------------------------
+  // This is a track finder.
+  //-----------------------------------------------------------------
+  if (LoadClusters(cTree)) {
+    Error("Clusters2Tracks","Problem with loading the clusters...");
+    return 1;
   }
 
-  out->cd();
-  TTree tracktree("TPCf","Tree with TPC tracks");
   AliTPCtrack *iotrack=0;
-  tracktree.Branch("tracks","AliTPCtrack",&iotrack,32000,0);
-
-  LoadOuterSectors();
+  TBranch *branch=tTree->GetBranch("tracks");
+  if (!branch) tTree->Branch("tracks","AliTPCtrack",&iotrack,32000,3);
+  else branch->SetAddress(&iotrack);
 
   //find track seeds
   Int_t nup=fOuterSec->GetNRows(), nlow=fInnerSec->GetNRows();
   Int_t nrows=nlow+nup;
   if (fSeeds==0) {
      Int_t gap=Int_t(0.125*nrows), shift=Int_t(0.5*gap);
+     fSectors=fOuterSec; fN=fkNOS;
+     fSeeds=new TObjArray(15000);     
      MakeSeeds(nup-1, nup-1-gap);
      MakeSeeds(nup-1-shift, nup-1-shift-gap);
-  }    
+  }
   fSeeds->Sort();
 
-  //tracking in outer sectors
+  Int_t found=0;
   Int_t nseed=fSeeds->GetEntriesFast();
-  Int_t i;
-  for (i=0; i<nseed; i++) {
+
+  for (Int_t i=0; i<nseed; i++) {
+    //tracking in the outer sectors
+    fSectors=fOuterSec; fN=fkNOS;
+
     AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
-    if (FollowProlongation(t)) {
-       UseClusters(&t);
+    if (!FollowProlongation(t)) {
+       delete fSeeds->RemoveAt(i);
        continue;
     }
-    delete fSeeds->RemoveAt(i);
-  }  
-  UnloadOuterSectors();
 
-  //tracking in inner sectors
-  LoadInnerSectors();
-  Int_t found=0;
-  for (i=0; i<nseed; i++) {
-    AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
-    if (!pt) continue;
-    Int_t nc=t.GetNumberOfClusters();
+    //tracking in the inner sectors
+    fSectors=fInnerSec; fN=fkNIS;
 
     Double_t alpha=t.GetAlpha() - fInnerSec->GetAlphaShift();
     if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
     if (alpha < 0.            ) alpha += 2.*TMath::Pi();
     Int_t ns=Int_t(alpha/fInnerSec->GetAlpha())%fkNIS;
 
-    alpha=ns*fInnerSec->GetAlpha() + fInnerSec->GetAlphaShift() - t.GetAlpha();
+    alpha=ns*fInnerSec->GetAlpha()+fInnerSec->GetAlphaShift()-t.GetAlpha();
 
     if (t.Rotate(alpha)) {
-       if (FollowProlongation(t)) {
-          if (t.GetNumberOfClusters() >= Int_t(0.4*nrows)) {
-             t.CookdEdx();
-             iotrack=pt;
-             tracktree.Fill();
-             UseClusters(&t,nc);
-             cerr<<found++<<'\r';
-          }
-       }
+      if (FollowProlongation(t)) {
+        if (t.GetNumberOfClusters() >= Int_t(0.4*nrows)) {
+          t.CookdEdx();
+          CookLabel(pt,0.1); //For comparison only
+          pt->PropagateTo(fParam->GetInnerRadiusLow());
+          iotrack=pt;
+          tTree->Fill();
+          UseClusters(&t);
+         found++;
+        }
+      }
     }
     delete fSeeds->RemoveAt(i); 
-  }  
-  UnloadInnerSectors();
+  }
+  
+  Info("Clusters2Tracks","Number of found tracks : %d",found);
+
+  UnloadClusters();
+
+  fSeeds->Clear(); delete fSeeds; fSeeds=0;
+
+  return 0;
+}
+
+//_____________________________________________________________________________
+Int_t AliTPCtracker::RefitInward(AliESD* event) {
+  //
+  // The function propagates tracks throught TPC inward
+  // using already associated clusters.
+  // The clusters must be already loaded !
+  //
+
+  Int_t nTracks = event->GetNumberOfTracks();
+  Int_t nRefited = 0;
+
+  for (Int_t i = 0; i < nTracks; i++) {
+    AliESDtrack* track = event->GetTrack(i);
+    ULong_t status = track->GetStatus();
+
+    if ( (status & AliESDtrack::kTPCout ) == 0 ) continue;
+    if ( (status & AliESDtrack::kTPCrefit) != 0 ) continue;
+    
+    AliTPCtrack* tpcTrack = new AliTPCtrack(*track);
+    AliTPCseed* seed = new AliTPCseed(*tpcTrack, tpcTrack->GetAlpha());
+
+    fSectors = fOuterSec;
+
+    Int_t res = FollowRefitInward(seed, tpcTrack);
+    UseClusters(seed);
+    Int_t nc = seed->GetNumberOfClusters();
+
+    fSectors = fInnerSec;
+
+    res = FollowRefitInward(seed, tpcTrack);
+    UseClusters(seed, nc);
+
+    if (res) {
+      seed->PropagateTo(fParam->GetInnerRadiusLow());
+      seed->SetLabel(tpcTrack->GetLabel());
+      seed->SetdEdx(tpcTrack->GetdEdx());
+      track->UpdateTrackParams(seed, AliESDtrack::kTPCrefit);
+      nRefited++;
+    }
+
+    delete seed;
+    delete tpcTrack;
+  }
+
+  Info("RefitInward","Number of refitted tracks : %d",nRefited);
+
+  return 0;
+}
+
+//_____________________________________________________________________________
+Int_t AliTPCtracker::RefitInward(TTree */*in*/, TTree */*out*/) {
+  //
+  // The function propagates tracks throught TPC inward
+  // using already associated clusters.
+  //
+  Error("RefitInward","This method is not converted to NewIO yet\n");
+  return 1;
+  /*
+  if (!inSeeds->IsOpen()) {
+    cout << "Input File with seeds not open !\n" << endl;
+    return 1;
+  }
+  
+  if (!inTracks->IsOpen()) {
+    cout << "Input File not open !\n" << endl;
+    return 2;
+  }
+  
+  if (!outTracks->IsOpen()) {
+    cout << "Output File not open !\n" << endl;
+    return 3;
+  }
+
+  TDirectory *savedir = gDirectory; 
+  LoadClusters();
+
+  // Connect to input seeds tree
+  inSeeds->cd();
+  char tname[100];
+  sprintf(tname, "seedTRDtoTPC_%d", GetEventNumber()); 
+  TTree *seedsTree = (TTree*)inSeeds->Get(tname);
+  TBranch *inSeedBranch = seedsTree->GetBranch("tracks");
+  AliTPCtrack *inSeedTrack = 0;
+  inSeedBranch->SetAddress(&inSeedTrack);
+
+  Int_t nSeeds = (Int_t)seedsTree->GetEntries();
+
+  // Connect to input tree
+  inTracks->cd();
+  sprintf(tname,"TreeT_TPC_%d",GetEventNumber());
+//  sprintf(tname,"seedsTPCtoTRD_%d",GetEventNumber());
+  TTree *inputTree = (TTree*)inTracks->Get(tname);
+  TBranch *inBranch = inputTree->GetBranch("tracks");
+  AliTPCtrack *inTrack = 0;
+  inBranch->SetAddress(&inTrack);
+
+  Int_t nTracks = (Int_t)inputTree->GetEntries();
+
+  // Create output tree
+  outTracks->cd(); 
+  AliTPCtrack *outTrack = new AliTPCtrack();
+  sprintf(tname, "tracksTPC_%d", GetEventNumber()); 
+  TTree *outputTree = new TTree(tname,"Refited TPC tracks");
+  outputTree->Branch("tracks", "AliTPCtrack", &outTrack, 32000, 3);
+
+  Int_t nRefited = 0;
+
+  // create table of track labels
+  Int_t* inLab = new Int_t[nTracks];
+  for (Int_t i = 0; i < nTracks; i++) inLab[i] = -1;
+
+  // [SR, 01.04.2003] - Barrel tracks
+  if (IsStoringBarrel()) SetBarrelTree("refit");
+
+  for(Int_t t=0; t < nSeeds; t++) {
+    
+    seedsTree->GetEntry(t);
+    // find TPC track for seed
+    Int_t lab = TMath::Abs(inSeedTrack->GetLabel());
+    for(Int_t i=0; i < nTracks; i++) {
+      if (inLab[i] == lab) {
+       inputTree->GetEntry(i);
+       break;
+      } else if (inLab[i] < 0) {
+       inputTree->GetEntry(i);
+       inLab[i] = TMath::Abs(inTrack->GetLabel());
+       if (inLab[i] == lab) break;
+      }
+    }
+    if (TMath::Abs(inTrack->GetLabel()) != lab) continue;
+    AliTPCseed *seed = new AliTPCseed(*inSeedTrack, inTrack->GetAlpha());
+    if (IsStoringBarrel()) StoreBarrelTrack(seed, 4, 2);
+
+    fSectors = fOuterSec;
+
+    Int_t res = FollowRefitInward(seed, inTrack);
+    UseClusters(seed);
+    Int_t nc = seed->GetNumberOfClusters();
+
+    if (IsStoringBarrel()) StoreBarrelTrack(seed, 3, 2);
+    if (IsStoringBarrel()) StoreBarrelTrack(seed, 2, 2);
+
+    fSectors = fInnerSec;
+
+    res = FollowRefitInward(seed, inTrack);
+    UseClusters(seed, nc);
+
+    if (IsStoringBarrel()) StoreBarrelTrack(seed, 1, 2);
+
+    if (res) {
+      seed->PropagateTo(fParam->GetInnerRadiusLow());
+      outTrack = (AliTPCtrack*)seed;
+      outTrack->SetLabel(inTrack->GetLabel());
+      outTrack->SetdEdx(inTrack->GetdEdx());
+      outputTree->Fill();
+      nRefited++;
+    }
 
-  tracktree.Write();
+    if (IsStoringBarrel()) fBarrelTree->Fill();
+    delete seed;
+  }
 
-  cerr<<"Number of found tracks : "<<found<<endl;
+  cout << "Refitted " << nRefited << " tracks." << endl;
+
+  outTracks->cd();
+  outputTree->Write();
+  
+  delete[] inLab;
+  
+  // [SR, 01.04.2003]
+  if (IsStoringBarrel()) {
+    fBarrelFile->cd();
+    fBarrelTree->Write();
+    fBarrelFile->Flush();  
+    
+    delete fBarrelArray;
+    delete fBarrelTree;
+  }
+  
+  if (inputTree) delete inputTree;
+  if (outputTree) delete outputTree;
 
   savedir->cd();
+  UnloadClusters();
+
+  return 0;
+  */
+}
+
+Int_t AliTPCtracker::PropagateBack(AliESD *event) {
+  //-----------------------------------------------------------------
+  // This function propagates tracks back through the TPC.
+  // The clusters must be already loaded !
+  //-----------------------------------------------------------------
+  Int_t nentr=event->GetNumberOfTracks();
+  Info("PropagateBack", "Number of ESD tracks: %d\n", nentr);
+
+  Int_t ntrk=0;
+  for (Int_t i=0; i<nentr; i++) {
+    AliESDtrack *esd=event->GetTrack(i);
+    ULong_t status=esd->GetStatus();
+
+    if ( (status & AliESDtrack::kTPCin ) == 0 ) continue;
+    if ( (status & AliESDtrack::kTPCout) != 0 ) continue;
+
+    const AliTPCtrack t(*esd);
+    AliTPCseed s(t,t.GetAlpha());
+
+    if ( (status & AliESDtrack::kITSout) == 0 ) s.ResetCovariance();
+
+    s.ResetNWrong();
+    s.ResetNRotation();
+    
+    Int_t nc=t.GetNumberOfClusters();
+    s.SetNumber(nc); //set number of the cluster to start with
+
+    //inner sectors
+    fSectors=fInnerSec; fN=fkNIS;
+
+    Double_t alpha=s.GetAlpha() - fSectors->GetAlphaShift();
+    if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
+    if (alpha < 0.            ) alpha += 2.*TMath::Pi();
+    Int_t ns=Int_t(alpha/fSectors->GetAlpha())%fN;
+    alpha =ns*fSectors->GetAlpha() + fSectors->GetAlphaShift();
+    alpha-=s.GetAlpha();
+
+    if (!s.Rotate(alpha)) continue;
+    if (!FollowBackProlongation(s,t)) continue;
+
+    UseClusters(&s);
+
+    //outer sectors
+    fSectors=fOuterSec; fN=fkNOS;
+
+    nc=s.GetNumberOfClusters();
+
+    alpha=s.GetAlpha() - fSectors->GetAlphaShift();
+    if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
+    if (alpha < 0.            ) alpha += 2.*TMath::Pi();
+    ns=Int_t(alpha/fSectors->GetAlpha())%fN;
+
+    alpha =ns*fSectors->GetAlpha() + fSectors->GetAlphaShift();
+    alpha-=s.GetAlpha();
+
+    if (!s.Rotate(alpha)) continue;
+    if (!FollowBackProlongation(s,t)) continue;
+    {
+    Int_t nrows=fOuterSec->GetNRows()+fInnerSec->GetNRows();
+    if (s.GetNumberOfClusters() < Int_t(0.4*nrows)) continue;
+    }
+    s.PropagateTo(fParam->GetOuterRadiusUp());
+    s.CookdEdx();
+    CookLabel(&s,0.1); //For comparison only
+    UseClusters(&s,nc);
+    esd->UpdateTrackParams(&s,AliESDtrack::kTPCout);
+    ntrk++;
+  }
+  Info("PropagateBack","Number of back propagated tracks: %d",ntrk);
 
   return 0;
 }
 
 //_____________________________________________________________________________
-Int_t AliTPCtracker::PropagateBack(const TFile *inp, TFile *out) {
+Int_t AliTPCtracker::PropagateBack(TTree */*in*/, TTree */*out*/) {
   //-----------------------------------------------------------------
   // This function propagates tracks back through the TPC.
   //-----------------------------------------------------------------
+  Error("PropagateBack","This method is not converted to NewIO yet\n");
+  return 1;
+  /*
   fSeeds=new TObjArray(15000);
 
   TFile *in=(TFile*)inp;
+  TFile *in2=(TFile*)inp2;
   TDirectory *savedir=gDirectory; 
 
   if (!in->IsOpen()) {
      cerr<<"AliTPCtracker::PropagateBack(): ";
-     cerr<<"file with back propagated ITS tracks is not open !\n";
+     cerr<<"file with TPC (or back propagated ITS) tracks is not open !\n";
      return 1;
   }
 
@@ -686,17 +1218,23 @@ Int_t AliTPCtracker::PropagateBack(const TFile *inp, TFile *out) {
      return 2;
   }
 
+  LoadClusters();
+
   in->cd();
-  TTree *bckTree=(TTree*)in->Get("ITSb");
+  char tName[100];
+  sprintf(tName,"TreeT_ITSb_%d",GetEventNumber());
+  TTree *bckTree=(TTree*)in->Get(tName);
+  if (!bckTree && inp2) bckTree=(TTree*)in2->Get(tName);
   if (!bckTree) {
      cerr<<"AliTPCtracker::PropagateBack() ";
      cerr<<"can't get a tree with back propagated ITS tracks !\n";
-     return 3;
+     //return 3;
   }
   AliTPCtrack *bckTrack=new AliTPCtrack; 
-  bckTree->SetBranchAddress("tracks",&bckTrack);
+  if (bckTree) bckTree->SetBranchAddress("tracks",&bckTrack);
 
-  TTree *tpcTree=(TTree*)in->Get("TPCf");
+  sprintf(tName,"TreeT_TPC_%d",GetEventNumber());
+  TTree *tpcTree=(TTree*)in->Get(tName);
   if (!tpcTree) {
      cerr<<"AliTPCtracker::PropagateBack() ";
      cerr<<"can't get a tree with TPC tracks !\n";
@@ -705,61 +1243,128 @@ Int_t AliTPCtracker::PropagateBack(const TFile *inp, TFile *out) {
   AliTPCtrack *tpcTrack=new AliTPCtrack; 
   tpcTree->SetBranchAddress("tracks",&tpcTrack);
 
-//*** Prepare an array of tracks to be back propagated
+  // [SR, 01.04.2003] - Barrel tracks
+  if (IsStoringBarrel()) SetBarrelTree("back");
+  
+  // Prepare an array of tracks to be back propagated
   Int_t nup=fOuterSec->GetNRows(), nlow=fInnerSec->GetNRows();
   Int_t nrows=nlow+nup;
 
+  //
+  // Match ITS tracks with old TPC tracks
+  // the tracks do not have to be sorted [SR, GSI, 18.02.2003]
+  //
+  // the algorithm is linear and uses LUT for sorting
+  // cost of the algorithm: 2 * number of tracks
+  //
+
   TObjArray tracks(15000);
-  Int_t i=0,j=0;
-  Int_t tpcN=(Int_t)tpcTree->GetEntries();
-  Int_t bckN=(Int_t)bckTree->GetEntries();
-  if (j<bckN) bckTree->GetEvent(j++);
-  for (i=0; i<tpcN; i++) {
-     tpcTree->GetEvent(i);
-     Double_t alpha=tpcTrack->GetAlpha();
-     if (j<bckN &&
-     TMath::Abs(tpcTrack->GetLabel())==TMath::Abs(bckTrack->GetLabel())) {
-        if (!bckTrack->Rotate(alpha-bckTrack->GetAlpha())) continue;
-        fSeeds->AddLast(new AliTPCseed(*bckTrack,bckTrack->GetAlpha()));
-        bckTree->GetEvent(j++);
-     } else {
-        tpcTrack->ResetCovariance();
-        fSeeds->AddLast(new AliTPCseed(*tpcTrack,alpha));
-     }
-     tracks.AddLast(new AliTPCtrack(*tpcTrack));
+  Int_t i=0;
+  Int_t tpcN= (Int_t)tpcTree->GetEntries();
+  Int_t bckN= (bckTree)? (Int_t)bckTree->GetEntries() : 0;
+
+  // look up table   
+  const Int_t nLab = 200000; // limit on number of primaries (arbitrary)
+  Int_t lut[nLab];
+  for(Int_t i=0; i<nLab; i++) lut[i] = -1;
+    
+  if (bckTree) {
+    for(Int_t i=0; i<bckN; i++) {
+      bckTree->GetEvent(i);
+      Int_t lab = TMath::Abs(bckTrack->GetLabel());
+      if (lab < nLab) lut[lab] = i;
+      else {
+       cerr << "AliTPCtracker: The size of the LUT is too small\n";
+      }
+    }
   }
+  
+  for (Int_t i=0; i<tpcN; i++) {
+    tpcTree->GetEvent(i);
+    Double_t alpha=tpcTrack->GetAlpha();
+    
+    if (!bckTree) { 
+
+      // No ITS - use TPC track only
+      
+      tpcTrack->ResetCovariance();
+      AliTPCseed * seed = new AliTPCseed(*tpcTrack, tpcTrack->GetAlpha());
+
+      fSeeds->AddLast(seed);
+      tracks.AddLast(new AliTPCtrack(*tpcTrack));
+    
+    } else {  
+      
+      // with ITS
+      // discard not prolongated tracks (to be discussed)
+
+      Int_t lab = TMath::Abs(tpcTrack->GetLabel());
+      if (lab > nLab || lut[lab] < 0) continue;
+
+      bckTree->GetEvent(lut[lab]);   
+      bckTrack->Rotate(alpha-bckTrack->GetAlpha());
+
+      fSeeds->AddLast(new AliTPCseed(*bckTrack,bckTrack->GetAlpha()));
+      tracks.AddLast(new AliTPCtrack(*tpcTrack));
+    }
+  }
+
+  // end of matching
 
   out->cd();
-  TTree backTree("TPCb","Tree with back propagated TPC tracks");
+
+  // tree name seedsTPCtoTRD as expected by TRD and as 
+  // discussed and decided in Strasbourg (May 2002)
+  // [SR, GSI, 18.02.2003]
+  
+  sprintf(tName,"seedsTPCtoTRD_%d",GetEventNumber());
+  TTree backTree(tName,"Tree with back propagated TPC tracks");
+
   AliTPCtrack *otrack=0;
   backTree.Branch("tracks","AliTPCtrack",&otrack,32000,0);
 
-//*** Back propagation through inner sectors
-  LoadInnerSectors();
+  //
+  Int_t nRefPlane;
+  Int_t found=0;
   Int_t nseed=fSeeds->GetEntriesFast();
+      
+  // loop changed [SR, 01.04.2003]
+
   for (i=0; i<nseed; i++) {
+
+    nRefPlane = 1;
+    if (IsStoringBarrel()) fBarrelArray->Clear();
+
      AliTPCseed *ps=(AliTPCseed*)fSeeds->UncheckedAt(i), &s=*ps;
      const AliTPCtrack *pt=(AliTPCtrack*)tracks.UncheckedAt(i), &t=*pt;
 
+    ps->ResetNWrong();
+    ps->ResetNRotation();
+    
+    if (IsStoringBarrel()) StoreBarrelTrack(ps, 1, 1);
+
+    // Load outer sectors
+    fSectors=fInnerSec;
+    fN=fkNIS;
+       
      Int_t nc=t.GetNumberOfClusters();
-     s.SetLabel(nc-1); //set number of the cluster to start with
+    //s.SetLabel(nc-1); //set number of the cluster to start with
+    s.SetNumber(nc);
 
-     if (FollowBackProlongation(s,t)) {
-       UseClusters(&s);
+    if (FollowBackProlongation(s,t)) UseClusters(&s);    
+    else {
+      fSeeds->RemoveAt(i);
         continue;
      }
-     delete fSeeds->RemoveAt(i);
-  }  
-  UnloadInnerSectors();
 
-//*** Back propagation through outer sectors
-  LoadOuterSectors();
-  Int_t found=0;
-  for (i=0; i<nseed; i++) {
-     AliTPCseed *ps=(AliTPCseed*)fSeeds->UncheckedAt(i), &s=*ps;
-     if (!ps) continue;
-     Int_t nc=s.GetNumberOfClusters();
-     const AliTPCtrack *pt=(AliTPCtrack*)tracks.UncheckedAt(i), &t=*pt;
+    if (IsStoringBarrel()) StoreBarrelTrack(ps, 2, 1);
+    if (IsStoringBarrel()) StoreBarrelTrack(ps, 3, 1);
+
+    // Load outer sectors
+    fSectors=fOuterSec; 
+    fN=fkNOS;
+    
+    nc=s.GetNumberOfClusters();
 
      Double_t alpha=s.GetAlpha() - fSectors->GetAlphaShift();
      if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
@@ -770,23 +1375,43 @@ Int_t AliTPCtracker::PropagateBack(const TFile *inp, TFile *out) {
      alpha-=s.GetAlpha();
 
      if (s.Rotate(alpha)) {
-        if (FollowBackProlongation(s,t)) {
-          if (s.GetNumberOfClusters() >= Int_t(0.4*nrows)) {
-             s.CookdEdx();
-              s.SetLabel(t.GetLabel());
-             UseClusters(&s,nc);
-              otrack=ps;
-              backTree.Fill();
-             cerr<<found++<<'\r';
-              continue;
-          }
-       }
+       if (FollowBackProlongation(s,t)) {
+         if (s.GetNumberOfClusters() >= Int_t(0.4*nrows)) {
+           s.CookdEdx();
+           s.SetLabel(t.GetLabel());
+           UseClusters(&s,nc);
+           
+           // Propagate to outer reference plane for comparison reasons
+           // reason for keeping fParam object [SR, GSI, 18.02.2003] 
+         
+           ps->PropagateTo(fParam->GetOuterRadiusUp()); 
+           otrack=ps;
+           backTree.Fill();
+
+          if (IsStoringBarrel()) StoreBarrelTrack(ps, 4, 1);
+          cerr<<found++<<'\r';
+         }
+       }
      }
+    
+    if (IsStoringBarrel()) fBarrelTree->Fill();
      delete fSeeds->RemoveAt(i);
   }  
-  UnloadOuterSectors();
 
+
+  out->cd();
   backTree.Write();
+
+  // [SR, 01.04.2003]
+  if (IsStoringBarrel()) {
+    fBarrelFile->cd();
+    fBarrelTree->Write();
+    fBarrelFile->Flush();  
+
+    delete fBarrelArray;
+    delete fBarrelTree;
+  }
+
   savedir->cd();
   cerr<<"Number of seeds: "<<nseed<<endl;
   cerr<<"Number of back propagated ITS tracks: "<<bckN<<endl;
@@ -795,7 +1420,13 @@ Int_t AliTPCtracker::PropagateBack(const TFile *inp, TFile *out) {
   delete bckTrack;
   delete tpcTrack;
 
+  if (bckTree) delete bckTree; //Thanks to Mariana Bondila
+  delete tpcTree; //Thanks to Mariana Bondila
+
+  UnloadClusters();  
+
   return 0;
+  */
 }
 
 //_________________________________________________________________________
@@ -807,8 +1438,16 @@ AliCluster *AliTPCtracker::GetCluster(Int_t index) const {
   Int_t row=(index&0x00ff0000)>>16; 
   Int_t ncl=(index&0x0000ffff)>>00;
 
-  AliTPCClustersRow *clrow=((AliTPCtracker *) this)->fClustersArray.GetRow(sec,row);
-  return (AliCluster*)(*clrow)[ncl];      
+  const AliTPCcluster *cl=0;
+
+  if (sec<fkNIS) {
+    cl=fInnerSec[sec][row].GetUnsortedCluster(ncl); 
+  } else {
+    sec-=fkNIS;
+    cl=fOuterSec[sec][row].GetUnsortedCluster(ncl);
+  }
+
+  return (AliCluster*)cl;      
 }
 
 //__________________________________________________________________________
@@ -877,7 +1516,8 @@ void AliTPCtracker::AliTPCSector::Setup(const AliTPCParam *par, Int_t f) {
      fAlpha=par->GetInnerAngle();
      fAlphaShift=par->GetInnerAngleShift();
      fPadPitchWidth=par->GetInnerPadPitchWidth();
-     fPadPitchLength=par->GetInnerPadPitchLength();
+     f1PadPitchLength=par->GetInnerPadPitchLength();
+     f2PadPitchLength=f1PadPitchLength;
 
      fN=par->GetNRowLow();
      fRow=new AliTPCRow[fN];
@@ -886,28 +1526,54 @@ void AliTPCtracker::AliTPCSector::Setup(const AliTPCParam *par, Int_t f) {
      fAlpha=par->GetOuterAngle();
      fAlphaShift=par->GetOuterAngleShift();
      fPadPitchWidth=par->GetOuterPadPitchWidth();
-     fPadPitchLength=par->GetOuterPadPitchLength();
+     f1PadPitchLength=par->GetOuter1PadPitchLength();
+     f2PadPitchLength=par->GetOuter2PadPitchLength();
 
      fN=par->GetNRowUp();
      fRow=new AliTPCRow[fN];
-     for (Int_t i=0; i<fN; i++) fRow[i].SetX(par->GetPadRowRadiiUp(i));
+     for (Int_t i=0; i<fN; i++){ 
+     fRow[i].SetX(par->GetPadRowRadiiUp(i));
+     }
   } 
 }
 
 //_________________________________________________________________________
-void 
-AliTPCtracker::AliTPCRow::InsertCluster(const AliTPCcluster* c, UInt_t index) {
+void AliTPCtracker::
+AliTPCRow::InsertCluster(const AliTPCcluster* c, Int_t sec, Int_t row) {
   //-----------------------------------------------------------------------
   // Insert a cluster into this pad row in accordence with its y-coordinate
   //-----------------------------------------------------------------------
   if (fN==kMaxClusterPerRow) {
-    cerr<<"AliTPCRow::InsertCluster(): Too many clusters !\n"; return;
+     ::Error("InsertCluster","Too many clusters !"); 
+     return;
+  }
+
+  Int_t index=(((sec<<8)+row)<<16)+fN;
+
+  if (fN==0) {
+     fSize=kMaxClusterPerRow/8;
+     fClusterArray=new AliTPCcluster[fSize];
+     fIndex[0]=index;
+     fClusterArray[0]=*c; fClusters[fN++]=fClusterArray; 
+     return;
   }
-  if (fN==0) {fIndex[0]=index; fClusters[fN++]=c; return;}
+
+  if (fN==fSize) {
+     Int_t size=fSize*2;
+     AliTPCcluster *buff=new AliTPCcluster[size];
+     memcpy(buff,fClusterArray,fSize*sizeof(AliTPCcluster));
+     for (Int_t i=0; i<fN; i++) 
+        fClusters[i]=buff+(fClusters[i]-fClusterArray);
+     delete[] fClusterArray;
+     fClusterArray=buff;
+     fSize=size;
+  }
+
   Int_t i=Find(c->GetY());
   memmove(fClusters+i+1 ,fClusters+i,(fN-i)*sizeof(AliTPCcluster*));
   memmove(fIndex   +i+1 ,fIndex   +i,(fN-i)*sizeof(UInt_t));
-  fIndex[i]=index; fClusters[i]=c; fN++;
+  fIndex[i]=index; 
+  fClusters[i]=fClusterArray+fN; fClusterArray[fN++]=*c;
 }
 
 //___________________________________________________________________
@@ -915,6 +1581,7 @@ Int_t AliTPCtracker::AliTPCRow::Find(Double_t y) const {
   //-----------------------------------------------------------------------
   // Return the index of the nearest cluster 
   //-----------------------------------------------------------------------
+  if(fN<=0) return 0;
   if (y <= fClusters[0]->GetY()) return 0;
   if (y > fClusters[fN-1]->GetY()) return fN;
   Int_t b=0, e=fN-1, m=(b+e)/2;
@@ -949,6 +1616,24 @@ void AliTPCtracker::AliTPCseed::CookdEdx(Double_t low, Double_t up) {
   for (i=nl; i<=nu; i++) dedx += fdEdxSample[i];
   dedx /= (nu-nl+1);
   SetdEdx(dedx);
+
+  //Very rough PID
+  Double_t p=TMath::Sqrt((1.+ GetTgl()*GetTgl())/(Get1Pt()*Get1Pt()));
+
+  Double_t log1=TMath::Log(p+0.45), log2=TMath::Log(p+0.12);
+  if (p<0.6) {
+    if (dedx < 34 + 30/(p+0.45)/(p+0.45) + 24*log1) {SetMass(0.13957); return;}
+    if (dedx < 34 + 30/(p+0.12)/(p+0.12) + 24*log2) {SetMass(0.49368); return;}
+    SetMass(0.93827); return;
+  }
+
+  if (p<1.2) {
+    if (dedx < 34 + 30/(p+0.12)/(p+0.12) + 24*log2) {SetMass(0.13957); return;}
+    SetMass(0.93827); return;
+  }
+
+  SetMass(0.13957); return;
+
 }