/* $Id$ */
-
-#include <TObjArray.h>
+#include "Riostream.h"
+#include <TClonesArray.h>
#include <TFile.h>
+#include <TObjArray.h>
#include <TTree.h>
-#include <TClonesArray.h>
-
-#include "Riostream.h"
-#include "AliTPCclusterMI.h"
#include "AliComplexCluster.h"
-#include "AliTPCParam.h"
-#include "AliTPCClustersRow.h"
-#include "AliTPCpolyTrack.h"
-#include "TStopwatch.h"
#include "AliESD.h"
+#include "AliESDkink.h"
#include "AliHelix.h"
-//
#include "AliRunLoader.h"
-//
-#include "AliTPCreco.h"
+#include "AliTPCClustersRow.h"
+#include "AliTPCParam.h"
+#include "AliTPCReconstructor.h"
+#include "AliTPCclusterMI.h"
+#include "AliTPCpolyTrack.h"
+#include "AliTPCreco.h"
+#include "AliTPCseed.h"
#include "AliTPCtrackerMI.h"
+#include "TStopwatch.h"
+#include "AliTPCReconstructor.h"
+#include "AliESDkink.h"
+#include "AliPID.h"
+#include "TTreeStream.h"
+#include "AliAlignObj.h"
+#include "AliTrackPointArray.h"
+//
-
-ClassImp(AliTPCseed)
ClassImp(AliTPCtrackerMI)
};
Double_t AliTPCFastMath::fgFastAsin[20000];
-AliTPCFastMath gAliTPCFastMath;
+AliTPCFastMath gAliTPCFastMath; // needed to fill the LUT
AliTPCFastMath::AliTPCFastMath(){
//
fNewIO =0;
fDebug =0;
fEvent =0;
+ fDebugStreamer = new TTreeSRedirector("TPCdebug.root");
+}
+//________________________________________________________________________
+AliTPCtrackerMI::AliTPCtrackerMI(const AliTPCtrackerMI &t):
+ AliTracker(t),
+ fkNIS(t.fkNIS),
+ fkNOS(t.fkNOS)
+{
+ //------------------------------------
+ // dummy copy constructor
+ //------------------------------------------------------------------
+}
+AliTPCtrackerMI & AliTPCtrackerMI::operator=(const AliTPCtrackerMI& /*r*/){
+ //------------------------------
+ // dummy
+ //--------------------------------------------------------------
+ return *this;
}
-
//_____________________________________________________________________________
AliTPCtrackerMI::~AliTPCtrackerMI() {
//------------------------------------------------------------------
fSeeds->Delete();
delete fSeeds;
}
+ if (fDebugStreamer) delete fDebugStreamer;
}
void AliTPCtrackerMI::SetIO()
{
//
fNewIO = kTRUE;
- fInput = AliRunLoader::GetTreeR("TPC", kFALSE,AliConfig::fgkDefaultEventFolderName);
+ fInput = AliRunLoader::GetTreeR("TPC", kFALSE,AliConfig::GetDefaultEventFolderName());
- fOutput = AliRunLoader::GetTreeT("TPC", kTRUE,AliConfig::fgkDefaultEventFolderName);
+ fOutput = AliRunLoader::GetTreeT("TPC", kTRUE,AliConfig::GetDefaultEventFolderName());
if (fOutput){
AliTPCtrack *iotrack= new AliTPCtrack;
fOutput->Branch("tracks","AliTPCtrack",&iotrack,32000,100);
// write tracks to the event
// store index of the track
Int_t nseed=arr->GetEntriesFast();
+ //FindKinks(arr,fEvent);
for (Int_t i=0; i<nseed; i++) {
AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
if (!pt) continue;
- pt->PropagateTo(fParam->GetInnerRadiusLow());
- if (pt->GetNumberOfClusters()>70) {
+ pt->UpdatePoints();
+ // pt->PropagateTo(fParam->GetInnerRadiusLow());
+ if (pt->GetKinkIndex(0)<=0){ //don't propagate daughter tracks
+ pt->PropagateTo(fParam->GetInnerRadiusLow());
+ }
+
+ if (( pt->GetPoints()[2]- pt->GetPoints()[0])>5 && pt->GetPoints()[3]>0.8){
+ AliESDtrack iotrack;
+ iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
+ iotrack.SetTPCPoints(pt->GetPoints());
+ iotrack.SetKinkIndexes(pt->GetKinkIndexes());
+ iotrack.SetV0Indexes(pt->GetV0Indexes());
+ // iotrack.SetTPCpid(pt->fTPCr);
+ //iotrack.SetTPCindex(i);
+ fEvent->AddTrack(&iotrack);
+ continue;
+ }
+
+ if ( (pt->GetNumberOfClusters()>70)&& (Float_t(pt->GetNumberOfClusters())/Float_t(pt->fNFoundable))>0.55) {
+ AliESDtrack iotrack;
+ iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
+ iotrack.SetTPCPoints(pt->GetPoints());
+ //iotrack.SetTPCindex(i);
+ iotrack.SetKinkIndexes(pt->GetKinkIndexes());
+ iotrack.SetV0Indexes(pt->GetV0Indexes());
+ // iotrack.SetTPCpid(pt->fTPCr);
+ fEvent->AddTrack(&iotrack);
+ continue;
+ }
+ //
+ // short tracks - maybe decays
+
+ if ( (pt->GetNumberOfClusters()>30) && (Float_t(pt->GetNumberOfClusters())/Float_t(pt->fNFoundable))>0.70) {
+ Int_t found,foundable,shared;
+ pt->GetClusterStatistic(0,60,found, foundable,shared,kFALSE);
+ if ( (found>20) && (pt->fNShared/float(pt->GetNumberOfClusters())<0.2)){
+ AliESDtrack iotrack;
+ iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
+ //iotrack.SetTPCindex(i);
+ iotrack.SetTPCPoints(pt->GetPoints());
+ iotrack.SetKinkIndexes(pt->GetKinkIndexes());
+ iotrack.SetV0Indexes(pt->GetV0Indexes());
+ //iotrack.SetTPCpid(pt->fTPCr);
+ fEvent->AddTrack(&iotrack);
+ continue;
+ }
+ }
+
+ if ( (pt->GetNumberOfClusters()>20) && (Float_t(pt->GetNumberOfClusters())/Float_t(pt->fNFoundable))>0.8) {
+ Int_t found,foundable,shared;
+ pt->GetClusterStatistic(0,60,found, foundable,shared,kFALSE);
+ if (found<20) continue;
+ if (pt->fNShared/float(pt->GetNumberOfClusters())>0.2) continue;
+ //
+ AliESDtrack iotrack;
+ iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
+ iotrack.SetTPCPoints(pt->GetPoints());
+ iotrack.SetKinkIndexes(pt->GetKinkIndexes());
+ iotrack.SetV0Indexes(pt->GetV0Indexes());
+ //iotrack.SetTPCpid(pt->fTPCr);
+ //iotrack.SetTPCindex(i);
+ fEvent->AddTrack(&iotrack);
+ continue;
+ }
+ // short tracks - secondaties
+ //
+ if ( (pt->GetNumberOfClusters()>30) ) {
+ Int_t found,foundable,shared;
+ pt->GetClusterStatistic(128,158,found, foundable,shared,kFALSE);
+ if ( (found>20) && (pt->fNShared/float(pt->GetNumberOfClusters())<0.2) &&float(found)/float(foundable)>0.8){
+ AliESDtrack iotrack;
+ iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
+ iotrack.SetTPCPoints(pt->GetPoints());
+ iotrack.SetKinkIndexes(pt->GetKinkIndexes());
+ iotrack.SetV0Indexes(pt->GetV0Indexes());
+ //iotrack.SetTPCpid(pt->fTPCr);
+ //iotrack.SetTPCindex(i);
+ fEvent->AddTrack(&iotrack);
+ continue;
+ }
+ }
+
+ if ( (pt->GetNumberOfClusters()>15)) {
+ Int_t found,foundable,shared;
+ pt->GetClusterStatistic(138,158,found, foundable,shared,kFALSE);
+ if (found<15) continue;
+ if (pt->fNShared/float(pt->GetNumberOfClusters())>0.2) continue;
+ if (float(found)/float(foundable)<0.8) continue;
+ //
AliESDtrack iotrack;
iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
+ iotrack.SetTPCPoints(pt->GetPoints());
+ iotrack.SetKinkIndexes(pt->GetKinkIndexes());
+ iotrack.SetV0Indexes(pt->GetV0Indexes());
+ // iotrack.SetTPCpid(pt->fTPCr);
//iotrack.SetTPCindex(i);
fEvent->AddTrack(&iotrack);
- }
+ continue;
+ }
}
}
+ printf("Number of filled ESDs-\t%d\n",fEvent->GetNumberOfTracks());
}
void AliTPCtrackerMI::WriteTracks(TTree * tree)
if (fOutput){
AliTPCtrack *iotrack= 0;
Int_t nseed=fSeeds->GetEntriesFast();
- for (Int_t i=0; i<nseed; i++) {
- iotrack= (AliTPCtrack*)fSeeds->UncheckedAt(i);
- if (iotrack) break;
- }
-
+ //for (Int_t i=0; i<nseed; i++) {
+ // iotrack= (AliTPCtrack*)fSeeds->UncheckedAt(i);
+ // if (iotrack) break;
+ //}
//TBranch * br = fOutput->Branch("tracks","AliTPCtrack",&iotrack,32000,100);
TBranch * br = fOutput->GetBranch("tracks");
br->SetAddress(&iotrack);
for (Int_t i=0; i<nseed; i++) {
AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i);
if (!pt) continue;
- iotrack = pt;
+ AliTPCtrack * track = new AliTPCtrack(*pt);
+ iotrack = track;
pt->fLab2 =i;
// br->SetAddress(&iotrack);
fOutput->Fill();
+ delete track;
iotrack =0;
}
- fOutput->GetDirectory()->cd();
- fOutput->Write();
+ //fOutput->GetDirectory()->cd();
+ //fOutput->Write();
}
// delete iotrack;
//
-void AliTPCseed::Reset(Bool_t all)
-{
- //
- //
- SetNumberOfClusters(0);
- fNFoundable = 0;
- SetChi2(0);
- ResetCovariance();
- /*
- if (fTrackPoints){
- for (Int_t i=0;i<8;i++){
- delete [] fTrackPoints[i];
- }
- delete fTrackPoints;
- fTrackPoints =0;
- }
- */
-
- if (all){
- for (Int_t i=0;i<200;i++) SetClusterIndex2(i,-3);
- for (Int_t i=0;i<160;i++) fClusterPointer[i]=0;
- }
-
-}
-
-
-void AliTPCseed::Modify(Double_t factor)
-{
-
- //------------------------------------------------------------------
- //This function makes a track forget its history :)
- //------------------------------------------------------------------
- if (factor<=0) {
- ResetCovariance();
- return;
- }
- fC00*=factor;
- fC10*=factor; fC11*=factor;
- fC20*=factor; fC21*=factor; fC22*=factor;
- fC30*=factor; fC31*=factor; fC32*=factor; fC33*=factor;
- fC40*=factor; fC41*=factor; fC42*=factor; fC43*=factor; fC44*=factor;
- SetNumberOfClusters(0);
- fNFoundable =0;
- SetChi2(0);
- fRemoval = 0;
- fCurrentSigmaY2 = 0.000005;
- fCurrentSigmaZ2 = 0.000005;
- fNoCluster = 0;
- //fFirstPoint = 160;
- //fLastPoint = 0;
-}
-
-
-
-
-Int_t AliTPCseed::GetProlongation(Double_t xk, Double_t &y, Double_t & z) const
-{
- //-----------------------------------------------------------------
- // This function find proloncation of a track to a reference plane x=xk.
- // doesn't change internal state of the track
- //-----------------------------------------------------------------
-
- Double_t x1=fX, x2=x1+(xk-x1), dx=x2-x1;
-
- if (TMath::Abs(fP4*xk - fP2) >= 0.999) {
- return 0;
- }
-
- // Double_t y1=fP0, z1=fP1;
- Double_t c1=fP4*x1 - fP2, r1=sqrt(1.- c1*c1);
- Double_t c2=fP4*x2 - fP2, r2=sqrt(1.- c2*c2);
-
- y = fP0;
- z = fP1;
- //y += dx*(c1+c2)/(r1+r2);
- //z += dx*(c1+c2)/(c1*r2 + c2*r1)*fP3;
-
- Double_t dy = dx*(c1+c2)/(r1+r2);
- Double_t dz = 0;
- //
- Double_t delta = fP4*dx*(c1+c2)/(c1*r2 + c2*r1);
- /*
- if (TMath::Abs(delta)>0.0001){
- dz = fP3*TMath::ASin(delta)/fP4;
- }else{
- dz = dx*fP3*(c1+c2)/(c1*r2 + c2*r1);
- }
- */
- dz = fP3*AliTPCFastMath::FastAsin(delta)/fP4;
- //
- y+=dy;
- z+=dz;
-
-
- return 1;
-}
-
-
-//_____________________________________________________________________________
-Double_t AliTPCseed::GetPredictedChi2(const AliTPCclusterMI *c) const
-{
- //-----------------------------------------------------------------
- // This function calculates a predicted chi2 increment.
- //-----------------------------------------------------------------
- //Double_t r00=c->GetSigmaY2(), r01=0., r11=c->GetSigmaZ2();
- Double_t r00=fErrorY2, r01=0., r11=fErrorZ2;
- r00+=fC00; r01+=fC10; r11+=fC11;
-
- Double_t det=r00*r11 - r01*r01;
- if (TMath::Abs(det) < 1.e-10) {
- Int_t n=GetNumberOfClusters();
- if (n>4) cerr<<n<<" AliKalmanTrack warning: Singular matrix !\n";
- return 1e10;
- }
- Double_t tmp=r00; r00=r11; r11=tmp; r01=-r01;
-
- Double_t dy=c->GetY() - fP0, dz=c->GetZ() - fP1;
-
- return (dy*r00*dy + 2*r01*dy*dz + dz*r11*dz)/det;
-}
-
-
-//_________________________________________________________________________________________
-
-
-Int_t AliTPCseed::Compare(const TObject *o) const {
- //-----------------------------------------------------------------
- // This function compares tracks according to the sector - for given sector according z
- //-----------------------------------------------------------------
- AliTPCseed *t=(AliTPCseed*)o;
-
- if (fSort == 0){
- if (t->fRelativeSector>fRelativeSector) return -1;
- if (t->fRelativeSector<fRelativeSector) return 1;
- Double_t z2 = t->GetZ();
- Double_t z1 = GetZ();
- if (z2>z1) return 1;
- if (z2<z1) return -1;
- return 0;
- }
- else {
- Float_t f2 =1;
- f2 = 1-20*TMath::Sqrt(t->fC44)/(TMath::Abs(t->GetC())+0.0066);
- if (t->fBConstrain) f2=1.2;
-
- Float_t f1 =1;
- f1 = 1-20*TMath::Sqrt(fC44)/(TMath::Abs(GetC())+0.0066);
-
- if (fBConstrain) f1=1.2;
-
- if (t->GetNumberOfClusters()*f2 <GetNumberOfClusters()*f1) return -1;
- else return +1;
- }
-}
void AliTPCtrackerMI::RotateToLocal(AliTPCseed *seed)
{
-
-//_____________________________________________________________________________
-Int_t AliTPCseed::Update(const AliTPCclusterMI *c, Double_t chisq, UInt_t /*index*/) {
- //-----------------------------------------------------------------
- // This function associates a cluster with this track.
- //-----------------------------------------------------------------
- Double_t r00=fErrorY2, r01=0., r11=fErrorZ2;
-
- r00+=fC00; r01+=fC10; r11+=fC11;
- Double_t det=r00*r11 - r01*r01;
- Double_t tmp=r00; r00=r11/det; r11=tmp/det; r01=-r01/det;
-
- Double_t k00=fC00*r00+fC10*r01, k01=fC00*r01+fC10*r11;
- Double_t k10=fC10*r00+fC11*r01, k11=fC10*r01+fC11*r11;
- Double_t k20=fC20*r00+fC21*r01, k21=fC20*r01+fC21*r11;
- Double_t k30=fC30*r00+fC31*r01, k31=fC30*r01+fC31*r11;
- Double_t k40=fC40*r00+fC41*r01, k41=fC40*r01+fC41*r11;
-
- Double_t dy=c->GetY() - fP0, dz=c->GetZ() - fP1;
- Double_t cur=fP4 + k40*dy + k41*dz, eta=fP2 + k20*dy + k21*dz;
- if (TMath::Abs(cur*fX-eta) >= 0.9) {
- return 0;
- }
-
- fP0 += k00*dy + k01*dz;
- fP1 += k10*dy + k11*dz;
- fP2 = eta;
- fP3 += k30*dy + k31*dz;
- fP4 = cur;
-
- Double_t c01=fC10, c02=fC20, c03=fC30, c04=fC40;
- Double_t c12=fC21, c13=fC31, c14=fC41;
-
- fC00-=k00*fC00+k01*fC10; fC10-=k00*c01+k01*fC11;
- fC20-=k00*c02+k01*c12; fC30-=k00*c03+k01*c13;
- fC40-=k00*c04+k01*c14;
-
- fC11-=k10*c01+k11*fC11;
- fC21-=k10*c02+k11*c12; fC31-=k10*c03+k11*c13;
- fC41-=k10*c04+k11*c14;
-
- fC22-=k20*c02+k21*c12; fC32-=k20*c03+k21*c13;
- fC42-=k20*c04+k21*c14;
-
- fC33-=k30*c03+k31*c13;
- fC43-=k40*c03+k41*c13;
-
- fC44-=k40*c04+k41*c14;
-
- Int_t n=GetNumberOfClusters();
- // fIndex[n]=index;
- SetNumberOfClusters(n+1);
- SetChi2(GetChi2()+chisq);
-
- return 1;
-}
-
-
-
//_____________________________________________________________________________
Double_t AliTPCtrackerMI::F1old(Double_t x1,Double_t y1,
Double_t x2,Double_t y2,
for (Int_t sec = 0;sec<fkNOS;sec++)
for (Int_t row = 0;row<nrows;row++){
AliTPCRow* tpcrow = &(fOuterSec[sec%fkNOS][row]);
- if (tpcrow){
- if (tpcrow->fClusters1) delete []tpcrow->fClusters1;
- if (tpcrow->fClusters2) delete []tpcrow->fClusters2;
- }
+ // if (tpcrow){
+ // if (tpcrow->fClusters1) delete []tpcrow->fClusters1;
+ // if (tpcrow->fClusters2) delete []tpcrow->fClusters2;
+ //}
+ tpcrow->ResetClusters();
}
//
nrows = fInnerSec->GetNRows();
for (Int_t sec = 0;sec<fkNIS;sec++)
for (Int_t row = 0;row<nrows;row++){
AliTPCRow* tpcrow = &(fInnerSec[sec%fkNIS][row]);
- if (tpcrow){
- if (tpcrow->fClusters1) delete []tpcrow->fClusters1;
- if (tpcrow->fClusters2) delete []tpcrow->fClusters2;
- }
+ //if (tpcrow){
+ // if (tpcrow->fClusters1) delete []tpcrow->fClusters1;
+ //if (tpcrow->fClusters2) delete []tpcrow->fClusters2;
+ //}
+ tpcrow->ResetClusters();
}
return ;
const AliTPCRow * tpcrow=0;
AliTPCclusterMI * clrow =0;
+
if (sec<fkNIS*2){
tpcrow = &(fInnerSec[sec%fkNIS][row]);
- if (sec<fkNIS)
+ if (tpcrow==0) return 0;
+
+ if (sec<fkNIS) {
+ if (tpcrow->fN1<=ncl) return 0;
clrow = tpcrow->fClusters1;
- else
+ }
+ else {
+ if (tpcrow->fN2<=ncl) return 0;
clrow = tpcrow->fClusters2;
+ }
}
- else{
+ else {
tpcrow = &(fOuterSec[(sec-fkNIS*2)%fkNOS][row]);
- if (sec-2*fkNIS<fkNOS)
+ if (tpcrow==0) return 0;
+
+ if (sec-2*fkNIS<fkNOS) {
+ if (tpcrow->fN1<=ncl) return 0;
clrow = tpcrow->fClusters1;
- else
+ }
+ else {
+ if (tpcrow->fN2<=ncl) return 0;
clrow = tpcrow->fClusters2;
+ }
}
- if (tpcrow==0) return 0;
- if (tpcrow->GetN()<=ncl) return 0;
- // return (AliTPCclusterMI*)(*tpcrow)[ncl];
+
return &(clrow[ncl]);
}
//-----------------------------------------------------------------
//
Double_t x= GetXrow(nr), ymax=GetMaxY(nr);
-
- // if (t.GetRadius()>x+10 ) return 0;
- // t.PropagateTo(x+0.02);
- //t.PropagateTo(x+0.01);
- if (!t.PropagateTo(x)) {
- t.fRemoval = 10;
- return 0;
+ AliTPCclusterMI *cl=0;
+ Int_t tpcindex= t.GetClusterIndex2(nr);
+ //
+ // update current shape info every 5 pad-row
+ // if ( (nr%5==0) || t.GetNumberOfClusters()<2 || (t.fCurrentSigmaY2<0.0001) ){
+ GetShape(&t,nr);
+ //}
+ //
+ if (fIteration>0 && tpcindex>=-1){ //if we have already clusters
+ //
+ if (tpcindex==-1) return 0; //track in dead zone
+ if (tpcindex>0){ //
+ cl = t.fClusterPointer[nr];
+ if ( (cl==0) ) cl = GetClusterMI(tpcindex);
+ t.fCurrentClusterIndex1 = tpcindex;
+ }
+ if (cl){
+ Int_t relativesector = ((tpcindex&0xff000000)>>24)%18; // if previously accepted cluster in different sector
+ Float_t angle = relativesector*fSectors->GetAlpha()+fSectors->GetAlphaShift();
+ //
+ if (angle<-TMath::Pi()) angle += 2*TMath::Pi();
+ if (angle>=TMath::Pi()) angle -= 2*TMath::Pi();
+
+ if (TMath::Abs(angle-t.GetAlpha())>0.001){
+ Double_t rotation = angle-t.GetAlpha();
+ t.fRelativeSector= relativesector;
+ t.Rotate(rotation);
+ }
+ t.PropagateTo(x);
+ //
+ t.fCurrentCluster = cl;
+ t.fRow = nr;
+ Int_t accept = AcceptCluster(&t,t.fCurrentCluster,1.);
+ if ((tpcindex&0x8000)==0) accept =0;
+ if (accept<3) {
+ //if founded cluster is acceptible
+ if (cl->IsUsed(11)) { // id cluster is shared inrease uncertainty
+ t.fErrorY2 += 0.03;
+ t.fErrorZ2 += 0.03;
+ t.fErrorY2 *= 3;
+ t.fErrorZ2 *= 3;
+ }
+ t.fNFoundable++;
+ UpdateTrack(&t,accept);
+ return 1;
+ }
+ }
}
+ if (fIteration>1) return 0; // not look for new cluster during refitting
//
- Double_t y=t.GetY(), z=t.GetZ();
+ UInt_t index=0;
+ if (TMath::Abs(t.GetSnp())>0.95 || TMath::Abs(x*t.GetC()-t.GetEta())>0.95) return 0;
+ Double_t y=t.GetYat(x);
if (TMath::Abs(y)>ymax){
if (y > ymax) {
t.fRelativeSector= (t.fRelativeSector+1) % fN;
if (!t.Rotate(-fSectors->GetAlpha()))
return 0;
}
- if (!t.PropagateTo(x)) {
- return 0;
- }
- y=t.GetY();
+ //return 1;
}
//
- // update current shape info every 3 pad-row
- if ( (nr%5==0) || t.GetNumberOfClusters()<2 || (t.fCurrentSigmaY2<0.0001) ){
- //t.fCurrentSigmaY = GetSigmaY(&t);
- //t.fCurrentSigmaZ = GetSigmaZ(&t);
- GetShape(&t,nr);
- }
- //
- AliTPCclusterMI *cl=0;
- UInt_t index=0;
-
-
- //Int_t nr2 = nr;
- if (t.GetClusterIndex2(nr)>0){
- //
- //cl = GetClusterMI(t.GetClusterIndex2(nr));
- index = t.GetClusterIndex2(nr);
- cl = t.fClusterPointer[nr];
- if ( (cl==0) && (index>0)) cl = GetClusterMI(index);
- t.fCurrentClusterIndex1 = index;
+ if (!t.PropagateTo(x)) {
+ if (fIteration==0) t.fRemoval = 10;
+ return 0;
}
-
+ y=t.GetY();
+ Double_t z=t.GetZ();
+ //
const AliTPCRow &krow=GetRow(t.fRelativeSector,nr);
if ( (t.GetSigmaY2()<0) || t.GetSigmaZ2()<0) return 0;
Double_t roady =1.;
}
else
{
- if (TMath::Abs(z)<(1.05*x+10)) t.fNFoundable++;
+ if (TMath::Abs(z)<(AliTPCReconstructor::GetCtgRange()*x+10) && TMath::Abs(z)<fParam->GetZLength() ) t.fNFoundable++;
else
return 0;
}
//calculate
- if (cl){
- t.fCurrentCluster = cl;
- t.fRow = nr;
- Int_t accept = AcceptCluster(&t,t.fCurrentCluster,1.);
- if (fIteration>0) accept =0;
- if (accept<3) {
- //if founded cluster is acceptible
- UpdateTrack(&t,accept);
- return 1;
- }
- }
-
if (krow) {
// cl = krow.FindNearest2(y+10.,z,roady,roadz,index);
cl = krow.FindNearest2(y,z,roady,roadz,index);
if (cl) t.fCurrentClusterIndex1 = krow.GetIndex(index);
}
- // t.fNoCluster++;
-
if (cl) {
t.fCurrentCluster = cl;
t.fRow = nr;
+ if (fIteration==2&&cl->IsUsed(10)) return 0;
Int_t accept = AcceptCluster(&t,t.fCurrentCluster,1.);
+ if (fIteration==2&&cl->IsUsed(11)) {
+ t.fErrorY2 += 0.03;
+ t.fErrorZ2 += 0.03;
+ t.fErrorY2 *= 3;
+ t.fErrorZ2 *= 3;
+ }
/*
if (t.fCurrentCluster->IsUsed(10)){
//
if (accept<3) UpdateTrack(&t,accept);
} else {
- if (t.fNFoundable*0.5 > t.GetNumberOfClusters()) t.fRemoval=10;
+ if ( fIteration==0 && t.fNFoundable*0.5 > t.GetNumberOfClusters()) t.fRemoval=10;
}
return 1;
//
//
if (TMath::Abs(y)>ymax){
- return 0;
if (y > ymax) {
t.fRelativeSector= (t.fRelativeSector+1) % fN;
}
else
{
- if (TMath::Abs(z)>(1.05*x+10)) t.SetClusterIndex2(row,-1);
+ if (TMath::Abs(z)>(AliTPCReconstructor::GetCtgRange()*x+10)) t.SetClusterIndex2(row,-1);
}
//calculate
+//_________________________________________________________________________
+Bool_t AliTPCtrackerMI::GetTrackPoint(Int_t index, AliTrackPoint &p ) const
+{
+ // Get track space point by index
+ // return false in case the cluster doesn't exist
+ AliTPCclusterMI *cl = GetClusterMI(index);
+ if (!cl) return kFALSE;
+ Int_t sector = (index&0xff000000)>>24;
+ Int_t row = (index&0x00ff0000)>>16;
+ Float_t xyz[3];
+ xyz[0] = fParam->GetPadRowRadii(sector,row);
+ xyz[1] = cl->GetY();
+ xyz[2] = cl->GetZ();
+ Float_t sin,cos;
+ fParam->AdjustCosSin(sector,cos,sin);
+ Float_t x = cos*xyz[0]-sin*xyz[1];
+ Float_t y = cos*xyz[1]+sin*xyz[0];
+ Float_t cov[6];
+ Float_t sigmaY2 = 0.027*cl->GetSigmaY2();
+ if (sector < fParam->GetNInnerSector()) sigmaY2 *= 2.07;
+ Float_t sigmaZ2 = 0.066*cl->GetSigmaZ2();
+ if (sector < fParam->GetNInnerSector()) sigmaZ2 *= 1.77;
+ cov[0] = sin*sin*sigmaY2;
+ cov[1] = -sin*cos*sigmaY2;
+ cov[2] = 0.;
+ cov[3] = cos*cos*sigmaY2;
+ cov[4] = 0.;
+ cov[5] = sigmaZ2;
+ p.SetXYZ(x,y,xyz[2],cov);
+ AliAlignObj::ELayerID iLayer;
+ Int_t idet;
+ if (sector < fParam->GetNInnerSector()) {
+ iLayer = AliAlignObj::kTPC1;
+ idet = sector;
+ }
+ else {
+ iLayer = AliAlignObj::kTPC2;
+ idet = sector - fParam->GetNInnerSector();
+ }
+ UShort_t volid = AliAlignObj::LayerToVolUID(iLayer,idet);
+ p.SetVolumeID(volid);
+ return kTRUE;
+}
+
+
+
Int_t AliTPCtrackerMI::UpdateClusters(AliTPCseed& t, Int_t nr) {
//-----------------------------------------------------------------
// This function tries to find a track prolongation to next pad row
if (!t.Rotate(-fSectors->GetAlpha()))
return 0;
}
- if (!t.PropagateTo(x)){
- return 0;
- }
- y = t.GetY();
+ // if (!t.PropagateTo(x)){
+ // return 0;
+ //}
+ return 1;
+ //y = t.GetY();
}
//
}
else
{
- if (TMath::Abs(t.GetZ())<(1.05*t.GetX()+10)) t.fNFoundable++;
+ if (TMath::Abs(t.GetZ())<(AliTPCReconstructor::GetCtgRange()*t.GetX()+10)) t.fNFoundable++;
else
return 0;
}
}
AliTPCclusterMI *cl=0;
- UInt_t index=0;
+ Int_t index=0;
//
Double_t roady = 1.;
Double_t roadz = 1.;
}
}
+ // if (index<0) return 0;
+ UInt_t uindex = TMath::Abs(index);
+
if (krow) {
- //cl = krow.FindNearest2(y+10,z,roady,roadz,index);
- cl = krow.FindNearest2(y,z,roady,roadz,index);
+ //cl = krow.FindNearest2(y+10,z,roady,roadz,uindex);
+ cl = krow.FindNearest2(y,z,roady,roadz,uindex);
}
- if (cl) t.fCurrentClusterIndex1 = krow.GetIndex(index);
+ if (cl) t.fCurrentClusterIndex1 = krow.GetIndex(uindex);
t.fCurrentCluster = cl;
return 1;
t.fRelativeSector = Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN;
Int_t first = GetRowNumber(xt)-1;
- for (Int_t nr= first; nr>=rf; nr-=step) {
+ for (Int_t nr= first; nr>=rf; nr-=step) {
+ // update kink info
+ if (t.GetKinkIndexes()[0]>0){
+ for (Int_t i=0;i<3;i++){
+ Int_t index = t.GetKinkIndexes()[i];
+ if (index==0) break;
+ if (index<0) continue;
+ //
+ AliESDkink * kink = fEvent->GetKink(index-1);
+ if (!kink){
+ printf("PROBLEM\n");
+ }
+ else{
+ Int_t kinkrow = kink->GetTPCRow0()+2+Int_t(0.5/(0.05+kink->GetAngle(2)));
+ if (kinkrow==nr){
+ AliExternalTrackParam paramd(t);
+ kink->SetDaughter(paramd);
+ kink->SetStatus(2,5);
+ kink->Update();
+ }
+ }
+ }
+ }
+
+ if (nr==80) t.UpdateReference();
+ if (nr<fInnerSec->GetNRows())
+ fSectors = fInnerSec;
+ else
+ fSectors = fOuterSec;
if (FollowToNext(t,nr)==0)
- if (!t.IsActive()) return 0;
+ if (!t.IsActive())
+ return 0;
}
return 1;
//-----------------------------------------------------------------
// This function tries to find a track prolongation.
//-----------------------------------------------------------------
- // Double_t xt=t.GetX();
//
+ Double_t xt=t.GetX();
Double_t alpha=t.GetAlpha() - fSectors->GetAlphaShift();
if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
if (alpha < 0. ) alpha += 2.*TMath::Pi();
t.fRelativeSector = Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN;
- Int_t first = 0;
- first = t.fFirstPoint+3;
+ Int_t first = t.fFirstPoint;
+ if (first<GetRowNumber(xt)+1) first = GetRowNumber(xt)+1;
//
if (first<0) first=0;
- for (Int_t nr=first+1; nr<=rf; nr++) {
- //if ( (t.GetSnp()<0.9))
+ for (Int_t nr=first; nr<=rf; nr++) {
+ if ( (TMath::Abs(t.GetSnp())>0.95)) break;
+ if (t.GetKinkIndexes()[0]<0){
+ for (Int_t i=0;i<3;i++){
+ Int_t index = t.GetKinkIndexes()[i];
+ if (index==0) break;
+ if (index>0) continue;
+ index = TMath::Abs(index);
+ AliESDkink * kink = fEvent->GetKink(index-1);
+ if (!kink){
+ printf("PROBLEM\n");
+ }
+ else{
+ Int_t kinkrow = kink->GetTPCRow0()-2-Int_t(0.5/(0.05+kink->GetAngle(2)));
+ if (kinkrow==nr){
+ AliExternalTrackParam paramm(t);
+ kink->SetMother(paramm);
+ kink->SetStatus(2,1);
+ kink->Update();
+ }
+ }
+ }
+ }
+ //
if (nr<fInnerSec->GetNRows())
fSectors = fInnerSec;
else
//sort trackss according sectors
//
if (fDebug&1) {
- printf("Number of tracks before double removal- %d\n",arr->GetEntries());
+ Info("RemoveDouble","Number of tracks before double removal- %d\n",arr->GetEntries());
}
//
for (Int_t i=0; i<arr->GetEntriesFast(); i++) {
}
arr->Compress();
if (fDebug&1) {
- printf("Number of tracks after double removal- %d\n",arr->GetEntries());
+ Info("RemoveDouble","Number of tracks after double removal- %d\n",arr->GetEntries());
}
}
}
fNtracks = good;
-
- printf("\n*****\nNumber of good tracks after shared removal\t%d\n",fNtracks);
+ if (fDebug>0){
+ Info("RemoveUsed","\n*****\nNumber of good tracks after shared removal\t%d\n",fNtracks);
+ }
+}
+
+
+void AliTPCtrackerMI::RemoveUsed2(TObjArray * arr, Float_t factor1, Float_t factor2, Int_t minimal)
+{
+
+ //Loop over all tracks and remove "overlaps"
+ //
+ //
+ UnsignClusters();
+ //
+ Int_t nseed = arr->GetEntriesFast();
+ Float_t * quality = new Float_t[nseed];
+ Int_t * indexes = new Int_t[nseed];
+ Int_t good =0;
+ //
+ //
+ for (Int_t i=0; i<nseed; i++) {
+ AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
+ if (!pt){
+ quality[i]=-1;
+ continue;
+ }
+ pt->UpdatePoints(); //select first last max dens points
+ Float_t * points = pt->GetPoints();
+ if (points[3]<0.8) quality[i] =-1;
+ //
+ quality[i] = (points[2]-points[0])+pt->GetNumberOfClusters();
+ }
+ TMath::Sort(nseed,quality,indexes);
+ //
+ //
+ for (Int_t itrack=0; itrack<nseed; itrack++) {
+ Int_t trackindex = indexes[itrack];
+ AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(trackindex);
+ if (quality[trackindex]<0){
+ if (pt) {
+ delete arr->RemoveAt(trackindex);
+ }
+ else{
+ arr->RemoveAt(trackindex);
+ }
+ continue;
+ }
+ //
+ Int_t first = Int_t(pt->GetPoints()[0]);
+ Int_t last = Int_t(pt->GetPoints()[2]);
+ Double_t factor = (pt->fBConstrain) ? factor1: factor2;
+ //
+ Int_t found,foundable,shared;
+ pt->GetClusterStatistic(first,last, found, foundable,shared,kFALSE);
+ Float_t sharedfactor = Float_t(shared+1)/Float_t(found+1);
+ //
+ if (Float_t(shared+1)/Float_t(found+1)>factor){
+ if (pt->GetKinkIndexes()[0]!=0) continue; //don't remove tracks - part of the kinks
+ delete arr->RemoveAt(trackindex);
+ continue;
+ }
+
+ if (pt->GetNumberOfClusters()<50&&(found-0.5*shared)<minimal){ //remove short tracks
+ if (pt->GetKinkIndexes()[0]!=0) continue; //don't remove tracks - part of the kinks
+ delete arr->RemoveAt(trackindex);
+ continue;
+ }
+
+ good++;
+ if (sharedfactor>0.4) continue;
+ for (Int_t i=first; i<last; i++) {
+ Int_t index=pt->GetClusterIndex2(i);
+ // if (index<0 || index&0x8000 ) continue;
+ if (index<0 || index&0x8000 ) continue;
+ AliTPCclusterMI *c= pt->fClusterPointer[i];
+ if (!c) continue;
+ c->Use(10);
+ }
+ }
+ fNtracks = good;
+ if (fDebug>0){
+ Info("RemoveUsed","\n*****\nNumber of good tracks after shared removal\t%d\n",fNtracks);
+ }
+ delete []quality;
+ delete []indexes;
}
void AliTPCtrackerMI::UnsignClusters()
fEvent = event;
ReadSeeds(event,2);
fIteration=2;
- PrepareForProlongation(fSeeds,1);
- PropagateForward();
+ //PrepareForProlongation(fSeeds,1);
+ PropagateForward2(fSeeds);
+
+ Int_t ntracks=0;
Int_t nseed = fSeeds->GetEntriesFast();
for (Int_t i=0;i<nseed;i++){
AliTPCseed * seed = (AliTPCseed*) fSeeds->UncheckedAt(i);
+ if (!seed) continue;
+ if (seed->GetKinkIndex(0)>0) UpdateKinkQualityD(seed); // update quality informations for kinks
+
seed->PropagateTo(fParam->GetInnerRadiusLow());
+ seed->UpdatePoints();
AliESDtrack *esd=event->GetTrack(i);
seed->CookdEdx(0.02,0.6);
CookLabel(seed,0.1); //For comparison only
- if (seed->GetNumberOfClusters()>20){
- esd->UpdateTrackParams(seed,AliESDtrack::kTPCrefit);
+ //
+ if (0 && seed!=0&&esd!=0) {
+ TTreeSRedirector &cstream = *fDebugStreamer;
+ cstream<<"Crefit"<<
+ "Esd.="<<esd<<
+ "Track.="<<seed<<
+ "\n";
+ }
+ if (seed->GetNumberOfClusters()>15){
+ esd->UpdateTrackParams(seed,AliESDtrack::kTPCrefit);
+ esd->SetTPCPoints(seed->GetPoints());
+ ntracks++;
}
else{
//printf("problem\n");
}
}
+ //FindKinks(fSeeds,event);
+ Info("RefitInward","Number of refitted tracks %d",ntracks);
fEvent =0;
//WriteTracks();
return 0;
fEvent = event;
fIteration = 1;
- ReadSeeds(event,0);
+ ReadSeeds(event,1);
PropagateBack(fSeeds);
Int_t nseed = fSeeds->GetEntriesFast();
+ Int_t ntracks=0;
for (Int_t i=0;i<nseed;i++){
AliTPCseed * seed = (AliTPCseed*) fSeeds->UncheckedAt(i);
+ if (!seed) continue;
+ if (seed->GetKinkIndex(0)<0) UpdateKinkQualityM(seed); // update quality informations for kinks
+ seed->UpdatePoints();
AliESDtrack *esd=event->GetTrack(i);
seed->CookdEdx(0.02,0.6);
CookLabel(seed,0.1); //For comparison only
- esd->UpdateTrackParams(seed,AliESDtrack::kTPCout);
+ if (seed->GetNumberOfClusters()>15){
+ esd->UpdateTrackParams(seed,AliESDtrack::kTPCout);
+ esd->SetTPCPoints(seed->GetPoints());
+ ntracks++;
+ }
}
+ //FindKinks(fSeeds,event);
+ Info("PropagateBack","Number of back propagated tracks %d",ntracks);
fEvent =0;
//WriteTracks();
return 0;
//read seeds from the event
Int_t nentr=event->GetNumberOfTracks();
- Info("PropagateBack", "Number of ESD tracks: %d\n", nentr);
+ if (fDebug>0){
+ Info("ReadSeeds", "Number of ESD tracks: %d\n", nentr);
+ }
if (fSeeds)
DeleteSeeds();
if (!fSeeds){
- fSeeds = new TObjArray;
+ fSeeds = new TObjArray(nentr);
}
-
- // Int_t ntrk=0;
+ UnsignClusters();
+ // Int_t ntrk=0;
for (Int_t i=0; i<nentr; i++) {
AliESDtrack *esd=event->GetTrack(i);
- ULong_t status=esd->GetStatus();
+ ULong_t status=esd->GetStatus();
+ if (!(status&AliESDtrack::kTPCin)) continue;
AliTPCtrack t(*esd);
- AliTPCseed *seed = new AliTPCseed(t,t.GetAlpha());
- if (status==AliESDtrack::kTPCin&&direction==1) seed->Modify(0.8);
+ t.SetNumberOfClusters(0);
+ // AliTPCseed *seed = new AliTPCseed(t,t.GetAlpha());
+ AliTPCseed *seed = new AliTPCseed(t/*,t.GetAlpha()*/);
+ for (Int_t ikink=0;ikink<3;ikink++) {
+ Int_t index = esd->GetKinkIndex(ikink);
+ seed->GetKinkIndexes()[ikink] = index;
+ if (index==0) continue;
+ index = TMath::Abs(index);
+ AliESDkink * kink = fEvent->GetKink(index-1);
+ if (kink&&esd->GetKinkIndex(ikink)<0){
+ if ((status & AliESDtrack::kTRDrefit) != 0) kink->SetStatus(1,2);
+ if ((status & AliESDtrack::kITSout) != 0) kink->SetStatus(1,0);
+ }
+ if (kink&&esd->GetKinkIndex(ikink)>0){
+ if ((status & AliESDtrack::kTRDrefit) != 0) kink->SetStatus(1,6);
+ if ((status & AliESDtrack::kITSout) != 0) kink->SetStatus(1,4);
+ }
+
+ }
+ if (((status&AliESDtrack::kITSout)==0)&&(direction==1)) seed->ResetCovariance();
+ if ( direction ==2 &&(status & AliESDtrack::kTRDrefit) == 0 ) seed->ResetCovariance();
+ if ( direction ==2 && ((status & AliESDtrack::kTPCout) == 0) ) {
+ fSeeds->AddAt(0,i);
+ delete seed;
+ continue;
+ }
+ if ( direction ==2 &&(status & AliESDtrack::kTRDrefit) > 0 ) {
+ Double_t par0[5],par1[5],alpha,x;
+ esd->GetInnerExternalParameters(alpha,x,par0);
+ esd->GetExternalParameters(x,par1);
+ Double_t delta1 = TMath::Abs(par0[4]-par1[4])/(0.000000001+TMath::Abs(par0[4]+par1[4]));
+ Double_t delta2 = TMath::Abs(par0[3]-par1[3]);
+ Double_t trdchi2=0;
+ if (esd->GetTRDncls()>0) trdchi2 = esd->GetTRDchi2()/esd->GetTRDncls();
+ //reset covariance if suspicious
+ if ( (delta1>0.1) || (delta2>0.006) ||trdchi2>7.)
+ seed->ResetCovariance();
+ }
+
//
//
// rotate to the local coordinate system
-
- fSectors=fInnerSec; fN=fkNIS;
-
+ //
+ fSectors=fInnerSec; fN=fkNIS;
Double_t alpha=seed->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();
+ if (alpha<-TMath::Pi()) alpha += 2*TMath::Pi();
+ if (alpha>=TMath::Pi()) alpha -= 2*TMath::Pi();
alpha-=seed->GetAlpha();
- if (!seed->Rotate(alpha)) continue;
+ if (!seed->Rotate(alpha)) {
+ delete seed;
+ continue;
+ }
seed->fEsd = esd;
- //
- //seed->PropagateTo(fSectors->GetX(0));
- //
- // Int_t index = esd->GetTPCindex();
- //AliTPCseed * seed2= (AliTPCseed*)fSeeds->At(index);
- //if (direction==2){
- // AliTPCseed * seed2 = ReSeed(seed,0.,0.5,1.);
- // if (seed2) {
- // delete seed;
- // seed = seed2;
- // }
- //}
-
- fSeeds->AddLast(seed);
+ // sign clusters
+ for (Int_t irow=0;irow<160;irow++){
+ Int_t index = seed->GetClusterIndex2(irow);
+ if (index>0){
+ //
+ AliTPCclusterMI * cl = GetClusterMI(index);
+ seed->fClusterPointer[irow] = cl;
+ if (cl){
+ if ((index & 0x8000)==0){
+ cl->Use(10); // accepted cluster
+ }else{
+ cl->Use(6); // close cluster not accepted
+ }
+ }else{
+ Info("ReadSeeds","Not found cluster");
+ }
+ }
+ }
+ fSeeds->AddAt(seed,i);
}
}
}
}
}
- if (fDebug>1){
- // printf("\nSeeding statiistic:\t%d\t%d\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin,nout1,nout2);
+ if (fDebug>3){
+ Info("MakeSeeds3","\nSeeding statistic:\t%d\t%d\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin,nout1,nout2);
}
delete seed;
}
}
}
- if (fDebug>1){
- // printf("\nSeeding statiistic:\t%d\t%d\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin,nout1,nout2,nout3);
+ if (fDebug>3){
+ Info("MakeSeeds5","\nSeeding statiistic:\t%d\t%d\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin,nout1,nout2,nout3);
}
delete seed;
}
}
} // if accepted seed
}
- if (fDebug>1){
- printf("\nSeeding statiistic:\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin3);
+ if (fDebug>3){
+ Info("MakeSeeds2","\nSeeding statiistic:\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin3);
}
delete seed;
}
Int_t p2 = int(r2*track->GetNumberOfClusters()); // last point
Int_t pp2=0;
Double_t x0[3],x1[3],x2[3];
- x0[0]=-1;
- x0[0]=-1;
- x0[0]=-1;
+ for (Int_t i=0;i<3;i++){
+ x0[i]=-1;
+ x1[i]=-1;
+ x2[i]=-1;
+ }
// find track position at given ratio of the length
- Int_t sec0, sec1, sec2;
- sec0=0;
- sec1=0;
- sec2=0;
+ Int_t sec0=0, sec1=0, sec2=0;
Int_t index=-1;
Int_t clindex;
for (Int_t i=0;i<160;i++){
Int_t clindex = track->GetClusterIndex2(row[ipoint]);
AliTPCclusterMI * cl = GetClusterMI(clindex);
if (cl==0) {
- printf("Bug\n");
+ //Error("Bug\n");
// AliTPCclusterMI * cl = GetClusterMI(clindex);
return 0;
}
return seed;
}
-Int_t AliTPCtrackerMI::CheckKinkPoint(AliTPCseed*seed, Float_t th)
+
+AliTPCseed *AliTPCtrackerMI::ReSeed(AliTPCseed *track,Int_t r0, Bool_t forward)
{
//
//
- //
- for (Int_t i=0;i<12;i++) seed->fKinkPoint[i]=0;
- //
- if (TMath::Abs(seed->GetC())>0.01) return 0;
- //
-
- Float_t x[160], y[160], erry[160], z[160], errz[160];
- Int_t sec[160];
- Float_t xt[160], yt[160], zt[160];
- Int_t i1 = 200;
- Int_t i2 = 0;
- Int_t secm = -1;
- Int_t padm = -1;
- Int_t middle = seed->GetNumberOfClusters()/2;
- //
- //
- // find central sector, get local cooordinates
- Int_t count = 0;
- for (Int_t i=seed->fFirstPoint;i<=seed->fLastPoint;i++) {
- sec[i]= seed->GetClusterSector(i)%18;
- x[i] = GetXrow(i);
- if (sec[i]>=0) {
- AliTPCclusterMI * cl = seed->fClusterPointer[i];
- // if (cl==0) cl = GetClusterMI(seed->GetClusterIndex2(i));
- if (cl==0) {
- sec[i] = -1;
- continue;
+ //reseed using founded clusters
+ //
+ Double_t xyz[3][3];
+ Int_t row[3]={0,0,0};
+ Int_t sec[3]={0,0,0};
+ //
+ // forward direction
+ if (forward){
+ for (Int_t irow=r0;irow<160;irow++){
+ if (track->GetClusterIndex(irow)>0){
+ row[0] = irow;
+ break;
}
- //
- //
- if (i>i2) i2 = i; //last point with cluster
- if (i2<i1) i1 = i; //first point with cluster
- y[i] = cl->GetY();
- z[i] = cl->GetZ();
- AliTPCTrackerPoint * point = seed->GetTrackPoint(i);
- xt[i] = x[i];
- yt[i] = point->GetY();
- zt[i] = point->GetZ();
-
- if (point->GetX()>0){
- erry[i] = point->GetErrY();
- errz[i] = point->GetErrZ();
+ }
+ for (Int_t irow=160;irow>r0;irow--){
+ if (track->GetClusterIndex(irow)>0){
+ row[2] = irow;
+ break;
}
-
- count++;
- if (count<middle) {
- secm = sec[i]; //central sector
- padm = i; //middle point with cluster
+ }
+ for (Int_t irow=row[2]-15;irow>row[0];irow--){
+ if (track->GetClusterIndex(irow)>0){
+ row[1] = irow;
+ break;
}
}
- }
- //
- // rotate position to global coordinate system connected to sector at last the point
- //
- for (Int_t i=i1;i<=i2;i++){
- //
- if (sec[i]<0) continue;
- Double_t alpha = (sec[i2]-sec[i])*fSectors->GetAlpha();
- Double_t cs = TMath::Cos(alpha);
- Double_t sn = TMath::Sin(alpha);
- Float_t xx2= x[i]*cs+y[i]*sn;
- Float_t yy2= -x[i]*sn+y[i]*cs;
- x[i] = xx2;
- y[i] = yy2;
//
- xx2= xt[i]*cs+yt[i]*sn;
- yy2= -xt[i]*sn+yt[i]*cs;
- xt[i] = xx2;
- yt[i] = yy2;
-
- }
- //get "state" vector
- Double_t xh[5],xm = x[padm];
- xh[0]=yt[i2];
- xh[1]=zt[i2];
- xh[4]=F1(xt[i2],yt[i2],xt[padm],yt[padm],xt[i1],yt[i1]);
- xh[2]=F2(xt[i2],yt[i2],xt[padm],yt[padm],xt[i1],yt[i1]);
- xh[3]=F3n(xt[i2],yt[i2],xt[i1],yt[i1],zt[i2],zt[i1],xh[4]);
- //
- //
- for (Int_t i=i1;i<=i2;i++){
- Double_t yy,zz;
- if (sec[i]<0) continue;
- GetProlongation(x[i2], x[i],xh,yy,zz);
- if (TMath::Abs(y[i]-yy)>4||TMath::Abs(z[i]-zz)>4){
- //Double_t xxh[5];
- //xxh[4]=F1old(x[i2],y[i2],x[padm],y[padm],x[i1],y[i1]);
- //xxh[2]=F2old(x[i2],y[i2],x[padm],y[padm],x[i1],y[i1]);
- printf("problem\n");
- }
- y[i] = y[i] - yy;
- z[i] = z[i] - zz;
}
- Float_t dyup[160],dydown[160], dzup[160], dzdown[160];
- Float_t yup[160], ydown[160], zup[160], zdown[160];
-
- AliTPCpolyTrack ptrack1,ptrack2;
- //
- // derivation up
- for (Int_t i=i1;i<=i2;i++){
- AliTPCclusterMI * cl = seed->fClusterPointer[i];
- if (!cl) continue;
- if (cl->GetType()<0) continue;
- if (cl->GetType()>10) continue;
-
- if (sec[i]>=0){
- ptrack1.AddPoint(x[i]-xm,y[i],z[i],0.1,0.1);
- }
- if (ptrack1.GetN()>4.){
- ptrack1.UpdateParameters();
- Double_t ddy,ddz;
- ptrack1.GetFitDerivation(x[i]-xm,ddy,ddz);
- Double_t yy,zz;
- ptrack1.GetFitPoint(x[i]-xm,yy,zz);
-
- dyup[i] = ddy;
- dzup[i] = ddz;
- yup[i] = yy;
- zup[i] = zz;
-
- }
- else{
- dyup[i]=0.; //not enough points
+ if (!forward){
+ for (Int_t irow=0;irow<r0;irow++){
+ if (track->GetClusterIndex(irow)>0){
+ row[0] = irow;
+ break;
+ }
}
+ for (Int_t irow=r0;irow>0;irow--){
+ if (track->GetClusterIndex(irow)>0){
+ row[2] = irow;
+ break;
+ }
+ }
+ for (Int_t irow=row[2]-15;irow>row[0];irow--){
+ if (track->GetClusterIndex(irow)>0){
+ row[1] = irow;
+ break;
+ }
+ }
}
//
- // derivation down
- for (Int_t i=i2;i>=i1;i--){
- AliTPCclusterMI * cl = seed->fClusterPointer[i];
- if (!cl) continue;
- if (cl->GetType()<0) continue;
- if (cl->GetType()>10) continue;
- if (sec[i]>=0){
- ptrack2.AddPoint(x[i]-xm,y[i],z[i],0.1,0.1);
+ if ((row[2]-row[0])<20) return 0;
+ if (row[1]==0) return 0;
+ //
+ //
+ //Get cluster and sector position
+ for (Int_t ipoint=0;ipoint<3;ipoint++){
+ Int_t clindex = track->GetClusterIndex2(row[ipoint]);
+ AliTPCclusterMI * cl = GetClusterMI(clindex);
+ if (cl==0) {
+ //Error("Bug\n");
+ // AliTPCclusterMI * cl = GetClusterMI(clindex);
+ return 0;
}
- if (ptrack2.GetN()>4){
- ptrack2.UpdateParameters();
- Double_t ddy,ddz;
- ptrack2.GetFitDerivation(x[i]-xm,ddy,ddz);
- Double_t yy,zz;
- ptrack2.GetFitPoint(x[i]-xm,yy,zz);
-
- dydown[i] = ddy;
- dzdown[i] = ddz;
- ydown[i] = yy;
- zdown[i] = zz;
+ sec[ipoint] = ((clindex&0xff000000)>>24)%18;
+ xyz[ipoint][0] = GetXrow(row[ipoint]);
+ AliTPCTrackerPoint * point = track->GetTrackPoint(row[ipoint]);
+ if (point&&ipoint<2){
+ //
+ xyz[ipoint][1] = point->GetY();
+ xyz[ipoint][2] = point->GetZ();
}
else{
- dydown[i]=0.; //not enough points
+ xyz[ipoint][1] = cl->GetY();
+ xyz[ipoint][2] = cl->GetZ();
}
}
//
//
- // find maximal difference of the derivation
- for (Int_t i=0;i<12;i++) seed->fKinkPoint[i]=0;
-
-
- for (Int_t i=i1+10;i<i2-10;i++){
- if ( (TMath::Abs(dydown[i])<0.00000001) || (TMath::Abs(dyup[i])<0.00000001) ||i<30)continue;
- // printf("%f\t%f\t%f\t%f\t%f\n",x[i],dydown[i],dyup[i],dzdown[i],dzup[i]);
- //
- Float_t ddy = TMath::Abs(dydown[i]-dyup[i]);
- Float_t ddz = TMath::Abs(dzdown[i]-dzup[i]);
- if ( (ddy+ddz)> th){
- seed->fKinkPoint[0] = i;
- seed->fKinkPoint[1] = ddy;
- seed->fKinkPoint[2] = ddz;
- th = ddy+ddz;
- }
- }
+ //
+ //
+ // Calculate seed state vector and covariance matrix
- if (fTreeDebug){
- //
- //write information to the debug tree
- TBranch * br = fTreeDebug->GetBranch("debug");
- TClonesArray * arr = new TClonesArray("AliTPCTrackPoint2");
- arr->ExpandCreateFast(i2-i1);
- br->SetAddress(&arr);
- //
- AliTPCclusterMI cldummy;
- cldummy.SetQ(0);
- AliTPCTrackPoint2 pdummy;
- pdummy.GetTPoint().fIsShared = 10;
- //
- Double_t alpha = sec[i2]*fSectors->GetAlpha();
- Double_t cs = TMath::Cos(alpha);
- Double_t sn = TMath::Sin(alpha);
-
- for (Int_t i=i1;i<i2;i++){
- AliTPCTrackPoint2 *trpoint = (AliTPCTrackPoint2*)arr->UncheckedAt(i-i1);
- //cluster info
- AliTPCclusterMI * cl0 = seed->fClusterPointer[i];
- //
- AliTPCTrackerPoint * point = seed->GetTrackPoint(i);
-
- if (cl0){
- Double_t x = GetXrow(i);
- trpoint->GetTPoint() = *point;
- trpoint->GetCPoint() = *cl0;
- trpoint->GetCPoint().SetQ(TMath::Abs(cl0->GetQ()));
- trpoint->fID = seed->GetUniqueID();
- trpoint->fLab = seed->GetLabel();
- //
- trpoint->fGX = cs *x + sn*point->GetY();
- trpoint->fGY = -sn *x + cs*point->GetY() ;
- trpoint->fGZ = point->GetZ();
- //
- trpoint->fDY = y[i];
- trpoint->fDZ = z[i];
- //
- trpoint->fDYU = dyup[i];
- trpoint->fDZU = dzup[i];
- //
- trpoint->fDYD = dydown[i];
- trpoint->fDZD = dzdown[i];
- //
- if (TMath::Abs(dyup[i])>0.00000000001 &&TMath::Abs(dydown[i])>0.00000000001){
- trpoint->fDDY = dydown[i]-dyup[i];
- trpoint->fDDZ = dzdown[i]-dzup[i];
- }else{
- trpoint->fDDY = 0.;
- trpoint->fDDZ = 0.;
- }
- }
- else{
- *trpoint = pdummy;
- trpoint->GetCPoint()= cldummy;
- trpoint->fID = -1;
- }
- //
- }
- fTreeDebug->Fill();
- }
+ Double_t alpha, cs,sn, xx2,yy2;
+ //
+ alpha = (sec[1]-sec[2])*fSectors->GetAlpha();
+ cs = TMath::Cos(alpha);
+ sn = TMath::Sin(alpha);
+ xx2= xyz[1][0]*cs-xyz[1][1]*sn;
+ yy2= xyz[1][0]*sn+xyz[1][1]*cs;
+ xyz[1][0] = xx2;
+ xyz[1][1] = yy2;
+ //
+ alpha = (sec[0]-sec[2])*fSectors->GetAlpha();
+ cs = TMath::Cos(alpha);
+ sn = TMath::Sin(alpha);
+ xx2= xyz[0][0]*cs-xyz[0][1]*sn;
+ yy2= xyz[0][0]*sn+xyz[0][1]*cs;
+ xyz[0][0] = xx2;
+ xyz[0][1] = yy2;
+ //
+ //
+ //
+ Double_t x[5],c[15];
+ //
+ x[0]=xyz[2][1];
+ x[1]=xyz[2][2];
+ x[4]=F1(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
+ x[2]=F2(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
+ x[3]=F3n(xyz[2][0],xyz[2][1],xyz[0][0],xyz[0][1],xyz[2][2],xyz[0][2],x[4]);
+ //
+ Double_t sy =0.1, sz =0.1;
+ //
+ Double_t sy1=0.2, sz1=0.2;
+ Double_t sy2=0.2, sz2=0.2;
+ Double_t sy3=0.2;
+ //
+ Double_t f40=(F1(xyz[2][0],xyz[2][1]+sy,xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1])-x[4])/sy;
+ Double_t f42=(F1(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1]+sy,xyz[0][0],xyz[0][1])-x[4])/sy;
+ Double_t f43=(F1(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]+sy)-x[4])/sy;
+ Double_t f20=(F2(xyz[2][0],xyz[2][1]+sy,xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1])-x[2])/sy;
+ Double_t f22=(F2(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1]+sy,xyz[0][0],xyz[0][1])-x[2])/sy;
+ Double_t f23=(F2(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]+sy)-x[2])/sy;
+ //
+ Double_t f30=(F3(xyz[2][0],xyz[2][1]+sy,xyz[0][0],xyz[0][1],xyz[2][2],xyz[0][2])-x[3])/sy;
+ Double_t f31=(F3(xyz[2][0],xyz[2][1],xyz[0][0],xyz[0][1],xyz[2][2]+sz,xyz[0][2])-x[3])/sz;
+ Double_t f32=(F3(xyz[2][0],xyz[2][1],xyz[0][0],xyz[0][1]+sy,xyz[2][2],xyz[0][2])-x[3])/sy;
+ Double_t f34=(F3(xyz[2][0],xyz[2][1],xyz[0][0],xyz[0][1],xyz[2][2],xyz[0][2]+sz)-x[3])/sz;
- return 0;
+ c[0]=sy1;
+ c[1]=0.; c[2]=sz1;
+ c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
+ c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
+ c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
+ c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
+ c[13]=f30*sy1*f40+f32*sy2*f42;
+ c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
-}
-
-
-
+ // Int_t row1 = fSectors->GetRowNumber(xyz[2][0]);
+ AliTPCseed *seed=new AliTPCseed(0, x, c, xyz[2][0], sec[2]*fSectors->GetAlpha()+fSectors->GetAlphaShift());
+ seed->fLastPoint = row[2];
+ seed->fFirstPoint = row[2];
+ for (Int_t i=row[0];i<row[2];i++){
+ seed->fIndex[i] = track->fIndex[i];
+ }
+ return seed;
+}
-AliTPCseed* AliTPCtrackerMI::ReSeed(AliTPCseed *t)
+void AliTPCtrackerMI::FindKinks(TObjArray * array, AliESD *esd)
{
//
- // reseed - refit - track
+ // find kinks
//
- Int_t first = 0;
- // Int_t last = fSectors->GetNRows()-1;
//
- if (fSectors == fOuterSec){
- first = TMath::Max(first, t->fFirstPoint-fInnerSec->GetNRows());
- //last =
+
+ TObjArray *kinks= new TObjArray(10000);
+ // TObjArray *v0s= new TObjArray(10000);
+ Int_t nentries = array->GetEntriesFast();
+ AliHelix *helixes = new AliHelix[nentries];
+ Int_t *sign = new Int_t[nentries];
+ Int_t *nclusters = new Int_t[nentries];
+ Float_t *alpha = new Float_t[nentries];
+ AliESDkink * kink = new AliESDkink();
+ Int_t * usage = new Int_t[nentries];
+ Float_t *zm = new Float_t[nentries];
+ Float_t *z0 = new Float_t[nentries];
+ Float_t *fim = new Float_t[nentries];
+ Float_t *shared = new Float_t[nentries];
+ Bool_t *circular = new Bool_t[nentries];
+ Float_t *dca = new Float_t[nentries];
+ //const AliESDVertex * primvertex = esd->GetVertex();
+ //
+ // nentries = array->GetEntriesFast();
+ //
+
+ //
+ //
+ for (Int_t i=0;i<nentries;i++){
+ sign[i]=0;
+ usage[i]=0;
+ AliTPCseed* track = (AliTPCseed*)array->At(i);
+ if (!track) continue;
+ track->fCircular =0;
+ shared[i] = kFALSE;
+ track->UpdatePoints();
+ if (( track->GetPoints()[2]- track->GetPoints()[0])>5 && track->GetPoints()[3]>0.8){
+ }
+ nclusters[i]=track->GetNumberOfClusters();
+ alpha[i] = track->GetAlpha();
+ new (&helixes[i]) AliHelix(*track);
+ Double_t xyz[3];
+ helixes[i].Evaluate(0,xyz);
+ sign[i] = (track->GetC()>0) ? -1:1;
+ Double_t x,y,z;
+ x=160;
+ if (track->GetProlongation(x,y,z)){
+ zm[i] = z;
+ fim[i] = alpha[i]+TMath::ATan2(y,x);
+ }
+ else{
+ zm[i] = track->GetZ();
+ fim[i] = alpha[i];
+ }
+ z0[i]=1000;
+ circular[i]= kFALSE;
+ if (track->GetProlongation(0,y,z)) z0[i] = z;
+ dca[i] = track->GetD(0,0);
}
- else
- first = t->fFirstPoint;
//
- AliTPCseed * seed = MakeSeed(t,0.1,0.5,0.9);
- FollowBackProlongation(*t,fSectors->GetNRows()-1);
- t->Reset(kFALSE);
- FollowProlongation(*t,first);
- return seed;
-}
-
-
-
-
-
-
-
-//_____________________________________________________________________________
-Int_t AliTPCtrackerMI::ReadSeeds(const TFile *inp) {
- //-----------------------------------------------------------------
- // This function reades track seeds.
- //-----------------------------------------------------------------
- TDirectory *savedir=gDirectory;
-
+ //
+ TStopwatch timer;
+ timer.Start();
+ Int_t ncandidates =0;
+ Int_t nall =0;
+ Int_t ntracks=0;
+ Double_t phase[2][2],radius[2];
+
+ //
+ // Find circling track
+ TTreeSRedirector &cstream = *fDebugStreamer;
+ //
+ for (Int_t i0=0;i0<nentries;i0++){
+ AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
+ if (!track0) continue;
+ if (track0->fN<40) continue;
+ if (TMath::Abs(1./track0->fP4)>200) continue;
+ for (Int_t i1=i0+1;i1<nentries;i1++){
+ AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
+ if (!track1) continue;
+ if (track1->fN<40) continue;
+ if ( TMath::Abs(track1->fP3+track0->fP3)>0.1) continue;
+ if (track0->fBConstrain&&track1->fBConstrain) continue;
+ if (TMath::Abs(1./track1->fP4)>200) continue;
+ if (track1->fP4*track0->fP4>0) continue;
+ if (track1->fP3*track0->fP3>0) continue;
+ if (max(TMath::Abs(1./track0->fP4),TMath::Abs(1./track1->fP4))>190) continue;
+ if (track0->fBConstrain&&TMath::Abs(track1->fP4)<TMath::Abs(track0->fP4)) continue; //returning - lower momenta
+ if (track1->fBConstrain&&TMath::Abs(track0->fP4)<TMath::Abs(track1->fP4)) continue; //returning - lower momenta
+ //
+ Float_t mindcar = TMath::Min(TMath::Abs(dca[i0]),TMath::Abs(dca[i1]));
+ if (mindcar<5) continue;
+ Float_t mindcaz = TMath::Min(TMath::Abs(z0[i0]-GetZ()),TMath::Abs(z0[i1]-GetZ()));
+ if (mindcaz<5) continue;
+ if (mindcar+mindcaz<20) continue;
+ //
+ //
+ Float_t xc0 = helixes[i0].GetHelix(6);
+ Float_t yc0 = helixes[i0].GetHelix(7);
+ Float_t r0 = helixes[i0].GetHelix(8);
+ Float_t xc1 = helixes[i1].GetHelix(6);
+ Float_t yc1 = helixes[i1].GetHelix(7);
+ Float_t r1 = helixes[i1].GetHelix(8);
+
+ Float_t rmean = (r0+r1)*0.5;
+ Float_t delta =TMath::Sqrt((xc1-xc0)*(xc1-xc0)+(yc1-yc0)*(yc1-yc0));
+ //if (delta>30) continue;
+ if (delta>rmean*0.25) continue;
+ if (TMath::Abs(r0-r1)/rmean>0.3) continue;
+ //
+ Int_t npoints = helixes[i0].GetRPHIintersections(helixes[i1], phase, radius,10);
+ if (npoints==0) continue;
+ helixes[i0].GetClosestPhases(helixes[i1], phase);
+ //
+ Double_t xyz0[3];
+ Double_t xyz1[3];
+ Double_t hangles[3];
+ helixes[i0].Evaluate(phase[0][0],xyz0);
+ helixes[i1].Evaluate(phase[0][1],xyz1);
+
+ helixes[i0].GetAngle(phase[0][0],helixes[i1],phase[0][1],hangles);
+ Double_t deltah[2],deltabest;
+ if (hangles[2]<2.8) continue;
+ /*
+ cstream<<"C"<<track0->fLab<<track1->fLab<<
+ track0->fP3<<track1->fP3<<
+ track0->fP4<<track1->fP4<<
+ delta<<rmean<<npoints<<
+ hangles[0]<<hangles[2]<<
+ xyz0[2]<<xyz1[2]<<radius[0]<<"\n";
+ */
+ if (npoints>0){
+ Int_t ibest=0;
+ helixes[i0].ParabolicDCA(helixes[i1],phase[0][0],phase[0][1],radius[0],deltah[0],2);
+ if (npoints==2){
+ helixes[i0].ParabolicDCA(helixes[i1],phase[1][0],phase[1][1],radius[1],deltah[1],2);
+ if (deltah[1]<deltah[0]) ibest=1;
+ }
+ deltabest = TMath::Sqrt(deltah[ibest]);
+ helixes[i0].Evaluate(phase[ibest][0],xyz0);
+ helixes[i1].Evaluate(phase[ibest][1],xyz1);
+ helixes[i0].GetAngle(phase[ibest][0],helixes[i1],phase[ibest][1],hangles);
+ Double_t radiusbest = TMath::Sqrt(radius[ibest]);
+ //
+ if (deltabest>6) continue;
+ if (mindcar+mindcaz<40 && (hangles[2]<3.12||deltabest>3)) continue;
+ Bool_t sign =kFALSE;
+ if (hangles[2]>3.06) sign =kTRUE;
+ //
+ if (sign){
+ circular[i0] = kTRUE;
+ circular[i1] = kTRUE;
+ if (TMath::Abs(track0->fP4)<TMath::Abs(track1->fP4)){
+ track0->fCircular += 1;
+ track1->fCircular += 2;
+ }
+ else{
+ track1->fCircular += 1;
+ track0->fCircular += 2;
+ }
+ }
+ if (sign&&0){
+ //debug stream
+ cstream<<"Curling"<<
+ "lab0="<<track0->fLab<<
+ "lab1="<<track1->fLab<<
+ "Tr0.="<<track0<<
+ "Tr1.="<<track1<<
+ "dca0="<<dca[i0]<<
+ "dca1="<<dca[i1]<<
+ "mindcar="<<mindcar<<
+ "mindcaz="<<mindcaz<<
+ "delta="<<delta<<
+ "rmean="<<rmean<<
+ "npoints="<<npoints<<
+ "hangles0="<<hangles[0]<<
+ "hangles2="<<hangles[2]<<
+ "xyz0="<<xyz0[2]<<
+ "xyzz1="<<xyz1[2]<<
+ "z0="<<z0[i0]<<
+ "z1="<<z0[i1]<<
+ "radius="<<radiusbest<<
+ "deltabest="<<deltabest<<
+ "phase0="<<phase[ibest][0]<<
+ "phase1="<<phase[ibest][1]<<
+ "\n";
+ }
+ }
+ }
+ }
+ //
+ // Finf kinks loop
+ //
+ //
+ for (Int_t i =0;i<nentries;i++){
+ if (sign[i]==0) continue;
+ AliTPCseed * track0 = (AliTPCseed*)array->At(i);
+ ntracks++;
+ //
+ Double_t cradius0 = 40*40;
+ Double_t cradius1 = 270*270;
+ Double_t cdist1=8.;
+ Double_t cdist2=8.;
+ Double_t cdist3=0.55;
+ for (Int_t j =i+1;j<nentries;j++){
+ nall++;
+ if (sign[j]*sign[i]<1) continue;
+ if ( (nclusters[i]+nclusters[j])>200) continue;
+ if ( (nclusters[i]+nclusters[j])<80) continue;
+ if ( TMath::Abs(zm[i]-zm[j])>60.) continue;
+ if ( TMath::Abs(fim[i]-fim[j])>0.6 && TMath::Abs(fim[i]-fim[j])<5.7 ) continue;
+ //AliTPCseed * track1 = (AliTPCseed*)array->At(j); Double_t phase[2][2],radius[2];
+ Int_t npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,20);
+ if (npoints<1) continue;
+ // cuts on radius
+ if (npoints==1){
+ if (radius[0]<cradius0||radius[0]>cradius1) continue;
+ }
+ else{
+ if ( (radius[0]<cradius0||radius[0]>cradius1) && (radius[1]<cradius0||radius[1]>cradius1) ) continue;
+ }
+ //
+ Double_t delta1=10000,delta2=10000;
+ // cuts on the intersection radius
+ helixes[i].LinearDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta1);
+ if (radius[0]<20&&delta1<1) continue; //intersection at vertex
+ if (radius[0]<10&&delta1<3) continue; //intersection at vertex
+ if (npoints==2){
+ helixes[i].LinearDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta2);
+ if (radius[1]<20&&delta2<1) continue; //intersection at vertex
+ if (radius[1]<10&&delta2<3) continue; //intersection at vertex
+ }
+ //
+ Double_t distance1 = TMath::Min(delta1,delta2);
+ if (distance1>cdist1) continue; // cut on DCA linear approximation
+ //
+ npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,20);
+ helixes[i].ParabolicDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta1);
+ if (radius[0]<20&&delta1<1) continue; //intersection at vertex
+ if (radius[0]<10&&delta1<3) continue; //intersection at vertex
+ //
+ if (npoints==2){
+ helixes[i].ParabolicDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta2);
+ if (radius[1]<20&&delta2<1) continue; //intersection at vertex
+ if (radius[1]<10&&delta2<3) continue; //intersection at vertex
+ }
+ distance1 = TMath::Min(delta1,delta2);
+ Float_t rkink =0;
+ if (delta1<delta2){
+ rkink = TMath::Sqrt(radius[0]);
+ }
+ else{
+ rkink = TMath::Sqrt(radius[1]);
+ }
+ if (distance1>cdist2) continue;
+ //
+ //
+ AliTPCseed * track1 = (AliTPCseed*)array->At(j);
+ //
+ //
+ Int_t row0 = GetRowNumber(rkink);
+ if (row0<10) continue;
+ if (row0>150) continue;
+ //
+ //
+ Float_t dens00=-1,dens01=-1;
+ Float_t dens10=-1,dens11=-1;
+ //
+ Int_t found,foundable,shared;
+ track0->GetClusterStatistic(0,row0-5, found, foundable,shared,kFALSE);
+ if (foundable>5) dens00 = Float_t(found)/Float_t(foundable);
+ track0->GetClusterStatistic(row0+5,155, found, foundable,shared,kFALSE);
+ if (foundable>5) dens01 = Float_t(found)/Float_t(foundable);
+ //
+ track1->GetClusterStatistic(0,row0-5, found, foundable,shared,kFALSE);
+ if (foundable>10) dens10 = Float_t(found)/Float_t(foundable);
+ track1->GetClusterStatistic(row0+5,155, found, foundable,shared,kFALSE);
+ if (foundable>10) dens11 = Float_t(found)/Float_t(foundable);
+ //
+ if (dens00<dens10 && dens01<dens11) continue;
+ if (dens00>dens10 && dens01>dens11) continue;
+ if (TMath::Max(dens00,dens10)<0.1) continue;
+ if (TMath::Max(dens01,dens11)<0.3) continue;
+ //
+ if (TMath::Min(dens00,dens10)>0.6) continue;
+ if (TMath::Min(dens01,dens11)>0.6) continue;
+
+ //
+ AliTPCseed * ktrack0, *ktrack1;
+ if (dens00>dens10){
+ ktrack0 = track0;
+ ktrack1 = track1;
+ }
+ else{
+ ktrack0 = track1;
+ ktrack1 = track0;
+ }
+ if (TMath::Abs(ktrack0->GetC())>5) continue; // cut on the curvature for mother particle
+ AliExternalTrackParam paramm(*ktrack0);
+ AliExternalTrackParam paramd(*ktrack1);
+ if (row0>60&&ktrack1->GetReference().GetX()>90.) new (¶md) AliExternalTrackParam(ktrack1->GetReference());
+ //
+ //
+ kink->SetMother(paramm);
+ kink->SetDaughter(paramd);
+ kink->Update();
+
+ Float_t x[3] = { kink->GetPosition()[0],kink->GetPosition()[1],kink->GetPosition()[2]};
+ Int_t index[4];
+ fParam->Transform0to1(x,index);
+ fParam->Transform1to2(x,index);
+ row0 = GetRowNumber(x[0]);
+
+ if (kink->GetR()<100) continue;
+ if (kink->GetR()>240) continue;
+ if (kink->GetPosition()[2]/kink->GetR()>AliTPCReconstructor::GetCtgRange()) continue; //out of fiducial volume
+ if (kink->GetDistance()>cdist3) continue;
+ Float_t dird = kink->GetDaughterP()[0]*kink->GetPosition()[0]+kink->GetDaughterP()[1]*kink->GetPosition()[1]; // rough direction estimate
+ if (dird<0) continue;
+
+ Float_t dirm = kink->GetMotherP()[0]*kink->GetPosition()[0]+kink->GetMotherP()[1]*kink->GetPosition()[1]; // rough direction estimate
+ if (dirm<0) continue;
+ Float_t mpt = TMath::Sqrt(kink->GetMotherP()[0]*kink->GetMotherP()[0]+kink->GetMotherP()[1]*kink->GetMotherP()[1]);
+ if (mpt<0.2) continue;
+
+ if (mpt<1){
+ //for high momenta momentum not defined well in first iteration
+ Double_t qt = TMath::Sin(kink->GetAngle(2))*ktrack1->P();
+ if (qt>0.35) continue;
+ }
+
+ kink->SetLabel(CookLabel(ktrack0,0.4,0,row0),0);
+ kink->SetLabel(CookLabel(ktrack1,0.4,row0,160),1);
+ if (dens00>dens10){
+ kink->SetTPCDensity(dens00,0,0);
+ kink->SetTPCDensity(dens01,0,1);
+ kink->SetTPCDensity(dens10,1,0);
+ kink->SetTPCDensity(dens11,1,1);
+ kink->SetIndex(i,0);
+ kink->SetIndex(j,1);
+ }
+ else{
+ kink->SetTPCDensity(dens10,0,0);
+ kink->SetTPCDensity(dens11,0,1);
+ kink->SetTPCDensity(dens00,1,0);
+ kink->SetTPCDensity(dens01,1,1);
+ kink->SetIndex(j,0);
+ kink->SetIndex(i,1);
+ }
+
+ if (mpt<1||kink->GetAngle(2)>0.1){
+ // angle and densities not defined yet
+ if (kink->GetTPCDensityFactor()<0.8) continue;
+ if ((2-kink->GetTPCDensityFactor())*kink->GetDistance() >0.25) continue;
+ if (kink->GetAngle(2)*ktrack0->P()<0.003) continue; //too small angle
+ if (kink->GetAngle(2)>0.2&&kink->GetTPCDensityFactor()<1.15) continue;
+ if (kink->GetAngle(2)>0.2&&kink->GetTPCDensity(0,1)>0.05) continue;
+
+ Float_t criticalangle = track0->fC22+track0->fC33;
+ criticalangle+= track1->fC22+track1->fC33;
+ criticalangle= 3*TMath::Sqrt(criticalangle);
+ if (criticalangle>0.02) criticalangle=0.02;
+ if (kink->GetAngle(2)<criticalangle) continue;
+ }
+ //
+ Int_t drow = Int_t(2.+0.5/(0.05+kink->GetAngle(2))); // overlap region defined
+ Float_t shapesum =0;
+ Float_t sum = 0;
+ for ( Int_t row = row0-drow; row<row0+drow;row++){
+ if (row<0) continue;
+ if (row>155) continue;
+ if (ktrack0->fClusterPointer[row]){
+ AliTPCTrackerPoint *point =ktrack0->GetTrackPoint(row);
+ shapesum+=point->GetSigmaY()+point->GetSigmaZ();
+ sum++;
+ }
+ if (ktrack1->fClusterPointer[row]){
+ AliTPCTrackerPoint *point =ktrack1->GetTrackPoint(row);
+ shapesum+=point->GetSigmaY()+point->GetSigmaZ();
+ sum++;
+ }
+ }
+ if (sum<4){
+ kink->SetShapeFactor(-1.);
+ }
+ else{
+ kink->SetShapeFactor(shapesum/sum);
+ }
+ // esd->AddKink(kink);
+ kinks->AddLast(kink);
+ kink = new AliESDkink;
+ ncandidates++;
+ }
+ }
+ //
+ // sort the kinks according quality - and refit them towards vertex
+ //
+ Int_t nkinks = kinks->GetEntriesFast();
+ Float_t *quality = new Float_t[nkinks];
+ Int_t *indexes = new Int_t[nkinks];
+ AliTPCseed *mothers = new AliTPCseed[nkinks];
+ AliTPCseed *daughters = new AliTPCseed[nkinks];
+ //
+ //
+ for (Int_t i=0;i<nkinks;i++){
+ quality[i] =100000;
+ AliESDkink *kink = (AliESDkink*)kinks->At(i);
+ //
+ // refit kinks towards vertex
+ //
+ Int_t index0 = kink->GetIndex(0);
+ Int_t index1 = kink->GetIndex(1);
+ AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
+ AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
+ //
+ Int_t sumn=ktrack0->fN+ktrack1->fN;
+ //
+ // Refit Kink under if too small angle
+ //
+ if (kink->GetAngle(2)<0.05){
+ kink->SetTPCRow0(GetRowNumber(kink->GetR()));
+ Int_t row0 = kink->GetTPCRow0();
+ Int_t drow = Int_t(2.+0.5/(0.05+kink->GetAngle(2)));
+ //
+ //
+ Int_t last = row0-drow;
+ if (last<40) last=40;
+ if (last<ktrack0->fFirstPoint+25) last = ktrack0->fFirstPoint+25;
+ AliTPCseed* seed0 = ReSeed(ktrack0,last,kFALSE);
+ //
+ //
+ Int_t first = row0+drow;
+ if (first>130) first=130;
+ if (first>ktrack1->fLastPoint-25) first = TMath::Max(ktrack1->fLastPoint-25,30);
+ AliTPCseed* seed1 = ReSeed(ktrack1,first,kTRUE);
+ //
+ if (seed0 && seed1){
+ kink->SetStatus(1,8);
+ if (RefitKink(*seed0,*seed1,*kink)) kink->SetStatus(1,9);
+ row0 = GetRowNumber(kink->GetR());
+ sumn = seed0->fN+seed1->fN;
+ new (&mothers[i]) AliTPCseed(*seed0);
+ new (&daughters[i]) AliTPCseed(*seed1);
+ }
+ else{
+ delete kinks->RemoveAt(i);
+ if (seed0) delete seed0;
+ if (seed1) delete seed1;
+ continue;
+ }
+ if (kink->GetDistance()>0.5 || kink->GetR()<110 || kink->GetR()>240) {
+ delete kinks->RemoveAt(i);
+ if (seed0) delete seed0;
+ if (seed1) delete seed1;
+ continue;
+ }
+ //
+ delete seed0;
+ delete seed1;
+ }
+ //
+ if (kink) quality[i] = 160*((0.1+kink->GetDistance())*(2.-kink->GetTPCDensityFactor()))/(sumn+40.); //the longest -clossest will win
+ }
+ TMath::Sort(nkinks,quality,indexes,kFALSE);
+ //
+ //remove double find kinks
+ //
+ for (Int_t ikink0=1;ikink0<nkinks;ikink0++){
+ AliESDkink * kink0 = (AliESDkink*) kinks->At(indexes[ikink0]);
+ if (!kink0) continue;
+ //
+ for (Int_t ikink1=0;ikink1<ikink0;ikink1++){
+ if (!kink0) continue;
+ AliESDkink * kink1 = (AliESDkink*) kinks->At(indexes[ikink1]);
+ if (!kink1) continue;
+ // if not close kink continue
+ if (TMath::Abs(kink1->GetPosition()[2]-kink0->GetPosition()[2])>10) continue;
+ if (TMath::Abs(kink1->GetPosition()[1]-kink0->GetPosition()[1])>10) continue;
+ if (TMath::Abs(kink1->GetPosition()[0]-kink0->GetPosition()[0])>10) continue;
+ //
+ AliTPCseed &mother0 = mothers[indexes[ikink0]];
+ AliTPCseed &daughter0 = daughters[indexes[ikink0]];
+ AliTPCseed &mother1 = mothers[indexes[ikink1]];
+ AliTPCseed &daughter1 = daughters[indexes[ikink1]];
+ Int_t row0 = (kink0->GetTPCRow0()+kink1->GetTPCRow0())/2;
+ //
+ Int_t same = 0;
+ Int_t both = 0;
+ Int_t samem = 0;
+ Int_t bothm = 0;
+ Int_t samed = 0;
+ Int_t bothd = 0;
+ //
+ for (Int_t i=0;i<row0;i++){
+ if (mother0.fIndex[i]>0 && mother1.fIndex[i]>0){
+ both++;
+ bothm++;
+ if (mother0.fIndex[i]==mother1.fIndex[i]){
+ same++;
+ samem++;
+ }
+ }
+ }
+
+ for (Int_t i=row0;i<158;i++){
+ if (daughter0.fIndex[i]>0 && daughter0.fIndex[i]>0){
+ both++;
+ bothd++;
+ if (mother0.fIndex[i]==mother1.fIndex[i]){
+ same++;
+ samed++;
+ }
+ }
+ }
+ Float_t ratio = Float_t(same+1)/Float_t(both+1);
+ Float_t ratiom = Float_t(samem+1)/Float_t(bothm+1);
+ Float_t ratiod = Float_t(samed+1)/Float_t(bothd+1);
+ if (ratio>0.3 && ratiom>0.5 &&ratiod>0.5) {
+ Int_t sum0 = mother0.fN+daughter0.fN;
+ Int_t sum1 = mother1.fN+daughter1.fN;
+ if (sum1>sum0){
+ shared[kink0->GetIndex(0)]= kTRUE;
+ shared[kink0->GetIndex(1)]= kTRUE;
+ delete kinks->RemoveAt(indexes[ikink0]);
+ }
+ else{
+ shared[kink1->GetIndex(0)]= kTRUE;
+ shared[kink1->GetIndex(1)]= kTRUE;
+ delete kinks->RemoveAt(indexes[ikink1]);
+ }
+ }
+ }
+ }
+
+
+ for (Int_t i=0;i<nkinks;i++){
+ AliESDkink * kink = (AliESDkink*) kinks->At(indexes[i]);
+ if (!kink) continue;
+ kink->SetTPCRow0(GetRowNumber(kink->GetR()));
+ Int_t index0 = kink->GetIndex(0);
+ Int_t index1 = kink->GetIndex(1);
+ if (circular[index0]||circular[index1]&&kink->GetDistance()>0.2) continue;
+ kink->SetMultiple(usage[index0],0);
+ kink->SetMultiple(usage[index1],1);
+ if (kink->GetMultiple()[0]+kink->GetMultiple()[1]>2) continue;
+ if (kink->GetMultiple()[0]+kink->GetMultiple()[1]>0 && quality[indexes[i]]>0.2) continue;
+ if (kink->GetMultiple()[0]+kink->GetMultiple()[1]>0 && kink->GetDistance()>0.2) continue;
+ if (circular[index0]||circular[index1]&&kink->GetDistance()>0.1) continue;
+
+ AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
+ AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
+ if (!ktrack0 || !ktrack1) continue;
+ Int_t index = esd->AddKink(kink);
+ //
+ //
+ if ( ktrack0->fKinkIndexes[0]==0 && ktrack1->fKinkIndexes[0]==0) { //best kink
+ if (mothers[indexes[i]].fN>20 && daughters[indexes[i]].fN>20 && (mothers[indexes[i]].fN+daughters[indexes[i]].fN)>100){
+ new (ktrack0) AliTPCseed(mothers[indexes[i]]);
+ new (ktrack1) AliTPCseed(daughters[indexes[i]]);
+ }
+ }
+ //
+ ktrack0->fKinkIndexes[usage[index0]] = -(index+1);
+ ktrack1->fKinkIndexes[usage[index1]] = (index+1);
+ usage[index0]++;
+ usage[index1]++;
+ }
+ //
+ // Remove tracks corresponding to shared kink's
+ //
+ for (Int_t i=0;i<nentries;i++){
+ AliTPCseed * track0 = (AliTPCseed*)array->At(i);
+ if (!track0) continue;
+ if (track0->fKinkIndexes[0]!=0) continue;
+ if (shared[i]) delete array->RemoveAt(i);
+ }
+
+ //
+ //
+ RemoveUsed2(array,0.5,0.4,30);
+ UnsignClusters();
+ for (Int_t i=0;i<nentries;i++){
+ AliTPCseed * track0 = (AliTPCseed*)array->At(i);
+ if (!track0) continue;
+ track0->CookdEdx(0.02,0.6);
+ track0->CookPID();
+ }
+ //
+ for (Int_t i=0;i<nentries;i++){
+ AliTPCseed * track0 = (AliTPCseed*)array->At(i);
+ if (!track0) continue;
+ if (track0->Pt()<1.4) continue;
+ //remove double high momenta tracks - overlapped with kink candidates
+ Int_t shared=0;
+ Int_t all =0;
+ for (Int_t icl=track0->fFirstPoint;icl<track0->fLastPoint; icl++){
+ if (track0->fClusterPointer[icl]!=0){
+ all++;
+ if (track0->fClusterPointer[icl]->IsUsed(10)) shared++;
+ }
+ }
+ if (Float_t(shared+1)/Float_t(nall+1)>0.5) {
+ delete array->RemoveAt(i);
+ }
+ //
+ if (track0->fKinkIndexes[0]!=0) continue;
+ if (track0->GetNumberOfClusters()<80) continue;
+
+ AliTPCseed *pmother = new AliTPCseed();
+ AliTPCseed *pdaughter = new AliTPCseed();
+ AliESDkink *pkink = new AliESDkink;
+
+ AliTPCseed & mother = *pmother;
+ AliTPCseed & daughter = *pdaughter;
+ AliESDkink & kink = *pkink;
+ if (CheckKinkPoint(track0,mother,daughter, kink)){
+ if (mother.fN<30||daughter.fN<20) {
+ delete pmother;
+ delete pdaughter;
+ delete pkink;
+ continue; //too short tracks
+ }
+ if (mother.Pt()<1.4) {
+ delete pmother;
+ delete pdaughter;
+ delete pkink;
+ continue;
+ }
+ Int_t row0= kink.GetTPCRow0();
+ if (kink.GetDistance()>0.5 || kink.GetR()<110. || kink.GetR()>240.) {
+ delete pmother;
+ delete pdaughter;
+ delete pkink;
+ continue;
+ }
+ //
+ Int_t index = esd->AddKink(&kink);
+ mother.fKinkIndexes[0] = -(index+1);
+ daughter.fKinkIndexes[0] = index+1;
+ if (mother.fN>50) {
+ delete array->RemoveAt(i);
+ array->AddAt(new AliTPCseed(mother),i);
+ }
+ else{
+ array->AddLast(new AliTPCseed(mother));
+ }
+ array->AddLast(new AliTPCseed(daughter));
+ for (Int_t icl=0;icl<row0;icl++) {
+ if (mother.fClusterPointer[icl]) mother.fClusterPointer[icl]->Use(20);
+ }
+ //
+ for (Int_t icl=row0;icl<158;icl++) {
+ if (daughter.fClusterPointer[icl]) daughter.fClusterPointer[icl]->Use(20);
+ }
+ //
+ }
+ delete pmother;
+ delete pdaughter;
+ delete pkink;
+ }
+
+ delete [] daughters;
+ delete [] mothers;
+ //
+ //
+ delete [] dca;
+ delete []circular;
+ delete []shared;
+ delete []quality;
+ delete []indexes;
+ //
+ delete kink;
+ delete[]fim;
+ delete[] zm;
+ delete[] z0;
+ delete [] usage;
+ delete[] alpha;
+ delete[] nclusters;
+ delete[] sign;
+ delete[] helixes;
+ kinks->Delete();
+ delete kinks;
+
+ printf("Ncandidates=\t%d\t%d\t%d\t%d\n",esd->GetNumberOfKinks(),ncandidates,ntracks,nall);
+ timer.Print();
+}
+
+void AliTPCtrackerMI::FindV0s(TObjArray * array, AliESD *esd)
+{
+ //
+ // find V0s
+ //
+ //
+ TObjArray *tpcv0s = new TObjArray(100000);
+ Int_t nentries = array->GetEntriesFast();
+ AliHelix *helixes = new AliHelix[nentries];
+ Int_t *sign = new Int_t[nentries];
+ Float_t *alpha = new Float_t[nentries];
+ Float_t *z0 = new Float_t[nentries];
+ Float_t *dca = new Float_t[nentries];
+ Float_t *sdcar = new Float_t[nentries];
+ Float_t *cdcar = new Float_t[nentries];
+ Float_t *pulldcar = new Float_t[nentries];
+ Float_t *pulldcaz = new Float_t[nentries];
+ Float_t *pulldca = new Float_t[nentries];
+ Bool_t *isPrim = new Bool_t[nentries];
+ const AliESDVertex * primvertex = esd->GetVertex();
+ Double_t zvertex = primvertex->GetZv();
+ //
+ // nentries = array->GetEntriesFast();
+ //
+ for (Int_t i=0;i<nentries;i++){
+ sign[i]=0;
+ isPrim[i]=0;
+ AliTPCseed* track = (AliTPCseed*)array->At(i);
+ if (!track) continue;
+ track->GetV0Indexes()[0] = 0; //rest v0 indexes
+ track->GetV0Indexes()[1] = 0; //rest v0 indexes
+ track->GetV0Indexes()[2] = 0; //rest v0 indexes
+ //
+ alpha[i] = track->GetAlpha();
+ new (&helixes[i]) AliHelix(*track);
+ Double_t xyz[3];
+ helixes[i].Evaluate(0,xyz);
+ sign[i] = (track->GetC()>0) ? -1:1;
+ Double_t x,y,z;
+ x=160;
+ z0[i]=1000;
+ if (track->GetProlongation(0,y,z)) z0[i] = z;
+ dca[i] = track->GetD(0,0);
+ //
+ // dca error parrameterezation + pulls
+ //
+ sdcar[i] = TMath::Sqrt(0.150*0.150+(100*track->fP4)*(100*track->fP4));
+ if (TMath::Abs(track->fP3)>1) sdcar[i]*=2.5;
+ cdcar[i] = TMath::Exp((TMath::Abs(track->fP4)-0.0106)*525.3);
+ pulldcar[i] = (dca[i]-cdcar[i])/sdcar[i];
+ pulldcaz[i] = (z0[i]-zvertex)/sdcar[i];
+ pulldca[i] = TMath::Sqrt(pulldcar[i]*pulldcar[i]+pulldcaz[i]*pulldcaz[i]);
+ if (track->fTPCr[1]+track->fTPCr[2]+track->fTPCr[3]>0.5) {
+ if (pulldca[i]<3.) isPrim[i]=kTRUE; //pion, muon and Kaon 3 sigma cut
+ }
+ if (track->fTPCr[4]>0.5) {
+ if (pulldca[i]<0.5) isPrim[i]=kTRUE; //proton 0.5 sigma cut
+ }
+ if (track->fTPCr[0]>0.4) {
+ isPrim[i]=kFALSE; //electron no sigma cut
+ }
+ }
+ //
+ //
+ TStopwatch timer;
+ timer.Start();
+ Int_t ncandidates =0;
+ Int_t nall =0;
+ Int_t ntracks=0;
+ Double_t phase[2][2],radius[2];
+ //
+ // Finf V0s loop
+ //
+ //
+ // //
+ TTreeSRedirector &cstream = *fDebugStreamer;
+ Float_t fprimvertex[3]={GetX(),GetY(),GetZ()};
+ AliESDV0MI vertex;
+ Double_t cradius0 = 10*10;
+ Double_t cradius1 = 200*200;
+ Double_t cdist1=3.;
+ Double_t cdist2=4.;
+ Double_t cpointAngle = 0.95;
+ //
+ Double_t delta[2]={10000,10000};
+ for (Int_t i =0;i<nentries;i++){
+ if (sign[i]==0) continue;
+ AliTPCseed * track0 = (AliTPCseed*)array->At(i);
+ if (!track0) continue;
+ cstream<<"Tracks"<<
+ "Tr0.="<<track0<<
+ "dca="<<dca[i]<<
+ "z0="<<z0[i]<<
+ "zvertex="<<zvertex<<
+ "sdcar0="<<sdcar[i]<<
+ "cdcar0="<<cdcar[i]<<
+ "pulldcar0="<<pulldcar[i]<<
+ "pulldcaz0="<<pulldcaz[i]<<
+ "pulldca0="<<pulldca[i]<<
+ "isPrim="<<isPrim[i]<<
+ "\n";
+ //
+ if (track0->fP4<0) continue;
+ if (track0->GetKinkIndex(0)>0||isPrim[i]) continue; //daughter kink
+ //
+ if (TMath::Abs(helixes[i].GetHelix(4))<0.000000001) continue;
+ ntracks++;
+ // debug output
+
+
+ for (Int_t j =0;j<nentries;j++){
+ AliTPCseed * track1 = (AliTPCseed*)array->At(j);
+ if (!track1) continue;
+ if (track1->GetKinkIndex(0)>0 || isPrim[j]) continue; //daughter kink
+ if (sign[j]*sign[i]>0) continue;
+ if (TMath::Abs(helixes[j].GetHelix(4))<0.000001) continue;
+ if (track0->fCircular+track1->fCircular>1) continue; //circling -returning track
+ nall++;
+ //
+ // DCA to prim vertex cut
+ //
+ //
+ delta[0]=10000;
+ delta[1]=10000;
+
+ Int_t npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,cdist2);
+ if (npoints<1) continue;
+ Int_t iclosest=0;
+ // cuts on radius
+ if (npoints==1){
+ if (radius[0]<cradius0||radius[0]>cradius1) continue;
+ helixes[i].LinearDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta[0]);
+ if (delta[0]>cdist1) continue;
+ }
+ else{
+ if (TMath::Max(radius[0],radius[1])<cradius0|| TMath::Min(radius[0],radius[1])>cradius1) continue;
+ helixes[i].LinearDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta[0]);
+ helixes[i].LinearDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta[1]);
+ if (delta[1]<delta[0]) iclosest=1;
+ if (delta[iclosest]>cdist1) continue;
+ }
+ helixes[i].ParabolicDCA(helixes[j],phase[iclosest][0],phase[iclosest][1],radius[iclosest],delta[iclosest]);
+ if (radius[iclosest]<cradius0 || radius[iclosest]>cradius1 || delta[iclosest]>cdist1) continue;
+ //
+ Double_t pointAngle = helixes[i].GetPointAngle(helixes[j],phase[iclosest],fprimvertex);
+ if (pointAngle<cpointAngle) continue;
+ //
+ Bool_t isGamma = kFALSE;
+ vertex.SetP(*track0); //track0 - plus
+ vertex.SetM(*track1); //track1 - minus
+ vertex.Update(fprimvertex);
+ if (track0->fTPCr[0]>0.3&&track1->fTPCr[0]>0.3&&vertex.GetAnglep()[2]<0.15) isGamma=kTRUE; // gamma conversion candidate
+ Double_t pointAngle2 = vertex.GetPointAngle();
+ //continue;
+ if (vertex.GetPointAngle()<cpointAngle && (!isGamma)) continue; // point angle cut
+ if (vertex.GetDist2()>2&&(!isGamma)) continue; // point angle cut
+ Float_t sigmae = 0.15*0.15;
+ if (vertex.GetRr()<80)
+ sigmae += (sdcar[i]*sdcar[i]+sdcar[j]*sdcar[j])*(1.-vertex.GetRr()/80.)*(1.-vertex.GetRr()/80.);
+ sigmae+= TMath::Sqrt(sigmae);
+ if (vertex.GetDist2()/sigmae>3.&&(!isGamma)) continue;
+ Float_t densb0=0,densb1=0,densa0=0,densa1=0;
+ Int_t row0 = GetRowNumber(vertex.GetRr());
+ if (row0>15){
+ if (vertex.GetDist2()>0.2) continue;
+ densb0 = track0->Density2(0,row0-5);
+ densb1 = track1->Density2(0,row0-5);
+ if (densb0>0.3|| densb1>0.3) continue; //clusters before vertex
+ densa0 = track0->Density2(row0+5,row0+40);
+ densa1 = track1->Density2(row0+5,row0+40);
+ if ((densa0<0.4|| densa1<0.4)&&(!isGamma)) continue; //missing clusters after vertex
+ }
+ else{
+ densa0 = track0->Density2(0,40); //cluster density
+ densa1 = track1->Density2(0,40); //cluster density
+ if ((vertex.GetRr()<80&&densa0+densa1<1.)&&(!isGamma)) continue;
+ }
+ vertex.SetLab(0,track0->GetLabel());
+ vertex.SetLab(1,track1->GetLabel());
+ vertex.SetChi2After((densa0+densa1)*0.5);
+ vertex.SetChi2Before((densb0+densb1)*0.5);
+ vertex.SetIndex(0,i);
+ vertex.SetIndex(1,j);
+ vertex.SetStatus(1); // TPC v0 candidate
+ vertex.SetRp(track0->fTPCr);
+ vertex.SetRm(track1->fTPCr);
+ tpcv0s->AddLast(new AliESDV0MI(vertex));
+ ncandidates++;
+ {
+ Int_t eventNr = esd->GetEventNumber();
+ Double_t radiusm= (delta[0]<delta[1])? TMath::Sqrt(radius[0]):TMath::Sqrt(radius[1]);
+ Double_t deltam= (delta[0]<delta[1])? TMath::Sqrt(delta[0]):TMath::Sqrt(delta[1]);
+ cstream<<"V0"<<
+ "Event="<<eventNr<<
+ "vertex.="<<&vertex<<
+ "Tr0.="<<track0<<
+ "lab0="<<track0->fLab<<
+ "Helix0.="<<&helixes[i]<<
+ "Tr1.="<<track1<<
+ "lab1="<<track1->fLab<<
+ "Helix1.="<<&helixes[j]<<
+ "pointAngle="<<pointAngle<<
+ "pointAngle2="<<pointAngle2<<
+ "dca0="<<dca[i]<<
+ "dca1="<<dca[j]<<
+ "z0="<<z0[i]<<
+ "z1="<<z0[j]<<
+ "zvertex="<<zvertex<<
+ "circular0="<<track0->fCircular<<
+ "circular1="<<track1->fCircular<<
+ "npoints="<<npoints<<
+ "radius0="<<radius[0]<<
+ "delta0="<<delta[0]<<
+ "radius1="<<radius[1]<<
+ "delta1="<<delta[1]<<
+ "radiusm="<<radiusm<<
+ "deltam="<<deltam<<
+ "sdcar0="<<sdcar[i]<<
+ "sdcar1="<<sdcar[j]<<
+ "cdcar0="<<cdcar[i]<<
+ "cdcar1="<<cdcar[j]<<
+ "pulldcar0="<<pulldcar[i]<<
+ "pulldcar1="<<pulldcar[j]<<
+ "pulldcaz0="<<pulldcaz[i]<<
+ "pulldcaz1="<<pulldcaz[j]<<
+ "pulldca0="<<pulldca[i]<<
+ "pulldca1="<<pulldca[j]<<
+ "densb0="<<densb0<<
+ "densb1="<<densb1<<
+ "densa0="<<densa0<<
+ "densa1="<<densa1<<
+ "sigmae="<<sigmae<<
+ "\n";
+ }
+ }
+ }
+ Float_t *quality = new Float_t[ncandidates];
+ Int_t *indexes = new Int_t[ncandidates];
+ Int_t naccepted =0;
+ for (Int_t i=0;i<ncandidates;i++){
+ quality[i] = 0;
+ AliESDV0MI *v0 = (AliESDV0MI*)tpcv0s->At(i);
+ quality[i] = 1./(1.00001-v0->GetPointAngle()); //base point angle
+ // quality[i] /= (0.5+v0->GetDist2());
+ // quality[i] *= v0->GetChi2After(); //density factor
+ Double_t minpulldca = TMath::Min(2.+pulldca[v0->GetIndex(0)],(2.+pulldca[v0->GetIndex(1)]) ); //pull
+ Int_t index0 = v0->GetIndex(0);
+ Int_t index1 = v0->GetIndex(1);
+ AliTPCseed * track0 = (AliTPCseed*)array->At(index0);
+ AliTPCseed * track1 = (AliTPCseed*)array->At(index1);
+ if (track0->fTPCr[0]>0.3&&track1->fTPCr[0]>0.3&&v0->GetAnglep()[2]<0.15) quality[i]+=1000000; // gamma conversion candidate
+ if (track0->fTPCr[4]>0.9||track1->fTPCr[4]>0.9&&minpulldca>4) quality[i]*=10; // lambda candidate candidate
+ }
+
+ TMath::Sort(ncandidates,quality,indexes,kTRUE);
+ //
+ //
+ for (Int_t i=0;i<ncandidates;i++){
+ AliESDV0MI * v0 = (AliESDV0MI*)tpcv0s->At(indexes[i]);
+ if (!v0) continue;
+ Int_t index0 = v0->GetIndex(0);
+ Int_t index1 = v0->GetIndex(1);
+ AliTPCseed * track0 = (AliTPCseed*)array->At(index0);
+ AliTPCseed * track1 = (AliTPCseed*)array->At(index1);
+ if (!track0||!track1) {
+ printf("Bug\n");
+ continue;
+ }
+ Bool_t accept =kTRUE; //default accept
+ Int_t *v0indexes0 = track0->GetV0Indexes();
+ Int_t *v0indexes1 = track1->GetV0Indexes();
+ //
+ Int_t order0 = (v0indexes0[0]!=0) ? 1:0;
+ Int_t order1 = (v0indexes1[0]!=0) ? 1:0;
+ if (v0indexes0[1]!=0) order0 =2;
+ if (v0indexes1[1]!=0) order1 =2;
+ //
+ if (v0indexes0[2]!=0) {order0=3; accept=kFALSE;}
+ if (v0indexes0[2]!=0) {order1=3; accept=kFALSE;}
+ //
+ AliESDV0MI * v02 = v0;
+ if (accept){
+ v0->SetOrder(0,order0);
+ v0->SetOrder(1,order1);
+ v0->SetOrder(1,order0+order1);
+ Int_t index = esd->AddV0MI(v0);
+ v02 = esd->GetV0MI(index);
+ v0indexes0[order0]=index;
+ v0indexes1[order1]=index;
+ naccepted++;
+ }
+ {
+ Int_t eventNr = esd->GetEventNumber();
+ cstream<<"V02"<<
+ "Event="<<eventNr<<
+ "vertex.="<<v0<<
+ "vertex2.="<<v02<<
+ "Tr0.="<<track0<<
+ "lab0="<<track0->fLab<<
+ "Tr1.="<<track1<<
+ "lab1="<<track1->fLab<<
+ "dca0="<<dca[index0]<<
+ "dca1="<<dca[index1]<<
+ "order0="<<order0<<
+ "order1="<<order1<<
+ "accept="<<accept<<
+ "quality="<<quality[i]<<
+ "pulldca0="<<pulldca[index0]<<
+ "pulldca1="<<pulldca[index1]<<
+ "index="<<i<<
+ "\n";
+ }
+ }
+
+
+ //
+ //
+ delete []quality;
+ delete []indexes;
+//
+ delete [] isPrim;
+ delete [] pulldca;
+ delete [] pulldcaz;
+ delete [] pulldcar;
+ delete [] cdcar;
+ delete [] sdcar;
+ delete [] dca;
+ //
+ delete[] z0;
+ delete[] alpha;
+ delete[] sign;
+ delete[] helixes;
+ printf("TPC V0 finder : naccepted\t%d\tncandidates\t%d\tntracks\t%d\tnall\t%d\n",naccepted,ncandidates,ntracks,nall);
+ timer.Print();
+}
+
+Int_t AliTPCtrackerMI::RefitKink(AliTPCseed &mother, AliTPCseed &daughter, AliESDkink &kink)
+{
+ //
+ // refit kink towards to the vertex
+ //
+ //
+ Int_t row0 = GetRowNumber(kink.GetR());
+ FollowProlongation(mother,0);
+ mother.Reset(kFALSE);
+ //
+ FollowProlongation(daughter,row0);
+ daughter.Reset(kFALSE);
+ FollowBackProlongation(daughter,158);
+ daughter.Reset(kFALSE);
+ Int_t first = TMath::Max(row0-20,30);
+ Int_t last = TMath::Min(row0+20,140);
+ //
+ const Int_t kNdiv =5;
+ AliTPCseed param0[kNdiv]; // parameters along the track
+ AliTPCseed param1[kNdiv]; // parameters along the track
+ AliESDkink kinks[kNdiv]; // corresponding kink parameters
+ //
+ Int_t rows[kNdiv];
+ for (Int_t irow=0; irow<kNdiv;irow++){
+ rows[irow] = first +((last-first)*irow)/(kNdiv-1);
+ }
+ // store parameters along the track
+ //
+ for (Int_t irow=0;irow<kNdiv;irow++){
+ FollowBackProlongation(mother, rows[irow]);
+ FollowProlongation(daughter,rows[kNdiv-1-irow]);
+ new(¶m0[irow]) AliTPCseed(mother);
+ new(¶m1[kNdiv-1-irow]) AliTPCseed(daughter);
+ }
+ //
+ // define kinks
+ for (Int_t irow=0; irow<kNdiv-1;irow++){
+ if (param0[irow].fN<kNdiv||param1[irow].fN<kNdiv) continue;
+ kinks[irow].SetMother(param0[irow]);
+ kinks[irow].SetDaughter(param1[irow]);
+ kinks[irow].Update();
+ }
+ //
+ // choose kink with best "quality"
+ Int_t index =-1;
+ Double_t mindist = 10000;
+ for (Int_t irow=0;irow<kNdiv;irow++){
+ if (param0[irow].fN<20||param1[irow].fN<20) continue;
+ if (TMath::Abs(kinks[irow].GetR())>240.) continue;
+ if (TMath::Abs(kinks[irow].GetR())<100.) continue;
+ //
+ Float_t normdist = TMath::Abs(param0[irow].fX-kinks[irow].GetR())*(0.1+kink.GetDistance());
+ normdist/= (param0[irow].fN+param1[irow].fN+40.);
+ if (normdist < mindist){
+ mindist = normdist;
+ index = irow;
+ }
+ }
+ //
+ if (index==-1) return 0;
+ //
+ //
+ param0[index].Reset(kTRUE);
+ FollowProlongation(param0[index],0);
+ //
+ new (&mother) AliTPCseed(param0[index]);
+ new (&daughter) AliTPCseed(param1[index]); // daughter in vertex
+ //
+ kink.SetMother(mother);
+ kink.SetDaughter(daughter);
+ kink.Update();
+ kink.SetTPCRow0(GetRowNumber(kink.GetR()));
+ kink.SetTPCncls(param0[index].fN,0);
+ kink.SetTPCncls(param1[index].fN,1);
+ kink.SetLabel(CookLabel(&mother,0.4, 0,kink.GetTPCRow0()),0);
+ kink.SetLabel(CookLabel(&daughter,0.4, kink.GetTPCRow0(),160),1);
+ mother.SetLabel(kink.GetLabel(0));
+ daughter.SetLabel(kink.GetLabel(1));
+
+ return 1;
+}
+
+
+void AliTPCtrackerMI::UpdateKinkQualityM(AliTPCseed * seed){
+ //
+ // update Kink quality information for mother after back propagation
+ //
+ if (seed->GetKinkIndex(0)>=0) return;
+ for (Int_t ikink=0;ikink<3;ikink++){
+ Int_t index = seed->GetKinkIndex(ikink);
+ if (index>=0) break;
+ index = TMath::Abs(index)-1;
+ AliESDkink * kink = fEvent->GetKink(index);
+ //kink->fTPCdensity2[0][0]=-1;
+ //kink->fTPCdensity2[0][1]=-1;
+ kink->SetTPCDensity2(-1,0,0);
+ kink->SetTPCDensity2(1,0,1);
+ //
+ Int_t row0 = kink->GetTPCRow0() - 2 - Int_t( 0.5/ (0.05+kink->GetAngle(2)));
+ if (row0<15) row0=15;
+ //
+ Int_t row1 = kink->GetTPCRow0() + 2 + Int_t( 0.5/ (0.05+kink->GetAngle(2)));
+ if (row1>145) row1=145;
+ //
+ Int_t found,foundable,shared;
+ seed->GetClusterStatistic(0,row0, found, foundable,shared,kFALSE);
+ if (foundable>5) kink->SetTPCDensity2(Float_t(found)/Float_t(foundable),0,0);
+ seed->GetClusterStatistic(row1,155, found, foundable,shared,kFALSE);
+ if (foundable>5) kink->SetTPCDensity2(Float_t(found)/Float_t(foundable),0,1);
+ }
+
+}
+
+void AliTPCtrackerMI::UpdateKinkQualityD(AliTPCseed * seed){
+ //
+ // update Kink quality information for daughter after refit
+ //
+ if (seed->GetKinkIndex(0)<=0) return;
+ for (Int_t ikink=0;ikink<3;ikink++){
+ Int_t index = seed->GetKinkIndex(ikink);
+ if (index<=0) break;
+ index = TMath::Abs(index)-1;
+ AliESDkink * kink = fEvent->GetKink(index);
+ kink->SetTPCDensity2(-1,1,0);
+ kink->SetTPCDensity2(-1,1,1);
+ //
+ Int_t row0 = kink->GetTPCRow0() -2 - Int_t( 0.5/ (0.05+kink->GetAngle(2)));
+ if (row0<15) row0=15;
+ //
+ Int_t row1 = kink->GetTPCRow0() +2 + Int_t( 0.5/ (0.05+kink->GetAngle(2)));
+ if (row1>145) row1=145;
+ //
+ Int_t found,foundable,shared;
+ seed->GetClusterStatistic(0,row0, found, foundable,shared,kFALSE);
+ if (foundable>5) kink->SetTPCDensity2(Float_t(found)/Float_t(foundable),1,0);
+ seed->GetClusterStatistic(row1,155, found, foundable,shared,kFALSE);
+ if (foundable>5) kink->SetTPCDensity2(Float_t(found)/Float_t(foundable),1,1);
+ }
+
+}
+
+
+Int_t AliTPCtrackerMI::CheckKinkPoint(AliTPCseed*seed,AliTPCseed &mother, AliTPCseed &daughter, AliESDkink &kink)
+{
+ //
+ // check kink point for given track
+ // if return value=0 kink point not found
+ // otherwise seed0 correspond to mother particle
+ // seed1 correspond to daughter particle
+ // kink parameter of kink point
+
+ Int_t middlerow = (seed->fFirstPoint+seed->fLastPoint)/2;
+ Int_t first = seed->fFirstPoint;
+ Int_t last = seed->fLastPoint;
+ if (last-first<20) return 0; // shortest length - 2*30 = 60 pad-rows
+
+
+ AliTPCseed *seed1 = ReSeed(seed,middlerow+20, kTRUE); //middle of chamber
+ if (!seed1) return 0;
+ FollowProlongation(*seed1,seed->fLastPoint-20);
+ seed1->Reset(kTRUE);
+ FollowProlongation(*seed1,158);
+ seed1->Reset(kTRUE);
+ last = seed1->fLastPoint;
+ //
+ AliTPCseed *seed0 = new AliTPCseed(*seed);
+ seed0->Reset(kFALSE);
+ seed0->Reset();
+ //
+ AliTPCseed param0[20]; // parameters along the track
+ AliTPCseed param1[20]; // parameters along the track
+ AliESDkink kinks[20]; // corresponding kink parameters
+ Int_t rows[20];
+ for (Int_t irow=0; irow<20;irow++){
+ rows[irow] = first +((last-first)*irow)/19;
+ }
+ // store parameters along the track
+ //
+ for (Int_t irow=0;irow<20;irow++){
+ FollowBackProlongation(*seed0, rows[irow]);
+ FollowProlongation(*seed1,rows[19-irow]);
+ new(¶m0[irow]) AliTPCseed(*seed0);
+ new(¶m1[19-irow]) AliTPCseed(*seed1);
+ }
+ //
+ // define kinks
+ for (Int_t irow=0; irow<19;irow++){
+ kinks[irow].SetMother(param0[irow]);
+ kinks[irow].SetDaughter(param1[irow]);
+ kinks[irow].Update();
+ }
+ //
+ // choose kink with biggest change of angle
+ Int_t index =-1;
+ Double_t maxchange= 0;
+ for (Int_t irow=1;irow<19;irow++){
+ if (TMath::Abs(kinks[irow].GetR())>240.) continue;
+ if (TMath::Abs(kinks[irow].GetR())<110.) continue;
+ Float_t quality = TMath::Abs(kinks[irow].GetAngle(2))/(3.+TMath::Abs(kinks[irow].GetR()-param0[irow].fX));
+ if ( quality > maxchange){
+ maxchange = quality;
+ index = irow;
+ //
+ }
+ }
+ delete seed0;
+ delete seed1;
+ if (index<0) return 0;
+ //
+ Int_t row0 = GetRowNumber(kinks[index].GetR()); //row 0 estimate
+ seed0 = new AliTPCseed(param0[index]);
+ seed1 = new AliTPCseed(param1[index]);
+ seed0->Reset(kFALSE);
+ seed1->Reset(kFALSE);
+ seed0->ResetCovariance();
+ seed1->ResetCovariance();
+ FollowProlongation(*seed0,0);
+ FollowBackProlongation(*seed1,158);
+ new (&mother) AliTPCseed(*seed0); // backup mother at position 0
+ seed0->Reset(kFALSE);
+ seed1->Reset(kFALSE);
+ seed0->ResetCovariance();
+ seed1->ResetCovariance();
+ //
+ first = TMath::Max(row0-20,0);
+ last = TMath::Min(row0+20,158);
+ //
+ for (Int_t irow=0; irow<20;irow++){
+ rows[irow] = first +((last-first)*irow)/19;
+ }
+ // store parameters along the track
+ //
+ for (Int_t irow=0;irow<20;irow++){
+ FollowBackProlongation(*seed0, rows[irow]);
+ FollowProlongation(*seed1,rows[19-irow]);
+ new(¶m0[irow]) AliTPCseed(*seed0);
+ new(¶m1[19-irow]) AliTPCseed(*seed1);
+ }
+ //
+ // define kinks
+ for (Int_t irow=0; irow<19;irow++){
+ kinks[irow].SetMother(param0[irow]);
+ kinks[irow].SetDaughter(param1[irow]);
+ // param0[irow].Dump();
+ //param1[irow].Dump();
+ kinks[irow].Update();
+ }
+ //
+ // choose kink with biggest change of angle
+ index =-1;
+ maxchange= 0;
+ for (Int_t irow=0;irow<20;irow++){
+ if (TMath::Abs(kinks[irow].GetR())>250.) continue;
+ if (TMath::Abs(kinks[irow].GetR())<90.) continue;
+ Float_t quality = TMath::Abs(kinks[irow].GetAngle(2))/(3.+TMath::Abs(kinks[irow].GetR()-param0[irow].fX));
+ if ( quality > maxchange){
+ maxchange = quality;
+ index = irow;
+ //
+ }
+ }
+ //
+ //
+ if (index==-1 || param0[index].fN+param1[index].fN<100){
+ delete seed0;
+ delete seed1;
+ return 0;
+ }
+ // Float_t anglesigma = TMath::Sqrt(param0[index].fC22+param0[index].fC33+param1[index].fC22+param1[index].fC33);
+
+ kink.SetMother(param0[index]);
+ kink.SetDaughter(param1[index]);
+ kink.Update();
+ row0 = GetRowNumber(kink.GetR());
+ kink.SetTPCRow0(row0);
+ kink.SetLabel(CookLabel(seed0,0.5,0,row0),0);
+ kink.SetLabel(CookLabel(seed1,0.5,row0,158),1);
+ kink.SetIndex(-10,0);
+ kink.SetIndex(int(param0[index].fN+param1[index].fN),1);
+ kink.SetTPCncls(param0[index].fN,0);
+ kink.SetTPCncls(param1[index].fN,1);
+ //
+ //
+ // new (&mother) AliTPCseed(param0[index]);
+ new (&daughter) AliTPCseed(param1[index]);
+ daughter.SetLabel(kink.GetLabel(1));
+ param0[index].Reset(kTRUE);
+ FollowProlongation(param0[index],0);
+ new (&mother) AliTPCseed(param0[index]);
+ mother.SetLabel(kink.GetLabel(0));
+ delete seed0;
+ delete seed1;
+ //
+ return 1;
+}
+
+
+
+
+AliTPCseed* AliTPCtrackerMI::ReSeed(AliTPCseed *t)
+{
+ //
+ // reseed - refit - track
+ //
+ Int_t first = 0;
+ // Int_t last = fSectors->GetNRows()-1;
+ //
+ if (fSectors == fOuterSec){
+ first = TMath::Max(first, t->fFirstPoint-fInnerSec->GetNRows());
+ //last =
+ }
+ else
+ first = t->fFirstPoint;
+ //
+ AliTPCseed * seed = MakeSeed(t,0.1,0.5,0.9);
+ FollowBackProlongation(*t,fSectors->GetNRows()-1);
+ t->Reset(kFALSE);
+ FollowProlongation(*t,first);
+ return seed;
+}
+
+
+
+
+
+
+
+//_____________________________________________________________________________
+Int_t AliTPCtrackerMI::ReadSeeds(const TFile *inp) {
+ //-----------------------------------------------------------------
+ // This function reades track seeds.
+ //-----------------------------------------------------------------
+ TDirectory *savedir=gDirectory;
+
TFile *in=(TFile*)inp;
if (!in->IsOpen()) {
cerr<<"AliTPCtrackerMI::ReadSeeds(): input file is not open !\n";
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()));
+ fSeeds->AddLast(new AliTPCseed(*seed/*,seed->GetAlpha()*/));
}
delete seed;
Int_t AliTPCtrackerMI::Clusters2Tracks (AliESD *esd)
{
//
+ if (fSeeds) DeleteSeeds();
fEvent = esd;
Clusters2Tracks();
if (!fSeeds) return 1;
fIteration = 0;
fSeeds = Tracking();
-
- printf("Time for tracking: \t");timer.Print();timer.Start();
-
+ if (fDebug>0){
+ Info("Clusters2Tracks","Time for tracking: \t");timer.Print();timer.Start();
+ }
//activate again some tracks
for (Int_t i=0; i<fSeeds->GetEntriesFast(); i++) {
AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
if (nc<20) {
delete fSeeds->RemoveAt(i);
continue;
- }
+ }
+ CookLabel(pt,0.1);
if (pt->fRemoval==10) {
if (pt->GetDensityFirst(20)>0.8 || pt->GetDensityFirst(30)>0.8 || pt->GetDensityFirst(40)>0.7)
pt->Desactivate(10); // make track again active
}
}
}
- RemoveDouble(fSeeds,0.2,0.6,11);
- RemoveUsed(fSeeds,0.5,0.5,6);
-
//
+ RemoveUsed2(fSeeds,0.85,0.85,0);
+ FindKinks(fSeeds,fEvent);
+ RemoveUsed2(fSeeds,0.5,0.4,20);
+ // //
+// // refit short tracks
+// //
Int_t nseed=fSeeds->GetEntriesFast();
+// for (Int_t i=0; i<nseed; i++) {
+// AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
+// if (!pt) continue;
+// Int_t nc=t.GetNumberOfClusters();
+// if (nc<15) {
+// delete fSeeds->RemoveAt(i);
+// continue;
+// }
+// if (pt->GetKinkIndexes()[0]!=0) continue; // ignore kink candidates
+// if (nc>100) continue; // hopefully, enough for ITS
+// AliTPCseed *seed2 = new AliTPCseed(*pt);
+// //seed2->Reset(kFALSE);
+// //pt->ResetCovariance();
+// seed2->Modify(1);
+// FollowBackProlongation(*seed2,158);
+// //seed2->Reset(kFALSE);
+// seed2->Modify(10);
+// FollowProlongation(*seed2,0);
+// TTreeSRedirector &cstream = *fDebugStreamer;
+// cstream<<"Crefit"<<
+// "Tr0.="<<pt<<
+// "Tr1.="<<seed2<<
+// "\n";
+// if (seed2->fN>pt->fN){
+// delete fSeeds->RemoveAt(i);
+// fSeeds->AddAt(seed2,i);
+// }else{
+// delete seed2;
+// }
+// }
+// RemoveUsed2(fSeeds,0.6,0.6,50);
+
+// FindV0s(fSeeds,fEvent);
+ //RemoveDouble(fSeeds,0.2,0.6,11);
+
+ //
Int_t found = 0;
for (Int_t i=0; i<nseed; i++) {
AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
CookLabel(pt,0.1); //For comparison only
//if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
if ((pt->IsActive() || (pt->fRemoval==10) )){
- cerr<<found++<<'\r';
+ found++;
+ if (fDebug>0) cerr<<found<<'\r';
pt->fLab2 = i;
}
else
// CheckKinkPoint(&t,0.05);
//if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
if ((pt->IsActive() || (pt->fRemoval==10) )){
- cerr<<found++<<'\r';
+ found++;
+ if (fDebug>0){
+ cerr<<found<<'\r';
+ }
pt->fLab2 = i;
}
else
SortTracks(fSeeds, 1);
- /*
+ /*
fIteration = 1;
- PrepareForBackProlongation(fSeeds,0.5);
+ PrepareForBackProlongation(fSeeds,5.);
PropagateBack(fSeeds);
printf("Time for back propagation: \t");timer.Print();timer.Start();
fIteration = 2;
- PrepareForProlongation(fSeeds,1.);
- PropagateForward();
+ PrepareForProlongation(fSeeds,5.);
+ PropagateForward2(fSeeds);
printf("Time for FORWARD propagation: \t");timer.Print();timer.Start();
// RemoveUsed(fSeeds,0.7,0.7,6);
*/
// fNTracks = found;
- printf("Time for overlap removal, track writing and dedx cooking: \t"); timer.Print();timer.Start();
+ if (fDebug>0){
+ Info("Clusters2Tracks","Time for overlap removal, track writing and dedx cooking: \t"); timer.Print();timer.Start();
+ }
//
- cerr<<"Number of found tracks : "<<"\t"<<found<<endl;
+ // cerr<<"Number of found tracks : "<<"\t"<<found<<endl;
+ Info("Clusters2Tracks","Number of found tracks %d",found);
savedir->cd();
// UnloadClusters();
//
if (seedtype==2) MakeSeeds2(arr,sec,i1,i2,cuts,dy);
}
if (fDebug>0){
- printf("\nSeeding - %d\t%d\t%d\t%d\n",seedtype,i1,i2,arr->GetEntriesFast());
+ Info("Tracking","\nSeeding - %d\t%d\t%d\t%d\n",seedtype,i1,i2,arr->GetEntriesFast());
timer.Print();
timer.Start();
}
fdensity = 2.;
if (fDebug>0){
- printf("\n\nPrimary seeding\t%d\n\n",seeds->GetEntriesFast());
+ Info("Tracking()","\n\nPrimary seeding\t%d\n\n",seeds->GetEntriesFast());
timer.Print();
timer.Start();
}
cuts[0]=0.0080;
// find secondaries
- for (Int_t delta = 30; delta<70; delta+=10){
+ for (Int_t delta = 30; delta<90; delta+=10){
//
cuts[0] = 0.3;
- cuts[1] = 1.5;
+ cuts[1] = 3.5;
cuts[2] = 3.;
- cuts[3] = 1.5;
+ cuts[3] = 3.5;
arr = Tracking(4,nup-1-delta,nup-1-delta-gap,cuts,-1);
SumTracks(seeds,arr);
SignClusters(seeds,fnumber,fdensity);
}
if (fDebug>0){
- printf("\n\nSecondary seeding\t%d\n\n",seeds->GetEntriesFast());
+ Info("Tracking()","\n\nSecondary seeding\t%d\n\n",seeds->GetEntriesFast());
timer.Print();
timer.Start();
}
//
- for (Int_t nr=rfirst; nr>=rlast; nr--){
+ for (Int_t nr=rfirst; nr>=rlast; nr--){
+ if (nr<fInnerSec->GetNRows())
+ fSectors = fInnerSec;
+ else
+ fSectors = fOuterSec;
// make indexes with the cluster tracks for given
// find nearest cluster
for (Int_t i=0; i<nseed; i++) {
AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i), &t=*pt;
if (!pt) continue;
+ if (nr==80) pt->UpdateReference();
if (!pt->IsActive()) continue;
// if ( (fSectors ==fOuterSec) && (pt->fFirstPoint-fParam->GetNRowLow())<nr) continue;
if (pt->fRelativeSector>17) {
Int_t nseed= arr->GetEntriesFast();
for (Int_t i=0;i<nseed;i++){
AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
- if (pt) {
- AliTPCseed *pt2 = new AliTPCseed(*pt);
+ if (pt&& pt->GetKinkIndex(0)<=0) {
+ //AliTPCseed *pt2 = new AliTPCseed(*pt);
fSectors = fInnerSec;
//FollowBackProlongation(*pt,fInnerSec->GetNRows()-1);
//fSectors = fOuterSec;
- FollowBackProlongation(*pt,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1);
-
- if (pt->GetNumberOfClusters()<20 && pt->GetLabel()>0 ){
- printf("\n%d",pt->GetLabel());
- fSectors = fInnerSec;
- //FollowBackProlongation(*pt2,fInnerSec->GetNRows()-1);
- //fSectors = fOuterSec;
- FollowBackProlongation(*pt2,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1);
- }
- }
+ FollowBackProlongation(*pt,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1);
+ //if (pt->GetNumberOfClusters()<(pt->fEsd->GetTPCclusters(0)) ){
+ // Error("PropagateBack","Not prolonged track %d",pt->GetLabel());
+ // FollowBackProlongation(*pt2,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1);
+ //}
+ }
+ if (pt&& pt->GetKinkIndex(0)>0) {
+ AliESDkink * kink = fEvent->GetKink(pt->GetKinkIndex(0)-1);
+ pt->fFirstPoint = kink->GetTPCRow0();
+ fSectors = fInnerSec;
+ FollowBackProlongation(*pt,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1);
+ }
+
}
return 0;
}
// make forward propagation
//
Int_t nseed= arr->GetEntriesFast();
+ //
for (Int_t i=0;i<nseed;i++){
AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
if (pt) {
- AliTPCseed *pt2 = new AliTPCseed(*pt);
- fSectors = fOuterSec;
FollowProlongation(*pt,0);
- fSectors = fOuterSec;
- FollowProlongation(*pt,0);
- fSectors = fInnerSec;
- if (pt->GetNumberOfClusters()<35 && pt->GetLabel()>0 ){
- printf("\n%d",pt->GetLabel());
- fSectors = fOuterSec;
- FollowProlongation(*pt2,0);
- fSectors = fOuterSec;
- FollowProlongation(*pt2,0);
- fSectors = fOuterSec;
- }
- }
+ }
}
return 0;
}
{
//
// propagate track forward
- UnsignClusters();
+ //UnsignClusters();
Int_t nseed = fSeeds->GetEntriesFast();
for (Int_t i=0;i<nseed;i++){
AliTPCseed *pt = (AliTPCseed*)fSeeds->UncheckedAt(i);
if (TMath::Abs(wy/seed->fCurrentSigmaY2-1)>0.0001 || TMath::Abs(wz/seed->fCurrentSigmaZ2-1)>0.0001 ){
printf("problem\n");
}
- */
-}
+ */
+}
+
+
+Float_t AliTPCtrackerMI::GetSigmaY(AliTPCseed * seed)
+{
+ //
+ //
+ Float_t sd2 = TMath::Abs((fParam->GetZLength()-TMath::Abs(seed->GetZ())))*fParam->GetDiffL()*fParam->GetDiffL();
+ Float_t padlength = fParam->GetPadPitchLength(seed->fSector);
+ Float_t sres = (seed->fSector < fParam->GetNSector()/2) ? 0.2 :0.3;
+ Float_t angular = seed->GetSnp();
+ angular = angular*angular/(1-angular*angular);
+ // angular*=angular;
+ //angular = TMath::Sqrt(angular/(1-angular));
+ Float_t res = TMath::Sqrt(sd2+padlength*padlength*angular/12.+sres*sres);
+ return res;
+}
+Float_t AliTPCtrackerMI::GetSigmaZ(AliTPCseed * seed)
+{
+ //
+ //
+ Float_t sd2 = TMath::Abs((fParam->GetZLength()-TMath::Abs(seed->GetZ())))*fParam->GetDiffL()*fParam->GetDiffL();
+ Float_t padlength = fParam->GetPadPitchLength(seed->fSector);
+ Float_t sres = fParam->GetZSigma();
+ Float_t angular = seed->GetTgl();
+ Float_t res = TMath::Sqrt(sd2+padlength*padlength*angular*angular/12.+sres*sres);
+ return res;
+}
+
+
+//__________________________________________________________________________
+void AliTPCtrackerMI::CookLabel(AliKalmanTrack *tk, Float_t wrong) const {
+ //--------------------------------------------------------------------
+ //This function "cooks" a track label. If label<0, this track is fake.
+ //--------------------------------------------------------------------
+ AliTPCseed * t = (AliTPCseed*)tk;
+ Int_t noc=t->GetNumberOfClusters();
+ if (noc<10){
+ //printf("\nnot founded prolongation\n\n\n");
+ //t->Dump();
+ return ;
+ }
+ Int_t lb[160];
+ Int_t mx[160];
+ AliTPCclusterMI *clusters[160];
+ //
+ for (Int_t i=0;i<160;i++) {
+ clusters[i]=0;
+ lb[i]=mx[i]=0;
+ }
+
+ Int_t i;
+ Int_t current=0;
+ for (i=0; i<160 && current<noc; i++) {
+
+ Int_t index=t->GetClusterIndex2(i);
+ if (index<=0) continue;
+ if (index&0x8000) continue;
+ //
+ //clusters[current]=GetClusterMI(index);
+ if (t->fClusterPointer[i]){
+ clusters[current]=t->fClusterPointer[i];
+ current++;
+ }
+ }
+ noc = current;
+
+ Int_t lab=123456789;
+ for (i=0; i<noc; i++) {
+ AliTPCclusterMI *c=clusters[i];
+ if (!c) continue;
+ lab=TMath::Abs(c->GetLabel(0));
+ Int_t j;
+ for (j=0; j<noc; j++) if (lb[j]==lab || mx[j]==0) break;
+ lb[j]=lab;
+ (mx[j])++;
+ }
+ Int_t max=0;
+ for (i=0; i<noc; i++) if (mx[i]>max) {max=mx[i]; lab=lb[i];}
+
+ for (i=0; i<noc; i++) {
+ AliTPCclusterMI *c=clusters[i];
+ if (!c) continue;
+ if (TMath::Abs(c->GetLabel(1)) == lab ||
+ TMath::Abs(c->GetLabel(2)) == lab ) max++;
+ }
-Float_t AliTPCtrackerMI::GetSigmaY(AliTPCseed * seed)
-{
- //
- //
- Float_t sd2 = TMath::Abs((fParam->GetZLength()-TMath::Abs(seed->GetZ())))*fParam->GetDiffL()*fParam->GetDiffL();
- Float_t padlength = fParam->GetPadPitchLength(seed->fSector);
- Float_t sres = (seed->fSector < fParam->GetNSector()/2) ? 0.2 :0.3;
- Float_t angular = seed->GetSnp();
- angular = angular*angular/(1-angular*angular);
- // angular*=angular;
- //angular = TMath::Sqrt(angular/(1-angular));
- Float_t res = TMath::Sqrt(sd2+padlength*padlength*angular/12.+sres*sres);
- return res;
-}
-Float_t AliTPCtrackerMI::GetSigmaZ(AliTPCseed * seed)
-{
- //
- //
- Float_t sd2 = TMath::Abs((fParam->GetZLength()-TMath::Abs(seed->GetZ())))*fParam->GetDiffL()*fParam->GetDiffL();
- Float_t padlength = fParam->GetPadPitchLength(seed->fSector);
- Float_t sres = fParam->GetZSigma();
- Float_t angular = seed->GetTgl();
- Float_t res = TMath::Sqrt(sd2+padlength*padlength*angular*angular/12.+sres*sres);
- return res;
-}
+ if ((1.- Float_t(max)/noc) > wrong) lab=-lab;
+
+ else {
+ Int_t tail=Int_t(0.10*noc);
+ max=0;
+ Int_t ind=0;
+ for (i=1; i<=160&&ind<tail; i++) {
+ // AliTPCclusterMI *c=clusters[noc-i];
+ AliTPCclusterMI *c=clusters[i];
+ if (!c) continue;
+ if (lab == TMath::Abs(c->GetLabel(0)) ||
+ lab == TMath::Abs(c->GetLabel(1)) ||
+ lab == TMath::Abs(c->GetLabel(2))) max++;
+ ind++;
+ }
+ if (max < Int_t(0.5*tail)) lab=-lab;
+ }
+ t->SetLabel(lab);
+ // delete[] lb;
+ //delete[] mx;
+ //delete[] clusters;
+}
//__________________________________________________________________________
-void AliTPCtrackerMI::CookLabel(AliTPCseed *t, Float_t wrong) const {
+Int_t AliTPCtrackerMI::CookLabel(AliTPCseed *t, Float_t wrong,Int_t first, Int_t last) const {
//--------------------------------------------------------------------
//This function "cooks" a track label. If label<0, this track is fake.
//--------------------------------------------------------------------
if (noc<10){
//printf("\nnot founded prolongation\n\n\n");
//t->Dump();
- return ;
+ return -1;
}
Int_t lb[160];
Int_t mx[160];
Int_t i;
Int_t current=0;
for (i=0; i<160 && current<noc; i++) {
-
+ if (i<first) continue;
+ if (i>last) continue;
Int_t index=t->GetClusterIndex2(i);
if (index<=0) continue;
if (index&0x8000) continue;
}
}
noc = current;
-
+ if (noc<5) return -1;
Int_t lab=123456789;
for (i=0; i<noc; i++) {
AliTPCclusterMI *c=clusters[i];
if (max < Int_t(0.5*tail)) lab=-lab;
}
- t->SetLabel(lab);
-
+ // t->SetLabel(lab);
+ return lab;
// delete[] lb;
//delete[] mx;
//delete[] clusters;
}
}
+Int_t AliTPCtrackerMI::GetRowNumber(Double_t x[3]) const
+{
+ //return pad row number for given x vector
+ Float_t phi = TMath::ATan2(x[1],x[0]);
+ if(phi<0) phi=2.*TMath::Pi()+phi;
+ // Get the local angle in the sector philoc
+ const Float_t kRaddeg = 180/3.14159265358979312;
+ Float_t phiangle = (Int_t (phi*kRaddeg/20.) + 0.5)*20./kRaddeg;
+ Double_t localx = x[0]*TMath::Cos(phiangle)-x[1]*TMath::Sin(phiangle);
+ return GetRowNumber(localx);
+}
+
//_________________________________________________________________________
void AliTPCtrackerMI::AliTPCSector::Setup(const AliTPCParam *par, Int_t f) {
//-----------------------------------------------------------------------
fIndex[i]=index; fClusters[i]=c; fN++;
}
+void AliTPCtrackerMI::AliTPCRow::ResetClusters() {
+ //
+ // reset clusters
+ fN = 0;
+ fN1 = 0;
+ fN2 = 0;
+ //delete[] fClusterArray;
+ if (fClusters1) delete []fClusters1;
+ if (fClusters2) delete []fClusters2;
+ //fClusterArray=0;
+ fClusters1 = 0;
+ fClusters2 = 0;
+}
+
//___________________________________________________________________
Int_t AliTPCtrackerMI::AliTPCRow::Find(Double_t z) const {
// Return the index of the nearest cluster in z y
//-----------------------------------------------------------------------
Float_t maxdistance = roady*roady + roadz*roadz;
- Int_t iz1 = TMath::Max(fFastCluster[Int_t(z-roadz+254.5)]-1,0);
- Int_t iz2 = TMath::Min(fFastCluster[Int_t(z+roadz+255.5)]+1,fN);
-
AliTPCclusterMI *cl =0;
+
+ //PH Check boundaries. 510 is the size of fFastCluster
+ Int_t iz1 = Int_t(z-roadz+254.5);
+ if (iz1<0 || iz1>=510) return cl;
+ iz1 = TMath::Max(fFastCluster[iz1]-1,0);
+ Int_t iz2 = Int_t(z+roadz+255.5);
+ if (iz2<0 || iz2>=510) return cl;
+ iz2 = TMath::Min(fFastCluster[iz2]+1,fN);
+
//FindNearest3(y,z,roady,roadz,index);
// for (Int_t i=Find(z-roadz); i<fN; i++) {
for (Int_t i=iz1; i<iz2; i++) {
-AliTPCseed::AliTPCseed():AliTPCtrack(){
- //
- fRow=0;
- fRemoval =0;
- for (Int_t i=0;i<200;i++) SetClusterIndex2(i,-3);
- for (Int_t i=0;i<160;i++) fClusterPointer[i]=0;
-
- fPoints = 0;
- fEPoints = 0;
- fNFoundable =0;
- fNShared =0;
- fRemoval = 0;
- fSort =0;
- fFirstPoint =0;
- fNoCluster =0;
- fBSigned = kFALSE;
- fSeed1 =-1;
- fSeed2 =-1;
- fCurrentCluster =0;
-}
-
-AliTPCseed::AliTPCseed(const AliTPCtrack &t):AliTPCtrack(t){
- //
- //copy constructor
- fPoints = 0;
- fEPoints = 0;
- fNShared =0;
- // fTrackPoints =0;
- fRemoval =0;
- fSort =0;
- for (Int_t i=0;i<160;i++) {
- fClusterPointer[i] = 0;
- Int_t index = t.GetClusterIndex(i);
- if (index>0) {
- SetClusterIndex2(i,index);
- }
- else{
- SetClusterIndex2(i,-3);
- }
- }
- fFirstPoint =0;
- fNoCluster =0;
- fBSigned = kFALSE;
- fSeed1 =-1;
- fSeed2 =-1;
- fCurrentCluster =0;
-
-}
-
-AliTPCseed::AliTPCseed(const AliKalmanTrack &t, Double_t a):AliTPCtrack(t,a){
- //
- //copy constructor
- fRow=0;
- for (Int_t i=0;i<160;i++) {
- fClusterPointer[i] = 0;
- Int_t index = t.GetClusterIndex(i);
- SetClusterIndex2(i,index);
- }
-
- fPoints = 0;
- fEPoints = 0;
- fNFoundable =0;
- fNShared =0;
- // fTrackPoints =0;
- fRemoval =0;
- fSort = 0;
- fFirstPoint =0;
- fNoCluster =0;
- fBSigned = kFALSE;
- fSeed1 =-1;
- fSeed2 =-1;
- fCurrentCluster =0;
-}
-
-AliTPCseed::AliTPCseed(UInt_t index, const Double_t xx[5], const Double_t cc[15],
- Double_t xr, Double_t alpha):
- AliTPCtrack(index, xx, cc, xr, alpha) {
- //
- //
- //constructor
- fRow =0;
- for (Int_t i=0;i<200;i++) SetClusterIndex2(i,-3);
- for (Int_t i=0;i<160;i++) fClusterPointer[i]=0;
- fPoints = 0;
- fEPoints = 0;
- fNFoundable =0;
- fNShared = 0;
- // fTrackPoints =0;
- fRemoval =0;
- fSort =0;
- fFirstPoint =0;
- // fHelixIn = new TClonesArray("AliHelix",0);
- //fHelixOut = new TClonesArray("AliHelix",0);
- fNoCluster =0;
- fBSigned = kFALSE;
- fSeed1 =-1;
- fSeed2 =-1;
- fCurrentCluster =0;
-
-}
-
-AliTPCseed::~AliTPCseed(){
- //
- // destructor
- if (fPoints) delete fPoints;
- fPoints =0;
- if (fEPoints) delete fEPoints;
- fEPoints = 0;
- fNoCluster =0;
-}
-
-AliTPCTrackerPoint * AliTPCseed::GetTrackPoint(Int_t i)
-{
- //
- //
- return &fTrackPoints[i];
-}
-
-void AliTPCseed::RebuildSeed()
-{
- //
- // rebuild seed to be ready for storing
- AliTPCclusterMI cldummy;
- cldummy.SetQ(0);
- AliTPCTrackPoint pdummy;
- pdummy.GetTPoint().fIsShared = 10;
- for (Int_t i=0;i<160;i++){
- AliTPCclusterMI * cl0 = fClusterPointer[i];
- AliTPCTrackPoint *trpoint = (AliTPCTrackPoint*)fPoints->UncheckedAt(i);
- if (cl0){
- trpoint->GetTPoint() = *(GetTrackPoint(i));
- trpoint->GetCPoint() = *cl0;
- trpoint->GetCPoint().SetQ(TMath::Abs(cl0->GetQ()));
- }
- else{
- *trpoint = pdummy;
- trpoint->GetCPoint()= cldummy;
- }
-
- }
-
-}
-
-
-Double_t AliTPCseed::GetDensityFirst(Int_t n)
-{
- //
- //
- // return cluster for n rows bellow first point
- Int_t nfoundable = 1;
- Int_t nfound = 1;
- for (Int_t i=fLastPoint-1;i>0&&nfoundable<n; i--){
- Int_t index = GetClusterIndex2(i);
- if (index!=-1) nfoundable++;
- if (index>0) nfound++;
- }
- if (nfoundable<n) return 0;
- return Double_t(nfound)/Double_t(nfoundable);
-
-}
-
-
-void AliTPCseed::GetClusterStatistic(Int_t first, Int_t last, Int_t &found, Int_t &foundable, Int_t &shared, Bool_t plus2)
-{
- // get cluster stat. on given region
- //
- found = 0;
- foundable = 0;
- shared =0;
- for (Int_t i=first;i<last; i++){
- Int_t index = GetClusterIndex2(i);
- if (index!=-1) foundable++;
- if (fClusterPointer[i]) {
- found++;
- }
- else
- continue;
-
- if (fClusterPointer[i]->IsUsed(10)) {
- shared++;
- continue;
- }
- if (!plus2) continue; //take also neighborhoud
- //
- if ( (i>0) && fClusterPointer[i-1]){
- if (fClusterPointer[i-1]->IsUsed(10)) {
- shared++;
- continue;
- }
- }
- if ( fClusterPointer[i+1]){
- if (fClusterPointer[i+1]->IsUsed(10)) {
- shared++;
- continue;
- }
- }
-
- }
- if (shared>found){
- printf("problem\n");
- }
-}
-
-//_____________________________________________________________________________
-void AliTPCseed::CookdEdx(Double_t low, Double_t up,Int_t i1, Int_t i2, Bool_t onlyused) {
- //-----------------------------------------------------------------
- // This funtion calculates dE/dX within the "low" and "up" cuts.
- //-----------------------------------------------------------------
-
- Float_t amp[200];
- Float_t angular[200];
- Float_t weight[200];
- Int_t index[200];
- //Int_t nc = 0;
- // TClonesArray & arr = *fPoints;
- Float_t meanlog = 100.;
-
- Float_t mean[4] = {0,0,0,0};
- Float_t sigma[4] = {1000,1000,1000,1000};
- Int_t nc[4] = {0,0,0,0};
- Float_t norm[4] = {1000,1000,1000,1000};
- //
- //
- fNShared =0;
-
- for (Int_t of =0; of<4; of++){
- for (Int_t i=of+i1;i<i2;i+=4)
- {
- Int_t index = fIndex[i];
- if (index<0||index&0x8000) continue;
-
- //AliTPCTrackPoint * point = (AliTPCTrackPoint *) arr.At(i);
- AliTPCTrackerPoint * point = GetTrackPoint(i);
- //AliTPCTrackerPoint * pointm = GetTrackPoint(i-1);
- //AliTPCTrackerPoint * pointp = 0;
- //if (i<159) pointp = GetTrackPoint(i+1);
-
- if (point==0) continue;
- AliTPCclusterMI * cl = fClusterPointer[i];
- if (cl==0) continue;
- if (onlyused && (!cl->IsUsed(10))) continue;
- if (cl->IsUsed(11)) {
- fNShared++;
- continue;
- }
- Int_t type = cl->GetType();
- //if (point->fIsShared){
- // fNShared++;
- // continue;
- //}
- //if (pointm)
- // if (pointm->fIsShared) continue;
- //if (pointp)
- // if (pointp->fIsShared) continue;
-
- if (type<0) continue;
- //if (type>10) continue;
- //if (point->GetErrY()==0) continue;
- //if (point->GetErrZ()==0) continue;
-
- //Float_t ddy = (point->GetY()-cl->GetY())/point->GetErrY();
- //Float_t ddz = (point->GetZ()-cl->GetZ())/point->GetErrZ();
- //if ((ddy*ddy+ddz*ddz)>10) continue;
-
-
- // if (point->GetCPoint().GetMax()<5) continue;
- if (cl->GetMax()<5) continue;
- Float_t angley = point->GetAngleY();
- Float_t anglez = point->GetAngleZ();
-
- Float_t rsigmay2 = point->GetSigmaY();
- Float_t rsigmaz2 = point->GetSigmaZ();
- /*
- Float_t ns = 1.;
- if (pointm){
- rsigmay += pointm->GetTPoint().GetSigmaY();
- rsigmaz += pointm->GetTPoint().GetSigmaZ();
- ns+=1.;
- }
- if (pointp){
- rsigmay += pointp->GetTPoint().GetSigmaY();
- rsigmaz += pointp->GetTPoint().GetSigmaZ();
- ns+=1.;
- }
- rsigmay/=ns;
- rsigmaz/=ns;
- */
-
- Float_t rsigma = TMath::Sqrt(rsigmay2*rsigmaz2);
-
- Float_t ampc = 0; // normalization to the number of electrons
- if (i>64){
- // ampc = 1.*point->GetCPoint().GetMax();
- ampc = 1.*cl->GetMax();
- //ampc = 1.*point->GetCPoint().GetQ();
- // AliTPCClusterPoint & p = point->GetCPoint();
- // Float_t dy = TMath::Abs(Int_t( TMath::Abs(p.GetY()/0.6)) - TMath::Abs(p.GetY()/0.6)+0.5);
- // Float_t iz = (250.0-TMath::Abs(p.GetZ())+0.11)/0.566;
- //Float_t dz =
- // TMath::Abs( Int_t(iz) - iz + 0.5);
- //ampc *= 1.15*(1-0.3*dy);
- //ampc *= 1.15*(1-0.3*dz);
- // Float_t zfactor = (1.05-0.0004*TMath::Abs(point->GetCPoint().GetZ()));
- //ampc *=zfactor;
- }
- else{
- //ampc = 1.0*point->GetCPoint().GetMax();
- ampc = 1.0*cl->GetMax();
- //ampc = 1.0*point->GetCPoint().GetQ();
- //AliTPCClusterPoint & p = point->GetCPoint();
- // Float_t dy = TMath::Abs(Int_t( TMath::Abs(p.GetY()/0.4)) - TMath::Abs(p.GetY()/0.4)+0.5);
- //Float_t iz = (250.0-TMath::Abs(p.GetZ())+0.11)/0.566;
- //Float_t dz =
- // TMath::Abs( Int_t(iz) - iz + 0.5);
-
- //ampc *= 1.15*(1-0.3*dy);
- //ampc *= 1.15*(1-0.3*dz);
- // Float_t zfactor = (1.02-0.000*TMath::Abs(point->GetCPoint().GetZ()));
- //ampc *=zfactor;
-
- }
- ampc *= 2.0; // put mean value to channel 50
- //ampc *= 0.58; // put mean value to channel 50
- Float_t w = 1.;
- // if (type>0) w = 1./(type/2.-0.5);
- // Float_t z = TMath::Abs(cl->GetZ());
- if (i<64) {
- ampc /= 0.6;
- //ampc /= (1+0.0008*z);
- } else
- if (i>128){
- ampc /=1.5;
- //ampc /= (1+0.0008*z);
- }else{
- //ampc /= (1+0.0008*z);
- }
-
- if (type<0) { //amp at the border - lower weight
- // w*= 2.;
-
- continue;
- }
- if (rsigma>1.5) ampc/=1.3; // if big backround
- amp[nc[of]] = ampc;
- angular[nc[of]] = TMath::Sqrt(1.+angley*angley+anglez*anglez);
- weight[nc[of]] = w;
- nc[of]++;
- }
-
- TMath::Sort(nc[of],amp,index,kFALSE);
- Float_t sumamp=0;
- Float_t sumamp2=0;
- Float_t sumw=0;
- //meanlog = amp[index[Int_t(nc[of]*0.33)]];
- meanlog = 50;
- for (Int_t i=int(nc[of]*low+0.5);i<int(nc[of]*up+0.5);i++){
- Float_t ampl = amp[index[i]]/angular[index[i]];
- ampl = meanlog*TMath::Log(1.+ampl/meanlog);
- //
- sumw += weight[index[i]];
- sumamp += weight[index[i]]*ampl;
- sumamp2 += weight[index[i]]*ampl*ampl;
- norm[of] += angular[index[i]]*weight[index[i]];
- }
- if (sumw<1){
- SetdEdx(0);
- }
- else {
- norm[of] /= sumw;
- mean[of] = sumamp/sumw;
- sigma[of] = sumamp2/sumw-mean[of]*mean[of];
- if (sigma[of]>0.1)
- sigma[of] = TMath::Sqrt(sigma[of]);
- else
- sigma[of] = 1000;
-
- mean[of] = (TMath::Exp(mean[of]/meanlog)-1)*meanlog;
- //mean *=(1-0.02*(sigma/(mean*0.17)-1.));
- //mean *=(1-0.1*(norm-1.));
- }
- }
-
- Float_t dedx =0;
- fSdEdx =0;
- fMAngular =0;
- // mean[0]*= (1-0.05*(sigma[0]/(0.01+mean[1]*0.18)-1));
- // mean[1]*= (1-0.05*(sigma[1]/(0.01+mean[0]*0.18)-1));
-
-
- // dedx = (mean[0]* TMath::Sqrt((1.+nc[0]))+ mean[1]* TMath::Sqrt((1.+nc[1])) )/
- // ( TMath::Sqrt((1.+nc[0]))+TMath::Sqrt((1.+nc[1])));
-
- Int_t norm2 = 0;
- Int_t norm3 = 0;
- for (Int_t i =0;i<4;i++){
- if (nc[i]>2&&nc[i]<1000){
- dedx += mean[i] *nc[i];
- fSdEdx += sigma[i]*(nc[i]-2);
- fMAngular += norm[i] *nc[i];
- norm2 += nc[i];
- norm3 += nc[i]-2;
- }
- fDEDX[i] = mean[i];
- fSDEDX[i] = sigma[i];
- fNCDEDX[i]= nc[i];
- }
-
- if (norm3>0){
- dedx /=norm2;
- fSdEdx /=norm3;
- fMAngular/=norm2;
- }
- else{
- SetdEdx(0);
- return;
- }
- // Float_t dedx1 =dedx;
- /*
- dedx =0;
- for (Int_t i =0;i<4;i++){
- if (nc[i]>2&&nc[i]<1000){
- mean[i] = mean[i]*(1-0.12*(sigma[i]/(fSdEdx)-1.));
- dedx += mean[i] *nc[i];
- }
- fDEDX[i] = mean[i];
- }
- dedx /= norm2;
- */
-
-
- SetdEdx(dedx);
-
- //mi deDX
-
-
-
- //Very rough PID
- Double_t p=TMath::Sqrt((1.+ GetTgl()*GetTgl())/(Get1Pt()*Get1Pt()));
-
- if (p<0.6) {
- if (dedx < 39.+ 12./(p+0.25)/(p+0.25)) { SetMass(0.13957); return;}
- if (dedx < 39.+ 12./p/p) { SetMass(0.49368); return;}
- SetMass(0.93827); return;
- }
-
- if (p<1.2) {
- if (dedx < 39.+ 12./(p+0.25)/(p+0.25)) { SetMass(0.13957); return;}
- SetMass(0.93827); return;
- }
-
- SetMass(0.13957); return;
-
-}
-
-
-
-/*
-
-
-
-void AliTPCseed::CookdEdx2(Double_t low, Double_t up) {
- //-----------------------------------------------------------------
- // This funtion calculates dE/dX within the "low" and "up" cuts.
- //-----------------------------------------------------------------
-
- Float_t amp[200];
- Float_t angular[200];
- Float_t weight[200];
- Int_t index[200];
- Bool_t inlimit[200];
- for (Int_t i=0;i<200;i++) inlimit[i]=kFALSE;
- for (Int_t i=0;i<200;i++) amp[i]=10000;
- for (Int_t i=0;i<200;i++) angular[i]= 1;;
-
-
- //
- Float_t meanlog = 100.;
- Int_t indexde[4]={0,64,128,160};
-
- Float_t amean =0;
- Float_t asigma =0;
- Float_t anc =0;
- Float_t anorm =0;
-
- Float_t mean[4] = {0,0,0,0};
- Float_t sigma[4] = {1000,1000,1000,1000};
- Int_t nc[4] = {0,0,0,0};
- Float_t norm[4] = {1000,1000,1000,1000};
- //
- //
- fNShared =0;
-
- // for (Int_t of =0; of<3; of++){
- // for (Int_t i=indexde[of];i<indexde[of+1];i++)
- for (Int_t i =0; i<160;i++)
- {
- AliTPCTrackPoint * point = GetTrackPoint(i);
- if (point==0) continue;
- if (point->fIsShared){
- fNShared++;
- continue;
- }
- Int_t type = point->GetCPoint().GetType();
- if (type<0) continue;
- if (point->GetCPoint().GetMax()<5) continue;
- Float_t angley = point->GetTPoint().GetAngleY();
- Float_t anglez = point->GetTPoint().GetAngleZ();
- Float_t rsigmay = point->GetCPoint().GetSigmaY();
- Float_t rsigmaz = point->GetCPoint().GetSigmaZ();
- Float_t rsigma = TMath::Sqrt(rsigmay*rsigmaz);
-
- Float_t ampc = 0; // normalization to the number of electrons
- if (i>64){
- ampc = point->GetCPoint().GetMax();
- }
- else{
- ampc = point->GetCPoint().GetMax();
- }
- ampc *= 2.0; // put mean value to channel 50
- // ampc *= 0.565; // put mean value to channel 50
-
- Float_t w = 1.;
- Float_t z = TMath::Abs(point->GetCPoint().GetZ());
- if (i<64) {
- ampc /= 0.63;
- } else
- if (i>128){
- ampc /=1.51;
- }
- if (type<0) { //amp at the border - lower weight
- continue;
- }
- if (rsigma>1.5) ampc/=1.3; // if big backround
- angular[i] = TMath::Sqrt(1.+angley*angley+anglez*anglez);
- amp[i] = ampc/angular[i];
- weight[i] = w;
- anc++;
- }
-
- TMath::Sort(159,amp,index,kFALSE);
- for (Int_t i=int(anc*low+0.5);i<int(anc*up+0.5);i++){
- inlimit[index[i]] = kTRUE; // take all clusters
- }
-
- // meanlog = amp[index[Int_t(anc*0.3)]];
- meanlog =10000.;
- for (Int_t of =0; of<3; of++){
- Float_t sumamp=0;
- Float_t sumamp2=0;
- Float_t sumw=0;
- for (Int_t i=indexde[of];i<indexde[of+1];i++)
- {
- if (inlimit[i]==kFALSE) continue;
- Float_t ampl = amp[i];
- ///angular[i];
- ampl = meanlog*TMath::Log(1.+ampl/meanlog);
- //
- sumw += weight[i];
- sumamp += weight[i]*ampl;
- sumamp2 += weight[i]*ampl*ampl;
- norm[of] += angular[i]*weight[i];
- nc[of]++;
- }
- if (sumw<1){
- SetdEdx(0);
- }
- else {
- norm[of] /= sumw;
- mean[of] = sumamp/sumw;
- sigma[of] = sumamp2/sumw-mean[of]*mean[of];
- if (sigma[of]>0.1)
- sigma[of] = TMath::Sqrt(sigma[of]);
- else
- sigma[of] = 1000;
- mean[of] = (TMath::Exp(mean[of]/meanlog)-1)*meanlog;
- }
- }
-
- Float_t dedx =0;
- fSdEdx =0;
- fMAngular =0;
- //
- Int_t norm2 = 0;
- Int_t norm3 = 0;
- Float_t www[3] = {12.,14.,17.};
- //Float_t www[3] = {1.,1.,1.};
-
- for (Int_t i =0;i<3;i++){
- if (nc[i]>2&&nc[i]<1000){
- dedx += mean[i] *nc[i]*www[i]/sigma[i];
- fSdEdx += sigma[i]*(nc[i]-2)*www[i]/sigma[i];
- fMAngular += norm[i] *nc[i];
- norm2 += nc[i]*www[i]/sigma[i];
- norm3 += (nc[i]-2)*www[i]/sigma[i];
- }
- fDEDX[i] = mean[i];
- fSDEDX[i] = sigma[i];
- fNCDEDX[i]= nc[i];
- }
-
- if (norm3>0){
- dedx /=norm2;
- fSdEdx /=norm3;
- fMAngular/=norm2;
- }
- else{
- SetdEdx(0);
- return;
- }
- // Float_t dedx1 =dedx;
-
- dedx =0;
- Float_t norm4 = 0;
- for (Int_t i =0;i<3;i++){
- if (nc[i]>2&&nc[i]<1000&&sigma[i]>3){
- //mean[i] = mean[i]*(1+0.08*(sigma[i]/(fSdEdx)-1.));
- dedx += mean[i] *(nc[i])/(sigma[i]);
- norm4 += (nc[i])/(sigma[i]);
- }
- fDEDX[i] = mean[i];
- }
- if (norm4>0) dedx /= norm4;
-
-
- SetdEdx(dedx);
-
- //mi deDX
+// AliTPCTrackerPoint * AliTPCseed::GetTrackPoint(Int_t i)
+// {
+// //
+// //
+// return &fTrackPoints[i];
+// }
-}
-*/