* provided "as is" without express or implied warranty. *
**************************************************************************/
-/*
-$Log$
-Revision 1.8 2001/05/08 15:00:15 hristov
-Corrections for tracking in arbitrary magnenetic field. Changes towards a concept of global Alice track. Back propagation of reconstructed tracks (Yu.Belikov)
-
-Revision 1.5 2000/12/20 07:51:59 kowal2
-Changes suggested by Alessandra and Paolo to avoid overlapped
-data fields in encapsulated classes.
-
-Revision 1.4 2000/11/02 07:27:16 kowal2
-code corrections
-
-Revision 1.2 2000/06/30 12:07:50 kowal2
-Updated from the TPC-PreRelease branch
-
-Revision 1.1.2.1 2000/06/25 08:53:55 kowal2
-Splitted from AliTPCtracking
-
-*/
+/* $Id$ */
//-------------------------------------------------------
// Implementation of the TPC tracker
//
// Origin: Iouri Belikov, CERN, Jouri.Belikov@cern.ch
//-------------------------------------------------------
-
#include <TObjArray.h>
+#include <TError.h>
#include <TFile.h>
#include <TTree.h>
-#include <iostream.h>
+
+#include "AliESDEvent.h"
+#include "AliESDtrack.h"
#include "AliTPCtracker.h"
#include "AliTPCcluster.h"
#include "AliTPCParam.h"
-#include "AliTPCClustersRow.h"
+#include "AliClusters.h"
+
+ClassImp(AliTPCtracker)
+
+//_____________________________________________________________________________
+AliTPCtracker::AliTPCtracker():
+ AliTracker(),
+ fkNIS(0),
+ fInnerSec(0),
+ fkNOS(0),
+ fOuterSec(0),
+ fN(0),
+ fSectors(0),
+ fParam(0),
+ fSeeds(0)
+{
+ //
+ // The default TPC tracker constructor
+ //
+}
//_____________________________________________________________________________
AliTPCtracker::AliTPCtracker(const AliTPCParam *par):
-fkNIS(par->GetNInnerSector()/2),
-fkNOS(par->GetNOuterSector()/2)
+ AliTracker(),
+ fkNIS(par->GetNInnerSector()/2),
+ fInnerSec(new AliTPCSector[fkNIS]),
+ fkNOS(par->GetNOuterSector()/2),
+ fOuterSec(new AliTPCSector[fkNOS]),
+ fN(0),
+ fSectors(0),
+ fParam((AliTPCParam*) par),
+ fSeeds(0)
{
//---------------------------------------------------------------------
// The main TPC tracker constructor
//---------------------------------------------------------------------
- fInnerSec=new AliTPCSector[fkNIS];
- fOuterSec=new AliTPCSector[fkNOS];
Int_t i;
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");
-
- fSeeds=0;
}
//_____________________________________________________________________________
//------------------------------------------------------------------
delete[] fInnerSec;
delete[] fOuterSec;
- delete fSeeds;
-}
-
-//_____________________________________________________________________________
-Double_t SigmaY2(Double_t r, Double_t tgl, Double_t pt)
-{
- //
- // Parametrised error of the cluster reconstruction (pad direction)
- //
- // Sigma rphi
- const Float_t kArphi=0.41818e-2;
- const Float_t kBrphi=0.17460e-4;
- const Float_t kCrphi=0.30993e-2;
- const Float_t kDrphi=0.41061e-3;
-
- pt=TMath::Abs(pt)*1000.;
- Double_t x=r/pt;
- tgl=TMath::Abs(tgl);
- Double_t s=kArphi - kBrphi*r*tgl + kCrphi*x*x + kDrphi*x;
- if (s<0.4e-3) s=0.4e-3;
- s*=1.3; //Iouri Belikov
-
- return s;
-}
-
-//_____________________________________________________________________________
-Double_t SigmaZ2(Double_t r, Double_t tgl)
-{
- //
- // Parametrised error of the cluster reconstruction (drift direction)
- //
- // Sigma z
- const Float_t kAz=0.39614e-2;
- const Float_t kBz=0.22443e-4;
- const Float_t kCz=0.51504e-1;
-
-
- tgl=TMath::Abs(tgl);
- Double_t s=kAz - kBz*r*tgl + kCz*tgl*tgl;
- if (s<0.4e-3) s=0.4e-3;
- s*=1.3; //Iouri Belikov
-
- return s;
+ if (fSeeds) {
+ fSeeds->Delete();
+ delete fSeeds;
+ }
}
//_____________________________________________________________________________
-inline Double_t f1(Double_t x1,Double_t y1,
+Double_t f1(Double_t x1,Double_t y1,
Double_t x2,Double_t y2,
Double_t x3,Double_t y3)
{
//_____________________________________________________________________________
-inline Double_t f2(Double_t x1,Double_t y1,
+Double_t f2(Double_t x1,Double_t y1,
Double_t x2,Double_t y2,
Double_t x3,Double_t y3)
{
}
//_____________________________________________________________________________
-inline Double_t f3(Double_t x1,Double_t y1,
+Double_t f3(Double_t x1,Double_t y1,
Double_t x2,Double_t y2,
Double_t z1,Double_t z2)
{
}
//_____________________________________________________________________________
-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))) {
+ Fatal("LoadClusters","Wrong index !");
+ }
+ 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;
}
//_____________________________________________________________________________
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;
UInt_t index=0;
Double_t maxchi2=kMaxCHI2;
const AliTPCRow &krow=fSectors[s][nr];
- Double_t pt=t.GetConvConst()/(100/0.299792458/0.2)/t.Get1Pt();
- Double_t sy2=SigmaY2(t.GetX(),t.GetTgl(),pt);
- Double_t sz2=SigmaZ2(t.GetX(),t.GetTgl());
+ Double_t pt=t.GetSignedPt();
+ Double_t sy2=AliTPCcluster::SigmaY2(t.GetX(),t.GetTgl(),pt);
+ Double_t sz2=AliTPCcluster::SigmaZ2(t.GetX(),t.GetTgl());
Double_t road=4.*sqrt(t.GetSigmaY2() + sy2), y=t.GetY(), z=t.GetZ();
if (road>kMaxROAD) {
if (t.GetNumberOfClusters()>4)
- cerr<<t.GetNumberOfClusters()
- <<"FindProlongation warning: Too broad road !\n";
+ Warning("FindProlongation","Too broad road !");
return 0;
}
}
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;
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-1; 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
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=track.GetNumberOfClusters();
+
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;
+ if (!seed.GetYAt(x,GetBz(),y)) return 0;
+
if (y > ymax) {
s = (s+1) % fN;
if (!seed.Rotate(fSectors->GetAlpha())) return 0;
if (!seed.Rotate(-fSectors->GetAlpha())) return 0;
}
+ if (!seed.PropagateTo(x)) return 0;
+
AliTPCcluster *cl=0;
Int_t index=0;
Double_t maxchi2=kMaxCHI2;
- Double_t pt=seed.GetConvConst()/(100/0.299792458/0.2)/seed.Get1Pt();
- Double_t sy2=SigmaY2(seed.GetX(),seed.GetTgl(),pt);
- Double_t sz2=SigmaZ2(seed.GetX(),seed.GetTgl());
+ Double_t pt=seed.GetSignedPt();
+ Double_t sy2=AliTPCcluster::SigmaY2(seed.GetX(),seed.GetTgl(),pt);
+ Double_t sz2=AliTPCcluster::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
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) {
const AliTPCRow &krow=fSectors[s][i];
if (accepted>27)
if (krow) {
- for (Int_t i=krow.Find(y-road); i<krow; i++) {
- AliTPCcluster *c=(AliTPCcluster*)(krow[i]);
+ for (Int_t icl=krow.Find(y-road); icl<krow; icl++) {
+ AliTPCcluster *c=(AliTPCcluster*)(krow[icl]);
if (c->GetY() > y+road) break;
if (c->IsUsed()) continue;
if ((c->GetZ()-z)*(c->GetZ()-z)>16.*(seed.GetSigmaZ2()+sz2)) continue;
if (chi2 > maxchi2) continue;
maxchi2=chi2;
cl=c;
- index=krow.GetIndex(i);
+ index=krow.GetIndex(icl);
}
}
}
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);
-
return 1;
}
//-----------------------------------------------------------------
// 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);
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;
c[13]=f30*sy1*f40+f32*sy2*f42;
c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
- UInt_t index=kr1.GetIndex(is);
- AliTPCseed *track=new AliTPCseed(index, x, c, x1, ns*alpha+shift);
- Float_t l=fOuterSec->GetPadPitchWidth();
+ Int_t index=kr1.GetIndex(is);
+ AliTPCseed *track=new AliTPCseed(x1, ns*alpha+shift, x, c, index);
+ Float_t l=fSectors->GetPadPitchWidth();
track->SetSampledEdx(kr1[is]->GetQ()/l,0);
Int_t rc=FollowProlongation(*track, i2);
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;
Int_t n=(Int_t)seedTree->GetEntries();
for (Int_t i=0; i<n; i++) {
seedTree->GetEvent(i);
- fSeeds->AddLast(new AliTPCseed(*seed,seed->GetAlpha()));
+ seed->ResetClusters();
+ fSeeds->AddLast(new AliTPCseed(*seed));
}
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(AliESDEvent *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;
- }
- }
-
- if (!out->IsOpen()) {
- cerr<<"AliTPCtracker::Clusters2Tracks(): output file is not open !\n";
- return 2;
- }
-
- out->cd();
- TTree tracktree("TPCf","Tree with TPC tracks");
- AliTPCtrack *iotrack=0;
- tracktree.Branch("tracks","AliTPCtrack",&iotrack,32000,0);
-
- LoadOuterSectors();
//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 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());
+ AliESDtrack iotrack;
+ iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
+
+ event->AddTrack(&iotrack);
+
+ UseClusters(&t);
+ }
+ }
}
- delete fSeeds->RemoveAt(i);
- }
- UnloadInnerSectors();
-
- tracktree.Write();
+ delete fSeeds->RemoveAt(i);
+ }
- cerr<<"Number of found tracks : "<<found<<endl;
+ Info("Clusters2Tracks","Number of found tracks : %d",
+ event->GetNumberOfTracks());
- savedir->cd();
+ fSeeds->Clear(); delete fSeeds; fSeeds=0;
return 0;
}
//_____________________________________________________________________________
-Int_t AliTPCtracker::PropagateBack(const TFile *inp, TFile *out) {
+Int_t AliTPCtracker::RefitInward(AliESDEvent* 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::kTPCrefit) != 0 ) continue;
+ if ( (status & AliESDtrack::kTPCout ) == 0 ) continue;
+
+ if ( (status & AliESDtrack::kTRDout ) != 0 )
+ if ( (status & AliESDtrack::kTRDrefit ) == 0 ) continue;
+
+ AliTPCtrack* tpcTrack = new AliTPCtrack(*track);
+ AliTPCseed* seed=new AliTPCseed(*tpcTrack); seed->ResetClusters();
+
+ if ( (status & AliESDtrack::kTRDrefit) == 0 ) seed->ResetCovariance(10.);
+
+ 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::PropagateBack(AliESDEvent *event) {
//-----------------------------------------------------------------
// This function propagates tracks back through the TPC.
+ // The clusters must be already loaded !
//-----------------------------------------------------------------
- fSeeds=new TObjArray(15000);
+ Int_t nentr=event->GetNumberOfTracks();
+ Info("PropagateBack", "Number of ESD tracks: %d\n", nentr);
- TFile *in=(TFile*)inp;
- TDirectory *savedir=gDirectory;
+ Int_t ntrk=0;
+ for (Int_t i=0; i<nentr; i++) {
+ AliESDtrack *esd=event->GetTrack(i);
+ ULong_t status=esd->GetStatus();
- if (!in->IsOpen()) {
- cerr<<"AliTPCtracker::PropagateBack(): ";
- cerr<<"file with back propagated ITS tracks is not open !\n";
- return 1;
- }
+ if ( (status & AliESDtrack::kTPCin ) == 0 ) continue;
+ if ( (status & AliESDtrack::kTPCout) != 0 ) continue;
+ if ( (status & AliESDtrack::kITSin) != 0 )
+ if ( (status & AliESDtrack::kITSout) == 0 ) continue;
- if (!out->IsOpen()) {
- cerr<<"AliTPCtracker::PropagateBack(): ";
- cerr<<"file for back propagated TPC tracks is not open !\n";
- return 2;
- }
+ const AliTPCtrack t(*esd);
+ AliTPCseed s(t); s.ResetClusters();
- in->cd();
- TTree *bckTree=(TTree*)in->Get("ITSb");
- if (!bckTree) {
- cerr<<"AliTPCtracker::PropagateBack() ";
- cerr<<"can't get a tree with back propagated ITS tracks !\n";
- return 3;
- }
- AliTPCtrack *bckTrack=new AliTPCtrack;
- bckTree->SetBranchAddress("tracks",&bckTrack);
-
- TTree *tpcTree=(TTree*)in->Get("TPCf");
- if (!tpcTree) {
- cerr<<"AliTPCtracker::PropagateBack() ";
- cerr<<"can't get a tree with TPC tracks !\n";
- return 4;
- }
- AliTPCtrack *tpcTrack=new AliTPCtrack;
- tpcTree->SetBranchAddress("tracks",&tpcTrack);
+ if ( (status & AliESDtrack::kITSout) == 0 ) s.ResetCovariance(10.);
-//*** Prepare an array of tracks to be back propagated
- Int_t nup=fOuterSec->GetNRows(), nlow=fInnerSec->GetNRows();
- Int_t nrows=nlow+nup;
+ //inner sectors
+ fSectors=fInnerSec; fN=fkNIS;
- 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));
- }
+ 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();
- out->cd();
- TTree backTree("TPCb","Tree with back propagated TPC tracks");
- AliTPCtrack *otrack=0;
- backTree.Branch("tracks","AliTPCtrack",&otrack,32000,0);
+ if (!s.Rotate(alpha)) continue;
+ if (!FollowBackProlongation(s,t)) continue;
-//*** Back propagation through inner sectors
- LoadInnerSectors();
- Int_t nseed=fSeeds->GetEntriesFast();
- for (i=0; i<nseed; i++) {
- AliTPCseed *ps=(AliTPCseed*)fSeeds->UncheckedAt(i), &s=*ps;
- const AliTPCtrack *pt=(AliTPCtrack*)tracks.UncheckedAt(i), &t=*pt;
+ UseClusters(&s);
- Int_t nc=t.GetNumberOfClusters();
- s.SetLabel(nc-1); //set number of the cluster to start with
+ //outer sectors
+ fSectors=fOuterSec; fN=fkNOS;
- if (FollowBackProlongation(s,t)) {
- UseClusters(&s);
- 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;
-
- 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)) {
- 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;
- }
- }
- }
- delete fSeeds->RemoveAt(i);
- }
- UnloadOuterSectors();
+ Int_t nc=s.GetNumberOfClusters();
- backTree.Write();
- savedir->cd();
- cerr<<"Number of seeds: "<<nseed<<endl;
- cerr<<"Number of back propagated ITS tracks: "<<bckN<<endl;
- cerr<<"Number of back propagated TPC tracks: "<<found<<endl;
+ 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;
- delete bckTrack;
- delete tpcTrack;
+ 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 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;
}
//__________________________________________________________________________
fAlpha=par->GetInnerAngle();
fAlphaShift=par->GetInnerAngleShift();
fPadPitchWidth=par->GetInnerPadPitchWidth();
- fPadPitchLength=par->GetInnerPadPitchLength();
+ f1PadPitchLength=par->GetInnerPadPitchLength();
+ f2PadPitchLength=f1PadPitchLength;
fN=par->GetNRowLow();
fRow=new AliTPCRow[fN];
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==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;
}
- if (fN==0) {fIndex[0]=index; fClusters[fN++]=c; return;}
+
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;
}
//___________________________________________________________________
//-----------------------------------------------------------------------
// 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;
for (i=nl; i<=nu; i++) dedx += fdEdxSample[i];
dedx /= (nu-nl+1);
SetdEdx(dedx);
+
+ return;
}