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); where nis bigger 0
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/cm)
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 (Log level 9) - dump information about
100 // 2.a) cluster error estimate
101 // 3.a) cluster shape estimate
104 //-------------------------------------------------------
109 #include "Riostream.h"
110 #include <TClonesArray.h>
112 #include <TObjArray.h>
115 #include "AliComplexCluster.h"
116 #include "AliESDEvent.h"
117 #include "AliESDtrack.h"
118 #include "AliESDVertex.h"
121 #include "AliHelix.h"
122 #include "AliRunLoader.h"
123 #include "AliTPCClustersRow.h"
124 #include "AliTPCParam.h"
125 #include "AliTPCReconstructor.h"
126 #include "AliTPCpolyTrack.h"
127 #include "AliTPCreco.h"
128 #include "AliTPCseed.h"
130 #include "AliTPCtrackerSector.h"
131 #include "AliTPCtrackerMI.h"
132 #include "TStopwatch.h"
133 #include "AliTPCReconstructor.h"
135 #include "TTreeStream.h"
136 #include "AliAlignObj.h"
137 #include "AliTrackPointArray.h"
139 #include "AliTPCcalibDB.h"
140 #include "AliTPCTransform.h"
141 #include "AliTPCClusterParam.h"
145 ClassImp(AliTPCtrackerMI)
149 class AliTPCFastMath {
152 static Double_t FastAsin(Double_t x);
154 static Double_t fgFastAsin[20000]; //lookup table for fast asin computation
157 Double_t AliTPCFastMath::fgFastAsin[20000];
158 AliTPCFastMath gAliTPCFastMath; // needed to fill the LUT
160 AliTPCFastMath::AliTPCFastMath(){
162 // initialized lookup table;
163 for (Int_t i=0;i<10000;i++){
164 fgFastAsin[2*i] = TMath::ASin(i/10000.);
165 fgFastAsin[2*i+1] = (TMath::ASin((i+1)/10000.)-fgFastAsin[2*i]);
169 Double_t AliTPCFastMath::FastAsin(Double_t x){
171 // return asin using lookup table
173 Int_t index = int(x*10000);
174 return fgFastAsin[2*index]+(x*10000.-index)*fgFastAsin[2*index+1];
177 Int_t index = int(x*10000);
178 return -(fgFastAsin[2*index]+(x*10000.-index)*fgFastAsin[2*index+1]);
180 //__________________________________________________________________
181 AliTPCtrackerMI::AliTPCtrackerMI()
203 // default constructor
206 //_____________________________________________________________________
210 Int_t AliTPCtrackerMI::UpdateTrack(AliTPCseed * track, Int_t accept){
212 //update track information using current cluster - track->fCurrentCluster
215 AliTPCclusterMI* c =track->GetCurrentCluster();
216 if (accept>0) track->SetCurrentClusterIndex1(track->GetCurrentClusterIndex1() | 0x8000); //sign not accepted clusters
218 UInt_t i = track->GetCurrentClusterIndex1();
220 Int_t sec=(i&0xff000000)>>24;
221 //Int_t row = (i&0x00ff0000)>>16;
222 track->SetRow((i&0x00ff0000)>>16);
223 track->SetSector(sec);
224 // Int_t index = i&0xFFFF;
225 if (sec>=fParam->GetNInnerSector()) track->SetRow(track->GetRow()+fParam->GetNRowLow());
226 track->SetClusterIndex2(track->GetRow(), i);
227 //track->fFirstPoint = row;
228 //if ( track->fLastPoint<row) track->fLastPoint =row;
229 // if (track->fRow<0 || track->fRow>160) {
230 // printf("problem\n");
232 if (track->GetFirstPoint()>track->GetRow())
233 track->SetFirstPoint(track->GetRow());
234 if (track->GetLastPoint()<track->GetRow())
235 track->SetLastPoint(track->GetRow());
238 track->SetClusterPointer(track->GetRow(),c);
241 Double_t angle2 = track->GetSnp()*track->GetSnp();
243 //SET NEW Track Point
245 if (angle2<1) //PH sometimes angle2 is very big. To be investigated...
247 angle2 = TMath::Sqrt(angle2/(1-angle2));
248 AliTPCTrackerPoint &point =*(track->GetTrackPoint(track->GetRow()));
250 point.SetSigmaY(c->GetSigmaY2()/track->GetCurrentSigmaY2());
251 point.SetSigmaZ(c->GetSigmaZ2()/track->GetCurrentSigmaZ2());
252 point.SetErrY(sqrt(track->GetErrorY2()));
253 point.SetErrZ(sqrt(track->GetErrorZ2()));
255 point.SetX(track->GetX());
256 point.SetY(track->GetY());
257 point.SetZ(track->GetZ());
258 point.SetAngleY(angle2);
259 point.SetAngleZ(track->GetTgl());
260 if (point.IsShared()){
261 track->SetErrorY2(track->GetErrorY2()*4);
262 track->SetErrorZ2(track->GetErrorZ2()*4);
266 Double_t chi2 = track->GetPredictedChi2(track->GetCurrentCluster());
268 // track->SetErrorY2(track->GetErrorY2()*1.3);
269 // track->SetErrorY2(track->GetErrorY2()+0.01);
270 // track->SetErrorZ2(track->GetErrorZ2()*1.3);
271 // track->SetErrorZ2(track->GetErrorZ2()+0.005);
273 if (accept>0) return 0;
274 if (track->GetNumberOfClusters()%20==0){
275 // if (track->fHelixIn){
276 // TClonesArray & larr = *(track->fHelixIn);
277 // Int_t ihelix = larr.GetEntriesFast();
278 // new(larr[ihelix]) AliHelix(*track) ;
281 track->SetNoCluster(0);
282 return track->Update(c,chi2,i);
287 Int_t AliTPCtrackerMI::AcceptCluster(AliTPCseed * seed, AliTPCclusterMI * cluster)
290 // decide according desired precision to accept given
291 // cluster for tracking
292 Double_t sy2=ErrY2(seed,cluster);
293 Double_t sz2=ErrZ2(seed,cluster);
295 Double_t sdistancey2 = sy2+seed->GetSigmaY2();
296 Double_t sdistancez2 = sz2+seed->GetSigmaZ2();
298 Double_t rdistancey2 = (seed->GetCurrentCluster()->GetY()-seed->GetY())*
299 (seed->GetCurrentCluster()->GetY()-seed->GetY())/sdistancey2;
300 Double_t rdistancez2 = (seed->GetCurrentCluster()->GetZ()-seed->GetZ())*
301 (seed->GetCurrentCluster()->GetZ()-seed->GetZ())/sdistancez2;
303 Double_t rdistance2 = rdistancey2+rdistancez2;
306 if (AliTPCReconstructor::StreamLevel()>5 && seed->GetNumberOfClusters()>20) {
307 Float_t rmsy2 = seed->GetCurrentSigmaY2();
308 Float_t rmsz2 = seed->GetCurrentSigmaZ2();
309 Float_t rmsy2p30 = seed->GetCMeanSigmaY2p30();
310 Float_t rmsz2p30 = seed->GetCMeanSigmaZ2p30();
311 Float_t rmsy2p30R = seed->GetCMeanSigmaY2p30R();
312 Float_t rmsz2p30R = seed->GetCMeanSigmaZ2p30R();
314 AliExternalTrackParam param(*seed);
315 static TVectorD gcl(3),gtr(3);
317 param.GetXYZ(gcl.GetMatrixArray());
318 cluster->GetGlobalXYZ(gclf);
319 gcl[0]=gclf[0]; gcl[1]=gclf[1]; gcl[2]=gclf[2];
321 if (AliTPCReconstructor::StreamLevel()>0) {
322 (*fDebugStreamer)<<"ErrParam"<<
331 "rmsy2p30="<<rmsy2p30<<
332 "rmsz2p30="<<rmsz2p30<<
333 "rmsy2p30R="<<rmsy2p30R<<
334 "rmsz2p30R="<<rmsz2p30R<<
339 if (rdistance2>16) return 3;
342 if ((rdistancey2>9. || rdistancez2>9.) && cluster->GetType()==0)
343 return 2; //suspisiouce - will be changed
345 if ((rdistancey2>6.25 || rdistancez2>6.25) && cluster->GetType()>0)
346 // strict cut on overlaped cluster
347 return 2; //suspisiouce - will be changed
349 if ( (rdistancey2>1. || rdistancez2>6.25 )
350 && cluster->GetType()<0){
351 seed->SetNFoundable(seed->GetNFoundable()-1);
360 //_____________________________________________________________________________
361 AliTPCtrackerMI::AliTPCtrackerMI(const AliTPCParam *par):
363 fkNIS(par->GetNInnerSector()/2),
365 fkNOS(par->GetNOuterSector()/2),
382 //---------------------------------------------------------------------
383 // The main TPC tracker constructor
384 //---------------------------------------------------------------------
385 fInnerSec=new AliTPCtrackerSector[fkNIS];
386 fOuterSec=new AliTPCtrackerSector[fkNOS];
389 for (i=0; i<fkNIS; i++) fInnerSec[i].Setup(par,0);
390 for (i=0; i<fkNOS; i++) fOuterSec[i].Setup(par,1);
393 Int_t nrowlow = par->GetNRowLow();
394 Int_t nrowup = par->GetNRowUp();
397 for (Int_t i=0;i<nrowlow;i++){
398 fXRow[i] = par->GetPadRowRadiiLow(i);
399 fPadLength[i]= par->GetPadPitchLength(0,i);
400 fYMax[i] = fXRow[i]*TMath::Tan(0.5*par->GetInnerAngle());
404 for (Int_t i=0;i<nrowup;i++){
405 fXRow[i+nrowlow] = par->GetPadRowRadiiUp(i);
406 fPadLength[i+nrowlow] = par->GetPadPitchLength(60,i);
407 fYMax[i+nrowlow] = fXRow[i+nrowlow]*TMath::Tan(0.5*par->GetOuterAngle());
410 if (AliTPCReconstructor::StreamLevel()>0) {
411 fDebugStreamer = new TTreeSRedirector("TPCdebug.root");
414 //________________________________________________________________________
415 AliTPCtrackerMI::AliTPCtrackerMI(const AliTPCtrackerMI &t):
436 //------------------------------------
437 // dummy copy constructor
438 //------------------------------------------------------------------
441 AliTPCtrackerMI & AliTPCtrackerMI::operator=(const AliTPCtrackerMI& /*r*/){
442 //------------------------------
444 //--------------------------------------------------------------
447 //_____________________________________________________________________________
448 AliTPCtrackerMI::~AliTPCtrackerMI() {
449 //------------------------------------------------------------------
450 // TPC tracker destructor
451 //------------------------------------------------------------------
458 if (fDebugStreamer) delete fDebugStreamer;
462 void AliTPCtrackerMI::FillESD(TObjArray* arr)
466 //fill esds using updated tracks
468 // write tracks to the event
469 // store index of the track
470 Int_t nseed=arr->GetEntriesFast();
471 //FindKinks(arr,fEvent);
472 for (Int_t i=0; i<nseed; i++) {
473 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
477 if (AliTPCReconstructor::StreamLevel()>1) {
478 (*fDebugStreamer)<<"Track0"<<
482 // pt->PropagateTo(fParam->GetInnerRadiusLow());
483 if (pt->GetKinkIndex(0)<=0){ //don't propagate daughter tracks
484 pt->PropagateTo(fParam->GetInnerRadiusLow());
487 if (( pt->GetPoints()[2]- pt->GetPoints()[0])>5 && pt->GetPoints()[3]>0.8){
489 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
490 iotrack.SetTPCPoints(pt->GetPoints());
491 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
492 iotrack.SetV0Indexes(pt->GetV0Indexes());
493 // iotrack.SetTPCpid(pt->fTPCr);
494 //iotrack.SetTPCindex(i);
495 fEvent->AddTrack(&iotrack);
499 if ( (pt->GetNumberOfClusters()>70)&& (Float_t(pt->GetNumberOfClusters())/Float_t(pt->GetNFoundable()))>0.55) {
501 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
502 iotrack.SetTPCPoints(pt->GetPoints());
503 //iotrack.SetTPCindex(i);
504 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
505 iotrack.SetV0Indexes(pt->GetV0Indexes());
506 // iotrack.SetTPCpid(pt->fTPCr);
507 fEvent->AddTrack(&iotrack);
511 // short tracks - maybe decays
513 if ( (pt->GetNumberOfClusters()>30) && (Float_t(pt->GetNumberOfClusters())/Float_t(pt->GetNFoundable()))>0.70) {
514 Int_t found,foundable,shared;
515 pt->GetClusterStatistic(0,60,found, foundable,shared,kFALSE);
516 if ( (found>20) && (pt->GetNShared()/float(pt->GetNumberOfClusters())<0.2)){
518 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
519 //iotrack.SetTPCindex(i);
520 iotrack.SetTPCPoints(pt->GetPoints());
521 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
522 iotrack.SetV0Indexes(pt->GetV0Indexes());
523 //iotrack.SetTPCpid(pt->fTPCr);
524 fEvent->AddTrack(&iotrack);
529 if ( (pt->GetNumberOfClusters()>20) && (Float_t(pt->GetNumberOfClusters())/Float_t(pt->GetNFoundable()))>0.8) {
530 Int_t found,foundable,shared;
531 pt->GetClusterStatistic(0,60,found, foundable,shared,kFALSE);
532 if (found<20) continue;
533 if (pt->GetNShared()/float(pt->GetNumberOfClusters())>0.2) continue;
536 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
537 iotrack.SetTPCPoints(pt->GetPoints());
538 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
539 iotrack.SetV0Indexes(pt->GetV0Indexes());
540 //iotrack.SetTPCpid(pt->fTPCr);
541 //iotrack.SetTPCindex(i);
542 fEvent->AddTrack(&iotrack);
545 // short tracks - secondaties
547 if ( (pt->GetNumberOfClusters()>30) ) {
548 Int_t found,foundable,shared;
549 pt->GetClusterStatistic(128,158,found, foundable,shared,kFALSE);
550 if ( (found>20) && (pt->GetNShared()/float(pt->GetNumberOfClusters())<0.2) &&float(found)/float(foundable)>0.8){
552 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
553 iotrack.SetTPCPoints(pt->GetPoints());
554 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
555 iotrack.SetV0Indexes(pt->GetV0Indexes());
556 //iotrack.SetTPCpid(pt->fTPCr);
557 //iotrack.SetTPCindex(i);
558 fEvent->AddTrack(&iotrack);
563 if ( (pt->GetNumberOfClusters()>15)) {
564 Int_t found,foundable,shared;
565 pt->GetClusterStatistic(138,158,found, foundable,shared,kFALSE);
566 if (found<15) continue;
567 if (foundable<=0) continue;
568 if (pt->GetNShared()/float(pt->GetNumberOfClusters())>0.2) continue;
569 if (float(found)/float(foundable)<0.8) continue;
572 iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
573 iotrack.SetTPCPoints(pt->GetPoints());
574 iotrack.SetKinkIndexes(pt->GetKinkIndexes());
575 iotrack.SetV0Indexes(pt->GetV0Indexes());
576 // iotrack.SetTPCpid(pt->fTPCr);
577 //iotrack.SetTPCindex(i);
578 fEvent->AddTrack(&iotrack);
583 printf("Number of filled ESDs-\t%d\n",fEvent->GetNumberOfTracks());
590 Double_t AliTPCtrackerMI::ErrY2(AliTPCseed* seed, AliTPCclusterMI * cl){
593 // Use calibrated cluster error from OCDB
595 AliTPCClusterParam * clparam = AliTPCcalibDB::Instance()->GetClusterParam();
597 Float_t z = TMath::Abs(fParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
598 Int_t ctype = cl->GetType();
599 Int_t type = (cl->GetRow()<63) ? 0: (cl->GetRow()>126) ? 1:2;
600 Double_t angle = seed->GetSnp()*seed->GetSnp();
601 angle = TMath::Sqrt(TMath::Abs(angle/(1.-angle)));
602 Double_t erry2 = clparam->GetError0Par(0,type, z,angle);
604 erry2+=0.5; // edge cluster
607 seed->SetErrorY2(erry2);
611 //calculate look-up table at the beginning
612 // static Bool_t ginit = kFALSE;
613 // static Float_t gnoise1,gnoise2,gnoise3;
614 // static Float_t ggg1[10000];
615 // static Float_t ggg2[10000];
616 // static Float_t ggg3[10000];
617 // static Float_t glandau1[10000];
618 // static Float_t glandau2[10000];
619 // static Float_t glandau3[10000];
621 // static Float_t gcor01[500];
622 // static Float_t gcor02[500];
623 // static Float_t gcorp[500];
627 // if (ginit==kFALSE){
628 // for (Int_t i=1;i<500;i++){
629 // Float_t rsigma = float(i)/100.;
630 // gcor02[i] = TMath::Max(0.78 +TMath::Exp(7.4*(rsigma-1.2)),0.6);
631 // gcor01[i] = TMath::Max(0.72 +TMath::Exp(3.36*(rsigma-1.2)),0.6);
632 // gcorp[i] = TMath::Max(TMath::Power((rsigma+0.5),1.5),1.2);
636 // for (Int_t i=3;i<10000;i++){
640 // Float_t amp = float(i);
641 // Float_t padlength =0.75;
642 // gnoise1 = 0.0004/padlength;
643 // Float_t nel = 0.268*amp;
644 // Float_t nprim = 0.155*amp;
645 // ggg1[i] = fParam->GetDiffT()*fParam->GetDiffT()*(2+0.001*nel/(padlength*padlength))/nel;
646 // glandau1[i] = (2.+0.12*nprim)*0.5* (2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
647 // if (glandau1[i]>1) glandau1[i]=1;
648 // glandau1[i]*=padlength*padlength/12.;
652 // gnoise2 = 0.0004/padlength;
654 // nprim = 0.133*amp;
655 // ggg2[i] = fParam->GetDiffT()*fParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
656 // glandau2[i] = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
657 // if (glandau2[i]>1) glandau2[i]=1;
658 // glandau2[i]*=padlength*padlength/12.;
663 // gnoise3 = 0.0004/padlength;
665 // nprim = 0.133*amp;
666 // ggg3[i] = fParam->GetDiffT()*fParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
667 // glandau3[i] = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
668 // if (glandau3[i]>1) glandau3[i]=1;
669 // glandau3[i]*=padlength*padlength/12.;
677 // Int_t amp = int(TMath::Abs(cl->GetQ()));
679 // seed->SetErrorY2(1.);
683 // Float_t z = TMath::Abs(fParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
684 // Int_t ctype = cl->GetType();
685 // Float_t padlength= GetPadPitchLength(seed->GetRow());
686 // Double_t angle2 = seed->GetSnp()*seed->GetSnp();
687 // angle2 = angle2/(1-angle2);
689 // //cluster "quality"
690 // Int_t rsigmay = int(100.*cl->GetSigmaY2()/(seed->GetCurrentSigmaY2()));
693 // if (fSectors==fInnerSec){
694 // snoise2 = gnoise1;
695 // res = ggg1[amp]*z+glandau1[amp]*angle2;
696 // if (ctype==0) res *= gcor01[rsigmay];
699 // res*= gcorp[rsigmay];
703 // if (padlength<1.1){
704 // snoise2 = gnoise2;
705 // res = ggg2[amp]*z+glandau2[amp]*angle2;
706 // if (ctype==0) res *= gcor02[rsigmay];
709 // res*= gcorp[rsigmay];
713 // snoise2 = gnoise3;
714 // res = ggg3[amp]*z+glandau3[amp]*angle2;
715 // if (ctype==0) res *= gcor02[rsigmay];
718 // res*= gcorp[rsigmay];
725 // res*=2.4; // overestimate error 2 times
729 // if (res<2*snoise2)
732 // seed->SetErrorY2(res);
740 Double_t AliTPCtrackerMI::ErrZ2(AliTPCseed* seed, AliTPCclusterMI * cl){
743 // Use calibrated cluster error from OCDB
745 AliTPCClusterParam * clparam = AliTPCcalibDB::Instance()->GetClusterParam();
747 Float_t z = TMath::Abs(fParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
748 Int_t ctype = cl->GetType();
749 Int_t type = (cl->GetRow()<63) ? 0: (cl->GetRow()>126) ? 1:2;
751 Double_t angle2 = seed->GetSnp()*seed->GetSnp();
752 angle2 = seed->GetTgl()*seed->GetTgl()*(1+angle2/(1-angle2));
753 Double_t angle = TMath::Sqrt(TMath::Abs(angle2));
754 Double_t errz2 = clparam->GetError0Par(1,type, z,angle);
756 errz2+=0.5; // edge cluster
759 seed->SetErrorZ2(errz2);
765 // //seed->SetErrorY2(0.1);
767 // //calculate look-up table at the beginning
768 // static Bool_t ginit = kFALSE;
769 // static Float_t gnoise1,gnoise2,gnoise3;
770 // static Float_t ggg1[10000];
771 // static Float_t ggg2[10000];
772 // static Float_t ggg3[10000];
773 // static Float_t glandau1[10000];
774 // static Float_t glandau2[10000];
775 // static Float_t glandau3[10000];
777 // static Float_t gcor01[1000];
778 // static Float_t gcor02[1000];
779 // static Float_t gcorp[1000];
783 // if (ginit==kFALSE){
784 // for (Int_t i=1;i<1000;i++){
785 // Float_t rsigma = float(i)/100.;
786 // gcor02[i] = TMath::Max(0.81 +TMath::Exp(6.8*(rsigma-1.2)),0.6);
787 // gcor01[i] = TMath::Max(0.72 +TMath::Exp(2.04*(rsigma-1.2)),0.6);
788 // gcorp[i] = TMath::Max(TMath::Power((rsigma+0.5),1.5),1.2);
792 // for (Int_t i=3;i<10000;i++){
796 // Float_t amp = float(i);
797 // Float_t padlength =0.75;
798 // gnoise1 = 0.0004/padlength;
799 // Float_t nel = 0.268*amp;
800 // Float_t nprim = 0.155*amp;
801 // ggg1[i] = fParam->GetDiffT()*fParam->GetDiffT()*(2+0.001*nel/(padlength*padlength))/nel;
802 // glandau1[i] = (2.+0.12*nprim)*0.5* (2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
803 // if (glandau1[i]>1) glandau1[i]=1;
804 // glandau1[i]*=padlength*padlength/12.;
808 // gnoise2 = 0.0004/padlength;
810 // nprim = 0.133*amp;
811 // ggg2[i] = fParam->GetDiffT()*fParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
812 // glandau2[i] = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
813 // if (glandau2[i]>1) glandau2[i]=1;
814 // glandau2[i]*=padlength*padlength/12.;
819 // gnoise3 = 0.0004/padlength;
821 // nprim = 0.133*amp;
822 // ggg3[i] = fParam->GetDiffT()*fParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
823 // glandau3[i] = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
824 // if (glandau3[i]>1) glandau3[i]=1;
825 // glandau3[i]*=padlength*padlength/12.;
833 // Int_t amp = int(TMath::Abs(cl->GetQ()));
835 // seed->SetErrorY2(1.);
839 // Float_t z = TMath::Abs(fParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
840 // Int_t ctype = cl->GetType();
841 // Float_t padlength= GetPadPitchLength(seed->GetRow());
843 // Double_t angle2 = seed->GetSnp()*seed->GetSnp();
844 // // if (angle2<0.6) angle2 = 0.6;
845 // angle2 = seed->GetTgl()*seed->GetTgl()*(1+angle2/(1-angle2));
847 // //cluster "quality"
848 // Int_t rsigmaz = int(100.*cl->GetSigmaZ2()/(seed->GetCurrentSigmaZ2()));
851 // if (fSectors==fInnerSec){
852 // snoise2 = gnoise1;
853 // res = ggg1[amp]*z+glandau1[amp]*angle2;
854 // if (ctype==0) res *= gcor01[rsigmaz];
857 // res*= gcorp[rsigmaz];
861 // if (padlength<1.1){
862 // snoise2 = gnoise2;
863 // res = ggg2[amp]*z+glandau2[amp]*angle2;
864 // if (ctype==0) res *= gcor02[rsigmaz];
867 // res*= gcorp[rsigmaz];
871 // snoise2 = gnoise3;
872 // res = ggg3[amp]*z+glandau3[amp]*angle2;
873 // if (ctype==0) res *= gcor02[rsigmaz];
876 // res*= gcorp[rsigmaz];
885 // if ((ctype<0) &&<70){
890 // if (res<2*snoise2)
892 // if (res>3) res =3;
893 // seed->SetErrorZ2(res);
901 void AliTPCtrackerMI::RotateToLocal(AliTPCseed *seed)
903 //rotate to track "local coordinata
904 Float_t x = seed->GetX();
905 Float_t y = seed->GetY();
906 Float_t ymax = x*TMath::Tan(0.5*fSectors->GetAlpha());
909 seed->SetRelativeSector((seed->GetRelativeSector()+1) % fN);
910 if (!seed->Rotate(fSectors->GetAlpha()))
912 } else if (y <-ymax) {
913 seed->SetRelativeSector((seed->GetRelativeSector()-1+fN) % fN);
914 if (!seed->Rotate(-fSectors->GetAlpha()))
922 //_____________________________________________________________________________
923 Double_t AliTPCtrackerMI::F1old(Double_t x1,Double_t y1,
924 Double_t x2,Double_t y2,
925 Double_t x3,Double_t y3)
927 //-----------------------------------------------------------------
928 // Initial approximation of the track curvature
929 //-----------------------------------------------------------------
930 Double_t d=(x2-x1)*(y3-y2)-(x3-x2)*(y2-y1);
931 Double_t a=0.5*((y3-y2)*(y2*y2-y1*y1+x2*x2-x1*x1)-
932 (y2-y1)*(y3*y3-y2*y2+x3*x3-x2*x2));
933 Double_t b=0.5*((x2-x1)*(y3*y3-y2*y2+x3*x3-x2*x2)-
934 (x3-x2)*(y2*y2-y1*y1+x2*x2-x1*x1));
936 Double_t xr=TMath::Abs(d/(d*x1-a)), yr=d/(d*y1-b);
937 if ( xr*xr+yr*yr<=0.00000000000001) return 100;
938 return -xr*yr/sqrt(xr*xr+yr*yr);
943 //_____________________________________________________________________________
944 Double_t AliTPCtrackerMI::F1(Double_t x1,Double_t y1,
945 Double_t x2,Double_t y2,
946 Double_t x3,Double_t y3)
948 //-----------------------------------------------------------------
949 // Initial approximation of the track curvature
950 //-----------------------------------------------------------------
956 Double_t det = x3*y2-x2*y3;
961 Double_t u = 0.5* (x2*(x2-x3)+y2*(y2-y3))/det;
962 Double_t x0 = x3*0.5-y3*u;
963 Double_t y0 = y3*0.5+x3*u;
964 Double_t c2 = 1/TMath::Sqrt(x0*x0+y0*y0);
970 Double_t AliTPCtrackerMI::F2(Double_t x1,Double_t y1,
971 Double_t x2,Double_t y2,
972 Double_t x3,Double_t y3)
974 //-----------------------------------------------------------------
975 // Initial approximation of the track curvature
976 //-----------------------------------------------------------------
982 Double_t det = x3*y2-x2*y3;
987 Double_t u = 0.5* (x2*(x2-x3)+y2*(y2-y3))/det;
988 Double_t x0 = x3*0.5-y3*u;
989 Double_t y0 = y3*0.5+x3*u;
990 Double_t c2 = 1/TMath::Sqrt(x0*x0+y0*y0);
999 //_____________________________________________________________________________
1000 Double_t AliTPCtrackerMI::F2old(Double_t x1,Double_t y1,
1001 Double_t x2,Double_t y2,
1002 Double_t x3,Double_t y3)
1004 //-----------------------------------------------------------------
1005 // Initial approximation of the track curvature times center of curvature
1006 //-----------------------------------------------------------------
1007 Double_t d=(x2-x1)*(y3-y2)-(x3-x2)*(y2-y1);
1008 Double_t a=0.5*((y3-y2)*(y2*y2-y1*y1+x2*x2-x1*x1)-
1009 (y2-y1)*(y3*y3-y2*y2+x3*x3-x2*x2));
1010 Double_t b=0.5*((x2-x1)*(y3*y3-y2*y2+x3*x3-x2*x2)-
1011 (x3-x2)*(y2*y2-y1*y1+x2*x2-x1*x1));
1013 Double_t xr=TMath::Abs(d/(d*x1-a)), yr=d/(d*y1-b);
1015 return -a/(d*y1-b)*xr/sqrt(xr*xr+yr*yr);
1018 //_____________________________________________________________________________
1019 Double_t AliTPCtrackerMI::F3(Double_t x1,Double_t y1,
1020 Double_t x2,Double_t y2,
1021 Double_t z1,Double_t z2)
1023 //-----------------------------------------------------------------
1024 // Initial approximation of the tangent of the track dip angle
1025 //-----------------------------------------------------------------
1026 return (z1 - z2)/sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
1030 Double_t AliTPCtrackerMI::F3n(Double_t x1,Double_t y1,
1031 Double_t x2,Double_t y2,
1032 Double_t z1,Double_t z2, Double_t c)
1034 //-----------------------------------------------------------------
1035 // Initial approximation of the tangent of the track dip angle
1036 //-----------------------------------------------------------------
1040 //angle1 = (z1-z2)*c/(TMath::ASin(c*x1-ni)-TMath::ASin(c*x2-ni));
1042 Double_t d = TMath::Sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
1043 if (TMath::Abs(d*c*0.5)>1) return 0;
1044 // Double_t angle2 = TMath::ASin(d*c*0.5);
1045 // Double_t angle2 = AliTPCFastMath::FastAsin(d*c*0.5);
1046 Double_t angle2 = (d*c*0.5>0.1)? TMath::ASin(d*c*0.5): AliTPCFastMath::FastAsin(d*c*0.5);
1048 angle2 = (z1-z2)*c/(angle2*2.);
1052 Bool_t AliTPCtrackerMI::GetProlongation(Double_t x1, Double_t x2, Double_t x[5], Double_t &y, Double_t &z)
1053 {//-----------------------------------------------------------------
1054 // This function find proloncation of a track to a reference plane x=x2.
1055 //-----------------------------------------------------------------
1059 if (TMath::Abs(x[4]*x1 - x[2]) >= 0.999) {
1063 Double_t c1=x[4]*x1 - x[2], r1=sqrt(1.- c1*c1);
1064 Double_t c2=x[4]*x2 - x[2], r2=sqrt(1.- c2*c2);
1068 Double_t dy = dx*(c1+c2)/(r1+r2);
1071 Double_t delta = x[4]*dx*(c1+c2)/(c1*r2 + c2*r1);
1073 if (TMath::Abs(delta)>0.01){
1074 dz = x[3]*TMath::ASin(delta)/x[4];
1076 dz = x[3]*AliTPCFastMath::FastAsin(delta)/x[4];
1079 //dz = x[3]*AliTPCFastMath::FastAsin(delta)/x[4];
1087 Int_t AliTPCtrackerMI::LoadClusters (TTree *tree)
1092 return LoadClusters();
1096 Int_t AliTPCtrackerMI::LoadClusters(TObjArray *arr)
1099 // load clusters to the memory
1100 AliTPCClustersRow *clrow = 0x0;
1101 Int_t lower = arr->LowerBound();
1102 Int_t entries = arr->GetEntriesFast();
1104 for (Int_t i=lower; i<entries; i++) {
1105 clrow = (AliTPCClustersRow*) arr->At(i);
1106 if(!clrow) continue;
1107 if(!clrow->GetArray()) continue;
1111 fParam->AdjustSectorRow(clrow->GetID(),sec,row);
1113 for (Int_t icl=0; icl<clrow->GetArray()->GetEntriesFast(); icl++){
1114 Transform((AliTPCclusterMI*)(clrow->GetArray()->At(icl)));
1117 if (clrow->GetArray()->GetEntriesFast()<=0) continue;
1118 AliTPCtrackerRow * tpcrow=0;
1121 tpcrow = &(fInnerSec[sec%fkNIS][row]);
1125 tpcrow = &(fOuterSec[(sec-fkNIS*2)%fkNOS][row]);
1126 left = (sec-fkNIS*2)/fkNOS;
1129 tpcrow->SetN1(clrow->GetArray()->GetEntriesFast());
1130 tpcrow->SetClusters1(new AliTPCclusterMI[tpcrow->GetN1()]);
1131 for (Int_t i=0;i<tpcrow->GetN1();i++)
1132 tpcrow->SetCluster1(i, *(AliTPCclusterMI*)(clrow->GetArray()->At(i)));
1135 tpcrow->SetN2(clrow->GetArray()->GetEntriesFast());
1136 tpcrow->SetClusters2(new AliTPCclusterMI[tpcrow->GetN2()]);
1137 for (Int_t i=0;i<tpcrow->GetN2();i++)
1138 tpcrow->SetCluster2(i,*(AliTPCclusterMI*)(clrow->GetArray()->At(i)));
1148 Int_t AliTPCtrackerMI::LoadClusters(TClonesArray *arr)
1151 // load clusters to the memory from one
1154 AliTPCclusterMI *clust=0;
1155 Int_t count[72][96] = { {0} , {0} };
1157 // loop over clusters
1158 for (Int_t icl=0; icl<arr->GetEntriesFast(); icl++) {
1159 clust = (AliTPCclusterMI*)arr->At(icl);
1160 if(!clust) continue;
1161 //printf("cluster: det %d, row %d \n", clust->GetDetector(),clust->GetRow());
1163 // transform clusters
1166 // count clusters per pad row
1167 count[clust->GetDetector()][clust->GetRow()]++;
1170 // insert clusters to sectors
1171 for (Int_t icl=0; icl<arr->GetEntriesFast(); icl++) {
1172 clust = (AliTPCclusterMI*)arr->At(icl);
1173 if(!clust) continue;
1175 Int_t sec = clust->GetDetector();
1176 Int_t row = clust->GetRow();
1178 // filter overlapping pad rows needed by HLT
1179 if(sec<fkNIS*2) { //IROCs
1180 if(row == 30) continue;
1183 if(row == 27 || row == 76) continue;
1189 fInnerSec[sec%fkNIS].InsertCluster(clust, count[sec][row], fParam);
1192 left = (sec-fkNIS*2)/fkNOS;
1193 fOuterSec[(sec-fkNIS*2)%fkNOS].InsertCluster(clust, count[sec][row], fParam);
1197 // Load functions must be called behind LoadCluster(TClonesArray*)
1199 //LoadOuterSectors();
1200 //LoadInnerSectors();
1206 Int_t AliTPCtrackerMI::LoadClusters()
1209 // load clusters to the memory
1210 AliTPCClustersRow *clrow= new AliTPCClustersRow;
1211 clrow->SetClass("AliTPCclusterMI");
1213 clrow->GetArray()->ExpandCreateFast(10000);
1215 // TTree * tree = fClustersArray.GetTree();
1217 TTree * tree = fInput;
1218 TBranch * br = tree->GetBranch("Segment");
1219 br->SetAddress(&clrow);
1221 Int_t j=Int_t(tree->GetEntries());
1222 for (Int_t i=0; i<j; i++) {
1226 fParam->AdjustSectorRow(clrow->GetID(),sec,row);
1227 for (Int_t icl=0; icl<clrow->GetArray()->GetEntriesFast(); icl++){
1228 Transform((AliTPCclusterMI*)(clrow->GetArray()->At(icl)));
1231 AliTPCtrackerRow * tpcrow=0;
1234 tpcrow = &(fInnerSec[sec%fkNIS][row]);
1238 tpcrow = &(fOuterSec[(sec-fkNIS*2)%fkNOS][row]);
1239 left = (sec-fkNIS*2)/fkNOS;
1242 tpcrow->SetN1(clrow->GetArray()->GetEntriesFast());
1243 tpcrow->SetClusters1(new AliTPCclusterMI[tpcrow->GetN1()]);
1244 for (Int_t i=0;i<tpcrow->GetN1();i++)
1245 tpcrow->SetCluster1(i, *(AliTPCclusterMI*)(clrow->GetArray()->At(i)));
1248 tpcrow->SetN2(clrow->GetArray()->GetEntriesFast());
1249 tpcrow->SetClusters2(new AliTPCclusterMI[tpcrow->GetN2()]);
1250 for (Int_t i=0;i<tpcrow->GetN2();i++)
1251 tpcrow->SetCluster2(i,*(AliTPCclusterMI*)(clrow->GetArray()->At(i)));
1262 void AliTPCtrackerMI::UnloadClusters()
1265 // unload clusters from the memory
1267 Int_t nrows = fOuterSec->GetNRows();
1268 for (Int_t sec = 0;sec<fkNOS;sec++)
1269 for (Int_t row = 0;row<nrows;row++){
1270 AliTPCtrackerRow* tpcrow = &(fOuterSec[sec%fkNOS][row]);
1272 // if (tpcrow->fClusters1) delete []tpcrow->fClusters1;
1273 // if (tpcrow->fClusters2) delete []tpcrow->fClusters2;
1275 tpcrow->ResetClusters();
1278 nrows = fInnerSec->GetNRows();
1279 for (Int_t sec = 0;sec<fkNIS;sec++)
1280 for (Int_t row = 0;row<nrows;row++){
1281 AliTPCtrackerRow* tpcrow = &(fInnerSec[sec%fkNIS][row]);
1283 // if (tpcrow->fClusters1) delete []tpcrow->fClusters1;
1284 //if (tpcrow->fClusters2) delete []tpcrow->fClusters2;
1286 tpcrow->ResetClusters();
1292 void AliTPCtrackerMI::FillClusterArray(TObjArray* array) const{
1294 // Filling cluster to the array - For visualization purposes
1297 nrows = fOuterSec->GetNRows();
1298 for (Int_t sec = 0;sec<fkNOS;sec++)
1299 for (Int_t row = 0;row<nrows;row++){
1300 AliTPCtrackerRow* tpcrow = &(fOuterSec[sec%fkNOS][row]);
1301 if (!tpcrow) continue;
1302 for (Int_t icl = 0;icl<tpcrow->GetN();icl++){
1303 array->AddLast((TObject*)((*tpcrow)[icl]));
1306 nrows = fInnerSec->GetNRows();
1307 for (Int_t sec = 0;sec<fkNIS;sec++)
1308 for (Int_t row = 0;row<nrows;row++){
1309 AliTPCtrackerRow* tpcrow = &(fInnerSec[sec%fkNIS][row]);
1310 if (!tpcrow) continue;
1311 for (Int_t icl = 0;icl<tpcrow->GetN();icl++){
1312 array->AddLast((TObject*)(*tpcrow)[icl]);
1318 void AliTPCtrackerMI::Transform(AliTPCclusterMI * cluster){
1322 AliTPCTransform *transform = AliTPCcalibDB::Instance()->GetTransform() ;
1324 AliFatal("Tranformations not in calibDB");
1326 Double_t x[3]={cluster->GetRow(),cluster->GetPad(),cluster->GetTimeBin()};
1327 Int_t i[1]={cluster->GetDetector()};
1328 transform->Transform(x,i,0,1);
1329 if (cluster->GetDetector()%36>17){
1334 // in debug mode check the transformation
1336 if (AliTPCReconstructor::StreamLevel()>1) {
1338 cluster->GetGlobalXYZ(gx);
1339 Int_t event = (fEvent==NULL)? 0: fEvent->GetEventNumberInFile();
1340 TTreeSRedirector &cstream = *fDebugStreamer;
1341 cstream<<"Transform"<<
1352 cluster->SetX(x[0]);
1353 cluster->SetY(x[1]);
1354 cluster->SetZ(x[2]);
1360 //if (!fParam->IsGeoRead()) fParam->ReadGeoMatrices();
1361 TGeoHMatrix *mat = fParam->GetClusterMatrix(cluster->GetDetector());
1363 Double_t pos[3]= {cluster->GetX(),cluster->GetY(),cluster->GetZ()};
1364 Double_t posC[3]={cluster->GetX(),cluster->GetY(),cluster->GetZ()};
1365 if (mat) mat->LocalToMaster(pos,posC);
1367 // chack Loading of Geo matrices from GeoManager - TEMPORARY FIX
1369 cluster->SetX(posC[0]);
1370 cluster->SetY(posC[1]);
1371 cluster->SetZ(posC[2]);
1374 //_____________________________________________________________________________
1375 Int_t AliTPCtrackerMI::LoadOuterSectors() {
1376 //-----------------------------------------------------------------
1377 // This function fills outer TPC sectors with clusters.
1378 //-----------------------------------------------------------------
1379 Int_t nrows = fOuterSec->GetNRows();
1381 for (Int_t sec = 0;sec<fkNOS;sec++)
1382 for (Int_t row = 0;row<nrows;row++){
1383 AliTPCtrackerRow* tpcrow = &(fOuterSec[sec%fkNOS][row]);
1384 Int_t sec2 = sec+2*fkNIS;
1386 Int_t ncl = tpcrow->GetN1();
1388 AliTPCclusterMI *c= (tpcrow->GetCluster1(ncl));
1389 index=(((sec2<<8)+row)<<16)+ncl;
1390 tpcrow->InsertCluster(c,index);
1393 ncl = tpcrow->GetN2();
1395 AliTPCclusterMI *c= (tpcrow->GetCluster2(ncl));
1396 index=((((sec2+fkNOS)<<8)+row)<<16)+ncl;
1397 tpcrow->InsertCluster(c,index);
1400 // write indexes for fast acces
1402 for (Int_t i=0;i<510;i++)
1403 tpcrow->SetFastCluster(i,-1);
1404 for (Int_t i=0;i<tpcrow->GetN();i++){
1405 Int_t zi = Int_t((*tpcrow)[i]->GetZ()+255.);
1406 tpcrow->SetFastCluster(zi,i); // write index
1409 for (Int_t i=0;i<510;i++){
1410 if (tpcrow->GetFastCluster(i)<0)
1411 tpcrow->SetFastCluster(i,last);
1413 last = tpcrow->GetFastCluster(i);
1422 //_____________________________________________________________________________
1423 Int_t AliTPCtrackerMI::LoadInnerSectors() {
1424 //-----------------------------------------------------------------
1425 // This function fills inner TPC sectors with clusters.
1426 //-----------------------------------------------------------------
1427 Int_t nrows = fInnerSec->GetNRows();
1429 for (Int_t sec = 0;sec<fkNIS;sec++)
1430 for (Int_t row = 0;row<nrows;row++){
1431 AliTPCtrackerRow* tpcrow = &(fInnerSec[sec%fkNIS][row]);
1434 Int_t ncl = tpcrow->GetN1();
1436 AliTPCclusterMI *c= (tpcrow->GetCluster1(ncl));
1437 index=(((sec<<8)+row)<<16)+ncl;
1438 tpcrow->InsertCluster(c,index);
1441 ncl = tpcrow->GetN2();
1443 AliTPCclusterMI *c= (tpcrow->GetCluster2(ncl));
1444 index=((((sec+fkNIS)<<8)+row)<<16)+ncl;
1445 tpcrow->InsertCluster(c,index);
1448 // write indexes for fast acces
1450 for (Int_t i=0;i<510;i++)
1451 tpcrow->SetFastCluster(i,-1);
1452 for (Int_t i=0;i<tpcrow->GetN();i++){
1453 Int_t zi = Int_t((*tpcrow)[i]->GetZ()+255.);
1454 tpcrow->SetFastCluster(zi,i); // write index
1457 for (Int_t i=0;i<510;i++){
1458 if (tpcrow->GetFastCluster(i)<0)
1459 tpcrow->SetFastCluster(i,last);
1461 last = tpcrow->GetFastCluster(i);
1473 //_________________________________________________________________________
1474 AliTPCclusterMI *AliTPCtrackerMI::GetClusterMI(Int_t index) const {
1475 //--------------------------------------------------------------------
1476 // Return pointer to a given cluster
1477 //--------------------------------------------------------------------
1478 if (index<0) return 0; // no cluster
1479 Int_t sec=(index&0xff000000)>>24;
1480 Int_t row=(index&0x00ff0000)>>16;
1481 Int_t ncl=(index&0x00007fff)>>00;
1483 const AliTPCtrackerRow * tpcrow=0;
1484 AliTPCclusterMI * clrow =0;
1486 if (sec<0 || sec>=fkNIS*4) {
1487 AliWarning(Form("Wrong sector %d",sec));
1492 tpcrow = &(fInnerSec[sec%fkNIS][row]);
1493 if (tpcrow==0) return 0;
1496 if (tpcrow->GetN1()<=ncl) return 0;
1497 clrow = tpcrow->GetClusters1();
1500 if (tpcrow->GetN2()<=ncl) return 0;
1501 clrow = tpcrow->GetClusters2();
1505 tpcrow = &(fOuterSec[(sec-fkNIS*2)%fkNOS][row]);
1506 if (tpcrow==0) return 0;
1508 if (sec-2*fkNIS<fkNOS) {
1509 if (tpcrow->GetN1()<=ncl) return 0;
1510 clrow = tpcrow->GetClusters1();
1513 if (tpcrow->GetN2()<=ncl) return 0;
1514 clrow = tpcrow->GetClusters2();
1518 return &(clrow[ncl]);
1524 Int_t AliTPCtrackerMI::FollowToNext(AliTPCseed& t, Int_t nr) {
1525 //-----------------------------------------------------------------
1526 // This function tries to find a track prolongation to next pad row
1527 //-----------------------------------------------------------------
1529 Double_t x= GetXrow(nr), ymax=GetMaxY(nr);
1530 AliTPCclusterMI *cl=0;
1531 Int_t tpcindex= t.GetClusterIndex2(nr);
1533 // update current shape info every 5 pad-row
1534 // if ( (nr%5==0) || t.GetNumberOfClusters()<2 || (t.fCurrentSigmaY2<0.0001) ){
1538 if (fIteration>0 && tpcindex>=-1){ //if we have already clusters
1540 if (tpcindex==-1) return 0; //track in dead zone
1542 cl = t.GetClusterPointer(nr);
1543 if ( (cl==0) ) cl = GetClusterMI(tpcindex);
1544 t.SetCurrentClusterIndex1(tpcindex);
1547 Int_t relativesector = ((tpcindex&0xff000000)>>24)%18; // if previously accepted cluster in different sector
1548 Float_t angle = relativesector*fSectors->GetAlpha()+fSectors->GetAlphaShift();
1550 if (angle<-TMath::Pi()) angle += 2*TMath::Pi();
1551 if (angle>=TMath::Pi()) angle -= 2*TMath::Pi();
1553 if (TMath::Abs(angle-t.GetAlpha())>0.001){
1554 Double_t rotation = angle-t.GetAlpha();
1555 t.SetRelativeSector(relativesector);
1556 if (!t.Rotate(rotation)) return 0;
1558 if (!t.PropagateTo(x)) return 0;
1560 t.SetCurrentCluster(cl);
1562 Int_t accept = AcceptCluster(&t,t.GetCurrentCluster());
1563 if ((tpcindex&0x8000)==0) accept =0;
1565 //if founded cluster is acceptible
1566 if (cl->IsUsed(11)) { // id cluster is shared inrease uncertainty
1567 t.SetErrorY2(t.GetErrorY2()+0.03);
1568 t.SetErrorZ2(t.GetErrorZ2()+0.03);
1569 t.SetErrorY2(t.GetErrorY2()*3);
1570 t.SetErrorZ2(t.GetErrorZ2()*3);
1572 t.SetNFoundable(t.GetNFoundable()+1);
1573 UpdateTrack(&t,accept);
1578 if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()) return 0; // cut on angle
1580 // not look for new cluster during refitting
1581 t.SetNFoundable(t.GetNFoundable()+1);
1586 // if (TMath::Abs(t.GetSnp())>0.95 || TMath::Abs(x*t.GetC()-t.GetEta())>0.95) return 0;// patch 28 fev 06
1587 Double_t y=t.GetYat(x);
1588 if (TMath::Abs(y)>ymax){
1590 t.SetRelativeSector((t.GetRelativeSector()+1) % fN);
1591 if (!t.Rotate(fSectors->GetAlpha()))
1593 } else if (y <-ymax) {
1594 t.SetRelativeSector((t.GetRelativeSector()-1+fN) % fN);
1595 if (!t.Rotate(-fSectors->GetAlpha()))
1601 if (!t.PropagateTo(x)) {
1602 if (fIteration==0) t.SetRemoval(10);
1606 Double_t z=t.GetZ();
1609 if (!IsActive(t.GetRelativeSector(),nr)) {
1611 t.SetClusterIndex2(nr,-1);
1614 //AliInfo(Form("A - Sector%d phi %f - alpha %f", t.fRelativeSector,y/x, t.GetAlpha()));
1615 Bool_t isActive = IsActive(t.GetRelativeSector(),nr);
1616 Bool_t isActive2 = (nr>=fInnerSec->GetNRows()) ? fOuterSec[t.GetRelativeSector()][nr-fInnerSec->GetNRows()].GetN()>0:fInnerSec[t.GetRelativeSector()][nr].GetN()>0;
1618 if (!isActive || !isActive2) return 0;
1620 const AliTPCtrackerRow &krow=GetRow(t.GetRelativeSector(),nr);
1621 if ( (t.GetSigmaY2()<0) || t.GetSigmaZ2()<0) return 0;
1623 Double_t roadz = 1.;
1625 if (TMath::Abs(TMath::Abs(y)-ymax)<krow.GetDeadZone()){
1627 t.SetClusterIndex2(nr,-1);
1632 if (TMath::Abs(z)<(AliTPCReconstructor::GetCtgRange()*x+10) && TMath::Abs(z)<fParam->GetZLength(0) && (TMath::Abs(t.GetSnp())<AliTPCReconstructor::GetMaxSnpTracker()))
1633 t.SetNFoundable(t.GetNFoundable()+1);
1639 // cl = krow.FindNearest2(y+10.,z,roady,roadz,index);
1640 cl = krow.FindNearest2(y,z,roady,roadz,index);
1641 if (cl) t.SetCurrentClusterIndex1(krow.GetIndex(index));
1644 t.SetCurrentCluster(cl);
1646 if (fIteration==2&&cl->IsUsed(10)) return 0;
1647 Int_t accept = AcceptCluster(&t,t.GetCurrentCluster());
1648 if (fIteration==2&&cl->IsUsed(11)) {
1649 t.SetErrorY2(t.GetErrorY2()+0.03);
1650 t.SetErrorZ2(t.GetErrorZ2()+0.03);
1651 t.SetErrorY2(t.GetErrorY2()*3);
1652 t.SetErrorZ2(t.GetErrorZ2()*3);
1655 if (t.fCurrentCluster->IsUsed(10)){
1660 if (t.fNShared>0.7*t.GetNumberOfClusters()) {
1666 if (accept<3) UpdateTrack(&t,accept);
1669 if ( fIteration==0 && t.GetNFoundable()*0.5 > t.GetNumberOfClusters()) t.SetRemoval(10);
1675 Int_t AliTPCtrackerMI::FollowToNextFast(AliTPCseed& t, Int_t nr) {
1676 //-----------------------------------------------------------------
1677 // This function tries to find a track prolongation to next pad row
1678 //-----------------------------------------------------------------
1680 Double_t x= GetXrow(nr), ymax=GetMaxY(nr);
1682 if (!t.GetProlongation(x,y,z)) {
1688 if (TMath::Abs(y)>ymax){
1691 t.SetRelativeSector((t.GetRelativeSector()+1) % fN);
1692 if (!t.Rotate(fSectors->GetAlpha()))
1694 } else if (y <-ymax) {
1695 t.SetRelativeSector((t.GetRelativeSector()-1+fN) % fN);
1696 if (!t.Rotate(-fSectors->GetAlpha()))
1699 if (!t.PropagateTo(x)) {
1702 t.GetProlongation(x,y,z);
1705 // update current shape info every 2 pad-row
1706 if ( (nr%2==0) || t.GetNumberOfClusters()<2 || (t.GetCurrentSigmaY2()<0.0001) ){
1707 // t.fCurrentSigmaY = GetSigmaY(&t);
1708 //t.fCurrentSigmaZ = GetSigmaZ(&t);
1712 AliTPCclusterMI *cl=0;
1717 const AliTPCtrackerRow &krow=GetRow(t.GetRelativeSector(),nr);
1718 if ( (t.GetSigmaY2()<0) || t.GetSigmaZ2()<0) return 0;
1720 Double_t roadz = 1.;
1723 if (TMath::Abs(TMath::Abs(y)-ymax)<krow.GetDeadZone()){
1725 t.SetClusterIndex2(row,-1);
1730 if (TMath::Abs(z)>(AliTPCReconstructor::GetCtgRange()*x+10)) t.SetClusterIndex2(row,-1);
1734 if ((cl==0)&&(krow)) {
1735 // cl = krow.FindNearest2(y+10,z,roady,roadz,index);
1736 cl = krow.FindNearest2(y,z,roady,roadz,index);
1738 if (cl) t.SetCurrentClusterIndex1(krow.GetIndex(index));
1742 t.SetCurrentCluster(cl);
1743 // Int_t accept = AcceptCluster(&t,t.fCurrentCluster);
1745 t.SetClusterIndex2(row,index);
1746 t.SetClusterPointer(row, cl);
1754 //_________________________________________________________________________
1755 Bool_t AliTPCtrackerMI::GetTrackPoint(Int_t index, AliTrackPoint &p ) const
1757 // Get track space point by index
1758 // return false in case the cluster doesn't exist
1759 AliTPCclusterMI *cl = GetClusterMI(index);
1760 if (!cl) return kFALSE;
1761 Int_t sector = (index&0xff000000)>>24;
1762 // Int_t row = (index&0x00ff0000)>>16;
1764 // xyz[0] = fParam->GetPadRowRadii(sector,row);
1765 xyz[0] = cl->GetX();
1766 xyz[1] = cl->GetY();
1767 xyz[2] = cl->GetZ();
1769 fParam->AdjustCosSin(sector,cos,sin);
1770 Float_t x = cos*xyz[0]-sin*xyz[1];
1771 Float_t y = cos*xyz[1]+sin*xyz[0];
1773 Float_t sigmaY2 = 0.027*cl->GetSigmaY2();
1774 if (sector < fParam->GetNInnerSector()) sigmaY2 *= 2.07;
1775 Float_t sigmaZ2 = 0.066*cl->GetSigmaZ2();
1776 if (sector < fParam->GetNInnerSector()) sigmaZ2 *= 1.77;
1777 cov[0] = sin*sin*sigmaY2;
1778 cov[1] = -sin*cos*sigmaY2;
1780 cov[3] = cos*cos*sigmaY2;
1783 p.SetXYZ(x,y,xyz[2],cov);
1784 AliGeomManager::ELayerID iLayer;
1786 if (sector < fParam->GetNInnerSector()) {
1787 iLayer = AliGeomManager::kTPC1;
1791 iLayer = AliGeomManager::kTPC2;
1792 idet = sector - fParam->GetNInnerSector();
1794 UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
1795 p.SetVolumeID(volid);
1801 Int_t AliTPCtrackerMI::UpdateClusters(AliTPCseed& t, Int_t nr) {
1802 //-----------------------------------------------------------------
1803 // This function tries to find a track prolongation to next pad row
1804 //-----------------------------------------------------------------
1805 t.SetCurrentCluster(0);
1806 t.SetCurrentClusterIndex1(0);
1808 Double_t xt=t.GetX();
1809 Int_t row = GetRowNumber(xt)-1;
1810 Double_t ymax= GetMaxY(nr);
1812 if (row < nr) return 1; // don't prolongate if not information until now -
1813 // if (TMath::Abs(t.GetSnp())>0.9 && t.GetNumberOfClusters()>40. && fIteration!=2) {
1815 // return 0; // not prolongate strongly inclined tracks
1817 // if (TMath::Abs(t.GetSnp())>0.95) {
1819 // return 0; // not prolongate strongly inclined tracks
1820 // }// patch 28 fev 06
1822 Double_t x= GetXrow(nr);
1824 //t.PropagateTo(x+0.02);
1825 //t.PropagateTo(x+0.01);
1826 if (!t.PropagateTo(x)){
1833 if (TMath::Abs(y)>ymax){
1835 t.SetRelativeSector((t.GetRelativeSector()+1) % fN);
1836 if (!t.Rotate(fSectors->GetAlpha()))
1838 } else if (y <-ymax) {
1839 t.SetRelativeSector((t.GetRelativeSector()-1+fN) % fN);
1840 if (!t.Rotate(-fSectors->GetAlpha()))
1843 // if (!t.PropagateTo(x)){
1850 if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()) return 0;
1852 if (!IsActive(t.GetRelativeSector(),nr)) {
1854 t.SetClusterIndex2(nr,-1);
1857 //AliInfo(Form("A - Sector%d phi %f - alpha %f", t.fRelativeSector,y/x, t.GetAlpha()));
1859 AliTPCtrackerRow &krow=GetRow(t.GetRelativeSector(),nr);
1861 if (TMath::Abs(TMath::Abs(y)-ymax)<krow.GetDeadZone()){
1863 t.SetClusterIndex2(nr,-1);
1868 if (TMath::Abs(t.GetZ())<(AliTPCReconstructor::GetCtgRange()*t.GetX()+10) && (TMath::Abs(t.GetSnp())<AliTPCReconstructor::GetMaxSnpTracker())) t.SetNFoundable(t.GetNFoundable()+1);
1874 if ( (nr%2==0) || t.GetNumberOfClusters()<2){
1875 // t.fCurrentSigmaY = GetSigmaY(&t);
1876 //t.fCurrentSigmaZ = GetSigmaZ(&t);
1880 AliTPCclusterMI *cl=0;
1883 Double_t roady = 1.;
1884 Double_t roadz = 1.;
1888 index = t.GetClusterIndex2(nr);
1889 if ( (index>0) && (index&0x8000)==0){
1890 cl = t.GetClusterPointer(nr);
1891 if ( (cl==0) && (index>0)) cl = GetClusterMI(index);
1892 t.SetCurrentClusterIndex1(index);
1894 t.SetCurrentCluster(cl);
1900 // if (index<0) return 0;
1901 UInt_t uindex = TMath::Abs(index);
1904 //cl = krow.FindNearest2(y+10,z,roady,roadz,uindex);
1905 cl = krow.FindNearest2(y,z,roady,roadz,uindex);
1908 if (cl) t.SetCurrentClusterIndex1(krow.GetIndex(uindex));
1909 t.SetCurrentCluster(cl);
1915 Int_t AliTPCtrackerMI::FollowToNextCluster(AliTPCseed & t, Int_t nr) {
1916 //-----------------------------------------------------------------
1917 // This function tries to find a track prolongation to next pad row
1918 //-----------------------------------------------------------------
1920 //update error according neighborhoud
1922 if (t.GetCurrentCluster()) {
1924 Int_t accept = AcceptCluster(&t,t.GetCurrentCluster());
1926 if (t.GetCurrentCluster()->IsUsed(10)){
1931 t.SetNShared(t.GetNShared()+1);
1932 if (t.GetNShared()>0.7*t.GetNumberOfClusters()) {
1937 if (fIteration>0) accept = 0;
1938 if (accept<3) UpdateTrack(&t,accept);
1942 if ( ( (t.GetSigmaY2()+t.GetSigmaZ2())>0.16)&& t.GetNumberOfClusters()>18) t.SetRemoval(10);
1943 if ( t.GetChi2()/t.GetNumberOfClusters()>6 &&t.GetNumberOfClusters()>18) t.SetRemoval(10);
1945 if (( (t.GetNFoundable()*0.5 > t.GetNumberOfClusters()) || t.GetNoCluster()>15)) t.SetRemoval(10);
1953 //_____________________________________________________________________________
1954 Int_t AliTPCtrackerMI::FollowProlongation(AliTPCseed& t, Int_t rf, Int_t step) {
1955 //-----------------------------------------------------------------
1956 // This function tries to find a track prolongation.
1957 //-----------------------------------------------------------------
1958 Double_t xt=t.GetX();
1960 Double_t alpha=t.GetAlpha() - fSectors->GetAlphaShift();
1961 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
1962 if (alpha < 0. ) alpha += 2.*TMath::Pi();
1964 t.SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
1966 Int_t first = GetRowNumber(xt)-1;
1967 for (Int_t nr= first; nr>=rf; nr-=step) {
1969 if (t.GetKinkIndexes()[0]>0){
1970 for (Int_t i=0;i<3;i++){
1971 Int_t index = t.GetKinkIndexes()[i];
1972 if (index==0) break;
1973 if (index<0) continue;
1975 AliKink * kink = (AliKink*)fEvent->GetKink(index-1);
1977 printf("PROBLEM\n");
1980 Int_t kinkrow = kink->GetTPCRow0()+2+Int_t(0.5/(0.05+kink->GetAngle(2)));
1982 AliExternalTrackParam paramd(t);
1983 kink->SetDaughter(paramd);
1984 kink->SetStatus(2,5);
1991 if (nr==80) t.UpdateReference();
1992 if (nr<fInnerSec->GetNRows())
1993 fSectors = fInnerSec;
1995 fSectors = fOuterSec;
1996 if (FollowToNext(t,nr)==0)
2005 //_____________________________________________________________________________
2006 Int_t AliTPCtrackerMI::FollowProlongationFast(AliTPCseed& t, Int_t rf, Int_t step) {
2007 //-----------------------------------------------------------------
2008 // This function tries to find a track prolongation.
2009 //-----------------------------------------------------------------
2010 Double_t xt=t.GetX();
2012 Double_t alpha=t.GetAlpha() - fSectors->GetAlphaShift();
2013 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
2014 if (alpha < 0. ) alpha += 2.*TMath::Pi();
2015 t.SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
2017 for (Int_t nr=GetRowNumber(xt)-1; nr>=rf; nr-=step) {
2019 if (FollowToNextFast(t,nr)==0)
2020 if (!t.IsActive()) return 0;
2030 Int_t AliTPCtrackerMI::FollowBackProlongation(AliTPCseed& t, Int_t rf) {
2031 //-----------------------------------------------------------------
2032 // This function tries to find a track prolongation.
2033 //-----------------------------------------------------------------
2035 Double_t xt=t.GetX();
2036 Double_t alpha=t.GetAlpha() - fSectors->GetAlphaShift();
2037 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
2038 if (alpha < 0. ) alpha += 2.*TMath::Pi();
2039 t.SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
2041 Int_t first = t.GetFirstPoint();
2042 if (first<GetRowNumber(xt)+1) first = GetRowNumber(xt)+1;
2044 if (first<0) first=0;
2045 for (Int_t nr=first; nr<=rf; nr++) {
2046 // if ( (TMath::Abs(t.GetSnp())>0.95)) break;//patch 28 fev 06
2047 if (t.GetKinkIndexes()[0]<0){
2048 for (Int_t i=0;i<3;i++){
2049 Int_t index = t.GetKinkIndexes()[i];
2050 if (index==0) break;
2051 if (index>0) continue;
2052 index = TMath::Abs(index);
2053 AliKink * kink = (AliKink*)fEvent->GetKink(index-1);
2055 printf("PROBLEM\n");
2058 Int_t kinkrow = kink->GetTPCRow0()-2-Int_t(0.5/(0.05+kink->GetAngle(2)));
2060 AliExternalTrackParam paramm(t);
2061 kink->SetMother(paramm);
2062 kink->SetStatus(2,1);
2069 if (nr<fInnerSec->GetNRows())
2070 fSectors = fInnerSec;
2072 fSectors = fOuterSec;
2083 Float_t AliTPCtrackerMI::OverlapFactor(AliTPCseed * s1, AliTPCseed * s2, Int_t &sum1, Int_t & sum2)
2091 Float_t dz2 =(s1->GetZ() - s2->GetZ());
2094 Float_t dy2 =TMath::Abs((s1->GetY() - s2->GetY()));
2096 Float_t distance = TMath::Sqrt(dz2+dy2);
2097 if (distance>4.) return 0; // if there are far away - not overlap - to reduce combinatorics
2100 Int_t firstpoint = TMath::Min(s1->GetFirstPoint(),s2->GetFirstPoint());
2101 Int_t lastpoint = TMath::Max(s1->GetLastPoint(),s2->GetLastPoint());
2106 if (firstpoint>lastpoint) {
2107 firstpoint =lastpoint;
2112 for (Int_t i=firstpoint-1;i<lastpoint+1;i++){
2113 if (s1->GetClusterIndex2(i)>0) sum1++;
2114 if (s2->GetClusterIndex2(i)>0) sum2++;
2115 if (s1->GetClusterIndex2(i)==s2->GetClusterIndex2(i) && s1->GetClusterIndex2(i)>0) {
2119 if (sum<5) return 0;
2121 Float_t summin = TMath::Min(sum1+1,sum2+1);
2122 Float_t ratio = (sum+1)/Float_t(summin);
2126 void AliTPCtrackerMI::SignShared(AliTPCseed * s1, AliTPCseed * s2)
2130 Float_t thetaCut = 0.2;//+10.*TMath::Sqrt(s1->GetSigmaTglZ()+ s2->GetSigmaTglZ());
2131 if (TMath::Abs(s1->GetTgl()-s2->GetTgl())>thetaCut) return;
2132 Float_t minCl = TMath::Min(s1->GetNumberOfClusters(),s2->GetNumberOfClusters());
2133 Int_t cutN0 = TMath::Max(5,TMath::Nint(0.1*minCl));
2138 //Int_t firstpoint = TMath::Max(s1->GetFirstPoint(),s2->GetFirstPoint());
2139 //Int_t lastpoint = TMath::Min(s1->GetLastPoint(),s2->GetLastPoint());
2140 Int_t firstpoint = 0;
2141 Int_t lastpoint = 160;
2143 // if (firstpoint>=lastpoint-5) return;;
2145 for (Int_t i=firstpoint;i<lastpoint;i++){
2146 // if ( (s1->GetClusterIndex2(i)&0xFFFF8FFF)==(s2->GetClusterIndex2(i)&0xFFFF8FFF) && s1->GetClusterIndex2(i)>0) {
2147 if ( (s1->GetClusterIndex2(i))==(s2->GetClusterIndex2(i)) && s1->GetClusterIndex2(i)>0) {
2149 s1->SetSharedMapBit(i, kTRUE);
2150 s2->SetSharedMapBit(i, kTRUE);
2152 if (s1->GetClusterIndex2(i)>0)
2153 s1->SetClusterMapBit(i, kTRUE);
2155 if (sumshared>cutN0){
2158 for (Int_t i=firstpoint;i<lastpoint;i++){
2159 // if ( (s1->GetClusterIndex2(i)&0xFFFF8FFF)==(s2->GetClusterIndex2(i)&0xFFFF8FFF) && s1->GetClusterIndex2(i)>0) {
2160 if ( (s1->GetClusterIndex2(i))==(s2->GetClusterIndex2(i)) && s1->GetClusterIndex2(i)>0) {
2161 AliTPCTrackerPoint *p1 = s1->GetTrackPoint(i);
2162 AliTPCTrackerPoint *p2 = s2->GetTrackPoint(i);;
2163 if (s1->IsActive()&&s2->IsActive()){
2164 p1->SetShared(kTRUE);
2165 p2->SetShared(kTRUE);
2171 if (sumshared>cutN0){
2172 for (Int_t i=0;i<4;i++){
2173 if (s1->GetOverlapLabel(3*i)==0){
2174 s1->SetOverlapLabel(3*i, s2->GetLabel());
2175 s1->SetOverlapLabel(3*i+1,sumshared);
2176 s1->SetOverlapLabel(3*i+2,s2->GetUniqueID());
2180 for (Int_t i=0;i<4;i++){
2181 if (s2->GetOverlapLabel(3*i)==0){
2182 s2->SetOverlapLabel(3*i, s1->GetLabel());
2183 s2->SetOverlapLabel(3*i+1,sumshared);
2184 s2->SetOverlapLabel(3*i+2,s1->GetUniqueID());
2191 void AliTPCtrackerMI::SignShared(TObjArray * arr)
2194 //sort trackss according sectors
2196 for (Int_t i=0; i<arr->GetEntriesFast(); i++) {
2197 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2199 //if (pt) RotateToLocal(pt);
2203 arr->Sort(); // sorting according relative sectors
2204 arr->Expand(arr->GetEntries());
2207 Int_t nseed=arr->GetEntriesFast();
2208 for (Int_t i=0; i<nseed; i++) {
2209 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2211 for (Int_t j=0;j<=12;j++){
2212 pt->SetOverlapLabel(j,0);
2215 for (Int_t i=0; i<nseed; i++) {
2216 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2218 if (pt->GetRemoval()>10) continue;
2219 for (Int_t j=i+1; j<nseed; j++){
2220 AliTPCseed *pt2=(AliTPCseed*)arr->UncheckedAt(j);
2221 if (TMath::Abs(pt->GetRelativeSector()-pt2->GetRelativeSector())>1) continue;
2223 if (pt2->GetRemoval()<=10) {
2224 //if ( TMath::Abs(pt->GetRelativeSector()-pt2->GetRelativeSector())>0) break;
2232 void AliTPCtrackerMI::SortTracks(TObjArray * arr, Int_t mode) const
2235 //sort tracks in array according mode criteria
2236 Int_t nseed = arr->GetEntriesFast();
2237 for (Int_t i=0; i<nseed; i++) {
2238 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2249 void AliTPCtrackerMI::RemoveUsed2(TObjArray * arr, Float_t factor1, Float_t factor2, Int_t minimal)
2252 // Loop over all tracks and remove overlaped tracks (with lower quality)
2254 // 1. Unsign clusters
2255 // 2. Sort tracks according quality
2256 // Quality is defined by the number of cluster between first and last points
2258 // 3. Loop over tracks - decreasing quality order
2259 // a.) remove - If the fraction of shared cluster less than factor (1- n or 2)
2260 // b.) remove - If the minimal number of clusters less than minimal and not ITS
2261 // c.) if track accepted - sign clusters
2263 //Called in - AliTPCtrackerMI::Clusters2Tracks()
2264 // - AliTPCtrackerMI::PropagateBack()
2265 // - AliTPCtrackerMI::RefitInward()
2271 Int_t nseed = arr->GetEntriesFast();
2272 Float_t * quality = new Float_t[nseed];
2273 Int_t * indexes = new Int_t[nseed];
2277 for (Int_t i=0; i<nseed; i++) {
2278 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2283 pt->UpdatePoints(); //select first last max dens points
2284 Float_t * points = pt->GetPoints();
2285 if (points[3]<0.8) quality[i] =-1;
2286 quality[i] = (points[2]-points[0])+pt->GetNumberOfClusters();
2287 //prefer high momenta tracks if overlaps
2288 quality[i] *= TMath::Sqrt(TMath::Abs(pt->Pt())+0.5);
2290 TMath::Sort(nseed,quality,indexes);
2293 for (Int_t itrack=0; itrack<nseed; itrack++) {
2294 Int_t trackindex = indexes[itrack];
2295 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(trackindex);
2298 if (quality[trackindex]<0){
2300 delete arr->RemoveAt(trackindex);
2303 arr->RemoveAt(trackindex);
2309 Int_t first = Int_t(pt->GetPoints()[0]);
2310 Int_t last = Int_t(pt->GetPoints()[2]);
2311 Double_t factor = (pt->GetBConstrain()) ? factor1: factor2;
2313 Int_t found,foundable,shared;
2314 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
2315 // pt->GetClusterStatistic(0,160, found, foundable,shared,kFALSE);
2316 Bool_t itsgold =kFALSE;
2319 if (pt->GetESD()->GetITSclusters(dummy)>4) itsgold= kTRUE;
2323 if (Float_t(shared+1)/Float_t(found+1)>factor){
2324 if (pt->GetKinkIndexes()[0]!=0) continue; //don't remove tracks - part of the kinks
2325 delete arr->RemoveAt(trackindex);
2328 if (pt->GetNumberOfClusters()<50&&(found-0.5*shared)<minimal){ //remove short tracks
2329 if (pt->GetKinkIndexes()[0]!=0) continue; //don't remove tracks - part of the kinks
2330 delete arr->RemoveAt(trackindex);
2336 //if (sharedfactor>0.4) continue;
2337 if (pt->GetKinkIndexes()[0]>0) continue;
2338 //Remove tracks with undefined properties - seems
2339 if (pt->GetSigmaY2()<kAlmost0) continue; // ? what is the origin ?
2341 for (Int_t i=first; i<last; i++) {
2342 Int_t index=pt->GetClusterIndex2(i);
2343 // if (index<0 || index&0x8000 ) continue;
2344 if (index<0 || index&0x8000 ) continue;
2345 AliTPCclusterMI *c= pt->GetClusterPointer(i);
2352 Info("RemoveUsed","\n*****\nNumber of good tracks after shared removal\t%d\n",fNtracks);
2358 void AliTPCtrackerMI::UnsignClusters()
2361 // loop over all clusters and unsign them
2364 for (Int_t sec=0;sec<fkNIS;sec++){
2365 for (Int_t row=0;row<fInnerSec->GetNRows();row++){
2366 AliTPCclusterMI *cl = fInnerSec[sec][row].GetClusters1();
2367 for (Int_t icl =0;icl< fInnerSec[sec][row].GetN1();icl++)
2368 // if (cl[icl].IsUsed(10))
2370 cl = fInnerSec[sec][row].GetClusters2();
2371 for (Int_t icl =0;icl< fInnerSec[sec][row].GetN2();icl++)
2372 //if (cl[icl].IsUsed(10))
2377 for (Int_t sec=0;sec<fkNOS;sec++){
2378 for (Int_t row=0;row<fOuterSec->GetNRows();row++){
2379 AliTPCclusterMI *cl = fOuterSec[sec][row].GetClusters1();
2380 for (Int_t icl =0;icl< fOuterSec[sec][row].GetN1();icl++)
2381 //if (cl[icl].IsUsed(10))
2383 cl = fOuterSec[sec][row].GetClusters2();
2384 for (Int_t icl =0;icl< fOuterSec[sec][row].GetN2();icl++)
2385 //if (cl[icl].IsUsed(10))
2394 void AliTPCtrackerMI::SignClusters(TObjArray * arr, Float_t fnumber, Float_t fdensity)
2397 //sign clusters to be "used"
2399 // snumber and sdensity sign number of sigmas - bellow mean value to be accepted
2400 // loop over "primaries"
2414 Int_t nseed = arr->GetEntriesFast();
2415 for (Int_t i=0; i<nseed; i++) {
2416 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2420 if (!(pt->IsActive())) continue;
2421 Float_t dens = pt->GetNumberOfClusters()/Float_t(pt->GetNFoundable());
2422 if ( (dens>0.7) && (pt->GetNumberOfClusters()>70)){
2424 sumdens2+= dens*dens;
2425 sumn += pt->GetNumberOfClusters();
2426 sumn2 += pt->GetNumberOfClusters()*pt->GetNumberOfClusters();
2427 Float_t chi2 = pt->GetChi2()/pt->GetNumberOfClusters();
2430 sumchi2 +=chi2*chi2;
2435 Float_t mdensity = 0.9;
2436 Float_t meann = 130;
2437 Float_t meanchi = 1;
2438 Float_t sdensity = 0.1;
2439 Float_t smeann = 10;
2440 Float_t smeanchi =0.4;
2444 mdensity = sumdens/sum;
2446 meanchi = sumchi/sum;
2448 sdensity = sumdens2/sum-mdensity*mdensity;
2450 sdensity = TMath::Sqrt(sdensity);
2454 smeann = sumn2/sum-meann*meann;
2456 smeann = TMath::Sqrt(smeann);
2460 smeanchi = sumchi2/sum - meanchi*meanchi;
2462 smeanchi = TMath::Sqrt(smeanchi);
2468 //REMOVE SHORT DELTAS or tracks going out of sensitive volume of TPC
2470 for (Int_t i=0; i<nseed; i++) {
2471 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2475 if (pt->GetBSigned()) continue;
2476 if (pt->GetBConstrain()) continue;
2477 //if (!(pt->IsActive())) continue;
2479 Int_t found,foundable,shared;
2480 pt->GetClusterStatistic(0,160,found, foundable,shared);
2481 if (shared/float(found)>0.3) {
2482 if (shared/float(found)>0.9 ){
2483 //delete arr->RemoveAt(i);
2488 Bool_t isok =kFALSE;
2489 if ( (pt->GetNShared()/pt->GetNumberOfClusters()<0.5) &&pt->GetNumberOfClusters()>60)
2491 if ((TMath::Abs(1/pt->GetC())<100.) && (pt->GetNShared()/pt->GetNumberOfClusters()<0.7))
2493 if (TMath::Abs(pt->GetZ()/pt->GetX())>1.1)
2495 if ( (TMath::Abs(pt->GetSnp()>0.7) && pt->GetD(0,0)>60.))
2499 for (Int_t i=0; i<160; i++) {
2500 Int_t index=pt->GetClusterIndex2(i);
2501 if (index<0) continue;
2502 AliTPCclusterMI *c= pt->GetClusterPointer(i);
2504 //if (!(c->IsUsed(10))) c->Use();
2511 Double_t maxchi = meanchi+2.*smeanchi;
2513 for (Int_t i=0; i<nseed; i++) {
2514 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2518 //if (!(pt->IsActive())) continue;
2519 if (pt->GetBSigned()) continue;
2520 Double_t chi = pt->GetChi2()/pt->GetNumberOfClusters();
2521 if (chi>maxchi) continue;
2524 Float_t dens = pt->GetNumberOfClusters()/Float_t(pt->GetNFoundable());
2526 //sign only tracks with enoug big density at the beginning
2528 if ((pt->GetDensityFirst(40)<0.75) && pt->GetNumberOfClusters()<meann) continue;
2531 Double_t mindens = TMath::Max(double(mdensity-sdensity*fdensity*bfactor),0.65);
2532 Double_t minn = TMath::Max(Int_t(meann-fnumber*smeann*bfactor),50);
2534 // if (pt->fBConstrain) mindens = TMath::Max(mdensity-sdensity*fdensity*bfactor,0.65);
2535 if ( (pt->GetRemoval()==10) && (pt->GetSnp()>0.8)&&(dens>mindens))
2538 if ((dens>mindens && pt->GetNumberOfClusters()>minn) && chi<maxchi ){
2539 //Int_t noc=pt->GetNumberOfClusters();
2540 pt->SetBSigned(kTRUE);
2541 for (Int_t i=0; i<160; i++) {
2543 Int_t index=pt->GetClusterIndex2(i);
2544 if (index<0) continue;
2545 AliTPCclusterMI *c= pt->GetClusterPointer(i);
2547 // if (!(c->IsUsed(10))) c->Use();
2552 // gLastCheck = nseed;
2560 void AliTPCtrackerMI::StopNotActive(TObjArray * arr, Int_t row0, Float_t th0, Float_t th1, Float_t th2) const
2562 // stop not active tracks
2563 // take th1 as threshold for number of founded to number of foundable on last 10 active rows
2564 // take th2 as threshold for number of founded to number of foundable on last 20 active rows
2565 Int_t nseed = arr->GetEntriesFast();
2567 for (Int_t i=0; i<nseed; i++) {
2568 AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);
2572 if (!(pt->IsActive())) continue;
2573 StopNotActive(pt,row0,th0, th1,th2);
2579 void AliTPCtrackerMI::StopNotActive(AliTPCseed * seed, Int_t row0, Float_t th0, Float_t th1,
2582 // stop not active tracks
2583 // take th1 as threshold for number of founded to number of foundable on last 10 active rows
2584 // take th2 as threshold for number of founded to number of foundable on last 20 active rows
2587 Int_t foundable = 0;
2588 Int_t maxindex = seed->GetLastPoint(); //last foundable row
2589 if (seed->GetNFoundable()*th0 > seed->GetNumberOfClusters()) {
2590 seed->Desactivate(10) ;
2594 for (Int_t i=row0; i<maxindex; i++){
2595 Int_t index = seed->GetClusterIndex2(i);
2596 if (index!=-1) foundable++;
2598 if (foundable<=30) sumgood1++;
2599 if (foundable<=50) {
2606 if (foundable>=30.){
2607 if (sumgood1<(th1*30.)) seed->Desactivate(10);
2610 if (sumgood2<(th2*50.)) seed->Desactivate(10);
2614 Int_t AliTPCtrackerMI::RefitInward(AliESDEvent *event)
2617 // back propagation of ESD tracks
2620 const Int_t kMaxFriendTracks=2000;
2624 //PrepareForProlongation(fSeeds,1);
2625 PropagateForward2(fSeeds);
2626 RemoveUsed2(fSeeds,0.4,0.4,20);
2628 TObjArray arraySeed(fSeeds->GetEntries());
2629 for (Int_t i=0;i<fSeeds->GetEntries();i++) {
2630 arraySeed.AddAt(fSeeds->At(i),i);
2632 SignShared(&arraySeed);
2633 // FindCurling(fSeeds, event,2); // find multi found tracks
2634 FindSplitted(fSeeds, event,2); // find multi found tracks
2637 Int_t nseed = fSeeds->GetEntriesFast();
2638 for (Int_t i=0;i<nseed;i++){
2639 AliTPCseed * seed = (AliTPCseed*) fSeeds->UncheckedAt(i);
2640 if (!seed) continue;
2641 if (seed->GetKinkIndex(0)>0) UpdateKinkQualityD(seed); // update quality informations for kinks
2643 seed->PropagateTo(fParam->GetInnerRadiusLow());
2644 seed->UpdatePoints();
2645 AddCovariance(seed);
2647 AliESDtrack *esd=event->GetTrack(i);
2648 seed->CookdEdx(0.02,0.6);
2649 CookLabel(seed,0.1); //For comparison only
2650 esd->SetTPCClusterMap(seed->GetClusterMap());
2651 esd->SetTPCSharedMap(seed->GetSharedMap());
2653 if (AliTPCReconstructor::StreamLevel()>1 && seed!=0&&esd!=0) {
2654 TTreeSRedirector &cstream = *fDebugStreamer;
2661 if (seed->GetNumberOfClusters()>15){
2662 esd->UpdateTrackParams(seed,AliESDtrack::kTPCrefit);
2663 esd->SetTPCPoints(seed->GetPoints());
2664 esd->SetTPCPointsF(seed->GetNFoundable());
2665 Int_t ndedx = seed->GetNCDEDX(0)+seed->GetNCDEDX(1)+seed->GetNCDEDX(2)+seed->GetNCDEDX(3);
2666 Float_t sdedx = (seed->GetSDEDX(0)+seed->GetSDEDX(1)+seed->GetSDEDX(2)+seed->GetSDEDX(3))*0.25;
2667 Float_t dedx = seed->GetdEdx();
2668 esd->SetTPCsignal(dedx, sdedx, ndedx);
2670 // add seed to the esd track in Calib level
2672 Bool_t storeFriend = gRandom->Rndm()<(kMaxFriendTracks)/Float_t(nseed);
2673 if (AliTPCReconstructor::StreamLevel()>0 &&storeFriend){
2674 AliTPCseed * seedCopy = new AliTPCseed(*seed, kTRUE);
2675 esd->AddCalibObject(seedCopy);
2680 //printf("problem\n");
2683 //FindKinks(fSeeds,event);
2684 Info("RefitInward","Number of refitted tracks %d",ntracks);
2689 Int_t AliTPCtrackerMI::PropagateBack(AliESDEvent *event)
2692 // back propagation of ESD tracks
2698 PropagateBack(fSeeds);
2699 RemoveUsed2(fSeeds,0.4,0.4,20);
2700 //FindCurling(fSeeds, fEvent,1);
2701 FindSplitted(fSeeds, event,1); // find multi found tracks
2704 Int_t nseed = fSeeds->GetEntriesFast();
2706 for (Int_t i=0;i<nseed;i++){
2707 AliTPCseed * seed = (AliTPCseed*) fSeeds->UncheckedAt(i);
2708 if (!seed) continue;
2709 if (seed->GetKinkIndex(0)<0) UpdateKinkQualityM(seed); // update quality informations for kinks
2710 seed->UpdatePoints();
2711 AddCovariance(seed);
2712 AliESDtrack *esd=event->GetTrack(i);
2713 seed->CookdEdx(0.02,0.6);
2714 CookLabel(seed,0.1); //For comparison only
2715 if (seed->GetNumberOfClusters()>15){
2716 esd->UpdateTrackParams(seed,AliESDtrack::kTPCout);
2717 esd->SetTPCPoints(seed->GetPoints());
2718 esd->SetTPCPointsF(seed->GetNFoundable());
2719 Int_t ndedx = seed->GetNCDEDX(0)+seed->GetNCDEDX(1)+seed->GetNCDEDX(2)+seed->GetNCDEDX(3);
2720 Float_t sdedx = (seed->GetSDEDX(0)+seed->GetSDEDX(1)+seed->GetSDEDX(2)+seed->GetSDEDX(3))*0.25;
2721 Float_t dedx = seed->GetdEdx();
2722 esd->SetTPCsignal(dedx, sdedx, ndedx);
2724 Int_t eventnumber = event->GetEventNumberInFile();// patch 28 fev 06
2725 // This is most likely NOT the event number you'd like to use. It has nothing to do with the 'real' event number
2726 if (AliTPCReconstructor::StreamLevel()>1 && esd) {
2727 (*fDebugStreamer)<<"Cback"<<
2730 "EventNrInFile="<<eventnumber<<
2735 //FindKinks(fSeeds,event);
2736 Info("PropagateBack","Number of back propagated tracks %d",ntracks);
2743 void AliTPCtrackerMI::DeleteSeeds()
2748 Int_t nseed = fSeeds->GetEntriesFast();
2749 for (Int_t i=0;i<nseed;i++){
2750 AliTPCseed * seed = (AliTPCseed*)fSeeds->At(i);
2751 if (seed) delete fSeeds->RemoveAt(i);
2758 void AliTPCtrackerMI::ReadSeeds(AliESDEvent *event, Int_t direction)
2761 //read seeds from the event
2763 Int_t nentr=event->GetNumberOfTracks();
2765 Info("ReadSeeds", "Number of ESD tracks: %d\n", nentr);
2770 fSeeds = new TObjArray(nentr);
2774 for (Int_t i=0; i<nentr; i++) {
2775 AliESDtrack *esd=event->GetTrack(i);
2776 ULong_t status=esd->GetStatus();
2777 if (!(status&AliESDtrack::kTPCin)) continue;
2778 AliTPCtrack t(*esd);
2779 t.SetNumberOfClusters(0);
2780 // AliTPCseed *seed = new AliTPCseed(t,t.GetAlpha());
2781 AliTPCseed *seed = new AliTPCseed(t/*,t.GetAlpha()*/);
2782 seed->SetUniqueID(esd->GetID());
2783 AddCovariance(seed); //add systematic ucertainty
2784 for (Int_t ikink=0;ikink<3;ikink++) {
2785 Int_t index = esd->GetKinkIndex(ikink);
2786 seed->GetKinkIndexes()[ikink] = index;
2787 if (index==0) continue;
2788 index = TMath::Abs(index);
2789 AliESDkink * kink = fEvent->GetKink(index-1);
2790 if (kink&&esd->GetKinkIndex(ikink)<0){
2791 if ((status & AliESDtrack::kTRDrefit) != 0) kink->SetStatus(1,2);
2792 if ((status & AliESDtrack::kITSout) != 0) kink->SetStatus(1,0);
2794 if (kink&&esd->GetKinkIndex(ikink)>0){
2795 if ((status & AliESDtrack::kTRDrefit) != 0) kink->SetStatus(1,6);
2796 if ((status & AliESDtrack::kITSout) != 0) kink->SetStatus(1,4);
2800 if (((status&AliESDtrack::kITSout)==0)&&(direction==1)) seed->ResetCovariance(10.);
2801 if ( direction ==2 &&(status & AliESDtrack::kTRDrefit) == 0 ) seed->ResetCovariance(10.);
2802 if ( direction ==2 && ((status & AliESDtrack::kTPCout) == 0) ) {
2807 if ( direction ==2 &&(status & AliESDtrack::kTRDrefit) > 0 ) {
2808 Double_t par0[5],par1[5],alpha,x;
2809 esd->GetInnerExternalParameters(alpha,x,par0);
2810 esd->GetExternalParameters(x,par1);
2811 Double_t delta1 = TMath::Abs(par0[4]-par1[4])/(0.000000001+TMath::Abs(par0[4]+par1[4]));
2812 Double_t delta2 = TMath::Abs(par0[3]-par1[3]);
2814 if (esd->GetTRDncls()>0) trdchi2 = esd->GetTRDchi2()/esd->GetTRDncls();
2815 //reset covariance if suspicious
2816 if ( (delta1>0.1) || (delta2>0.006) ||trdchi2>7.)
2817 seed->ResetCovariance(10.);
2822 // rotate to the local coordinate system
2824 fSectors=fInnerSec; fN=fkNIS;
2825 Double_t alpha=seed->GetAlpha() - fSectors->GetAlphaShift();
2826 if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
2827 if (alpha < 0. ) alpha += 2.*TMath::Pi();
2828 Int_t ns=Int_t(alpha/fSectors->GetAlpha())%fN;
2829 alpha =ns*fSectors->GetAlpha() + fSectors->GetAlphaShift();
2830 if (alpha<-TMath::Pi()) alpha += 2*TMath::Pi();
2831 if (alpha>=TMath::Pi()) alpha -= 2*TMath::Pi();
2832 alpha-=seed->GetAlpha();
2833 if (!seed->Rotate(alpha)) {
2839 if (esd->GetKinkIndex(0)<=0){
2840 for (Int_t irow=0;irow<160;irow++){
2841 Int_t index = seed->GetClusterIndex2(irow);
2844 AliTPCclusterMI * cl = GetClusterMI(index);
2845 seed->SetClusterPointer(irow,cl);
2847 if ((index & 0x8000)==0){
2848 cl->Use(10); // accepted cluster
2850 cl->Use(6); // close cluster not accepted
2853 Info("ReadSeeds","Not found cluster");
2858 fSeeds->AddAt(seed,i);
2864 //_____________________________________________________________________________
2865 void AliTPCtrackerMI::MakeSeeds3(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t cuts[4],
2866 Float_t deltay, Int_t ddsec) {
2867 //-----------------------------------------------------------------
2868 // This function creates track seeds.
2869 // SEEDING WITH VERTEX CONSTRAIN
2870 //-----------------------------------------------------------------
2871 // cuts[0] - fP4 cut
2872 // cuts[1] - tan(phi) cut
2873 // cuts[2] - zvertex cut
2874 // cuts[3] - fP3 cut
2882 Double_t x[5], c[15];
2883 // Int_t di = i1-i2;
2885 AliTPCseed * seed = new AliTPCseed();
2886 Double_t alpha=fSectors->GetAlpha(), shift=fSectors->GetAlphaShift();
2887 Double_t cs=cos(alpha), sn=sin(alpha);
2889 // Double_t x1 =fOuterSec->GetX(i1);
2890 //Double_t xx2=fOuterSec->GetX(i2);
2892 Double_t x1 =GetXrow(i1);
2893 Double_t xx2=GetXrow(i2);
2895 Double_t x3=GetX(), y3=GetY(), z3=GetZ();
2897 Int_t imiddle = (i2+i1)/2; //middle pad row index
2898 Double_t xm = GetXrow(imiddle); // radius of middle pad-row
2899 const AliTPCtrackerRow& krm=GetRow(sec,imiddle); //middle pad -row
2903 const AliTPCtrackerRow& kr1=GetRow(ns,i1);
2904 Double_t ymax = GetMaxY(i1)-kr1.GetDeadZone()-1.5;
2905 Double_t ymaxm = GetMaxY(imiddle)-kr1.GetDeadZone()-1.5;
2908 // change cut on curvature if it can't reach this layer
2909 // maximal curvature set to reach it
2910 Double_t dvertexmax = TMath::Sqrt((x1-x3)*(x1-x3)+(ymax+5-y3)*(ymax+5-y3));
2911 if (dvertexmax*0.5*cuts[0]>0.85){
2912 cuts[0] = 0.85/(dvertexmax*0.5+1.);
2914 Double_t r2min = 1/(cuts[0]*cuts[0]); //minimal square of radius given by cut
2917 if (deltay>0) ddsec = 0;
2918 // loop over clusters
2919 for (Int_t is=0; is < kr1; is++) {
2921 if (kr1[is]->IsUsed(10)) continue;
2922 Double_t y1=kr1[is]->GetY(), z1=kr1[is]->GetZ();
2923 //if (TMath::Abs(y1)>ymax) continue;
2925 if (deltay>0 && TMath::Abs(ymax-TMath::Abs(y1))> deltay ) continue; // seed only at the edge
2927 // find possible directions
2928 Float_t anglez = (z1-z3)/(x1-x3);
2929 Float_t extraz = z1 - anglez*(x1-xx2); // extrapolated z
2932 //find rotation angles relative to line given by vertex and point 1
2933 Double_t dvertex2 = (x1-x3)*(x1-x3)+(y1-y3)*(y1-y3);
2934 Double_t dvertex = TMath::Sqrt(dvertex2);
2935 Double_t angle13 = TMath::ATan((y1-y3)/(x1-x3));
2936 Double_t cs13 = cos(-angle13), sn13 = sin(-angle13);
2939 // loop over 2 sectors
2945 Double_t dddz1=0; // direction of delta inclination in z axis
2952 for (Int_t dsec = dsec1; dsec<=dsec2;dsec++){
2953 Int_t sec2 = sec + dsec;
2955 // AliTPCtrackerRow& kr2 = fOuterSec[(sec2+fkNOS)%fkNOS][i2];
2956 //AliTPCtrackerRow& kr2m = fOuterSec[(sec2+fkNOS)%fkNOS][imiddle];
2957 AliTPCtrackerRow& kr2 = GetRow((sec2+fkNOS)%fkNOS,i2);
2958 AliTPCtrackerRow& kr2m = GetRow((sec2+fkNOS)%fkNOS,imiddle);
2959 Int_t index1 = TMath::Max(kr2.Find(extraz-0.6-dddz1*TMath::Abs(z1)*0.05)-1,0);
2960 Int_t index2 = TMath::Min(kr2.Find(extraz+0.6+dddz2*TMath::Abs(z1)*0.05)+1,kr2);
2962 // rotation angles to p1-p3
2963 Double_t cs13r = cos(-angle13+dsec*alpha)/dvertex, sn13r = sin(-angle13+dsec*alpha)/dvertex;
2964 Double_t x2, y2, z2;
2966 // Double_t dymax = maxangle*TMath::Abs(x1-xx2);
2969 Double_t dxx0 = (xx2-x3)*cs13r;
2970 Double_t dyy0 = (xx2-x3)*sn13r;
2971 for (Int_t js=index1; js < index2; js++) {
2972 const AliTPCclusterMI *kcl = kr2[js];
2973 if (kcl->IsUsed(10)) continue;
2975 //calcutate parameters
2977 Double_t yy0 = dyy0 +(kcl->GetY()-y3)*cs13r;
2979 if (TMath::Abs(yy0)<0.000001) continue;
2980 Double_t xx0 = dxx0 -(kcl->GetY()-y3)*sn13r;
2981 Double_t y0 = 0.5*(xx0*xx0+yy0*yy0-xx0)/yy0;
2982 Double_t r02 = (0.25+y0*y0)*dvertex2;
2983 //curvature (radius) cut
2984 if (r02<r2min) continue;
2988 Double_t c0 = 1/TMath::Sqrt(r02);
2992 //Double_t dfi0 = 2.*TMath::ASin(dvertex*c0*0.5);
2993 //Double_t dfi1 = 2.*TMath::ASin(TMath::Sqrt(yy0*yy0+(1-xx0)*(1-xx0))*dvertex*c0*0.5);
2994 Double_t dfi0 = 2.*AliTPCFastMath::FastAsin(dvertex*c0*0.5);
2995 Double_t dfi1 = 2.*AliTPCFastMath::FastAsin(TMath::Sqrt(yy0*yy0+(1-xx0)*(1-xx0))*dvertex*c0*0.5);
2998 Double_t z0 = kcl->GetZ();
2999 Double_t zzzz2 = z1-(z1-z3)*dfi1/dfi0;
3000 if (TMath::Abs(zzzz2-z0)>0.5) continue;
3003 Double_t dip = (z1-z0)*c0/dfi1;
3004 Double_t x0 = (0.5*cs13+y0*sn13)*dvertex*c0;
3015 x2= xx2*cs-y2*sn*dsec;
3016 y2=+xx2*sn*dsec+y2*cs;
3026 // do we have cluster at the middle ?
3028 GetProlongation(x1,xm,x,ym,zm);
3030 AliTPCclusterMI * cm=0;
3031 if (TMath::Abs(ym)-ymaxm<0){
3032 cm = krm.FindNearest2(ym,zm,1.0,0.6,dummy);
3033 if ((!cm) || (cm->IsUsed(10))) {
3038 // rotate y1 to system 0
3039 // get state vector in rotated system
3040 Double_t yr1 = (-0.5*sn13+y0*cs13)*dvertex*c0;
3041 Double_t xr2 = x0*cs+yr1*sn*dsec;
3042 Double_t xr[5]={kcl->GetY(),kcl->GetZ(), xr2, dip, c0};
3044 GetProlongation(xx2,xm,xr,ym,zm);
3045 if (TMath::Abs(ym)-ymaxm<0){
3046 cm = kr2m.FindNearest2(ym,zm,1.0,0.6,dummy);
3047 if ((!cm) || (cm->IsUsed(10))) {
3057 dym = ym - cm->GetY();
3058 dzm = zm - cm->GetZ();
3065 Double_t sy1=kr1[is]->GetSigmaY2()*2., sz1=kr1[is]->GetSigmaZ2()*2.;
3066 Double_t sy2=kcl->GetSigmaY2()*2., sz2=kcl->GetSigmaZ2()*2.;
3067 //Double_t sy3=400*3./12., sy=0.1, sz=0.1;
3068 Double_t sy3=25000*x[4]*x[4]+0.1, sy=0.1, sz=0.1;
3069 //Double_t sy3=25000*x[4]*x[4]*60+0.5, sy=0.1, sz=0.1;
3071 Double_t f40=(F1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
3072 Double_t f42=(F1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
3073 Double_t f43=(F1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
3074 Double_t f20=(F2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
3075 Double_t f22=(F2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
3076 Double_t f23=(F2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
3078 Double_t f30=(F3(x1,y1+sy,x2,y2,z1,z2)-x[3])/sy;
3079 Double_t f31=(F3(x1,y1,x2,y2,z1+sz,z2)-x[3])/sz;
3080 Double_t f32=(F3(x1,y1,x2,y2+sy,z1,z2)-x[3])/sy;
3081 Double_t f34=(F3(x1,y1,x2,y2,z1,z2+sz)-x[3])/sz;
3085 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
3086 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
3087 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
3088 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
3089 c[13]=f30*sy1*f40+f32*sy2*f42;
3090 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
3092 // if (!BuildSeed(kr1[is],kcl,0,x1,x2,x3,x,c)) continue;
3094 UInt_t index=kr1.GetIndex(is);
3095 seed->~AliTPCseed(); // this does not set the pointer to 0...
3096 AliTPCseed *track=new(seed) AliTPCseed(x1, ns*alpha+shift, x, c, index);
3098 track->SetIsSeeding(kTRUE);
3099 track->SetSeed1(i1);
3100 track->SetSeed2(i2);
3101 track->SetSeedType(3);
3105 FollowProlongation(*track, (i1+i2)/2,1);
3106 Int_t foundable,found,shared;
3107 track->GetClusterStatistic((i1+i2)/2,i1, found, foundable, shared, kTRUE);
3108 if ((found<0.55*foundable) || shared>0.5*found || (track->GetSigmaY2()+track->GetSigmaZ2())>0.5){
3110 seed->~AliTPCseed();
3116 FollowProlongation(*track, i2,1);
3120 track->SetBConstrain(1);
3121 // track->fLastPoint = i1+fInnerSec->GetNRows(); // first cluster in track position
3122 track->SetLastPoint(i1); // first cluster in track position
3123 track->SetFirstPoint(track->GetLastPoint());
3125 if (track->GetNumberOfClusters()<(i1-i2)*0.5 ||
3126 track->GetNumberOfClusters() < track->GetNFoundable()*0.6 ||
3127 track->GetNShared()>0.4*track->GetNumberOfClusters() ) {
3129 seed->~AliTPCseed();
3133 // Z VERTEX CONDITION
3134 Double_t zv, bz=GetBz();
3135 if ( !track->GetZAt(0.,bz,zv) ) continue;
3136 if (TMath::Abs(zv-z3)>cuts[2]) {
3137 FollowProlongation(*track, TMath::Max(i2-20,0));
3138 if ( !track->GetZAt(0.,bz,zv) ) continue;
3139 if (TMath::Abs(zv-z3)>cuts[2]){
3140 FollowProlongation(*track, TMath::Max(i2-40,0));
3141 if ( !track->GetZAt(0.,bz,zv) ) continue;
3142 if (TMath::Abs(zv-z3)>cuts[2] &&(track->GetNumberOfClusters() > track->GetNFoundable()*0.7)){
3143 // make seed without constrain
3144 AliTPCseed * track2 = MakeSeed(track,0.2,0.5,1.);
3145 FollowProlongation(*track2, i2,1);
3146 track2->SetBConstrain(kFALSE);
3147 track2->SetSeedType(1);
3148 arr->AddLast(track2);
3150 seed->~AliTPCseed();
3155 seed->~AliTPCseed();
3162 track->SetSeedType(0);
3163 arr->AddLast(track);
3164 seed = new AliTPCseed;
3166 // don't consider other combinations
3167 if (track->GetNumberOfClusters() > track->GetNFoundable()*0.8)
3173 Info("MakeSeeds3","\nSeeding statistic:\t%d\t%d\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin,nout1,nout2);
3179 void AliTPCtrackerMI::MakeSeeds5(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t cuts[4],
3184 //-----------------------------------------------------------------
3185 // This function creates track seeds.
3186 //-----------------------------------------------------------------
3187 // cuts[0] - fP4 cut
3188 // cuts[1] - tan(phi) cut
3189 // cuts[2] - zvertex cut
3190 // cuts[3] - fP3 cut
3200 Double_t x[5], c[15];
3202 // make temporary seed
3203 AliTPCseed * seed = new AliTPCseed;
3204 Double_t alpha=fOuterSec->GetAlpha(), shift=fOuterSec->GetAlphaShift();
3205 // Double_t cs=cos(alpha), sn=sin(alpha);
3210 Double_t x1 = GetXrow(i1-1);
3211 const AliTPCtrackerRow& kr1=GetRow(sec,i1-1);
3212 Double_t y1max = GetMaxY(i1-1)-kr1.GetDeadZone()-1.5;
3214 Double_t x1p = GetXrow(i1);
3215 const AliTPCtrackerRow& kr1p=GetRow(sec,i1);
3217 Double_t x1m = GetXrow(i1-2);
3218 const AliTPCtrackerRow& kr1m=GetRow(sec,i1-2);
3221 //last 3 padrow for seeding
3222 AliTPCtrackerRow& kr3 = GetRow((sec+fkNOS)%fkNOS,i1-7);
3223 Double_t x3 = GetXrow(i1-7);
3224 // Double_t y3max= GetMaxY(i1-7)-kr3.fDeadZone-1.5;
3226 AliTPCtrackerRow& kr3p = GetRow((sec+fkNOS)%fkNOS,i1-6);
3227 Double_t x3p = GetXrow(i1-6);
3229 AliTPCtrackerRow& kr3m = GetRow((sec+fkNOS)%fkNOS,i1-8);
3230 Double_t x3m = GetXrow(i1-8);
3235 Int_t im = i1-4; //middle pad row index
3236 Double_t xm = GetXrow(im); // radius of middle pad-row
3237 const AliTPCtrackerRow& krm=GetRow(sec,im); //middle pad -row
3238 // Double_t ymmax = GetMaxY(im)-kr1.fDeadZone-1.5;
3241 Double_t deltax = x1-x3;
3242 Double_t dymax = deltax*cuts[1];
3243 Double_t dzmax = deltax*cuts[3];
3245 // loop over clusters
3246 for (Int_t is=0; is < kr1; is++) {
3248 if (kr1[is]->IsUsed(10)) continue;
3249 Double_t y1=kr1[is]->GetY(), z1=kr1[is]->GetZ();
3251 if (deltay>0 && TMath::Abs(y1max-TMath::Abs(y1))> deltay ) continue; // seed only at the edge
3253 Int_t index1 = TMath::Max(kr3.Find(z1-dzmax)-1,0);
3254 Int_t index2 = TMath::Min(kr3.Find(z1+dzmax)+1,kr3);
3260 for (Int_t js=index1; js < index2; js++) {
3261 const AliTPCclusterMI *kcl = kr3[js];
3262 if (kcl->IsUsed(10)) continue;
3264 // apply angular cuts
3265 if (TMath::Abs(y1-y3)>dymax) continue;
3268 if (TMath::Abs(z1-z3)>dzmax) continue;
3270 Double_t angley = (y1-y3)/(x1-x3);
3271 Double_t anglez = (z1-z3)/(x1-x3);
3273 Double_t erry = TMath::Abs(angley)*(x1-x1m)*0.5+0.5;
3274 Double_t errz = TMath::Abs(anglez)*(x1-x1m)*0.5+0.5;
3276 Double_t yyym = angley*(xm-x1)+y1;
3277 Double_t zzzm = anglez*(xm-x1)+z1;
3279 const AliTPCclusterMI *kcm = krm.FindNearest2(yyym,zzzm,erry,errz,index);
3281 if (kcm->IsUsed(10)) continue;
3283 erry = TMath::Abs(angley)*(x1-x1m)*0.4+0.5;
3284 errz = TMath::Abs(anglez)*(x1-x1m)*0.4+0.5;
3291 // look around first
3292 const AliTPCclusterMI *kc1m = kr1m.FindNearest2(angley*(x1m-x1)+y1,
3298 if (kc1m->IsUsed(10)) used++;
3300 const AliTPCclusterMI *kc1p = kr1p.FindNearest2(angley*(x1p-x1)+y1,
3306 if (kc1p->IsUsed(10)) used++;
3308 if (used>1) continue;
3309 if (found<1) continue;
3313 const AliTPCclusterMI *kc3m = kr3m.FindNearest2(angley*(x3m-x3)+y3,
3319 if (kc3m->IsUsed(10)) used++;
3323 const AliTPCclusterMI *kc3p = kr3p.FindNearest2(angley*(x3p-x3)+y3,
3329 if (kc3p->IsUsed(10)) used++;
3333 if (used>1) continue;
3334 if (found<3) continue;
3344 x[4]=F1(x1,y1,x2,y2,x3,y3);
3345 //if (TMath::Abs(x[4]) >= cuts[0]) continue;
3348 x[2]=F2(x1,y1,x2,y2,x3,y3);
3351 x[3]=F3n(x1,y1,x2,y2,z1,z2,x[4]);
3352 //if (TMath::Abs(x[3]) > cuts[3]) continue;
3356 Double_t sy1=0.1, sz1=0.1;
3357 Double_t sy2=0.1, sz2=0.1;
3358 Double_t sy3=0.1, sy=0.1, sz=0.1;
3360 Double_t f40=(F1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
3361 Double_t f42=(F1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
3362 Double_t f43=(F1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
3363 Double_t f20=(F2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
3364 Double_t f22=(F2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
3365 Double_t f23=(F2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
3367 Double_t f30=(F3(x1,y1+sy,x2,y2,z1,z2)-x[3])/sy;
3368 Double_t f31=(F3(x1,y1,x2,y2,z1+sz,z2)-x[3])/sz;
3369 Double_t f32=(F3(x1,y1,x2,y2+sy,z1,z2)-x[3])/sy;
3370 Double_t f34=(F3(x1,y1,x2,y2,z1,z2+sz)-x[3])/sz;
3374 c[3]=f20*sy1; c[4]=0.; c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
3375 c[6]=f30*sy1; c[7]=f31*sz1; c[8]=f30*sy1*f20+f32*sy2*f22;
3376 c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
3377 c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
3378 c[13]=f30*sy1*f40+f32*sy2*f42;
3379 c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
3381 // if (!BuildSeed(kr1[is],kcl,0,x1,x2,x3,x,c)) continue;
3383 UInt_t index=kr1.GetIndex(is);
3384 seed->~AliTPCseed();
3385 AliTPCseed *track=new(seed) AliTPCseed(x1, sec*alpha+shift, x, c, index);
3387 track->SetIsSeeding(kTRUE);
3390 FollowProlongation(*track, i1-7,1);
3391 if (track->GetNumberOfClusters() < track->GetNFoundable()*0.75 ||
3392 track->GetNShared()>0.6*track->GetNumberOfClusters() || ( track->GetSigmaY2()+ track->GetSigmaZ2())>0.6){
3394 seed->~AliTPCseed();
3400 FollowProlongation(*track, i2,1);
3401 track->SetBConstrain(0);
3402 track->SetLastPoint(i1+fInnerSec->GetNRows()); // first cluster in track position
3403 track->SetFirstPoint(track->GetLastPoint());
3405 if (track->GetNumberOfClusters()<(i1-i2)*0.5 ||
3406 track->GetNumberOfClusters()<track->GetNFoundable()*0.7 ||
3407 track->GetNShared()>2. || track->GetChi2()/track->GetNumberOfClusters()>6 || ( track->GetSigmaY2()+ track->GetSigmaZ2())>0.5 ) {
3409 seed->~AliTPCseed();
3414 FollowProlongation(*track, TMath::Max(i2-10,0),1);
3415 AliTPCseed * track2 = MakeSeed(track,0.2,0.5,0.9);
3416 FollowProlongation(*track2, i2,1);
3417 track2->SetBConstrain(kFALSE);
3418 track2->SetSeedType(4);
3419 arr->AddLast(track2);
3421 seed->~AliTPCseed();
3425 //arr->AddLast(track);
3426 //seed = new AliTPCseed;
3432 Info("MakeSeeds5","\nSeeding statiistic:\t%d\t%d\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin,nout1,nout2,nout3);
3438 //_____________________________________________________________________________
3439 void AliTPCtrackerMI::MakeSeeds2(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t */*cuts[4]*/,
3440 Float_t deltay, Bool_t /*bconstrain*/) {
3441 //-----------------------------------------------------------------
3442 // This function creates track seeds - without vertex constraint
3443 //-----------------------------------------------------------------
3444 // cuts[0] - fP4 cut - not applied
3445 // cuts[1] - tan(phi) cut
3446 // cuts[2] - zvertex cut - not applied
3447 // cuts[3] - fP3 cut
3457 Double_t alpha=fOuterSec->GetAlpha(), shift=fOuterSec->GetAlphaShift();
3458 // Double_t cs=cos(alpha), sn=sin(alpha);
3459 Int_t row0 = (i1+i2)/2;
3460 Int_t drow = (i1-i2)/2;
3461 const AliTPCtrackerRow& kr0=fSectors[sec][row0];
3462 AliTPCtrackerRow * kr=0;
3464 AliTPCpolyTrack polytrack;
3465 Int_t nclusters=fSectors[sec][row0];
3466 AliTPCseed * seed = new AliTPCseed;
3471 for (Int_t is=0; is < nclusters; is++) { //LOOP over clusters
3473 Int_t nfoundable =0;
3474 for (Int_t iter =1; iter<2; iter++){ //iterations
3475 const AliTPCtrackerRow& krm=fSectors[sec][row0-iter];
3476 const AliTPCtrackerRow& krp=fSectors[sec][row0+iter];
3477 const AliTPCclusterMI * cl= kr0[is];
3479 if (cl->IsUsed(10)) {
3485 Double_t x = kr0.GetX();
3486 // Initialization of the polytrack
3491 Double_t y0= cl->GetY();
3492 Double_t z0= cl->GetZ();
3496 Double_t ymax = fSectors->GetMaxY(row0)-kr0.GetDeadZone()-1.5;
3497 if (deltay>0 && TMath::Abs(ymax-TMath::Abs(y0))> deltay ) continue; // seed only at the edge
3499 erry = (0.5)*cl->GetSigmaY2()/TMath::Sqrt(cl->GetQ())*6;
3500 errz = (0.5)*cl->GetSigmaZ2()/TMath::Sqrt(cl->GetQ())*6;
3501 polytrack.AddPoint(x,y0,z0,erry, errz);
3504 if (cl->IsUsed(10)) sumused++;
3507 Float_t roady = (5*TMath::Sqrt(cl->GetSigmaY2()+0.2)+1.)*iter;
3508 Float_t roadz = (5*TMath::Sqrt(cl->GetSigmaZ2()+0.2)+1.)*iter;
3511 AliTPCclusterMI * cl1 = krm.FindNearest(y0,z0,roady,roadz);
3512 if (cl1 && TMath::Abs(ymax-TMath::Abs(y0))) {
3513 erry = (0.5)*cl1->GetSigmaY2()/TMath::Sqrt(cl1->GetQ())*3;
3514 errz = (0.5)*cl1->GetSigmaZ2()/TMath::Sqrt(cl1->GetQ())*3;
3515 if (cl1->IsUsed(10)) sumused++;
3516 polytrack.AddPoint(x,cl1->GetY(),cl1->GetZ(),erry,errz);
3520 AliTPCclusterMI * cl2 = krp.FindNearest(y0,z0,roady,roadz);
3522 erry = (0.5)*cl2->GetSigmaY2()/TMath::Sqrt(cl2->GetQ())*3;
3523 errz = (0.5)*cl2->GetSigmaZ2()/TMath::Sqrt(cl2->GetQ())*3;
3524 if (cl2->IsUsed(10)) sumused++;
3525 polytrack.AddPoint(x,cl2->GetY(),cl2->GetZ(),erry,errz);
3528 if (sumused>0) continue;
3530 polytrack.UpdateParameters();
3536 nfoundable = polytrack.GetN();
3537 nfound = nfoundable;
3539 for (Int_t ddrow = iter+1; ddrow<drow;ddrow++){
3540 Float_t maxdist = 0.8*(1.+3./(ddrow));
3541 for (Int_t delta = -1;delta<=1;delta+=2){
3542 Int_t row = row0+ddrow*delta;
3543 kr = &(fSectors[sec][row]);
3544 Double_t xn = kr->GetX();
3545 Double_t ymax = fSectors->GetMaxY(row)-kr->GetDeadZone()-1.5;
3546 polytrack.GetFitPoint(xn,yn,zn);
3547 if (TMath::Abs(yn)>ymax) continue;
3549 AliTPCclusterMI * cln = kr->FindNearest(yn,zn,roady,roadz);
3551 Float_t dist = TMath::Sqrt( (yn-cln->GetY())*(yn-cln->GetY())+(zn-cln->GetZ())*(zn-cln->GetZ()));
3554 erry = (dist+0.3)*cln->GetSigmaY2()/TMath::Sqrt(cln->GetQ())*(1.+1./(ddrow));
3555 errz = (dist+0.3)*cln->GetSigmaZ2()/TMath::Sqrt(cln->GetQ())*(1.+1./(ddrow));
3556 if (cln->IsUsed(10)) {
3557 // printf("used\n");
3565 polytrack.AddPoint(xn,cln->GetY(),cln->GetZ(),erry, errz);
3570 if ( (sumused>3) || (sumused>0.5*nfound) || (nfound<0.6*nfoundable)) break;
3571 polytrack.UpdateParameters();
3574 if ( (sumused>3) || (sumused>0.5*nfound)) {
3575 //printf("sumused %d\n",sumused);
3580 polytrack.GetFitDerivation(kr0.GetX(),dy,dz);
3581 AliTPCpolyTrack track2;
3583 polytrack.Refit(track2,0.5+TMath::Abs(dy)*0.3,0.4+TMath::Abs(dz)*0.3);
3584 if (track2.GetN()<0.5*nfoundable) continue;