+ }
+ //
+ //
+ //
+ //
+ // Calculate seed state vector and covariance matrix
+
+ 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;
+
+
+ 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(xyz[2][0], sec[2]*fSectors->GetAlpha()+fSectors->GetAlphaShift(), x, c, 0);
+ seed->SetLastPoint(row[2]);
+ seed->SetFirstPoint(row[2]);
+ for (Int_t i=row[0];i<row[2];i++){
+ seed->SetClusterIndex(i, track->GetClusterIndex(i));
+ }
+
+ return seed;
+}
+
+
+
+void AliTPCtrackerMI::FindMultiMC(TObjArray * array, AliESDEvent */*esd*/, Int_t iter)
+{
+ //
+ // find multi tracks - THIS FUNCTION IS ONLY FOR DEBUG PURPOSES
+ // USES MC LABELS
+ // Use AliTPCReconstructor::StreamLevel()>2 if you want to tune parameters - cuts
+ //
+ // Two reasons to have multiple find tracks
+ // 1. Curling tracks can be find more than once
+ // 2. Splitted tracks
+ // a.) Multiple seeding to increase tracking efficiency - (~ 100% reached)
+ // b.) Edge effect on the sector boundaries
+ //
+ //
+ // Algorithm done in 2 phases - because of CPU consumption
+ // it is n^2 algorithm - for lead-lead 20000x20000 combination are investigated
+ //
+ // Algorihm for curling tracks sign:
+ // 1 phase -makes a very rough fast cuts to minimize combinatorics
+ // a.) opposite sign
+ // b.) one of the tracks - not pointing to the primary vertex -
+ // c.) delta tan(theta)
+ // d.) delta phi
+ // 2 phase - calculates DCA between tracks - time consument
+
+ //
+ // fast cuts
+ //
+ // General cuts - for splitted tracks and for curling tracks
+ //
+ const Float_t kMaxdPhi = 0.2; // maximal distance in phi
+ //
+ // Curling tracks cuts
+ //
+ //
+ //
+ //
+ Int_t nentries = array->GetEntriesFast();
+ AliHelix *helixes = new AliHelix[nentries];
+ Float_t *xm = new Float_t[nentries];
+ Float_t *dz0 = new Float_t[nentries];
+ Float_t *dz1 = new Float_t[nentries];
+ //
+ //
+ TStopwatch timer;
+ timer.Start();
+ //
+ // Find track COG in x direction - point with best defined parameters
+ //
+ for (Int_t i=0;i<nentries;i++){
+ AliTPCseed* track = (AliTPCseed*)array->At(i);
+ if (!track) continue;
+ track->SetCircular(0);
+ new (&helixes[i]) AliHelix(*track);
+ Int_t ncl=0;
+ xm[i]=0;
+ Float_t dz[2];
+ track->GetDZ(GetX(),GetY(),GetZ(),GetBz(),dz);
+ dz0[i]=dz[0];
+ dz1[i]=dz[1];
+ for (Int_t icl=0; icl<160; icl++){
+ AliTPCclusterMI * cl = track->GetClusterPointer(icl);
+ if (cl) {
+ xm[i]+=cl->GetX();
+ ncl++;
+ }
+ }
+ if (ncl>0) xm[i]/=Float_t(ncl);
+ }
+ //
+ for (Int_t i0=0;i0<nentries;i0++){
+ AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
+ if (!track0) continue;
+ Float_t xc0 = helixes[i0].GetHelix(6);
+ Float_t yc0 = helixes[i0].GetHelix(7);
+ Float_t r0 = helixes[i0].GetHelix(8);
+ Float_t rc0 = TMath::Sqrt(xc0*xc0+yc0*yc0);
+ Float_t fi0 = TMath::ATan2(yc0,xc0);
+
+ for (Int_t i1=i0+1;i1<nentries;i1++){
+ AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
+ if (!track1) continue;
+ Int_t lab0=track0->GetLabel();
+ Int_t lab1=track1->GetLabel();
+ if (TMath::Abs(lab0)!=TMath::Abs(lab1)) continue;
+ //
+ Float_t xc1 = helixes[i1].GetHelix(6);
+ Float_t yc1 = helixes[i1].GetHelix(7);
+ Float_t r1 = helixes[i1].GetHelix(8);
+ Float_t rc1 = TMath::Sqrt(xc1*xc1+yc1*yc1);
+ Float_t fi1 = TMath::ATan2(yc1,xc1);
+ //
+ Float_t dfi = fi0-fi1;
+ //
+ //
+ if (dfi>1.5*TMath::Pi()) dfi-=TMath::Pi(); // take care about edge effect
+ if (dfi<-1.5*TMath::Pi()) dfi+=TMath::Pi(); //
+ if (TMath::Abs(dfi)>kMaxdPhi&&helixes[i0].GetHelix(4)*helixes[i1].GetHelix(4)<0){
+ //
+ // if short tracks with undefined sign
+ fi1 = -TMath::ATan2(yc1,-xc1);
+ dfi = fi0-fi1;
+ }
+ Float_t dtheta = TMath::Abs(track0->GetTgl()-track1->GetTgl())<TMath::Abs(track0->GetTgl()+track1->GetTgl())? track0->GetTgl()-track1->GetTgl():track0->GetTgl()+track1->GetTgl();
+
+ //
+ // debug stream to tune "fast cuts"
+ //
+ Double_t dist[3]; // distance at X
+ Double_t mdist[3]={0,0,0}; // mean distance X+-40cm
+ track0->GetDistance(track1,0.5*(xm[i0]+xm[i1])-40.,dist,AliTracker::GetBz());
+ for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[i]);
+ track0->GetDistance(track1,0.5*(xm[i0]+xm[i1])+40.,dist,AliTracker::GetBz());
+ for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[i]);
+ track0->GetDistance(track1,0.5*(xm[i0]+xm[i1]),dist,AliTracker::GetBz());
+ for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[i]);
+ for (Int_t i=0;i<3;i++) mdist[i]*=0.33333;
+
+ Float_t sum =0;
+ Float_t sums=0;
+ for (Int_t icl=0; icl<160; icl++){
+ AliTPCclusterMI * cl0 = track0->GetClusterPointer(icl);
+ AliTPCclusterMI * cl1 = track1->GetClusterPointer(icl);
+ if (cl0&&cl1) {
+ sum++;
+ if (cl0==cl1) sums++;
+ }
+ }
+ //
+ if (AliTPCReconstructor::StreamLevel()>0) {
+ TTreeSRedirector &cstream = *fDebugStreamer;
+ cstream<<"Multi"<<
+ "iter="<<iter<<
+ "lab0="<<lab0<<
+ "lab1="<<lab1<<
+ "Tr0.="<<track0<< // seed0
+ "Tr1.="<<track1<< // seed1
+ "h0.="<<&helixes[i0]<<
+ "h1.="<<&helixes[i1]<<
+ //
+ "sum="<<sum<< //the sum of rows with cl in both
+ "sums="<<sums<< //the sum of shared clusters
+ "xm0="<<xm[i0]<< // the center of track
+ "xm1="<<xm[i1]<< // the x center of track
+ // General cut variables
+ "dfi="<<dfi<< // distance in fi angle
+ "dtheta="<<dtheta<< // distance int theta angle
+ //
+ "dz00="<<dz0[i0]<<
+ "dz01="<<dz0[i1]<<
+ "dz10="<<dz1[i1]<<
+ "dz11="<<dz1[i1]<<
+ "dist0="<<dist[0]<< //distance x
+ "dist1="<<dist[1]<< //distance y
+ "dist2="<<dist[2]<< //distance z
+ "mdist0="<<mdist[0]<< //distance x
+ "mdist1="<<mdist[1]<< //distance y
+ "mdist2="<<mdist[2]<< //distance z
+ //
+ "r0="<<r0<<
+ "rc0="<<rc0<<
+ "fi0="<<fi0<<
+ "fi1="<<fi1<<
+ "r1="<<r1<<
+ "rc1="<<rc1<<
+ "\n";
+ }
+ }
+ }
+ delete [] helixes;
+ delete [] xm;
+ if (AliTPCReconstructor::StreamLevel()>1) {
+ AliInfo("Time for curling tracks removal DEBUGGING MC");
+ timer.Print();
+ }
+}
+
+
+void AliTPCtrackerMI::FindSplitted(TObjArray * array, AliESDEvent */*esd*/, Int_t iter)
+{
+ //
+ //
+ // Two reasons to have multiple find tracks
+ // 1. Curling tracks can be find more than once
+ // 2. Splitted tracks
+ // a.) Multiple seeding to increase tracking efficiency - (~ 100% reached)
+ // b.) Edge effect on the sector boundaries
+ //
+ // This function tries to find tracks closed in the parametric space
+ //
+ // cut logic if distance is bigger than cut continue - Do Nothing
+ const Float_t kMaxdTheta = 0.05; // maximal distance in theta
+ const Float_t kMaxdPhi = 0.05; // maximal deistance in phi
+ const Float_t kdelta = 40.; //delta r to calculate track distance
+ //
+ // const Float_t kMaxDist0 = 1.; // maximal distance 0
+ //const Float_t kMaxDist1 = 0.3; // maximal distance 1 - cut if track in separate rows
+ //
+ /*
+ TCut csec("csec","abs(Tr0.fRelativeSector-Tr1.fRelativeSector)<2");
+ TCut cdtheta("cdtheta","abs(dtheta)<0.05");
+ */
+ //
+ //
+ //
+ Int_t nentries = array->GetEntriesFast();
+ AliHelix *helixes = new AliHelix[nentries];
+ Float_t *xm = new Float_t[nentries];
+ //
+ //
+ TStopwatch timer;
+ timer.Start();
+ //
+ //Sort tracks according quality
+ //
+ Int_t nseed = array->GetEntriesFast();
+ Float_t * quality = new Float_t[nseed];
+ Int_t * indexes = new Int_t[nseed];
+ for (Int_t i=0; i<nseed; i++) {
+ AliTPCseed *pt=(AliTPCseed*)array->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();
+ //prefer high momenta tracks if overlaps
+ quality[i] *= TMath::Sqrt(TMath::Abs(pt->Pt())+0.5);
+ }
+ TMath::Sort(nseed,quality,indexes);
+
+
+ //
+ // Find track COG in x direction - point with best defined parameters
+ //
+ for (Int_t i=0;i<nentries;i++){
+ AliTPCseed* track = (AliTPCseed*)array->At(i);
+ if (!track) continue;
+ track->SetCircular(0);
+ new (&helixes[i]) AliHelix(*track);
+ Int_t ncl=0;
+ xm[i]=0;
+ for (Int_t icl=0; icl<160; icl++){
+ AliTPCclusterMI * cl = track->GetClusterPointer(icl);
+ if (cl) {
+ xm[i]+=cl->GetX();
+ ncl++;
+ }
+ }
+ if (ncl>0) xm[i]/=Float_t(ncl);
+ }
+ //
+ for (Int_t is0=0;is0<nentries;is0++){
+ Int_t i0 = indexes[is0];
+ AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
+ if (!track0) continue;
+ if (track0->GetKinkIndexes()[0]!=0) continue;
+ Float_t xc0 = helixes[i0].GetHelix(6);
+ Float_t yc0 = helixes[i0].GetHelix(7);
+ Float_t fi0 = TMath::ATan2(yc0,xc0);
+
+ for (Int_t is1=is0+1;is1<nentries;is1++){
+ Int_t i1 = indexes[is1];
+ AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
+ if (!track1) continue;
+ //
+ if (TMath::Abs(track0->GetRelativeSector()-track1->GetRelativeSector())>1) continue;
+ if (track1->GetKinkIndexes()[0]>0 &&track0->GetKinkIndexes()[0]<0) continue;
+ if (track1->GetKinkIndexes()[0]!=0) continue;
+
+ Float_t dtheta = TMath::Abs(track0->GetTgl()-track1->GetTgl())<TMath::Abs(track0->GetTgl()+track1->GetTgl())? track0->GetTgl()-track1->GetTgl():track0->GetTgl()+track1->GetTgl();
+ if (TMath::Abs(dtheta)>kMaxdTheta) continue;
+ //
+ Float_t xc1 = helixes[i1].GetHelix(6);
+ Float_t yc1 = helixes[i1].GetHelix(7);
+ Float_t fi1 = TMath::ATan2(yc1,xc1);
+ //
+ Float_t dfi = fi0-fi1;
+ if (dfi>1.5*TMath::Pi()) dfi-=TMath::Pi(); // take care about edge effect
+ if (dfi<-1.5*TMath::Pi()) dfi+=TMath::Pi(); //
+ if (TMath::Abs(dfi)>kMaxdPhi&&helixes[i0].GetHelix(4)*helixes[i1].GetHelix(4)<0){
+ //
+ // if short tracks with undefined sign
+ fi1 = -TMath::ATan2(yc1,-xc1);
+ dfi = fi0-fi1;
+ }
+ if (TMath::Abs(dfi)>kMaxdPhi) continue;
+ //
+ //
+ Float_t sum =0;
+ Float_t sums=0;
+ Float_t sum0=0;
+ Float_t sum1=0;
+ for (Int_t icl=0; icl<160; icl++){
+ Int_t index0=track0->GetClusterIndex2(icl);
+ Int_t index1=track1->GetClusterIndex2(icl);
+ Bool_t used0 = (index0>0 && !(index0&0x8000));
+ Bool_t used1 = (index1>0 && !(index1&0x8000));
+ //
+ if (used0) sum0++; // used cluster0
+ if (used1) sum1++; // used clusters1
+ if (used0&&used1) sum++;
+ if (index0==index1 && used0 && used1) sums++;
+ }
+
+ //
+ if (sums<10) continue;
+ if (sum<40) continue;
+ if (sums/Float_t(TMath::Min(sum0,sum1))<0.5) continue;
+ //
+ Double_t dist[5][4]; // distance at X
+ Double_t mdist[4]={0,0,0,0}; // mean distance on range +-delta
+
+ //
+ //
+ track0->GetDistance(track1,xm[i0],dist[0],AliTracker::GetBz());
+ for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[0][i]);
+ track0->GetDistance(track1,xm[i1],dist[1],AliTracker::GetBz());
+ for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[1][i]);
+ //
+ track0->GetDistance(track1,TMath::Min(xm[i1],xm[i0])-kdelta,dist[2],AliTracker::GetBz());
+ for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[2][i]);
+ track0->GetDistance(track1,TMath::Max(xm[i1],xm[i0])+kdelta,dist[3],AliTracker::GetBz());
+ for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[3][i]);
+ //
+ track0->GetDistance(track1,(xm[i1]+xm[i0])*0.5,dist[4],AliTracker::GetBz());
+ for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[4][i]);
+ for (Int_t i=0;i<3;i++) mdist[i]*=0.2;
+ //
+ //
+ Int_t lab0=track0->GetLabel();
+ Int_t lab1=track1->GetLabel();
+ if( AliTPCReconstructor::StreamLevel()>5){
+ TTreeSRedirector &cstream = *fDebugStreamer;
+ cstream<<"Splitted"<<
+ "iter="<<iter<<
+ "lab0="<<lab0<<
+ "lab1="<<lab1<<
+ "Tr0.="<<track0<< // seed0
+ "Tr1.="<<track1<< // seed1
+ "h0.="<<&helixes[i0]<<
+ "h1.="<<&helixes[i1]<<
+ //
+ "sum="<<sum<< //the sum of rows with cl in both
+ "sum0="<<sum0<< //the sum of rows with cl in 0 track
+ "sum1="<<sum1<< //the sum of rows with cl in 1 track
+ "sums="<<sums<< //the sum of shared clusters
+ "xm0="<<xm[i0]<< // the center of track
+ "xm1="<<xm[i1]<< // the x center of track
+ // General cut variables
+ "dfi="<<dfi<< // distance in fi angle
+ "dtheta="<<dtheta<< // distance int theta angle
+ //
+ //
+ "dist0="<<dist[4][0]<< //distance x
+ "dist1="<<dist[4][1]<< //distance y
+ "dist2="<<dist[4][2]<< //distance z
+ "mdist0="<<mdist[0]<< //distance x
+ "mdist1="<<mdist[1]<< //distance y
+ "mdist2="<<mdist[2]<< //distance z
+ "\n";
+ }
+ delete array->RemoveAt(i1);
+ }
+ }
+ delete [] helixes;
+ delete [] xm;
+ delete [] quality;
+ delete [] indexes;
+ AliInfo("Time for splitted tracks removal");
+ timer.Print();
+}
+
+
+
+void AliTPCtrackerMI::FindCurling(TObjArray * array, AliESDEvent */*esd*/, Int_t iter)
+{