]> 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 1cf1666922f88350ca673138f7d4a775aba68fe5..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
 
@@ -79,16 +121,20 @@ Splitted from AliTPCtracking
 //   Origin: Iouri Belikov, CERN, Jouri.Belikov@cern.ch 
 //-------------------------------------------------------
 #include <TObjArray.h>
+#include <TError.h>
 #include <TFile.h>
 #include <TTree.h>
-#include <Riostream.h>
+#include <stdlib.h>
+
+#include "AliESD.h"
 
 #include "AliTPCtracker.h"
 #include "AliTPCcluster.h"
 #include "AliTPCParam.h"
 #include "AliClusters.h"
 
-#include <stdlib.h>
+ClassImp(AliTPCtracker)
+
 //_____________________________________________________________________________
 AliTPCtracker::AliTPCtracker(const AliTPCParam *par): 
 AliTracker(), fkNIS(par->GetNInnerSector()/2), fkNOS(par->GetNOuterSector()/2)
@@ -103,7 +149,16 @@ AliTracker(), fkNIS(par->GetNInnerSector()/2), 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);
 
+  fParam = (AliTPCParam*) par;
   fSeeds=0;
+
+  // [SR 17.03.2003]
+  
+  fBarrelFile = 0;
+  fBarrelTree = 0;
+  fBarrelArray = 0;
+  fBarrelTrack = 0;
+  
 }
 
 //_____________________________________________________________________________
@@ -117,6 +172,96 @@ AliTPCtracker::~AliTPCtracker() {
     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);
 }
 
 //_____________________________________________________________________________
@@ -212,31 +357,16 @@ Double_t f3(Double_t x1,Double_t y1,
 }
 
 //_____________________________________________________________________________
-void AliTPCtracker::LoadClusters() {
+Int_t AliTPCtracker::LoadClusters(TTree *cTree) {
   //-----------------------------------------------------------------
   // This function loads TPC clusters.
   //-----------------------------------------------------------------
-  if (!gFile->IsOpen()) {
-    cerr<<"AliTPCtracker::LoadClusters : "<<
-      "file with clusters has not been open !\n";
-    return;
-  }
-
-  Char_t name[100];
-  sprintf(name,"TreeC_TPC_%d",GetEventNumber());
-  TTree *cTree=(TTree*)gFile->Get(name);
-  if (!cTree) {
-    cerr<<"AliTPCtracker::LoadClusters : "<<
-      "can't get the tree with TPC clusters !\n";
-    return;
-  }
-
   TBranch *branch=cTree->GetBranch("Segment");
   if (!branch) {
-    cerr<<"AliTPCtracker::LoadClusters : "<<
-      "can't get the segment branch !\n";
-    return;
+     Error("LoadClusters","Can't get the branch !");
+     return 1;
   }
+
   AliClusters carray, *addr=&carray;
   carray.SetClass("AliTPCcluster");
   carray.SetArray(0);
@@ -252,10 +382,9 @@ void AliTPCtracker::LoadClusters() {
       Int_t nir=fInnerSec->GetNRows(), nor=fOuterSec->GetNRows();
       Int_t id=carray.GetID();
       if ((id<0) || (id>2*(fkNIS*nir + fkNOS*nor))) {
-         cerr<<"AliTPCtracker::LoadClusters : "<<
-              "wrong index !\n";
+        Error("LoadClusters","Wrong index !");
          exit(1);
-      }        
+      }
       Int_t outindex = 2*fkNIS*nir;
       if (id<outindex) {
          Int_t sec = id/nir;
@@ -265,7 +394,7 @@ void AliTPCtracker::LoadClusters() {
          while (ncl--) {
            AliTPCcluster *c=(AliTPCcluster*)carray[ncl];
            padrow.InsertCluster(c,sec,row);
-         }           
+         }
       } else {
          id -= outindex;
          Int_t sec = id/nor;
@@ -277,10 +406,10 @@ void AliTPCtracker::LoadClusters() {
            padrow.InsertCluster(c,sec+fkNIS,row);
          }
       }
-
       carray.GetArray()->Clear();
   }
-  delete cTree;
+
+  return 0;
 }
 
 //_____________________________________________________________________________
@@ -330,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;
     }
 
@@ -370,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
@@ -383,7 +562,8 @@ 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;
@@ -394,10 +574,8 @@ Int_t AliTPCtracker::FollowBackProlongation
   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;
@@ -406,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;
@@ -414,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
@@ -465,7 +643,7 @@ Int_t AliTPCtracker::FollowBackProlongation
 
   }
 
-  seed.SetLabel(nc);
+  seed.SetNumber(nc);
 
   return 1;
 }
@@ -518,8 +696,10 @@ void AliTPCtracker::MakeSeeds(Int_t i1, Int_t i2) {
         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);
@@ -579,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; 
@@ -611,34 +790,85 @@ Int_t AliTPCtracker::ReadSeeds(const TFile *inp) {
 }
 
 //_____________________________________________________________________________
-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();
 
-  if (!out->IsOpen()) {
-     cerr<<"AliTPCtracker::Clusters2Tracks(): output file is not open !\n";
-     return 2;
+  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);
   }
 
-  LoadClusters();
+  Info("Clusters2Tracks","Number of found tracks : %d",
+       event->GetNumberOfTracks());
 
-  out->cd();
+  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;
+  }
 
-  char   tname[100];
-  sprintf(tname,"TreeT_TPC_%d",GetEventNumber());
-  TTree tracktree(tname,"Tree with TPC tracks");
   AliTPCtrack *iotrack=0;
-  tracktree.Branch("tracks","AliTPCtrack",&iotrack,32000,0);
+  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();
@@ -654,6 +884,7 @@ Int_t AliTPCtracker::Clusters2Tracks(const TFile *inp, TFile *out) {
 
   Int_t found=0;
   Int_t nseed=fSeeds->GetEntriesFast();
+
   for (Int_t i=0; i<nseed; i++) {
     //tracking in the outer sectors
     fSectors=fOuterSec; fN=fkNOS;
@@ -675,45 +906,309 @@ Int_t AliTPCtracker::Clusters2Tracks(const TFile *inp, TFile *out) {
     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
-             iotrack=pt;
-             tracktree.Fill();
-             UseClusters(&t);
-             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); 
   }
+  
+  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;
+  }
 
-  tracktree.Write();
+  Info("RefitInward","Number of refitted tracks : %d",nRefited);
 
-  cerr<<"Number of found tracks : "<<found<<endl;
+  return 0;
+}
 
-  savedir->cd();
+//_____________________________________________________________________________
+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++;
+    }
+
+    if (IsStoringBarrel()) fBarrelTree->Fill();
+    delete seed;
+  }
+
+  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();
-  fSeeds->Clear(); delete fSeeds; fSeeds=0;
+
+  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;
   }
 
@@ -726,16 +1221,20 @@ Int_t AliTPCtracker::PropagateBack(const TFile *inp, TFile *out) {
   LoadClusters();
 
   in->cd();
-  TTree *bckTree=(TTree*)in->Get("TreeT_ITSb_0");
+  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("TreeT_TPC_0");
+  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";
@@ -744,60 +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("TreeT_TPCb_0","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
-  fSectors=fInnerSec; fN=fkNIS;
+  //
+  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);
-  }  
 
-//*** Back propagation through outer sectors
-  fSectors=fOuterSec; fN=fkNOS;
-  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();
@@ -808,22 +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);
   }  
 
+
+  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;
@@ -832,12 +1420,13 @@ Int_t AliTPCtracker::PropagateBack(const TFile *inp, TFile *out) {
   delete bckTrack;
   delete tpcTrack;
 
-  delete bckTree; //Thanks to Mariana Bondila
+  if (bckTree) delete bckTree; //Thanks to Mariana Bondila
   delete tpcTree; //Thanks to Mariana Bondila
 
   UnloadClusters();  
 
   return 0;
+  */
 }
 
 //_________________________________________________________________________
@@ -955,12 +1544,15 @@ 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;