1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
17 //-------------------------------------------------------
18 // Implementation of the TPC tracker
20 // Origin: Marian Ivanov Marian.Ivanov@cern.ch
22 // AliTPC parallel tracker
24 // The track fitting is based on Kalaman filtering approach
26 // The track finding steps:
27 // 1. Seeding - with and without vertex constraint
28 // - seeding with vertex constain done at first n^2 proble
29 // - seeding without vertex constraint n^3 problem
30 // 2. Tracking - follow prolongation road - find cluster - update kalman track
32 // The seeding and tracking is repeated several times, in different seeding region.
33 // This approach enables to find the track which cannot be seeded in some region of TPC
34 // This can happen because of low momenta (track do not reach outer radius), or track is currently in the ded region between sectors, or the track is for the moment overlapped with other track (seed quality is poor) ...
36 // With this approach we reach almost 100 % efficiency also for high occupancy events.
37 // (If the seeding efficiency in a region is about 90 % than with logical or of several
38 // regions we will reach 100% (in theory - supposing independence)
40 // Repeating several seeding - tracking procedures some of the tracks can be find
43 // The procedures to remove multi find tacks are impremented:
44 // RemoveUsed2 - fast procedure n problem -
45 // Algorithm - Sorting tracks according quality
46 // remove tracks with some shared fraction
47 // Sharing in respect to all tacks
48 // Signing clusters in gold region
49 // FindSplitted - slower algorithm n^2
50 // Sort the tracks according quality
51 // Loop over pair of tracks
52 // If overlap with other track bigger than threshold - remove track
54 // FindCurling - Finds the pair of tracks which are curling
55 // - About 10% of tracks can be find with this procedure
56 // The combinatorial background is too big to be used in High
57 // multiplicity environment
58 // - n^2 problem - Slow procedure - currently it is disabled because of
61 // The number of splitted tracks can be reduced disabling the sharing of the cluster.
62 // tpcRecoParam-> SetClusterSharing(kFALSE);
63 // IT IS HIGHLY non recomended to use it in high flux enviroonment
64 // Even using this switch some tracks can be found more than once
65 // (because of multiple seeding and low quality tracks which will not cross full chamber)
68 // The tracker itself can be debugged - the information about tracks can be stored in several // phases of the reconstruction
69 // To enable storage of the TPC tracks in the ESD friend track
70 // use AliTPCReconstructor::SetStreamLevel(n);
72 // The debug level - different procedure produce tree for numerical debugging
73 // To enable them set AliTPCReconstructor::SetStreamLevel(n); where nis bigger 1
77 // Adding systematic errors to the covariance:
79 // The systematic errors due to the misalignment and miscalibration are added to the covariance matrix
80 // of the tracks (not to the clusters as they are dependent):
81 // The parameters form AliTPCRecoParam are used AliTPCRecoParam::GetSystematicError
82 // The systematic errors are expressed there in RMS - position (cm), angle (rad), curvature (1/GeV)
83 // The default values are 0.
85 // The sytematic errors are added to the covariance matrix in following places:
87 // 1. During fisrt itteration - AliTPCtrackerMI::FillESD
88 // 2. Second iteration -
89 // 2.a ITS->TPC - AliTPCtrackerMI::ReadSeeds
90 // 2.b TPC->TRD - AliTPCtrackerMI::PropagateBack
91 // 3. Third iteration -
92 // 3.a TRD->TPC - AliTPCtrackerMI::ReadSeeds
93 // 3.b TPC->ITS - AliTPCtrackerMI::RefitInward
95 // There are several places in the code which can be numerically debuged
96 // This code is keeped in order to enable code development and to check the calibration implementtion
98 // 1. ErrParam stream - dump information about
100 // 2.a) cluster error estimate
101 // 3.a) cluster shape estimate
104 // Debug streamer levels:
106 //-------------------------------------------------------
111 #include "Riostream.h"
112 #include <TClonesArray.h>
114 #include <TObjArray.h>
116 #include <TGraphErrors.h>
118 #include "AliComplexCluster.h"
119 #include "AliESDEvent.h"
120 #include "AliESDtrack.h"
121 #include "AliESDVertex.h"
124 #include "AliHelix.h"
125 #include "AliRunLoader.h"
126 #include "AliTPCClustersRow.h"
127 #include "AliTPCParam.h"
128 #include "AliTPCReconstructor.h"
129 #include "AliTPCpolyTrack.h"
130 #include "AliTPCreco.h"
131 #include "AliTPCseed.h"
133 #include "AliTPCtrackerSector.h"
134 #include "AliTPCtrackerMI.h"
135 #include "TStopwatch.h"
136 #include "AliTPCReconstructor.h"
137 #include "AliAlignObj.h"
138 #include "AliTrackPointArray.h"
140 #include "AliTPCcalibDB.h"
141 #include "AliTPCcalibDButil.h"
142 #include "AliTPCTransform.h"
143 #include "AliTPCClusterParam.h"
144 #include "AliTPCdEdxInfo.h"
145 #include "AliDCSSensorArray.h"
146 #include "AliDCSSensor.h"
148 #include "AliCosmicTracker.h"
154 ClassImp(AliTPCtrackerMI)
158 class AliTPCFastMath {
161 static Double_t FastAsin(Double_t x);
163 static Double_t fgFastAsin[20000]; //lookup table for fast asin computation
166 Double_t AliTPCFastMath::fgFastAsin[20000];
167 AliTPCFastMath gAliTPCFastMath; // needed to fill the LUT
169 AliTPCFastMath::AliTPCFastMath(){
171 // initialized lookup table;
172 for (Int_t i=0;i<10000;i++){
173 fgFastAsin[2*i] = TMath::ASin(i/10000.);
174 fgFastAsin[2*i+1] = (TMath::ASin((i+1)/10000.)-fgFastAsin[2*i]);
178 Double_t AliTPCFastMath::FastAsin(Double_t x){
180 // return asin using lookup table
182 Int_t index = int(x*10000);
183 return fgFastAsin[2*index]+(x*10000.-index)*fgFastAsin[2*index+1];
186 Int_t index = int(x*10000);
187 return -(fgFastAsin[2*index]+(x*10000.-index)*fgFastAsin[2*index+1]);
189 //__________________________________________________________________
190 AliTPCtrackerMI::AliTPCtrackerMI()
218 // default constructor
220 for (Int_t irow=0; irow<200; irow++){
227 //_____________________________________________________________________
231 Int_t AliTPCtrackerMI::UpdateTrack(AliTPCseed * track, Int_t accept){
233 //update track information using current cluster - track->fCurrentCluster
236 AliTPCclusterMI* c =track->GetCurrentCluster();
237 if (accept > 0) //sign not accepted clusters
238 track->SetCurrentClusterIndex1(track->GetCurrentClusterIndex1() | 0x8000);
239 else // unsign accpeted clusters
240 track->SetCurrentClusterIndex1(track->GetCurrentClusterIndex1() & 0xffff7fff);
241 UInt_t i = track->GetCurrentClusterIndex1();
243 Int_t sec=(i&0xff000000)>>24;
244 //Int_t row = (i&0x00ff0000)>>16;
245 track->SetRow((i&0x00ff0000)>>16);
246 track->SetSector(sec);
247 // Int_t index = i&0xFFFF;
248 if (sec>=fkParam->GetNInnerSector()) track->SetRow(track->GetRow()+fkParam->GetNRowLow());
249 track->SetClusterIndex2(track->GetRow(), i);
250 //track->fFirstPoint = row;
251 //if ( track->fLastPoint<row) track->fLastPoint =row;
252 // if (track->fRow<0 || track->fRow>160) {
253 // printf("problem\n");
255 if (track->GetFirstPoint()>track->GetRow())
256 track->SetFirstPoint(track->GetRow());
257 if (track->GetLastPoint()<track->GetRow())
258 track->SetLastPoint(track->GetRow());
261 track->SetClusterPointer(track->GetRow(),c);
264 Double_t angle2 = track->GetSnp()*track->GetSnp();
266 //SET NEW Track Point
268 if (angle2<1) //PH sometimes angle2 is very big. To be investigated...
270 angle2 = TMath::Sqrt(angle2/(1-angle2));
271 AliTPCTrackerPoint &point =*(track->GetTrackPoint(track->GetRow()));
273 point.SetSigmaY(c->GetSigmaY2()/track->GetCurrentSigmaY2());
274 point.SetSigmaZ(c->GetSigmaZ2()/track->GetCurrentSigmaZ2());
275 point.SetErrY(sqrt(track->GetErrorY2()));
276 point.SetErrZ(sqrt(track->GetErrorZ2()));
278 point.SetX(track->GetX());
279 point.SetY(track->GetY());
280 point.SetZ(track->GetZ());
281 point.SetAngleY(angle2);
282 point.SetAngleZ(track->GetTgl());
283 if (point.IsShared()){
284 track->SetErrorY2(track->GetErrorY2()*4);
285 track->SetErrorZ2(track->GetErrorZ2()*4);
289 Double_t chi2 = track->GetPredictedChi2(track->GetCurrentCluster());
291 // track->SetErrorY2(track->GetErrorY2()*1.3);
292 // track->SetErrorY2(track->GetErrorY2()+0.01);
293 // track->SetErrorZ2(track->GetErrorZ2()*1.3);
294 // track->SetErrorZ2(track->GetErrorZ2()+0.005);
296 if (accept>0) return 0;
297 if (track->GetNumberOfClusters()%20==0){
298 // if (track->fHelixIn){
299 // TClonesArray & larr = *(track->fHelixIn);
300 // Int_t ihelix = larr.GetEntriesFast();
301 // new(larr[ihelix]) AliHelix(*track) ;
304 track->SetNoCluster(0);
305 return track->Update(c,chi2,i);
310 Int_t AliTPCtrackerMI::AcceptCluster(AliTPCseed * seed, AliTPCclusterMI * cluster)
313 // decide according desired precision to accept given
314 // cluster for tracking
316 seed->GetProlongation(cluster->GetX(),yt,zt);
317 Double_t sy2=ErrY2(seed,cluster);
318 Double_t sz2=ErrZ2(seed,cluster);
320 Double_t sdistancey2 = sy2+seed->GetSigmaY2();
321 Double_t sdistancez2 = sz2+seed->GetSigmaZ2();
322 Double_t dy=seed->GetCurrentCluster()->GetY()-yt;
323 Double_t dz=seed->GetCurrentCluster()->GetZ()-zt;
324 Double_t rdistancey2 = (seed->GetCurrentCluster()->GetY()-yt)*
325 (seed->GetCurrentCluster()->GetY()-yt)/sdistancey2;
326 Double_t rdistancez2 = (seed->GetCurrentCluster()->GetZ()-zt)*
327 (seed->GetCurrentCluster()->GetZ()-zt)/sdistancez2;
329 Double_t rdistance2 = rdistancey2+rdistancez2;
332 if (AliTPCReconstructor::StreamLevel()>2 && seed->GetNumberOfClusters()>20) {
333 Float_t rmsy2 = seed->GetCurrentSigmaY2();
334 Float_t rmsz2 = seed->GetCurrentSigmaZ2();
335 Float_t rmsy2p30 = seed->GetCMeanSigmaY2p30();
336 Float_t rmsz2p30 = seed->GetCMeanSigmaZ2p30();
337 Float_t rmsy2p30R = seed->GetCMeanSigmaY2p30R();
338 Float_t rmsz2p30R = seed->GetCMeanSigmaZ2p30R();
339 AliExternalTrackParam param(*seed);
340 static TVectorD gcl(3),gtr(3);
342 param.GetXYZ(gcl.GetMatrixArray());
343 cluster->GetGlobalXYZ(gclf);
344 gcl[0]=gclf[0]; gcl[1]=gclf[1]; gcl[2]=gclf[2];
347 if (AliTPCReconstructor::StreamLevel()>2) {
348 (*fDebugStreamer)<<"ErrParam"<<
361 "rmsy2p30="<<rmsy2p30<<
362 "rmsz2p30="<<rmsz2p30<<
363 "rmsy2p30R="<<rmsy2p30R<<
364 "rmsz2p30R="<<rmsz2p30R<<
365 // normalize distance -
366 "rdisty="<<rdistancey2<<
367 "rdistz="<<rdistancez2<<
368 "rdist="<<rdistance2<< //
372 //return 0; // temporary
373 if (rdistance2>32) return 3;
376 if ((rdistancey2>9. || rdistancez2>9.) && cluster->GetType()==0)
377 return 2; //suspisiouce - will be changed
379 if ((rdistancey2>6.25 || rdistancez2>6.25) && cluster->GetType()>0)
380 // strict cut on overlaped cluster
381 return 2; //suspisiouce - will be changed
383 if ( (rdistancey2>1. || rdistancez2>6.25 )
384 && cluster->GetType()<0){
385 seed->SetNFoundable(seed->GetNFoundable()-1);
389 if (fUseHLTClusters == 3 || fUseHLTClusters == 4) {
391 if(!AliTPCReconstructor::GetRecoParam()->GetUseHLTOnePadCluster()) {
392 if (TMath::Abs(cluster->GetSigmaY2()) < kAlmost0)
405 //_____________________________________________________________________________
406 AliTPCtrackerMI::AliTPCtrackerMI(const AliTPCParam *par):
408 fkNIS(par->GetNInnerSector()/2),
410 fkNOS(par->GetNOuterSector()/2),
433 //---------------------------------------------------------------------
434 // The main TPC tracker constructor
435 //---------------------------------------------------------------------
436 fInnerSec=new AliTPCtrackerSector[fkNIS];
437 fOuterSec=new AliTPCtrackerSector[fkNOS];
440 for (i=0; i<fkNIS; i++) fInnerSec[i].Setup(par,0);
441 for (i=0; i<fkNOS; i++) fOuterSec[i].Setup(par,1);
444 Int_t nrowlow = par->GetNRowLow();
445 Int_t nrowup = par->GetNRowUp();
448 for (i=0;i<nrowlow;i++){
449 fXRow[i] = par->GetPadRowRadiiLow(i);
450 fPadLength[i]= par->GetPadPitchLength(0,i);
451 fYMax[i] = fXRow[i]*TMath::Tan(0.5*par->GetInnerAngle());
455 for (i=0;i<nrowup;i++){
456 fXRow[i+nrowlow] = par->GetPadRowRadiiUp(i);
457 fPadLength[i+nrowlow] = par->GetPadPitchLength(60,i);
458 fYMax[i+nrowlow] = fXRow[i+nrowlow]*TMath::Tan(0.5*par->GetOuterAngle());
461 if (AliTPCReconstructor::StreamLevel()>0) {
462 fDebugStreamer = new TTreeSRedirector("TPCdebug.root");
465 fSeedsPool = new TClonesArray("AliTPCseed",1000);
467 //________________________________________________________________________
468 AliTPCtrackerMI::AliTPCtrackerMI(const AliTPCtrackerMI &t):
495 //------------------------------------
496 // dummy copy constructor
497 //------------------------------------------------------------------
499 for (Int_t irow=0; irow<200; irow++){
506 AliTPCtrackerMI & AliTPCtrackerMI::operator=(const AliTPCtrackerMI& /*r*/)
508 //------------------------------
510 //--------------------------------------------------------------
513 //_____________________________________________________________________________
514 AliTPCtrackerMI::~AliTPCtrackerMI() {
515 //------------------------------------------------------------------
516 // TPC tracker destructor
517 //------------------------------------------------------------------
524 if (fDebugStreamer) delete fDebugStreamer;
525 if (fSeedsPool) delete fSeedsPool;
529 void AliTPCtrackerMI::FillESD(const TObjArray* arr)
533 //fill esds using updated tracks
536 // write tracks to the event
537 // store index of the track
538 Int_t nseed=arr->GetEntriesFast();
539 //FindKinks(arr,fEvent);
540 for (Int_t i=0; i<nseed; i++) {
541 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
545 if (AliTPCReconstructor::StreamLevel()>1) {
546 (*fDebugStreamer)<<"Track0"<<
550 // pt->PropagateTo(fkParam->GetInnerRadiusLow());
551 if (pt->GetKinkIndex(0)<=0){ //don't propagate daughter tracks
552 pt->PropagateTo(fkParam->GetInnerRadiusLow());
555 if (( pt->GetPoints()[2]- pt->GetPoints()[0])>5 && pt->GetPoints()[3]>0.8){
557 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
558 iotrack.SetTPCPoints(pt->GetPoints());
559 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
560 iotrack.SetV0Indexes(pt->GetV0Indexes());
561 // iotrack.SetTPCpid(pt->fTPCr);
562 //iotrack.SetTPCindex(i);
563 MakeESDBitmaps(pt, &iotrack);
564 fEvent->AddTrack(&iotrack);
568 if ( (pt->GetNumberOfClusters()>70)&& (Float_t(pt->GetNumberOfClusters())/Float_t(pt->GetNFoundable()))>0.55) {
570 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
571 iotrack.SetTPCPoints(pt->GetPoints());
572 //iotrack.SetTPCindex(i);
573 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
574 iotrack.SetV0Indexes(pt->GetV0Indexes());
575 MakeESDBitmaps(pt, &iotrack);
576 // iotrack.SetTPCpid(pt->fTPCr);
577 fEvent->AddTrack(&iotrack);
581 // short tracks - maybe decays
583 if ( (pt->GetNumberOfClusters()>30) && (Float_t(pt->GetNumberOfClusters())/Float_t(pt->GetNFoundable()))>0.70) {
584 Int_t found,foundable,shared;
585 pt->GetClusterStatistic(0,60,found, foundable,shared,kFALSE);
586 if ( (found>20) && (pt->GetNShared()/float(pt->GetNumberOfClusters())<0.2)){
588 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
589 //iotrack.SetTPCindex(i);
590 iotrack.SetTPCPoints(pt->GetPoints());
591 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
592 iotrack.SetV0Indexes(pt->GetV0Indexes());
593 MakeESDBitmaps(pt, &iotrack);
594 //iotrack.SetTPCpid(pt->fTPCr);
595 fEvent->AddTrack(&iotrack);
600 if ( (pt->GetNumberOfClusters()>20) && (Float_t(pt->GetNumberOfClusters())/Float_t(pt->GetNFoundable()))>0.8) {
601 Int_t found,foundable,shared;
602 pt->GetClusterStatistic(0,60,found, foundable,shared,kFALSE);
603 if (found<20) continue;
604 if (pt->GetNShared()/float(pt->GetNumberOfClusters())>0.2) continue;
607 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
608 iotrack.SetTPCPoints(pt->GetPoints());
609 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
610 iotrack.SetV0Indexes(pt->GetV0Indexes());
611 MakeESDBitmaps(pt, &iotrack);
612 //iotrack.SetTPCpid(pt->fTPCr);
613 //iotrack.SetTPCindex(i);
614 fEvent->AddTrack(&iotrack);
617 // short tracks - secondaties
619 if ( (pt->GetNumberOfClusters()>30) ) {
620 Int_t found,foundable,shared;
621 pt->GetClusterStatistic(128,158,found, foundable,shared,kFALSE);
622 if ( (found>20) && (pt->GetNShared()/float(pt->GetNumberOfClusters())<0.2) &&float(found)/float(foundable)>0.8){
624 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
625 iotrack.SetTPCPoints(pt->GetPoints());
626 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
627 iotrack.SetV0Indexes(pt->GetV0Indexes());
628 MakeESDBitmaps(pt, &iotrack);
629 //iotrack.SetTPCpid(pt->fTPCr);
630 //iotrack.SetTPCindex(i);
631 fEvent->AddTrack(&iotrack);
636 if ( (pt->GetNumberOfClusters()>15)) {
637 Int_t found,foundable,shared;
638 pt->GetClusterStatistic(138,158,found, foundable,shared,kFALSE);
639 if (found<15) continue;
640 if (foundable<=0) continue;
641 if (pt->GetNShared()/float(pt->GetNumberOfClusters())>0.2) continue;
642 if (float(found)/float(foundable)<0.8) continue;
645 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
646 iotrack.SetTPCPoints(pt->GetPoints());
647 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
648 iotrack.SetV0Indexes(pt->GetV0Indexes());
649 MakeESDBitmaps(pt, &iotrack);
650 // iotrack.SetTPCpid(pt->fTPCr);
651 //iotrack.SetTPCindex(i);
652 fEvent->AddTrack(&iotrack);
656 // >> account for suppressed tracks in the kink indices (RS)
657 int nESDtracks = fEvent->GetNumberOfTracks();
658 for (int it=nESDtracks;it--;) {
659 AliESDtrack* esdTr = fEvent->GetTrack(it);
660 if (!esdTr || !esdTr->GetKinkIndex(0)) continue;
661 for (int ik=0;ik<3;ik++) {
663 if (!(knkId=esdTr->GetKinkIndex(ik))) break; // no more kinks for this track
664 AliESDkink* kink = fEvent->GetKink(TMath::Abs(knkId)-1);
666 AliError(Form("ESDTrack%d refers to non-existing kink %d",it,TMath::Abs(knkId)-1));
669 kink->SetIndex(it, knkId<0 ? 0:1); // update track index of the kink: mother at 0, daughter at 1
672 // << account for suppressed tracks in the kink indices (RS)
673 AliInfo(Form("Number of filled ESDs-\t%d\n",fEvent->GetNumberOfTracks()));
681 Double_t AliTPCtrackerMI::ErrY2(AliTPCseed* seed, const AliTPCclusterMI * cl){
684 // Use calibrated cluster error from OCDB
686 AliTPCClusterParam * clparam = AliTPCcalibDB::Instance()->GetClusterParam();
688 Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
689 Int_t ctype = cl->GetType();
690 Int_t type = (cl->GetRow()<63) ? 0: (cl->GetRow()>126) ? 1:2;
691 Double_t angle = seed->GetSnp()*seed->GetSnp();
692 angle = TMath::Sqrt(TMath::Abs(angle/(1.-angle)));
693 Double_t erry2 = clparam->GetError0Par(0,type, z,angle);
695 erry2+=0.5; // edge cluster
699 const Double_t *errInner = AliTPCReconstructor::GetRecoParam()->GetSystematicErrorClusterInner();
700 addErr=errInner[0]*TMath::Exp(-TMath::Abs((cl->GetX()-85.)/errInner[1]));
701 erry2+=addErr*addErr;
702 seed->SetErrorY2(erry2);
706 //calculate look-up table at the beginning
707 // static Bool_t ginit = kFALSE;
708 // static Float_t gnoise1,gnoise2,gnoise3;
709 // static Float_t ggg1[10000];
710 // static Float_t ggg2[10000];
711 // static Float_t ggg3[10000];
712 // static Float_t glandau1[10000];
713 // static Float_t glandau2[10000];
714 // static Float_t glandau3[10000];
716 // static Float_t gcor01[500];
717 // static Float_t gcor02[500];
718 // static Float_t gcorp[500];
722 // if (ginit==kFALSE){
723 // for (Int_t i=1;i<500;i++){
724 // Float_t rsigma = float(i)/100.;
725 // gcor02[i] = TMath::Max(0.78 +TMath::Exp(7.4*(rsigma-1.2)),0.6);
726 // gcor01[i] = TMath::Max(0.72 +TMath::Exp(3.36*(rsigma-1.2)),0.6);
727 // gcorp[i] = TMath::Max(TMath::Power((rsigma+0.5),1.5),1.2);
731 // for (Int_t i=3;i<10000;i++){
735 // Float_t amp = float(i);
736 // Float_t padlength =0.75;
737 // gnoise1 = 0.0004/padlength;
738 // Float_t nel = 0.268*amp;
739 // Float_t nprim = 0.155*amp;
740 // ggg1[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.001*nel/(padlength*padlength))/nel;
741 // glandau1[i] = (2.+0.12*nprim)*0.5* (2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
742 // if (glandau1[i]>1) glandau1[i]=1;
743 // glandau1[i]*=padlength*padlength/12.;
747 // gnoise2 = 0.0004/padlength;
749 // nprim = 0.133*amp;
750 // ggg2[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
751 // glandau2[i] = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
752 // if (glandau2[i]>1) glandau2[i]=1;
753 // glandau2[i]*=padlength*padlength/12.;
758 // gnoise3 = 0.0004/padlength;
760 // nprim = 0.133*amp;
761 // ggg3[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
762 // glandau3[i] = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
763 // if (glandau3[i]>1) glandau3[i]=1;
764 // glandau3[i]*=padlength*padlength/12.;
772 // Int_t amp = int(TMath::Abs(cl->GetQ()));
774 // seed->SetErrorY2(1.);
778 // Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
779 // Int_t ctype = cl->GetType();
780 // Float_t padlength= GetPadPitchLength(seed->GetRow());
781 // Double_t angle2 = seed->GetSnp()*seed->GetSnp();
782 // angle2 = angle2/(1-angle2);
784 // //cluster "quality"
785 // Int_t rsigmay = int(100.*cl->GetSigmaY2()/(seed->GetCurrentSigmaY2()));
788 // if (fSectors==fInnerSec){
789 // snoise2 = gnoise1;
790 // res = ggg1[amp]*z+glandau1[amp]*angle2;
791 // if (ctype==0) res *= gcor01[rsigmay];
794 // res*= gcorp[rsigmay];
798 // if (padlength<1.1){
799 // snoise2 = gnoise2;
800 // res = ggg2[amp]*z+glandau2[amp]*angle2;
801 // if (ctype==0) res *= gcor02[rsigmay];
804 // res*= gcorp[rsigmay];
808 // snoise2 = gnoise3;
809 // res = ggg3[amp]*z+glandau3[amp]*angle2;
810 // if (ctype==0) res *= gcor02[rsigmay];
813 // res*= gcorp[rsigmay];
820 // res*=2.4; // overestimate error 2 times
824 // if (res<2*snoise2)
827 // seed->SetErrorY2(res);
835 Double_t AliTPCtrackerMI::ErrZ2(AliTPCseed* seed, const AliTPCclusterMI * cl){
838 // Use calibrated cluster error from OCDB
840 AliTPCClusterParam * clparam = AliTPCcalibDB::Instance()->GetClusterParam();
842 Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
843 Int_t ctype = cl->GetType();
844 Int_t type = (cl->GetRow()<63) ? 0: (cl->GetRow()>126) ? 1:2;
846 Double_t angle2 = seed->GetSnp()*seed->GetSnp();
847 angle2 = seed->GetTgl()*seed->GetTgl()*(1+angle2/(1-angle2));
848 Double_t angle = TMath::Sqrt(TMath::Abs(angle2));
849 Double_t errz2 = clparam->GetError0Par(1,type, z,angle);
851 errz2+=0.5; // edge cluster
855 const Double_t *errInner = AliTPCReconstructor::GetRecoParam()->GetSystematicErrorClusterInner();
856 addErr=errInner[0]*TMath::Exp(-TMath::Abs((cl->GetX()-85.)/errInner[1]));
857 errz2+=addErr*addErr;
858 seed->SetErrorZ2(errz2);
864 // //seed->SetErrorY2(0.1);
866 // //calculate look-up table at the beginning
867 // static Bool_t ginit = kFALSE;
868 // static Float_t gnoise1,gnoise2,gnoise3;
869 // static Float_t ggg1[10000];
870 // static Float_t ggg2[10000];
871 // static Float_t ggg3[10000];
872 // static Float_t glandau1[10000];
873 // static Float_t glandau2[10000];
874 // static Float_t glandau3[10000];
876 // static Float_t gcor01[1000];
877 // static Float_t gcor02[1000];
878 // static Float_t gcorp[1000];
882 // if (ginit==kFALSE){
883 // for (Int_t i=1;i<1000;i++){
884 // Float_t rsigma = float(i)/100.;
885 // gcor02[i] = TMath::Max(0.81 +TMath::Exp(6.8*(rsigma-1.2)),0.6);
886 // gcor01[i] = TMath::Max(0.72 +TMath::Exp(2.04*(rsigma-1.2)),0.6);
887 // gcorp[i] = TMath::Max(TMath::Power((rsigma+0.5),1.5),1.2);
891 // for (Int_t i=3;i<10000;i++){
895 // Float_t amp = float(i);
896 // Float_t padlength =0.75;
897 // gnoise1 = 0.0004/padlength;
898 // Float_t nel = 0.268*amp;
899 // Float_t nprim = 0.155*amp;
900 // ggg1[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.001*nel/(padlength*padlength))/nel;
901 // glandau1[i] = (2.+0.12*nprim)*0.5* (2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
902 // if (glandau1[i]>1) glandau1[i]=1;
903 // glandau1[i]*=padlength*padlength/12.;
907 // gnoise2 = 0.0004/padlength;
909 // nprim = 0.133*amp;
910 // ggg2[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
911 // glandau2[i] = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
912 // if (glandau2[i]>1) glandau2[i]=1;
913 // glandau2[i]*=padlength*padlength/12.;
918 // gnoise3 = 0.0004/padlength;
920 // nprim = 0.133*amp;
921 // ggg3[i] = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
922 // glandau3[i] = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
923 // if (glandau3[i]>1) glandau3[i]=1;
924 // glandau3[i]*=padlength*padlength/12.;
932 // Int_t amp = int(TMath::Abs(cl->GetQ()));
934 // seed->SetErrorY2(1.);
938 // Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
939 // Int_t ctype = cl->GetType();
940 // Float_t padlength= GetPadPitchLength(seed->GetRow());
942 // Double_t angle2 = seed->GetSnp()*seed->GetSnp();
943 // // if (angle2<0.6) angle2 = 0.6;
944 // angle2 = seed->GetTgl()*seed->GetTgl()*(1+angle2/(1-angle2));
946 // //cluster "quality"
947 // Int_t rsigmaz = int(100.*cl->GetSigmaZ2()/(seed->GetCurrentSigmaZ2()));
950 // if (fSectors==fInnerSec){
951 // snoise2 = gnoise1;
952 // res = ggg1[amp]*z+glandau1[amp]*angle2;
953 // if (ctype==0) res *= gcor01[rsigmaz];
956 // res*= gcorp[rsigmaz];
960 // if (padlength<1.1){
961 // snoise2 = gnoise2;
962 // res = ggg2[amp]*z+glandau2[amp]*angle2;
963 // if (ctype==0) res *= gcor02[rsigmaz];
966 // res*= gcorp[rsigmaz];
970 // snoise2 = gnoise3;
971 // res = ggg3[amp]*z+glandau3[amp]*angle2;
972 // if (ctype==0) res *= gcor02[rsigmaz];
975 // res*= gcorp[rsigmaz];
984 // if ((ctype<0) &&<70){
989 // if (res<2*snoise2)
991 // if (res>3) res =3;
992 // seed->SetErrorZ2(res);
1000 void AliTPCtrackerMI::RotateToLocal(AliTPCseed *seed)
1002 //rotate to track "local coordinata
1003 Float_t x = seed->GetX();
1004 Float_t y = seed->GetY();
1005 Float_t ymax = x*TMath::Tan(0.5*fSectors->GetAlpha());
1008 seed->SetRelativeSector((seed->GetRelativeSector()+1) % fN);
1009 if (!seed->Rotate(fSectors->GetAlpha()))
1011 } else if (y <-ymax) {
1012 seed->SetRelativeSector((seed->GetRelativeSector()-1+fN) % fN);
1013 if (!seed->Rotate(-fSectors->GetAlpha()))
1021 //_____________________________________________________________________________
1022 Double_t AliTPCtrackerMI::F1old(Double_t x1,Double_t y1,
1023 Double_t x2,Double_t y2,
1024 Double_t x3,Double_t y3) const
1026 //-----------------------------------------------------------------
1027 // Initial approximation of the track curvature
1028 //-----------------------------------------------------------------
1029 Double_t d=(x2-x1)*(y3-y2)-(x3-x2)*(y2-y1);
1030 Double_t a=0.5*((y3-y2)*(y2*y2-y1*y1+x2*x2-x1*x1)-
1031 (y2-y1)*(y3*y3-y2*y2+x3*x3-x2*x2));
1032 Double_t b=0.5*((x2-x1)*(y3*y3-y2*y2+x3*x3-x2*x2)-
1033 (x3-x2)*(y2*y2-y1*y1+x2*x2-x1*x1));
1035 Double_t xr=TMath::Abs(d/(d*x1-a)), yr=d/(d*y1-b);
1036 if ( xr*xr+yr*yr<=0.00000000000001) return 100;
1037 return -xr*yr/sqrt(xr*xr+yr*yr);
1042 //_____________________________________________________________________________
1043 Double_t AliTPCtrackerMI::F1(Double_t x1,Double_t y1,
1044 Double_t x2,Double_t y2,
1045 Double_t x3,Double_t y3) const
1047 //-----------------------------------------------------------------
1048 // Initial approximation of the track curvature
1049 //-----------------------------------------------------------------
1055 Double_t det = x3*y2-x2*y3;
1056 if (TMath::Abs(det)<1e-10){
1060 Double_t u = 0.5* (x2*(x2-x3)+y2*(y2-y3))/det;
1061 Double_t x0 = x3*0.5-y3*u;
1062 Double_t y0 = y3*0.5+x3*u;
1063 Double_t c2 = 1/TMath::Sqrt(x0*x0+y0*y0);
1069 Double_t AliTPCtrackerMI::F2(Double_t x1,Double_t y1,
1070 Double_t x2,Double_t y2,
1071 Double_t x3,Double_t y3) const
1073 //-----------------------------------------------------------------
1074 // Initial approximation of the track curvature
1075 //-----------------------------------------------------------------
1081 Double_t det = x3*y2-x2*y3;
1082 if (TMath::Abs(det)<1e-10) {
1086 Double_t u = 0.5* (x2*(x2-x3)+y2*(y2-y3))/det;
1087 Double_t x0 = x3*0.5-y3*u;
1088 Double_t y0 = y3*0.5+x3*u;
1089 Double_t c2 = 1/TMath::Sqrt(x0*x0+y0*y0);
1098 //_____________________________________________________________________________
1099 Double_t AliTPCtrackerMI::F2old(Double_t x1,Double_t y1,
1100 Double_t x2,Double_t y2,
1101 Double_t x3,Double_t y3) const
1103 //-----------------------------------------------------------------
1104 // Initial approximation of the track curvature times center of curvature
1105 //-----------------------------------------------------------------
1106 Double_t d=(x2-x1)*(y3-y2)-(x3-x2)*(y2-y1);
1107 Double_t a=0.5*((y3-y2)*(y2*y2-y1*y1+x2*x2-x1*x1)-
1108 (y2-y1)*(y3*y3-y2*y2+x3*x3-x2*x2));
1109 Double_t b=0.5*((x2-x1)*(y3*y3-y2*y2+x3*x3-x2*x2)-
1110 (x3-x2)*(y2*y2-y1*y1+x2*x2-x1*x1));
1112 Double_t xr=TMath::Abs(d/(d*x1-a)), yr=d/(d*y1-b);
1114 return -a/(d*y1-b)*xr/sqrt(xr*xr+yr*yr);
1117 //_____________________________________________________________________________
1118 Double_t AliTPCtrackerMI::F3(Double_t x1,Double_t y1,
1119 Double_t x2,Double_t y2,
1120 Double_t z1,Double_t z2) const
1122 //-----------------------------------------------------------------
1123 // Initial approximation of the tangent of the track dip angle
1124 //-----------------------------------------------------------------
1125 return (z1 - z2)/sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
1129 Double_t AliTPCtrackerMI::F3n(Double_t x1,Double_t y1,
1130 Double_t x2,Double_t y2,
1131 Double_t z1,Double_t z2, Double_t c) const
1133 //-----------------------------------------------------------------
1134 // Initial approximation of the tangent of the track dip angle
1135 //-----------------------------------------------------------------
1139 //angle1 = (z1-z2)*c/(TMath::ASin(c*x1-ni)-TMath::ASin(c*x2-ni));
1141 Double_t d = TMath::Sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
1142 if (TMath::Abs(d*c*0.5)>1) return 0;
1143 // Double_t angle2 = TMath::ASin(d*c*0.5);
1144 // Double_t angle2 = AliTPCFastMath::FastAsin(d*c*0.5);
1145 Double_t angle2 = (d*c*0.5>0.1)? TMath::ASin(d*c*0.5): AliTPCFastMath::FastAsin(d*c*0.5);
1147 angle2 = (z1-z2)*c/(angle2*2.);
1151 Bool_t AliTPCtrackerMI::GetProlongation(Double_t x1, Double_t x2, Double_t x[5], Double_t &y, Double_t &z) const
1152 {//-----------------------------------------------------------------
1153 // This function find proloncation of a track to a reference plane x=x2.
1154 //-----------------------------------------------------------------
1158 if (TMath::Abs(x[4]*x1 - x[2]) >= 0.999) {
1162 Double_t c1=x[4]*x1 - x[2], r1=TMath::Sqrt((1.-c1)*(1.+c1));
1163 Double_t c2=x[4]*x2 - x[2], r2=TMath::Sqrt((1.-c2)*(1.+c2));
1167 Double_t dy = dx*(c1+c2)/(r1+r2);
1170 Double_t delta = x[4]*dx*(c1+c2)/(c1*r2 + c2*r1);
1172 if (TMath::Abs(delta)>0.01){
1173 dz = x[3]*TMath::ASin(delta)/x[4];
1175 dz = x[3]*AliTPCFastMath::FastAsin(delta)/x[4];
1178 //dz = x[3]*AliTPCFastMath::FastAsin(delta)/x[4];
1186 Int_t AliTPCtrackerMI::LoadClusters (TTree *const tree)
1191 return LoadClusters();
1195 Int_t AliTPCtrackerMI::LoadClusters(const TObjArray *arr)
1198 // load clusters to the memory
1199 AliTPCClustersRow *clrow = new AliTPCClustersRow("AliTPCclusterMI");
1200 Int_t lower = arr->LowerBound();
1201 Int_t entries = arr->GetEntriesFast();
1203 for (Int_t i=lower; i<entries; i++) {
1204 clrow = (AliTPCClustersRow*) arr->At(i);
1205 if(!clrow) continue;
1206 if(!clrow->GetArray()) continue;
1210 fkParam->AdjustSectorRow(clrow->GetID(),sec,row);
1212 for (Int_t icl=0; icl<clrow->GetArray()->GetEntriesFast(); icl++){
1213 Transform((AliTPCclusterMI*)(clrow->GetArray()->At(icl)));
1216 if (clrow->GetArray()->GetEntriesFast()<=0) continue;
1217 AliTPCtrackerRow * tpcrow=0;
1220 tpcrow = &(fInnerSec[sec%fkNIS][row]);
1224 tpcrow = &(fOuterSec[(sec-fkNIS*2)%fkNOS][row]);
1225 left = (sec-fkNIS*2)/fkNOS;
1228 tpcrow->SetN1(clrow->GetArray()->GetEntriesFast());
1229 for (Int_t j=0;j<tpcrow->GetN1();++j)
1230 tpcrow->SetCluster1(j, *(AliTPCclusterMI*)(clrow->GetArray()->At(j)));
1233 tpcrow->SetN2(clrow->GetArray()->GetEntriesFast());
1234 for (Int_t j=0;j<tpcrow->GetN2();++j)
1235 tpcrow->SetCluster2(j, *(AliTPCclusterMI*)(clrow->GetArray()->At(j)));
1237 clrow->GetArray()->Clear("C");
1243 ApllyTailCancellation();
1247 Int_t AliTPCtrackerMI::LoadClusters(const TClonesArray *arr)
1250 // load clusters to the memory from one
1253 AliTPCclusterMI *clust=0;
1254 Int_t count[72][96] = { {0} , {0} };
1256 // loop over clusters
1257 for (Int_t icl=0; icl<arr->GetEntriesFast(); icl++) {
1258 clust = (AliTPCclusterMI*)arr->At(icl);
1259 if(!clust) continue;
1260 //printf("cluster: det %d, row %d \n", clust->GetDetector(),clust->GetRow());
1262 // transform clusters
1265 // count clusters per pad row
1266 count[clust->GetDetector()][clust->GetRow()]++;
1269 // insert clusters to sectors
1270 for (Int_t icl=0; icl<arr->GetEntriesFast(); icl++) {
1271 clust = (AliTPCclusterMI*)arr->At(icl);
1272 if(!clust) continue;
1274 Int_t sec = clust->GetDetector();
1275 Int_t row = clust->GetRow();
1277 // filter overlapping pad rows needed by HLT
1278 if(sec<fkNIS*2) { //IROCs
1279 if(row == 30) continue;
1282 if(row == 27 || row == 76) continue;
1287 // left = sec/fkNIS;
1288 fInnerSec[sec%fkNIS].InsertCluster(clust, count[sec][row], fkParam);
1291 // left = (sec-fkNIS*2)/fkNOS;
1292 fOuterSec[(sec-fkNIS*2)%fkNOS].InsertCluster(clust, count[sec][row], fkParam);
1296 // Load functions must be called behind LoadCluster(TClonesArray*)
1298 //LoadOuterSectors();
1299 //LoadInnerSectors();
1305 Int_t AliTPCtrackerMI::LoadClusters()
1308 // load clusters to the memory
1309 static AliTPCClustersRow *clrow= new AliTPCClustersRow("AliTPCclusterMI");
1311 // TTree * tree = fClustersArray.GetTree();
1313 TTree * tree = fInput;
1314 TBranch * br = tree->GetBranch("Segment");
1315 br->SetAddress(&clrow);
1317 // Conversion of pad, row coordinates in local tracking coords.
1318 // Could be skipped here; is already done in clusterfinder
1320 Int_t j=Int_t(tree->GetEntries());
1321 for (Int_t i=0; i<j; i++) {
1325 fkParam->AdjustSectorRow(clrow->GetID(),sec,row);
1326 for (Int_t icl=0; icl<clrow->GetArray()->GetEntriesFast(); icl++){
1327 Transform((AliTPCclusterMI*)(clrow->GetArray()->At(icl)));
1330 AliTPCtrackerRow * tpcrow=0;
1333 tpcrow = &(fInnerSec[sec%fkNIS][row]);
1337 tpcrow = &(fOuterSec[(sec-fkNIS*2)%fkNOS][row]);
1338 left = (sec-fkNIS*2)/fkNOS;
1341 tpcrow->SetN1(clrow->GetArray()->GetEntriesFast());
1342 for (Int_t k=0;k<tpcrow->GetN1();++k)
1343 tpcrow->SetCluster1(k, *(AliTPCclusterMI*)(clrow->GetArray()->At(k)));
1346 tpcrow->SetN2(clrow->GetArray()->GetEntriesFast());
1347 for (Int_t k=0;k<tpcrow->GetN2();++k)
1348 tpcrow->SetCluster2(k, *(AliTPCclusterMI*)(clrow->GetArray()->At(k)));
1359 void AliTPCtrackerMI::UnloadClusters()
1362 // unload clusters from the memory
1364 Int_t nrows = fOuterSec->GetNRows();
1365 for (Int_t sec = 0;sec<fkNOS;sec++)
1366 for (Int_t row = 0;row<nrows;row++){
1367 AliTPCtrackerRow* tpcrow = &(fOuterSec[sec%fkNOS][row]);
1369 // if (tpcrow->fClusters1) delete []tpcrow->fClusters1;
1370 // if (tpcrow->fClusters2) delete []tpcrow->fClusters2;
1372 tpcrow->ResetClusters();
1375 nrows = fInnerSec->GetNRows();
1376 for (Int_t sec = 0;sec<fkNIS;sec++)
1377 for (Int_t row = 0;row<nrows;row++){
1378 AliTPCtrackerRow* tpcrow = &(fInnerSec[sec%fkNIS][row]);
1380 // if (tpcrow->fClusters1) delete []tpcrow->fClusters1;
1381 //if (tpcrow->fClusters2) delete []tpcrow->fClusters2;
1383 tpcrow->ResetClusters();
1389 void AliTPCtrackerMI::FillClusterArray(TObjArray* array) const{
1391 // Filling cluster to the array - For visualization purposes
1394 nrows = fOuterSec->GetNRows();
1395 for (Int_t sec = 0;sec<fkNOS;sec++)
1396 for (Int_t row = 0;row<nrows;row++){
1397 AliTPCtrackerRow* tpcrow = &(fOuterSec[sec%fkNOS][row]);
1398 if (!tpcrow) continue;
1399 for (Int_t icl = 0;icl<tpcrow->GetN();icl++){
1400 array->AddLast((TObject*)((*tpcrow)[icl]));
1403 nrows = fInnerSec->GetNRows();
1404 for (Int_t sec = 0;sec<fkNIS;sec++)
1405 for (Int_t row = 0;row<nrows;row++){
1406 AliTPCtrackerRow* tpcrow = &(fInnerSec[sec%fkNIS][row]);
1407 if (!tpcrow) continue;
1408 for (Int_t icl = 0;icl<tpcrow->GetN();icl++){
1409 array->AddLast((TObject*)(*tpcrow)[icl]);
1415 void AliTPCtrackerMI::Transform(AliTPCclusterMI * cluster){
1419 AliTPCcalibDB * calibDB = AliTPCcalibDB::Instance();
1420 AliTPCTransform *transform = calibDB->GetTransform() ;
1422 AliFatal("Tranformations not in calibDB");
1425 transform->SetCurrentRecoParam((AliTPCRecoParam*)AliTPCReconstructor::GetRecoParam());
1426 Double_t x[3]={cluster->GetRow(),cluster->GetPad(),cluster->GetTimeBin()};
1427 Int_t i[1]={cluster->GetDetector()};
1428 transform->Transform(x,i,0,1);
1429 // if (cluster->GetDetector()%36>17){
1434 // in debug mode check the transformation
1436 if (AliTPCReconstructor::StreamLevel()>2) {
1438 cluster->GetGlobalXYZ(gx);
1439 Int_t event = (fEvent==NULL)? 0: fEvent->GetEventNumberInFile();
1440 TTreeSRedirector &cstream = *fDebugStreamer;
1441 cstream<<"Transform"<<
1452 cluster->SetX(x[0]);
1453 cluster->SetY(x[1]);
1454 cluster->SetZ(x[2]);
1459 //if (!fkParam->IsGeoRead()) fkParam->ReadGeoMatrices();
1460 if (AliTPCReconstructor::GetRecoParam()->GetUseSectorAlignment() && (!calibDB->HasAlignmentOCDB())){
1461 TGeoHMatrix *mat = fkParam->GetClusterMatrix(cluster->GetDetector());
1463 Double_t pos[3]= {cluster->GetX(),cluster->GetY(),cluster->GetZ()};
1464 Double_t posC[3]={cluster->GetX(),cluster->GetY(),cluster->GetZ()};
1465 if (mat) mat->LocalToMaster(pos,posC);
1467 // chack Loading of Geo matrices from GeoManager - TEMPORARY FIX
1469 cluster->SetX(posC[0]);
1470 cluster->SetY(posC[1]);
1471 cluster->SetZ(posC[2]);
1475 void AliTPCtrackerMI::ApllyTailCancellation(){
1477 // Correct the cluster charge for the tail from the previous clusters
1478 // The TimeResponse function accessed via AliTPCcalibDB (TPC/Calib/IonTail)
1482 for (Int_t secType=0; secType<2; secType++){ //loop inner or outer sector
1485 for (Int_t sec = 0;sec<fkNOS;sec++){ //loop overs sectors
1488 AliTPCtrackerSector §or= (secType==0)?fInnerSec[sec]:fOuterSec[sec];
1490 Int_t nrows = sector.GetNRows();
1491 for (Int_t row = 0;row<nrows;row++){ //loop over rows
1492 AliTPCtrackerRow& tpcrow = sector[row];
1493 Int_t ncl = tpcrow.GetN1();
1495 for (Int_t icl0=0; icl0<ncl;icl0++){ // first loop over clusters
1496 AliTPCclusterMI *cl0= (tpcrow.GetCluster1(icl0));
1497 if (!icl0) continue;
1498 for (Int_t icl1=0; icl1<ncl;icl1++){ // second loop over clusters
1499 AliTPCclusterMI *cl1= (tpcrow.GetCluster1(icl1));
1500 if (!icl1) continue;
1501 if (TMath::Abs(cl0->GetPad()-cl1->GetPad())>2) continue; // no contribution if far away in pad direction
1502 if (cl1->GetTimeBin()> cl0->GetTimeBin()) continue; // no contibution to the tail if later
1503 Double_t ionTailMax=0; //
1504 Double_t ionTailTotal=0; //
1506 cl0->SetQ(cl0->GetQ()+ionTailTotal);
1507 cl0->SetMax(cl0->GetMax()+ionTailMax);
1508 if (AliTPCReconstructor::StreamLevel()>5) {
1509 TTreeSRedirector &cstream = *fDebugStreamer;
1510 cstream<<"IonTail"<<
1511 "cl0.="<<cl0<< // cluster 0 (to be corrected)
1512 "cl1.="<<cl1<< // cluster 1 (previous cluster)
1513 "ionTailTotal="<<ionTailTotal<< // ion Tail from cluster 1 contribution to cluster0
1514 "ionTailMax="<<ionTailMax<< // ion Tail from cluster 1 contribution to cluster0
1516 }// dump the results to the debug streamer if in debug mode
1517 }//end of secon loop over clusters
1518 }//end of first loop over cluster
1519 }//end of loop over rows
1520 }//end of loop over sectors
1521 }//end of loop over IROC/OROC
1527 //_____________________________________________________________________________
1528 Int_t AliTPCtrackerMI::LoadOuterSectors() {
1529 //-----------------------------------------------------------------
1530 // This function fills outer TPC sectors with clusters.
1531 //-----------------------------------------------------------------
1532 Int_t nrows = fOuterSec->GetNRows();
1534 for (Int_t sec = 0;sec<fkNOS;sec++)
1535 for (Int_t row = 0;row<nrows;row++){
1536 AliTPCtrackerRow* tpcrow = &(fOuterSec[sec%fkNOS][row]);
1537 Int_t sec2 = sec+2*fkNIS;
1539 Int_t ncl = tpcrow->GetN1();
1541 AliTPCclusterMI *c= (tpcrow->GetCluster1(ncl));
1542 index=(((sec2<<8)+row)<<16)+ncl;
1543 tpcrow->InsertCluster(c,index);
1546 ncl = tpcrow->GetN2();
1548 AliTPCclusterMI *c= (tpcrow->GetCluster2(ncl));
1549 index=((((sec2+fkNOS)<<8)+row)<<16)+ncl;
1550 tpcrow->InsertCluster(c,index);
1553 // write indexes for fast acces
1555 for (Int_t i=0;i<510;i++)
1556 tpcrow->SetFastCluster(i,-1);
1557 for (Int_t i=0;i<tpcrow->GetN();i++){
1558 Int_t zi = Int_t((*tpcrow)[i]->GetZ()+255.);
1559 tpcrow->SetFastCluster(zi,i); // write index
1562 for (Int_t i=0;i<510;i++){
1563 if (tpcrow->GetFastCluster(i)<0)
1564 tpcrow->SetFastCluster(i,last);
1566 last = tpcrow->GetFastCluster(i);
1575 //_____________________________________________________________________________
1576 Int_t AliTPCtrackerMI::LoadInnerSectors() {
1577 //-----------------------------------------------------------------
1578 // This function fills inner TPC sectors with clusters.
1579 //-----------------------------------------------------------------
1580 Int_t nrows = fInnerSec->GetNRows();
1582 for (Int_t sec = 0;sec<fkNIS;sec++)
1583 for (Int_t row = 0;row<nrows;row++){
1584 AliTPCtrackerRow* tpcrow = &(fInnerSec[sec%fkNIS][row]);
1587 Int_t ncl = tpcrow->GetN1();
1589 AliTPCclusterMI *c= (tpcrow->GetCluster1(ncl));
1590 index=(((sec<<8)+row)<<16)+ncl;
1591 tpcrow->InsertCluster(c,index);
1594 ncl = tpcrow->GetN2();
1596 AliTPCclusterMI *c= (tpcrow->GetCluster2(ncl));
1597 index=((((sec+fkNIS)<<8)+row)<<16)+ncl;
1598 tpcrow->InsertCluster(c,index);
1601 // write indexes for fast acces
1603 for (Int_t i=0;i<510;i++)
1604 tpcrow->SetFastCluster(i,-1);
1605 for (Int_t i=0;i<tpcrow->GetN();i++){
1606 Int_t zi = Int_t((*tpcrow)[i]->GetZ()+255.);
1607 tpcrow->SetFastCluster(zi,i); // write index
1610 for (Int_t i=0;i<510;i++){
1611 if (tpcrow->GetFastCluster(i)<0)
1612 tpcrow->SetFastCluster(i,last);
1614 last = tpcrow->GetFastCluster(i);
1626 //_________________________________________________________________________
1627 AliTPCclusterMI *AliTPCtrackerMI::GetClusterMI(Int_t index) const {
1628 //--------------------------------------------------------------------
1629 // Return pointer to a given cluster
1630 //--------------------------------------------------------------------
1631 if (index<0) return 0; // no cluster
1632 Int_t sec=(index&0xff000000)>>24;
1633 Int_t row=(index&0x00ff0000)>>16;
1634 Int_t ncl=(index&0x00007fff)>>00;
1636 const AliTPCtrackerRow * tpcrow=0;
1637 TClonesArray * clrow =0;
1639 if (sec<0 || sec>=fkNIS*4) {
1640 AliWarning(Form("Wrong sector %d",sec));
1645 AliTPCtrackerSector& tracksec = fInnerSec[sec%fkNIS];
1646 if (tracksec.GetNRows()<=row) return 0;
1647 tpcrow = &(tracksec[row]);
1648 if (tpcrow==0) return 0;
1651 if (tpcrow->GetN1()<=ncl) return 0;
1652 clrow = tpcrow->GetClusters1();
1655 if (tpcrow->GetN2()<=ncl) return 0;
1656 clrow = tpcrow->GetClusters2();
1660 AliTPCtrackerSector& tracksec = fOuterSec[(sec-fkNIS*2)%fkNOS];
1661 if (tracksec.GetNRows()<=row) return 0;
1662 tpcrow = &(tracksec[row]);
1663 if (tpcrow==0) return 0;
1665 if (sec-2*fkNIS<fkNOS) {
1666 if (tpcrow->GetN1()<=ncl) return 0;
1667 clrow = tpcrow->GetClusters1();
1670 if (tpcrow->GetN2()<=ncl) return 0;
1671 clrow = tpcrow->GetClusters2();
1675 return (AliTPCclusterMI*)clrow->At(ncl);
1681 Int_t AliTPCtrackerMI::FollowToNext(AliTPCseed& t, Int_t nr) {
1682 //-----------------------------------------------------------------
1683 // This function tries to find a track prolongation to next pad row
1684 //-----------------------------------------------------------------
1686 Double_t x= GetXrow(nr), ymax=GetMaxY(nr);
1689 AliTPCclusterMI *cl=0;
1690 Int_t tpcindex= t.GetClusterIndex2(nr);
1692 // update current shape info every 5 pad-row
1693 // if ( (nr%5==0) || t.GetNumberOfClusters()<2 || (t.fCurrentSigmaY2<0.0001) ){
1697 if (fIteration>0 && tpcindex>=-1){ //if we have already clusters
1699 if (tpcindex==-1) return 0; //track in dead zone
1700 if (tpcindex >= 0){ //
1701 cl = t.GetClusterPointer(nr);
1702 //if (cl==0) cl = GetClusterMI(tpcindex);
1703 if (!cl) cl = GetClusterMI(tpcindex);
1704 t.SetCurrentClusterIndex1(tpcindex);
1707 Int_t relativesector = ((tpcindex&0xff000000)>>24)%18; // if previously accepted cluster in different sector
1708 Float_t angle = relativesector*fSectors->GetAlpha()+fSectors->GetAlphaShift();
1710 if (angle<-TMath::Pi()) angle += 2*TMath::Pi();
1711 if (angle>=TMath::Pi()) angle -= 2*TMath::Pi();
1713 if (TMath::Abs(angle-t.GetAlpha())>0.001){
1714 Double_t rotation = angle-t.GetAlpha();
1715 t.SetRelativeSector(relativesector);
1716 if (!t.Rotate(rotation)) {
1717 t.SetClusterIndex(nr, t.GetClusterIndex(nr) | 0x8000);
1721 if (!t.PropagateTo(x)) {
1722 t.SetClusterIndex(nr, t.GetClusterIndex(nr) | 0x8000);
1726 t.SetCurrentCluster(cl);
1728 Int_t accept = AcceptCluster(&t,t.GetCurrentCluster());
1729 if ((tpcindex&0x8000)==0) accept =0;
1731 //if founded cluster is acceptible
1732 if (cl->IsUsed(11)) { // id cluster is shared inrease uncertainty
1733 t.SetErrorY2(t.GetErrorY2()+0.03);
1734 t.SetErrorZ2(t.GetErrorZ2()+0.03);
1735 t.SetErrorY2(t.GetErrorY2()*3);
1736 t.SetErrorZ2(t.GetErrorZ2()*3);
1738 t.SetNFoundable(t.GetNFoundable()+1);
1739 UpdateTrack(&t,accept);
1742 else { // Remove old cluster from track
1743 t.SetClusterIndex(nr, -3);
1744 t.SetClusterPointer(nr, 0);
1748 if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()) return 0; // cut on angle
1749 if (fIteration>1 && IsFindable(t)){
1750 // not look for new cluster during refitting
1751 t.SetNFoundable(t.GetNFoundable()+1);
1756 // if (TMath::Abs(t.GetSnp())>0.95 || TMath::Abs(x*t.GetC()-t.GetEta())>0.95) return 0;// patch 28 fev 06
1757 if (!t.PropagateTo(x)) {
1758 if (fIteration==0) t.SetRemoval(10);
1761 Double_t y = t.GetY();
1762 if (TMath::Abs(y)>ymax){
1764 t.SetRelativeSector((t.GetRelativeSector()+1) % fN);
1765 if (!t.Rotate(fSectors->GetAlpha()))
1767 } else if (y <-ymax) {
1768 t.SetRelativeSector((t.GetRelativeSector()-1+fN) % fN);
1769 if (!t.Rotate(-fSectors->GetAlpha()))
1772 if (!t.PropagateTo(x)) {
1773 if (fIteration==0) t.SetRemoval(10);
1779 Double_t z=t.GetZ();
1782 if (!IsActive(t.GetRelativeSector(),nr)) {
1784 t.SetClusterIndex2(nr,-1);
1787 //AliInfo(Form("A - Sector%d phi %f - alpha %f", t.fRelativeSector,y/x, t.GetAlpha()));
1788 Bool_t isActive = IsActive(t.GetRelativeSector(),nr);
1789 Bool_t isActive2 = (nr>=fInnerSec->GetNRows()) ? fOuterSec[t.GetRelativeSector()][nr-fInnerSec->GetNRows()].GetN()>0:fInnerSec[t.GetRelativeSector()][nr].GetN()>0;
1791 if (!isActive || !isActive2) return 0;
1793 const AliTPCtrackerRow &krow=GetRow(t.GetRelativeSector(),nr);
1794 if ( (t.GetSigmaY2()<0) || t.GetSigmaZ2()<0) return 0;
1796 Double_t roadz = 1.;
1798 if (TMath::Abs(TMath::Abs(y)-ymax)<krow.GetDeadZone()){
1800 t.SetClusterIndex2(nr,-1);
1806 // if (TMath::Abs(z)<(AliTPCReconstructor::GetCtgRange()*x+10) && TMath::Abs(z)<fkParam->GetZLength(0) && (TMath::Abs(t.GetSnp())<AliTPCReconstructor::GetMaxSnpTracker()))
1807 t.SetNFoundable(t.GetNFoundable()+1);
1813 // cl = krow.FindNearest2(y+10.,z,roady,roadz,index);
1814 cl = krow.FindNearest2(y,z,roady,roadz,index);
1815 if (cl) t.SetCurrentClusterIndex1(krow.GetIndex(index));
1818 t.SetCurrentCluster(cl);
1820 if (fIteration==2&&cl->IsUsed(10)) return 0;
1821 Int_t accept = AcceptCluster(&t,t.GetCurrentCluster());
1822 if (fIteration==2&&cl->IsUsed(11)) {
1823 t.SetErrorY2(t.GetErrorY2()+0.03);
1824 t.SetErrorZ2(t.GetErrorZ2()+0.03);
1825 t.SetErrorY2(t.GetErrorY2()*3);
1826 t.SetErrorZ2(t.GetErrorZ2()*3);
1829 if (t.fCurrentCluster->IsUsed(10)){
1834 if (t.fNShared>0.7*t.GetNumberOfClusters()) {
1840 if (accept<3) UpdateTrack(&t,accept);
1843 if ( fIteration==0 && t.GetNFoundable()*0.5 > t.GetNumberOfClusters()) t.SetRemoval(10);
1851 //_________________________________________________________________________
1852 Bool_t AliTPCtrackerMI::GetTrackPoint(Int_t index, AliTrackPoint &p ) const
1854 // Get track space point by index
1855 // return false in case the cluster doesn't exist
1856 AliTPCclusterMI *cl = GetClusterMI(index);
1857 if (!cl) return kFALSE;
1858 Int_t sector = (index&0xff000000)>>24;
1859 // Int_t row = (index&0x00ff0000)>>16;
1861 // xyz[0] = fkParam->GetPadRowRadii(sector,row);
1862 xyz[0] = cl->GetX();
1863 xyz[1] = cl->GetY();
1864 xyz[2] = cl->GetZ();
1866 fkParam->AdjustCosSin(sector,cos,sin);
1867 Float_t x = cos*xyz[0]-sin*xyz[1];
1868 Float_t y = cos*xyz[1]+sin*xyz[0];
1870 Float_t sigmaY2 = 0.027*cl->GetSigmaY2();
1871 if (sector < fkParam->GetNInnerSector()) sigmaY2 *= 2.07;
1872 Float_t sigmaZ2 = 0.066*cl->GetSigmaZ2();
1873 if (sector < fkParam->GetNInnerSector()) sigmaZ2 *= 1.77;
1874 cov[0] = sin*sin*sigmaY2;
1875 cov[1] = -sin*cos*sigmaY2;
1877 cov[3] = cos*cos*sigmaY2;
1880 p.SetXYZ(x,y,xyz[2],cov);
1881 AliGeomManager::ELayerID iLayer;
1883 if (sector < fkParam->GetNInnerSector()) {
1884 iLayer = AliGeomManager::kTPC1;
1888 iLayer = AliGeomManager::kTPC2;
1889 idet = sector - fkParam->GetNInnerSector();
1891 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
1892 p.SetVolumeID(volid);
1898 Int_t AliTPCtrackerMI::UpdateClusters(AliTPCseed& t, Int_t nr) {
1899 //-----------------------------------------------------------------
1900 // This function tries to find a track prolongation to next pad row
1901 //-----------------------------------------------------------------
1902 t.SetCurrentCluster(0);
1903 t.SetCurrentClusterIndex1(-3);
1905 Double_t xt=t.GetX();
1906 Int_t row = GetRowNumber(xt)-1;
1907 Double_t ymax= GetMaxY(nr);
1909 if (row < nr) return 1; // don't prolongate if not information until now -
1910 // if (TMath::Abs(t.GetSnp())>0.9 && t.GetNumberOfClusters()>40. && fIteration!=2) {
1912 // return 0; // not prolongate strongly inclined tracks
1914 // if (TMath::Abs(t.GetSnp())>0.95) {
1916 // return 0; // not prolongate strongly inclined tracks
1917 // }// patch 28 fev 06
1919 Double_t x= GetXrow(nr);
1921 //t.PropagateTo(x+0.02);
1922 //t.PropagateTo(x+0.01);
1923 if (!t.PropagateTo(x)){
1930 if (TMath::Abs(y)>ymax){
1932 t.SetRelativeSector((t.GetRelativeSector()+1) % fN);
1933 if (!t.Rotate(fSectors->GetAlpha()))
1935 } else if (y <-ymax) {
1936 t.SetRelativeSector((t.GetRelativeSector()-1+fN) % fN);
1937 if (!t.Rotate(-fSectors->GetAlpha()))
1940 // if (!t.PropagateTo(x)){
1947 if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()) return 0;
1949 if (!IsActive(t.GetRelativeSector(),nr)) {
1951 t.SetClusterIndex2(nr,-1);
1954 //AliInfo(Form("A - Sector%d phi %f - alpha %f", t.fRelativeSector,y/x, t.GetAlpha()));
1956 AliTPCtrackerRow &krow=GetRow(t.GetRelativeSector(),nr);
1958 if (TMath::Abs(TMath::Abs(y)-ymax)<krow.GetDeadZone()){
1960 t.SetClusterIndex2(nr,-1);
1966 // if (TMath::Abs(t.GetZ())<(AliTPCReconstructor::GetCtgRange()*t.GetX()+10) && (TMath::Abs(t.GetSnp())<AliTPCReconstructor::GetMaxSnpTracker()))
1967 if (IsFindable(t)) t.SetNFoundable(t.GetNFoundable()+1);
1973 if ( (nr%2==0) || t.GetNumberOfClusters()<2){
1974 // t.fCurrentSigmaY = GetSigmaY(&t);
1975 //t.fCurrentSigmaZ = GetSigmaZ(&t);
1979 AliTPCclusterMI *cl=0;
1982 Double_t roady = 1.;
1983 Double_t roadz = 1.;
1987 index = t.GetClusterIndex2(nr);
1988 if ( (index >= 0) && (index&0x8000)==0){
1989 cl = t.GetClusterPointer(nr);
1990 if ( (cl==0) && (index >= 0)) cl = GetClusterMI(index);
1991 t.SetCurrentClusterIndex1(index);
1993 t.SetCurrentCluster(cl);
1999 // if (index<0) return 0;
2000 UInt_t uindex = TMath::Abs(index);
2003 //cl = krow.FindNearest2(y+10,z,roady,roadz,uindex);
2004 cl = krow.FindNearest2(y,z,roady,roadz,uindex);
2007 if (cl) t.SetCurrentClusterIndex1(krow.GetIndex(uindex));
2008 t.SetCurrentCluster(cl);
2014 Int_t AliTPCtrackerMI::FollowToNextCluster(AliTPCseed & t, Int_t nr) {
2015 //-----------------------------------------------------------------
2016 // This function tries to find a track prolongation to next pad row
2017 //-----------------------------------------------------------------
2019 //update error according neighborhoud
2021 if (t.GetCurrentCluster()) {
2023 Int_t accept = AcceptCluster(&t,t.GetCurrentCluster());
2025 if (t.GetCurrentCluster()->IsUsed(10)){
2030 t.SetNShared(t.GetNShared()+1);
2031 if (t.GetNShared()>0.7*t.GetNumberOfClusters()) {
2036 if (fIteration>0) accept = 0;
2037 if (accept<3) UpdateTrack(&t,accept);
2041 if ( t.GetNumberOfClusters()>18 && ( (t.GetSigmaY2()+t.GetSigmaZ2())>0.16)) t.SetRemoval(10);
2042 if ( t.GetNumberOfClusters()>18 && t.GetChi2()/t.GetNumberOfClusters()>6 ) t.SetRemoval(10);
2044 if (( (t.GetNFoundable()*0.5 > t.GetNumberOfClusters()) || t.GetNoCluster()>15)) t.SetRemoval(10);
2052 //_____________________________________________________________________________
2053 Int_t AliTPCtrackerMI::FollowProlongation(AliTPCseed& t, Int_t rf, Int_t step, Bool_t fromSeeds) {
2054 //-----------------------------------------------------------------
2055 // This function tries to find a track prolongation.
2056 //-----------------------------------------------------------------
2057 Double_t xt=t.GetX();
2059 Double_t alpha=t.GetAlpha();
2060 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
2061 if (alpha < 0. ) alpha += 2.*TMath::Pi();
2063 t.SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
2065 Int_t first = GetRowNumber(xt);
2070 for (Int_t nr= first; nr>=rf; nr-=step) {
2072 if (t.GetKinkIndexes()[0]>0){
2073 for (Int_t i=0;i<3;i++){
2074 Int_t index = t.GetKinkIndexes()[i];
2075 if (index==0) break;
2076 if (index<0) continue;
2078 AliKink * kink = (AliKink*)fEvent->GetKink(index-1);
2080 printf("PROBLEM\n");
2083 Int_t kinkrow = kink->GetTPCRow0()+2+Int_t(0.5/(0.05+kink->GetAngle(2)));
2085 AliExternalTrackParam paramd(t);
2086 kink->SetDaughter(paramd);
2087 kink->SetStatus(2,5);
2094 if (nr==80) t.UpdateReference();
2095 if (nr<fInnerSec->GetNRows())
2096 fSectors = fInnerSec;
2098 fSectors = fOuterSec;
2099 if (FollowToNext(t,nr)==0)
2112 Int_t AliTPCtrackerMI::FollowBackProlongation(AliTPCseed& t, Int_t rf, Bool_t fromSeeds) {
2113 //-----------------------------------------------------------------
2114 // This function tries to find a track prolongation.
2115 //-----------------------------------------------------------------
2117 Double_t xt=t.GetX();
2118 Double_t alpha=t.GetAlpha();
2119 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
2120 if (alpha < 0. ) alpha += 2.*TMath::Pi();
2121 t.SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
2123 Int_t first = t.GetFirstPoint();
2124 Int_t ri = GetRowNumber(xt);
2128 if (first<ri) first = ri;
2130 if (first<0) first=0;
2131 for (Int_t nr=first; nr<=rf; nr++) {
2132 // if ( (TMath::Abs(t.GetSnp())>0.95)) break;//patch 28 fev 06
2133 if (t.GetKinkIndexes()[0]<0){
2134 for (Int_t i=0;i<3;i++){
2135 Int_t index = t.GetKinkIndexes()[i];
2136 if (index==0) break;
2137 if (index>0) continue;
2138 index = TMath::Abs(index);
2139 AliKink * kink = (AliKink*)fEvent->GetKink(index-1);
2141 printf("PROBLEM\n");
2144 Int_t kinkrow = kink->GetTPCRow0()-2-Int_t(0.5/(0.05+kink->GetAngle(2)));
2146 AliExternalTrackParam paramm(t);
2147 kink->SetMother(paramm);
2148 kink->SetStatus(2,1);
2155 if (nr<fInnerSec->GetNRows())
2156 fSectors = fInnerSec;
2158 fSectors = fOuterSec;
2169 Float_t AliTPCtrackerMI::OverlapFactor(AliTPCseed * s1, AliTPCseed * s2, Int_t &sum1, Int_t & sum2)
2171 // overlapping factor
2177 Float_t dz2 =(s1->GetZ() - s2->GetZ());
2180 Float_t dy2 =TMath::Abs((s1->GetY() - s2->GetY()));
2182 Float_t distance = TMath::Sqrt(dz2+dy2);
2183 if (distance>4.) return 0; // if there are far away - not overlap - to reduce combinatorics
2186 Int_t firstpoint = TMath::Min(s1->GetFirstPoint(),s2->GetFirstPoint());
2187 Int_t lastpoint = TMath::Max(s1->GetLastPoint(),s2->GetLastPoint());
2192 if (firstpoint>lastpoint) {
2193 firstpoint =lastpoint;
2198 for (Int_t i=firstpoint-1;i<lastpoint+1;i++){
2199 if (s1->GetClusterIndex2(i)>0) sum1++;
2200 if (s2->GetClusterIndex2(i)>0) sum2++;
2201 if (s1->GetClusterIndex2(i)==s2->GetClusterIndex2(i) && s1->GetClusterIndex2(i)>0) {
2205 if (sum<5) return 0;
2207 Float_t summin = TMath::Min(sum1+1,sum2+1);
2208 Float_t ratio = (sum+1)/Float_t(summin);
2212 void AliTPCtrackerMI::SignShared(AliTPCseed * s1, AliTPCseed * s2)
2216 Float_t thetaCut = 0.2;//+10.*TMath::Sqrt(s1->GetSigmaTglZ()+ s2->GetSigmaTglZ());
2217 if (TMath::Abs(s1->GetTgl()-s2->GetTgl())>thetaCut) return;
2218 Float_t minCl = TMath::Min(s1->GetNumberOfClusters(),s2->GetNumberOfClusters());
2219 Int_t cutN0 = TMath::Max(5,TMath::Nint(0.1*minCl));
2224 //Int_t firstpoint = TMath::Max(s1->GetFirstPoint(),s2->GetFirstPoint());
2225 //Int_t lastpoint = TMath::Min(s1->GetLastPoint(),s2->GetLastPoint());
2226 Int_t firstpoint = 0;
2227 Int_t lastpoint = 160;
2229 // if (firstpoint>=lastpoint-5) return;;
2231 for (Int_t i=firstpoint;i<lastpoint;i++){
2232 // if ( (s1->GetClusterIndex2(i)&0xFFFF8FFF)==(s2->GetClusterIndex2(i)&0xFFFF8FFF) && s1->GetClusterIndex2(i)>0) {
2233 if ( (s1->GetClusterIndex2(i))==(s2->GetClusterIndex2(i)) && s1->GetClusterIndex2(i)>0) {
2237 if (sumshared>cutN0){
2240 for (Int_t i=firstpoint;i<lastpoint;i++){
2241 // if ( (s1->GetClusterIndex2(i)&0xFFFF8FFF)==(s2->GetClusterIndex2(i)&0xFFFF8FFF) && s1->GetClusterIndex2(i)>0) {
2242 if ( (s1->GetClusterIndex2(i))==(s2->GetClusterIndex2(i)) && s1->GetClusterIndex2(i)>0) {
2243 AliTPCTrackerPoint *p1 = s1->GetTrackPoint(i);
2244 AliTPCTrackerPoint *p2 = s2->GetTrackPoint(i);;
2245 if (s1->IsActive()&&s2->IsActive()){
2246 p1->SetShared(kTRUE);
2247 p2->SetShared(kTRUE);
2253 if (sumshared>cutN0){
2254 for (Int_t i=0;i<4;i++){
2255 if (s1->GetOverlapLabel(3*i)==0){
2256 s1->SetOverlapLabel(3*i, s2->GetLabel());
2257 s1->SetOverlapLabel(3*i+1,sumshared);
2258 s1->SetOverlapLabel(3*i+2,s2->GetUniqueID());
2262 for (Int_t i=0;i<4;i++){
2263 if (s2->GetOverlapLabel(3*i)==0){
2264 s2->SetOverlapLabel(3*i, s1->GetLabel());
2265 s2->SetOverlapLabel(3*i+1,sumshared);
2266 s2->SetOverlapLabel(3*i+2,s1->GetUniqueID());
2273 void AliTPCtrackerMI::SignShared(TObjArray * arr)
2276 //sort trackss according sectors
2278 for (Int_t i=0; i<arr->GetEntriesFast(); i++) {
2279 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2281 //if (pt) RotateToLocal(pt);
2285 arr->Sort(); // sorting according relative sectors
2286 arr->Expand(arr->GetEntries());
2289 Int_t nseed=arr->GetEntriesFast();
2290 for (Int_t i=0; i<nseed; i++) {
2291 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2293 for (Int_t j=0;j<12;j++){
2294 pt->SetOverlapLabel(j,0);
2297 for (Int_t i=0; i<nseed; i++) {
2298 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2300 if (pt->GetRemoval()>10) continue;
2301 for (Int_t j=i+1; j<nseed; j++){
2302 AliTPCseed *pt2=(AliTPCseed*)arr->UncheckedAt(j);
2303 if (TMath::Abs(pt->GetRelativeSector()-pt2->GetRelativeSector())>1) continue;
2305 if (pt2->GetRemoval()<=10) {
2306 //if ( TMath::Abs(pt->GetRelativeSector()-pt2->GetRelativeSector())>0) break;
2314 void AliTPCtrackerMI::SortTracks(TObjArray * arr, Int_t mode) const
2317 //sort tracks in array according mode criteria
2318 Int_t nseed = arr->GetEntriesFast();
2319 for (Int_t i=0; i<nseed; i++) {
2320 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2331 void AliTPCtrackerMI::RemoveUsed2(TObjArray * arr, Float_t factor1, Float_t factor2, Int_t minimal)
2334 // Loop over all tracks and remove overlaped tracks (with lower quality)
2336 // 1. Unsign clusters
2337 // 2. Sort tracks according quality
2338 // Quality is defined by the number of cluster between first and last points
2340 // 3. Loop over tracks - decreasing quality order
2341 // a.) remove - If the fraction of shared cluster less than factor (1- n or 2)
2342 // b.) remove - If the minimal number of clusters less than minimal and not ITS
2343 // c.) if track accepted - sign clusters
2345 //Called in - AliTPCtrackerMI::Clusters2Tracks()
2346 // - AliTPCtrackerMI::PropagateBack()
2347 // - AliTPCtrackerMI::RefitInward()
2350 // factor1 - factor for constrained
2351 // factor2 - for non constrained tracks
2352 // if (Float_t(shared+1)/Float_t(found+1)>factor) - DELETE
2356 Int_t nseed = arr->GetEntriesFast();
2357 Float_t * quality = new Float_t[nseed];
2358 Int_t * indexes = new Int_t[nseed];
2362 for (Int_t i=0; i<nseed; i++) {
2363 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2368 pt->UpdatePoints(); //select first last max dens points
2369 Float_t * points = pt->GetPoints();
2370 if (points[3]<0.8) quality[i] =-1;
2371 quality[i] = (points[2]-points[0])+pt->GetNumberOfClusters();
2372 //prefer high momenta tracks if overlaps
2373 quality[i] *= TMath::Sqrt(TMath::Abs(pt->Pt())+0.5);
2375 TMath::Sort(nseed,quality,indexes);
2378 for (Int_t itrack=0; itrack<nseed; itrack++) {
2379 Int_t trackindex = indexes[itrack];
2380 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(trackindex);
2383 if (quality[trackindex]<0){
2384 MarkSeedFree( arr->RemoveAt(trackindex) );
2389 Int_t first = Int_t(pt->GetPoints()[0]);
2390 Int_t last = Int_t(pt->GetPoints()[2]);
2391 Double_t factor = (pt->GetBConstrain()) ? factor1: factor2;
2393 Int_t found,foundable,shared;
2394 pt->GetClusterStatistic(first,last, found, foundable,shared,kFALSE); // better to get statistic in "high-dens" region do't use full track as in line bellow
2395 // pt->GetClusterStatistic(0,160, found, foundable,shared,kFALSE);
2396 Bool_t itsgold =kFALSE;
2399 if (pt->GetESD()->GetITSclusters(dummy)>4) itsgold= kTRUE;
2403 if (Float_t(shared+1)/Float_t(found+1)>factor){
2404 if (pt->GetKinkIndexes()[0]!=0) continue; //don't remove tracks - part of the kinks
2405 if( AliTPCReconstructor::StreamLevel()>3){
2406 TTreeSRedirector &cstream = *fDebugStreamer;
2407 cstream<<"RemoveUsed"<<
2408 "iter="<<fIteration<<
2412 MarkSeedFree( arr->RemoveAt(trackindex) );
2415 if (pt->GetNumberOfClusters()<50&&(found-0.5*shared)<minimal){ //remove short tracks
2416 if (pt->GetKinkIndexes()[0]!=0) continue; //don't remove tracks - part of the kinks
2417 if( AliTPCReconstructor::StreamLevel()>3){
2418 TTreeSRedirector &cstream = *fDebugStreamer;
2419 cstream<<"RemoveShort"<<
2420 "iter="<<fIteration<<
2424 MarkSeedFree( arr->RemoveAt(trackindex) );
2430 //if (sharedfactor>0.4) continue;
2431 if (pt->GetKinkIndexes()[0]>0) continue;
2432 //Remove tracks with undefined properties - seems
2433 if (pt->GetSigmaY2()<kAlmost0) continue; // ? what is the origin ?
2435 for (Int_t i=first; i<last; i++) {
2436 Int_t index=pt->GetClusterIndex2(i);
2437 // if (index<0 || index&0x8000 ) continue;
2438 if (index<0 || index&0x8000 ) continue;
2439 AliTPCclusterMI *c= pt->GetClusterPointer(i);
2446 Info("RemoveUsed","\n*****\nNumber of good tracks after shared removal\t%d\n",fNtracks);
2452 void AliTPCtrackerMI::DumpClusters(Int_t iter, TObjArray *trackArray)
2455 // Dump clusters after reco
2456 // signed and unsigned cluster can be visualized
2457 // 1. Unsign all cluster
2458 // 2. Sign all used clusters
2461 Int_t nseed = trackArray->GetEntries();
2462 for (Int_t i=0; i<nseed; i++){
2463 AliTPCseed *pt=(AliTPCseed*)trackArray->UncheckedAt(i);
2467 Bool_t isKink=pt->GetKinkIndex(0)!=0;
2468 for (Int_t j=0; j<160; ++j) {
2469 Int_t index=pt->GetClusterIndex2(j);
2470 if (index<0) continue;
2471 AliTPCclusterMI *c= pt->GetClusterPointer(j);
2473 if (isKink) c->Use(100); // kink
2474 c->Use(10); // by default usage 10
2479 for (Int_t sec=0;sec<fkNIS;sec++){
2480 for (Int_t row=0;row<fInnerSec->GetNRows();row++){
2481 TClonesArray *cla = fInnerSec[sec][row].GetClusters1();
2482 for (Int_t icl =0;icl< fInnerSec[sec][row].GetN1();icl++){
2483 AliTPCclusterMI* cl = (AliTPCclusterMI*)cla->At(icl);
2484 Float_t gx[3]; cl->GetGlobalXYZ(gx);
2485 (*fDebugStreamer)<<"clDump"<<
2493 cla = fInnerSec[sec][row].GetClusters2();
2494 for (Int_t icl =0;icl< fInnerSec[sec][row].GetN2();icl++){
2495 AliTPCclusterMI* cl = (AliTPCclusterMI*)cla->At(icl);
2496 Float_t gx[3]; cl->GetGlobalXYZ(gx);
2497 (*fDebugStreamer)<<"clDump"<<
2508 for (Int_t sec=0;sec<fkNOS;sec++){
2509 for (Int_t row=0;row<fOuterSec->GetNRows();row++){
2510 TClonesArray *cla = fOuterSec[sec][row].GetClusters1();
2511 for (Int_t icl =0;icl< fOuterSec[sec][row].GetN1();icl++){
2513 AliTPCclusterMI* cl = (AliTPCclusterMI*) cla->At(icl);
2514 cl->GetGlobalXYZ(gx);
2515 (*fDebugStreamer)<<"clDump"<<
2523 cla = fOuterSec[sec][row].GetClusters2();
2524 for (Int_t icl =0;icl< fOuterSec[sec][row].GetN2();icl++){
2526 AliTPCclusterMI* cl = (AliTPCclusterMI*) cla->At(icl);
2527 cl->GetGlobalXYZ(gx);
2528 (*fDebugStreamer)<<"clDump"<<
2540 void AliTPCtrackerMI::UnsignClusters()
2543 // loop over all clusters and unsign them
2546 for (Int_t sec=0;sec<fkNIS;sec++){
2547 for (Int_t row=0;row<fInnerSec->GetNRows();row++){
2548 TClonesArray *cla = fInnerSec[sec][row].GetClusters1();
2549 for (Int_t icl =0;icl< fInnerSec[sec][row].GetN1();icl++)
2550 // if (cl[icl].IsUsed(10))
2551 ((AliTPCclusterMI*) cla->At(icl))->Use(-1);
2552 cla = fInnerSec[sec][row].GetClusters2();
2553 for (Int_t icl =0;icl< fInnerSec[sec][row].GetN2();icl++)
2554 //if (cl[icl].IsUsed(10))
2555 ((AliTPCclusterMI*) cla->At(icl))->Use(-1);
2559 for (Int_t sec=0;sec<fkNOS;sec++){
2560 for (Int_t row=0;row<fOuterSec->GetNRows();row++){
2561 TClonesArray *cla = fOuterSec[sec][row].GetClusters1();
2562 for (Int_t icl =0;icl< fOuterSec[sec][row].GetN1();icl++)
2563 //if (cl[icl].IsUsed(10))
2564 ((AliTPCclusterMI*) cla->At(icl))->Use(-1);
2565 cla = fOuterSec[sec][row].GetClusters2();
2566 for (Int_t icl =0;icl< fOuterSec[sec][row].GetN2();icl++)
2567 //if (cl[icl].IsUsed(10))
2568 ((AliTPCclusterMI*) cla->At(icl))->Use(-1);
2576 void AliTPCtrackerMI::SignClusters(const TObjArray * arr, Float_t fnumber, Float_t fdensity)
2579 //sign clusters to be "used"
2581 // snumber and sdensity sign number of sigmas - bellow mean value to be accepted
2582 // loop over "primaries"
2596 Int_t nseed = arr->GetEntriesFast();
2597 for (Int_t i=0; i<nseed; i++) {
2598 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2602 if (!(pt->IsActive())) continue;
2603 Float_t dens = pt->GetNumberOfClusters()/Float_t(pt->GetNFoundable());
2604 if ( (dens>0.7) && (pt->GetNumberOfClusters()>70)){
2606 sumdens2+= dens*dens;
2607 sumn += pt->GetNumberOfClusters();
2608 sumn2 += pt->GetNumberOfClusters()*pt->GetNumberOfClusters();
2609 Float_t chi2 = pt->GetChi2()/pt->GetNumberOfClusters();
2612 sumchi2 +=chi2*chi2;
2617 Float_t mdensity = 0.9;
2618 Float_t meann = 130;
2619 Float_t meanchi = 1;
2620 Float_t sdensity = 0.1;
2621 Float_t smeann = 10;
2622 Float_t smeanchi =0.4;
2626 mdensity = sumdens/sum;
2628 meanchi = sumchi/sum;
2630 sdensity = sumdens2/sum-mdensity*mdensity;
2632 sdensity = TMath::Sqrt(sdensity);
2636 smeann = sumn2/sum-meann*meann;
2638 smeann = TMath::Sqrt(smeann);
2642 smeanchi = sumchi2/sum - meanchi*meanchi;
2644 smeanchi = TMath::Sqrt(smeanchi);
2650 //REMOVE SHORT DELTAS or tracks going out of sensitive volume of TPC
2652 for (Int_t i=0; i<nseed; i++) {
2653 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2657 if (pt->GetBSigned()) continue;
2658 if (pt->GetBConstrain()) continue;
2659 //if (!(pt->IsActive())) continue;
2661 Int_t found,foundable,shared;
2662 pt->GetClusterStatistic(0,160,found, foundable,shared);
2663 if (shared/float(found)>0.3) {
2664 if (shared/float(found)>0.9 ){
2665 //MarkSeedFree( arr->RemoveAt(i) );
2670 Bool_t isok =kFALSE;
2671 if ( (pt->GetNShared()/pt->GetNumberOfClusters()<0.5) &&pt->GetNumberOfClusters()>60)
2673 if ((TMath::Abs(1/pt->GetC())<100.) && (pt->GetNShared()/pt->GetNumberOfClusters()<0.7))
2675 if (TMath::Abs(pt->GetZ()/pt->GetX())>1.1)
2677 if ( (TMath::Abs(pt->GetSnp()>0.7) && pt->GetD(0,0)>60.))
2681 for (Int_t j=0; j<160; ++j) {
2682 Int_t index=pt->GetClusterIndex2(j);
2683 if (index<0) continue;
2684 AliTPCclusterMI *c= pt->GetClusterPointer(j);
2686 //if (!(c->IsUsed(10))) c->Use();
2693 Double_t maxchi = meanchi+2.*smeanchi;
2695 for (Int_t i=0; i<nseed; i++) {
2696 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2700 //if (!(pt->IsActive())) continue;
2701 if (pt->GetBSigned()) continue;
2702 Double_t chi = pt->GetChi2()/pt->GetNumberOfClusters();
2703 if (chi>maxchi) continue;
2706 Float_t dens = pt->GetNumberOfClusters()/Float_t(pt->GetNFoundable());
2708 //sign only tracks with enoug big density at the beginning
2710 if ((pt->GetDensityFirst(40)<0.75) && pt->GetNumberOfClusters()<meann) continue;
2713 Double_t mindens = TMath::Max(double(mdensity-sdensity*fdensity*bfactor),0.65);
2714 Double_t minn = TMath::Max(Int_t(meann-fnumber*smeann*bfactor),50);
2716 // if (pt->fBConstrain) mindens = TMath::Max(mdensity-sdensity*fdensity*bfactor,0.65);
2717 if ( (pt->GetRemoval()==10) && (pt->GetSnp()>0.8)&&(dens>mindens))
2720 if ((dens>mindens && pt->GetNumberOfClusters()>minn) && chi<maxchi ){
2721 //Int_t noc=pt->GetNumberOfClusters();
2722 pt->SetBSigned(kTRUE);
2723 for (Int_t j=0; j<160; ++j) {
2725 Int_t index=pt->GetClusterIndex2(j);
2726 if (index<0) continue;
2727 AliTPCclusterMI *c= pt->GetClusterPointer(j);
2729 // if (!(c->IsUsed(10))) c->Use();
2734 // gLastCheck = nseed;
2743 Int_t AliTPCtrackerMI::RefitInward(AliESDEvent *event)
2746 // back propagation of ESD tracks
2749 if (!event) return 0;
2750 const Int_t kMaxFriendTracks=2000;
2753 // extract correction object for multiplicity dependence of dEdx
2754 TObjArray * gainCalibArray = AliTPCcalibDB::Instance()->GetTimeGainSplinesRun(event->GetRunNumber());
2756 AliTPCTransform *transform = AliTPCcalibDB::Instance()->GetTransform() ;
2758 AliFatal("Tranformations not in RefitInward");
2761 transform->SetCurrentRecoParam((AliTPCRecoParam*)AliTPCReconstructor::GetRecoParam());
2762 const AliTPCRecoParam * recoParam = AliTPCcalibDB::Instance()->GetTransform()->GetCurrentRecoParam();
2763 Int_t nContribut = event->GetNumberOfTracks();
2764 TGraphErrors * graphMultDependenceDeDx = 0x0;
2765 if (recoParam && recoParam->GetUseMultiplicityCorrectionDedx() && gainCalibArray) {
2766 if (recoParam->GetUseTotCharge()) {
2767 graphMultDependenceDeDx = (TGraphErrors *) gainCalibArray->FindObject("TGRAPHERRORS_MEANQTOT_MULTIPLICITYDEPENDENCE_BEAM_ALL");
2769 graphMultDependenceDeDx = (TGraphErrors *) gainCalibArray->FindObject("TGRAPHERRORS_MEANQMAX_MULTIPLICITYDEPENDENCE_BEAM_ALL");
2775 //PrepareForProlongation(fSeeds,1);
2776 PropagateForward2(fSeeds);
2777 RemoveUsed2(fSeeds,0.4,0.4,20);
2779 TObjArray arraySeed(fSeeds->GetEntries());
2780 for (Int_t i=0;i<fSeeds->GetEntries();i++) {
2781 arraySeed.AddAt(fSeeds->At(i),i);
2783 SignShared(&arraySeed);
2784 // FindCurling(fSeeds, event,2); // find multi found tracks
2785 FindSplitted(fSeeds, event,2); // find multi found tracks
2786 if (AliTPCReconstructor::StreamLevel()>5) FindMultiMC(fSeeds, fEvent,2); // find multi found tracks
2789 Int_t nseed = fSeeds->GetEntriesFast();
2790 for (Int_t i=0;i<nseed;i++){
2791 AliTPCseed * seed = (AliTPCseed*) fSeeds->UncheckedAt(i);
2792 if (!seed) continue;
2793 if (seed->GetKinkIndex(0)>0) UpdateKinkQualityD(seed); // update quality informations for kinks
2794 AliESDtrack *esd=event->GetTrack(i);
2796 if (seed->GetNumberOfClusters()<60 && seed->GetNumberOfClusters()<(esd->GetTPCclusters(0) -5)*0.8){
2797 AliExternalTrackParam paramIn;
2798 AliExternalTrackParam paramOut;
2799 Int_t ncl = seed->RefitTrack(seed,¶mIn,¶mOut);
2800 if (AliTPCReconstructor::StreamLevel()>2) {
2801 (*fDebugStreamer)<<"RecoverIn"<<
2805 "pout.="<<¶mOut<<
2810 seed->Set(paramIn.GetX(),paramIn.GetAlpha(),paramIn.GetParameter(),paramIn.GetCovariance());
2811 seed->SetNumberOfClusters(ncl);
2815 seed->PropagateTo(fkParam->GetInnerRadiusLow());
2816 seed->UpdatePoints();
2817 AddCovariance(seed);
2818 MakeESDBitmaps(seed, esd);
2819 seed->CookdEdx(0.02,0.6);
2820 CookLabel(seed,0.1); //For comparison only
2822 if (AliTPCReconstructor::StreamLevel()>1 && seed!=0) {
2823 TTreeSRedirector &cstream = *fDebugStreamer;
2830 if (seed->GetNumberOfClusters()>15){
2831 esd->UpdateTrackParams(seed,AliESDtrack::kTPCrefit);
2832 esd->SetTPCPoints(seed->GetPoints());
2833 esd->SetTPCPointsF(seed->GetNFoundable());
2834 Int_t ndedx = seed->GetNCDEDX(0);
2835 Float_t sdedx = seed->GetSDEDX(0);
2836 Float_t dedx = seed->GetdEdx();
2837 // apply mutliplicity dependent dEdx correction if available
2838 if (graphMultDependenceDeDx) {
2839 Double_t corrGain = AliTPCcalibDButil::EvalGraphConst(graphMultDependenceDeDx, nContribut);
2840 dedx += (1 - corrGain)*50.; // MIP is normalized to 50
2842 esd->SetTPCsignal(dedx, sdedx, ndedx);
2844 // fill new dEdx information
2846 Double32_t signal[4];
2850 for(Int_t iarr=0;iarr<3;iarr++) {
2851 signal[iarr] = seed->GetDEDXregion(iarr+1);
2852 ncl[iarr] = seed->GetNCDEDX(iarr+1);
2853 nrows[iarr] = seed->GetNCDEDXInclThres(iarr+1);
2855 signal[3] = seed->GetDEDXregion(4);
2857 AliTPCdEdxInfo * infoTpcPid = new AliTPCdEdxInfo();
2858 infoTpcPid->SetTPCSignalRegionInfo(signal, ncl, nrows);
2859 esd->SetTPCdEdxInfo(infoTpcPid);
2861 // add seed to the esd track in Calib level
2863 Bool_t storeFriend = gRandom->Rndm()<(kMaxFriendTracks)/Float_t(nseed);
2864 if (AliTPCReconstructor::StreamLevel()>0 &&storeFriend){
2865 // RS: this is the only place where the seed is created not in the pool,
2866 // since it should belong to ESDevent
2867 AliTPCseed * seedCopy = new AliTPCseed(*seed, kTRUE);
2868 esd->AddCalibObject(seedCopy);
2873 //printf("problem\n");
2876 //FindKinks(fSeeds,event);
2877 if (AliTPCReconstructor::StreamLevel()>3) DumpClusters(2,fSeeds);
2878 Info("RefitInward","Number of refitted tracks %d",ntracks);
2880 AliCosmicTracker::FindCosmic(event, kTRUE);
2886 Int_t AliTPCtrackerMI::PropagateBack(AliESDEvent *event)
2889 // back propagation of ESD tracks
2891 if (!event) return 0;
2896 PropagateBack(fSeeds);
2897 RemoveUsed2(fSeeds,0.4,0.4,20);
2898 //FindCurling(fSeeds, fEvent,1);
2899 FindSplitted(fSeeds, event,1); // find multi found tracks
2900 if (AliTPCReconstructor::StreamLevel()>5) FindMultiMC(fSeeds, fEvent,1); // find multi found tracks
2903 Int_t nseed = fSeeds->GetEntriesFast();
2905 for (Int_t i=0;i<nseed;i++){
2906 AliTPCseed * seed = (AliTPCseed*) fSeeds->UncheckedAt(i);
2907 if (!seed) continue;
2908 if (seed->GetKinkIndex(0)<0) UpdateKinkQualityM(seed); // update quality informations for kinks
2909 seed->UpdatePoints();
2910 AddCovariance(seed);
2911 AliESDtrack *esd=event->GetTrack(i);
2912 if (!esd) continue; //never happen
2913 if (seed->GetNumberOfClusters()<60 && seed->GetNumberOfClusters()<(esd->GetTPCclusters(0) -5)*0.8){
2914 AliExternalTrackParam paramIn;
2915 AliExternalTrackParam paramOut;
2916 Int_t ncl = seed->RefitTrack(seed,¶mIn,¶mOut);
2917 if (AliTPCReconstructor::StreamLevel()>2) {
2918 (*fDebugStreamer)<<"RecoverBack"<<
2922 "pout.="<<¶mOut<<
2927 seed->Set(paramOut.GetX(),paramOut.GetAlpha(),paramOut.GetParameter(),paramOut.GetCovariance());
2928 seed->SetNumberOfClusters(ncl);
2931 seed->CookdEdx(0.02,0.6);
2932 CookLabel(seed,0.1); //For comparison only
2933 if (seed->GetNumberOfClusters()>15){
2934 esd->UpdateTrackParams(seed,AliESDtrack::kTPCout);
2935 esd->SetTPCPoints(seed->GetPoints());
2936 esd->SetTPCPointsF(seed->GetNFoundable());
2937 Int_t ndedx = seed->GetNCDEDX(0);
2938 Float_t sdedx = seed->GetSDEDX(0);
2939 Float_t dedx = seed->GetdEdx();
2940 esd->SetTPCsignal(dedx, sdedx, ndedx);
2942 Int_t eventnumber = event->GetEventNumberInFile();// patch 28 fev 06
2943 // This is most likely NOT the event number you'd like to use. It has nothing to do with the 'real' event number
2944 if (AliTPCReconstructor::StreamLevel()>1 && esd) {
2945 (*fDebugStreamer)<<"Cback"<<
2948 "EventNrInFile="<<eventnumber<<
2953 if (AliTPCReconstructor::StreamLevel()>3) DumpClusters(1,fSeeds);
2954 //FindKinks(fSeeds,event);
2955 Info("PropagateBack","Number of back propagated tracks %d",ntracks);
2963 Int_t AliTPCtrackerMI::PostProcess(AliESDEvent *event)
2966 // Post process events
2968 if (!event) return 0;
2971 // Set TPC event status
2974 // event affected by HV dip
2976 if(IsTPCHVDipEvent(event)) {
2977 event->ResetDetectorStatus(AliDAQ::kTPC);
2980 //printf("Status %d \n", event->IsDetectorOn(AliDAQ::kTPC));
2986 void AliTPCtrackerMI::DeleteSeeds()
2995 void AliTPCtrackerMI::ReadSeeds(const AliESDEvent *const event, Int_t direction)
2998 //read seeds from the event
3000 Int_t nentr=event->GetNumberOfTracks();
3002 Info("ReadSeeds", "Number of ESD tracks: %d\n", nentr);
3007 fSeeds = new TObjArray(nentr);
3011 for (Int_t i=0; i<nentr; i++) {
3012 AliESDtrack *esd=event->GetTrack(i);
3013 ULong_t status=esd->GetStatus();
3014 if (!(status&AliESDtrack::kTPCin)) continue;
3015 AliTPCtrack t(*esd);
3016 t.SetNumberOfClusters(0);
3017 // AliTPCseed *seed = new AliTPCseed(t,t.GetAlpha());
3018 AliTPCseed *seed = new( NextFreeSeed() ) AliTPCseed(t/*,t.GetAlpha()*/);
3019 seed->SetPoolID(fLastSeedID);
3020 seed->SetUniqueID(esd->GetID());
3021 AddCovariance(seed); //add systematic ucertainty
3022 for (Int_t ikink=0;ikink<3;ikink++) {
3023 Int_t index = esd->GetKinkIndex(ikink);
3024 seed->GetKinkIndexes()[ikink] = index;
3025 if (index==0) continue;
3026 index = TMath::Abs(index);
3027 AliESDkink * kink = fEvent->GetKink(index-1);
3028 if (kink&&esd->GetKinkIndex(ikink)<0){
3029 if ((status & AliESDtrack::kTRDrefit) != 0) kink->SetStatus(1,2);
3030 if ((status & AliESDtrack::kITSout) != 0) kink->SetStatus(1,0);
3032 if (kink&&esd->GetKinkIndex(ikink)>0){
3033 if ((status & AliESDtrack::kTRDrefit) != 0) kink->SetStatus(1,6);
3034 if ((status & AliESDtrack::kITSout) != 0) kink->SetStatus(1,4);
3038 if (((status&AliESDtrack::kITSout)==0)&&(direction==1)) seed->ResetCovariance(10.);
3039 if ( direction ==2 &&(status & AliESDtrack::kTRDrefit) == 0 ) seed->ResetCovariance(10.);
3040 //if ( direction ==2 && ((status & AliESDtrack::kTPCout) == 0) ) {
3041 // fSeeds->AddAt(0,i);
3042 // MarkSeedFree( seed );
3045 if ( direction ==2 &&(status & AliESDtrack::kTRDrefit) > 0 ) {
3046 Double_t par0[5],par1[5],alpha,x;
3047 esd->GetInnerExternalParameters(alpha,x,par0);
3048 esd->GetExternalParameters(x,par1);
3049 Double_t delta1 = TMath::Abs(par0[4]-par1[4])/(0.000000001+TMath::Abs(par0[4]+par1[4]));
3050 Double_t delta2 = TMath::Abs(par0[3]-par1[3]);
3052 if (esd->GetTRDncls()>0) trdchi2 = esd->GetTRDchi2()/esd->GetTRDncls();
3053 //reset covariance if suspicious
3054 if ( (delta1>0.1) || (delta2>0.006) ||trdchi2>7.)
3055 seed->ResetCovariance(10.);
3060 // rotate to the local coordinate system
3062 fSectors=fInnerSec; fN=fkNIS;
3063 Double_t alpha=seed->GetAlpha();
3064 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
3065 if (alpha < 0. ) alpha += 2.*TMath::Pi();
3066 Int_t ns=Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN;
3067 alpha =ns*fSectors->GetAlpha() + fSectors->GetAlphaShift();
3068 alpha-=seed->GetAlpha();
3069 if (alpha<-TMath::Pi()) alpha += 2*TMath::Pi();
3070 if (alpha>=TMath::Pi()) alpha -= 2*TMath::Pi();
3071 if (TMath::Abs(alpha) > 0.001) { // This should not happen normally
3072 AliWarning(Form("Rotating track over %f",alpha));
3073 if (!seed->Rotate(alpha)) {
3074 MarkSeedFree( seed );
3080 if (esd->GetKinkIndex(0)<=0){
3081 for (Int_t irow=0;irow<160;irow++){
3082 Int_t index = seed->GetClusterIndex2(irow);
3085 AliTPCclusterMI * cl = GetClusterMI(index);
3086 seed->SetClusterPointer(irow,cl);
3088 if ((index & 0x8000)==0){
3089 cl->Use(10); // accepted cluster
3091 cl->Use(6); // close cluster not accepted
3094 Info("ReadSeeds","Not found cluster");
3099 fSeeds->AddAt(seed,i);
3105 //_____________________________________________________________________________
3106 void AliTPCtrackerMI::MakeSeeds3(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t cuts[4],
3107 Float_t deltay, Int_t ddsec) {
3108 //-----------------------------------------------------------------
3109 // This function creates track seeds.
3110 // SEEDING WITH VERTEX CONSTRAIN
3111 //-----------------------------------------------------------------
3112 // cuts[0] - fP4 cut
3113 // cuts[1] - tan(phi) cut
3114 // cuts[2] - zvertex cut
3115 // cuts[3] - fP3 cut
3123 Double_t x[5], c[15];
3124 // Int_t di = i1-i2;
3126 AliTPCseed * seed = new( NextFreeSeed() ) AliTPCseed();
3127 seed->SetPoolID(fLastSeedID);
3128 Double_t alpha=fSectors->GetAlpha(), shift=fSectors->GetAlphaShift();
3129 Double_t cs=cos(alpha), sn=sin(alpha);
3131 // Double_t x1 =fOuterSec->GetX(i1);
3132 //Double_t xx2=fOuterSec->GetX(i2);
3134 Double_t x1 =GetXrow(i1);
3135 Double_t xx2=GetXrow(i2);
3137 Double_t x3=GetX(), y3=GetY(), z3=GetZ();
3139 Int_t imiddle = (i2+i1)/2; //middle pad row index
3140 Double_t xm = GetXrow(imiddle); // radius of middle pad-row
3141 const AliTPCtrackerRow& krm=GetRow(sec,imiddle); //middle pad -row
3145 const AliTPCtrackerRow& kr1=GetRow(ns,i1);
3146 Double_t ymax = GetMaxY(i1)-kr1.GetDeadZone()-1.5;
3147 Double_t ymaxm = GetMaxY(imiddle)-kr1.GetDeadZone()-1.5;
3150 // change cut on curvature if it can't reach this layer
3151 // maximal curvature set to reach it
3152 Double_t dvertexmax = TMath::Sqrt((x1-x3)*(x1-x3)+(ymax+5-y3)*(ymax+5-y3));
3153 if (dvertexmax*0.5*cuts[0]>0.85){
3154 cuts[0] = 0.85/(dvertexmax*0.5+1.);
3156 Double_t r2min = 1/(cuts[0]*cuts[0]); //minimal square of radius given by cut
3159 if (deltay>0) ddsec = 0;
3160 // loop over clusters
3161 for (Int_t is=0; is < kr1; is++) {
3163 if (kr1[is]->IsUsed(10)) continue;
3164 Double_t y1=kr1[is]->GetY(), z1=kr1[is]->GetZ();
3165 //if (TMath::Abs(y1)>ymax) continue;
3167 if (deltay>0 && TMath::Abs(ymax-TMath::Abs(y1))> deltay ) continue; // seed only at the edge
3169 // find possible directions
3170 Float_t anglez = (z1-z3)/(x1-x3);
3171 Float_t extraz = z1 - anglez*(x1-xx2); // extrapolated z
3174 //find rotation angles relative to line given by vertex and point 1
3175 Double_t dvertex2 = (x1-x3)*(x1-x3)+(y1-y3)*(y1-y3);
3176 Double_t dvertex = TMath::Sqrt(dvertex2);
3177 Double_t angle13 = TMath::ATan((y1-y3)/(x1-x3));
3178 Double_t cs13 = cos(-angle13), sn13 = sin(-angle13);
3181 // loop over 2 sectors
3187 Double_t dddz1=0; // direction of delta inclination in z axis
3194 for (Int_t dsec = dsec1; dsec<=dsec2;dsec++){
3195 Int_t sec2 = sec + dsec;
3197 // AliTPCtrackerRow& kr2 = fOuterSec[(sec2+fkNOS)%fkNOS][i2];
3198 //AliTPCtrackerRow& kr2m = fOuterSec[(sec2+fkNOS)%fkNOS][imiddle];
3199 AliTPCtrackerRow& kr2 = GetRow((sec2+fkNOS)%fkNOS,i2);
3200 AliTPCtrackerRow& kr2m = GetRow((sec2+fkNOS)%fkNOS,imiddle);
3201 Int_t index1 = TMath::Max(kr2.Find(extraz-0.6-dddz1*TMath::Abs(z1)*0.05)-1,0);
3202 Int_t index2 = TMath::Min(kr2.Find(extraz+0.6+dddz2*TMath::Abs(z1)*0.05)+1,kr2);
3204 // rotation angles to p1-p3
3205 Double_t cs13r = cos(-angle13+dsec*alpha)/dvertex, sn13r = sin(-angle13+dsec*alpha)/dvertex;
3206 Double_t x2, y2, z2;
3208 // Double_t dymax = maxangle*TMath::Abs(x1-xx2);
3211 Double_t dxx0 = (xx2-x3)*cs13r;
3212 Double_t dyy0 = (xx2-x3)*sn13r;
3213 for (Int_t js=index1; js < index2; js++) {
3214 const AliTPCclusterMI *kcl = kr2[js];
3215 if (kcl->IsUsed(10)) continue;
3217 //calcutate parameters
3219 Double_t yy0 = dyy0 +(kcl->GetY()-y3)*cs13r;
3221 if (TMath::Abs(yy0)<0.000001) continue;
3222 Double_t xx0 = dxx0 -(kcl->GetY()-y3)*sn13r;
3223 Double_t y0 = 0.5*(xx0*xx0+yy0*yy0-xx0)/yy0;
3224 Double_t r02 = (0.25+y0*y0)*dvertex2;
3225 //curvature (radius) cut
3226 if (r02<r2min) continue;
3230 Double_t c0 = 1/TMath::Sqrt(r02);
3234 //Double_t dfi0 = 2.*TMath::ASin(dvertex*c0*0.5);
3235 //Double_t dfi1 = 2.*TMath::ASin(TMath::Sqrt(yy0*yy0+(1-xx0)*(1-xx0))*dvertex*c0*0.5);
3236 Double_t dfi0 = 2.*AliTPCFastMath::FastAsin(dvertex*c0*0.5);
3237 Double_t dfi1 = 2.*AliTPCFastMath::FastAsin(TMath::Sqrt(yy0*yy0+(1-xx0)*(1-xx0))*dvertex*c0*0.5);
3240 Double_t z0 = kcl->GetZ();
3241 Double_t zzzz2 = z1-(z1-z3)*dfi1/dfi0;
3242 if (TMath::Abs(zzzz2-z0)>0.5) continue;
3245 Double_t dip = (z1-z0)*c0/dfi1;
3246 Double_t x0 = (0.5*cs13+y0*sn13)*dvertex*c0;
3257 x2= xx2*cs-y2*sn*dsec;
3258 y2=+xx2*sn*dsec+y2*cs;
3268 // do we have cluster at the middle ?
3270 GetProlongation(x1,xm,x,ym,zm);
3272 AliTPCclusterMI * cm=0;
3273 if (TMath::Abs(ym)-ymaxm<0){
3274 cm = krm.FindNearest2(ym,zm,1.0,0.6,dummy);
3275 if ((!cm) || (cm->IsUsed(10))) {
3280 // rotate y1 to system 0
3281 // get state vector in rotated system
3282 Double_t yr1 = (-0.5*sn13+y0*cs13)*dvertex*c0;
3283 Double_t xr2 = x0*cs+yr1*sn*dsec;
3284 Double_t xr[5]={kcl->GetY(),kcl->GetZ(), xr2, dip, c0};
3286 GetProlongation(xx2,xm,xr,ym,zm);
3287 if (TMath::Abs(ym)-ymaxm<0){
3288 cm = kr2m.FindNearest2(ym,zm,1.0,0.6,dummy);
3289 if ((!cm) || (cm->IsUsed(10))) {
3296 // Double_t dym = 0;
3297 // Double_t dzm = 0;
3299 // dym = ym - cm->GetY();
3300 // dzm = zm - cm->GetZ();
3307 Double_t sy1=kr1[is]->GetSigmaY2()*2., sz1=kr1[is]->GetSigmaZ2()*2.;
3308 Double_t sy2=kcl->GetSigmaY2()*2., sz2=kcl->GetSigmaZ2()*2.;
3309 //Double_t sy3=400*3./12., sy=0.1, sz=0.1;
3310 Double_t sy3=25000*x[4]*x[4]+0.1, sy=0.1, sz=0.1;
3311 //Double_t sy3=25000*x[4]*x[4]*60+0.5, sy=0.1, sz=0.1;
3313 Double_t f40=(F1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
3314 Double_t f42=(F1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
3315 Double_t f43=(F1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
3316 Double_t f20=(F2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
3317 Double_t f22=(F2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
3318 Double_t f23=(F2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
3320 Double_t f30=(F3(x1,y1+sy,x2,y2,z1,z2)-x[3])/sy;
3321 Double_t f31=(F3(x1,y1,x2,y2,z1+sz,z2)-x[3])/sz;
3322 Double_t f32=(F3(x1,y1,x2,y2+sy,z1,z2)-x[3])/sy;
3323 Double_t f34=(F3(x1,y1,x2,y2,z1,z2+sz)-x[3])/sz;
3327 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
3328 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
3329 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
3330 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
3331 c[13]=f30*sy1*f40+f32*sy2*f42;
3332 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
3334 // if (!BuildSeed(kr1[is],kcl,0,x1,x2,x3,x,c)) continue;
3336 UInt_t index=kr1.GetIndex(is);
3337 if (seed) {MarkSeedFree(seed); seed = 0;}
3338 AliTPCseed *track = seed = new( NextFreeSeed() ) AliTPCseed(x1, ns*alpha+shift, x, c, index);
3339 seed->SetPoolID(fLastSeedID);
3340 track->SetIsSeeding(kTRUE);
3341 track->SetSeed1(i1);
3342 track->SetSeed2(i2);
3343 track->SetSeedType(3);
3347 FollowProlongation(*track, (i1+i2)/2,1);
3348 Int_t foundable,found,shared;
3349 track->GetClusterStatistic((i1+i2)/2,i1, found, foundable, shared, kTRUE);
3350 if ((found<0.55*foundable) || shared>0.5*found || (track->GetSigmaY2()+track->GetSigmaZ2())>0.5){
3351 MarkSeedFree(seed); seed = 0;
3357 FollowProlongation(*track, i2,1);
3361 track->SetBConstrain(1);
3362 // track->fLastPoint = i1+fInnerSec->GetNRows(); // first cluster in track position
3363 track->SetLastPoint(i1); // first cluster in track position
3364 track->SetFirstPoint(track->GetLastPoint());
3366 if (track->GetNumberOfClusters()<(i1-i2)*0.5 ||
3367 track->GetNumberOfClusters() < track->GetNFoundable()*0.6 ||
3368 track->GetNShared()>0.4*track->GetNumberOfClusters() ) {
3369 MarkSeedFree(seed); seed = 0;
3373 // Z VERTEX CONDITION
3374 Double_t zv, bz=GetBz();
3375 if ( !track->GetZAt(0.,bz,zv) ) continue;
3376 if (TMath::Abs(zv-z3)>cuts[2]) {
3377 FollowProlongation(*track, TMath::Max(i2-20,0));
3378 if ( !track->GetZAt(0.,bz,zv) ) continue;
3379 if (TMath::Abs(zv-z3)>cuts[2]){
3380 FollowProlongation(*track, TMath::Max(i2-40,0));
3381 if ( !track->GetZAt(0.,bz,zv) ) continue;
3382 if (TMath::Abs(zv-z3)>cuts[2] &&(track->GetNumberOfClusters() > track->GetNFoundable()*0.7)){
3383 // make seed without constrain
3384 AliTPCseed * track2 = MakeSeed(track,0.2,0.5,1.);
3385 FollowProlongation(*track2, i2,1);
3386 track2->SetBConstrain(kFALSE);
3387 track2->SetSeedType(1);
3388 arr->AddLast(track2);
3389 MarkSeedFree( seed ); seed = 0;
3393 MarkSeedFree( seed ); seed = 0;
3400 track->SetSeedType(0);
3401 arr->AddLast(track); // note, track is seed, don't free the seed
3402 seed = new( NextFreeSeed() ) AliTPCseed;
3403 seed->SetPoolID(fLastSeedID);
3405 // don't consider other combinations
3406 if (track->GetNumberOfClusters() > track->GetNFoundable()*0.8)
3412 Info("MakeSeeds3","\nSeeding statistic:\t%d\t%d\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin,nout1,nout2);
3414 if (seed) MarkSeedFree( seed );
3418 void AliTPCtrackerMI::MakeSeeds5(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t cuts[4],
3423 //-----------------------------------------------------------------
3424 // This function creates track seeds.
3425 //-----------------------------------------------------------------
3426 // cuts[0] - fP4 cut
3427 // cuts[1] - tan(phi) cut
3428 // cuts[2] - zvertex cut
3429 // cuts[3] - fP3 cut
3439 Double_t x[5], c[15];
3441 // make temporary seed
3442 AliTPCseed * seed = new( NextFreeSeed() ) AliTPCseed;
3443 seed->SetPoolID(fLastSeedID);
3444 Double_t alpha=fOuterSec->GetAlpha(), shift=fOuterSec->GetAlphaShift();
3445 // Double_t cs=cos(alpha), sn=sin(alpha);
3450 Double_t x1 = GetXrow(i1-1);
3451 const AliTPCtrackerRow& kr1=GetRow(sec,i1-1);
3452 Double_t y1max = GetMaxY(i1-1)-kr1.GetDeadZone()-1.5;
3454 Double_t x1p = GetXrow(i1);
3455 const AliTPCtrackerRow& kr1p=GetRow(sec,i1);
3457 Double_t x1m = GetXrow(i1-2);
3458 const AliTPCtrackerRow& kr1m=GetRow(sec,i1-2);
3461 //last 3 padrow for seeding
3462 AliTPCtrackerRow& kr3 = GetRow((sec+fkNOS)%fkNOS,i1-7);
3463 Double_t x3 = GetXrow(i1-7);
3464 // Double_t y3max= GetMaxY(i1-7)-kr3.fDeadZone-1.5;
3466 AliTPCtrackerRow& kr3p = GetRow((sec+fkNOS)%fkNOS,i1-6);
3467 Double_t x3p = GetXrow(i1-6);
3469 AliTPCtrackerRow& kr3m = GetRow((sec+fkNOS)%fkNOS,i1-8);
3470 Double_t x3m = GetXrow(i1-8);
3475 Int_t im = i1-4; //middle pad row index
3476 Double_t xm = GetXrow(im); // radius of middle pad-row
3477 const AliTPCtrackerRow& krm=GetRow(sec,im); //middle pad -row
3478 // Double_t ymmax = GetMaxY(im)-kr1.fDeadZone-1.5;
3481 Double_t deltax = x1-x3;
3482 Double_t dymax = deltax*cuts[1];
3483 Double_t dzmax = deltax*cuts[3];
3485 // loop over clusters
3486 for (Int_t is=0; is < kr1; is++) {
3488 if (kr1[is]->IsUsed(10)) continue;
3489 Double_t y1=kr1[is]->GetY(), z1=kr1[is]->GetZ();
3491 if (deltay>0 && TMath::Abs(y1max-TMath::Abs(y1))> deltay ) continue; // seed only at the edge
3493 Int_t index1 = TMath::Max(kr3.Find(z1-dzmax)-1,0);
3494 Int_t index2 = TMath::Min(kr3.Find(z1+dzmax)+1,kr3);
3500 for (Int_t js=index1; js < index2; js++) {
3501 const AliTPCclusterMI *kcl = kr3[js];
3502 if (kcl->IsUsed(10)) continue;
3504 // apply angular cuts
3505 if (TMath::Abs(y1-y3)>dymax) continue;
3508 if (TMath::Abs(z1-z3)>dzmax) continue;
3510 Double_t angley = (y1-y3)/(x1-x3);
3511 Double_t anglez = (z1-z3)/(x1-x3);
3513 Double_t erry = TMath::Abs(angley)*(x1-x1m)*0.5+0.5;
3514 Double_t errz = TMath::Abs(anglez)*(x1-x1m)*0.5+0.5;
3516 Double_t yyym = angley*(xm-x1)+y1;
3517 Double_t zzzm = anglez*(xm-x1)+z1;
3519 const AliTPCclusterMI *kcm = krm.FindNearest2(yyym,zzzm,erry,errz,index);
3521 if (kcm->IsUsed(10)) continue;
3523 erry = TMath::Abs(angley)*(x1-x1m)*0.4+0.5;
3524 errz = TMath::Abs(anglez)*(x1-x1m)*0.4+0.5;
3531 // look around first
3532 const AliTPCclusterMI *kc1m = kr1m.FindNearest2(angley*(x1m-x1)+y1,
3538 if (kc1m->IsUsed(10)) used++;
3540 const AliTPCclusterMI *kc1p = kr1p.FindNearest2(angley*(x1p-x1)+y1,
3546 if (kc1p->IsUsed(10)) used++;
3548 if (used>1) continue;
3549 if (found<1) continue;
3553 const AliTPCclusterMI *kc3m = kr3m.FindNearest2(angley*(x3m-x3)+y3,
3559 if (kc3m->IsUsed(10)) used++;
3563 const AliTPCclusterMI *kc3p = kr3p.FindNearest2(angley*(x3p-x3)+y3,
3569 if (kc3p->IsUsed(10)) used++;
3573 if (used>1) continue;
3574 if (found<3) continue;
3584 x[4]=F1(x1,y1,x2,y2,x3,y3);
3585 //if (TMath::Abs(x[4]) >= cuts[0]) continue;
3588 x[2]=F2(x1,y1,x2,y2,x3,y3);
3591 x[3]=F3n(x1,y1,x2,y2,z1,z2,x[4]);
3592 //if (TMath::Abs(x[3]) > cuts[3]) continue;
3596 Double_t sy1=0.1, sz1=0.1;
3597 Double_t sy2=0.1, sz2=0.1;
3598 Double_t sy3=0.1, sy=0.1, sz=0.1;
3600 Double_t f40=(F1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
3601 Double_t f42=(F1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
3602 Double_t f43=(F1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
3603 Double_t f20=(F2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
3604 Double_t f22=(F2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
3605 Double_t f23=(F2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
3607 Double_t f30=(F3(x1,y1+sy,x2,y2,z1,z2)-x[3])/sy;
3608 Double_t f31=(F3(x1,y1,x2,y2,z1+sz,z2)-x[3])/sz;
3609 Double_t f32=(F3(x1,y1,x2,y2+sy,z1,z2)-x[3])/sy;
3610 Double_t f34=(F3(x1,y1,x2,y2,z1,z2+sz)-x[3])/sz;
3614 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
3615 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
3616 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
3617 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
3618 c[13]=f30*sy1*f40+f32*sy2*f42;
3619 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
3621 // if (!BuildSeed(kr1[is],kcl,0,x1,x2,x3,x,c)) continue;
3623 index=kr1.GetIndex(is);
3624 if (seed) {MarkSeedFree( seed ); seed = 0;}
3625 AliTPCseed *track = seed = new( NextFreeSeed() ) AliTPCseed(x1, sec*alpha+shift, x, c, index);
3626 seed->SetPoolID(fLastSeedID);
3628 track->SetIsSeeding(kTRUE);
3631 FollowProlongation(*track, i1-7,1);
3632 if (track->GetNumberOfClusters() < track->GetNFoundable()*0.75 ||
3633 track->GetNShared()>0.6*track->GetNumberOfClusters() || ( track->GetSigmaY2()+ track->GetSigmaZ2())>0.6){
3634 MarkSeedFree( seed ); seed = 0;
3640 FollowProlongation(*track, i2,1);
3641 track->SetBConstrain(0);
3642 track->SetLastPoint(i1+fInnerSec->GetNRows()); // first cluster in track position
3643 track->SetFirstPoint(track->GetLastPoint());
3645 if (track->GetNumberOfClusters()<(i1-i2)*0.5 ||
3646 track->GetNumberOfClusters()<track->GetNFoundable()*0.7 ||
3647 track->GetNShared()>2. || track->GetChi2()/track->GetNumberOfClusters()>6 || ( track->GetSigmaY2()+ track->GetSigmaZ2())>0.5 ) {
3648 MarkSeedFree( seed ); seed = 0;
3653 FollowProlongation(*track, TMath::Max(i2-10,0),1);
3654 AliTPCseed * track2 = MakeSeed(track,0.2,0.5,0.9);
3655 FollowProlongation(*track2, i2,1);
3656 track2->SetBConstrain(kFALSE);
3657 track2->SetSeedType(4);
3658 arr->AddLast(track2);
3659 MarkSeedFree( seed ); seed = 0;
3663 //arr->AddLast(track);
3664 //seed = new AliTPCseed;
3670 Info("MakeSeeds5","\nSeeding statiistic:\t%d\t%d\t%d\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin,nout1,nout2,nout3);
3672 if (seed) MarkSeedFree(seed);
3676 //_____________________________________________________________________________
3677 void AliTPCtrackerMI::MakeSeeds2(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t */*cuts[4]*/,
3678 Float_t deltay, Bool_t /*bconstrain*/) {
3679 //-----------------------------------------------------------------
3680 // This function creates track seeds - without vertex constraint
3681 //-----------------------------------------------------------------
3682 // cuts[0] - fP4 cut - not applied
3683 // cuts[1] - tan(phi) cut
3684 // cuts[2] - zvertex cut - not applied
3685 // cuts[3] - fP3 cut
3695 Double_t alpha=fOuterSec->GetAlpha(), shift=fOuterSec->GetAlphaShift();
3696 // Double_t cs=cos(alpha), sn=sin(alpha);
3697 Int_t row0 = (i1+i2)/2;
3698 Int_t drow = (i1-i2)/2;
3699 const AliTPCtrackerRow& kr0=fSectors[sec][row0];
3700 AliTPCtrackerRow * kr=0;
3702 AliTPCpolyTrack polytrack;
3703 Int_t nclusters=fSectors[sec][row0];
3704 AliTPCseed * seed = new( NextFreeSeed() ) AliTPCseed;
3705 seed->SetPoolID(fLastSeedID);
3710 for (Int_t is=0; is < nclusters; is++) { //LOOP over clusters
3712 Int_t nfoundable =0;
3713 for (Int_t iter =1; iter<2; iter++){ //iterations
3714 const AliTPCtrackerRow& krm=fSectors[sec][row0-iter];
3715 const AliTPCtrackerRow& krp=fSectors[sec][row0+iter];
3716 const AliTPCclusterMI * cl= kr0[is];
3718 if (cl->IsUsed(10)) {
3724 Double_t x = kr0.GetX();
3725 // Initialization of the polytrack
3730 Double_t y0= cl->GetY();
3731 Double_t z0= cl->GetZ();
3735 Double_t ymax = fSectors->GetMaxY(row0)-kr0.GetDeadZone()-1.5;
3736 if (deltay>0 && TMath::Abs(ymax-TMath::Abs(y0))> deltay ) continue; // seed only at the edge
3738 erry = (0.5)*cl->GetSigmaY2()/TMath::Sqrt(cl->GetQ())*6;
3739 errz = (0.5)*cl->GetSigmaZ2()/TMath::Sqrt(cl->GetQ())*6;
3740 polytrack.AddPoint(x,y0,z0,erry, errz);
3743 if (cl->IsUsed(10)) sumused++;
3746 Float_t roady = (5*TMath::Sqrt(cl->GetSigmaY2()+0.2)+1.)*iter;
3747 Float_t roadz = (5*TMath::Sqrt(cl->GetSigmaZ2()+0.2)+1.)*iter;
3750 AliTPCclusterMI * cl1 = krm.FindNearest(y0,z0,roady,roadz);
3751 if (cl1 && TMath::Abs(ymax-TMath::Abs(y0))) {
3752 erry = (0.5)*cl1->GetSigmaY2()/TMath::Sqrt(cl1->GetQ())*3;
3753 errz = (0.5)*cl1->GetSigmaZ2()/TMath::Sqrt(cl1->GetQ())*3;
3754 if (cl1->IsUsed(10)) sumused++;
3755 polytrack.AddPoint(x,cl1->GetY(),cl1->GetZ(),erry,errz);
3759 AliTPCclusterMI * cl2 = krp.FindNearest(y0,z0,roady,roadz);
3761 erry = (0.5)*cl2->GetSigmaY2()/TMath::Sqrt(cl2->GetQ())*3;
3762 errz = (0.5)*cl2->GetSigmaZ2()/TMath::Sqrt(cl2->GetQ())*3;
3763 if (cl2->IsUsed(10)) sumused++;
3764 polytrack.AddPoint(x,cl2->GetY(),cl2->GetZ(),erry,errz);
3767 if (sumused>0) continue;
3769 polytrack.UpdateParameters();
3775 nfoundable = polytrack.GetN();
3776 nfound = nfoundable;
3778 for (Int_t ddrow = iter+1; ddrow<drow;ddrow++){
3779 Float_t maxdist = 0.8*(1.+3./(ddrow));
3780 for (Int_t delta = -1;delta<=1;delta+=2){
3781 Int_t row = row0+ddrow*delta;
3782 kr = &(fSectors[sec][row]);
3783 Double_t xn = kr->GetX();
3784 Double_t ymax1 = fSectors->GetMaxY(row)-kr->GetDeadZone()-1.5;
3785 polytrack.GetFitPoint(xn,yn,zn);
3786 if (TMath::Abs(yn)>ymax1) continue;
3788 AliTPCclusterMI * cln = kr->FindNearest(yn,zn,roady,roadz);
3790 Float_t dist = TMath::Sqrt( (yn-cln->GetY())*(yn-cln->GetY())+(zn-cln->GetZ())*(zn-cln->GetZ()));
3793 erry = (dist+0.3)*cln->GetSigmaY2()/TMath::Sqrt(cln->GetQ())*(1.+1./(ddrow));
3794 errz = (dist+0.3)*cln->GetSigmaZ2()/TMath::Sqrt(cln->GetQ())*(1.+1./(ddrow));
3795 if (cln->IsUsed(10)) {
3796 // printf("used\n");
3804 polytrack.AddPoint(xn,cln->GetY(),cln->GetZ(),erry, errz);
3809 if ( (sumused>3) || (sumused>0.5*nfound) || (nfound<0.6*nfoundable)) break;
3810 polytrack.UpdateParameters();
3813 if ( (sumused>3) || (sumused>0.5*nfound)) {
3814 //printf("sumused %d\n",sumused);
3819 polytrack.GetFitDerivation(kr0.GetX(),dy,dz);
3820 AliTPCpolyTrack track2;
3822 polytrack.Refit(track2,0.5+TMath::Abs(dy)*0.3,0.4+TMath::Abs(dz)*0.3);
3823 if (track2.GetN()<0.5*nfoundable) continue;
3826 if ((nfound>0.6*nfoundable) &&( nfoundable>0.4*(i1-i2))) {
3828 // test seed with and without constrain
3829 for (Int_t constrain=0; constrain<=0;constrain++){
3830 // add polytrack candidate
3832 Double_t x[5], c[15];
3833 Double_t x1,x2,x3,y1,y2,y3,z1,z2,z3;
3834 track2.GetBoundaries(x3,x1);
3836 track2.GetFitPoint(x1,y1,z1);
3837 track2.GetFitPoint(x2,y2,z2);
3838 track2.GetFitPoint(x3,y3,z3);
3840 //is track pointing to the vertex ?
3843 polytrack.GetFitPoint(x0,y0,z0);
3856 x[4]=F1(x1,y1,x2,y2,x3,y3);
3858 // if (TMath::Abs(x[4]) >= cuts[0]) continue; //
3859 x[2]=F2(x1,y1,x2,y2,x3,y3);
3861 //if (TMath::Abs(x[4]*x1-x[2]) >= cuts[1]) continue;
3862 //x[3]=F3(x1,y1,x2,y2,z1,z2);
3863 x[3]=F3n(x1,y1,x3,y3,z1,z3,x[4]);
3864 //if (TMath::Abs(x[3]) > cuts[3]) continue;
3867 Double_t sy =0.1, sz =0.1;
3868 Double_t sy1=0.02, sz1=0.02;
3869 Double_t sy2=0.02, sz2=0.02;
3873 sy3=25000*x[4]*x[4]+0.1, sy=0.1, sz=0.1;
3876 Double_t f40=(F1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
3877 Double_t f42=(F1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
3878 Double_t f43=(F1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
3879 Double_t f20=(F2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
3880 Double_t f22=(F2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
3881 Double_t f23=(F2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
3883 Double_t f30=(F3(x1,y1+sy,x3,y3,z1,z3)-x[3])/sy;
3884 Double_t f31=(F3(x1,y1,x3,y3,z1+sz,z3)-x[3])/sz;
3885 Double_t f32=(F3(x1,y1,x3,y3+sy,z1,z3)-x[3])/sy;
3886 Double_t f34=(F3(x1,y1,x3,y3,z1,z3+sz)-x[3])/sz;
3891 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
3892 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
3893 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
3894 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
3895 c[13]=f30*sy1*f40+f32*sy2*f42;
3896 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
3898 //Int_t row1 = fSectors->GetRowNumber(x1);
3899 Int_t row1 = GetRowNumber(x1);
3903 if (seed) {MarkSeedFree( seed ); seed = 0;}
3904 AliTPCseed *track = seed = new( NextFreeSeed() ) AliTPCseed(x1,sec*alpha+shift,x,c,index);
3905 seed->SetPoolID(fLastSeedID);
3906 track->SetIsSeeding(kTRUE);
3907 Int_t rc=FollowProlongation(*track, i2);
3908 if (constrain) track->SetBConstrain(1);
3910 track->SetBConstrain(0);
3911 track->SetLastPoint(row1+fInnerSec->GetNRows()); // first cluster in track position
3912 track->SetFirstPoint(track->GetLastPoint());
3914 if (rc==0 || track->GetNumberOfClusters()<(i1-i2)*0.5 ||
3915 track->GetNumberOfClusters() < track->GetNFoundable()*0.6 ||
3916 track->GetNShared()>0.4*track->GetNumberOfClusters()) {
3917 MarkSeedFree( seed ); seed = 0;
3920 arr->AddLast(track); // track IS seed, don't free seed
3921 seed = new( NextFreeSeed() ) AliTPCseed;
3922 seed->SetPoolID(fLastSeedID);
3926 } // if accepted seed
3929 Info("MakeSeeds2","\nSeeding statiistic:\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin3);
3931 if (seed) MarkSeedFree( seed );
3935 AliTPCseed *AliTPCtrackerMI::MakeSeed(AliTPCseed *const track, Float_t r0, Float_t r1, Float_t r2)
3939 //reseed using track points
3940 Int_t p0 = int(r0*track->GetNumberOfClusters()); // point 0
3941 Int_t p1 = int(r1*track->GetNumberOfClusters());
3942 Int_t p2 = int(r2*track->GetNumberOfClusters()); // last point
3944 Double_t x0[3],x1[3],x2[3];
3945 for (Int_t i=0;i<3;i++){
3951 // find track position at given ratio of the length
3952 Int_t sec0=0, sec1=0, sec2=0;
3955 for (Int_t i=0;i<160;i++){
3956 if (track->GetClusterPointer(i)){
3958 AliTPCTrackerPoint *trpoint =track->GetTrackPoint(i);
3959 if ( (index<p0) || x0[0]<0 ){
3960 if (trpoint->GetX()>1){
3961 clindex = track->GetClusterIndex2(i);
3963 x0[0] = trpoint->GetX();
3964 x0[1] = trpoint->GetY();
3965 x0[2] = trpoint->GetZ();
3966 sec0 = ((clindex&0xff000000)>>24)%18;
3971 if ( (index<p1) &&(trpoint->GetX()>1)){
3972 clindex = track->GetClusterIndex2(i);
3974 x1[0] = trpoint->GetX();
3975 x1[1] = trpoint->GetY();
3976 x1[2] = trpoint->GetZ();
3977 sec1 = ((clindex&0xff000000)>>24)%18;
3980 if ( (index<p2) &&(trpoint->GetX()>1)){
3981 clindex = track->GetClusterIndex2(i);
3983 x2[0] = trpoint->GetX();
3984 x2[1] = trpoint->GetY();
3985 x2[2] = trpoint->GetZ();
3986 sec2 = ((clindex&0xff000000)>>24)%18;
3993 Double_t alpha, cs,sn, xx2,yy2;
3995 alpha = (sec1-sec2)*fSectors->GetAlpha();
3996 cs = TMath::Cos(alpha);
3997 sn = TMath::Sin(alpha);
3998 xx2= x1[0]*cs-x1[1]*sn;
3999 yy2= x1[0]*sn+x1[1]*cs;
4003 alpha = (sec0-sec2)*fSectors->GetAlpha();
4004 cs = TMath::Cos(alpha);
4005 sn = TMath::Sin(alpha);
4006 xx2= x0[0]*cs-x0[1]*sn;
4007 yy2= x0[0]*sn+x0[1]*cs;
4013 Double_t x[5],c[15];
4017 x[4]=F1(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]);
4018 // if (x[4]>1) return 0;
4019 x[2]=F2(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]);
4020 x[3]=F3n(x2[0],x2[1],x0[0],x0[1],x2[2],x0[2],x[4]);
4021 //if (TMath::Abs(x[3]) > 2.2) return 0;
4022 //if (TMath::Abs(x[2]) > 1.99) return 0;
4024 Double_t sy =0.1, sz =0.1;
4026 Double_t sy1=0.02+track->GetSigmaY2(), sz1=0.02+track->GetSigmaZ2();
4027 Double_t sy2=0.01+track->GetSigmaY2(), sz2=0.01+track->GetSigmaZ2();
4028 Double_t sy3=0.01+track->GetSigmaY2();
4030 Double_t f40=(F1(x2[0],x2[1]+sy,x1[0],x1[1],x0[0],x0[1])-x[4])/sy;
4031 Double_t f42=(F1(x2[0],x2[1],x1[0],x1[1]+sy,x0[0],x0[1])-x[4])/sy;
4032 Double_t f43=(F1(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]+sy)-x[4])/sy;
4033 Double_t f20=(F2(x2[0],x2[1]+sy,x1[0],x1[1],x0[0],x0[1])-x[2])/sy;
4034 Double_t f22=(F2(x2[0],x2[1],x1[0],x1[1]+sy,x0[0],x0[1])-x[2])/sy;
4035 Double_t f23=(F2(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]+sy)-x[2])/sy;
4037 Double_t f30=(F3(x2[0],x2[1]+sy,x0[0],x0[1],x2[2],x0[2])-x[3])/sy;
4038 Double_t f31=(F3(x2[0],x2[1],x0[0],x0[1],x2[2]+sz,x0[2])-x[3])/sz;
4039 Double_t f32=(F3(x2[0],x2[1],x0[0],x0[1]+sy,x2[2],x0[2])-x[3])/sy;
4040 Double_t f34=(F3(x2[0],x2[1],x0[0],x0[1],x2[2],x0[2]+sz)-x[3])/sz;
4045 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
4046 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
4047 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
4048 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
4049 c[13]=f30*sy1*f40+f32*sy2*f42;
4050 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
4052 // Int_t row1 = fSectors->GetRowNumber(x2[0]);
4053 AliTPCseed *seed = new( NextFreeSeed() ) AliTPCseed(x2[0], sec2*fSectors->GetAlpha()+fSectors->GetAlphaShift(), x, c, 0);
4054 seed->SetPoolID(fLastSeedID);
4055 // Double_t y0,z0,y1,z1, y2,z2;
4056 //seed->GetProlongation(x0[0],y0,z0);
4057 // seed->GetProlongation(x1[0],y1,z1);
4058 //seed->GetProlongation(x2[0],y2,z2);
4060 seed->SetLastPoint(pp2);
4061 seed->SetFirstPoint(pp2);
4068 AliTPCseed *AliTPCtrackerMI::ReSeed(const AliTPCseed *track, Float_t r0, Float_t r1, Float_t r2)
4072 //reseed using founded clusters
4074 // Find the number of clusters
4075 Int_t nclusters = 0;
4076 for (Int_t irow=0;irow<160;irow++){
4077 if (track->GetClusterIndex(irow)>0) nclusters++;
4081 ipos[0] = TMath::Max(int(r0*nclusters),0); // point 0 cluster
4082 ipos[1] = TMath::Min(int(r1*nclusters),nclusters-1); //
4083 ipos[2] = TMath::Min(int(r2*nclusters),nclusters-1); // last point
4086 Double_t xyz[3][3]={{0}};
4087 Int_t row[3]={0},sec[3]={0,0,0};
4089 // find track row position at given ratio of the length
4091 for (Int_t irow=0;irow<160;irow++){
4092 if (track->GetClusterIndex2(irow)<0) continue;
4094 for (Int_t ipoint=0;ipoint<3;ipoint++){
4095 if (index<=ipos[ipoint]) row[ipoint] = irow;
4099 //Get cluster and sector position
4100 for (Int_t ipoint=0;ipoint<3;ipoint++){
4101 Int_t clindex = track->GetClusterIndex2(row[ipoint]);
4102 AliTPCclusterMI * cl = GetClusterMI(clindex);
4105 // AliTPCclusterMI * cl = GetClusterMI(clindex);
4108 sec[ipoint] = ((clindex&0xff000000)>>24)%18;
4109 xyz[ipoint][0] = GetXrow(row[ipoint]);
4110 xyz[ipoint][1] = cl->GetY();
4111 xyz[ipoint][2] = cl->GetZ();
4115 // Calculate seed state vector and covariance matrix
4117 Double_t alpha, cs,sn, xx2,yy2;
4119 alpha = (sec[1]-sec[2])*fSectors->GetAlpha();
4120 cs = TMath::Cos(alpha);
4121 sn = TMath::Sin(alpha);
4122 xx2= xyz[1][0]*cs-xyz[1][1]*sn;
4123 yy2= xyz[1][0]*sn+xyz[1][1]*cs;
4127 alpha = (sec[0]-sec[2])*fSectors->GetAlpha();
4128 cs = TMath::Cos(alpha);
4129 sn = TMath::Sin(alpha);
4130 xx2= xyz[0][0]*cs-xyz[0][1]*sn;
4131 yy2= xyz[0][0]*sn+xyz[0][1]*cs;
4137 Double_t x[5],c[15];
4141 x[4]=F1(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
4142 x[2]=F2(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
4143 x[3]=F3n(xyz[2][0],xyz[2][1],xyz[0][0],xyz[0][1],xyz[2][2],xyz[0][2],x[4]);
4145 Double_t sy =0.1, sz =0.1;
4147 Double_t sy1=0.2, sz1=0.2;
4148 Double_t sy2=0.2, sz2=0.2;
4151 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;
4152 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;
4153 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;
4154 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;
4155 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;
4156 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;
4158 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;
4159 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;
4160 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;
4161 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;
4166 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
4167 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
4168 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
4169 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
4170 c[13]=f30*sy1*f40+f32*sy2*f42;
4171 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
4173 // Int_t row1 = fSectors->GetRowNumber(xyz[2][0]);
4174 AliTPCseed *seed=new( NextFreeSeed() ) AliTPCseed(xyz[2][0], sec[2]*fSectors->GetAlpha()+fSectors->GetAlphaShift(), x, c, 0);
4175 seed->SetPoolID(fLastSeedID);
4176 seed->SetLastPoint(row[2]);
4177 seed->SetFirstPoint(row[2]);
4182 AliTPCseed *AliTPCtrackerMI::ReSeed(AliTPCseed *track,Int_t r0, Bool_t forward)
4186 //reseed using founded clusters
4189 Int_t row[3]={0,0,0};
4190 Int_t sec[3]={0,0,0};
4192 // forward direction
4194 for (Int_t irow=r0;irow<160;irow++){
4195 if (track->GetClusterIndex(irow)>0){
4200 for (Int_t irow=160;irow>r0;irow--){
4201 if (track->GetClusterIndex(irow)>0){
4206 for (Int_t irow=row[2]-15;irow>row[0];irow--){
4207 if (track->GetClusterIndex(irow)>0){
4215 for (Int_t irow=0;irow<r0;irow++){
4216 if (track->GetClusterIndex(irow)>0){
4221 for (Int_t irow=r0;irow>0;irow--){
4222 if (track->GetClusterIndex(irow)>0){
4227 for (Int_t irow=row[2]-15;irow>row[0];irow--){
4228 if (track->GetClusterIndex(irow)>0){
4235 if ((row[2]-row[0])<20) return 0;
4236 if (row[1]==0) return 0;
4239 //Get cluster and sector position
4240 for (Int_t ipoint=0;ipoint<3;ipoint++){
4241 Int_t clindex = track->GetClusterIndex2(row[ipoint]);
4242 AliTPCclusterMI * cl = GetClusterMI(clindex);
4245 // AliTPCclusterMI * cl = GetClusterMI(clindex);
4248 sec[ipoint] = ((clindex&0xff000000)>>24)%18;
4249 xyz[ipoint][0] = GetXrow(row[ipoint]);
4250 AliTPCTrackerPoint * point = track->GetTrackPoint(row[ipoint]);
4251 if (point&&ipoint<2){
4253 xyz[ipoint][1] = point->GetY();
4254 xyz[ipoint][2] = point->GetZ();
4257 xyz[ipoint][1] = cl->GetY();
4258 xyz[ipoint][2] = cl->GetZ();
4265 // Calculate seed state vector and covariance matrix
4267 Double_t alpha, cs,sn, xx2,yy2;
4269 alpha = (sec[1]-sec[2])*fSectors->GetAlpha();
4270 cs = TMath::Cos(alpha);
4271 sn = TMath::Sin(alpha);
4272 xx2= xyz[1][0]*cs-xyz[1][1]*sn;
4273 yy2= xyz[1][0]*sn+xyz[1][1]*cs;
4277 alpha = (sec[0]-sec[2])*fSectors->GetAlpha();
4278 cs = TMath::Cos(alpha);
4279 sn = TMath::Sin(alpha);
4280 xx2= xyz[0][0]*cs-xyz[0][1]*sn;
4281 yy2= xyz[0][0]*sn+xyz[0][1]*cs;
4287 Double_t x[5],c[15];
4291 x[4]=F1(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
4292 x[2]=F2(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
4293 x[3]=F3n(xyz[2][0],xyz[2][1],xyz[0][0],xyz[0][1],xyz[2][2],xyz[0][2],x[4]);
4295 Double_t sy =0.1, sz =0.1;
4297 Double_t sy1=0.2, sz1=0.2;
4298 Double_t sy2=0.2, sz2=0.2;
4301 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;
4302 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;
4303 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;
4304 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;
4305 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;
4306 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;
4308 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;
4309 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;
4310 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;
4311 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;
4316 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
4317 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
4318 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
4319 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
4320 c[13]=f30*sy1*f40+f32*sy2*f42;
4321 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
4323 // Int_t row1 = fSectors->GetRowNumber(xyz[2][0]);
4324 AliTPCseed *seed=new( NextFreeSeed() ) AliTPCseed(xyz[2][0], sec[2]*fSectors->GetAlpha()+fSectors->GetAlphaShift(), x, c, 0);
4325 seed->SetPoolID(fLastSeedID);
4326 seed->SetLastPoint(row[2]);
4327 seed->SetFirstPoint(row[2]);
4328 for (Int_t i=row[0];i<row[2];i++){
4329 seed->SetClusterIndex(i, track->GetClusterIndex(i));
4337 void AliTPCtrackerMI::FindMultiMC(const TObjArray * array, AliESDEvent */*esd*/, Int_t iter)
4340 // find multi tracks - THIS FUNCTION IS ONLY FOR DEBUG PURPOSES
4342 // Use AliTPCReconstructor::StreamLevel()>2 if you want to tune parameters - cuts
4344 // Two reasons to have multiple find tracks
4345 // 1. Curling tracks can be find more than once
4346 // 2. Splitted tracks
4347 // a.) Multiple seeding to increase tracking efficiency - (~ 100% reached)
4348 // b.) Edge effect on the sector boundaries
4351 // Algorithm done in 2 phases - because of CPU consumption
4352 // it is n^2 algorithm - for lead-lead 20000x20000 combination are investigated
4354 // Algorihm for curling tracks sign:
4355 // 1 phase -makes a very rough fast cuts to minimize combinatorics
4356 // a.) opposite sign
4357 // b.) one of the tracks - not pointing to the primary vertex -
4358 // c.) delta tan(theta)
4360 // 2 phase - calculates DCA between tracks - time consument
4365 // General cuts - for splitted tracks and for curling tracks
4367 const Float_t kMaxdPhi = 0.2; // maximal distance in phi
4369 // Curling tracks cuts
4374 Int_t nentries = array->GetEntriesFast();
4375 AliHelix *helixes = new AliHelix[nentries];
4376 Float_t *xm = new Float_t[nentries];
4377 Float_t *dz0 = new Float_t[nentries];
4378 Float_t *dz1 = new Float_t[nentries];
4384 // Find track COG in x direction - point with best defined parameters
4386 for (Int_t i=0;i<nentries;i++){
4387 AliTPCseed* track = (AliTPCseed*)array->At(i);
4388 if (!track) continue;
4389 track->SetCircular(0);
4390 new (&helixes[i]) AliHelix(*track);
4394 track->GetDZ(GetX(),GetY(),GetZ(),GetBz(),dz);
4397 for (Int_t icl=0; icl<160; icl++){
4398 AliTPCclusterMI * cl = track->GetClusterPointer(icl);
4404 if (ncl>0) xm[i]/=Float_t(ncl);
4407 for (Int_t i0=0;i0<nentries;i0++){
4408 AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
4409 if (!track0) continue;
4410 Float_t xc0 = helixes[i0].GetHelix(6);
4411 Float_t yc0 = helixes[i0].GetHelix(7);
4412 Float_t r0 = helixes[i0].GetHelix(8);
4413 Float_t rc0 = TMath::Sqrt(xc0*xc0+yc0*yc0);
4414 Float_t fi0 = TMath::ATan2(yc0,xc0);
4416 for (Int_t i1=i0+1;i1<nentries;i1++){
4417 AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
4418 if (!track1) continue;
4419 Int_t lab0=track0->GetLabel();
4420 Int_t lab1=track1->GetLabel();
4421 if (TMath::Abs(lab0)!=TMath::Abs(lab1)) continue;
4423 Float_t xc1 = helixes[i1].GetHelix(6);
4424 Float_t yc1 = helixes[i1].GetHelix(7);
4425 Float_t r1 = helixes[i1].GetHelix(8);
4426 Float_t rc1 = TMath::Sqrt(xc1*xc1+yc1*yc1);
4427 Float_t fi1 = TMath::ATan2(yc1,xc1);
4429 Float_t dfi = fi0-fi1;
4432 if (dfi>1.5*TMath::Pi()) dfi-=TMath::Pi(); // take care about edge effect
4433 if (dfi<-1.5*TMath::Pi()) dfi+=TMath::Pi(); //
4434 if (TMath::Abs(dfi)>kMaxdPhi&&helixes[i0].GetHelix(4)*helixes[i1].GetHelix(4)<0){
4436 // if short tracks with undefined sign
4437 fi1 = -TMath::ATan2(yc1,-xc1);
4440 Float_t dtheta = TMath::Abs(track0->GetTgl()-track1->GetTgl())<TMath::Abs(track0->GetTgl()+track1->GetTgl())? track0->GetTgl()-track1->GetTgl():track0->GetTgl()+track1->GetTgl();
4443 // debug stream to tune "fast cuts"
4445 Double_t dist[3]; // distance at X
4446 Double_t mdist[3]={0,0,0}; // mean distance X+-40cm
4447 track0->GetDistance(track1,0.5*(xm[i0]+xm[i1])-40.,dist,AliTracker::GetBz());
4448 for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[i]);
4449 track0->GetDistance(track1,0.5*(xm[i0]+xm[i1])+40.,dist,AliTracker::GetBz());
4450 for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[i]);
4451 track0->GetDistance(track1,0.5*(xm[i0]+xm[i1]),dist,AliTracker::GetBz());
4452 for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[i]);
4453 for (Int_t i=0;i<3;i++) mdist[i]*=0.33333;
4457 for (Int_t icl=0; icl<160; icl++){
4458 AliTPCclusterMI * cl0 = track0->GetClusterPointer(icl);
4459 AliTPCclusterMI * cl1 = track1->GetClusterPointer(icl);
4462 if (cl0==cl1) sums++;
4466 if (AliTPCReconstructor::StreamLevel()>5) {
4467 TTreeSRedirector &cstream = *fDebugStreamer;
4472 "Tr0.="<<track0<< // seed0
4473 "Tr1.="<<track1<< // seed1
4474 "h0.="<<&helixes[i0]<<
4475 "h1.="<<&helixes[i1]<<
4477 "sum="<<sum<< //the sum of rows with cl in both
4478 "sums="<<sums<< //the sum of shared clusters
4479 "xm0="<<xm[i0]<< // the center of track
4480 "xm1="<<xm[i1]<< // the x center of track
4481 // General cut variables
4482 "dfi="<<dfi<< // distance in fi angle
4483 "dtheta="<<dtheta<< // distance int theta angle
4489 "dist0="<<dist[0]<< //distance x
4490 "dist1="<<dist[1]<< //distance y
4491 "dist2="<<dist[2]<< //distance z
4492 "mdist0="<<mdist[0]<< //distance x
4493 "mdist1="<<mdist[1]<< //distance y
4494 "mdist2="<<mdist[2]<< //distance z
4510 if (AliTPCReconstructor::StreamLevel()>1) {
4511 AliInfo("Time for curling tracks removal DEBUGGING MC");
4518 void AliTPCtrackerMI::FindSplitted(TObjArray * array, AliESDEvent */*esd*/, Int_t /*iter*/){
4520 // Find Splitted tracks and remove the one with worst quality
4521 // Corresponding debug streamer to tune selections - "Splitted2"
4523 // 0. Sort tracks according quility
4524 // 1. Propagate the tracks to the reference radius
4525 // 2. Double_t loop to select close tracks (only to speed up process)
4526 // 3. Calculate cluster overlap ratio - and remove the track if bigger than a threshold
4527 // 4. Delete temporary parameters
4529 const Double_t xref=GetXrow(63); // reference radius -IROC/OROC boundary
4531 const Double_t kCutP1=10; // delta Z cut 10 cm
4532 const Double_t kCutP2=0.15; // delta snp(fi) cut 0.15
4533 const Double_t kCutP3=0.15; // delta tgl(theta) cut 0.15
4534 const Double_t kCutAlpha=0.15; // delta alpha cut
4535 Int_t firstpoint = 0;
4536 Int_t lastpoint = 160;
4538 Int_t nentries = array->GetEntriesFast();
4539 AliExternalTrackParam *params = new AliExternalTrackParam[nentries];
4545 //0. Sort tracks according quality
4546 //1. Propagate the ext. param to reference radius
4547 Int_t nseed = array->GetEntriesFast();
4548 if (nseed<=0) return;
4549 Float_t * quality = new Float_t[nseed];
4550 Int_t * indexes = new Int_t[nseed];
4551 for (Int_t i=0; i<nseed; i++) {
4552 AliTPCseed *pt=(AliTPCseed*)array->UncheckedAt(i);
4557 pt->UpdatePoints(); //select first last max dens points
4558 Float_t * points = pt->GetPoints();
4559 if (points[3]<0.8) quality[i] =-1;
4560 quality[i] = (points[2]-points[0])+pt->GetNumberOfClusters();
4561 //prefer high momenta tracks if overlaps
4562 quality[i] *= TMath::Sqrt(TMath::Abs(pt->Pt())+0.5);
4564 AliTracker::PropagateTrackToBxByBz(&(params[i]),xref,pt->GetMass(),5.,kTRUE);
4565 AliTracker::PropagateTrackToBxByBz(&(params[i]),xref,pt->GetMass(),1.,kTRUE);
4567 TMath::Sort(nseed,quality,indexes);
4569 // 3. Loop over pair of tracks
4571 for (Int_t i0=0; i0<nseed; i0++) {
4572 Int_t index0=indexes[i0];
4573 if (!(array->UncheckedAt(index0))) continue;
4574 AliTPCseed *s1 = (AliTPCseed*)array->UncheckedAt(index0);
4575 if (!s1->IsActive()) continue;
4576 AliExternalTrackParam &par0=params[index0];
4577 for (Int_t i1=i0+1; i1<nseed; i1++) {
4578 Int_t index1=indexes[i1];
4579 if (!(array->UncheckedAt(index1))) continue;
4580 AliTPCseed *s2 = (AliTPCseed*)array->UncheckedAt(index1);
4581 if (!s2->IsActive()) continue;
4582 if (s2->GetKinkIndexes()[0]!=0)
4583 if (s2->GetKinkIndexes()[0] == -s1->GetKinkIndexes()[0]) continue;
4584 AliExternalTrackParam &par1=params[index1];
4585 if (TMath::Abs(par0.GetParameter()[3]-par1.GetParameter()[3])>kCutP3) continue;
4586 if (TMath::Abs(par0.GetParameter()[1]-par1.GetParameter()[1])>kCutP1) continue;
4587 if (TMath::Abs(par0.GetParameter()[2]-par1.GetParameter()[2])>kCutP2) continue;
4588 Double_t dAlpha= TMath::Abs(par0.GetAlpha()-par1.GetAlpha());
4589 if (dAlpha>TMath::Pi()) dAlpha-=TMath::Pi();
4590 if (TMath::Abs(dAlpha)>kCutAlpha) continue;
4595 Int_t firstShared=lastpoint, lastShared=firstpoint;
4596 Int_t firstRow=lastpoint, lastRow=firstpoint;
4598 for (Int_t i=firstpoint;i<lastpoint;i++){
4599 if (s1->GetClusterIndex2(i)>0) nall0++;
4600 if (s2->GetClusterIndex2(i)>0) nall1++;
4601 if (s1->GetClusterIndex2(i)>0 && s2->GetClusterIndex2(i)>0) {
4602 if (i<firstRow) firstRow=i;
4603 if (i>lastRow) lastRow=i;
4605 if ( (s1->GetClusterIndex2(i))==(s2->GetClusterIndex2(i)) && s1->GetClusterIndex2(i)>0) {
4606 if (i<firstShared) firstShared=i;
4607 if (i>lastShared) lastShared=i;
4611 Double_t ratio0 = Float_t(sumShared)/Float_t(TMath::Min(nall0+1,nall1+1));
4612 Double_t ratio1 = Float_t(sumShared)/Float_t(TMath::Max(nall0+1,nall1+1));
4614 if( AliTPCReconstructor::StreamLevel()>1){
4615 TTreeSRedirector &cstream = *fDebugStreamer;
4616 Int_t n0=s1->GetNumberOfClusters();
4617 Int_t n1=s2->GetNumberOfClusters();
4618 Int_t n0F=s1->GetNFoundable();
4619 Int_t n1F=s2->GetNFoundable();
4620 Int_t lab0=s1->GetLabel();
4621 Int_t lab1=s2->GetLabel();
4623 cstream<<"Splitted2"<<
4624 "iter="<<fIteration<<
4625 "lab0="<<lab0<< // MC label if exist
4626 "lab1="<<lab1<< // MC label if exist
4629 "ratio0="<<ratio0<< // shared ratio
4630 "ratio1="<<ratio1<< // shared ratio
4631 "p0.="<<&par0<< // track parameters
4633 "s0.="<<s1<< // full seed
4635 "n0="<<n0<< // number of clusters track 0
4636 "n1="<<n1<< // number of clusters track 1
4637 "nall0="<<nall0<< // number of clusters track 0
4638 "nall1="<<nall1<< // number of clusters track 1
4639 "n0F="<<n0F<< // number of findable
4640 "n1F="<<n1F<< // number of findable
4641 "shared="<<sumShared<< // number of shared clusters
4642 "firstS="<<firstShared<< // first and the last shared row
4643 "lastS="<<lastShared<<
4644 "firstRow="<<firstRow<< // first and the last row with cluster
4645 "lastRow="<<lastRow<< //
4649 // remove track with lower quality
4651 if (ratio0>AliTPCReconstructor::GetRecoParam()->GetCutSharedClusters(0) ||
4652 ratio1>AliTPCReconstructor::GetRecoParam()->GetCutSharedClusters(1)){
4656 MarkSeedFree( array->RemoveAt(index1) );
4661 // 4. Delete temporary array
4671 void AliTPCtrackerMI::FindCurling(const TObjArray * array, AliESDEvent */*esd*/, Int_t iter)
4674 // find Curling tracks
4675 // Use AliTPCReconstructor::StreamLevel()>1 if you want to tune parameters - cuts
4678 // Algorithm done in 2 phases - because of CPU consumption
4679 // it is n^2 algorithm - for lead-lead 20000x20000 combination are investigated
4680 // see detal in MC part what can be used to cut
4684 const Float_t kMaxC = 400; // maximal curvature to of the track
4685 const Float_t kMaxdTheta = 0.15; // maximal distance in theta
4686 const Float_t kMaxdPhi = 0.15; // maximal distance in phi
4687 const Float_t kPtRatio = 0.3; // ratio between pt
4688 const Float_t kMinDCAR = 2.; // distance to the primary vertex in r - see cpipe cut
4691 // Curling tracks cuts
4694 const Float_t kMaxDeltaRMax = 40; // distance in outer radius
4695 const Float_t kMaxDeltaRMin = 5.; // distance in lower radius - see cpipe cut
4696 const Float_t kMinAngle = 2.9; // angle between tracks
4697 const Float_t kMaxDist = 5; // biggest distance
4699 // The cuts can be tuned using the "MC information stored in Multi tree ==> see FindMultiMC
4702 TCut csign("csign","Tr0.fP[4]*Tr1.fP[4]<0"); //opposite sign
4703 TCut cmax("cmax","abs(Tr0.GetC())>1/400");
4704 TCut cda("cda","sqrt(dtheta^2+dfi^2)<0.15");
4705 TCut ccratio("ccratio","abs((Tr0.fP[4]+Tr1.fP[4])/(abs(Tr0.fP[4])+abs(Tr1.fP[4])))<0.3");
4706 TCut cpipe("cpipe", "min(abs(r0-rc0),abs(r1-rc1))>5");
4708 TCut cdrmax("cdrmax","abs(abs(rc0+r0)-abs(rc1+r1))<40")
4709 TCut cdrmin("cdrmin","abs(abs(rc0+r0)-abs(rc1+r1))<10")
4711 Multi->Draw("dfi","iter==0"+csign+cmax+cda+ccratio); ~94% of curling tracks fulfill
4712 Multi->Draw("min(abs(r0-rc0),abs(r1-rc1))","iter==0&&abs(lab1)==abs(lab0)"+csign+cmax+cda+ccratio+cpipe+cdrmin+cdrmax); //80%
4714 Curling2->Draw("dfi","iter==0&&abs(lab0)==abs(lab1)"+csign+cmax+cdtheta+cdfi+ccratio)
4720 Int_t nentries = array->GetEntriesFast();
4721 AliHelix *helixes = new AliHelix[nentries];
4722 for (Int_t i=0;i<nentries;i++){
4723 AliTPCseed* track = (AliTPCseed*)array->At(i);
4724 if (!track) continue;
4725 track->SetCircular(0);
4726 new (&helixes[i]) AliHelix(*track);
4732 Double_t phase[2][2]={{0,0},{0,0}},radius[2]={0,0};
4738 for (Int_t i0=0;i0<nentries;i0++){
4739 AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
4740 if (!track0) continue;
4741 if (TMath::Abs(track0->GetC())<1/kMaxC) continue;
4742 Float_t xc0 = helixes[i0].GetHelix(6);
4743 Float_t yc0 = helixes[i0].GetHelix(7);
4744 Float_t r0 = helixes[i0].GetHelix(8);
4745 Float_t rc0 = TMath::Sqrt(xc0*xc0+yc0*yc0);
4746 Float_t fi0 = TMath::ATan2(yc0,xc0);
4748 for (Int_t i1=i0+1;i1<nentries;i1++){
4749 AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
4750 if (!track1) continue;
4751 if (TMath::Abs(track1->GetC())<1/kMaxC) continue;
4752 Float_t xc1 = helixes[i1].GetHelix(6);
4753 Float_t yc1 = helixes[i1].GetHelix(7);
4754 Float_t r1 = helixes[i1].GetHelix(8);
4755 Float_t rc1 = TMath::Sqrt(xc1*xc1+yc1*yc1);
4756 Float_t fi1 = TMath::ATan2(yc1,xc1);
4758 Float_t dfi = fi0-fi1;
4761 if (dfi>1.5*TMath::Pi()) dfi-=TMath::Pi(); // take care about edge effect
4762 if (dfi<-1.5*TMath::Pi()) dfi+=TMath::Pi(); //
4763 Float_t dtheta = TMath::Abs(track0->GetTgl()-track1->GetTgl())<TMath::Abs(track0->GetTgl()+track1->GetTgl())? track0->GetTgl()-track1->GetTgl():track0->GetTgl()+track1->GetTgl();
4767 if (track0->GetBConstrain()&&track1->GetBConstrain()) continue; // not constrained
4768 if (track1->GetSigned1Pt()*track0->GetSigned1Pt()>0) continue; // not the same sign
4769 if ( TMath::Abs(track1->GetTgl()+track0->GetTgl())>kMaxdTheta) continue; //distance in the Theta
4770 if ( TMath::Abs(dfi)>kMaxdPhi) continue; //distance in phi
4771 if ( TMath::Sqrt(dfi*dfi+dtheta*dtheta)>kMaxdPhi) continue; //common angular offset
4773 Float_t pt0 = track0->GetSignedPt();
4774 Float_t pt1 = track1->GetSignedPt();
4775 if ((TMath::Abs(pt0+pt1)/(TMath::Abs(pt0)+TMath::Abs(pt1)))>kPtRatio) continue;
4776 if ((iter==1) && TMath::Abs(TMath::Abs(rc0+r0)-TMath::Abs(rc1+r1))>kMaxDeltaRMax) continue;
4777 if ((iter!=1) &&TMath::Abs(TMath::Abs(rc0-r0)-TMath::Abs(rc1-r1))>kMaxDeltaRMin) continue;
4778 if (TMath::Min(TMath::Abs(rc0-r0),TMath::Abs(rc1-r1))<kMinDCAR) continue;
4781 // Now find closest approach
4785 Int_t npoints = helixes[i0].GetRPHIintersections(helixes[i1], phase, radius,10);
4786 if (npoints==0) continue;
4787 helixes[i0].GetClosestPhases(helixes[i1], phase);
4791 Double_t hangles[3];
4792 helixes[i0].Evaluate(phase[0][0],xyz0);
4793 helixes[i1].Evaluate(phase[0][1],xyz1);
4795 helixes[i0].GetAngle(phase[0][0],helixes[i1],phase[0][1],hangles);
4796 Double_t deltah[2],deltabest;
4797 if (TMath::Abs(hangles[2])<kMinAngle) continue;
4801 helixes[i0].ParabolicDCA(helixes[i1],phase[0][0],phase[0][1],radius[0],deltah[0],2);
4803 helixes[i0].ParabolicDCA(helixes[i1],phase[1][0],phase[1][1],radius[1],deltah[1],2);
4804 if (deltah[1]<deltah[0]) ibest=1;
4806 deltabest = TMath::Sqrt(deltah[ibest]);
4807 helixes[i0].Evaluate(phase[ibest][0],xyz0);
4808 helixes[i1].Evaluate(phase[ibest][1],xyz1);
4809 helixes[i0].GetAngle(phase[ibest][0],helixes[i1],phase[ibest][1],hangles);
4810 Double_t radiusbest = TMath::Sqrt(radius[ibest]);
4812 if (deltabest>kMaxDist) continue;
4813 // if (mindcar+mindcaz<40 && (TMath::Abs(hangles[2])<kMinAngle ||deltabest>3)) continue;
4814 Bool_t sign =kFALSE;
4815 if (hangles[2]>kMinAngle) sign =kTRUE;
4818 // circular[i0] = kTRUE;
4819 // circular[i1] = kTRUE;
4820 if (track0->OneOverPt()<track1->OneOverPt()){
4821 track0->SetCircular(track0->GetCircular()+1);
4822 track1->SetCircular(track1->GetCircular()+2);
4825 track1->SetCircular(track1->GetCircular()+1);
4826 track0->SetCircular(track0->GetCircular()+2);
4829 if (AliTPCReconstructor::StreamLevel()>2){
4831 //debug stream to tune "fine" cuts
4832 Int_t lab0=track0->GetLabel();
4833 Int_t lab1=track1->GetLabel();
4834 TTreeSRedirector &cstream = *fDebugStreamer;
4835 cstream<<"Curling2"<<
4851 "npoints="<<npoints<<
4852 "hangles0="<<hangles[0]<<
4853 "hangles1="<<hangles[1]<<
4854 "hangles2="<<hangles[2]<<
4857 "radius="<<radiusbest<<
4858 "deltabest="<<deltabest<<
4859 "phase0="<<phase[ibest][0]<<
4860 "phase1="<<phase[ibest][1]<<
4868 if (AliTPCReconstructor::StreamLevel()>1) {
4869 AliInfo("Time for curling tracks removal");
4875 void AliTPCtrackerMI::FindKinks(TObjArray * array, AliESDEvent *esd)
4881 // RS something is wrong in this routine: not all seeds are assigned to daughters and mothers array, but they all are queried
4884 TObjArray *kinks= new TObjArray(10000);
4885 // TObjArray *v0s= new TObjArray(10000);
4886 Int_t nentries = array->GetEntriesFast();
4887 AliHelix *helixes = new AliHelix[nentries];
4888 Int_t *sign = new Int_t[nentries];
4889 Int_t *nclusters = new Int_t[nentries];
4890 Float_t *alpha = new Float_t[nentries];
4891 AliKink *kink = new AliKink();
4892 Int_t * usage = new Int_t[nentries];
4893 Float_t *zm = new Float_t[nentries];
4894 Float_t *z0 = new Float_t[nentries];
4895 Float_t *fim = new Float_t[nentries];
4896 Float_t *shared = new Float_t[nentries];
4897 Bool_t *circular = new Bool_t[nentries];
4898 Float_t *dca = new Float_t[nentries];
4899 //const AliESDVertex * primvertex = esd->GetVertex();
4901 // nentries = array->GetEntriesFast();
4906 for (Int_t i=0;i<nentries;i++){
4909 AliTPCseed* track = (AliTPCseed*)array->At(i);
4910 if (!track) continue;
4911 track->SetCircular(0);
4913 track->UpdatePoints();
4914 if (( track->GetPoints()[2]- track->GetPoints()[0])>5 && track->GetPoints()[3]>0.8){
4916 nclusters[i]=track->GetNumberOfClusters();
4917 alpha[i] = track->GetAlpha();
4918 new (&helixes[i]) AliHelix(*track);
4920 helixes[i].Evaluate(0,xyz);
4921 sign[i] = (track->GetC()>0) ? -1:1;
4924 if (track->GetProlongation(x,y,z)){
4926 fim[i] = alpha[i]+TMath::ATan2(y,x);
4929 zm[i] = track->GetZ();
4933 circular[i]= kFALSE;
4934 if (track->GetProlongation(0,y,z)) z0[i] = z;
4935 dca[i] = track->GetD(0,0);
4941 Int_t ncandidates =0;
4944 Double_t phase[2][2]={{0,0},{0,0}},radius[2]={0,0};
4947 // Find circling track
4949 for (Int_t i0=0;i0<nentries;i0++){
4950 AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
4951 if (!track0) continue;
4952 if (track0->GetNumberOfClusters()<40) continue;
4953 if (TMath::Abs(1./track0->GetC())>200) continue;
4954 for (Int_t i1=i0+1;i1<nentries;i1++){
4955 AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
4956 if (!track1) continue;
4957 if (track1->GetNumberOfClusters()<40) continue;
4958 if ( TMath::Abs(track1->GetTgl()+track0->GetTgl())>0.1) continue;
4959 if (track0->GetBConstrain()&&track1->GetBConstrain()) continue;
4960 if (TMath::Abs(1./track1->GetC())>200) continue;
4961 if (track1->GetSigned1Pt()*track0->GetSigned1Pt()>0) continue;
4962 if (track1->GetTgl()*track0->GetTgl()>0) continue;
4963 if (TMath::Max(TMath::Abs(1./track0->GetC()),TMath::Abs(1./track1->GetC()))>190) continue;
4964 if (track0->GetBConstrain()&&track1->OneOverPt()<track0->OneOverPt()) continue; //returning - lower momenta
4965 if (track1->GetBConstrain()&&track0->OneOverPt()<track1->OneOverPt()) continue; //returning - lower momenta
4967 Float_t mindcar = TMath::Min(TMath::Abs(dca[i0]),TMath::Abs(dca[i1]));
4968 if (mindcar<5) continue;
4969 Float_t mindcaz = TMath::Min(TMath::Abs(z0[i0]-GetZ()),TMath::Abs(z0[i1]-GetZ()));
4970 if (mindcaz<5) continue;
4971 if (mindcar+mindcaz<20) continue;
4974 Float_t xc0 = helixes[i0].GetHelix(6);
4975 Float_t yc0 = helixes[i0].GetHelix(7);
4976 Float_t r0 = helixes[i0].GetHelix(8);
4977 Float_t xc1 = helixes[i1].GetHelix(6);
4978 Float_t yc1 = helixes[i1].GetHelix(7);
4979 Float_t r1 = helixes[i1].GetHelix(8);
4981 Float_t rmean = (r0+r1)*0.5;
4982 Float_t delta =TMath::Sqrt((xc1-xc0)*(xc1-xc0)+(yc1-yc0)*(yc1-yc0));
4983 //if (delta>30) continue;
4984 if (delta>rmean*0.25) continue;
4985 if (TMath::Abs(r0-r1)/rmean>0.3) continue;
4987 Int_t npoints = helixes[i0].GetRPHIintersections(helixes[i1], phase, radius,10);
4988 if (npoints==0) continue;
4989 helixes[i0].GetClosestPhases(helixes[i1], phase);
4993 Double_t hangles[3];
4994 helixes[i0].Evaluate(phase[0][0],xyz0);
4995 helixes[i1].Evaluate(phase[0][1],xyz1);
4997 helixes[i0].GetAngle(phase[0][0],helixes[i1],phase[0][1],hangles);
4998 Double_t deltah[2],deltabest;
4999 if (hangles[2]<2.8) continue;
5002 helixes[i0].ParabolicDCA(helixes[i1],phase[0][0],phase[0][1],radius[0],deltah[0],2);
5004 helixes[i0].ParabolicDCA(helixes[i1],phase[1][0],phase[1][1],radius[1],deltah[1],2);
5005 if (deltah[1]<deltah[0]) ibest=1;
5007 deltabest = TMath::Sqrt(deltah[ibest]);
5008 helixes[i0].Evaluate(phase[ibest][0],xyz0);
5009 helixes[i1].Evaluate(phase[ibest][1],xyz1);
5010 helixes[i0].GetAngle(phase[ibest][0],helixes[i1],phase[ibest][1],hangles);
5011 Double_t radiusbest = TMath::Sqrt(radius[ibest]);
5013 if (deltabest>6) continue;
5014 if (mindcar+mindcaz<40 && (hangles[2]<3.12||deltabest>3)) continue;
5015 Bool_t lsign =kFALSE;
5016 if (hangles[2]>3.06) lsign =kTRUE;
5019 circular[i0] = kTRUE;
5020 circular[i1] = kTRUE;
5021 if (track0->OneOverPt()<track1->OneOverPt()){
5022 track0->SetCircular(track0->GetCircular()+1);
5023 track1->SetCircular(track1->GetCircular()+2);
5026 track1->SetCircular(track1->GetCircular()+1);
5027 track0->SetCircular(track0->GetCircular()+2);
5030 if (lsign&&AliTPCReconstructor::StreamLevel()>1){
5032 Int_t lab0=track0->GetLabel();
5033 Int_t lab1=track1->GetLabel();
5034 TTreeSRedirector &cstream = *fDebugStreamer;
5035 cstream<<"Curling"<<
5042 "mindcar="<<mindcar<<
5043 "mindcaz="<<mindcaz<<
5046 "npoints="<<npoints<<
5047 "hangles0="<<hangles[0]<<
5048 "hangles2="<<hangles[2]<<
5053 "radius="<<radiusbest<<
5054 "deltabest="<<deltabest<<
5055 "phase0="<<phase[ibest][0]<<
5056 "phase1="<<phase[ibest][1]<<
5066 for (Int_t i =0;i<nentries;i++){
5067 if (sign[i]==0) continue;
5068 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
5075 Double_t cradius0 = 40*40;
5076 Double_t cradius1 = 270*270;
5079 Double_t cdist3=0.55;
5080 for (Int_t j =i+1;j<nentries;j++){
5082 if (sign[j]*sign[i]<1) continue;
5083 if ( (nclusters[i]+nclusters[j])>200) continue;
5084 if ( (nclusters[i]+nclusters[j])<80) continue;
5085 if ( TMath::Abs(zm[i]-zm[j])>60.) continue;
5086 if ( TMath::Abs(fim[i]-fim[j])>0.6 && TMath::Abs(fim[i]-fim[j])<5.7 ) continue;
5087 //AliTPCseed * track1 = (AliTPCseed*)array->At(j); Double_t phase[2][2],radius[2];
5088 Int_t npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,20);
5089 if (npoints<1) continue;
5092 if (radius[0]<cradius0||radius[0]>cradius1) continue;
5095 if ( (radius[0]<cradius0||radius[0]>cradius1) && (radius[1]<cradius0||radius[1]>cradius1) ) continue;
5098 Double_t delta1=10000,delta2=10000;
5099 // cuts on the intersection radius
5100 helixes[i].LinearDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta1);
5101 if (radius[0]<20&&delta1<1) continue; //intersection at vertex
5102 if (radius[0]<10&&delta1<3) continue; //intersection at vertex
5104 helixes[i].LinearDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta2);
5105 if (radius[1]<20&&delta2<1) continue; //intersection at vertex
5106 if (radius[1]<10&&delta2<3) continue; //intersection at vertex
5109 Double_t distance1 = TMath::Min(delta1,delta2);
5110 if (distance1>cdist1) continue; // cut on DCA linear approximation
5112 npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,20);
5113 helixes[i].ParabolicDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta1);
5114 if (radius[0]<20&&delta1<1) continue; //intersection at vertex
5115 if (radius[0]<10&&delta1<3) continue; //intersection at vertex
5118 helixes[i].ParabolicDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta2);
5119 if (radius[1]<20&&delta2<1) continue; //intersection at vertex
5120 if (radius[1]<10&&delta2<3) continue; //intersection at vertex
5122 distance1 = TMath::Min(delta1,delta2);
5125 rkink = TMath::Sqrt(radius[0]);
5128 rkink = TMath::Sqrt(radius[1]);
5130 if (distance1>cdist2) continue;
5133 AliTPCseed * track1 = (AliTPCseed*)array->At(j);
5136 Int_t row0 = GetRowNumber(rkink);
5137 if (row0<10) continue;
5138 if (row0>150) continue;
5141 Float_t dens00=-1,dens01=-1;
5142 Float_t dens10=-1,dens11=-1;
5144 Int_t found,foundable,ishared;
5145 track0->GetClusterStatistic(0,row0-5, found, foundable,ishared,kFALSE);
5146 if (foundable>5) dens00 = Float_t(found)/Float_t(foundable);
5147 track0->GetClusterStatistic(row0+5,155, found, foundable,ishared,kFALSE);
5148 if (foundable>5) dens01 = Float_t(found)/Float_t(foundable);
5150 track1->GetClusterStatistic(0,row0-5, found, foundable,ishared,kFALSE);
5151 if (foundable>10) dens10 = Float_t(found)/Float_t(foundable);
5152 track1->GetClusterStatistic(row0+5,155, found, foundable,ishared,kFALSE);
5153 if (foundable>10) dens11 = Float_t(found)/Float_t(foundable);
5155 if (dens00<dens10 && dens01<dens11) continue;
5156 if (dens00>dens10 && dens01>dens11) continue;
5157 if (TMath::Max(dens00,dens10)<0.1) continue;
5158 if (TMath::Max(dens01,dens11)<0.3) continue;
5160 if (TMath::Min(dens00,dens10)>0.6) continue;
5161 if (TMath::Min(dens01,dens11)>0.6) continue;
5164 AliTPCseed * ktrack0, *ktrack1;
5173 if (TMath::Abs(ktrack0->GetC())>5) continue; // cut on the curvature for mother particle
5174 AliExternalTrackParam paramm(*ktrack0);
5175 AliExternalTrackParam paramd(*ktrack1);
5176 if (row0>60&&ktrack1->GetReference().GetX()>90.)new (¶md) AliExternalTrackParam(ktrack1->GetReference());
5179 kink->SetMother(paramm);
5180 kink->SetDaughter(paramd);
5183 Float_t x[3] = { kink->GetPosition()[0],kink->GetPosition()[1],kink->GetPosition()[2]};
5185 fkParam->Transform0to1(x,index);
5186 fkParam->Transform1to2(x,index);
5187 row0 = GetRowNumber(x[0]);
5189 if (kink->GetR()<100) continue;
5190 if (kink->GetR()>240) continue;
5191 if (kink->GetPosition()[2]/kink->GetR()>AliTPCReconstructor::GetCtgRange()) continue; //out of fiducial volume
5192 if (kink->GetDistance()>cdist3) continue;
5193 Float_t dird = kink->GetDaughterP()[0]*kink->GetPosition()[0]+kink->GetDaughterP()[1]*kink->GetPosition()[1]; // rough direction estimate
5194 if (dird<0) continue;
5196 Float_t dirm = kink->GetMotherP()[0]*kink->GetPosition()[0]+kink->GetMotherP()[1]*kink->GetPosition()[1]; // rough direction estimate
5197 if (dirm<0) continue;
5198 Float_t mpt = TMath::Sqrt(kink->GetMotherP()[0]*kink->GetMotherP()[0]+kink->GetMotherP()[1]*kink->GetMotherP()[1]);
5199 if (mpt<0.2) continue;
5202 //for high momenta momentum not defined well in first iteration
5203 Double_t qt = TMath::Sin(kink->GetAngle(2))*ktrack1->GetP();
5204 if (qt>0.35) continue;
5207 kink->SetLabel(CookLabel(ktrack0,0.4,0,row0),0);
5208 kink->SetLabel(CookLabel(ktrack1,0.4,row0,160),1);
5210 kink->SetTPCDensity(dens00,0,0);
5211 kink->SetTPCDensity(dens01,0,1);
5212 kink->SetTPCDensity(dens10,1,0);
5213 kink->SetTPCDensity(dens11,1,1);
5214 kink->SetIndex(i,0);
5215 kink->SetIndex(j,1);
5218 kink->SetTPCDensity(dens10,0,0);
5219 kink->SetTPCDensity(dens11,0,1);
5220 kink->SetTPCDensity(dens00,1,0);
5221 kink->SetTPCDensity(dens01,1,1);
5222 kink->SetIndex(j,0);
5223 kink->SetIndex(i,1);
5226 if (mpt<1||kink->GetAngle(2)>0.1){
5227 // angle and densities not defined yet
5228 if (kink->GetTPCDensityFactor()<0.8) continue;
5229 if ((2-kink->GetTPCDensityFactor())*kink->GetDistance() >0.25) continue;
5230 if (kink->GetAngle(2)*ktrack0->GetP()<0.003) continue; //too small angle
5231 if (kink->GetAngle(2)>0.2&&kink->GetTPCDensityFactor()<1.15) continue;
5232 if (kink->GetAngle(2)>0.2&&kink->GetTPCDensity(0,1)>0.05) continue;
5234 Float_t criticalangle = track0->GetSigmaSnp2()+track0->GetSigmaTgl2();
5235 criticalangle+= track1->GetSigmaSnp2()+track1->GetSigmaTgl2();
5236 criticalangle= 3*TMath::Sqrt(criticalangle);
5237 if (criticalangle>0.02) criticalangle=0.02;
5238 if (kink->GetAngle(2)<criticalangle) continue;
5241 Int_t drow = Int_t(2.+0.5/(0.05+kink->GetAngle(2))); // overlap region defined
5242 Float_t shapesum =0;
5244 for ( Int_t row = row0-drow; row<row0+drow;row++){
5245 if (row<0) continue;
5246 if (row>155) continue;
5247 if (ktrack0->GetClusterPointer(row)){
5248 AliTPCTrackerPoint *point =ktrack0->GetTrackPoint(row);
5249 shapesum+=point->GetSigmaY()+point->GetSigmaZ();
5252 if (ktrack1->GetClusterPointer(row)){
5253 AliTPCTrackerPoint *point =ktrack1->GetTrackPoint(row);
5254 shapesum+=point->GetSigmaY()+point->GetSigmaZ();
5259 kink->SetShapeFactor(-1.);
5262 kink->SetShapeFactor(shapesum/sum);
5264 // esd->AddKink(kink);
5266 // kink->SetMother(paramm);
5267 //kink->SetDaughter(paramd);
5269 Double_t chi2P2 = paramm.GetParameter()[2]-paramd.GetParameter()[2];
5271 chi2P2/=paramm.GetCovariance()[5]+paramd.GetCovariance()[5];
5272 Double_t chi2P3 = paramm.GetParameter()[3]-paramd.GetParameter()[3];
5274 chi2P3/=paramm.GetCovariance()[9]+paramd.GetCovariance()[9];
5276 if (AliTPCReconstructor::StreamLevel()>1) {
5277 (*fDebugStreamer)<<"kinkLpt"<<
5285 if ( chi2P2+chi2P3<AliTPCReconstructor::GetRecoParam()->GetKinkAngleCutChi2(0)){
5289 kinks->AddLast(kink);
5295 // sort the kinks according quality - and refit them towards vertex
5297 Int_t nkinks = kinks->GetEntriesFast();
5298 Float_t *quality = new Float_t[nkinks];
5299 Int_t *indexes = new Int_t[nkinks];
5300 AliTPCseed *mothers = new AliTPCseed[nkinks];
5301 AliTPCseed *daughters = new AliTPCseed[nkinks];
5304 for (Int_t i=0;i<nkinks;i++){
5306 AliKink *kinkl = (AliKink*)kinks->At(i);
5308 // refit kinks towards vertex
5310 Int_t index0 = kinkl->GetIndex(0);
5311 Int_t index1 = kinkl->GetIndex(1);
5312 AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
5313 AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
5315 Int_t sumn=ktrack0->GetNumberOfClusters()+ktrack1->GetNumberOfClusters();
5317 // Refit Kink under if too small angle
5319 if (kinkl->GetAngle(2)<0.05){
5320 kinkl->SetTPCRow0(GetRowNumber(kinkl->GetR()));
5321 Int_t row0 = kinkl->GetTPCRow0();
5322 Int_t drow = Int_t(2.+0.5/(0.05+kinkl->GetAngle(2)));
5325 Int_t last = row0-drow;
5326 if (last<40) last=40;
5327 if (last<ktrack0->GetFirstPoint()+25) last = ktrack0->GetFirstPoint()+25;
5328 AliTPCseed* seed0 = ReSeed(ktrack0,last,kFALSE);
5331 Int_t first = row0+drow;
5332 if (first>130) first=130;
5333 if (first>ktrack1->GetLastPoint()-25) first = TMath::Max(ktrack1->GetLastPoint()-25,30);
5334 AliTPCseed* seed1 = ReSeed(ktrack1,first,kTRUE);
5336 if (seed0 && seed1){
5337 kinkl->SetStatus(1,8);
5338 if (RefitKink(*seed0,*seed1,*kinkl)) kinkl->SetStatus(1,9);
5339 row0 = GetRowNumber(kinkl->GetR());
5340 sumn = seed0->GetNumberOfClusters()+seed1->GetNumberOfClusters();
5341 mothers[i] = *seed0;
5342 daughters[i] = *seed1;
5345 delete kinks->RemoveAt(i);
5346 if (seed0) MarkSeedFree( seed0 );
5347 if (seed1) MarkSeedFree( seed1 );
5350 if (kinkl->GetDistance()>0.5 || kinkl->GetR()<110 || kinkl->GetR()>240) {
5351 delete kinks->RemoveAt(i);
5352 if (seed0) MarkSeedFree( seed0 );
5353 if (seed1) MarkSeedFree( seed1 );
5357 MarkSeedFree( seed0 );
5358 MarkSeedFree( seed1 );
5361 if (kinkl) quality[i] = 160*((0.1+kinkl->GetDistance())*(2.-kinkl->GetTPCDensityFactor()))/(sumn+40.); //the longest -clossest will win
5363 TMath::Sort(nkinks,quality,indexes,kFALSE);
5365 //remove double find kinks
5367 for (Int_t ikink0=1;ikink0<nkinks;ikink0++){
5368 AliKink * kink0 = (AliKink*) kinks->At(indexes[ikink0]);
5369 if (!kink0) continue;
5371 for (Int_t ikink1=0;ikink1<ikink0;ikink1++){
5372 kink0 = (AliKink*) kinks->At(indexes[ikink0]);
5373 if (!kink0) continue;
5374 AliKink * kink1 = (AliKink*) kinks->At(indexes[ikink1]);
5375 if (!kink1) continue;
5376 // if not close kink continue
5377 if (TMath::Abs(kink1->GetPosition()[2]-kink0->GetPosition()[2])>10) continue;
5378 if (TMath::Abs(kink1->GetPosition()[1]-kink0->GetPosition()[1])>10) continue;
5379 if (TMath::Abs(kink1->GetPosition()[0]-kink0->GetPosition()[0])>10) continue;
5381 AliTPCseed &mother0 = mothers[indexes[ikink0]];
5382 AliTPCseed &daughter0 = daughters[indexes[ikink0]];
5383 AliTPCseed &mother1 = mothers[indexes[ikink1]];
5384 AliTPCseed &daughter1 = daughters[indexes[ikink1]];
5385 Int_t row0 = (kink0->GetTPCRow0()+kink1->GetTPCRow0())/2;
5394 for (Int_t i=0;i<row0;i++){
5395 if (mother0.GetClusterIndex(i)>0 && mother1.GetClusterIndex(i)>0){
5398 if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
5405 for (Int_t i=row0;i<158;i++){
5406 //if (daughter0.GetClusterIndex(i)>0 && daughter0.GetClusterIndex(i)>0){ // RS: Bug?
5407 if (daughter0.GetClusterIndex(i)>0 && daughter1.GetClusterIndex(i)>0){
5410 if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
5416 Float_t ratio = Float_t(same+1)/Float_t(both+1);
5417 Float_t ratiom = Float_t(samem+1)/Float_t(bothm+1);
5418 Float_t ratiod = Float_t(samed+1)/Float_t(bothd+1);
5419 if (ratio>0.3 && ratiom>0.5 &&ratiod>0.5) {
5420 Int_t sum0 = mother0.GetNumberOfClusters()+daughter0.GetNumberOfClusters();
5421 Int_t sum1 = mother1.GetNumberOfClusters()+daughter1.GetNumberOfClusters();
5423 shared[kink0->GetIndex(0)]= kTRUE;
5424 shared[kink0->GetIndex(1)]= kTRUE;
5425 delete kinks->RemoveAt(indexes[ikink0]);
5429 shared[kink1->GetIndex(0)]= kTRUE;
5430 shared[kink1->GetIndex(1)]= kTRUE;
5431 delete kinks->RemoveAt(indexes[ikink1]);
5438 for (Int_t i=0;i<nkinks;i++){
5439 AliKink * kinkl = (AliKink*) kinks->At(indexes[i]);
5440 if (!kinkl) continue;
5441 kinkl->SetTPCRow0(GetRowNumber(kinkl->GetR()));
5442 Int_t index0 = kinkl->GetIndex(0);
5443 Int_t index1 = kinkl->GetIndex(1);
5444 if (circular[index0]||(circular[index1]&&kinkl->GetDistance()>0.2)) continue;
5445 kinkl->SetMultiple(usage[index0],0);
5446 kinkl->SetMultiple(usage[index1],1);
5447 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>2) continue;
5448 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>0 && quality[indexes[i]]>0.2) continue;
5449 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>0 && kinkl->GetDistance()>0.2) continue;
5450 if (circular[index0]||(circular[index1]&&kinkl->GetDistance()>0.1)) continue;
5452 AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
5453 AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
5454 if (!ktrack0 || !ktrack1) continue;
5455 Int_t index = esd->AddKink(kinkl);
5458 if ( ktrack0->GetKinkIndex(0)==0 && ktrack1->GetKinkIndex(0)==0) { //best kink
5459 if (mothers[indexes[i]].GetNumberOfClusters()>20 && daughters[indexes[i]].GetNumberOfClusters()>20 && (mothers[indexes[i]].GetNumberOfClusters()+daughters[indexes[i]].GetNumberOfClusters())>100){
5460 *ktrack0 = mothers[indexes[i]];
5461 *ktrack1 = daughters[indexes[i]];
5465 ktrack0->SetKinkIndex(usage[index0],-(index+1));
5466 ktrack1->SetKinkIndex(usage[index1], (index+1));
5471 // Remove tracks corresponding to shared kink's
5473 for (Int_t i=0;i<nentries;i++){
5474 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
5475 if (!track0) continue;
5476 if (track0->GetKinkIndex(0)!=0) continue;
5477 if (shared[i]) MarkSeedFree( array->RemoveAt(i) );
5482 RemoveUsed2(array,0.5,0.4,30);
5484 for (Int_t i=0;i<nentries;i++){
5485 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
5486 if (!track0) continue;
5487 track0->CookdEdx(0.02,0.6);
5491 for (Int_t i=0;i<nentries;i++){
5492 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
5493 if (!track0) continue;
5494 if (track0->Pt()<1.4) continue;
5495 //remove double high momenta tracks - overlapped with kink candidates
5498 for (Int_t icl=track0->GetFirstPoint();icl<track0->GetLastPoint(); icl++){
5499 if (track0->GetClusterPointer(icl)!=0){
5501 if (track0->GetClusterPointer(icl)->IsUsed(10)) ishared++;
5504 if (Float_t(ishared+1)/Float_t(all+1)>0.5) {
5505 MarkSeedFree( array->RemoveAt(i) );
5509 if (track0->GetKinkIndex(0)!=0) continue;
5510 if (track0->GetNumberOfClusters()<80) continue;
5512 AliTPCseed *pmother = new AliTPCseed();
5513 AliTPCseed *pdaughter = new AliTPCseed();
5514 AliKink *pkink = new AliKink;
5516 AliTPCseed & mother = *pmother;
5517 AliTPCseed & daughter = *pdaughter;
5518 AliKink & kinkl = *pkink;
5519 if (CheckKinkPoint(track0,mother,daughter, kinkl)){
5520 if (mother.GetNumberOfClusters()<30||daughter.GetNumberOfClusters()<20) {
5524 continue; //too short tracks
5526 if (mother.Pt()<1.4) {
5532 Int_t row0= kinkl.GetTPCRow0();
5533 if (kinkl.GetDistance()>0.5 || kinkl.GetR()<110. || kinkl.GetR()>240.) {
5540 Int_t index = esd->AddKink(&kinkl);
5541 mother.SetKinkIndex(0,-(index+1));
5542 daughter.SetKinkIndex(0,index+1);
5543 if (mother.GetNumberOfClusters()>50) {
5544 MarkSeedFree( array->RemoveAt(i) );
5545 AliTPCseed* mtc = new( NextFreeSeed() ) AliTPCseed(mother);
5546 mtc->SetPoolID(fLastSeedID);
5547 array->AddAt(mtc,i);
5550 AliTPCseed* mtc = new( NextFreeSeed() ) AliTPCseed(mother);
5551 mtc->SetPoolID(fLastSeedID);
5552 array->AddLast(mtc);
5554 AliTPCseed* dtc = new( NextFreeSeed() ) AliTPCseed(daughter);
5555 dtc->SetPoolID(fLastSeedID);
5556 array->AddLast(dtc);
5557 for (Int_t icl=0;icl<row0;icl++) {
5558 if (mother.GetClusterPointer(icl)) mother.GetClusterPointer(icl)->Use(20);
5561 for (Int_t icl=row0;icl<158;icl++) {
5562 if (daughter.GetClusterPointer(icl)) daughter.GetClusterPointer(icl)->Use(20);
5571 delete [] daughters;
5593 AliInfo(Form("Ncandidates=\t%d\t%d\t%d\t%d\n",esd->GetNumberOfKinks(),ncandidates,ntracks,nall));
5599 void AliTPCtrackerMI::FindKinks(TObjArray * array, AliESDEvent *esd)
5606 TObjArray *kinks= new TObjArray(10000);
5607 // TObjArray *v0s= new TObjArray(10000);
5608 Int_t nentries = array->GetEntriesFast();
5609 AliHelix *helixes = new AliHelix[nentries];
5610 Int_t *sign = new Int_t[nentries];
5611 Int_t *nclusters = new Int_t[nentries];
5612 Float_t *alpha = new Float_t[nentries];
5613 AliKink *kink = new AliKink();
5614 Int_t * usage = new Int_t[nentries];
5615 Float_t *zm = new Float_t[nentries];
5616 Float_t *z0 = new Float_t[nentries];
5617 Float_t *fim = new Float_t[nentries];
5618 Float_t *shared = new Float_t[nentries];
5619 Bool_t *circular = new Bool_t[nentries];
5620 Float_t *dca = new Float_t[nentries];
5621 //const AliESDVertex * primvertex = esd->GetVertex();
5623 // nentries = array->GetEntriesFast();
5628 for (Int_t i=0;i<nentries;i++){
5631 AliTPCseed* track = (AliTPCseed*)array->At(i);
5632 if (!track) continue;
5633 track->SetCircular(0);
5635 track->UpdatePoints();
5636 if (( track->GetPoints()[2]- track->GetPoints()[0])>5 && track->GetPoints()[3]>0.8){
5638 nclusters[i]=track->GetNumberOfClusters();
5639 alpha[i] = track->GetAlpha();
5640 new (&helixes[i]) AliHelix(*track);
5642 helixes[i].Evaluate(0,xyz);
5643 sign[i] = (track->GetC()>0) ? -1:1;
5646 if (track->GetProlongation(x,y,z)){
5648 fim[i] = alpha[i]+TMath::ATan2(y,x);
5651 zm[i] = track->GetZ();
5655 circular[i]= kFALSE;
5656 if (track->GetProlongation(0,y,z)) z0[i] = z;
5657 dca[i] = track->GetD(0,0);
5663 Int_t ncandidates =0;
5666 Double_t phase[2][2]={{0,0},{0,0}},radius[2]={0,0};
5669 // Find circling track
5671 for (Int_t i0=0;i0<nentries;i0++){
5672 AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
5673 if (!track0) continue;
5674 if (track0->GetNumberOfClusters()<40) continue;
5675 if (TMath::Abs(1./track0->GetC())>200) continue;
5676 for (Int_t i1=i0+1;i1<nentries;i1++){
5677 AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
5678 if (!track1) continue;
5679 if (track1->GetNumberOfClusters()<40) continue;
5680 if ( TMath::Abs(track1->GetTgl()+track0->GetTgl())>0.1) continue;
5681 if (track0->GetBConstrain()&&track1->GetBConstrain()) continue;
5682 if (TMath::Abs(1./track1->GetC())>200) continue;
5683 if (track1->GetSigned1Pt()*track0->GetSigned1Pt()>0) continue;
5684 if (track1->GetTgl()*track0->GetTgl()>0) continue;
5685 if (TMath::Max(TMath::Abs(1./track0->GetC()),TMath::Abs(1./track1->GetC()))>190) continue;
5686 if (track0->GetBConstrain()&&track1->OneOverPt()<track0->OneOverPt()) continue; //returning - lower momenta
5687 if (track1->GetBConstrain()&&track0->OneOverPt()<track1->OneOverPt()) continue; //returning - lower momenta
5689 Float_t mindcar = TMath::Min(TMath::Abs(dca[i0]),TMath::Abs(dca[i1]));
5690 if (mindcar<5) continue;
5691 Float_t mindcaz = TMath::Min(TMath::Abs(z0[i0]-GetZ()),TMath::Abs(z0[i1]-GetZ()));
5692 if (mindcaz<5) continue;
5693 if (mindcar+mindcaz<20) continue;
5696 Float_t xc0 = helixes[i0].GetHelix(6);
5697 Float_t yc0 = helixes[i0].GetHelix(7);
5698 Float_t r0 = helixes[i0].GetHelix(8);
5699 Float_t xc1 = helixes[i1].GetHelix(6);
5700 Float_t yc1 = helixes[i1].GetHelix(7);
5701 Float_t r1 = helixes[i1].GetHelix(8);
5703 Float_t rmean = (r0+r1)*0.5;
5704 Float_t delta =TMath::Sqrt((xc1-xc0)*(xc1-xc0)+(yc1-yc0)*(yc1-yc0));
5705 //if (delta>30) continue;
5706 if (delta>rmean*0.25) continue;
5707 if (TMath::Abs(r0-r1)/rmean>0.3) continue;
5709 Int_t npoints = helixes[i0].GetRPHIintersections(helixes[i1], phase, radius,10);
5710 if (npoints==0) continue;
5711 helixes[i0].GetClosestPhases(helixes[i1], phase);
5715 Double_t hangles[3];
5716 helixes[i0].Evaluate(phase[0][0],xyz0);
5717 helixes[i1].Evaluate(phase[0][1],xyz1);
5719 helixes[i0].GetAngle(phase[0][0],helixes[i1],phase[0][1],hangles);
5720 Double_t deltah[2],deltabest;
5721 if (hangles[2]<2.8) continue;
5724 helixes[i0].ParabolicDCA(helixes[i1],phase[0][0],phase[0][1],radius[0],deltah[0],2);
5726 helixes[i0].ParabolicDCA(helixes[i1],phase[1][0],phase[1][1],radius[1],deltah[1],2);
5727 if (deltah[1]<deltah[0]) ibest=1;
5729 deltabest = TMath::Sqrt(deltah[ibest]);
5730 helixes[i0].Evaluate(phase[ibest][0],xyz0);
5731 helixes[i1].Evaluate(phase[ibest][1],xyz1);
5732 helixes[i0].GetAngle(phase[ibest][0],helixes[i1],phase[ibest][1],hangles);
5733 Double_t radiusbest = TMath::Sqrt(radius[ibest]);
5735 if (deltabest>6) continue;
5736 if (mindcar+mindcaz<40 && (hangles[2]<3.12||deltabest>3)) continue;
5737 Bool_t lsign =kFALSE;
5738 if (hangles[2]>3.06) lsign =kTRUE;
5741 circular[i0] = kTRUE;
5742 circular[i1] = kTRUE;
5743 if (track0->OneOverPt()<track1->OneOverPt()){
5744 track0->SetCircular(track0->GetCircular()+1);
5745 track1->SetCircular(track1->GetCircular()+2);
5748 track1->SetCircular(track1->GetCircular()+1);
5749 track0->SetCircular(track0->GetCircular()+2);
5752 if (lsign&&AliTPCReconstructor::StreamLevel()>1){
5754 Int_t lab0=track0->GetLabel();
5755 Int_t lab1=track1->GetLabel();
5756 TTreeSRedirector &cstream = *fDebugStreamer;
5757 cstream<<"Curling"<<
5764 "mindcar="<<mindcar<<
5765 "mindcaz="<<mindcaz<<
5768 "npoints="<<npoints<<
5769 "hangles0="<<hangles[0]<<
5770 "hangles2="<<hangles[2]<<
5775 "radius="<<radiusbest<<
5776 "deltabest="<<deltabest<<
5777 "phase0="<<phase[ibest][0]<<
5778 "phase1="<<phase[ibest][1]<<
5788 for (Int_t i =0;i<nentries;i++){
5789 if (sign[i]==0) continue;
5790 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
5797 Double_t cradius0 = 40*40;
5798 Double_t cradius1 = 270*270;
5801 Double_t cdist3=0.55;
5802 for (Int_t j =i+1;j<nentries;j++){
5804 if (sign[j]*sign[i]<1) continue;
5805 if ( (nclusters[i]+nclusters[j])>200) continue;
5806 if ( (nclusters[i]+nclusters[j])<80) continue;
5807 if ( TMath::Abs(zm[i]-zm[j])>60.) continue;
5808 if ( TMath::Abs(fim[i]-fim[j])>0.6 && TMath::Abs(fim[i]-fim[j])<5.7 ) continue;
5809 //AliTPCseed * track1 = (AliTPCseed*)array->At(j); Double_t phase[2][2],radius[2];
5810 Int_t npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,20);
5811 if (npoints<1) continue;
5814 if (radius[0]<cradius0||radius[0]>cradius1) continue;
5817 if ( (radius[0]<cradius0||radius[0]>cradius1) && (radius[1]<cradius0||radius[1]>cradius1) ) continue;
5820 Double_t delta1=10000,delta2=10000;
5821 // cuts on the intersection radius
5822 helixes[i].LinearDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta1);
5823 if (radius[0]<20&&delta1<1) continue; //intersection at vertex
5824 if (radius[0]<10&&delta1<3) continue; //intersection at vertex
5826 helixes[i].LinearDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta2);
5827 if (radius[1]<20&&delta2<1) continue; //intersection at vertex
5828 if (radius[1]<10&&delta2<3) continue; //intersection at vertex
5831 Double_t distance1 = TMath::Min(delta1,delta2);
5832 if (distance1>cdist1) continue; // cut on DCA linear approximation
5834 npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,20);
5835 helixes[i].ParabolicDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta1);
5836 if (radius[0]<20&&delta1<1) continue; //intersection at vertex
5837 if (radius[0]<10&&delta1<3) continue; //intersection at vertex
5840 helixes[i].ParabolicDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta2);
5841 if (radius[1]<20&&delta2<1) continue; //intersection at vertex
5842 if (radius[1]<10&&delta2<3) continue; //intersection at vertex
5844 distance1 = TMath::Min(delta1,delta2);
5847 rkink = TMath::Sqrt(radius[0]);
5850 rkink = TMath::Sqrt(radius[1]);
5852 if (distance1>cdist2) continue;
5855 AliTPCseed * track1 = (AliTPCseed*)array->At(j);
5858 Int_t row0 = GetRowNumber(rkink);
5859 if (row0<10) continue;
5860 if (row0>150) continue;
5863 Float_t dens00=-1,dens01=-1;
5864 Float_t dens10=-1,dens11=-1;
5866 Int_t found,foundable,ishared;
5867 track0->GetClusterStatistic(0,row0-5, found, foundable,ishared,kFALSE);
5868 if (foundable>5) dens00 = Float_t(found)/Float_t(foundable);
5869 track0->GetClusterStatistic(row0+5,155, found, foundable,ishared,kFALSE);
5870 if (foundable>5) dens01 = Float_t(found)/Float_t(foundable);
5872 track1->GetClusterStatistic(0,row0-5, found, foundable,ishared,kFALSE);
5873 if (foundable>10) dens10 = Float_t(found)/Float_t(foundable);
5874 track1->GetClusterStatistic(row0+5,155, found, foundable,ishared,kFALSE);
5875 if (foundable>10) dens11 = Float_t(found)/Float_t(foundable);
5877 if (dens00<dens10 && dens01<dens11) continue;
5878 if (dens00>dens10 && dens01>dens11) continue;
5879 if (TMath::Max(dens00,dens10)<0.1) continue;
5880 if (TMath::Max(dens01,dens11)<0.3) continue;
5882 if (TMath::Min(dens00,dens10)>0.6) continue;
5883 if (TMath::Min(dens01,dens11)>0.6) continue;
5886 AliTPCseed * ktrack0, *ktrack1;
5895 if (TMath::Abs(ktrack0->GetC())>5) continue; // cut on the curvature for mother particle
5896 AliExternalTrackParam paramm(*ktrack0);
5897 AliExternalTrackParam paramd(*ktrack1);
5898 if (row0>60&&ktrack1->GetReference().GetX()>90.)new (¶md) AliExternalTrackParam(ktrack1->GetReference());
5901 kink->SetMother(paramm);
5902 kink->SetDaughter(paramd);
5905 Float_t x[3] = { kink->GetPosition()[0],kink->GetPosition()[1],kink->GetPosition()[2]};
5907 fkParam->Transform0to1(x,index);
5908 fkParam->Transform1to2(x,index);
5909 row0 = GetRowNumber(x[0]);
5911 if (kink->GetR()<100) continue;
5912 if (kink->GetR()>240) continue;
5913 if (kink->GetPosition()[2]/kink->GetR()>AliTPCReconstructor::GetCtgRange()) continue; //out of fiducial volume
5914 if (kink->GetDistance()>cdist3) continue;
5915 Float_t dird = kink->GetDaughterP()[0]*kink->GetPosition()[0]+kink->GetDaughterP()[1]*kink->GetPosition()[1]; // rough direction estimate
5916 if (dird<0) continue;
5918 Float_t dirm = kink->GetMotherP()[0]*kink->GetPosition()[0]+kink->GetMotherP()[1]*kink->GetPosition()[1]; // rough direction estimate
5919 if (dirm<0) continue;
5920 Float_t mpt = TMath::Sqrt(kink->GetMotherP()[0]*kink->GetMotherP()[0]+kink->GetMotherP()[1]*kink->GetMotherP()[1]);
5921 if (mpt<0.2) continue;
5924 //for high momenta momentum not defined well in first iteration
5925 Double_t qt = TMath::Sin(kink->GetAngle(2))*ktrack1->GetP();
5926 if (qt>0.35) continue;
5929 kink->SetLabel(CookLabel(ktrack0,0.4,0,row0),0);
5930 kink->SetLabel(CookLabel(ktrack1,0.4,row0,160),1);
5932 kink->SetTPCDensity(dens00,0,0);
5933 kink->SetTPCDensity(dens01,0,1);
5934 kink->SetTPCDensity(dens10,1,0);
5935 kink->SetTPCDensity(dens11,1,1);
5936 kink->SetIndex(i,0);
5937 kink->SetIndex(j,1);
5940 kink->SetTPCDensity(dens10,0,0);
5941 kink->SetTPCDensity(dens11,0,1);
5942 kink->SetTPCDensity(dens00,1,0);
5943 kink->SetTPCDensity(dens01,1,1);
5944 kink->SetIndex(j,0);
5945 kink->SetIndex(i,1);
5948 if (mpt<1||kink->GetAngle(2)>0.1){
5949 // angle and densities not defined yet
5950 if (kink->GetTPCDensityFactor()<0.8) continue;
5951 if ((2-kink->GetTPCDensityFactor())*kink->GetDistance() >0.25) continue;
5952 if (kink->GetAngle(2)*ktrack0->GetP()<0.003) continue; //too small angle
5953 if (kink->GetAngle(2)>0.2&&kink->GetTPCDensityFactor()<1.15) continue;
5954 if (kink->GetAngle(2)>0.2&&kink->GetTPCDensity(0,1)>0.05) continue;
5956 Float_t criticalangle = track0->GetSigmaSnp2()+track0->GetSigmaTgl2();
5957 criticalangle+= track1->GetSigmaSnp2()+track1->GetSigmaTgl2();
5958 criticalangle= 3*TMath::Sqrt(criticalangle);
5959 if (criticalangle>0.02) criticalangle=0.02;
5960 if (kink->GetAngle(2)<criticalangle) continue;
5963 Int_t drow = Int_t(2.+0.5/(0.05+kink->GetAngle(2))); // overlap region defined
5964 Float_t shapesum =0;
5966 for ( Int_t row = row0-drow; row<row0+drow;row++){
5967 if (row<0) continue;
5968 if (row>155) continue;
5969 if (ktrack0->GetClusterPointer(row)){
5970 AliTPCTrackerPoint *point =ktrack0->GetTrackPoint(row);
5971 shapesum+=point->GetSigmaY()+point->GetSigmaZ();
5974 if (ktrack1->GetClusterPointer(row)){
5975 AliTPCTrackerPoint *point =ktrack1->GetTrackPoint(row);
5976 shapesum+=point->GetSigmaY()+point->GetSigmaZ();
5981 kink->SetShapeFactor(-1.);
5984 kink->SetShapeFactor(shapesum/sum);
5986 // esd->AddKink(kink);
5988 // kink->SetMother(paramm);
5989 //kink->SetDaughter(paramd);
5991 Double_t chi2P2 = paramm.GetParameter()[2]-paramd.GetParameter()[2];
5993 chi2P2/=paramm.GetCovariance()[5]+paramd.GetCovariance()[5];
5994 Double_t chi2P3 = paramm.GetParameter()[3]-paramd.GetParameter()[3];
5996 chi2P3/=paramm.GetCovariance()[9]+paramd.GetCovariance()[9];
5998 if (AliTPCReconstructor::StreamLevel()>1) {
5999 (*fDebugStreamer)<<"kinkLpt"<<
6007 if ( chi2P2+chi2P3<AliTPCReconstructor::GetRecoParam()->GetKinkAngleCutChi2(0)){
6011 kinks->AddLast(kink);
6017 // sort the kinks according quality - and refit them towards vertex
6019 Int_t nkinks = kinks->GetEntriesFast();
6020 Float_t *quality = new Float_t[nkinks];
6021 Int_t *indexes = new Int_t[nkinks];
6022 AliTPCseed **mothers = new AliTPCseed*[nkinks]; memset(mothers, 0, nkinks*sizeof(AliTPCseed*));
6023 AliTPCseed **daughters = new AliTPCseed*[nkinks]; memset(daughters, 0, nkinks*sizeof(AliTPCseed*));
6026 for (Int_t i=0;i<nkinks;i++){
6028 AliKink *kinkl = (AliKink*)kinks->At(i);
6030 // refit kinks towards vertex
6032 Int_t index0 = kinkl->GetIndex(0);
6033 Int_t index1 = kinkl->GetIndex(1);
6034 AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
6035 AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
6037 Int_t sumn=ktrack0->GetNumberOfClusters()+ktrack1->GetNumberOfClusters();
6039 // Refit Kink under if too small angle
6041 if (kinkl->GetAngle(2)<0.05){
6042 kinkl->SetTPCRow0(GetRowNumber(kinkl->GetR()));
6043 Int_t row0 = kinkl->GetTPCRow0();
6044 Int_t drow = Int_t(2.+0.5/(0.05+kinkl->GetAngle(2)));
6047 Int_t last = row0-drow;
6048 if (last<40) last=40;
6049 if (last<ktrack0->GetFirstPoint()+25) last = ktrack0->GetFirstPoint()+25;
6050 AliTPCseed* seed0 = ReSeed(ktrack0,last,kFALSE);
6053 Int_t first = row0+drow;
6054 if (first>130) first=130;
6055 if (first>ktrack1->GetLastPoint()-25) first = TMath::Max(ktrack1->GetLastPoint()-25,30);
6056 AliTPCseed* seed1 = ReSeed(ktrack1,first,kTRUE);
6058 if (seed0 && seed1){
6059 kinkl->SetStatus(1,8);
6060 if (RefitKink(*seed0,*seed1,*kinkl)) kinkl->SetStatus(1,9);
6061 row0 = GetRowNumber(kinkl->GetR());
6062 sumn = seed0->GetNumberOfClusters()+seed1->GetNumberOfClusters();
6063 mothers[i] = new ( NextFreeSeed() ) AliTPCseed(*seed0);
6064 mothers[i]->SetPoolID(fLastSeedID);
6065 daughters[i] = new (NextFreeSeed() ) AliTPCseed(*seed1);
6066 daughters[i]->SetPoolID(fLastSeedID);
6069 delete kinks->RemoveAt(i);
6070 if (seed0) MarkSeedFree( seed0 );
6071 if (seed1) MarkSeedFree( seed1 );
6074 if (kinkl->GetDistance()>0.5 || kinkl->GetR()<110 || kinkl->GetR()>240) {
6075 delete kinks->RemoveAt(i);
6076 if (seed0) MarkSeedFree( seed0 );
6077 if (seed1) MarkSeedFree( seed1 );
6081 MarkSeedFree( seed0 );
6082 MarkSeedFree( seed1 );
6085 if (kinkl) quality[i] = 160*((0.1+kinkl->GetDistance())*(2.-kinkl->GetTPCDensityFactor()))/(sumn+40.); //the longest -clossest will win
6087 TMath::Sort(nkinks,quality,indexes,kFALSE);
6089 //remove double find kinks
6091 for (Int_t ikink0=1;ikink0<nkinks;ikink0++){
6092 AliKink * kink0 = (AliKink*) kinks->At(indexes[ikink0]);
6093 if (!kink0) continue;
6095 for (Int_t ikink1=0;ikink1<ikink0;ikink1++){
6096 kink0 = (AliKink*) kinks->At(indexes[ikink0]);
6097 if (!kink0) continue;
6098 AliKink * kink1 = (AliKink*) kinks->At(indexes[ikink1]);
6099 if (!kink1) continue;
6100 // if not close kink continue
6101 if (TMath::Abs(kink1->GetPosition()[2]-kink0->GetPosition()[2])>10) continue;
6102 if (TMath::Abs(kink1->GetPosition()[1]-kink0->GetPosition()[1])>10) continue;
6103 if (TMath::Abs(kink1->GetPosition()[0]-kink0->GetPosition()[0])>10) continue;
6105 AliTPCseed &mother0 = *mothers[indexes[ikink0]];
6106 AliTPCseed &daughter0 = *daughters[indexes[ikink0]];
6107 AliTPCseed &mother1 = *mothers[indexes[ikink1]];
6108 AliTPCseed &daughter1 = *daughters[indexes[ikink1]];
6109 Int_t row0 = (kink0->GetTPCRow0()+kink1->GetTPCRow0())/2;
6118 for (Int_t i=0;i<row0;i++){
6119 if (mother0.GetClusterIndex(i)>0 && mother1.GetClusterIndex(i)>0){
6122 if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
6129 for (Int_t i=row0;i<158;i++){
6130 //if (daughter0.GetClusterIndex(i)>0 && daughter0.GetClusterIndex(i)>0){ // RS: Bug?
6131 if (daughter0.GetClusterIndex(i)>0 && daughter1.GetClusterIndex(i)>0){
6134 if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
6140 Float_t ratio = Float_t(same+1)/Float_t(both+1);
6141 Float_t ratiom = Float_t(samem+1)/Float_t(bothm+1);
6142 Float_t ratiod = Float_t(samed+1)/Float_t(bothd+1);
6143 if (ratio>0.3 && ratiom>0.5 &&ratiod>0.5) {
6144 Int_t sum0 = mother0.GetNumberOfClusters()+daughter0.GetNumberOfClusters();
6145 Int_t sum1 = mother1.GetNumberOfClusters()+daughter1.GetNumberOfClusters();
6147 shared[kink0->GetIndex(0)]= kTRUE;
6148 shared[kink0->GetIndex(1)]= kTRUE;
6149 delete kinks->RemoveAt(indexes[ikink0]);
6153 shared[kink1->GetIndex(0)]= kTRUE;
6154 shared[kink1->GetIndex(1)]= kTRUE;
6155 delete kinks->RemoveAt(indexes[ikink1]);
6162 for (Int_t i=0;i<nkinks;i++){
6163 AliKink * kinkl = (AliKink*) kinks->At(indexes[i]);
6164 if (!kinkl) continue;
6165 kinkl->SetTPCRow0(GetRowNumber(kinkl->GetR()));
6166 Int_t index0 = kinkl->GetIndex(0);
6167 Int_t index1 = kinkl->GetIndex(1);
6168 if (circular[index0]||(circular[index1]&&kinkl->GetDistance()>0.2)) continue;
6169 kinkl->SetMultiple(usage[index0],0);
6170 kinkl->SetMultiple(usage[index1],1);
6171 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>2) continue;
6172 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>0 && quality[indexes[i]]>0.2) continue;
6173 if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>0 && kinkl->GetDistance()>0.2) continue;
6174 if (circular[index0]||(circular[index1]&&kinkl->GetDistance()>0.1)) continue;
6176 AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
6177 AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
6178 if (!ktrack0 || !ktrack1) continue;
6179 Int_t index = esd->AddKink(kinkl);
6182 if ( ktrack0->GetKinkIndex(0)==0 && ktrack1->GetKinkIndex(0)==0) { //best kink
6183 if (mothers[indexes[i]]->GetNumberOfClusters()>20 && daughters[indexes[i]]->GetNumberOfClusters()>20 &&
6184 (mothers[indexes[i]]->GetNumberOfClusters()+daughters[indexes[i]]->GetNumberOfClusters())>100){
6185 *ktrack0 = *mothers[indexes[i]];
6186 *ktrack1 = *daughters[indexes[i]];
6190 ktrack0->SetKinkIndex(usage[index0],-(index+1));
6191 ktrack1->SetKinkIndex(usage[index1], (index+1));
6196 // Remove tracks corresponding to shared kink's
6198 for (Int_t i=0;i<nentries;i++){
6199 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
6200 if (!track0) continue;
6201 if (track0->GetKinkIndex(0)!=0) continue;
6202 if (shared[i]) MarkSeedFree( array->RemoveAt(i) );
6207 RemoveUsed2(array,0.5,0.4,30);
6209 for (Int_t i=0;i<nentries;i++){
6210 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
6211 if (!track0) continue;
6212 track0->CookdEdx(0.02,0.6);
6216 for (Int_t i=0;i<nentries;i++){
6217 AliTPCseed * track0 = (AliTPCseed*)array->At(i);
6218 if (!track0) continue;
6219 if (track0->Pt()<1.4) continue;
6220 //remove double high momenta tracks - overlapped with kink candidates
6223 for (Int_t icl=track0->GetFirstPoint();icl<track0->GetLastPoint(); icl++){
6224 if (track0->GetClusterPointer(icl)!=0){
6226 if (track0->GetClusterPointer(icl)->IsUsed(10)) ishared++;
6229 if (Float_t(ishared+1)/Float_t(all+1)>0.5) {
6230 MarkSeedFree( array->RemoveAt(i) );
6234 if (track0->GetKinkIndex(0)!=0) continue;
6235 if (track0->GetNumberOfClusters()<80) continue;
6237 AliTPCseed *pmother = new( NextFreeSeed() ) AliTPCseed();
6238 pmother->SetPoolID(fLastSeedID);
6239 AliTPCseed *pdaughter = new( NextFreeSeed() ) AliTPCseed();
6240 pdaughter->SetPoolID(fLastSeedID);
6241 AliKink *pkink = new AliKink;
6243 AliTPCseed & mother = *pmother;
6244 AliTPCseed & daughter = *pdaughter;
6245 AliKink & kinkl = *pkink;
6246 if (CheckKinkPoint(track0,mother,daughter, kinkl)){
6247 if (mother.GetNumberOfClusters()<30||daughter.GetNumberOfClusters()<20) {
6248 MarkSeedFree( pmother );
6249 MarkSeedFree( pdaughter );
6251 continue; //too short tracks
6253 if (mother.Pt()<1.4) {
6254 MarkSeedFree( pmother );
6255 MarkSeedFree( pdaughter );
6259 Int_t row0= kinkl.GetTPCRow0();
6260 if (kinkl.GetDistance()>0.5 || kinkl.GetR()<110. || kinkl.GetR()>240.) {
6261 MarkSeedFree( pmother );
6262 MarkSeedFree( pdaughter );
6267 Int_t index = esd->AddKink(&kinkl);
6268 mother.SetKinkIndex(0,-(index+1));
6269 daughter.SetKinkIndex(0,index+1);
6270 if (mother.GetNumberOfClusters()>50) {
6271 MarkSeedFree( array->RemoveAt(i) );
6272 AliTPCseed* mtc = new( NextFreeSeed() ) AliTPCseed(mother);
6273 mtc->SetPoolID(fLastSeedID);
6274 array->AddAt(mtc,i);
6277 AliTPCseed* mtc = new( NextFreeSeed() ) AliTPCseed(mother);
6278 mtc->SetPoolID(fLastSeedID);
6279 array->AddLast(mtc);
6281 AliTPCseed* dtc = new( NextFreeSeed() ) AliTPCseed(daughter);
6282 dtc->SetPoolID(fLastSeedID);
6283 array->AddLast(dtc);
6284 for (Int_t icl=0;icl<row0;icl++) {
6285 if (mother.GetClusterPointer(icl)) mother.GetClusterPointer(icl)->Use(20);
6288 for (Int_t icl=row0;icl<158;icl++) {
6289 if (daughter.GetClusterPointer(icl)) daughter.GetClusterPointer(icl)->Use(20);
6293 MarkSeedFree( pmother );
6294 MarkSeedFree( pdaughter );
6298 delete [] daughters;
6320 AliInfo(Form("Ncandidates=\t%d\t%d\t%d\t%d\n",esd->GetNumberOfKinks(),ncandidates,ntracks,nall));
6325 Int_t AliTPCtrackerMI::RefitKink(AliTPCseed &mother, AliTPCseed &daughter, const AliESDkink &knk)
6328 // refit kink towards to the vertex
6331 AliKink &kink=(AliKink &)knk;
6333 Int_t row0 = GetRowNumber(kink.GetR());
6334 FollowProlongation(mother,0);
6335 mother.Reset(kFALSE);
6337 FollowProlongation(daughter,row0);
6338 daughter.Reset(kFALSE);
6339 FollowBackProlongation(daughter,158);
6340 daughter.Reset(kFALSE);
6341 Int_t first = TMath::Max(row0-20,30);
6342 Int_t last = TMath::Min(row0+20,140);
6344 const Int_t kNdiv =5;
6345 AliTPCseed param0[kNdiv]; // parameters along the track
6346 AliTPCseed param1[kNdiv]; // parameters along the track
6347 AliKink kinks[kNdiv]; // corresponding kink parameters
6350 for (Int_t irow=0; irow<kNdiv;irow++){
6351 rows[irow] = first +((last-first)*irow)/(kNdiv-1);
6353 // store parameters along the track
6355 for (Int_t irow=0;irow<kNdiv;irow++){
6356 FollowBackProlongation(mother, rows[irow]);
6357 FollowProlongation(daughter,rows[kNdiv-1-irow]);
6358 param0[irow] = mother;
6359 param1[kNdiv-1-irow] = daughter;
6363 for (Int_t irow=0; irow<kNdiv-1;irow++){
6364 if (param0[irow].GetNumberOfClusters()<kNdiv||param1[irow].GetNumberOfClusters()<kNdiv) continue;
6365 kinks[irow].SetMother(param0[irow]);
6366 kinks[irow].SetDaughter(param1[irow]);
6367 kinks[irow].Update();
6370 // choose kink with best "quality"
6372 Double_t mindist = 10000;
6373 for (Int_t irow=0;irow<kNdiv;irow++){
6374 if (param0[irow].GetNumberOfClusters()<20||param1[irow].GetNumberOfClusters()<20) continue;
6375 if (TMath::Abs(kinks[irow].GetR())>240.) continue;
6376 if (TMath::Abs(kinks[irow].GetR())<100.) continue;
6378 Float_t normdist = TMath::Abs(param0[irow].GetX()-kinks[irow].GetR())*(0.1+kink.GetDistance());
6379 normdist/= (param0[irow].GetNumberOfClusters()+param1[irow].GetNumberOfClusters()+40.);
6380 if (normdist < mindist){
6386 if (index==-1) return 0;
6389 param0[index].Reset(kTRUE);
6390 FollowProlongation(param0[index],0);
6392 mother = param0[index];
6393 daughter = param1[index]; // daughter in vertex
6395 kink.SetMother(mother);
6396 kink.SetDaughter(daughter);
6398 kink.SetTPCRow0(GetRowNumber(kink.GetR()));
6399 kink.SetTPCncls(param0[index].GetNumberOfClusters(),0);
6400 kink.SetTPCncls(param1[index].GetNumberOfClusters(),1);
6401 kink.SetLabel(CookLabel(&mother,0.4, 0,kink.GetTPCRow0()),0);
6402 kink.SetLabel(CookLabel(&daughter,0.4, kink.GetTPCRow0(),160),1);
6403 mother.SetLabel(kink.GetLabel(0));
6404 daughter.SetLabel(kink.GetLabel(1));
6410 void AliTPCtrackerMI::UpdateKinkQualityM(AliTPCseed * seed){
6412 // update Kink quality information for mother after back propagation
6414 if (seed->GetKinkIndex(0)>=0) return;
6415 for (Int_t ikink=0;ikink<3;ikink++){
6416 Int_t index = seed->GetKinkIndex(ikink);
6417 if (index>=0) break;
6418 index = TMath::Abs(index)-1;
6419 AliESDkink * kink = fEvent->GetKink(index);
6420 kink->SetTPCDensity(-1,0,0);
6421 kink->SetTPCDensity(1,0,1);
6423 Int_t row0 = kink->GetTPCRow0() - 2 - Int_t( 0.5/ (0.05+kink->GetAngle(2)));
6424 if (row0<15) row0=15;
6426 Int_t row1 = kink->GetTPCRow0() + 2 + Int_t( 0.5/ (0.05+kink->GetAngle(2)));
6427 if (row1>145) row1=145;
6429 Int_t found,foundable,shared;
6430 seed->GetClusterStatistic(0,row0, found, foundable,shared,kFALSE);
6431 if (foundable>5) kink->SetTPCDensity(Float_t(found)/Float_t(foundable),0,0);
6432 seed->GetClusterStatistic(row1,155, found, foundable,shared,kFALSE);
6433 if (foundable>5) kink->SetTPCDensity(Float_t(found)/Float_t(foundable),0,1);
6438 void AliTPCtrackerMI::UpdateKinkQualityD(AliTPCseed * seed){
6440 // update Kink quality information for daughter after refit
6442 if (seed->GetKinkIndex(0)<=0) return;
6443 for (Int_t ikink=0;ikink<3;ikink++){
6444 Int_t index = seed->GetKinkIndex(ikink);
6445 if (index<=0) break;
6446 index = TMath::Abs(index)-1;
6447 AliESDkink * kink = fEvent->GetKink(index);
6448 kink->SetTPCDensity(-1,1,0);
6449 kink->SetTPCDensity(-1,1,1);
6451 Int_t row0 = kink->GetTPCRow0() -2 - Int_t( 0.5/ (0.05+kink->GetAngle(2)));
6452 if (row0<15) row0=15;
6454 Int_t row1 = kink->GetTPCRow0() +2 + Int_t( 0.5/ (0.05+kink->GetAngle(2)));
6455 if (row1>145) row1=145;
6457 Int_t found,foundable,shared;
6458 seed->GetClusterStatistic(0,row0, found, foundable,shared,kFALSE);
6459 if (foundable>5) kink->SetTPCDensity(Float_t(found)/Float_t(foundable),1,0);
6460 seed->GetClusterStatistic(row1,155, found, foundable,shared,kFALSE);
6461 if (foundable>5) kink->SetTPCDensity(Float_t(found)/Float_t(foundable),1,1);
6467 Int_t AliTPCtrackerMI::CheckKinkPoint(AliTPCseed*seed,AliTPCseed &mother, AliTPCseed &daughter, const AliESDkink &knk)
6470 // check kink point for given track
6471 // if return value=0 kink point not found
6472 // otherwise seed0 correspond to mother particle
6473 // seed1 correspond to daughter particle
6474 // kink parameter of kink point
6475 AliKink &kink=(AliKink &)knk;
6477 Int_t middlerow = (seed->GetFirstPoint()+seed->GetLastPoint())/2;
6478 Int_t first = seed->GetFirstPoint();
6479 Int_t last = seed->GetLastPoint();
6480 if (last-first<20) return 0; // shortest length - 2*30 = 60 pad-rows
6483 AliTPCseed *seed1 = ReSeed(seed,middlerow+20, kTRUE); //middle of chamber
6484 if (!seed1) return 0;
6485 FollowProlongation(*seed1,seed->GetLastPoint()-20);
6486 seed1->Reset(kTRUE);
6487 FollowProlongation(*seed1,158);
6488 seed1->Reset(kTRUE);
6489 last = seed1->GetLastPoint();
6491 AliTPCseed *seed0 = new( NextFreeSeed() ) AliTPCseed(*seed);
6492 seed0->SetPoolID(fLastSeedID);
6493 seed0->Reset(kFALSE);
6496 AliTPCseed param0[20]; // parameters along the track
6497 AliTPCseed param1[20]; // parameters along the track
6498 AliKink kinks[20]; // corresponding kink parameters
6500 for (Int_t irow=0; irow<20;irow++){
6501 rows[irow] = first +((last-first)*irow)/19;
6503 // store parameters along the track
6505 for (Int_t irow=0;irow<20;irow++){
6506 FollowBackProlongation(*seed0, rows[irow]);
6507 FollowProlongation(*seed1,rows[19-irow]);
6508 param0[irow] = *seed0;
6509 param1[19-irow] = *seed1;
6513 for (Int_t irow=0; irow<19;irow++){
6514 kinks[irow].SetMother(param0[irow]);
6515 kinks[irow].SetDaughter(param1[irow]);
6516 kinks[irow].Update();
6519 // choose kink with biggest change of angle
6521 Double_t maxchange= 0;
6522 for (Int_t irow=1;irow<19;irow++){
6523 if (TMath::Abs(kinks[irow].GetR())>240.) continue;
6524 if (TMath::Abs(kinks[irow].GetR())<110.) continue;
6525 Float_t quality = TMath::Abs(kinks[irow].GetAngle(2))/(3.+TMath::Abs(kinks[irow].GetR()-param0[irow].GetX()));
6526 if ( quality > maxchange){
6527 maxchange = quality;
6532 MarkSeedFree( seed0 );
6533 MarkSeedFree( seed1 );
6534 if (index<0) return 0;
6536 Int_t row0 = GetRowNumber(kinks[index].GetR()); //row 0 estimate
6537 seed0 = new( NextFreeSeed() ) AliTPCseed(param0[index]);
6538 seed0->SetPoolID(fLastSeedID);
6539 seed1 = new( NextFreeSeed() ) AliTPCseed(param1[index]);
6540 seed1->SetPoolID(fLastSeedID);
6541 seed0->Reset(kFALSE);
6542 seed1->Reset(kFALSE);
6543 seed0->ResetCovariance(10.);
6544 seed1->ResetCovariance(10.);
6545 FollowProlongation(*seed0,0);
6546 FollowBackProlongation(*seed1,158);
6547 mother = *seed0; // backup mother at position 0
6548 seed0->Reset(kFALSE);
6549 seed1->Reset(kFALSE);
6550 seed0->ResetCovariance(10.);
6551 seed1->ResetCovariance(10.);
6553 first = TMath::Max(row0-20,0);
6554 last = TMath::Min(row0+20,158);
6556 for (Int_t irow=0; irow<20;irow++){
6557 rows[irow] = first +((last-first)*irow)/19;
6559 // store parameters along the track
6561 for (Int_t irow=0;irow<20;irow++){
6562 FollowBackProlongation(*seed0, rows[irow]);
6563 FollowProlongation(*seed1,rows[19-irow]);
6564 param0[irow] = *seed0;
6565 param1[19-irow] = *seed1;
6569 for (Int_t irow=0; irow<19;irow++){
6570 kinks[irow].SetMother(param0[irow]);
6571 kinks[irow].SetDaughter(param1[irow]);
6572 // param0[irow].Dump();
6573 //param1[irow].Dump();
6574 kinks[irow].Update();
6577 // choose kink with biggest change of angle
6580 for (Int_t irow=0;irow<20;irow++){
6581 if (TMath::Abs(kinks[irow].GetR())>250.) continue;
6582 if (TMath::Abs(kinks[irow].GetR())<90.) continue;
6583 Float_t quality = TMath::Abs(kinks[irow].GetAngle(2))/(3.+TMath::Abs(kinks[irow].GetR()-param0[irow].GetX()));
6584 if ( quality > maxchange){
6585 maxchange = quality;
6592 if (index==-1 || param0[index].GetNumberOfClusters()+param1[index].GetNumberOfClusters()<100){
6593 MarkSeedFree( seed0 );
6594 MarkSeedFree( seed1 );
6598 // Float_t anglesigma = TMath::Sqrt(param0[index].fC22+param0[index].fC33+param1[index].fC22+param1[index].fC33);
6600 kink.SetMother(param0[index]);
6601 kink.SetDaughter(param1[index]);
6604 Double_t chi2P2 = param0[index].GetParameter()[2]-param1[index].GetParameter()[2];
6606 chi2P2/=param0[index].GetCovariance()[5]+param1[index].GetCovariance()[5];
6607 Double_t chi2P3 = param0[index].GetParameter()[3]-param1[index].GetParameter()[3];
6609 chi2P3/=param0[index].GetCovariance()[9]+param1[index].GetCovariance()[9];
6611 if (AliTPCReconstructor::StreamLevel()>1) {
6612 (*fDebugStreamer)<<"kinkHpt"<<
6615 "p0.="<<¶m0[index]<<
6616 "p1.="<<¶m1[index]<<
6620 if ( chi2P2+chi2P3<AliTPCReconstructor::GetRecoParam()->GetKinkAngleCutChi2(0)){
6621 MarkSeedFree( seed0 );
6622 MarkSeedFree( seed1 );
6627 row0 = GetRowNumber(kink.GetR());
6628 kink.SetTPCRow0(row0);
6629 kink.SetLabel(CookLabel(seed0,0.5,0,row0),0);
6630 kink.SetLabel(CookLabel(seed1,0.5,row0,158),1);
6631 kink.SetIndex(-10,0);
6632 kink.SetIndex(int(param0[index].GetNumberOfClusters()+param1[index].GetNumberOfClusters()),1);
6633 kink.SetTPCncls(param0[index].GetNumberOfClusters(),0);
6634 kink.SetTPCncls(param1[index].GetNumberOfClusters(),1);
6637 // new (&mother) AliTPCseed(param0[index]);
6638 daughter = param1[index];
6639 daughter.SetLabel(kink.GetLabel(1));
6640 param0[index].Reset(kTRUE);
6641 FollowProlongation(param0[index],0);
6642 mother = param0[index];
6643 mother.SetLabel(kink.GetLabel(0));
6644 if ( chi2P2+chi2P3<AliTPCReconstructor::GetRecoParam()->GetKinkAngleCutChi2(1)){
6647 MarkSeedFree( seed0 );
6648 MarkSeedFree( seed1 );
6656 AliTPCseed* AliTPCtrackerMI::ReSeed(AliTPCseed *t)
6659 // reseed - refit - track
6662 // Int_t last = fSectors->GetNRows()-1;
6664 if (fSectors == fOuterSec){
6665 first = TMath::Max(first, t->GetFirstPoint()-fInnerSec->GetNRows());
6669 first = t->GetFirstPoint();
6671 AliTPCseed * seed = MakeSeed(t,0.1,0.5,0.9);
6672 FollowBackProlongation(*t,fSectors->GetNRows()-1);
6674 FollowProlongation(*t,first);
6684 //_____________________________________________________________________________
6685 Int_t AliTPCtrackerMI::ReadSeeds(const TFile *inp) {
6686 //-----------------------------------------------------------------
6687 // This function reades track seeds.
6688 //-----------------------------------------------------------------
6689 TDirectory *savedir=gDirectory;
6691 TFile *in=(TFile*)inp;
6692 if (!in->IsOpen()) {
6693 cerr<<"AliTPCtrackerMI::ReadSeeds(): input file is not open !\n";
6698 TTree *seedTree=(TTree*)in->Get("Seeds");
6700 cerr<<"AliTPCtrackerMI::ReadSeeds(): ";
6701 cerr<<"can't get a tree with track seeds !\n";
6704 AliTPCtrack *seed=new AliTPCtrack;
6705 seedTree->SetBranchAddress("tracks",&seed);
6707 if (fSeeds==0) fSeeds=new TObjArray(15000);
6709 Int_t n=(Int_t)seedTree->GetEntries();
6710 for (Int_t i=0; i<n; i++) {
6711 seedTree->GetEvent(i);
6712 AliTPCseed* sdc = new( NextFreeSeed() ) AliTPCseed(*seed/*,seed->GetAlpha()*/);
6713 sdc->SetPoolID(fLastSeedID);
6714 fSeeds->AddLast(sdc);
6717 delete seed; // RS: this seed is not from the pool, delete it !!!
6723 Int_t AliTPCtrackerMI::Clusters2TracksHLT (AliESDEvent *const esd, const AliESDEvent *hltEvent)
6726 // clusters to tracks
6727 if (fSeeds) DeleteSeeds();
6728 else ResetSeedsPool();
6730 fEventHLT = hltEvent;
6732 AliTPCTransform *transform = AliTPCcalibDB::Instance()->GetTransform() ;
6733 transform->SetCurrentTimeStamp( esd->GetTimeStamp());
6734 transform->SetCurrentRun(esd->GetRunNumber());
6738 if (!fSeeds) return 1;
6740 if (AliTPCReconstructor::StreamLevel()>3) DumpClusters(0,fSeeds);
6745 Int_t AliTPCtrackerMI::Clusters2Tracks(AliESDEvent *const esd)
6748 // clusters to tracks
6749 return Clusters2TracksHLT( esd, 0);
6752 //_____________________________________________________________________________
6753 Int_t AliTPCtrackerMI::Clusters2Tracks() {
6754 //-----------------------------------------------------------------
6755 // This is a track finder.
6756 //-----------------------------------------------------------------
6757 TDirectory *savedir=gDirectory;
6761 fSeeds = Tracking();
6764 Info("Clusters2Tracks","Time for tracking: \t");timer.Print();timer.Start();
6766 //activate again some tracks
6767 for (Int_t i=0; i<fSeeds->GetEntriesFast(); i++) {
6768 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
6770 Int_t nc=t.GetNumberOfClusters();
6772 MarkSeedFree( fSeeds->RemoveAt(i) );
6776 if (pt->GetRemoval()==10) {
6777 if (pt->GetDensityFirst(20)>0.8 || pt->GetDensityFirst(30)>0.8 || pt->GetDensityFirst(40)>0.7)
6778 pt->Desactivate(10); // make track again active // MvL: should be 0 ?
6780 pt->Desactivate(20);
6781 MarkSeedFree( fSeeds->RemoveAt(i) );
6786 RemoveUsed2(fSeeds,0.85,0.85,0);
6787 if (AliTPCReconstructor::GetRecoParam()->GetDoKinks()) FindKinks(fSeeds,fEvent);
6788 //FindCurling(fSeeds, fEvent,0);
6789 if (AliTPCReconstructor::StreamLevel()>5) FindMultiMC(fSeeds, fEvent,-1); // find multi found tracks
6790 RemoveUsed2(fSeeds,0.5,0.4,20);
6791 FindSplitted(fSeeds, fEvent,0); // find multi found tracks
6792 if (AliTPCReconstructor::StreamLevel()>5) FindMultiMC(fSeeds, fEvent,0); // find multi found tracks
6795 // // refit short tracks
6797 Int_t nseed=fSeeds->GetEntriesFast();
6800 for (Int_t i=0; i<nseed; i++) {
6801 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
6803 Int_t nc=t.GetNumberOfClusters();
6805 MarkSeedFree( fSeeds->RemoveAt(i) );
6808 CookLabel(pt,0.1); //For comparison only
6809 //if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
6810 if ((pt->IsActive() || (pt->GetRemoval()==10) )){
6812 if (fDebug>0) cerr<<found<<'\r';
6816 MarkSeedFree( fSeeds->RemoveAt(i) );
6820 //RemoveOverlap(fSeeds,0.99,7,kTRUE);
6822 //RemoveUsed(fSeeds,0.9,0.9,6);
6824 nseed=fSeeds->GetEntriesFast();
6826 for (Int_t i=0; i<nseed; i++) {
6827 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
6829 Int_t nc=t.GetNumberOfClusters();
6831 MarkSeedFree( fSeeds->RemoveAt(i) );
6835 t.CookdEdx(0.02,0.6);
6836 // CheckKinkPoint(&t,0.05);
6837 //if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
6838 if ((pt->IsActive() || (pt->GetRemoval()==10) )){
6846 MarkSeedFree( fSeeds->RemoveAt(i) );
6847 //AliTPCseed * seed1 = ReSeed(pt,0.05,0.5,1);
6849 // FollowProlongation(*seed1,0);
6850 // Int_t n = seed1->GetNumberOfClusters();
6851 // printf("fP4\t%f\t%f\n",seed1->GetC(),pt->GetC());
6852 // printf("fN\t%d\t%d\n", seed1->GetNumberOfClusters(),pt->GetNumberOfClusters());
6855 //AliTPCseed * seed2 = ReSeed(pt,0.95,0.5,0.05);
6859 SortTracks(fSeeds, 1);
6863 PrepareForBackProlongation(fSeeds,5.);
6864 PropagateBack(fSeeds);
6865 printf("Time for back propagation: \t");timer.Print();timer.Start();
6869 PrepareForProlongation(fSeeds,5.);
6870 PropagateForard2(fSeeds);
6872 printf("Time for FORWARD propagation: \t");timer.Print();timer.Start();
6873 // RemoveUsed(fSeeds,0.7,0.7,6);
6874 //RemoveOverlap(fSeeds,0.9,7,kTRUE);
6876 nseed=fSeeds->GetEntriesFast();
6878 for (Int_t i=0; i<nseed; i++) {
6879 AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;
6881 Int_t nc=t.GetNumberOfClusters();
6883 MarkSeedFree( fSeeds->RemoveAt(i) );
6886 t.CookdEdx(0.02,0.6);
6887 // CookLabel(pt,0.1); //For comparison only
6888 //if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
6889 if ((pt->IsActive() || (pt->fRemoval==10) )){
6890 cerr<<found++<<'\r';
6893 MarkSeedFree( fSeeds->RemoveAt(i) );
6898 // fNTracks = found;
6900 Info("Clusters2Tracks","Time for overlap removal, track writing and dedx cooking: \t"); timer.Print();timer.Start();
6903 // cerr<<"Number of found tracks : "<<"\t"<<found<<endl;
6904 Info("Clusters2Tracks","Number of found tracks %d",found);
6906 // UnloadClusters();
6911 void AliTPCtrackerMI::Tracking(TObjArray * arr)
6914 // tracking of the seeds
6917 fSectors = fOuterSec;
6918 ParallelTracking(arr,150,63);
6919 fSectors = fOuterSec;
6920 ParallelTracking(arr,63,0);
6923 TObjArray * AliTPCtrackerMI::Tracking(Int_t seedtype, Int_t i1, Int_t i2, Float_t cuts[4], Float_t dy, Int_t dsec)
6928 static TObjArray arrTracks;
6929 TObjArray * arr = &arrTracks;
6931 fSectors = fOuterSec;
6934 for (Int_t sec=0;sec<fkNOS;sec++){
6935 if (seedtype==3) MakeSeeds3(arr,sec,i1,i2,cuts,dy, dsec);
6936 if (seedtype==4) MakeSeeds5(arr,sec,i1,i2,cuts,dy);
6937 if (seedtype==2) MakeSeeds2(arr,sec,i1,i2,cuts,dy);
6940 Info("Tracking","\nSeeding - %d\t%d\t%d\t%d\n",seedtype,i1,i2,arr->GetEntriesFast());
6952 TObjArray * AliTPCtrackerMI::Tracking()
6956 if (AliTPCReconstructor::GetRecoParam()->GetSpecialSeeding()) return TrackingSpecial();
6959 Int_t nup=fOuterSec->GetNRows()+fInnerSec->GetNRows();
6961 TObjArray * seeds = new TObjArray;
6963 Int_t fLastSeedRowSec=AliTPCReconstructor::GetRecoParam()->GetLastSeedRowSec();
6964 Int_t gapPrim = AliTPCReconstructor::GetRecoParam()->GetSeedGapPrim();
6965 Int_t gapSec = AliTPCReconstructor::GetRecoParam()->GetSeedGapSec();
6973 Float_t fnumber = 3.0;
6974 Float_t fdensity = 3.0;
6977 if (AliTPCReconstructor::GetRecoParam()->GetUseHLTPreSeeding()) {
6978 arr = MakeSeedsHLT( fEventHLT );
6980 SumTracks(seeds,arr);
6983 //cout<<"HLT tracks left after sorting: "<<seeds->GetEntriesFast()<<endl;
6984 //SignClusters(seeds,fnumber,fdensity);
6991 for (Int_t delta = 0; delta<18; delta+=gapPrim){
6995 arr = Tracking(3,nup-1-delta,nup-1-delta-gap,cuts,-1,1);
6996 SumTracks(seeds,arr);
6997 SignClusters(seeds,fnumber,fdensity);
6999 for (Int_t i=2;i<6;i+=2){
7000 // seed high pt tracks
7003 arr = Tracking(3,nup-i-delta,nup-i-delta-gap,cuts,-1,0);
7004 SumTracks(seeds,arr);
7005 SignClusters(seeds,fnumber,fdensity);
7010 // RemoveUsed(seeds,0.9,0.9,1);
7011 // UnsignClusters();
7012 // SignClusters(seeds,fnumber,fdensity);
7016 for (Int_t delta = 20; delta<120; delta+=gapPrim){
7018 // seed high pt tracks
7022 arr = Tracking(3,nup-delta,nup-delta-gap,cuts,-1);
7023 SumTracks(seeds,arr);
7024 SignClusters(seeds,fnumber,fdensity);
7029 arr = Tracking(3,nup-delta-5,nup-delta-5-gap,cuts,-1);
7030 SumTracks(seeds,arr);
7031 SignClusters(seeds,fnumber,fdensity);
7042 Info("Tracking()","\n\nPrimary seeding\t%d\n\n",seeds->GetEntriesFast());
7046 // RemoveUsed(seeds,0.75,0.75,1);
7048 //SignClusters(seeds,fnumber,fdensity);
7057 arr = Tracking(4,nup-1,nup-1-gap,cuts,-1);
7058 SumTracks(seeds,arr);
7059 SignClusters(seeds,fnumber,fdensity);
7061 arr = Tracking(4,nup-2,nup-2-gap,cuts,-1);
7062 SumTracks(seeds,arr);
7063 SignClusters(seeds,fnumber,fdensity);
7065 arr = Tracking(4,nup-3,nup-3-gap,cuts,-1);
7066 SumTracks(seeds,arr);
7067 SignClusters(seeds,fnumber,fdensity);
7069 arr = Tracking(4,nup-5,nup-5-gap,cuts,-1);
7070 SumTracks(seeds,arr);
7071 SignClusters(seeds,fnumber,fdensity);
7073 arr = Tracking(4,nup-7,nup-7-gap,cuts,-1);
7074 SumTracks(seeds,arr);
7075 SignClusters(seeds,fnumber,fdensity);
7078 arr = Tracking(4,nup-9,nup-9-gap,cuts,-1);
7079 SumTracks(seeds,arr);
7080 SignClusters(seeds,fnumber,fdensity);
7084 for (Int_t delta = 9; delta<30; delta+=gapSec){
7090 arr = Tracking(4,nup-1-delta,nup-1-delta-gap,cuts,-1);
7091 SumTracks(seeds,arr);
7092 SignClusters(seeds,fnumber,fdensity);
7094 arr = Tracking(4,nup-3-delta,nup-5-delta-gap,cuts,4);
7095 SumTracks(seeds,arr);
7096 SignClusters(seeds,fnumber,fdensity);
7109 for (Int_t delta = 30; delta<fLastSeedRowSec; delta+=gapSec){
7115 arr = Tracking(4,nup-1-delta,nup-1-delta-gap,cuts,-1);
7116 SumTracks(seeds,arr);
7117 SignClusters(seeds,fnumber,fdensity);
7119 arr = Tracking(4,nup-5-delta,nup-5-delta-gap,cuts,5 );
7120 SumTracks(seeds,arr);
7121 SignClusters(seeds,fnumber,fdensity);
7125 Info("Tracking()","\n\nSecondary seeding\t%d\n\n",seeds->GetEntriesFast());
7136 TObjArray * AliTPCtrackerMI::TrackingSpecial()
7139 // seeding adjusted for laser and cosmic tests - short tracks with big inclination angle
7140 // no primary vertex seeding tried
7144 Int_t nup=fOuterSec->GetNRows()+fInnerSec->GetNRows();
7146 TObjArray * seeds = new TObjArray;
7151 Float_t fnumber = 3.0;
7152 Float_t fdensity = 3.0;
7155 cuts[0] = AliTPCReconstructor::GetRecoParam()->GetMaxC(); // max curvature
7156 cuts[1] = 3.5; // max tan(phi) angle for seeding
7157 cuts[2] = 3.; // not used (cut on z primary vertex)
7158 cuts[3] = 3.5; // max tan(theta) angle for seeding
7160 for (Int_t delta = 0; nup-delta-gap-1>0; delta+=3){
7162 arr = Tracking(4,nup-1-delta,nup-1-delta-gap,cuts,-1);
7163 SumTracks(seeds,arr);
7164 SignClusters(seeds,fnumber,fdensity);
7168 Info("Tracking()","\n\nSecondary seeding\t%d\n\n",seeds->GetEntriesFast());
7179 void AliTPCtrackerMI::SumTracks(TObjArray *arr1,TObjArray *&arr2)
7182 //sum tracks to common container
7183 //remove suspicious tracks
7184 // RS: Attention: supplied tracks come in the static array, don't delete them
7185 Int_t nseed = arr2->GetEntriesFast();
7186 for (Int_t i=0;i<nseed;i++){
7187 AliTPCseed *pt=(AliTPCseed*)arr2->UncheckedAt(i);
7190 // remove tracks with too big curvature
7192 if (TMath::Abs(pt->GetC())>AliTPCReconstructor::GetRecoParam()->GetMaxC()){
7193 MarkSeedFree( arr2->RemoveAt(i) );
7196 // REMOVE VERY SHORT TRACKS
7197 if (pt->GetNumberOfClusters()<20){
7198 MarkSeedFree( arr2->RemoveAt(i) );
7201 // NORMAL ACTIVE TRACK
7202 if (pt->IsActive()){
7203 arr1->AddLast(arr2->RemoveAt(i));
7206 //remove not usable tracks
7207 if (pt->GetRemoval()!=10){
7208 MarkSeedFree( arr2->RemoveAt(i) );
7212 // ENABLE ONLY ENOUGH GOOD STOPPED TRACKS
7213 if (pt->GetDensityFirst(20)>0.8 || pt->GetDensityFirst(30)>0.8 || pt->GetDensityFirst(40)>0.7)
7214 arr1->AddLast(arr2->RemoveAt(i));
7216 MarkSeedFree( arr2->RemoveAt(i) );
7220 // delete arr2; arr2 = 0; // RS: this is static array, don't delete it
7225 void AliTPCtrackerMI::ParallelTracking(TObjArray *const arr, Int_t rfirst, Int_t rlast)
7228 // try to track in parralel
7230 Int_t nseed=arr->GetEntriesFast();
7231 //prepare seeds for tracking
7232 for (Int_t i=0; i<nseed; i++) {
7233 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i), &t=*pt;
7235 if (!t.IsActive()) continue;
7236 // follow prolongation to the first layer
7237 if ( (fSectors ==fInnerSec) || (t.GetFirstPoint()-fkParam->GetNRowLow()>rfirst+1) )
7238 FollowProlongation(t, rfirst+1);
7243 for (Int_t nr=rfirst; nr>=rlast; nr--){
7244 if (nr<fInnerSec->GetNRows())
7245 fSectors = fInnerSec;
7247 fSectors = fOuterSec;
7248 // make indexes with the cluster tracks for given
7250 // find nearest cluster
7251 for (Int_t i=0; i<nseed; i++) {
7252 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i), &t=*pt;
7254 if (nr==80) pt->UpdateReference();
7255 if (!pt->IsActive()) continue;
7256 // if ( (fSectors ==fOuterSec) && (pt->fFirstPoint-fkParam->GetNRowLow())<nr) continue;
7257 if (pt->GetRelativeSector()>17) {
7260 UpdateClusters(t,nr);
7262 // prolonagate to the nearest cluster - if founded
7263 for (Int_t i=0; i<nseed; i++) {
7264 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
7266 if (!pt->IsActive()) continue;
7267 // if ((fSectors ==fOuterSec) && (pt->fFirstPoint-fkParam->GetNRowLow())<nr) continue;
7268 if (pt->GetRelativeSector()>17) {
7271 FollowToNextCluster(*pt,nr);
7276 void AliTPCtrackerMI::PrepareForBackProlongation(const TObjArray *const arr,Float_t fac) const
7280 // if we use TPC track itself we have to "update" covariance
7282 Int_t nseed= arr->GetEntriesFast();
7283 for (Int_t i=0;i<nseed;i++){
7284 AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
7288 //rotate to current local system at first accepted point
7289 Int_t index = pt->GetClusterIndex2(pt->GetFirstPoint());
7290 Int_t sec = (index&0xff000000)>>24;
7292 Float_t angle1 = fInnerSec->GetAlpha()*sec+fInnerSec->GetAlphaShift();
7293 if (angle1>TMath::Pi())
7294 angle1-=2.*TMath::Pi();
7295 Float_t angle2 = pt->GetAlpha();
7297 if (TMath::Abs(angle1-angle2)>0.001){
7298 if (!pt->Rotate(angle1-angle2)) return;
7299 //angle2 = pt->GetAlpha();
7300 //pt->fRelativeSector = pt->GetAlpha()/fInnerSec->GetAlpha();
7301 //if (pt->GetAlpha()<0)
7302 // pt->fRelativeSector+=18;
7303 //sec = pt->fRelativeSector;
7312 void AliTPCtrackerMI::PrepareForProlongation(TObjArray *const arr, Float_t fac) const
7316 // if we use TPC track itself we have to "update" covariance
7318 Int_t nseed= arr->GetEntriesFast();
7319 for (Int_t i=0;i<nseed;i++){
7320 AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
7323 pt->SetFirstPoint(pt->GetLastPoint());
7331 Int_t AliTPCtrackerMI::PropagateBack(const TObjArray *const arr)
7334 // make back propagation
7336 Int_t nseed= arr->GetEntriesFast();
7337 for (Int_t i=0;i<nseed;i++){
7338 AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
7339 if (pt&& pt->GetKinkIndex(0)<=0) {
7340 //AliTPCseed *pt2 = new AliTPCseed(*pt);
7341 fSectors = fInnerSec;
7342 //FollowBackProlongation(*pt,fInnerSec->GetNRows()-1);
7343 //fSectors = fOuterSec;
7344 FollowBackProlongation(*pt,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1,1);
7345 //if (pt->GetNumberOfClusters()<(pt->fEsd->GetTPCclusters(0)) ){
7346 // Error("PropagateBack","Not prolonged track %d",pt->GetLabel());
7347 // FollowBackProlongation(*pt2,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1);
7350 if (pt&& pt->GetKinkIndex(0)>0) {
7351 AliESDkink * kink = fEvent->GetKink(pt->GetKinkIndex(0)-1);
7352 pt->SetFirstPoint(kink->GetTPCRow0());
7353 fSectors = fInnerSec;
7354 FollowBackProlongation(*pt,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1,1);
7362 Int_t AliTPCtrackerMI::PropagateForward2(const TObjArray *const arr)
7365 // make forward propagation
7367 Int_t nseed= arr->GetEntriesFast();
7369 for (Int_t i=0;i<nseed;i++){
7370 AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
7372 FollowProlongation(*pt,0,1,1);
7381 Int_t AliTPCtrackerMI::PropagateForward()
7384 // propagate track forward
7386 Int_t nseed = fSeeds->GetEntriesFast();
7387 for (Int_t i=0;i<nseed;i++){
7388 AliTPCseed *pt = (AliTPCseed*)fSeeds->UncheckedAt(i);
7390 AliTPCseed &t = *pt;
7391 Double_t alpha=t.GetAlpha() - fSectors->GetAlphaShift();
7392 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
7393 if (alpha < 0. ) alpha += 2.*TMath::Pi();
7394 t.SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
7398 fSectors = fOuterSec;
7399 ParallelTracking(fSeeds,fOuterSec->GetNRows()+fInnerSec->GetNRows()-1,fInnerSec->GetNRows());
7400 fSectors = fInnerSec;
7401 ParallelTracking(fSeeds,fInnerSec->GetNRows()-1,0);
7410 Int_t AliTPCtrackerMI::PropagateBack(AliTPCseed *const pt, Int_t row0, Int_t row1)
7413 // make back propagation, in between row0 and row1
7417 fSectors = fInnerSec;
7420 if (row1<fSectors->GetNRows())
7423 r1 = fSectors->GetNRows()-1;
7425 if (row0<fSectors->GetNRows()&& r1>0 )
7426 FollowBackProlongation(*pt,r1);
7427 if (row1<=fSectors->GetNRows())
7430 r1 = row1 - fSectors->GetNRows();
7431 if (r1<=0) return 0;
7432 if (r1>=fOuterSec->GetNRows()) return 0;
7433 fSectors = fOuterSec;
7434 return FollowBackProlongation(*pt,r1);
7442 void AliTPCtrackerMI::GetShape(AliTPCseed * seed, Int_t row)
7444 // gets cluster shape
7446 AliTPCClusterParam * clparam = AliTPCcalibDB::Instance()->GetClusterParam();
7447 Float_t zdrift = TMath::Abs((fkParam->GetZLength(0)-TMath::Abs(seed->GetZ())));
7448 Int_t type = (seed->GetSector() < fkParam->GetNSector()/2) ? 0: (row>126) ? 1:2;
7449 Double_t angulary = seed->GetSnp();
7451 if (TMath::Abs(angulary)>AliTPCReconstructor::GetMaxSnpTracker()) {
7452 angulary = TMath::Sign(AliTPCReconstructor::GetMaxSnpTracker(),angulary);
7455 angulary = angulary*angulary/((1.-angulary)*(1.+angulary));
7456 Double_t angularz = seed->GetTgl()*seed->GetTgl()*(1.+angulary);
7458 Double_t sigmay = clparam->GetRMS0(0,type,zdrift,TMath::Sqrt(TMath::Abs(angulary)));
7459 Double_t sigmaz = clparam->GetRMS0(1,type,zdrift,TMath::Sqrt(TMath::Abs(angularz)));
7460 seed->SetCurrentSigmaY2(sigmay*sigmay);
7461 seed->SetCurrentSigmaZ2(sigmaz*sigmaz);
7462 // Float_t sd2 = TMath::Abs((fkParam->GetZLength(0)-TMath::Abs(seed->GetZ())))*fkParam->GetDiffL()*fkParam->GetDiffL();
7463 // // Float_t padlength = fkParam->GetPadPitchLength(seed->fSector);
7464 // Float_t padlength = GetPadPitchLength(row);
7466 // Float_t sresy = (seed->GetSector() < fkParam->GetNSector()/2) ? 0.2 :0.3;
7467 // seed->SetCurrentSigmaY2(sd2+padlength*padlength*angulary/12.+sresy*sresy);
7469 // Float_t sresz = fkParam->GetZSigma();
7470 // seed->SetCurrentSigmaZ2(sd2+padlength*padlength*angularz*angularz*(1+angulary)/12.+sresz*sresz);
7472 Float_t wy = GetSigmaY(seed);
7473 Float_t wz = GetSigmaZ(seed);
7476 if (TMath::Abs(wy/seed->fCurrentSigmaY2-1)>0.0001 || TMath::Abs(wz/seed->fCurrentSigmaZ2-1)>0.0001 ){
7477 printf("problem\n");
7484 //__________________________________________________________________________
7485 void AliTPCtrackerMI::CookLabel(AliKalmanTrack *tk, Float_t wrong) const {
7486 //--------------------------------------------------------------------
7487 //This function "cooks" a track label. If label<0, this track is fake.
7488 //--------------------------------------------------------------------
7489 AliTPCseed * t = dynamic_cast<AliTPCseed*>(tk);
7491 printf("%s:%d wrong type \n",(char*)__FILE__,__LINE__);
7495 Int_t noc=t->GetNumberOfClusters();
7497 //printf("\nnot founded prolongation\n\n\n");
7503 AliTPCclusterMI *clusters[160];
7505 for (Int_t i=0;i<160;i++) {
7512 for (i=0; i<160 && current<noc; i++) {
7514 Int_t index=t->GetClusterIndex2(i);
7515 if (index<=0) continue;
7516 if (index&0x8000) continue;
7518 //clusters[current]=GetClusterMI(index);
7519 if (t->GetClusterPointer(i)){
7520 clusters[current]=t->GetClusterPointer(i);
7526 Int_t lab=123456789;
7527 for (i=0; i<noc; i++) {
7528 AliTPCclusterMI *c=clusters[i];
7530 lab=TMath::Abs(c->GetLabel(0));
7532 for (j=0; j<noc; j++) if (lb[j]==lab || mx[j]==0) break;
7538 for (i=0; i<noc; i++) if (mx[i]>max) {max=mx[i]; lab=lb[i];}
7540 for (i=0; i<noc; i++) {
7541 AliTPCclusterMI *c=clusters[i];
7543 if (TMath::Abs(c->GetLabel(1)) == lab ||
7544 TMath::Abs(c->GetLabel(2)) == lab ) max++;
7546 if (noc<=0) { lab=-1; return;}
7547 if ((1.- Float_t(max)/(noc)) > wrong) lab=-lab;
7550 Int_t tail=Int_t(0.10*noc);
7553 for (i=1; i<160&&ind<tail; i++) {
7554 // AliTPCclusterMI *c=clusters[noc-i];
7555 AliTPCclusterMI *c=clusters[i];
7557 if (lab == TMath::Abs(c->GetLabel(0)) ||
7558 lab == TMath::Abs(c->GetLabel(1)) ||
7559 lab == TMath::Abs(c->GetLabel(2))) max++;
7562 if (max < Int_t(0.5*tail)) lab=-lab;
7569 //delete[] clusters;
7573 //__________________________________________________________________________
7574 Int_t AliTPCtrackerMI::CookLabel(AliTPCseed *const t, Float_t wrong,Int_t first, Int_t last) const {
7575 //--------------------------------------------------------------------
7576 //This function "cooks" a track label. If label<0, this track is fake.
7577 //--------------------------------------------------------------------
7578 Int_t noc=t->GetNumberOfClusters();
7580 //printf("\nnot founded prolongation\n\n\n");
7586 AliTPCclusterMI *clusters[160];
7588 for (Int_t i=0;i<160;i++) {
7595 for (i=0; i<160 && current<noc; i++) {
7596 if (i<first) continue;
7597 if (i>last) continue;
7598 Int_t index=t->GetClusterIndex2(i);
7599 if (index<=0) continue;
7600 if (index&0x8000) continue;
7602 //clusters[current]=GetClusterMI(index);
7603 if (t->GetClusterPointer(i)){
7604 clusters[current]=t->GetClusterPointer(i);
7609 //if (noc<5) return -1;
7610 Int_t lab=123456789;
7611 for (i=0; i<noc; i++) {
7612 AliTPCclusterMI *c=clusters[i];
7614 lab=TMath::Abs(c->GetLabel(0));
7616 for (j=0; j<noc; j++) if (lb[j]==lab || mx[j]==0) break;
7622 for (i=0; i<noc; i++) if (mx[i]>max) {max=mx[i]; lab=lb[i];}
7624 for (i=0; i<noc; i++) {
7625 AliTPCclusterMI *c=clusters[i];
7627 if (TMath::Abs(c->GetLabel(1)) == lab ||
7628 TMath::Abs(c->GetLabel(2)) == lab ) max++;
7630 if (noc<=0) { lab=-1; return -1;}
7631 if ((1.- Float_t(max)/(noc)) > wrong) lab=-lab;
7634 Int_t tail=Int_t(0.10*noc);
7637 for (i=1; i<160&&ind<tail; i++) {
7638 // AliTPCclusterMI *c=clusters[noc-i];
7639 AliTPCclusterMI *c=clusters[i];
7641 if (lab == TMath::Abs(c->GetLabel(0)) ||
7642 lab == TMath::Abs(c->GetLabel(1)) ||
7643 lab == TMath::Abs(c->GetLabel(2))) max++;
7646 if (max < Int_t(0.5*tail)) lab=-lab;
7649 // t->SetLabel(lab);
7653 //delete[] clusters;
7657 Int_t AliTPCtrackerMI::GetRowNumber(Double_t x[3]) const
7659 //return pad row number for given x vector
7660 Float_t phi = TMath::ATan2(x[1],x[0]);
7661 if(phi<0) phi=2.*TMath::Pi()+phi;
7662 // Get the local angle in the sector philoc
7663 const Float_t kRaddeg = 180/3.14159265358979312;
7664 Float_t phiangle = (Int_t (phi*kRaddeg/20.) + 0.5)*20./kRaddeg;
7665 Double_t localx = x[0]*TMath::Cos(phiangle)-x[1]*TMath::Sin(phiangle);
7666 return GetRowNumber(localx);
7671 void AliTPCtrackerMI::MakeESDBitmaps(AliTPCseed *t, AliESDtrack *esd)
7673 //-----------------------------------------------------------------------
7674 // Fill the cluster and sharing bitmaps of the track
7675 //-----------------------------------------------------------------------
7677 Int_t firstpoint = 0;
7678 Int_t lastpoint = 159;
7679 AliTPCTrackerPoint *point;
7680 AliTPCclusterMI *cluster;
7683 TBits clusterMap(159);
7684 TBits sharedMap(159);
7686 for (int iter=firstpoint; iter<lastpoint; iter++) {
7687 // Change to cluster pointers to see if we have a cluster at given padrow
7689 cluster = t->GetClusterPointer(iter);
7691 clusterMap.SetBitNumber(iter, kTRUE);
7692 point = t->GetTrackPoint(iter);
7693 if (point->IsShared())
7694 sharedMap.SetBitNumber(iter,kTRUE);
7696 if (t->GetClusterIndex(iter) >= 0 && (t->GetClusterIndex(iter) & 0x8000) == 0) {
7697 fitMap.SetBitNumber(iter, kTRUE);
7701 esd->SetTPCClusterMap(clusterMap);
7702 esd->SetTPCSharedMap(sharedMap);
7703 esd->SetTPCFitMap(fitMap);
7704 if (nclsf != t->GetNumberOfClusters())
7705 AliWarning(Form("Inconsistency between ncls %d and indices %d (found %d)",t->GetNumberOfClusters(),nclsf,esd->GetTPCClusterMap().CountBits()));
7708 Bool_t AliTPCtrackerMI::IsFindable(AliTPCseed & track){
7710 // return flag if there is findable cluster at given position
7713 Float_t z = track.GetZ();
7715 if (TMath::Abs(z)<(AliTPCReconstructor::GetCtgRange()*track.GetX()+kDeltaZ) &&
7716 TMath::Abs(z)<fkParam->GetZLength(0) &&
7717 (TMath::Abs(track.GetSnp())<AliTPCReconstructor::GetMaxSnpTracker()))
7723 void AliTPCtrackerMI::AddCovariance(AliTPCseed * seed){
7725 // Adding systematic error estimate to the covariance matrix
7726 // !!!! the systematic error for element 4 is in 1/GeV
7727 // 03.03.2012 MI changed in respect to the previous versions
7728 const Double_t *param = AliTPCReconstructor::GetRecoParam()->GetSystematicError();
7730 // use only the diagonal part if not specified otherwise
7731 if (!AliTPCReconstructor::GetRecoParam()->GetUseSystematicCorrelation()) return AddCovarianceAdd(seed);
7733 Double_t *covarS= (Double_t*)seed->GetCovariance();
7734 Double_t factor[5]={1,1,1,1,1};
7735 factor[0]= TMath::Sqrt(TMath::Abs((covarS[0] + param[0]*param[0])/covarS[0]));
7736 factor[1]= TMath::Sqrt(TMath::Abs((covarS[2] + param[1]*param[1])/covarS[2]));
7737 factor[2]= TMath::Sqrt(TMath::Abs((covarS[5] + param[2]*param[2])/covarS[5]));
7738 factor[3]= TMath::Sqrt(TMath::Abs((covarS[9] + param[3]*param[3])/covarS[9]));
7739 factor[4]= TMath::Sqrt(TMath::Abs((covarS[14] +param[4]*param[4])/covarS[14]));
7741 factor[0]=factor[2];
7742 factor[4]=factor[2];
7748 for (Int_t i=0; i<5; i++){
7749 for (Int_t j=i; j<5; j++){
7750 Int_t index=seed->GetIndex(i,j);
7751 covarS[index]*=factor[i]*factor[j];
7757 void AliTPCtrackerMI::AddCovarianceAdd(AliTPCseed * seed){
7759 // Adding systematic error - as additive factor without correlation
7761 // !!!! the systematic error for element 4 is in 1/GeV
7762 // 03.03.2012 MI changed in respect to the previous versions
7764 const Double_t *param = AliTPCReconstructor::GetRecoParam()->GetSystematicError();
7765 Double_t *covarIn= (Double_t*)seed->GetCovariance();
7767 for (Int_t i=0;i<15;i++) covar[i]=0;
7773 covar[0] = param[0]*param[0];
7774 covar[2] = param[1]*param[1];
7775 covar[5] = param[2]*param[2];
7776 covar[9] = param[3]*param[3];
7777 covar[14]= param[4]*param[4];
7779 covar[1]=TMath::Sqrt((covar[0]*covar[2]))*covarIn[1]/TMath::Sqrt((covarIn[0]*covarIn[2]));
7781 covar[3]=TMath::Sqrt((covar[0]*covar[5]))*covarIn[3]/TMath::Sqrt((covarIn[0]*covarIn[5]));
7782 covar[4]=TMath::Sqrt((covar[2]*covar[5]))*covarIn[4]/TMath::Sqrt((covarIn[2]*covarIn[5]));
7784 covar[6]=TMath::Sqrt((covar[0]*covar[9]))*covarIn[6]/TMath::Sqrt((covarIn[0]*covarIn[9]));
7785 covar[7]=TMath::Sqrt((covar[2]*covar[9]))*covarIn[7]/TMath::Sqrt((covarIn[2]*covarIn[9]));
7786 covar[8]=TMath::Sqrt((covar[5]*covar[9]))*covarIn[8]/TMath::Sqrt((covarIn[5]*covarIn[9]));
7788 covar[10]=TMath::Sqrt((covar[0]*covar[14]))*covarIn[10]/TMath::Sqrt((covarIn[0]*covarIn[14]));
7789 covar[11]=TMath::Sqrt((covar[2]*covar[14]))*covarIn[11]/TMath::Sqrt((covarIn[2]*covarIn[14]));
7790 covar[12]=TMath::Sqrt((covar[5]*covar[14]))*covarIn[12]/TMath::Sqrt((covarIn[5]*covarIn[14]));
7791 covar[13]=TMath::Sqrt((covar[9]*covar[14]))*covarIn[13]/TMath::Sqrt((covarIn[9]*covarIn[14]));
7793 seed->AddCovariance(covar);
7796 //_____________________________________________________________________________
7797 Bool_t AliTPCtrackerMI::IsTPCHVDipEvent(AliESDEvent const *esdEvent) {
7799 // check events affected by TPC HV dip
7801 if(!esdEvent) return kFALSE;
7804 if(!AliTPCcalibDB::Instance()) return kFALSE;
7805 AliTPCcalibDB::Instance()->SetRun(esdEvent->GetRunNumber());
7807 // Get HV TPC chamber sensors and calculate the median
7808 AliDCSSensorArray *voltageArray= AliTPCcalibDB::Instance()->GetVoltageSensors(esdEvent->GetRunNumber());
7809 if(!voltageArray) return kFALSE;
7811 TString sensorName="";
7812 Double_t kTPCHVdip = 2.0; // allow for 2V dip as compared to median from given sensor
7815 for(Int_t sector=0; sector<72; sector++)
7817 Char_t sideName='A';
7818 if ((sector/18)%2==1) sideName='C';
7821 sensorName=Form("TPC_ANODE_I_%c%02d_VMEAS",sideName,sector%18);
7824 sensorName=Form("TPC_ANODE_O_%c%02d_0_VMEAS",sideName,sector%18);
7827 AliDCSSensor* sensor = voltageArray->GetSensor(sensorName.Data());
7828 if(!sensor) continue;
7829 TGraph *graph = sensor->GetGraph();
7830 if(!graph) continue;
7831 Double_t median = TMath::Median(graph->GetN(), graph->GetY());
7832 if(median == 0) continue;
7834 //printf("chamber %d, sensor %s, HV %f, median %f\n", sector, sensorName.Data(), sensor->GetValue(esdEvent->GetTimeStamp()), median);
7836 if(TMath::Abs(sensor->GetValue(esdEvent->GetTimeStamp())-median)>kTPCHVdip) {
7844 //________________________________________
7845 void AliTPCtrackerMI::MarkSeedFree(TObject *sd)
7847 // account that this seed is "deleted"
7848 AliTPCseed* seed = dynamic_cast<AliTPCseed*>(sd);
7850 AliError(Form("Freeing of non-AliTPCseed %p from the pool is requested",sd));
7853 int id = seed->GetPoolID();
7855 AliError(Form("Freeing of seed %p NOT from the pool is requested",sd));
7858 // AliInfo(Form("%d %p",id, seed));
7859 fSeedsPool->RemoveAt(id);
7860 if (fFreeSeedsID.GetSize()<=fNFreeSeeds) fFreeSeedsID.Set( 2*fNFreeSeeds + 100 );
7861 fFreeSeedsID.GetArray()[fNFreeSeeds++] = id;
7864 //________________________________________
7865 TObject *&AliTPCtrackerMI::NextFreeSeed()
7867 // return next free slot where the seed can be created
7868 fLastSeedID = fNFreeSeeds ? fFreeSeedsID.GetArray()[--fNFreeSeeds] : fSeedsPool->GetEntriesFast();
7869 // AliInfo(Form("%d",fLastSeedID));
7870 return (*fSeedsPool)[ fLastSeedID ];
7874 //________________________________________
7875 void AliTPCtrackerMI::ResetSeedsPool()
7877 // mark all seeds in the pool as unused
7878 AliInfo(Form("CurrentSize: %d, BookedUpTo: %d, free: %d",fSeedsPool->GetSize(),fSeedsPool->GetEntriesFast(),fNFreeSeeds));
7880 fSeedsPool->Clear("C"); // RS: nominally the seeds may allocate memory...
7883 Int_t AliTPCtrackerMI::PropagateToRowHLT(AliTPCseed *pt, int nrow)
7886 Double_t x= GetXrow(nrow);
7887 Double_t ymax= GetMaxY(nrow);
7893 if (!t.PropagateTo(x) ){
7894 //cout<<"can't propagate to row "<<nrow<<", x="<<t.GetX()<<" -> "<<x<<endl;
7900 Double_t y = t.GetY();
7902 if( rotate!=-1 ) rotate=1;
7903 } else if (y <-ymax) {
7904 if( rotate!=1 ) rotate = -1;
7906 if( rotate==0 ) break;
7907 //cout<<"rotate at row "<<nrow<<": "<<rotate<<endl;
7908 if (!t.Rotate( rotate==1 ?fSectors->GetAlpha() :-fSectors->GetAlpha())) {
7909 //cout<<"can't rotate "<<endl;
7913 nRotations+= rotate;
7915 if( nRotations!=0 ){
7916 int newSec= t.GetRelativeSector()+nRotations;
7917 if( newSec>=fN ) newSec-=fN;
7918 else if( newSec<0 ) newSec +=fN;
7919 //cout<<"rotate at row "<<nrow<<": "<<nRotations<<" times "<<" sec "
7920 //<< t.GetRelativeSector()<<" -> "<<newSec<<endl;
7921 t.SetRelativeSector(newSec);
7926 void AliTPCtrackerMI::TrackFollowingHLT(TObjArray *const arr )
7929 // try to track in parralel
7931 Int_t nRows=fOuterSec->GetNRows()+fInnerSec->GetNRows();
7934 Int_t nseed=arr->GetEntriesFast();
7935 //cout<<"Parallel tracking My.."<<endl;
7936 double shapeY2[160], shapeZ2[160];
7937 Int_t clusterIndex[160];
7939 for (Int_t iSeed=0; iSeed<nseed; iSeed++) {
7940 //if( iSeed!=1 ) continue;
7941 AliTPCseed *pt=(AliTPCseed*) (arr->UncheckedAt(iSeed));
7945 //cout <<"Pt "<<t.GetSigned1Pt()<<endl;
7949 for( int iter=0; iter<3; iter++ ){
7952 t.SetLastPoint(0); // first cluster in track position
7953 t.SetFirstPoint(nRows-1);
7954 t.ResetCovariance(.1);
7955 t.SetNumberOfClusters(0);
7956 for( int i=0; i<nRows; i++ ){
7960 t.SetClusterIndex2(i,-1);
7961 t.SetClusterIndex(i,-1);
7964 // pick up the clusters
7966 Double_t roady = 20.;
7967 Double_t roadz = 20.;
7974 t0.SetRelativeSector(t.GetRelativeSector());
7975 t0.SetLastPoint(0); // first cluster in track position
7976 t0.SetFirstPoint(159);
7977 for (Int_t nr=0; nr<nRows; nr++){
7978 if( nr<fInnerSec->GetNRows() ) fSectors=fInnerSec;
7979 else fSectors=fOuterSec;
7981 if( !PropagateToRowHLT(&t0, nr ) ){ break; }
7982 if (TMath::Abs(t0.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()){
7983 //cout<<"Snp is too big: "<<t0.GetSnp()<<endl;
7986 if (!IsActive(t0.GetRelativeSector(),nr)) {
7992 shapeY2[nr]=t0.GetCurrentSigmaY2();
7993 shapeZ2[nr]=t0.GetCurrentSigmaZ2();
7996 AliTPCtrackerRow &krow=GetRow(t0.GetRelativeSector(),nr);
7997 if( !krow ) continue;
7999 t.SetClusterIndex2(nr,-3); // foundable
8000 t.SetClusterIndex(nr,-3);
8002 AliTPCclusterMI *cl=0;
8004 cl = krow.FindNearest2(t0.GetY(),t0.GetZ(),roady,roadz,uindex);
8006 double dy = cl->GetY()-t0.GetY();
8007 double dz = cl->GetZ()-t0.GetZ();
8008 double dr = sqrt(dy*dy+dz*dz);
8010 //cout<<"row "<<nr<<", best cluster r= "<<dr<<" y,z = "<<dy<<" "<<dz<<endl;
8013 //cout<<"row "<<nr<<", found cluster r= "<<dr<<" y,z = "<<dy<<" "<<dz<<endl;
8015 t0.SetClusterPointer(nr, cl);
8016 clusterIndex[nr] = krow.GetIndex(uindex);
8017 if( t0.GetFirstPoint()>nr ) t0.SetFirstPoint(nr);
8018 t0.SetLastPoint(nr);
8024 //cout<<"NOT ENOUGTH CLUSTERS: "<<nClusters<<endl;
8027 Int_t basePoints[3] = {t0.GetFirstPoint(),t0.GetFirstPoint(),t0.GetLastPoint()};
8031 Int_t midRow = (t0.GetLastPoint()-t0.GetFirstPoint())/2;
8033 for( int nr=t0.GetFirstPoint()+1; nr< t0.GetLastPoint(); nr++){
8034 if( !t0.GetClusterPointer(nr) ) continue;
8035 int d = TMath::Abs(nr-midRow);
8043 // first fit 3 base points
8045 //cout<<"Fit3: "<<endl;
8046 for( int icl=0; icl<3; icl++){
8047 int nr = basePoints[icl];
8049 if( nr>=fInnerSec->GetNRows()){
8050 lr = nr - fInnerSec->GetNRows();
8052 } else fSectors=fInnerSec;
8054 AliTPCclusterMI *cl=t0.GetClusterPointer(nr);
8056 //cout<<"WRONG!!!!"<<endl;
8059 int iSec = cl->GetDetector() %fkNIS;
8060 int rotate = iSec - t.GetRelativeSector();
8062 //cout<<"Rotate at row"<<nr<<" to "<<rotate<<" sectors"<<endl;
8063 if (!t.Rotate( rotate*fSectors->GetAlpha()) ) {
8064 //cout<<"can't rotate "<<endl;
8067 t.SetRelativeSector(iSec);
8069 Double_t x= cl->GetX();
8070 if (!t.PropagateTo(x)){
8071 //cout<<"can't propagate to x="<<x<<endl;
8075 if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()){
8076 //cout<<"Snp is too big: "<<t.GetSnp()<<endl;
8079 //cout<<"fit3 : row "<<nr<<" ind = "<<clusterIndex[nr]<<endl;
8081 t.SetCurrentClusterIndex1(clusterIndex[nr]);
8082 t.SetCurrentCluster(cl);
8085 t.SetErrorY2(shapeY2[nr]);
8086 t.SetErrorZ2(shapeZ2[nr]);
8089 for( int j=0; j<15; j++ ) cov[j]=0;
8095 t.AliExternalTrackParam::AddCovariance(cov);
8097 if( !UpdateTrack(&t,0) ){
8098 //cout<<"Can not update"<<endl;
8100 t.SetClusterIndex2(nr,-1);
8101 t.SetClusterIndex(nr,-1);
8102 t.SetClusterPointer(nr,0);
8105 //t.SetClusterPointer(nr, cl);
8108 //t.SetLastPoint(t0.GetLastPoint());
8109 //t.SetFirstPoint(t0.GetFirstPoint());
8111 //cout<<"Fit: "<<endl;
8112 for (Int_t nr=t0.GetLastPoint(); nr>=t0.GetFirstPoint(); nr-- ){
8114 if( nr>=fInnerSec->GetNRows()){
8115 lr = nr - fInnerSec->GetNRows();
8117 } else fSectors=fInnerSec;
8120 if( nr == basePoints[0] ) continue;
8121 if( nr == basePoints[1] ) continue;
8122 if( nr == basePoints[2] ) continue;
8124 AliTPCclusterMI *cl=t0.GetClusterPointer(nr);
8127 int iSec = cl->GetDetector() %fkNIS;
8128 int rotate = iSec - t.GetRelativeSector();
8130 //cout<<"Rotate at row"<<nr<<" to "<<rotate<<" sectors"<<endl;
8131 if (!t.Rotate( rotate*fSectors->GetAlpha()) ) {
8132 //cout<<"can't rotate "<<endl;
8135 t.SetRelativeSector(iSec);
8137 Double_t x= cl->GetX();
8138 if (!t.PropagateTo(x)){
8139 //cout<<"can't propagate to x="<<x<<endl;
8142 if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()){
8143 //cout<<"Snp is too big: "<<t.GetSnp()<<endl;
8147 //cout<<"fit: row "<<nr<<" ind = "<<clusterIndex[nr]<<endl;
8149 t.SetCurrentClusterIndex1(clusterIndex[nr]);
8150 t.SetCurrentCluster(cl);
8152 t.SetErrorY2(shapeY2[nr]);
8153 t.SetErrorZ2(shapeZ2[nr]);
8155 if( !UpdateTrack(&t,0) ){
8156 //cout<<"Can not update"<<endl;
8158 t.SetClusterIndex2(nr,-1);
8159 t.SetClusterIndex(nr,-1);
8162 //t.SetClusterPointer(nr, cl);
8165 //cout<<"After iter "<<iter<<": N clusters="<<t.GetNumberOfClusters()<<" : "<<nClusters<<endl;
8168 //cout<<"fitted track"<<iSeed<<endl;
8170 //cout<<"Statistics: "<<endl;
8171 Int_t foundable,found,shared;
8172 t.GetClusterStatistic(0,nRows, found, foundable, shared, kTRUE);
8173 t.SetNFoundable(foundable);
8174 //cout<<"found "<<found<<" foundable "<<foundable<<" shared "<<shared<<endl;
8180 TObjArray * AliTPCtrackerMI::MakeSeedsHLT(const AliESDEvent *hltEvent)
8185 if( !hltEvent ) return 0;
8188 Int_t nentr=hltEvent->GetNumberOfTracks();
8190 AliInfo(Form("Using %d HLT tracks for seeding",nentr));
8192 TObjArray * seeds = new TObjArray(nentr);
8194 Int_t nup=fOuterSec->GetNRows()+fInnerSec->GetNRows();
8197 Int_t nTr=hltEvent->GetNumberOfTracks();
8199 for( int itr=0; itr<nTr; itr++ ){
8200 //if( itr!=97 ) continue;
8201 const AliExternalTrackParam *param = hltEvent->GetTrack(itr)->GetTPCInnerParam();
8202 if( !param ) continue;
8203 //if( TMath::Abs(esdTr->GetSigned1Pt())>1 ) continue;
8204 //if( TMath::Abs(esdTr->GetTgl())>1. ) continue;
8206 tr.Set(param->GetX(),param->GetAlpha(),param->GetParameter(),param->GetCovariance());
8207 tr.SetNumberOfClusters(0);
8208 AliTPCseed * seed = new( NextFreeSeed() ) AliTPCseed(tr);
8210 Double_t alpha=seed->GetAlpha();// - fSectors->GetAlphaShift();
8211 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
8212 if (alpha < 0. ) alpha += 2.*TMath::Pi();
8214 seed->SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
8215 Double_t alphaSec = fSectors->GetAlpha() * seed->GetRelativeSector() + fSectors->GetAlphaShift();
8217 if (alphaSec >= TMath::Pi()) alphaSec -= 2.*TMath::Pi();
8218 if (alphaSec < -TMath::Pi()) alphaSec += 2.*TMath::Pi();
8220 seed->Rotate(alphaSec - alpha);
8222 seed->SetPoolID(fLastSeedID);
8223 seed->SetIsSeeding(kTRUE);
8224 seed->SetSeed1(nup-1);
8225 seed->SetSeed2(nup-2);
8226 seed->SetSeedType(0);
8227 seed->SetFirstPoint(-1);
8228 seed->SetLastPoint(-1);
8229 seeds->AddLast(seed); // note, track is seed, don't free the seed
8231 //if( index>3 ) break;
8235 fSectors = fOuterSec;
8237 TrackFollowingHLT(seeds );
8239 nTr = seeds->GetEntriesFast();
8240 for( int itr=0; itr<nTr; itr++ ){
8241 AliTPCseed * seed = (AliTPCseed*) seeds->UncheckedAt(itr);
8242 if( !seed ) continue;
8243 //FollowBackProlongation(*seed,0);
8244 // cout<<seed->GetNumberOfClusters()<<endl;
8245 Int_t foundable,found,shared;
8246 seed->GetClusterStatistic(0,nup, found, foundable, shared, kTRUE);
8247 seed->SetNFoundable(foundable);
8248 //cout<<"found "<<found<<" foundable "<<foundable<<" shared "<<shared<<endl;
8249 //if ((found<0.55*foundable) || shared>0.5*found ){// || (seed->GetSigmaY2()+seed->GetSigmaZ2())>0.5){
8250 //MarkSeedFree(seeds->RemoveAt(itr));
8253 if (seed->GetNumberOfClusters()<30 ||
8254 seed->GetNumberOfClusters() < seed->GetNFoundable()*0.6 ||
8255 seed->GetNShared()>0.4*seed->GetNumberOfClusters() ) {
8256 MarkSeedFree(seeds->RemoveAt(itr));
8260 for( int ir=0; ir<nup; ir++){
8261 AliTPCclusterMI *c = seed->GetClusterPointer(ir);
8265 std::cout<<"\n\nHLT tracks left: "<<seeds->GetEntries()<<" out of "<<hltEvent->GetNumberOfTracks()<<endl<<endl;