]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TPC/AliTPCtrackerMI.cxx
Empirical cut to increase robustness
[u/mrichter/AliRoot.git] / TPC / AliTPCtrackerMI.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
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  **************************************************************************/
15
16
17 //-------------------------------------------------------
18 //          Implementation of the TPC tracker
19 //
20 //   Origin: Marian Ivanov   Marian.Ivanov@cern.ch
21 // 
22 //  AliTPC parallel tracker
23 //
24 //  The track fitting is based on Kalaman filtering approach
25
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
31
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) ...
35
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) 
39
40 //  Repeating several seeding - tracking procedures some of the tracks can be find 
41 //  several times. 
42
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
53 //  
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 
59 //                  low efficiency
60 //                 
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)
66 //                          
67 //
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); 
71 //
72 // The debug level -  different procedure produce tree for numerical debugging
73 //                    To enable them set AliTPCReconstructor::SetStreamLevel(n); where nis bigger 1
74 //
75
76 //
77 // Adding systematic errors to the covariance:
78 // 
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. 
84 //
85 // The sytematic errors are added to the covariance matrix in following places:
86 //
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
94 //
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
97 //
98 //      1. ErrParam stream  - dump information about 
99 //         1.a) cluster
100 //         2.a) cluster error estimate
101 //         3.a) cluster shape estimate
102 //
103 //
104 //  Debug streamer levels:
105 //  
106 //-------------------------------------------------------
107
108
109 /* $Id$ */
110
111 #include "Riostream.h"
112 #include <TClonesArray.h>
113 #include <TFile.h>
114 #include <TObjArray.h>
115 #include <TTree.h>
116 #include <TGraphErrors.h>
117 #include "AliLog.h"
118 #include "AliComplexCluster.h"
119 #include "AliESDEvent.h"
120 #include "AliESDtrack.h"
121 #include "AliESDVertex.h"
122 #include "AliKink.h"
123 #include "AliV0.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"
132
133 #include "AliTPCtrackerSector.h" 
134 #include "AliTPCtrackerMI.h"
135 #include "TStopwatch.h"
136 #include "AliTPCReconstructor.h"
137 #include "AliAlignObj.h"
138 #include "AliTrackPointArray.h"
139 #include "TRandom.h"
140 #include "AliTPCcalibDB.h"
141 #include "AliTPCcalibDButil.h"
142 #include "AliTPCTransform.h"
143 #include "AliTPCClusterParam.h"
144
145 //
146
147 ClassImp(AliTPCtrackerMI)
148
149
150
151 class AliTPCFastMath {
152 public:
153   AliTPCFastMath();  
154   static Double_t FastAsin(Double_t x);   
155  private: 
156   static Double_t fgFastAsin[20000];  //lookup table for fast asin computation
157 };
158
159 Double_t AliTPCFastMath::fgFastAsin[20000];
160 AliTPCFastMath gAliTPCFastMath; // needed to fill the LUT
161
162 AliTPCFastMath::AliTPCFastMath(){
163   //
164   // initialized lookup table;
165   for (Int_t i=0;i<10000;i++){
166     fgFastAsin[2*i] = TMath::ASin(i/10000.);
167     fgFastAsin[2*i+1] = (TMath::ASin((i+1)/10000.)-fgFastAsin[2*i]);
168   }
169 }
170
171 Double_t AliTPCFastMath::FastAsin(Double_t x){
172   //
173   // return asin using lookup table
174   if (x>0){
175     Int_t index = int(x*10000);
176     return fgFastAsin[2*index]+(x*10000.-index)*fgFastAsin[2*index+1];
177   }
178   x*=-1;
179   Int_t index = int(x*10000);
180   return -(fgFastAsin[2*index]+(x*10000.-index)*fgFastAsin[2*index+1]);
181 }
182 //__________________________________________________________________
183 AliTPCtrackerMI::AliTPCtrackerMI()
184                 :AliTracker(),
185                  fkNIS(0),
186                  fInnerSec(0),
187                  fkNOS(0),
188                  fOuterSec(0),
189                  fN(0),
190                  fSectors(0),
191                  fInput(0),
192                  fOutput(0),
193                  fSeedTree(0),
194                  fTreeDebug(0),
195                  fEvent(0),
196                  fDebug(0),
197                  fNewIO(kFALSE),
198                  fNtracks(0),
199                  fSeeds(0),
200                  fIteration(0),
201                  fkParam(0),
202                  fDebugStreamer(0)
203 {
204   //
205   // default constructor
206   //
207   for (Int_t irow=0; irow<200; irow++){
208     fXRow[irow]=0;
209     fYMax[irow]=0;
210     fPadLength[irow]=0;
211   }
212
213 }
214 //_____________________________________________________________________
215
216
217
218 Int_t AliTPCtrackerMI::UpdateTrack(AliTPCseed * track, Int_t accept){
219   //
220   //update track information using current cluster - track->fCurrentCluster
221
222
223   AliTPCclusterMI* c =track->GetCurrentCluster();
224   if (accept>0) track->SetCurrentClusterIndex1(track->GetCurrentClusterIndex1() | 0x8000);  //sign not accepted clusters
225
226   UInt_t i = track->GetCurrentClusterIndex1();
227
228   Int_t sec=(i&0xff000000)>>24; 
229   //Int_t row = (i&0x00ff0000)>>16; 
230   track->SetRow((i&0x00ff0000)>>16);
231   track->SetSector(sec);
232   //  Int_t index = i&0xFFFF;
233   if (sec>=fkParam->GetNInnerSector()) track->SetRow(track->GetRow()+fkParam->GetNRowLow()); 
234   track->SetClusterIndex2(track->GetRow(), i);  
235   //track->fFirstPoint = row;
236   //if ( track->fLastPoint<row) track->fLastPoint =row;
237   //  if (track->fRow<0 || track->fRow>160) {
238   //  printf("problem\n");
239   //}
240   if (track->GetFirstPoint()>track->GetRow()) 
241     track->SetFirstPoint(track->GetRow());
242   if (track->GetLastPoint()<track->GetRow()) 
243     track->SetLastPoint(track->GetRow());
244   
245
246   track->SetClusterPointer(track->GetRow(),c);  
247   //
248
249   Double_t angle2 = track->GetSnp()*track->GetSnp();
250   //
251   //SET NEW Track Point
252   //
253   if (angle2<1) //PH sometimes angle2 is very big. To be investigated...
254   {
255     angle2 = TMath::Sqrt(angle2/(1-angle2)); 
256     AliTPCTrackerPoint   &point =*(track->GetTrackPoint(track->GetRow()));
257     //
258     point.SetSigmaY(c->GetSigmaY2()/track->GetCurrentSigmaY2());
259     point.SetSigmaZ(c->GetSigmaZ2()/track->GetCurrentSigmaZ2());
260     point.SetErrY(sqrt(track->GetErrorY2()));
261     point.SetErrZ(sqrt(track->GetErrorZ2()));
262     //
263     point.SetX(track->GetX());
264     point.SetY(track->GetY());
265     point.SetZ(track->GetZ());
266     point.SetAngleY(angle2);
267     point.SetAngleZ(track->GetTgl());
268     if (point.IsShared()){
269       track->SetErrorY2(track->GetErrorY2()*4);
270       track->SetErrorZ2(track->GetErrorZ2()*4);
271     }
272   }  
273
274   Double_t chi2 = track->GetPredictedChi2(track->GetCurrentCluster());
275   //
276 //   track->SetErrorY2(track->GetErrorY2()*1.3);
277 //   track->SetErrorY2(track->GetErrorY2()+0.01);    
278 //   track->SetErrorZ2(track->GetErrorZ2()*1.3);   
279 //   track->SetErrorZ2(track->GetErrorZ2()+0.005);      
280     //}
281   if (accept>0) return 0;
282   if (track->GetNumberOfClusters()%20==0){
283     //    if (track->fHelixIn){
284     //  TClonesArray & larr = *(track->fHelixIn);    
285     //  Int_t ihelix = larr.GetEntriesFast();
286     //  new(larr[ihelix]) AliHelix(*track) ;    
287     //}
288   }
289   track->SetNoCluster(0);
290   return track->Update(c,chi2,i);
291 }
292
293
294
295 Int_t AliTPCtrackerMI::AcceptCluster(AliTPCseed * seed, AliTPCclusterMI * cluster)
296 {
297   //
298   // decide according desired precision to accept given 
299   // cluster for tracking
300   Double_t  yt=0,zt=0;
301   seed->GetProlongation(cluster->GetX(),yt,zt);
302   Double_t sy2=ErrY2(seed,cluster);
303   Double_t sz2=ErrZ2(seed,cluster);
304   
305   Double_t sdistancey2 = sy2+seed->GetSigmaY2();
306   Double_t sdistancez2 = sz2+seed->GetSigmaZ2();
307   Double_t dy=seed->GetCurrentCluster()->GetY()-yt;
308   Double_t dz=seed->GetCurrentCluster()->GetZ()-zt;
309   Double_t rdistancey2 = (seed->GetCurrentCluster()->GetY()-yt)*
310     (seed->GetCurrentCluster()->GetY()-yt)/sdistancey2;
311   Double_t rdistancez2 = (seed->GetCurrentCluster()->GetZ()-zt)*
312     (seed->GetCurrentCluster()->GetZ()-zt)/sdistancez2;
313   
314   Double_t rdistance2  = rdistancey2+rdistancez2;
315   //Int_t  accept =0;
316   
317   if (AliTPCReconstructor::StreamLevel()>2 && seed->GetNumberOfClusters()>20) {
318     Float_t rmsy2 = seed->GetCurrentSigmaY2();
319     Float_t rmsz2 = seed->GetCurrentSigmaZ2();
320     Float_t rmsy2p30 = seed->GetCMeanSigmaY2p30();
321     Float_t rmsz2p30 = seed->GetCMeanSigmaZ2p30();
322     Float_t rmsy2p30R  = seed->GetCMeanSigmaY2p30R();
323     Float_t rmsz2p30R  = seed->GetCMeanSigmaZ2p30R();
324     AliExternalTrackParam param(*seed);
325     static TVectorD gcl(3),gtr(3);
326     Float_t gclf[3];
327     param.GetXYZ(gcl.GetMatrixArray());
328     cluster->GetGlobalXYZ(gclf);
329     gcl[0]=gclf[0];    gcl[1]=gclf[1];    gcl[2]=gclf[2];
330
331     
332     if (AliTPCReconstructor::StreamLevel()>2) {
333     (*fDebugStreamer)<<"ErrParam"<<
334       "Cl.="<<cluster<<
335       "T.="<<&param<<
336       "dy="<<dy<<
337       "dz="<<dz<<
338       "yt="<<yt<<
339       "zt="<<zt<<
340       "gcl.="<<&gcl<<
341       "gtr.="<<&gtr<<
342       "erry2="<<sy2<<
343       "errz2="<<sz2<<
344       "rmsy2="<<rmsy2<<
345       "rmsz2="<<rmsz2<< 
346       "rmsy2p30="<<rmsy2p30<<
347       "rmsz2p30="<<rmsz2p30<<   
348       "rmsy2p30R="<<rmsy2p30R<<
349       "rmsz2p30R="<<rmsz2p30R<< 
350       // normalize distance - 
351       "rdisty="<<rdistancey2<<
352       "rdistz="<<rdistancez2<<
353       "rdist="<<rdistance2<< //       
354       "\n";
355     }
356   }
357   //return 0;  // temporary
358   if (rdistance2>32) return 3;
359   
360   
361   if ((rdistancey2>9. || rdistancez2>9.) && cluster->GetType()==0)  
362     return 2;  //suspisiouce - will be changed
363   
364   if ((rdistancey2>6.25 || rdistancez2>6.25) && cluster->GetType()>0)  
365     // strict cut on overlaped cluster
366     return  2;  //suspisiouce - will be changed
367   
368   if ( (rdistancey2>1. || rdistancez2>6.25 ) 
369        && cluster->GetType()<0){
370     seed->SetNFoundable(seed->GetNFoundable()-1);
371     return 2;    
372   }
373   return 0;
374 }
375
376
377
378
379
380 //_____________________________________________________________________________
381 AliTPCtrackerMI::AliTPCtrackerMI(const AliTPCParam *par): 
382 AliTracker(), 
383                  fkNIS(par->GetNInnerSector()/2),
384                  fInnerSec(0),
385                  fkNOS(par->GetNOuterSector()/2),
386                  fOuterSec(0),
387                  fN(0),
388                  fSectors(0),
389                  fInput(0),
390                  fOutput(0),
391                  fSeedTree(0),
392                  fTreeDebug(0),
393                  fEvent(0),
394                  fDebug(0),
395                  fNewIO(0),
396                  fNtracks(0),
397                  fSeeds(0),
398                  fIteration(0),
399                  fkParam(0),
400                  fDebugStreamer(0)
401 {
402   //---------------------------------------------------------------------
403   // The main TPC tracker constructor
404   //---------------------------------------------------------------------
405   fInnerSec=new AliTPCtrackerSector[fkNIS];         
406   fOuterSec=new AliTPCtrackerSector[fkNOS];
407  
408   Int_t i;
409   for (i=0; i<fkNIS; i++) fInnerSec[i].Setup(par,0);
410   for (i=0; i<fkNOS; i++) fOuterSec[i].Setup(par,1);
411
412   fkParam = par;  
413   Int_t nrowlow = par->GetNRowLow();
414   Int_t nrowup = par->GetNRowUp();
415
416   
417   for (i=0;i<nrowlow;i++){
418     fXRow[i]     = par->GetPadRowRadiiLow(i);
419     fPadLength[i]= par->GetPadPitchLength(0,i);
420     fYMax[i]     = fXRow[i]*TMath::Tan(0.5*par->GetInnerAngle());
421   }
422
423   
424   for (i=0;i<nrowup;i++){
425     fXRow[i+nrowlow]      = par->GetPadRowRadiiUp(i);
426     fPadLength[i+nrowlow] = par->GetPadPitchLength(60,i);
427     fYMax[i+nrowlow]      = fXRow[i+nrowlow]*TMath::Tan(0.5*par->GetOuterAngle());
428   }
429
430   if (AliTPCReconstructor::StreamLevel()>0) {
431     fDebugStreamer = new TTreeSRedirector("TPCdebug.root");
432   }
433 }
434 //________________________________________________________________________
435 AliTPCtrackerMI::AliTPCtrackerMI(const AliTPCtrackerMI &t):
436   AliTracker(t),
437                  fkNIS(t.fkNIS),
438                  fInnerSec(0),
439                  fkNOS(t.fkNOS),
440                  fOuterSec(0),
441                  fN(0),
442                  fSectors(0),
443                  fInput(0),
444                  fOutput(0),
445                  fSeedTree(0),
446                  fTreeDebug(0),
447                  fEvent(0),
448                  fDebug(0),
449                  fNewIO(kFALSE),
450                  fNtracks(0),
451                  fSeeds(0),
452                  fIteration(0),
453                  fkParam(0),
454                  fDebugStreamer(0)
455 {
456   //------------------------------------
457   // dummy copy constructor
458   //------------------------------------------------------------------
459   fOutput=t.fOutput;
460 }
461 AliTPCtrackerMI & AliTPCtrackerMI::operator=(const AliTPCtrackerMI& /*r*/)
462 {
463   //------------------------------
464   // dummy 
465   //--------------------------------------------------------------
466   return *this;
467 }
468 //_____________________________________________________________________________
469 AliTPCtrackerMI::~AliTPCtrackerMI() {
470   //------------------------------------------------------------------
471   // TPC tracker destructor
472   //------------------------------------------------------------------
473   delete[] fInnerSec;
474   delete[] fOuterSec;
475   if (fSeeds) {
476     fSeeds->Delete(); 
477     delete fSeeds;
478   }
479   if (fDebugStreamer) delete fDebugStreamer;
480 }
481
482
483 void AliTPCtrackerMI::FillESD(const TObjArray* arr)
484 {
485   //
486   //
487   //fill esds using updated tracks
488   if (!fEvent) return;
489   
490     // write tracks to the event
491     // store index of the track
492     Int_t nseed=arr->GetEntriesFast();
493     //FindKinks(arr,fEvent);
494     for (Int_t i=0; i<nseed; i++) {
495       AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);    
496       if (!pt) continue; 
497       pt->UpdatePoints();
498       AddCovariance(pt);
499       if (AliTPCReconstructor::StreamLevel()>1) {
500         (*fDebugStreamer)<<"Track0"<<
501           "Tr0.="<<pt<<
502           "\n";       
503       }
504       //      pt->PropagateTo(fkParam->GetInnerRadiusLow());
505       if (pt->GetKinkIndex(0)<=0){  //don't propagate daughter tracks 
506         pt->PropagateTo(fkParam->GetInnerRadiusLow());
507       }
508  
509       if (( pt->GetPoints()[2]- pt->GetPoints()[0])>5 && pt->GetPoints()[3]>0.8){
510         AliESDtrack iotrack;
511         iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
512         iotrack.SetTPCPoints(pt->GetPoints());
513         iotrack.SetKinkIndexes(pt->GetKinkIndexes());
514         iotrack.SetV0Indexes(pt->GetV0Indexes());
515         //      iotrack.SetTPCpid(pt->fTPCr);
516         //iotrack.SetTPCindex(i);
517         fEvent->AddTrack(&iotrack);
518         continue;
519       }
520        
521       if ( (pt->GetNumberOfClusters()>70)&& (Float_t(pt->GetNumberOfClusters())/Float_t(pt->GetNFoundable()))>0.55) {
522         AliESDtrack iotrack;
523         iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);
524         iotrack.SetTPCPoints(pt->GetPoints());
525         //iotrack.SetTPCindex(i);
526         iotrack.SetKinkIndexes(pt->GetKinkIndexes());
527         iotrack.SetV0Indexes(pt->GetV0Indexes());
528         //      iotrack.SetTPCpid(pt->fTPCr);
529         fEvent->AddTrack(&iotrack);
530         continue;
531       } 
532       //
533       // short tracks  - maybe decays
534
535       if ( (pt->GetNumberOfClusters()>30) && (Float_t(pt->GetNumberOfClusters())/Float_t(pt->GetNFoundable()))>0.70) {
536         Int_t found,foundable,shared;
537         pt->GetClusterStatistic(0,60,found, foundable,shared,kFALSE);
538         if ( (found>20) && (pt->GetNShared()/float(pt->GetNumberOfClusters())<0.2)){
539           AliESDtrack iotrack;
540           iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);    
541           //iotrack.SetTPCindex(i);
542           iotrack.SetTPCPoints(pt->GetPoints());
543           iotrack.SetKinkIndexes(pt->GetKinkIndexes());
544           iotrack.SetV0Indexes(pt->GetV0Indexes());
545           //iotrack.SetTPCpid(pt->fTPCr);
546           fEvent->AddTrack(&iotrack);
547           continue;
548         }
549       }       
550       
551       if ( (pt->GetNumberOfClusters()>20) && (Float_t(pt->GetNumberOfClusters())/Float_t(pt->GetNFoundable()))>0.8) {
552         Int_t found,foundable,shared;
553         pt->GetClusterStatistic(0,60,found, foundable,shared,kFALSE);
554         if (found<20) continue;
555         if (pt->GetNShared()/float(pt->GetNumberOfClusters())>0.2) continue;
556         //
557         AliESDtrack iotrack;
558         iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);      
559         iotrack.SetTPCPoints(pt->GetPoints());
560         iotrack.SetKinkIndexes(pt->GetKinkIndexes());
561         iotrack.SetV0Indexes(pt->GetV0Indexes());
562         //iotrack.SetTPCpid(pt->fTPCr);
563         //iotrack.SetTPCindex(i);
564         fEvent->AddTrack(&iotrack);
565         continue;
566       }   
567       // short tracks  - secondaties
568       //
569       if ( (pt->GetNumberOfClusters()>30) ) {
570         Int_t found,foundable,shared;
571         pt->GetClusterStatistic(128,158,found, foundable,shared,kFALSE);
572         if ( (found>20) && (pt->GetNShared()/float(pt->GetNumberOfClusters())<0.2) &&float(found)/float(foundable)>0.8){
573           AliESDtrack iotrack;
574           iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);    
575           iotrack.SetTPCPoints(pt->GetPoints());
576           iotrack.SetKinkIndexes(pt->GetKinkIndexes());
577           iotrack.SetV0Indexes(pt->GetV0Indexes());
578           //iotrack.SetTPCpid(pt->fTPCr);       
579           //iotrack.SetTPCindex(i);
580           fEvent->AddTrack(&iotrack);
581           continue;
582         }
583       }       
584       
585       if ( (pt->GetNumberOfClusters()>15)) {
586         Int_t found,foundable,shared;
587         pt->GetClusterStatistic(138,158,found, foundable,shared,kFALSE);
588         if (found<15) continue;
589         if (foundable<=0) continue;
590         if (pt->GetNShared()/float(pt->GetNumberOfClusters())>0.2) continue;
591         if (float(found)/float(foundable)<0.8) continue;
592         //
593         AliESDtrack iotrack;
594         iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);      
595         iotrack.SetTPCPoints(pt->GetPoints());
596         iotrack.SetKinkIndexes(pt->GetKinkIndexes());
597         iotrack.SetV0Indexes(pt->GetV0Indexes());
598         //      iotrack.SetTPCpid(pt->fTPCr);
599         //iotrack.SetTPCindex(i);
600         fEvent->AddTrack(&iotrack);
601         continue;
602       }   
603     }
604     // >> account for suppressed tracks in the kink indices (RS)
605     int nESDtracks = fEvent->GetNumberOfTracks();
606     for (int it=nESDtracks;it--;) {
607       AliESDtrack* esdTr = fEvent->GetTrack(it);
608       if (!esdTr || !esdTr->GetKinkIndex(0)) continue;
609       for (int ik=0;ik<3;ik++) {
610         int knkId=0;
611         if (!(knkId=esdTr->GetKinkIndex(ik))) break; // no more kinks for this track
612         AliESDkink* kink = fEvent->GetKink(TMath::Abs(knkId)-1);
613         if (!kink) {
614           AliError(Form("ESDTrack%d refers to non-existing kink %d",it,TMath::Abs(knkId)-1));
615           continue;
616         }
617         kink->SetIndex(it, knkId<0 ? 0:1); // update track index of the kink: mother at 0, daughter at 1
618       }
619     }
620     // << account for suppressed tracks in the kink indices (RS)  
621     AliInfo(Form("Number of filled ESDs-\t%d\n",fEvent->GetNumberOfTracks()));
622   
623 }
624
625
626
627
628
629 Double_t AliTPCtrackerMI::ErrY2(AliTPCseed* seed, const AliTPCclusterMI * cl){
630   //
631   //
632   // Use calibrated cluster error from OCDB
633   //
634   AliTPCClusterParam * clparam = AliTPCcalibDB::Instance()->GetClusterParam();
635   //
636   Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
637   Int_t ctype = cl->GetType();  
638   Int_t    type = (cl->GetRow()<63) ? 0: (cl->GetRow()>126) ? 1:2;
639   Double_t angle = seed->GetSnp()*seed->GetSnp();
640   angle = TMath::Sqrt(TMath::Abs(angle/(1.-angle)));
641   Double_t erry2 = clparam->GetError0Par(0,type, z,angle);
642   if (ctype<0) {
643     erry2+=0.5;  // edge cluster
644   }
645   erry2*=erry2;
646   seed->SetErrorY2(erry2);
647   //
648   return erry2;
649
650 //calculate look-up table at the beginning
651 //   static Bool_t  ginit = kFALSE;
652 //   static Float_t gnoise1,gnoise2,gnoise3;
653 //   static Float_t ggg1[10000];
654 //   static Float_t ggg2[10000];
655 //   static Float_t ggg3[10000];
656 //   static Float_t glandau1[10000];
657 //   static Float_t glandau2[10000];
658 //   static Float_t glandau3[10000];
659 //   //
660 //   static Float_t gcor01[500];
661 //   static Float_t gcor02[500];
662 //   static Float_t gcorp[500];
663 //   //
664
665 //   //
666 //   if (ginit==kFALSE){
667 //     for (Int_t i=1;i<500;i++){
668 //       Float_t rsigma = float(i)/100.;
669 //       gcor02[i] = TMath::Max(0.78 +TMath::Exp(7.4*(rsigma-1.2)),0.6);
670 //       gcor01[i] = TMath::Max(0.72 +TMath::Exp(3.36*(rsigma-1.2)),0.6);
671 //       gcorp[i]  = TMath::Max(TMath::Power((rsigma+0.5),1.5),1.2);
672 //     }
673
674 //     //
675 //     for (Int_t i=3;i<10000;i++){
676 //       //
677 //       //
678 //       // inner sector
679 //       Float_t amp = float(i);
680 //       Float_t padlength =0.75;
681 //       gnoise1 = 0.0004/padlength;
682 //       Float_t nel     = 0.268*amp;
683 //       Float_t nprim   = 0.155*amp;
684 //       ggg1[i]          = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.001*nel/(padlength*padlength))/nel;
685 //       glandau1[i]      = (2.+0.12*nprim)*0.5* (2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
686 //       if (glandau1[i]>1) glandau1[i]=1;
687 //       glandau1[i]*=padlength*padlength/12.;      
688 //       //
689 //       // outer short
690 //       padlength =1.;
691 //       gnoise2   = 0.0004/padlength;
692 //       nel       = 0.3*amp;
693 //       nprim     = 0.133*amp;
694 //       ggg2[i]      = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
695 //       glandau2[i]  = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
696 //       if (glandau2[i]>1) glandau2[i]=1;
697 //       glandau2[i]*=padlength*padlength/12.;
698 //       //
699 //       //
700 //       // outer long
701 //       padlength =1.5;
702 //       gnoise3   = 0.0004/padlength;
703 //       nel       = 0.3*amp;
704 //       nprim     = 0.133*amp;
705 //       ggg3[i]      = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
706 //       glandau3[i]  = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
707 //       if (glandau3[i]>1) glandau3[i]=1;
708 //       glandau3[i]*=padlength*padlength/12.;
709 //       //
710 //     }
711 //     ginit = kTRUE;
712 //   }
713 //   //
714 //   //
715 //   //
716 //   Int_t amp = int(TMath::Abs(cl->GetQ()));  
717 //   if (amp>9999) {
718 //     seed->SetErrorY2(1.);
719 //     return 1.;
720 //   }
721 //   Float_t snoise2;
722 //   Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
723 //   Int_t ctype = cl->GetType();  
724 //   Float_t padlength= GetPadPitchLength(seed->GetRow());
725 //   Double_t angle2 = seed->GetSnp()*seed->GetSnp();
726 //   angle2 = angle2/(1-angle2); 
727 //   //
728 //   //cluster "quality"
729 //   Int_t rsigmay = int(100.*cl->GetSigmaY2()/(seed->GetCurrentSigmaY2()));
730 //   Float_t res;
731 //   //
732 //   if (fSectors==fInnerSec){
733 //     snoise2 = gnoise1;
734 //     res     = ggg1[amp]*z+glandau1[amp]*angle2;     
735 //     if (ctype==0) res *= gcor01[rsigmay];
736 //     if ((ctype>0)){
737 //       res+=0.002;
738 //       res*= gcorp[rsigmay];
739 //     }
740 //   }
741 //   else {
742 //     if (padlength<1.1){
743 //       snoise2 = gnoise2;
744 //       res     = ggg2[amp]*z+glandau2[amp]*angle2; 
745 //       if (ctype==0) res *= gcor02[rsigmay];      
746 //       if ((ctype>0)){
747 //      res+=0.002;
748 //      res*= gcorp[rsigmay];
749 //       }
750 //     }
751 //     else{
752 //       snoise2 = gnoise3;      
753 //       res     = ggg3[amp]*z+glandau3[amp]*angle2; 
754 //       if (ctype==0) res *= gcor02[rsigmay];
755 //       if ((ctype>0)){
756 //      res+=0.002;
757 //      res*= gcorp[rsigmay];
758 //       }
759 //     }
760 //   }  
761
762 //   if (ctype<0){
763 //     res+=0.005;
764 //     res*=2.4;  // overestimate error 2 times
765 //   }
766 //   res+= snoise2;
767  
768 //   if (res<2*snoise2)
769 //     res = 2*snoise2;
770   
771 //   seed->SetErrorY2(res);
772 //   return res;
773
774
775 }
776
777
778
779 Double_t AliTPCtrackerMI::ErrZ2(AliTPCseed* seed, const AliTPCclusterMI * cl){
780   //
781   //
782   // Use calibrated cluster error from OCDB
783   //
784   AliTPCClusterParam * clparam = AliTPCcalibDB::Instance()->GetClusterParam();
785   //
786   Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
787   Int_t ctype = cl->GetType();  
788   Int_t    type = (cl->GetRow()<63) ? 0: (cl->GetRow()>126) ? 1:2;
789   //
790   Double_t angle2 = seed->GetSnp()*seed->GetSnp();
791   angle2 = seed->GetTgl()*seed->GetTgl()*(1+angle2/(1-angle2)); 
792   Double_t angle = TMath::Sqrt(TMath::Abs(angle2));
793   Double_t errz2 = clparam->GetError0Par(1,type, z,angle);
794   if (ctype<0) {
795     errz2+=0.5;  // edge cluster
796   }
797   errz2*=errz2;
798   seed->SetErrorZ2(errz2);
799   //
800   return errz2;
801
802
803
804 //   //seed->SetErrorY2(0.1);
805 //   //return 0.1;
806 //   //calculate look-up table at the beginning
807 //   static Bool_t  ginit = kFALSE;
808 //   static Float_t gnoise1,gnoise2,gnoise3;
809 //   static Float_t ggg1[10000];
810 //   static Float_t ggg2[10000];
811 //   static Float_t ggg3[10000];
812 //   static Float_t glandau1[10000];
813 //   static Float_t glandau2[10000];
814 //   static Float_t glandau3[10000];
815 //   //
816 //   static Float_t gcor01[1000];
817 //   static Float_t gcor02[1000];
818 //   static Float_t gcorp[1000];
819 //   //
820
821 //   //
822 //   if (ginit==kFALSE){
823 //     for (Int_t i=1;i<1000;i++){
824 //       Float_t rsigma = float(i)/100.;
825 //       gcor02[i] = TMath::Max(0.81 +TMath::Exp(6.8*(rsigma-1.2)),0.6);
826 //       gcor01[i] = TMath::Max(0.72 +TMath::Exp(2.04*(rsigma-1.2)),0.6);
827 //       gcorp[i]  = TMath::Max(TMath::Power((rsigma+0.5),1.5),1.2);
828 //     }
829
830 //     //
831 //     for (Int_t i=3;i<10000;i++){
832 //       //
833 //       //
834 //       // inner sector
835 //       Float_t amp = float(i);
836 //       Float_t padlength =0.75;
837 //       gnoise1 = 0.0004/padlength;
838 //       Float_t nel     = 0.268*amp;
839 //       Float_t nprim   = 0.155*amp;
840 //       ggg1[i]          = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.001*nel/(padlength*padlength))/nel;
841 //       glandau1[i]      = (2.+0.12*nprim)*0.5* (2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
842 //       if (glandau1[i]>1) glandau1[i]=1;
843 //       glandau1[i]*=padlength*padlength/12.;      
844 //       //
845 //       // outer short
846 //       padlength =1.;
847 //       gnoise2   = 0.0004/padlength;
848 //       nel       = 0.3*amp;
849 //       nprim     = 0.133*amp;
850 //       ggg2[i]      = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
851 //       glandau2[i]  = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
852 //       if (glandau2[i]>1) glandau2[i]=1;
853 //       glandau2[i]*=padlength*padlength/12.;
854 //       //
855 //       //
856 //       // outer long
857 //       padlength =1.5;
858 //       gnoise3   = 0.0004/padlength;
859 //       nel       = 0.3*amp;
860 //       nprim     = 0.133*amp;
861 //       ggg3[i]      = fkParam->GetDiffT()*fkParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
862 //       glandau3[i]  = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
863 //       if (glandau3[i]>1) glandau3[i]=1;
864 //       glandau3[i]*=padlength*padlength/12.;
865 //       //
866 //     }
867 //     ginit = kTRUE;
868 //   }
869 //   //
870 //   //
871 //   //
872 //   Int_t amp = int(TMath::Abs(cl->GetQ()));  
873 //   if (amp>9999) {
874 //     seed->SetErrorY2(1.);
875 //     return 1.;
876 //   }
877 //   Float_t snoise2;
878 //   Float_t z = TMath::Abs(fkParam->GetZLength(0)-TMath::Abs(seed->GetZ()));
879 //   Int_t ctype = cl->GetType();  
880 //   Float_t padlength= GetPadPitchLength(seed->GetRow());
881 //   //
882 //   Double_t angle2 = seed->GetSnp()*seed->GetSnp();
883 //   //  if (angle2<0.6) angle2 = 0.6;
884 //   angle2 = seed->GetTgl()*seed->GetTgl()*(1+angle2/(1-angle2)); 
885 //   //
886 //   //cluster "quality"
887 //   Int_t rsigmaz = int(100.*cl->GetSigmaZ2()/(seed->GetCurrentSigmaZ2()));
888 //   Float_t res;
889 //   //
890 //   if (fSectors==fInnerSec){
891 //     snoise2 = gnoise1;
892 //     res     = ggg1[amp]*z+glandau1[amp]*angle2;     
893 //     if (ctype==0) res *= gcor01[rsigmaz];
894 //     if ((ctype>0)){
895 //       res+=0.002;
896 //       res*= gcorp[rsigmaz];
897 //     }
898 //   }
899 //   else {
900 //     if (padlength<1.1){
901 //       snoise2 = gnoise2;
902 //       res     = ggg2[amp]*z+glandau2[amp]*angle2; 
903 //       if (ctype==0) res *= gcor02[rsigmaz];      
904 //       if ((ctype>0)){
905 //      res+=0.002;
906 //      res*= gcorp[rsigmaz];
907 //       }
908 //     }
909 //     else{
910 //       snoise2 = gnoise3;      
911 //       res     = ggg3[amp]*z+glandau3[amp]*angle2; 
912 //       if (ctype==0) res *= gcor02[rsigmaz];
913 //       if ((ctype>0)){
914 //      res+=0.002;
915 //      res*= gcorp[rsigmaz];
916 //       }
917 //     }
918 //   }  
919
920 //   if (ctype<0){
921 //     res+=0.002;
922 //     res*=1.3;
923 //   }
924 //   if ((ctype<0) &&amp<70){
925 //     res+=0.002;
926 //     res*=1.3;  
927 //   }
928 //   res += snoise2;
929 //   if (res<2*snoise2)
930 //      res = 2*snoise2;
931 //   if (res>3) res =3;
932 //   seed->SetErrorZ2(res);
933 //   return res;
934 }
935
936
937
938
939
940 void AliTPCtrackerMI::RotateToLocal(AliTPCseed *seed)
941 {
942   //rotate to track "local coordinata
943   Float_t x = seed->GetX();
944   Float_t y = seed->GetY();
945   Float_t ymax = x*TMath::Tan(0.5*fSectors->GetAlpha());
946   
947   if (y > ymax) {
948     seed->SetRelativeSector((seed->GetRelativeSector()+1) % fN);
949     if (!seed->Rotate(fSectors->GetAlpha())) 
950       return;
951   } else if (y <-ymax) {
952     seed->SetRelativeSector((seed->GetRelativeSector()-1+fN) % fN);
953     if (!seed->Rotate(-fSectors->GetAlpha())) 
954       return;
955   }   
956
957 }
958
959
960
961 //_____________________________________________________________________________
962 Double_t AliTPCtrackerMI::F1old(Double_t x1,Double_t y1,
963                    Double_t x2,Double_t y2,
964                    Double_t x3,Double_t y3) const
965 {
966   //-----------------------------------------------------------------
967   // Initial approximation of the track curvature
968   //-----------------------------------------------------------------
969   Double_t d=(x2-x1)*(y3-y2)-(x3-x2)*(y2-y1);
970   Double_t a=0.5*((y3-y2)*(y2*y2-y1*y1+x2*x2-x1*x1)-
971                   (y2-y1)*(y3*y3-y2*y2+x3*x3-x2*x2));
972   Double_t b=0.5*((x2-x1)*(y3*y3-y2*y2+x3*x3-x2*x2)-
973                   (x3-x2)*(y2*y2-y1*y1+x2*x2-x1*x1));
974
975   Double_t xr=TMath::Abs(d/(d*x1-a)), yr=d/(d*y1-b);
976   if ( xr*xr+yr*yr<=0.00000000000001) return 100;
977   return -xr*yr/sqrt(xr*xr+yr*yr); 
978 }
979
980
981
982 //_____________________________________________________________________________
983 Double_t AliTPCtrackerMI::F1(Double_t x1,Double_t y1,
984                    Double_t x2,Double_t y2,
985                    Double_t x3,Double_t y3) const
986 {
987   //-----------------------------------------------------------------
988   // Initial approximation of the track curvature
989   //-----------------------------------------------------------------
990   x3 -=x1;
991   x2 -=x1;
992   y3 -=y1;
993   y2 -=y1;
994   //  
995   Double_t det = x3*y2-x2*y3;
996   if (TMath::Abs(det)<1e-10){
997     return 100;
998   }
999   //
1000   Double_t u = 0.5* (x2*(x2-x3)+y2*(y2-y3))/det;
1001   Double_t x0 = x3*0.5-y3*u;
1002   Double_t y0 = y3*0.5+x3*u;
1003   Double_t c2 = 1/TMath::Sqrt(x0*x0+y0*y0);
1004   if (det<0) c2*=-1;
1005   return c2;
1006 }
1007
1008
1009 Double_t AliTPCtrackerMI::F2(Double_t x1,Double_t y1,
1010                    Double_t x2,Double_t y2,
1011                    Double_t x3,Double_t y3) const 
1012 {
1013   //-----------------------------------------------------------------
1014   // Initial approximation of the track curvature
1015   //-----------------------------------------------------------------
1016   x3 -=x1;
1017   x2 -=x1;
1018   y3 -=y1;
1019   y2 -=y1;
1020   //  
1021   Double_t det = x3*y2-x2*y3;
1022   if (TMath::Abs(det)<1e-10) {
1023     return 100;
1024   }
1025   //
1026   Double_t u = 0.5* (x2*(x2-x3)+y2*(y2-y3))/det;
1027   Double_t x0 = x3*0.5-y3*u; 
1028   Double_t y0 = y3*0.5+x3*u;
1029   Double_t c2 = 1/TMath::Sqrt(x0*x0+y0*y0);
1030   if (det<0) c2*=-1;
1031   x0+=x1;
1032   x0*=c2;  
1033   return x0;
1034 }
1035
1036
1037
1038 //_____________________________________________________________________________
1039 Double_t AliTPCtrackerMI::F2old(Double_t x1,Double_t y1,
1040                    Double_t x2,Double_t y2,
1041                    Double_t x3,Double_t y3) const
1042 {
1043   //-----------------------------------------------------------------
1044   // Initial approximation of the track curvature times center of curvature
1045   //-----------------------------------------------------------------
1046   Double_t d=(x2-x1)*(y3-y2)-(x3-x2)*(y2-y1);
1047   Double_t a=0.5*((y3-y2)*(y2*y2-y1*y1+x2*x2-x1*x1)-
1048                   (y2-y1)*(y3*y3-y2*y2+x3*x3-x2*x2));
1049   Double_t b=0.5*((x2-x1)*(y3*y3-y2*y2+x3*x3-x2*x2)-
1050                   (x3-x2)*(y2*y2-y1*y1+x2*x2-x1*x1));
1051
1052   Double_t xr=TMath::Abs(d/(d*x1-a)), yr=d/(d*y1-b);
1053   
1054   return -a/(d*y1-b)*xr/sqrt(xr*xr+yr*yr);
1055 }
1056
1057 //_____________________________________________________________________________
1058 Double_t AliTPCtrackerMI::F3(Double_t x1,Double_t y1, 
1059                    Double_t x2,Double_t y2,
1060                    Double_t z1,Double_t z2) const
1061 {
1062   //-----------------------------------------------------------------
1063   // Initial approximation of the tangent of the track dip angle
1064   //-----------------------------------------------------------------
1065   return (z1 - z2)/sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
1066 }
1067
1068
1069 Double_t AliTPCtrackerMI::F3n(Double_t x1,Double_t y1, 
1070                    Double_t x2,Double_t y2,
1071                    Double_t z1,Double_t z2, Double_t c) const
1072 {
1073   //-----------------------------------------------------------------
1074   // Initial approximation of the tangent of the track dip angle
1075   //-----------------------------------------------------------------
1076
1077   //  Double_t angle1;
1078   
1079   //angle1    =  (z1-z2)*c/(TMath::ASin(c*x1-ni)-TMath::ASin(c*x2-ni));
1080   //
1081   Double_t d  =  TMath::Sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
1082   if (TMath::Abs(d*c*0.5)>1) return 0;
1083   //  Double_t   angle2    =  TMath::ASin(d*c*0.5);
1084   //  Double_t   angle2    =  AliTPCFastMath::FastAsin(d*c*0.5);
1085   Double_t   angle2    = (d*c*0.5>0.1)? TMath::ASin(d*c*0.5): AliTPCFastMath::FastAsin(d*c*0.5);
1086
1087   angle2  = (z1-z2)*c/(angle2*2.);
1088   return angle2;
1089 }
1090
1091 Bool_t   AliTPCtrackerMI::GetProlongation(Double_t x1, Double_t x2, Double_t x[5], Double_t &y, Double_t &z) const
1092 {//-----------------------------------------------------------------
1093   // This function find proloncation of a track to a reference plane x=x2.
1094   //-----------------------------------------------------------------
1095   
1096   Double_t dx=x2-x1;
1097
1098   if (TMath::Abs(x[4]*x1 - x[2]) >= 0.999) {   
1099     return kFALSE;
1100   }
1101
1102   Double_t c1=x[4]*x1 - x[2], r1=TMath::Sqrt((1.-c1)*(1.+c1));
1103   Double_t c2=x[4]*x2 - x[2], r2=TMath::Sqrt((1.-c2)*(1.+c2));  
1104   y = x[0];
1105   z = x[1];
1106   
1107   Double_t dy = dx*(c1+c2)/(r1+r2);
1108   Double_t dz = 0;
1109   //
1110   Double_t delta = x[4]*dx*(c1+c2)/(c1*r2 + c2*r1);
1111   
1112   if (TMath::Abs(delta)>0.01){
1113     dz = x[3]*TMath::ASin(delta)/x[4];
1114   }else{
1115     dz = x[3]*AliTPCFastMath::FastAsin(delta)/x[4];
1116   }
1117   
1118   //dz = x[3]*AliTPCFastMath::FastAsin(delta)/x[4];
1119
1120   y+=dy;
1121   z+=dz;
1122   
1123   return kTRUE;  
1124 }
1125
1126 Int_t  AliTPCtrackerMI::LoadClusters (TTree *const tree)
1127 {
1128   //
1129   //
1130   fInput = tree;
1131   return LoadClusters();
1132 }
1133
1134
1135 Int_t  AliTPCtrackerMI::LoadClusters(const TObjArray *arr)
1136 {
1137   //
1138   // load clusters to the memory
1139   AliTPCClustersRow *clrow = new AliTPCClustersRow("AliTPCclusterMI");
1140   Int_t lower   = arr->LowerBound();
1141   Int_t entries = arr->GetEntriesFast();
1142   
1143   for (Int_t i=lower; i<entries; i++) {
1144     clrow = (AliTPCClustersRow*) arr->At(i);
1145     if(!clrow) continue;
1146     if(!clrow->GetArray()) continue;
1147     
1148     //  
1149     Int_t sec,row;
1150     fkParam->AdjustSectorRow(clrow->GetID(),sec,row);
1151     
1152     for (Int_t icl=0; icl<clrow->GetArray()->GetEntriesFast(); icl++){
1153       Transform((AliTPCclusterMI*)(clrow->GetArray()->At(icl)));
1154     }
1155     //
1156     if (clrow->GetArray()->GetEntriesFast()<=0) continue;
1157     AliTPCtrackerRow * tpcrow=0;
1158     Int_t left=0;
1159     if (sec<fkNIS*2){
1160       tpcrow = &(fInnerSec[sec%fkNIS][row]);    
1161       left = sec/fkNIS;
1162     }
1163     else{
1164       tpcrow = &(fOuterSec[(sec-fkNIS*2)%fkNOS][row]);
1165       left = (sec-fkNIS*2)/fkNOS;
1166     }
1167     if (left ==0){
1168       tpcrow->SetN1(clrow->GetArray()->GetEntriesFast());
1169       tpcrow->SetClusters1(new AliTPCclusterMI[tpcrow->GetN1()]);
1170       for (Int_t j=0;j<tpcrow->GetN1();++j) 
1171         tpcrow->SetCluster1(j, *(AliTPCclusterMI*)(clrow->GetArray()->At(j)));
1172     }
1173     if (left ==1){
1174       tpcrow->SetN2(clrow->GetArray()->GetEntriesFast());
1175       tpcrow->SetClusters2(new AliTPCclusterMI[tpcrow->GetN2()]);
1176       for (Int_t j=0;j<tpcrow->GetN2();++j) 
1177         tpcrow->SetCluster2(j,*(AliTPCclusterMI*)(clrow->GetArray()->At(j)));
1178     }
1179     clrow->GetArray()->Clear("C");
1180   }
1181   //
1182   delete clrow;
1183   LoadOuterSectors();
1184   LoadInnerSectors();
1185   return 0;
1186 }
1187
1188 Int_t  AliTPCtrackerMI::LoadClusters(const TClonesArray *arr)
1189 {
1190   //
1191   // load clusters to the memory from one 
1192   // TClonesArray
1193   //
1194   AliTPCclusterMI *clust=0;
1195   Int_t count[72][96] = { {0} , {0} }; 
1196
1197   // loop over clusters
1198   for (Int_t icl=0; icl<arr->GetEntriesFast(); icl++) {
1199     clust = (AliTPCclusterMI*)arr->At(icl);
1200     if(!clust) continue;
1201     //printf("cluster: det %d, row %d \n", clust->GetDetector(),clust->GetRow());
1202
1203     // transform clusters
1204     Transform(clust);
1205
1206     // count clusters per pad row
1207     count[clust->GetDetector()][clust->GetRow()]++;
1208   }
1209
1210   // insert clusters to sectors
1211   for (Int_t icl=0; icl<arr->GetEntriesFast(); icl++) {
1212     clust = (AliTPCclusterMI*)arr->At(icl);
1213     if(!clust) continue;
1214
1215     Int_t sec = clust->GetDetector();
1216     Int_t row = clust->GetRow();
1217
1218     // filter overlapping pad rows needed by HLT
1219     if(sec<fkNIS*2) { //IROCs
1220      if(row == 30) continue;
1221     }
1222     else { // OROCs
1223       if(row == 27 || row == 76) continue;
1224     }
1225
1226     Int_t left=0;
1227     if (sec<fkNIS*2){
1228       left = sec/fkNIS;
1229       fInnerSec[sec%fkNIS].InsertCluster(clust, count[sec][row], fkParam);    
1230     }
1231     else{
1232       left = (sec-fkNIS*2)/fkNOS;
1233       fOuterSec[(sec-fkNIS*2)%fkNOS].InsertCluster(clust, count[sec][row], fkParam);
1234     }
1235   }
1236
1237   // Load functions must be called behind LoadCluster(TClonesArray*)
1238   // needed by HLT
1239   //LoadOuterSectors();
1240   //LoadInnerSectors();
1241
1242   return 0;
1243 }
1244
1245
1246 Int_t  AliTPCtrackerMI::LoadClusters()
1247 {
1248   //
1249   // load clusters to the memory
1250   AliTPCClustersRow *clrow= new AliTPCClustersRow("AliTPCclusterMI");
1251   //
1252   //  TTree * tree = fClustersArray.GetTree();
1253
1254   TTree * tree = fInput;
1255   TBranch * br = tree->GetBranch("Segment");
1256   br->SetAddress(&clrow);
1257   //
1258   Int_t j=Int_t(tree->GetEntries());
1259   for (Int_t i=0; i<j; i++) {
1260     br->GetEntry(i);
1261     //  
1262     Int_t sec,row;
1263     fkParam->AdjustSectorRow(clrow->GetID(),sec,row);
1264     for (Int_t icl=0; icl<clrow->GetArray()->GetEntriesFast(); icl++){
1265       Transform((AliTPCclusterMI*)(clrow->GetArray()->At(icl)));
1266     }
1267     //
1268     AliTPCtrackerRow * tpcrow=0;
1269     Int_t left=0;
1270     if (sec<fkNIS*2){
1271       tpcrow = &(fInnerSec[sec%fkNIS][row]);    
1272       left = sec/fkNIS;
1273     }
1274     else{
1275       tpcrow = &(fOuterSec[(sec-fkNIS*2)%fkNOS][row]);
1276       left = (sec-fkNIS*2)/fkNOS;
1277     }
1278     if (left ==0){
1279       tpcrow->SetN1(clrow->GetArray()->GetEntriesFast());
1280       tpcrow->SetClusters1(new AliTPCclusterMI[tpcrow->GetN1()]);
1281       for (Int_t k=0;k<tpcrow->GetN1();++k) 
1282         tpcrow->SetCluster1(k, *(AliTPCclusterMI*)(clrow->GetArray()->At(k)));
1283     }
1284     if (left ==1){
1285       tpcrow->SetN2(clrow->GetArray()->GetEntriesFast());
1286       tpcrow->SetClusters2(new AliTPCclusterMI[tpcrow->GetN2()]);
1287       for (Int_t k=0;k<tpcrow->GetN2();++k) 
1288         tpcrow->SetCluster2(k,*(AliTPCclusterMI*)(clrow->GetArray()->At(k)));
1289     }
1290   }
1291   //
1292   delete clrow;
1293   LoadOuterSectors();
1294   LoadInnerSectors();
1295   return 0;
1296 }
1297
1298
1299 void AliTPCtrackerMI::UnloadClusters()
1300 {
1301   //
1302   // unload clusters from the memory
1303   //
1304   Int_t nrows = fOuterSec->GetNRows();
1305   for (Int_t sec = 0;sec<fkNOS;sec++)
1306     for (Int_t row = 0;row<nrows;row++){
1307       AliTPCtrackerRow*  tpcrow = &(fOuterSec[sec%fkNOS][row]);
1308       //      if (tpcrow){
1309       //        if (tpcrow->fClusters1) delete []tpcrow->fClusters1; 
1310       //        if (tpcrow->fClusters2) delete []tpcrow->fClusters2; 
1311       //}
1312       tpcrow->ResetClusters();
1313     }
1314   //
1315   nrows = fInnerSec->GetNRows();
1316   for (Int_t sec = 0;sec<fkNIS;sec++)
1317     for (Int_t row = 0;row<nrows;row++){
1318       AliTPCtrackerRow*  tpcrow = &(fInnerSec[sec%fkNIS][row]);
1319       //if (tpcrow){
1320       //        if (tpcrow->fClusters1) delete []tpcrow->fClusters1; 
1321       //if (tpcrow->fClusters2) delete []tpcrow->fClusters2; 
1322       //}
1323       tpcrow->ResetClusters();
1324     }
1325
1326   return ;
1327 }
1328
1329 void AliTPCtrackerMI::FillClusterArray(TObjArray* array) const{
1330   //
1331   // Filling cluster to the array - For visualization purposes
1332   //
1333   Int_t nrows=0;
1334   nrows = fOuterSec->GetNRows();
1335   for (Int_t sec = 0;sec<fkNOS;sec++)
1336     for (Int_t row = 0;row<nrows;row++){
1337       AliTPCtrackerRow*  tpcrow = &(fOuterSec[sec%fkNOS][row]);
1338       if (!tpcrow) continue;
1339       for (Int_t icl = 0;icl<tpcrow->GetN();icl++){
1340         array->AddLast((TObject*)((*tpcrow)[icl]));
1341       }
1342     } 
1343   nrows = fInnerSec->GetNRows();
1344   for (Int_t sec = 0;sec<fkNIS;sec++)
1345     for (Int_t row = 0;row<nrows;row++){
1346       AliTPCtrackerRow*  tpcrow = &(fInnerSec[sec%fkNIS][row]);
1347       if (!tpcrow) continue;
1348       for (Int_t icl = 0;icl<tpcrow->GetN();icl++){
1349         array->AddLast((TObject*)(*tpcrow)[icl]);
1350       }
1351     }
1352 }
1353
1354
1355 void   AliTPCtrackerMI::Transform(AliTPCclusterMI * cluster){
1356   //
1357   //
1358   //
1359   AliTPCcalibDB * calibDB = AliTPCcalibDB::Instance();
1360   AliTPCTransform *transform = calibDB->GetTransform() ;
1361   if (!transform) {
1362     AliFatal("Tranformations not in calibDB");
1363     return;
1364   }
1365   transform->SetCurrentRecoParam((AliTPCRecoParam*)AliTPCReconstructor::GetRecoParam());
1366   Double_t x[3]={cluster->GetRow(),cluster->GetPad(),cluster->GetTimeBin()};
1367   Int_t i[1]={cluster->GetDetector()};
1368   transform->Transform(x,i,0,1);  
1369   //  if (cluster->GetDetector()%36>17){
1370   //  x[1]*=-1;
1371   //}
1372
1373   //
1374   // in debug mode  check the transformation
1375   //
1376   if (AliTPCReconstructor::StreamLevel()>2) {
1377     Float_t gx[3];
1378     cluster->GetGlobalXYZ(gx);
1379     Int_t event = (fEvent==NULL)? 0: fEvent->GetEventNumberInFile();
1380     TTreeSRedirector &cstream = *fDebugStreamer;
1381     cstream<<"Transform"<<
1382       "event="<<event<<
1383       "x0="<<x[0]<<
1384       "x1="<<x[1]<<
1385       "x2="<<x[2]<<
1386       "gx0="<<gx[0]<<
1387       "gx1="<<gx[1]<<
1388       "gx2="<<gx[2]<<
1389       "Cl.="<<cluster<<
1390       "\n"; 
1391   }
1392   cluster->SetX(x[0]);
1393   cluster->SetY(x[1]);
1394   cluster->SetZ(x[2]);
1395   // The old stuff:
1396   //
1397   // 
1398   //
1399   //if (!fkParam->IsGeoRead()) fkParam->ReadGeoMatrices();
1400   if (AliTPCReconstructor::GetRecoParam()->GetUseSectorAlignment() && (!calibDB->HasAlignmentOCDB())){
1401     TGeoHMatrix  *mat = fkParam->GetClusterMatrix(cluster->GetDetector());
1402     //TGeoHMatrix  mat;
1403     Double_t pos[3]= {cluster->GetX(),cluster->GetY(),cluster->GetZ()};
1404     Double_t posC[3]={cluster->GetX(),cluster->GetY(),cluster->GetZ()};
1405     if (mat) mat->LocalToMaster(pos,posC);
1406     else{
1407       // chack Loading of Geo matrices from GeoManager - TEMPORARY FIX
1408     }
1409     cluster->SetX(posC[0]);
1410     cluster->SetY(posC[1]);
1411     cluster->SetZ(posC[2]);
1412   }
1413 }
1414
1415 //_____________________________________________________________________________
1416 Int_t AliTPCtrackerMI::LoadOuterSectors() {
1417   //-----------------------------------------------------------------
1418   // This function fills outer TPC sectors with clusters.
1419   //-----------------------------------------------------------------
1420   Int_t nrows = fOuterSec->GetNRows();
1421   UInt_t index=0;
1422   for (Int_t sec = 0;sec<fkNOS;sec++)
1423     for (Int_t row = 0;row<nrows;row++){
1424       AliTPCtrackerRow*  tpcrow = &(fOuterSec[sec%fkNOS][row]);  
1425       Int_t sec2 = sec+2*fkNIS;
1426       //left
1427       Int_t ncl = tpcrow->GetN1();
1428       while (ncl--) {
1429         AliTPCclusterMI *c= (tpcrow->GetCluster1(ncl));
1430         index=(((sec2<<8)+row)<<16)+ncl;
1431         tpcrow->InsertCluster(c,index);
1432       }
1433       //right
1434       ncl = tpcrow->GetN2();
1435       while (ncl--) {
1436         AliTPCclusterMI *c= (tpcrow->GetCluster2(ncl));
1437         index=((((sec2+fkNOS)<<8)+row)<<16)+ncl;
1438         tpcrow->InsertCluster(c,index);
1439       }
1440       //
1441       // write indexes for fast acces
1442       //
1443       for (Int_t i=0;i<510;i++)
1444         tpcrow->SetFastCluster(i,-1);
1445       for (Int_t i=0;i<tpcrow->GetN();i++){
1446         Int_t zi = Int_t((*tpcrow)[i]->GetZ()+255.);
1447         tpcrow->SetFastCluster(zi,i);  // write index
1448       }
1449       Int_t last = 0;
1450       for (Int_t i=0;i<510;i++){
1451         if (tpcrow->GetFastCluster(i)<0)
1452           tpcrow->SetFastCluster(i,last);
1453         else
1454           last = tpcrow->GetFastCluster(i);
1455       }
1456     }  
1457   fN=fkNOS;
1458   fSectors=fOuterSec;
1459   return 0;
1460 }
1461
1462
1463 //_____________________________________________________________________________
1464 Int_t  AliTPCtrackerMI::LoadInnerSectors() {
1465   //-----------------------------------------------------------------
1466   // This function fills inner TPC sectors with clusters.
1467   //-----------------------------------------------------------------
1468   Int_t nrows = fInnerSec->GetNRows();
1469   UInt_t index=0;
1470   for (Int_t sec = 0;sec<fkNIS;sec++)
1471     for (Int_t row = 0;row<nrows;row++){
1472       AliTPCtrackerRow*  tpcrow = &(fInnerSec[sec%fkNIS][row]);
1473       //
1474       //left
1475       Int_t ncl = tpcrow->GetN1();
1476       while (ncl--) {
1477         AliTPCclusterMI *c= (tpcrow->GetCluster1(ncl));
1478         index=(((sec<<8)+row)<<16)+ncl;
1479         tpcrow->InsertCluster(c,index);
1480       }
1481       //right
1482       ncl = tpcrow->GetN2();
1483       while (ncl--) {
1484         AliTPCclusterMI *c= (tpcrow->GetCluster2(ncl));
1485         index=((((sec+fkNIS)<<8)+row)<<16)+ncl;
1486         tpcrow->InsertCluster(c,index);
1487       }
1488       //
1489       // write indexes for fast acces
1490       //
1491       for (Int_t i=0;i<510;i++)
1492         tpcrow->SetFastCluster(i,-1);
1493       for (Int_t i=0;i<tpcrow->GetN();i++){
1494         Int_t zi = Int_t((*tpcrow)[i]->GetZ()+255.);
1495         tpcrow->SetFastCluster(zi,i);  // write index
1496       }
1497       Int_t last = 0;
1498       for (Int_t i=0;i<510;i++){
1499         if (tpcrow->GetFastCluster(i)<0)
1500           tpcrow->SetFastCluster(i,last);
1501         else
1502           last = tpcrow->GetFastCluster(i);
1503       }
1504
1505     }  
1506    
1507   fN=fkNIS;
1508   fSectors=fInnerSec;
1509   return 0;
1510 }
1511
1512
1513
1514 //_________________________________________________________________________
1515 AliTPCclusterMI *AliTPCtrackerMI::GetClusterMI(Int_t index) const {
1516   //--------------------------------------------------------------------
1517   //       Return pointer to a given cluster
1518   //--------------------------------------------------------------------
1519   if (index<0) return 0; // no cluster
1520   Int_t sec=(index&0xff000000)>>24; 
1521   Int_t row=(index&0x00ff0000)>>16; 
1522   Int_t ncl=(index&0x00007fff)>>00;
1523
1524   const AliTPCtrackerRow * tpcrow=0;
1525   AliTPCclusterMI * clrow =0;
1526
1527   if (sec<0 || sec>=fkNIS*4) {
1528     AliWarning(Form("Wrong sector %d",sec));
1529     return 0x0;
1530   }
1531
1532   if (sec<fkNIS*2){
1533     AliTPCtrackerSector& tracksec = fInnerSec[sec%fkNIS];
1534     if (tracksec.GetNRows()<=row) return 0;
1535     tpcrow = &(tracksec[row]);
1536     if (tpcrow==0) return 0;
1537
1538     if (sec<fkNIS) {
1539       if (tpcrow->GetN1()<=ncl) return 0;
1540       clrow = tpcrow->GetClusters1();
1541     }
1542     else {
1543       if (tpcrow->GetN2()<=ncl) return 0;
1544       clrow = tpcrow->GetClusters2();
1545     }
1546   }
1547   else {
1548     AliTPCtrackerSector& tracksec = fOuterSec[(sec-fkNIS*2)%fkNOS];
1549     if (tracksec.GetNRows()<=row) return 0;
1550     tpcrow = &(tracksec[row]);
1551     if (tpcrow==0) return 0;
1552
1553     if (sec-2*fkNIS<fkNOS) {
1554       if (tpcrow->GetN1()<=ncl) return 0;
1555       clrow = tpcrow->GetClusters1();
1556     }
1557     else {
1558       if (tpcrow->GetN2()<=ncl) return 0;
1559       clrow = tpcrow->GetClusters2();
1560     }
1561   }
1562
1563   return &(clrow[ncl]);      
1564   
1565 }
1566
1567
1568
1569 Int_t AliTPCtrackerMI::FollowToNext(AliTPCseed& t, Int_t nr) {
1570   //-----------------------------------------------------------------
1571   // This function tries to find a track prolongation to next pad row
1572   //-----------------------------------------------------------------
1573   //
1574   Double_t  x= GetXrow(nr), ymax=GetMaxY(nr);
1575   //
1576   //
1577   AliTPCclusterMI *cl=0;
1578   Int_t tpcindex= t.GetClusterIndex2(nr);
1579   //
1580   // update current shape info every 5 pad-row
1581   //  if ( (nr%5==0) || t.GetNumberOfClusters()<2 || (t.fCurrentSigmaY2<0.0001) ){
1582     GetShape(&t,nr);    
1583     //}
1584   //  
1585   if (fIteration>0 && tpcindex>=-1){  //if we have already clusters 
1586     //        
1587     if (tpcindex==-1) return 0; //track in dead zone
1588     if (tpcindex>0){     //
1589       cl = t.GetClusterPointer(nr);
1590       if ( (cl==0) ) cl = GetClusterMI(tpcindex);
1591       t.SetCurrentClusterIndex1(tpcindex); 
1592     }
1593     if (cl){      
1594       Int_t relativesector = ((tpcindex&0xff000000)>>24)%18;  // if previously accepted cluster in different sector
1595       Float_t angle = relativesector*fSectors->GetAlpha()+fSectors->GetAlphaShift();
1596       //
1597       if (angle<-TMath::Pi()) angle += 2*TMath::Pi();
1598       if (angle>=TMath::Pi()) angle -= 2*TMath::Pi();
1599       
1600       if (TMath::Abs(angle-t.GetAlpha())>0.001){
1601         Double_t rotation = angle-t.GetAlpha();
1602         t.SetRelativeSector(relativesector);
1603         if (!t.Rotate(rotation)) return 0;      
1604       }
1605       if (!t.PropagateTo(x)) return 0;
1606       //
1607       t.SetCurrentCluster(cl); 
1608       t.SetRow(nr);
1609       Int_t accept = AcceptCluster(&t,t.GetCurrentCluster());
1610       if ((tpcindex&0x8000)==0) accept =0;
1611       if (accept<3) { 
1612         //if founded cluster is acceptible
1613         if (cl->IsUsed(11)) {  // id cluster is shared inrease uncertainty
1614           t.SetErrorY2(t.GetErrorY2()+0.03);
1615           t.SetErrorZ2(t.GetErrorZ2()+0.03); 
1616           t.SetErrorY2(t.GetErrorY2()*3);
1617           t.SetErrorZ2(t.GetErrorZ2()*3); 
1618         }
1619         t.SetNFoundable(t.GetNFoundable()+1);
1620         UpdateTrack(&t,accept);
1621         return 1;
1622       }    
1623     }
1624   }
1625   if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()) return 0;  // cut on angle
1626   if (fIteration>1 && IsFindable(t)){
1627     // not look for new cluster during refitting    
1628     t.SetNFoundable(t.GetNFoundable()+1);
1629     return 0;
1630   }
1631   //
1632   UInt_t index=0;
1633   //  if (TMath::Abs(t.GetSnp())>0.95 || TMath::Abs(x*t.GetC()-t.GetEta())>0.95) return 0;// patch 28 fev 06
1634   Double_t  y=t.GetYat(x);
1635   if (TMath::Abs(y)>ymax){
1636     if (y > ymax) {
1637       t.SetRelativeSector((t.GetRelativeSector()+1) % fN);
1638       if (!t.Rotate(fSectors->GetAlpha())) 
1639         return 0;
1640     } else if (y <-ymax) {
1641       t.SetRelativeSector((t.GetRelativeSector()-1+fN) % fN);
1642       if (!t.Rotate(-fSectors->GetAlpha())) 
1643         return 0;
1644     }
1645     //return 1;
1646   }
1647   //
1648   if (!t.PropagateTo(x)) {
1649     if (fIteration==0) t.SetRemoval(10);
1650     return 0;
1651   }
1652   y=t.GetY(); 
1653   Double_t z=t.GetZ();
1654   //
1655
1656   if (!IsActive(t.GetRelativeSector(),nr)) {
1657     t.SetInDead(kTRUE);
1658     t.SetClusterIndex2(nr,-1); 
1659     return 0;
1660   }
1661   //AliInfo(Form("A - Sector%d phi %f - alpha %f", t.fRelativeSector,y/x, t.GetAlpha()));
1662   Bool_t isActive  = IsActive(t.GetRelativeSector(),nr);
1663   Bool_t isActive2 = (nr>=fInnerSec->GetNRows()) ? fOuterSec[t.GetRelativeSector()][nr-fInnerSec->GetNRows()].GetN()>0:fInnerSec[t.GetRelativeSector()][nr].GetN()>0;
1664   
1665   if (!isActive || !isActive2) return 0;
1666
1667   const AliTPCtrackerRow &krow=GetRow(t.GetRelativeSector(),nr);
1668   if ( (t.GetSigmaY2()<0) || t.GetSigmaZ2()<0) return 0;
1669   Double_t  roady  =1.;
1670   Double_t  roadz = 1.;
1671   //
1672   if (TMath::Abs(TMath::Abs(y)-ymax)<krow.GetDeadZone()){
1673     t.SetInDead(kTRUE);
1674     t.SetClusterIndex2(nr,-1); 
1675     return 0;
1676   } 
1677   else
1678     {
1679       if (IsFindable(t))
1680           //      if (TMath::Abs(z)<(AliTPCReconstructor::GetCtgRange()*x+10) && TMath::Abs(z)<fkParam->GetZLength(0) && (TMath::Abs(t.GetSnp())<AliTPCReconstructor::GetMaxSnpTracker())) 
1681         t.SetNFoundable(t.GetNFoundable()+1);
1682       else
1683         return 0;
1684     }   
1685   //calculate 
1686   if (krow) {
1687     //    cl = krow.FindNearest2(y+10.,z,roady,roadz,index);    
1688     cl = krow.FindNearest2(y,z,roady,roadz,index);    
1689     if (cl) t.SetCurrentClusterIndex1(krow.GetIndex(index));       
1690   }  
1691   if (cl) {
1692     t.SetCurrentCluster(cl); 
1693     t.SetRow(nr);
1694     if (fIteration==2&&cl->IsUsed(10)) return 0; 
1695     Int_t accept = AcceptCluster(&t,t.GetCurrentCluster());
1696     if (fIteration==2&&cl->IsUsed(11)) {
1697       t.SetErrorY2(t.GetErrorY2()+0.03);
1698       t.SetErrorZ2(t.GetErrorZ2()+0.03); 
1699       t.SetErrorY2(t.GetErrorY2()*3);
1700       t.SetErrorZ2(t.GetErrorZ2()*3); 
1701     }
1702     /*    
1703     if (t.fCurrentCluster->IsUsed(10)){
1704       //
1705       //     
1706
1707       t.fNShared++;
1708       if (t.fNShared>0.7*t.GetNumberOfClusters()) {
1709         t.fRemoval =10;
1710         return 0;
1711       }
1712     }
1713     */
1714     if (accept<3) UpdateTrack(&t,accept);
1715
1716   } else {  
1717     if ( fIteration==0 && t.GetNFoundable()*0.5 > t.GetNumberOfClusters()) t.SetRemoval(10);
1718     
1719   }
1720   return 1;
1721 }
1722
1723
1724
1725 //_________________________________________________________________________
1726 Bool_t AliTPCtrackerMI::GetTrackPoint(Int_t index, AliTrackPoint &p ) const
1727 {
1728   // Get track space point by index
1729   // return false in case the cluster doesn't exist
1730   AliTPCclusterMI *cl = GetClusterMI(index);
1731   if (!cl) return kFALSE;
1732   Int_t sector = (index&0xff000000)>>24;
1733   //  Int_t row = (index&0x00ff0000)>>16;
1734   Float_t xyz[3];
1735   //  xyz[0] = fkParam->GetPadRowRadii(sector,row);
1736   xyz[0] = cl->GetX();
1737   xyz[1] = cl->GetY();
1738   xyz[2] = cl->GetZ();
1739   Float_t sin,cos;
1740   fkParam->AdjustCosSin(sector,cos,sin);
1741   Float_t x = cos*xyz[0]-sin*xyz[1];
1742   Float_t y = cos*xyz[1]+sin*xyz[0];
1743   Float_t cov[6];
1744   Float_t sigmaY2 = 0.027*cl->GetSigmaY2();
1745   if (sector < fkParam->GetNInnerSector()) sigmaY2 *= 2.07;
1746   Float_t sigmaZ2 = 0.066*cl->GetSigmaZ2();
1747   if (sector < fkParam->GetNInnerSector()) sigmaZ2 *= 1.77;
1748   cov[0] = sin*sin*sigmaY2;
1749   cov[1] = -sin*cos*sigmaY2;
1750   cov[2] = 0.;
1751   cov[3] = cos*cos*sigmaY2;
1752   cov[4] = 0.;
1753   cov[5] = sigmaZ2;
1754   p.SetXYZ(x,y,xyz[2],cov);
1755   AliGeomManager::ELayerID iLayer;
1756   Int_t idet;
1757   if (sector < fkParam->GetNInnerSector()) {
1758     iLayer = AliGeomManager::kTPC1;
1759     idet = sector;
1760   }
1761   else {
1762     iLayer = AliGeomManager::kTPC2;
1763     idet = sector - fkParam->GetNInnerSector();
1764   }
1765   UShort_t volid = AliGeomManager::LayerToVolUID(iLayer,idet);
1766   p.SetVolumeID(volid);
1767   return kTRUE;
1768 }
1769
1770
1771
1772 Int_t AliTPCtrackerMI::UpdateClusters(AliTPCseed& t,  Int_t nr) {
1773   //-----------------------------------------------------------------
1774   // This function tries to find a track prolongation to next pad row
1775   //-----------------------------------------------------------------
1776   t.SetCurrentCluster(0);
1777   t.SetCurrentClusterIndex1(0);   
1778    
1779   Double_t xt=t.GetX();
1780   Int_t     row = GetRowNumber(xt)-1; 
1781   Double_t  ymax= GetMaxY(nr);
1782
1783   if (row < nr) return 1; // don't prolongate if not information until now -
1784 //   if (TMath::Abs(t.GetSnp())>0.9 && t.GetNumberOfClusters()>40. && fIteration!=2) {
1785 //     t.fRemoval =10;
1786 //     return 0;  // not prolongate strongly inclined tracks
1787 //   } 
1788 //   if (TMath::Abs(t.GetSnp())>0.95) {
1789 //     t.fRemoval =10;
1790 //     return 0;  // not prolongate strongly inclined tracks
1791 //   }// patch 28 fev 06
1792
1793   Double_t x= GetXrow(nr);
1794   Double_t y,z;
1795   //t.PropagateTo(x+0.02);
1796   //t.PropagateTo(x+0.01);
1797   if (!t.PropagateTo(x)){
1798     return 0;
1799   }
1800   //
1801   y=t.GetY();
1802   z=t.GetZ();
1803
1804   if (TMath::Abs(y)>ymax){
1805     if (y > ymax) {
1806       t.SetRelativeSector((t.GetRelativeSector()+1) % fN);
1807       if (!t.Rotate(fSectors->GetAlpha())) 
1808         return 0;
1809     } else if (y <-ymax) {
1810       t.SetRelativeSector((t.GetRelativeSector()-1+fN) % fN);
1811       if (!t.Rotate(-fSectors->GetAlpha())) 
1812         return 0;
1813     }
1814     //    if (!t.PropagateTo(x)){
1815     //  return 0;
1816     //}
1817     return 1;
1818     //y = t.GetY();    
1819   }
1820   //
1821   if (TMath::Abs(t.GetSnp())>AliTPCReconstructor::GetMaxSnpTracker()) return 0;
1822
1823   if (!IsActive(t.GetRelativeSector(),nr)) {
1824     t.SetInDead(kTRUE);
1825     t.SetClusterIndex2(nr,-1); 
1826     return 0;
1827   }
1828   //AliInfo(Form("A - Sector%d phi %f - alpha %f", t.fRelativeSector,y/x, t.GetAlpha()));
1829
1830   AliTPCtrackerRow &krow=GetRow(t.GetRelativeSector(),nr);
1831
1832   if (TMath::Abs(TMath::Abs(y)-ymax)<krow.GetDeadZone()){
1833     t.SetInDead(kTRUE);
1834     t.SetClusterIndex2(nr,-1); 
1835     return 0;
1836   } 
1837   else
1838     {
1839
1840       //      if (TMath::Abs(t.GetZ())<(AliTPCReconstructor::GetCtgRange()*t.GetX()+10) && (TMath::Abs(t.GetSnp())<AliTPCReconstructor::GetMaxSnpTracker())) 
1841       if (IsFindable(t)) t.SetNFoundable(t.GetNFoundable()+1);
1842       else
1843         return 0;      
1844     }
1845
1846   // update current
1847   if ( (nr%2==0) || t.GetNumberOfClusters()<2){
1848     //    t.fCurrentSigmaY = GetSigmaY(&t);
1849     //t.fCurrentSigmaZ = GetSigmaZ(&t);
1850     GetShape(&t,nr);
1851   }
1852     
1853   AliTPCclusterMI *cl=0;
1854   Int_t index=0;
1855   //
1856   Double_t roady = 1.;
1857   Double_t roadz = 1.;
1858   //
1859
1860   if (!cl){
1861     index = t.GetClusterIndex2(nr);    
1862     if ( (index>0) && (index&0x8000)==0){
1863       cl = t.GetClusterPointer(nr);
1864       if ( (cl==0) && (index>0)) cl = GetClusterMI(index);
1865       t.SetCurrentClusterIndex1(index);
1866       if (cl) {
1867         t.SetCurrentCluster(cl);
1868         return 1;
1869       }
1870     }
1871   }
1872
1873   //  if (index<0) return 0;
1874   UInt_t uindex = TMath::Abs(index);
1875
1876   if (krow) {    
1877     //cl = krow.FindNearest2(y+10,z,roady,roadz,uindex);      
1878     cl = krow.FindNearest2(y,z,roady,roadz,uindex);      
1879   }
1880
1881   if (cl) t.SetCurrentClusterIndex1(krow.GetIndex(uindex));   
1882   t.SetCurrentCluster(cl);
1883
1884   return 1;
1885 }
1886
1887
1888 Int_t AliTPCtrackerMI::FollowToNextCluster(AliTPCseed & t, Int_t nr) {
1889   //-----------------------------------------------------------------
1890   // This function tries to find a track prolongation to next pad row
1891   //-----------------------------------------------------------------
1892
1893   //update error according neighborhoud
1894
1895   if (t.GetCurrentCluster()) {
1896     t.SetRow(nr); 
1897     Int_t accept = AcceptCluster(&t,t.GetCurrentCluster());
1898     
1899     if (t.GetCurrentCluster()->IsUsed(10)){
1900       //
1901       //
1902       //  t.fErrorZ2*=2;
1903       //  t.fErrorY2*=2;
1904       t.SetNShared(t.GetNShared()+1);
1905       if (t.GetNShared()>0.7*t.GetNumberOfClusters()) {
1906         t.SetRemoval(10);
1907         return 0;
1908       }
1909     }   
1910     if (fIteration>0) accept = 0;
1911     if (accept<3)  UpdateTrack(&t,accept);  
1912  
1913   } else {
1914     if (fIteration==0){
1915       if ( ( (t.GetSigmaY2()+t.GetSigmaZ2())>0.16)&& t.GetNumberOfClusters()>18) t.SetRemoval(10);      
1916       if (  t.GetChi2()/t.GetNumberOfClusters()>6 &&t.GetNumberOfClusters()>18) t.SetRemoval(10);      
1917
1918       if (( (t.GetNFoundable()*0.5 > t.GetNumberOfClusters()) || t.GetNoCluster()>15)) t.SetRemoval(10);
1919     }
1920   }
1921   return 1;
1922 }
1923
1924
1925
1926 //_____________________________________________________________________________
1927 Int_t AliTPCtrackerMI::FollowProlongation(AliTPCseed& t, Int_t rf, Int_t step) {
1928   //-----------------------------------------------------------------
1929   // This function tries to find a track prolongation.
1930   //-----------------------------------------------------------------
1931   Double_t xt=t.GetX();
1932   //
1933   Double_t alpha=t.GetAlpha() - fSectors->GetAlphaShift();
1934   if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();  
1935   if (alpha < 0.            ) alpha += 2.*TMath::Pi();  
1936   //
1937   t.SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
1938     
1939   Int_t first = GetRowNumber(xt)-1;
1940   for (Int_t nr= first; nr>=rf; nr-=step) {
1941     // update kink info
1942     if (t.GetKinkIndexes()[0]>0){
1943       for (Int_t i=0;i<3;i++){
1944         Int_t index = t.GetKinkIndexes()[i];
1945         if (index==0) break;
1946         if (index<0) continue;
1947         //
1948         AliKink * kink = (AliKink*)fEvent->GetKink(index-1);
1949         if (!kink){
1950           printf("PROBLEM\n");
1951         }
1952         else{
1953           Int_t kinkrow = kink->GetTPCRow0()+2+Int_t(0.5/(0.05+kink->GetAngle(2)));
1954           if (kinkrow==nr){
1955             AliExternalTrackParam paramd(t);
1956             kink->SetDaughter(paramd);
1957             kink->SetStatus(2,5);
1958             kink->Update();
1959           }
1960         }
1961       }
1962     }
1963
1964     if (nr==80) t.UpdateReference();
1965     if (nr<fInnerSec->GetNRows()) 
1966       fSectors = fInnerSec;
1967     else
1968       fSectors = fOuterSec;
1969     if (FollowToNext(t,nr)==0) 
1970       if (!t.IsActive()) 
1971         return 0;
1972     
1973   }   
1974   return 1;
1975 }
1976
1977
1978
1979
1980
1981
1982 Int_t AliTPCtrackerMI::FollowBackProlongation(AliTPCseed& t, Int_t rf) {
1983   //-----------------------------------------------------------------
1984   // This function tries to find a track prolongation.
1985   //-----------------------------------------------------------------
1986   //
1987   Double_t xt=t.GetX();  
1988   Double_t alpha=t.GetAlpha() - fSectors->GetAlphaShift();
1989   if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();  
1990   if (alpha < 0.            ) alpha += 2.*TMath::Pi();  
1991   t.SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
1992     
1993   Int_t first = t.GetFirstPoint();
1994   if (first<GetRowNumber(xt)+1) first = GetRowNumber(xt)+1;
1995   //
1996   if (first<0) first=0;
1997   for (Int_t nr=first; nr<=rf; nr++) {
1998     //    if ( (TMath::Abs(t.GetSnp())>0.95)) break;//patch 28 fev 06
1999     if (t.GetKinkIndexes()[0]<0){
2000       for (Int_t i=0;i<3;i++){
2001         Int_t index = t.GetKinkIndexes()[i];
2002         if (index==0) break;
2003         if (index>0) continue;
2004         index = TMath::Abs(index);
2005         AliKink * kink = (AliKink*)fEvent->GetKink(index-1);
2006         if (!kink){
2007           printf("PROBLEM\n");
2008         }
2009         else{
2010           Int_t kinkrow = kink->GetTPCRow0()-2-Int_t(0.5/(0.05+kink->GetAngle(2)));
2011           if (kinkrow==nr){
2012             AliExternalTrackParam paramm(t);
2013             kink->SetMother(paramm);
2014             kink->SetStatus(2,1);
2015             kink->Update();
2016           }
2017         }
2018       }      
2019     }
2020     //
2021     if (nr<fInnerSec->GetNRows()) 
2022       fSectors = fInnerSec;
2023     else
2024       fSectors = fOuterSec;
2025
2026     FollowToNext(t,nr);                                                             
2027   }   
2028   return 1;
2029 }
2030
2031
2032
2033
2034    
2035 Float_t AliTPCtrackerMI::OverlapFactor(AliTPCseed * s1, AliTPCseed * s2, Int_t &sum1, Int_t & sum2)
2036 {
2037   //
2038   //
2039   sum1=0;
2040   sum2=0;
2041   Int_t sum=0;
2042   //
2043   Float_t dz2 =(s1->GetZ() - s2->GetZ());
2044   dz2*=dz2;  
2045
2046   Float_t dy2 =TMath::Abs((s1->GetY() - s2->GetY()));
2047   dy2*=dy2;
2048   Float_t distance = TMath::Sqrt(dz2+dy2);
2049   if (distance>4.) return 0; // if there are far away  - not overlap - to reduce combinatorics
2050  
2051   //  Int_t offset =0;
2052   Int_t firstpoint = TMath::Min(s1->GetFirstPoint(),s2->GetFirstPoint());
2053   Int_t lastpoint = TMath::Max(s1->GetLastPoint(),s2->GetLastPoint());
2054   if (lastpoint>160) 
2055     lastpoint =160;
2056   if (firstpoint<0) 
2057     firstpoint = 0;
2058   if (firstpoint>lastpoint) {
2059     firstpoint =lastpoint;
2060     //    lastpoint  =160;
2061   }
2062     
2063   
2064   for (Int_t i=firstpoint-1;i<lastpoint+1;i++){
2065     if (s1->GetClusterIndex2(i)>0) sum1++;
2066     if (s2->GetClusterIndex2(i)>0) sum2++;
2067     if (s1->GetClusterIndex2(i)==s2->GetClusterIndex2(i) && s1->GetClusterIndex2(i)>0) {
2068       sum++;
2069     }
2070   }
2071   if (sum<5) return 0;
2072
2073   Float_t summin = TMath::Min(sum1+1,sum2+1);
2074   Float_t ratio = (sum+1)/Float_t(summin);
2075   return ratio;
2076 }
2077
2078 void  AliTPCtrackerMI::SignShared(AliTPCseed * s1, AliTPCseed * s2)
2079 {
2080   //
2081   //
2082   Float_t thetaCut = 0.2;//+10.*TMath::Sqrt(s1->GetSigmaTglZ()+ s2->GetSigmaTglZ());
2083   if (TMath::Abs(s1->GetTgl()-s2->GetTgl())>thetaCut) return;
2084   Float_t minCl = TMath::Min(s1->GetNumberOfClusters(),s2->GetNumberOfClusters());
2085   Int_t cutN0 = TMath::Max(5,TMath::Nint(0.1*minCl));
2086   
2087   //
2088   Int_t sumshared=0;
2089   //
2090   //Int_t firstpoint = TMath::Max(s1->GetFirstPoint(),s2->GetFirstPoint());
2091   //Int_t lastpoint = TMath::Min(s1->GetLastPoint(),s2->GetLastPoint());
2092   Int_t firstpoint = 0;
2093   Int_t lastpoint = 160;
2094   //
2095   //  if (firstpoint>=lastpoint-5) return;;
2096
2097   for (Int_t i=firstpoint;i<lastpoint;i++){
2098     //    if ( (s1->GetClusterIndex2(i)&0xFFFF8FFF)==(s2->GetClusterIndex2(i)&0xFFFF8FFF) && s1->GetClusterIndex2(i)>0) {
2099     if ( (s1->GetClusterIndex2(i))==(s2->GetClusterIndex2(i)) && s1->GetClusterIndex2(i)>0) {
2100       sumshared++;
2101       s1->SetSharedMapBit(i, kTRUE);
2102       s2->SetSharedMapBit(i, kTRUE);
2103     }
2104     if (s1->GetClusterIndex2(i)>0)
2105       s1->SetClusterMapBit(i, kTRUE);
2106   }
2107   if (sumshared>cutN0){
2108     // sign clusters
2109     //
2110     for (Int_t i=firstpoint;i<lastpoint;i++){
2111       //      if ( (s1->GetClusterIndex2(i)&0xFFFF8FFF)==(s2->GetClusterIndex2(i)&0xFFFF8FFF) && s1->GetClusterIndex2(i)>0) {
2112       if ( (s1->GetClusterIndex2(i))==(s2->GetClusterIndex2(i)) && s1->GetClusterIndex2(i)>0) {
2113         AliTPCTrackerPoint *p1  = s1->GetTrackPoint(i);
2114         AliTPCTrackerPoint *p2  = s2->GetTrackPoint(i);; 
2115         if (s1->IsActive()&&s2->IsActive()){
2116           p1->SetShared(kTRUE);
2117           p2->SetShared(kTRUE);
2118         }       
2119       }
2120     }
2121   }
2122   //  
2123   if (sumshared>cutN0){
2124     for (Int_t i=0;i<4;i++){
2125       if (s1->GetOverlapLabel(3*i)==0){
2126         s1->SetOverlapLabel(3*i,  s2->GetLabel());
2127         s1->SetOverlapLabel(3*i+1,sumshared);
2128         s1->SetOverlapLabel(3*i+2,s2->GetUniqueID());
2129         break;
2130       } 
2131     }
2132     for (Int_t i=0;i<4;i++){
2133       if (s2->GetOverlapLabel(3*i)==0){
2134         s2->SetOverlapLabel(3*i,  s1->GetLabel());
2135         s2->SetOverlapLabel(3*i+1,sumshared);
2136         s2->SetOverlapLabel(3*i+2,s1->GetUniqueID());
2137         break;
2138       } 
2139     }    
2140   }
2141 }
2142
2143 void  AliTPCtrackerMI::SignShared(TObjArray * arr)
2144 {
2145   //
2146   //sort trackss according sectors
2147   //  
2148   for (Int_t i=0; i<arr->GetEntriesFast(); i++) {
2149     AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);    
2150     if (!pt) continue;
2151     //if (pt) RotateToLocal(pt);
2152     pt->SetSort(0);
2153   }
2154   arr->UnSort();
2155   arr->Sort();  // sorting according relative sectors
2156   arr->Expand(arr->GetEntries());
2157   //
2158   //
2159   Int_t nseed=arr->GetEntriesFast();
2160   for (Int_t i=0; i<nseed; i++) {
2161     AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);    
2162     if (!pt) continue;
2163     for (Int_t j=0;j<12;j++){
2164       pt->SetOverlapLabel(j,0);
2165     }
2166   }
2167   for (Int_t i=0; i<nseed; i++) {
2168     AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);    
2169     if (!pt) continue;
2170     if (pt->GetRemoval()>10) continue;
2171     for (Int_t j=i+1; j<nseed; j++){
2172       AliTPCseed *pt2=(AliTPCseed*)arr->UncheckedAt(j);
2173       if (TMath::Abs(pt->GetRelativeSector()-pt2->GetRelativeSector())>1) continue;
2174       //      if (pt2){
2175       if (pt2->GetRemoval()<=10) {
2176         //if ( TMath::Abs(pt->GetRelativeSector()-pt2->GetRelativeSector())>0) break;
2177         SignShared(pt,pt2);
2178       }
2179     }  
2180   }
2181 }
2182
2183
2184 void AliTPCtrackerMI::SortTracks(TObjArray * arr, Int_t mode) const
2185 {
2186   //
2187   //sort tracks in array according mode criteria
2188   Int_t nseed = arr->GetEntriesFast();    
2189   for (Int_t i=0; i<nseed; i++) {
2190     AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);    
2191     if (!pt) {
2192       continue;
2193     }
2194     pt->SetSort(mode);
2195   }
2196   arr->UnSort();
2197   arr->Sort();
2198 }
2199
2200
2201 void AliTPCtrackerMI::RemoveUsed2(TObjArray * arr, Float_t factor1,  Float_t factor2, Int_t minimal)
2202 {
2203   //
2204   // Loop over all tracks and remove overlaped tracks (with lower quality)
2205   // Algorithm:
2206   //    1. Unsign clusters
2207   //    2. Sort tracks according quality
2208   //       Quality is defined by the number of cluster between first and last points 
2209   //       
2210   //    3. Loop over tracks - decreasing quality order
2211   //       a.) remove - If the fraction of shared cluster less than factor (1- n or 2) 
2212   //       b.) remove - If the minimal number of clusters less than minimal and not ITS
2213   //       c.) if track accepted - sign clusters
2214   //
2215   //Called in - AliTPCtrackerMI::Clusters2Tracks()
2216   //          - AliTPCtrackerMI::PropagateBack()
2217   //          - AliTPCtrackerMI::RefitInward()
2218   //
2219   // Arguments:
2220   //   factor1 - factor for constrained
2221   //   factor2 -        for non constrained tracks 
2222   //            if (Float_t(shared+1)/Float_t(found+1)>factor) - DELETE
2223   //
2224   UnsignClusters();
2225   //
2226   Int_t nseed = arr->GetEntriesFast();  
2227   Float_t * quality = new Float_t[nseed];
2228   Int_t   * indexes = new Int_t[nseed];
2229   Int_t good =0;
2230   //
2231   //
2232   for (Int_t i=0; i<nseed; i++) {
2233     AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);    
2234     if (!pt){
2235       quality[i]=-1;
2236       continue;
2237     }
2238     pt->UpdatePoints();    //select first last max dens points
2239     Float_t * points = pt->GetPoints();
2240     if (points[3]<0.8) quality[i] =-1;
2241     quality[i] = (points[2]-points[0])+pt->GetNumberOfClusters();
2242     //prefer high momenta tracks if overlaps
2243     quality[i] *= TMath::Sqrt(TMath::Abs(pt->Pt())+0.5); 
2244   }
2245   TMath::Sort(nseed,quality,indexes);
2246   //
2247   //
2248   for (Int_t itrack=0; itrack<nseed; itrack++) {
2249     Int_t trackindex = indexes[itrack];
2250     AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(trackindex);   
2251     if (!pt) continue;
2252     //
2253     if (quality[trackindex]<0){
2254         delete arr->RemoveAt(trackindex);
2255         continue;
2256     }
2257     //
2258     //
2259     Int_t first = Int_t(pt->GetPoints()[0]);
2260     Int_t last  = Int_t(pt->GetPoints()[2]);
2261     Double_t factor = (pt->GetBConstrain()) ? factor1: factor2;
2262     //
2263     Int_t found,foundable,shared;
2264     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
2265     //    pt->GetClusterStatistic(0,160, found, foundable,shared,kFALSE);
2266     Bool_t itsgold =kFALSE;
2267     if (pt->GetESD()){
2268       Int_t dummy[12];
2269       if (pt->GetESD()->GetITSclusters(dummy)>4) itsgold= kTRUE;
2270     }
2271     if (!itsgold){
2272       //
2273       if (Float_t(shared+1)/Float_t(found+1)>factor){
2274         if (pt->GetKinkIndexes()[0]!=0) continue;  //don't remove tracks  - part of the kinks
2275         if( AliTPCReconstructor::StreamLevel()>3){
2276           TTreeSRedirector &cstream = *fDebugStreamer;
2277           cstream<<"RemoveUsed"<<
2278             "iter="<<fIteration<<
2279             "pt.="<<pt<<
2280             "\n";
2281         }
2282         delete arr->RemoveAt(trackindex);
2283         continue;
2284       }      
2285       if (pt->GetNumberOfClusters()<50&&(found-0.5*shared)<minimal){  //remove short tracks
2286         if (pt->GetKinkIndexes()[0]!=0) continue;  //don't remove tracks  - part of the kinks
2287         if( AliTPCReconstructor::StreamLevel()>3){
2288           TTreeSRedirector &cstream = *fDebugStreamer;
2289           cstream<<"RemoveShort"<<
2290             "iter="<<fIteration<<
2291             "pt.="<<pt<<
2292             "\n";
2293         }
2294         delete arr->RemoveAt(trackindex);
2295         continue;
2296       }
2297     }
2298
2299     good++;
2300     //if (sharedfactor>0.4) continue;
2301     if (pt->GetKinkIndexes()[0]>0) continue;
2302     //Remove tracks with undefined properties - seems
2303     if (pt->GetSigmaY2()<kAlmost0) continue; // ? what is the origin ? 
2304     //
2305     for (Int_t i=first; i<last; i++) {
2306       Int_t index=pt->GetClusterIndex2(i);
2307       // if (index<0 || index&0x8000 ) continue;
2308       if (index<0 || index&0x8000 ) continue;
2309       AliTPCclusterMI *c= pt->GetClusterPointer(i);        
2310       if (!c) continue;
2311       c->Use(10);  
2312     }    
2313   }
2314   fNtracks = good;
2315   if (fDebug>0){
2316     Info("RemoveUsed","\n*****\nNumber of good tracks after shared removal\t%d\n",fNtracks);
2317   }
2318   delete []quality;
2319   delete []indexes;
2320 }
2321
2322 void AliTPCtrackerMI::DumpClusters(Int_t iter, TObjArray *trackArray) 
2323 {
2324   //
2325   // Dump clusters after reco
2326   // signed and unsigned cluster can be visualized   
2327   // 1. Unsign all cluster
2328   // 2. Sign all used clusters
2329   // 3. Dump clusters
2330   UnsignClusters();
2331   Int_t nseed = trackArray->GetEntries();
2332   for (Int_t i=0; i<nseed; i++){
2333     AliTPCseed *pt=(AliTPCseed*)trackArray->UncheckedAt(i);    
2334     if (!pt) {
2335       continue;
2336     }    
2337     Bool_t isKink=pt->GetKinkIndex(0)!=0;
2338     for (Int_t j=0; j<160; ++j) {
2339       Int_t index=pt->GetClusterIndex2(j);
2340       if (index<0) continue;
2341       AliTPCclusterMI *c= pt->GetClusterPointer(j);
2342       if (!c) continue;
2343       if (isKink) c->Use(100);   // kink
2344       c->Use(10);                // by default usage 10
2345     }
2346   }
2347   //
2348
2349   for (Int_t sec=0;sec<fkNIS;sec++){
2350     for (Int_t row=0;row<fInnerSec->GetNRows();row++){
2351       AliTPCclusterMI *cl = fInnerSec[sec][row].GetClusters1();
2352       for (Int_t icl =0;icl< fInnerSec[sec][row].GetN1();icl++){    
2353         Float_t gx[3];  cl[icl].GetGlobalXYZ(gx);
2354         (*fDebugStreamer)<<"clDump"<< 
2355           "iter="<<iter<<
2356           "cl.="<<&cl[icl]<<      
2357           "gx0="<<gx[0]<<
2358           "gx1="<<gx[1]<<
2359           "gx2="<<gx[2]<<
2360           "\n";
2361       }
2362       cl = fInnerSec[sec][row].GetClusters2();
2363       for (Int_t icl =0;icl< fInnerSec[sec][row].GetN2();icl++){
2364         Float_t gx[3];  cl[icl].GetGlobalXYZ(gx);
2365         (*fDebugStreamer)<<"clDump"<< 
2366           "iter="<<iter<<
2367           "cl.="<<&cl[icl]<<
2368           "gx0="<<gx[0]<<
2369           "gx1="<<gx[1]<<
2370           "gx2="<<gx[2]<<
2371           "\n";
2372       }
2373     }
2374   }
2375   
2376   for (Int_t sec=0;sec<fkNOS;sec++){
2377     for (Int_t row=0;row<fOuterSec->GetNRows();row++){
2378       AliTPCclusterMI *cl = fOuterSec[sec][row].GetClusters1();
2379       for (Int_t icl =0;icl< fOuterSec[sec][row].GetN1();icl++){
2380         Float_t gx[3];  cl[icl].GetGlobalXYZ(gx);
2381         (*fDebugStreamer)<<"clDump"<< 
2382           "iter="<<iter<<
2383           "cl.="<<&cl[icl]<<
2384           "gx0="<<gx[0]<<
2385           "gx1="<<gx[1]<<
2386           "gx2="<<gx[2]<<
2387           "\n";      
2388       }
2389       cl = fOuterSec[sec][row].GetClusters2();
2390       for (Int_t icl =0;icl< fOuterSec[sec][row].GetN2();icl++){
2391         Float_t gx[3];  cl[icl].GetGlobalXYZ(gx);
2392         (*fDebugStreamer)<<"clDump"<< 
2393           "iter="<<iter<<
2394           "cl.="<<&cl[icl]<<
2395           "gx0="<<gx[0]<<
2396           "gx1="<<gx[1]<<
2397           "gx2="<<gx[2]<<
2398           "\n";      
2399       }
2400     }
2401   }
2402   
2403 }
2404 void AliTPCtrackerMI::UnsignClusters() 
2405 {
2406   //
2407   // loop over all clusters and unsign them
2408   //
2409   
2410   for (Int_t sec=0;sec<fkNIS;sec++){
2411     for (Int_t row=0;row<fInnerSec->GetNRows();row++){
2412       AliTPCclusterMI *cl = fInnerSec[sec][row].GetClusters1();
2413       for (Int_t icl =0;icl< fInnerSec[sec][row].GetN1();icl++)
2414         //      if (cl[icl].IsUsed(10))         
2415         cl[icl].Use(-1);
2416       cl = fInnerSec[sec][row].GetClusters2();
2417       for (Int_t icl =0;icl< fInnerSec[sec][row].GetN2();icl++)
2418         //if (cl[icl].IsUsed(10))       
2419           cl[icl].Use(-1);      
2420     }
2421   }
2422   
2423   for (Int_t sec=0;sec<fkNOS;sec++){
2424     for (Int_t row=0;row<fOuterSec->GetNRows();row++){
2425       AliTPCclusterMI *cl = fOuterSec[sec][row].GetClusters1();
2426       for (Int_t icl =0;icl< fOuterSec[sec][row].GetN1();icl++)
2427         //if (cl[icl].IsUsed(10))       
2428           cl[icl].Use(-1);
2429       cl = fOuterSec[sec][row].GetClusters2();
2430       for (Int_t icl =0;icl< fOuterSec[sec][row].GetN2();icl++)
2431         //if (cl[icl].IsUsed(10))       
2432         cl[icl].Use(-1);      
2433     }
2434   }
2435   
2436 }
2437
2438
2439
2440 void AliTPCtrackerMI::SignClusters(const TObjArray * arr, Float_t fnumber, Float_t fdensity)
2441 {
2442   //
2443   //sign clusters to be "used"
2444   //
2445   // snumber and sdensity sign number of sigmas - bellow mean value to be accepted
2446   // loop over "primaries"
2447   
2448   Float_t sumdens=0;
2449   Float_t sumdens2=0;
2450   Float_t sumn   =0;
2451   Float_t sumn2  =0;
2452   Float_t sumchi =0;
2453   Float_t sumchi2 =0;
2454
2455   Float_t sum    =0;
2456
2457   TStopwatch timer;
2458   timer.Start();
2459
2460   Int_t nseed = arr->GetEntriesFast();
2461   for (Int_t i=0; i<nseed; i++) {
2462     AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);    
2463     if (!pt) {
2464       continue;
2465     }    
2466     if (!(pt->IsActive())) continue;
2467     Float_t dens = pt->GetNumberOfClusters()/Float_t(pt->GetNFoundable());
2468     if ( (dens>0.7) && (pt->GetNumberOfClusters()>70)){
2469       sumdens += dens;
2470       sumdens2+= dens*dens;
2471       sumn    += pt->GetNumberOfClusters();
2472       sumn2   += pt->GetNumberOfClusters()*pt->GetNumberOfClusters();
2473       Float_t chi2 = pt->GetChi2()/pt->GetNumberOfClusters();
2474       if (chi2>5) chi2=5;
2475       sumchi  +=chi2;
2476       sumchi2 +=chi2*chi2;
2477       sum++;
2478     }
2479   }
2480
2481   Float_t mdensity = 0.9;
2482   Float_t meann    = 130;
2483   Float_t meanchi  = 1;
2484   Float_t sdensity = 0.1;
2485   Float_t smeann    = 10;
2486   Float_t smeanchi  =0.4;
2487   
2488
2489   if (sum>20){
2490     mdensity = sumdens/sum;
2491     meann    = sumn/sum;
2492     meanchi  = sumchi/sum;
2493     //
2494     sdensity = sumdens2/sum-mdensity*mdensity;
2495     if (sdensity >= 0)
2496        sdensity = TMath::Sqrt(sdensity);
2497     else
2498        sdensity = 0.1;
2499     //
2500     smeann   = sumn2/sum-meann*meann;
2501     if (smeann >= 0)
2502       smeann   = TMath::Sqrt(smeann);
2503     else 
2504       smeann   = 10;
2505     //
2506     smeanchi = sumchi2/sum - meanchi*meanchi;
2507     if (smeanchi >= 0)
2508       smeanchi = TMath::Sqrt(smeanchi);
2509     else
2510       smeanchi = 0.4;
2511   }
2512
2513
2514   //REMOVE  SHORT DELTAS or tracks going out of sensitive volume of TPC
2515   //
2516   for (Int_t i=0; i<nseed; i++) {
2517     AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);    
2518     if (!pt) {
2519       continue;
2520     }
2521     if (pt->GetBSigned()) continue;
2522     if (pt->GetBConstrain()) continue;    
2523     //if (!(pt->IsActive())) continue;
2524     /*
2525     Int_t found,foundable,shared;    
2526     pt->GetClusterStatistic(0,160,found, foundable,shared);
2527     if (shared/float(found)>0.3) {
2528       if (shared/float(found)>0.9 ){
2529         //delete arr->RemoveAt(i);
2530       }
2531       continue;
2532     }
2533     */
2534     Bool_t isok =kFALSE;
2535     if ( (pt->GetNShared()/pt->GetNumberOfClusters()<0.5) &&pt->GetNumberOfClusters()>60)
2536       isok = kTRUE;
2537     if ((TMath::Abs(1/pt->GetC())<100.) && (pt->GetNShared()/pt->GetNumberOfClusters()<0.7))
2538       isok =kTRUE;
2539     if  (TMath::Abs(pt->GetZ()/pt->GetX())>1.1)
2540       isok =kTRUE;
2541     if ( (TMath::Abs(pt->GetSnp()>0.7) && pt->GetD(0,0)>60.))
2542       isok =kTRUE;
2543     
2544     if (isok)     
2545       for (Int_t j=0; j<160; ++j) {     
2546         Int_t index=pt->GetClusterIndex2(j);
2547         if (index<0) continue;
2548         AliTPCclusterMI *c= pt->GetClusterPointer(j);
2549         if (!c) continue;
2550         //if (!(c->IsUsed(10))) c->Use();  
2551         c->Use(10);  
2552       }
2553   }
2554   
2555   
2556   //
2557   Double_t maxchi  = meanchi+2.*smeanchi;
2558
2559   for (Int_t i=0; i<nseed; i++) {
2560     AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);    
2561     if (!pt) {
2562       continue;
2563     }    
2564     //if (!(pt->IsActive())) continue;
2565     if (pt->GetBSigned()) continue;
2566     Double_t chi     = pt->GetChi2()/pt->GetNumberOfClusters();
2567     if (chi>maxchi) continue;
2568
2569     Float_t bfactor=1;
2570     Float_t dens = pt->GetNumberOfClusters()/Float_t(pt->GetNFoundable());
2571    
2572     //sign only tracks with enoug big density at the beginning
2573     
2574     if ((pt->GetDensityFirst(40)<0.75) && pt->GetNumberOfClusters()<meann) continue; 
2575     
2576     
2577     Double_t mindens = TMath::Max(double(mdensity-sdensity*fdensity*bfactor),0.65);
2578     Double_t minn    = TMath::Max(Int_t(meann-fnumber*smeann*bfactor),50);
2579    
2580     //    if (pt->fBConstrain) mindens = TMath::Max(mdensity-sdensity*fdensity*bfactor,0.65);
2581     if ( (pt->GetRemoval()==10) && (pt->GetSnp()>0.8)&&(dens>mindens))
2582       minn=0;
2583
2584     if ((dens>mindens && pt->GetNumberOfClusters()>minn) && chi<maxchi ){
2585       //Int_t noc=pt->GetNumberOfClusters();
2586       pt->SetBSigned(kTRUE);
2587       for (Int_t j=0; j<160; ++j) {
2588
2589         Int_t index=pt->GetClusterIndex2(j);
2590         if (index<0) continue;
2591         AliTPCclusterMI *c= pt->GetClusterPointer(j);
2592         if (!c) continue;
2593         //      if (!(c->IsUsed(10))) c->Use();  
2594         c->Use(10);  
2595       }
2596     }
2597   }
2598   //  gLastCheck = nseed;
2599   //  arr->Compress();
2600   if (fDebug>0){
2601     timer.Print();
2602   }
2603 }
2604
2605
2606 void  AliTPCtrackerMI::StopNotActive(const TObjArray * arr, Int_t row0, Float_t th0, Float_t th1, Float_t th2) const
2607 {
2608   // stop not active tracks
2609   // take th1 as threshold for number of founded to number of foundable on last 10 active rows
2610   // take th2 as threshold for number of founded to number of foundable on last 20 active rows 
2611   Int_t nseed = arr->GetEntriesFast();  
2612   //
2613   for (Int_t i=0; i<nseed; i++) {
2614     AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);    
2615     if (!pt) {
2616       continue;
2617     }
2618     if (!(pt->IsActive())) continue;
2619     StopNotActive(pt,row0,th0, th1,th2);
2620   }
2621 }
2622
2623
2624
2625 void  AliTPCtrackerMI::StopNotActive(AliTPCseed * seed, Int_t row0, Float_t th0, Float_t th1,
2626  Float_t th2) const
2627 {
2628   // stop not active tracks
2629   // take th1 as threshold for number of founded to number of foundable on last 10 active rows
2630   // take th2 as threshold for number of founded to number of foundable on last 20 active rows 
2631   Int_t sumgood1  = 0;
2632   Int_t sumgood2  = 0;
2633   Int_t foundable = 0;
2634   Int_t maxindex = seed->GetLastPoint();  //last foundable row
2635   if (seed->GetNFoundable()*th0 > seed->GetNumberOfClusters()) {
2636     seed->Desactivate(10) ;
2637     return;
2638   }
2639
2640   for (Int_t i=row0; i<maxindex; i++){
2641     Int_t index = seed->GetClusterIndex2(i);
2642     if (index!=-1) foundable++;
2643     //if (!c) continue;
2644     if (foundable<=30) sumgood1++;
2645     if (foundable<=50) {
2646       sumgood2++;
2647     }
2648     else{ 
2649       break;
2650     }        
2651   }
2652   if (foundable>=30.){ 
2653      if (sumgood1<(th1*30.)) seed->Desactivate(10);
2654   }
2655   if (foundable>=50)
2656     if (sumgood2<(th2*50.)) seed->Desactivate(10);
2657 }
2658
2659
2660 Int_t AliTPCtrackerMI::RefitInward(AliESDEvent *event)
2661 {
2662   //
2663   // back propagation of ESD tracks
2664   //
2665   //return 0;
2666   if (!event) return 0;
2667   const Int_t kMaxFriendTracks=2000;
2668   fEvent = event;
2669   // extract correction object for multiplicity dependence of dEdx
2670   TObjArray * gainCalibArray = AliTPCcalibDB::Instance()->GetTimeGainSplinesRun(event->GetRunNumber());
2671
2672   AliTPCTransform *transform = AliTPCcalibDB::Instance()->GetTransform() ;
2673   if (!transform) {
2674     AliFatal("Tranformations not in RefitInward");
2675     return 0;
2676   }
2677   transform->SetCurrentRecoParam((AliTPCRecoParam*)AliTPCReconstructor::GetRecoParam());
2678   const AliTPCRecoParam * recoParam = AliTPCcalibDB::Instance()->GetTransform()->GetCurrentRecoParam();
2679
2680   TGraphErrors * graphMultDependenceDeDx = 0x0;
2681   if (recoParam && recoParam->GetUseMultiplicityCorrectionDedx() && gainCalibArray) {
2682     if (recoParam->GetUseTotCharge()) {
2683       graphMultDependenceDeDx = (TGraphErrors *) gainCalibArray->FindObject("TGRAPHERRORS_MEANQTOT_MULTIPLICITYDEPENDENCE_BEAM_ALL");
2684     } else {
2685       graphMultDependenceDeDx = (TGraphErrors *) gainCalibArray->FindObject("TGRAPHERRORS_MEANQMAX_MULTIPLICITYDEPENDENCE_BEAM_ALL");
2686     }
2687   }
2688   //
2689   ReadSeeds(event,2);
2690   fIteration=2;
2691   //PrepareForProlongation(fSeeds,1);
2692   PropagateForward2(fSeeds);
2693   RemoveUsed2(fSeeds,0.4,0.4,20);
2694
2695   TObjArray arraySeed(fSeeds->GetEntries());
2696   for (Int_t i=0;i<fSeeds->GetEntries();i++) {
2697     arraySeed.AddAt(fSeeds->At(i),i);    
2698   }
2699   SignShared(&arraySeed);
2700   //  FindCurling(fSeeds, event,2); // find multi found tracks
2701   FindSplitted(fSeeds, event,2); // find multi found tracks
2702   if (AliTPCReconstructor::StreamLevel()>5)  FindMultiMC(fSeeds, fEvent,2); // find multi found tracks
2703
2704   Int_t ntracks=0;
2705   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)  UpdateKinkQualityD(seed);  // update quality informations for kinks
2710     AliESDtrack *esd=event->GetTrack(i);
2711
2712     if (seed->GetNumberOfClusters()<60 && seed->GetNumberOfClusters()<(esd->GetTPCclusters(0) -5)*0.8){
2713       AliExternalTrackParam paramIn;
2714       AliExternalTrackParam paramOut;
2715       Int_t ncl = seed->RefitTrack(seed,&paramIn,&paramOut);
2716       if (AliTPCReconstructor::StreamLevel()>2) {
2717         (*fDebugStreamer)<<"RecoverIn"<<
2718           "seed.="<<seed<<
2719           "esd.="<<esd<<
2720           "pin.="<<&paramIn<<
2721           "pout.="<<&paramOut<<
2722           "ncl="<<ncl<<
2723           "\n";
2724       }
2725       if (ncl>15) {
2726         seed->Set(paramIn.GetX(),paramIn.GetAlpha(),paramIn.GetParameter(),paramIn.GetCovariance());
2727         seed->SetNumberOfClusters(ncl);
2728       }
2729     }
2730
2731     seed->PropagateTo(fkParam->GetInnerRadiusLow());
2732     seed->UpdatePoints();
2733     AddCovariance(seed);
2734     MakeBitmaps(seed);
2735     seed->CookdEdx(0.02,0.6);
2736     CookLabel(seed,0.1); //For comparison only
2737     esd->SetTPCClusterMap(seed->GetClusterMap());
2738     esd->SetTPCSharedMap(seed->GetSharedMap());
2739     //
2740     if (AliTPCReconstructor::StreamLevel()>1 && seed!=0) {
2741       TTreeSRedirector &cstream = *fDebugStreamer;
2742       cstream<<"Crefit"<<
2743         "Esd.="<<esd<<
2744         "Track.="<<seed<<
2745         "\n"; 
2746     }
2747
2748     if (seed->GetNumberOfClusters()>15){
2749       esd->UpdateTrackParams(seed,AliESDtrack::kTPCrefit); 
2750       esd->SetTPCPoints(seed->GetPoints());
2751       esd->SetTPCPointsF(seed->GetNFoundable());
2752       Int_t   ndedx = seed->GetNCDEDX(0);
2753       Float_t sdedx = seed->GetSDEDX(0);
2754       Float_t dedx  = seed->GetdEdx();
2755       // apply mutliplicity dependent dEdx correction if available
2756       if (graphMultDependenceDeDx) {
2757         Int_t nContribut  = event->GetPrimaryVertexTPC()->GetNContributors();
2758         Double_t corrGain =  AliTPCcalibDButil::EvalGraphConst(graphMultDependenceDeDx, nContribut);
2759         dedx /= corrGain;
2760       }
2761       esd->SetTPCsignal(dedx, sdedx, ndedx);
2762       //
2763       // add seed to the esd track in Calib level
2764       //
2765       Bool_t storeFriend = gRandom->Rndm()<(kMaxFriendTracks)/Float_t(nseed);
2766       if (AliTPCReconstructor::StreamLevel()>0 &&storeFriend){
2767         AliTPCseed * seedCopy = new AliTPCseed(*seed, kTRUE); 
2768         esd->AddCalibObject(seedCopy);
2769       }
2770       ntracks++;
2771     }
2772     else{
2773       //printf("problem\n");
2774     }
2775   }
2776   //FindKinks(fSeeds,event);
2777   if (AliTPCReconstructor::StreamLevel()>3)  DumpClusters(2,fSeeds);
2778   Info("RefitInward","Number of refitted tracks %d",ntracks);
2779   return 0;
2780 }
2781
2782
2783 Int_t AliTPCtrackerMI::PropagateBack(AliESDEvent *event)
2784 {
2785   //
2786   // back propagation of ESD tracks
2787   //
2788   if (!event) return 0;
2789   fEvent = event;
2790   fIteration = 1;
2791   ReadSeeds(event,1);
2792   PropagateBack(fSeeds); 
2793   RemoveUsed2(fSeeds,0.4,0.4,20);
2794   //FindCurling(fSeeds, fEvent,1);  
2795   FindSplitted(fSeeds, event,1); // find multi found tracks
2796   if (AliTPCReconstructor::StreamLevel()>5)  FindMultiMC(fSeeds, fEvent,1); // find multi found tracks
2797
2798   //
2799   Int_t nseed = fSeeds->GetEntriesFast();
2800   Int_t ntracks=0;
2801   for (Int_t i=0;i<nseed;i++){
2802     AliTPCseed * seed = (AliTPCseed*) fSeeds->UncheckedAt(i);
2803     if (!seed) continue;
2804     if (seed->GetKinkIndex(0)<0)  UpdateKinkQualityM(seed);  // update quality informations for kinks
2805     seed->UpdatePoints();
2806     AddCovariance(seed);
2807     AliESDtrack *esd=event->GetTrack(i);
2808     if (seed->GetNumberOfClusters()<60 && seed->GetNumberOfClusters()<(esd->GetTPCclusters(0) -5)*0.8){
2809       AliExternalTrackParam paramIn;
2810       AliExternalTrackParam paramOut;
2811       Int_t ncl = seed->RefitTrack(seed,&paramIn,&paramOut);
2812       if (AliTPCReconstructor::StreamLevel()>2) {
2813         (*fDebugStreamer)<<"RecoverBack"<<
2814           "seed.="<<seed<<
2815           "esd.="<<esd<<
2816           "pin.="<<&paramIn<<
2817           "pout.="<<&paramOut<<
2818           "ncl="<<ncl<<
2819           "\n";
2820       }
2821       if (ncl>15) {
2822         seed->Set(paramOut.GetX(),paramOut.GetAlpha(),paramOut.GetParameter(),paramOut.GetCovariance());
2823         seed->SetNumberOfClusters(ncl);
2824       }
2825     }
2826     seed->CookdEdx(0.02,0.6);
2827     CookLabel(seed,0.1); //For comparison only
2828     if (seed->GetNumberOfClusters()>15){
2829       esd->UpdateTrackParams(seed,AliESDtrack::kTPCout);
2830       esd->SetTPCPoints(seed->GetPoints());
2831       esd->SetTPCPointsF(seed->GetNFoundable());
2832       Int_t   ndedx = seed->GetNCDEDX(0);
2833       Float_t sdedx = seed->GetSDEDX(0);
2834       Float_t dedx  = seed->GetdEdx();
2835       esd->SetTPCsignal(dedx, sdedx, ndedx);
2836       ntracks++;
2837       Int_t eventnumber = event->GetEventNumberInFile();// patch 28 fev 06
2838       // This is most likely NOT the event number you'd like to use. It has nothing to do with the 'real' event number      
2839       if (AliTPCReconstructor::StreamLevel()>1 && esd) {
2840         (*fDebugStreamer)<<"Cback"<<
2841           "Tr0.="<<seed<<
2842           "esd.="<<esd<<
2843           "EventNrInFile="<<eventnumber<<
2844           "\n";       
2845       }
2846     }
2847   }
2848   if (AliTPCReconstructor::StreamLevel()>3)  DumpClusters(1,fSeeds);
2849   //FindKinks(fSeeds,event);
2850   Info("PropagateBack","Number of back propagated tracks %d",ntracks);
2851   fEvent =0;
2852   
2853   return 0;
2854 }
2855
2856
2857 void AliTPCtrackerMI::DeleteSeeds()
2858 {
2859   //
2860   //delete Seeds
2861
2862   Int_t nseed = fSeeds->GetEntriesFast();
2863   for (Int_t i=0;i<nseed;i++){
2864     AliTPCseed * seed = (AliTPCseed*)fSeeds->At(i);
2865     if (seed) delete fSeeds->RemoveAt(i);
2866   }
2867   delete fSeeds;
2868
2869   fSeeds =0;
2870 }
2871
2872 void AliTPCtrackerMI::ReadSeeds(AliESDEvent *const event, Int_t direction)
2873 {
2874   //
2875   //read seeds from the event
2876   
2877   Int_t nentr=event->GetNumberOfTracks();
2878   if (fDebug>0){
2879     Info("ReadSeeds", "Number of ESD tracks: %d\n", nentr);
2880   }
2881   if (fSeeds) 
2882     DeleteSeeds();
2883   if (!fSeeds){   
2884     fSeeds = new TObjArray(nentr);
2885   }
2886   UnsignClusters();
2887   //  Int_t ntrk=0;  
2888   for (Int_t i=0; i<nentr; i++) {
2889     AliESDtrack *esd=event->GetTrack(i);
2890     ULong_t status=esd->GetStatus();
2891     if (!(status&AliESDtrack::kTPCin)) continue;
2892     AliTPCtrack t(*esd);
2893     t.SetNumberOfClusters(0);
2894     //    AliTPCseed *seed = new AliTPCseed(t,t.GetAlpha());
2895     AliTPCseed *seed = new AliTPCseed(t/*,t.GetAlpha()*/);
2896     seed->SetUniqueID(esd->GetID());
2897     AddCovariance(seed);   //add systematic ucertainty
2898     for (Int_t ikink=0;ikink<3;ikink++) {
2899       Int_t index = esd->GetKinkIndex(ikink);
2900       seed->GetKinkIndexes()[ikink] = index;
2901       if (index==0) continue;
2902       index = TMath::Abs(index);
2903       AliESDkink * kink = fEvent->GetKink(index-1);
2904       if (kink&&esd->GetKinkIndex(ikink)<0){
2905         if ((status & AliESDtrack::kTRDrefit) != 0) kink->SetStatus(1,2);
2906         if ((status & AliESDtrack::kITSout) != 0)   kink->SetStatus(1,0);
2907       }
2908       if (kink&&esd->GetKinkIndex(ikink)>0){
2909         if ((status & AliESDtrack::kTRDrefit) != 0) kink->SetStatus(1,6);
2910         if ((status & AliESDtrack::kITSout) != 0)   kink->SetStatus(1,4);
2911       }
2912
2913     }
2914     if (((status&AliESDtrack::kITSout)==0)&&(direction==1)) seed->ResetCovariance(10.); 
2915     if ( direction ==2 &&(status & AliESDtrack::kTRDrefit) == 0 ) seed->ResetCovariance(10.);
2916     //if ( direction ==2 && ((status & AliESDtrack::kTPCout) == 0) ) {
2917     //  fSeeds->AddAt(0,i);
2918     //  delete seed;
2919     //  continue;    
2920     //}
2921     if ( direction ==2 &&(status & AliESDtrack::kTRDrefit) > 0 )  {
2922       Double_t par0[5],par1[5],alpha,x;
2923       esd->GetInnerExternalParameters(alpha,x,par0);
2924       esd->GetExternalParameters(x,par1);
2925       Double_t delta1 = TMath::Abs(par0[4]-par1[4])/(0.000000001+TMath::Abs(par0[4]+par1[4]));
2926       Double_t delta2 = TMath::Abs(par0[3]-par1[3]);
2927       Double_t trdchi2=0;
2928       if (esd->GetTRDncls()>0) trdchi2 = esd->GetTRDchi2()/esd->GetTRDncls();
2929       //reset covariance if suspicious 
2930       if ( (delta1>0.1) || (delta2>0.006) ||trdchi2>7.)
2931         seed->ResetCovariance(10.);
2932     }
2933
2934     //
2935     //
2936     // rotate to the local coordinate system
2937     //   
2938     fSectors=fInnerSec; fN=fkNIS;    
2939     Double_t alpha=seed->GetAlpha() - fSectors->GetAlphaShift();
2940     if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
2941     if (alpha < 0.            ) alpha += 2.*TMath::Pi();
2942     Int_t ns=Int_t(alpha/fSectors->GetAlpha())%fN;
2943     alpha =ns*fSectors->GetAlpha() + fSectors->GetAlphaShift();
2944     if (alpha<-TMath::Pi()) alpha += 2*TMath::Pi();
2945     if (alpha>=TMath::Pi()) alpha -= 2*TMath::Pi();
2946     alpha-=seed->GetAlpha();  
2947     if (!seed->Rotate(alpha)) {
2948       delete seed;
2949       continue;
2950     }
2951     seed->SetESD(esd);
2952     // sign clusters
2953     if (esd->GetKinkIndex(0)<=0){
2954       for (Int_t irow=0;irow<160;irow++){
2955         Int_t index = seed->GetClusterIndex2(irow);    
2956         if (index>0){ 
2957           //
2958           AliTPCclusterMI * cl = GetClusterMI(index);
2959           seed->SetClusterPointer(irow,cl);
2960           if (cl){
2961             if ((index & 0x8000)==0){
2962               cl->Use(10);  // accepted cluster   
2963             }else{
2964               cl->Use(6);   // close cluster not accepted
2965             }   
2966           }else{
2967             Info("ReadSeeds","Not found cluster");
2968           }
2969         }
2970       }
2971     }
2972     fSeeds->AddAt(seed,i);
2973   }
2974 }
2975
2976
2977
2978 //_____________________________________________________________________________
2979 void AliTPCtrackerMI::MakeSeeds3(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2,  Float_t cuts[4],
2980                                  Float_t deltay, Int_t ddsec) {
2981   //-----------------------------------------------------------------
2982   // This function creates track seeds.
2983   // SEEDING WITH VERTEX CONSTRAIN 
2984   //-----------------------------------------------------------------
2985   // cuts[0]   - fP4 cut
2986   // cuts[1]   - tan(phi)  cut
2987   // cuts[2]   - zvertex cut
2988   // cuts[3]   - fP3 cut
2989   Int_t nin0  = 0;
2990   Int_t nin1  = 0;
2991   Int_t nin2  = 0;
2992   Int_t nin   = 0;
2993   Int_t nout1 = 0;
2994   Int_t nout2 = 0;
2995
2996   Double_t x[5], c[15];
2997   //  Int_t di = i1-i2;
2998   //
2999   AliTPCseed * seed = new AliTPCseed();
3000   Double_t alpha=fSectors->GetAlpha(), shift=fSectors->GetAlphaShift();
3001   Double_t cs=cos(alpha), sn=sin(alpha);
3002   //
3003   //  Double_t x1 =fOuterSec->GetX(i1);
3004   //Double_t xx2=fOuterSec->GetX(i2);
3005   
3006   Double_t x1 =GetXrow(i1);
3007   Double_t xx2=GetXrow(i2);
3008
3009   Double_t x3=GetX(), y3=GetY(), z3=GetZ();
3010
3011   Int_t imiddle = (i2+i1)/2;    //middle pad row index
3012   Double_t xm = GetXrow(imiddle); // radius of middle pad-row
3013   const AliTPCtrackerRow& krm=GetRow(sec,imiddle); //middle pad -row
3014   //
3015   Int_t ns =sec;   
3016
3017   const AliTPCtrackerRow& kr1=GetRow(ns,i1);
3018   Double_t ymax  = GetMaxY(i1)-kr1.GetDeadZone()-1.5;  
3019   Double_t ymaxm = GetMaxY(imiddle)-kr1.GetDeadZone()-1.5;  
3020
3021   //
3022   // change cut on curvature if it can't reach this layer
3023   // maximal curvature set to reach it
3024   Double_t dvertexmax  = TMath::Sqrt((x1-x3)*(x1-x3)+(ymax+5-y3)*(ymax+5-y3));
3025   if (dvertexmax*0.5*cuts[0]>0.85){
3026     cuts[0] = 0.85/(dvertexmax*0.5+1.);
3027   }
3028   Double_t r2min = 1/(cuts[0]*cuts[0]);  //minimal square of radius given by cut
3029
3030   //  Int_t ddsec = 1;
3031   if (deltay>0) ddsec = 0; 
3032   // loop over clusters  
3033   for (Int_t is=0; is < kr1; is++) {
3034     //
3035     if (kr1[is]->IsUsed(10)) continue;
3036     Double_t y1=kr1[is]->GetY(), z1=kr1[is]->GetZ();    
3037     //if (TMath::Abs(y1)>ymax) continue;
3038
3039     if (deltay>0 && TMath::Abs(ymax-TMath::Abs(y1))> deltay ) continue;  // seed only at the edge
3040
3041     // find possible directions    
3042     Float_t anglez = (z1-z3)/(x1-x3); 
3043     Float_t extraz = z1 - anglez*(x1-xx2);  // extrapolated z      
3044     //
3045     //
3046     //find   rotation angles relative to line given by vertex and point 1
3047     Double_t dvertex2 = (x1-x3)*(x1-x3)+(y1-y3)*(y1-y3);
3048     Double_t dvertex  = TMath::Sqrt(dvertex2);
3049     Double_t angle13  = TMath::ATan((y1-y3)/(x1-x3));
3050     Double_t cs13     = cos(-angle13), sn13 = sin(-angle13);            
3051     
3052     //
3053     // loop over 2 sectors
3054     Int_t dsec1=-ddsec;
3055     Int_t dsec2= ddsec;
3056     if (y1<0)  dsec2= 0;
3057     if (y1>0)  dsec1= 0;
3058     
3059     Double_t dddz1=0;  // direction of delta inclination in z axis
3060     Double_t dddz2=0;
3061     if ( (z1-z3)>0)
3062       dddz1 =1;    
3063     else
3064       dddz2 =1;
3065     //
3066     for (Int_t dsec = dsec1; dsec<=dsec2;dsec++){
3067       Int_t sec2 = sec + dsec;
3068       // 
3069       //      AliTPCtrackerRow&  kr2  = fOuterSec[(sec2+fkNOS)%fkNOS][i2];
3070       //AliTPCtrackerRow&  kr2m = fOuterSec[(sec2+fkNOS)%fkNOS][imiddle];
3071       AliTPCtrackerRow&  kr2  = GetRow((sec2+fkNOS)%fkNOS,i2);
3072       AliTPCtrackerRow&  kr2m = GetRow((sec2+fkNOS)%fkNOS,imiddle);
3073       Int_t  index1 = TMath::Max(kr2.Find(extraz-0.6-dddz1*TMath::Abs(z1)*0.05)-1,0);
3074       Int_t  index2 = TMath::Min(kr2.Find(extraz+0.6+dddz2*TMath::Abs(z1)*0.05)+1,kr2);
3075
3076       // rotation angles to p1-p3
3077       Double_t cs13r     = cos(-angle13+dsec*alpha)/dvertex, sn13r = sin(-angle13+dsec*alpha)/dvertex;            
3078       Double_t x2,   y2,   z2; 
3079       //
3080       //      Double_t dymax = maxangle*TMath::Abs(x1-xx2);
3081
3082       //
3083       Double_t dxx0 =  (xx2-x3)*cs13r;
3084       Double_t dyy0 =  (xx2-x3)*sn13r;
3085       for (Int_t js=index1; js < index2; js++) {
3086         const AliTPCclusterMI *kcl = kr2[js];
3087         if (kcl->IsUsed(10)) continue;  
3088         //
3089         //calcutate parameters
3090         //      
3091         Double_t yy0 =  dyy0 +(kcl->GetY()-y3)*cs13r;
3092         // stright track
3093         if (TMath::Abs(yy0)<0.000001) continue;
3094         Double_t xx0 =  dxx0 -(kcl->GetY()-y3)*sn13r;
3095         Double_t y0  =  0.5*(xx0*xx0+yy0*yy0-xx0)/yy0;
3096         Double_t r02 = (0.25+y0*y0)*dvertex2;   
3097         //curvature (radius) cut
3098         if (r02<r2min) continue;                
3099        
3100         nin0++; 
3101         //
3102         Double_t c0  = 1/TMath::Sqrt(r02);
3103         if (yy0>0) c0*=-1.;     
3104                
3105        
3106         //Double_t dfi0   = 2.*TMath::ASin(dvertex*c0*0.5);
3107         //Double_t dfi1   = 2.*TMath::ASin(TMath::Sqrt(yy0*yy0+(1-xx0)*(1-xx0))*dvertex*c0*0.5);
3108         Double_t dfi0   = 2.*AliTPCFastMath::FastAsin(dvertex*c0*0.5);
3109         Double_t dfi1   = 2.*AliTPCFastMath::FastAsin(TMath::Sqrt(yy0*yy0+(1-xx0)*(1-xx0))*dvertex*c0*0.5);  
3110         //
3111         //
3112         Double_t z0  =  kcl->GetZ();  
3113         Double_t zzzz2    = z1-(z1-z3)*dfi1/dfi0;
3114         if (TMath::Abs(zzzz2-z0)>0.5) continue;       
3115         nin1++;              
3116         //      
3117         Double_t dip    = (z1-z0)*c0/dfi1;        
3118         Double_t x0 = (0.5*cs13+y0*sn13)*dvertex*c0;
3119         //
3120         y2 = kcl->GetY(); 
3121         if (dsec==0){
3122           x2 = xx2; 
3123           z2 = kcl->GetZ();       
3124         }
3125         else
3126           {
3127             // rotation 
3128             z2 = kcl->GetZ();  
3129             x2= xx2*cs-y2*sn*dsec;
3130             y2=+xx2*sn*dsec+y2*cs;
3131           }
3132         
3133         x[0] = y1;
3134         x[1] = z1;
3135         x[2] = x0;
3136         x[3] = dip;
3137         x[4] = c0;
3138         //
3139         //
3140         // do we have cluster at the middle ?
3141         Double_t ym,zm;
3142         GetProlongation(x1,xm,x,ym,zm);
3143         UInt_t dummy; 
3144         AliTPCclusterMI * cm=0;
3145         if (TMath::Abs(ym)-ymaxm<0){      
3146           cm = krm.FindNearest2(ym,zm,1.0,0.6,dummy);
3147           if ((!cm) || (cm->IsUsed(10))) {        
3148             continue;
3149           }
3150         }
3151         else{     
3152           // rotate y1 to system 0
3153           // get state vector in rotated system 
3154           Double_t yr1  = (-0.5*sn13+y0*cs13)*dvertex*c0;
3155           Double_t xr2  =  x0*cs+yr1*sn*dsec;
3156           Double_t xr[5]={kcl->GetY(),kcl->GetZ(), xr2, dip, c0};
3157           //
3158           GetProlongation(xx2,xm,xr,ym,zm);
3159           if (TMath::Abs(ym)-ymaxm<0){
3160             cm = kr2m.FindNearest2(ym,zm,1.0,0.6,dummy);
3161             if ((!cm) || (cm->IsUsed(10))) {      
3162               continue;
3163             }
3164           }
3165         }
3166        
3167
3168         Double_t dym = 0;
3169         Double_t dzm = 0;
3170         if (cm){
3171           dym = ym - cm->GetY();
3172           dzm = zm - cm->GetZ();
3173         }
3174         nin2++;
3175
3176
3177         //
3178         //
3179         Double_t sy1=kr1[is]->GetSigmaY2()*2., sz1=kr1[is]->GetSigmaZ2()*2.;
3180         Double_t sy2=kcl->GetSigmaY2()*2.,     sz2=kcl->GetSigmaZ2()*2.;
3181         //Double_t sy3=400*3./12., sy=0.1, sz=0.1;
3182         Double_t sy3=25000*x[4]*x[4]+0.1, sy=0.1, sz=0.1;
3183         //Double_t sy3=25000*x[4]*x[4]*60+0.5, sy=0.1, sz=0.1;
3184
3185         Double_t f40=(F1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
3186         Double_t f42=(F1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
3187         Double_t f43=(F1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
3188         Double_t f20=(F2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
3189         Double_t f22=(F2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
3190         Double_t f23=(F2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
3191         
3192         Double_t f30=(F3(x1,y1+sy,x2,y2,z1,z2)-x[3])/sy;
3193         Double_t f31=(F3(x1,y1,x2,y2,z1+sz,z2)-x[3])/sz;
3194         Double_t f32=(F3(x1,y1,x2,y2+sy,z1,z2)-x[3])/sy;
3195         Double_t f34=(F3(x1,y1,x2,y2,z1,z2+sz)-x[3])/sz;
3196         
3197         c[0]=sy1;
3198         c[1]=0.;       c[2]=sz1;
3199         c[3]=f20*sy1;  c[4]=0.;       c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
3200         c[6]=f30*sy1;  c[7]=f31*sz1;  c[8]=f30*sy1*f20+f32*sy2*f22;
3201                        c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
3202         c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
3203         c[13]=f30*sy1*f40+f32*sy2*f42;
3204         c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
3205         
3206         //      if (!BuildSeed(kr1[is],kcl,0,x1,x2,x3,x,c)) continue;
3207         
3208         UInt_t index=kr1.GetIndex(is);
3209         seed->~AliTPCseed(); // this does not set the pointer to 0...
3210         AliTPCseed *track=new(seed) AliTPCseed(x1, ns*alpha+shift, x, c, index);
3211         
3212         track->SetIsSeeding(kTRUE);
3213         track->SetSeed1(i1);
3214         track->SetSeed2(i2);
3215         track->SetSeedType(3);
3216
3217        
3218         //if (dsec==0) {
3219           FollowProlongation(*track, (i1+i2)/2,1);
3220           Int_t foundable,found,shared;
3221           track->GetClusterStatistic((i1+i2)/2,i1, found, foundable, shared, kTRUE);
3222           if ((found<0.55*foundable)  || shared>0.5*found || (track->GetSigmaY2()+track->GetSigmaZ2())>0.5){
3223             seed->Reset();
3224             seed->~AliTPCseed();
3225             continue;
3226           }
3227           //}
3228         
3229         nin++;
3230         FollowProlongation(*track, i2,1);
3231         
3232         
3233         //Int_t rc = 1;
3234         track->SetBConstrain(1);
3235         //      track->fLastPoint = i1+fInnerSec->GetNRows();  // first cluster in track position
3236         track->SetLastPoint(i1);  // first cluster in track position
3237         track->SetFirstPoint(track->GetLastPoint());
3238         
3239         if (track->GetNumberOfClusters()<(i1-i2)*0.5 || 
3240             track->GetNumberOfClusters() < track->GetNFoundable()*0.6 || 
3241             track->GetNShared()>0.4*track->GetNumberOfClusters() ) {
3242           seed->Reset();
3243           seed->~AliTPCseed();
3244           continue;
3245         }
3246         nout1++;
3247         // Z VERTEX CONDITION
3248         Double_t zv, bz=GetBz();
3249         if ( !track->GetZAt(0.,bz,zv) ) continue;
3250         if (TMath::Abs(zv-z3)>cuts[2]) {
3251           FollowProlongation(*track, TMath::Max(i2-20,0));
3252           if ( !track->GetZAt(0.,bz,zv) ) continue;
3253           if (TMath::Abs(zv-z3)>cuts[2]){
3254             FollowProlongation(*track, TMath::Max(i2-40,0));
3255             if ( !track->GetZAt(0.,bz,zv) ) continue;
3256             if (TMath::Abs(zv-z3)>cuts[2] &&(track->GetNumberOfClusters() > track->GetNFoundable()*0.7)){
3257               // make seed without constrain
3258               AliTPCseed * track2 = MakeSeed(track,0.2,0.5,1.);
3259               FollowProlongation(*track2, i2,1);
3260               track2->SetBConstrain(kFALSE);
3261               track2->SetSeedType(1);
3262               arr->AddLast(track2); 
3263               seed->Reset();
3264               seed->~AliTPCseed();
3265               continue;         
3266             }
3267             else{
3268               seed->Reset();
3269               seed->~AliTPCseed();
3270               continue;
3271             
3272             }
3273           }
3274         }
3275       
3276         track->SetSeedType(0);
3277         arr->AddLast(track); 
3278         seed = new AliTPCseed;  
3279         nout2++;
3280         // don't consider other combinations
3281         if (track->GetNumberOfClusters() > track->GetNFoundable()*0.8)
3282           break;
3283       }
3284     }
3285   }
3286   if (fDebug>3){
3287     Info("MakeSeeds3","\nSeeding statistic:\t%d\t%d\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin,nout1,nout2);
3288   }
3289   delete seed;
3290 }
3291
3292
3293 void AliTPCtrackerMI::MakeSeeds5(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2,  Float_t cuts[4],
3294                                  Float_t deltay) {
3295   
3296
3297
3298   //-----------------------------------------------------------------
3299   // This function creates track seeds.
3300   //-----------------------------------------------------------------
3301   // cuts[0]   - fP4 cut
3302   // cuts[1]   - tan(phi)  cut
3303   // cuts[2]   - zvertex cut
3304   // cuts[3]   - fP3 cut
3305
3306
3307   Int_t nin0  = 0;
3308   Int_t nin1  = 0;
3309   Int_t nin2  = 0;
3310   Int_t nin   = 0;
3311   Int_t nout1 = 0;
3312   Int_t nout2 = 0;
3313   Int_t nout3 =0;
3314   Double_t x[5], c[15];
3315   //
3316   // make temporary seed
3317   AliTPCseed * seed = new AliTPCseed;
3318   Double_t alpha=fOuterSec->GetAlpha(), shift=fOuterSec->GetAlphaShift();
3319   //  Double_t cs=cos(alpha), sn=sin(alpha);
3320   //
3321   //
3322
3323   // first 3 padrows
3324   Double_t x1 = GetXrow(i1-1);
3325   const    AliTPCtrackerRow& kr1=GetRow(sec,i1-1);
3326   Double_t y1max  = GetMaxY(i1-1)-kr1.GetDeadZone()-1.5;  
3327   //
3328   Double_t x1p = GetXrow(i1);
3329   const    AliTPCtrackerRow& kr1p=GetRow(sec,i1);
3330   //
3331   Double_t x1m = GetXrow(i1-2);
3332   const    AliTPCtrackerRow& kr1m=GetRow(sec,i1-2);
3333
3334   //
3335   //last 3 padrow for seeding
3336   AliTPCtrackerRow&  kr3  = GetRow((sec+fkNOS)%fkNOS,i1-7);
3337   Double_t    x3   =  GetXrow(i1-7);
3338   //  Double_t    y3max= GetMaxY(i1-7)-kr3.fDeadZone-1.5;  
3339   //
3340   AliTPCtrackerRow&  kr3p  = GetRow((sec+fkNOS)%fkNOS,i1-6);
3341   Double_t    x3p   = GetXrow(i1-6);
3342   //
3343   AliTPCtrackerRow&  kr3m  = GetRow((sec+fkNOS)%fkNOS,i1-8);
3344   Double_t    x3m   = GetXrow(i1-8);
3345
3346   //
3347   //
3348   // middle padrow
3349   Int_t im = i1-4;                           //middle pad row index
3350   Double_t xm         = GetXrow(im);         // radius of middle pad-row
3351   const AliTPCtrackerRow& krm=GetRow(sec,im);   //middle pad -row
3352   //  Double_t ymmax = GetMaxY(im)-kr1.fDeadZone-1.5;  
3353   //
3354   //
3355   Double_t deltax  = x1-x3;
3356   Double_t dymax   = deltax*cuts[1];
3357   Double_t dzmax   = deltax*cuts[3];
3358   //
3359   // loop over clusters  
3360   for (Int_t is=0; is < kr1; is++) {
3361     //
3362     if (kr1[is]->IsUsed(10)) continue;
3363     Double_t y1=kr1[is]->GetY(), z1=kr1[is]->GetZ();    
3364     //
3365     if (deltay>0 && TMath::Abs(y1max-TMath::Abs(y1))> deltay ) continue;  // seed only at the edge    
3366     // 
3367     Int_t  index1 = TMath::Max(kr3.Find(z1-dzmax)-1,0);
3368     Int_t  index2 = TMath::Min(kr3.Find(z1+dzmax)+1,kr3);
3369     //    
3370     Double_t y3,   z3;
3371     //
3372     //
3373     UInt_t index;
3374     for (Int_t js=index1; js < index2; js++) {
3375       const AliTPCclusterMI *kcl = kr3[js];
3376       if (kcl->IsUsed(10)) continue;
3377       y3 = kcl->GetY(); 
3378       // apply angular cuts
3379       if (TMath::Abs(y1-y3)>dymax) continue;
3380       x3 = x3; 
3381       z3 = kcl->GetZ(); 
3382       if (TMath::Abs(z1-z3)>dzmax) continue;
3383       //
3384       Double_t angley = (y1-y3)/(x1-x3);
3385       Double_t anglez = (z1-z3)/(x1-x3);
3386       //
3387       Double_t erry = TMath::Abs(angley)*(x1-x1m)*0.5+0.5;
3388       Double_t errz = TMath::Abs(anglez)*(x1-x1m)*0.5+0.5;
3389       //
3390       Double_t yyym = angley*(xm-x1)+y1;
3391       Double_t zzzm = anglez*(xm-x1)+z1;
3392
3393       const AliTPCclusterMI *kcm = krm.FindNearest2(yyym,zzzm,erry,errz,index);
3394       if (!kcm) continue;
3395       if (kcm->IsUsed(10)) continue;
3396       
3397       erry = TMath::Abs(angley)*(x1-x1m)*0.4+0.5;
3398       errz = TMath::Abs(anglez)*(x1-x1m)*0.4+0.5;
3399       //
3400       //
3401       //
3402       Int_t used  =0;
3403       Int_t found =0;
3404       //
3405       // look around first
3406       const AliTPCclusterMI *kc1m = kr1m.FindNearest2(angley*(x1m-x1)+y1,
3407                                                       anglez*(x1m-x1)+z1,
3408                                                       erry,errz,index);
3409       //
3410       if (kc1m){
3411         found++;
3412         if (kc1m->IsUsed(10)) used++;
3413       }
3414       const AliTPCclusterMI *kc1p = kr1p.FindNearest2(angley*(x1p-x1)+y1,
3415                                                       anglez*(x1p-x1)+z1,
3416                                                       erry,errz,index);
3417       //
3418       if (kc1p){
3419         found++;
3420         if (kc1p->IsUsed(10)) used++;
3421       }
3422       if (used>1)  continue;
3423       if (found<1) continue; 
3424
3425       //
3426       // look around last
3427       const AliTPCclusterMI *kc3m = kr3m.FindNearest2(angley*(x3m-x3)+y3,
3428                                                       anglez*(x3m-x3)+z3,
3429                                                       erry,errz,index);
3430       //
3431       if (kc3m){
3432         found++;
3433         if (kc3m->IsUsed(10)) used++;
3434       }
3435       else 
3436         continue;
3437       const AliTPCclusterMI *kc3p = kr3p.FindNearest2(angley*(x3p-x3)+y3,
3438                                                       anglez*(x3p-x3)+z3,
3439                                                       erry,errz,index);
3440       //
3441       if (kc3p){
3442         found++;
3443         if (kc3p->IsUsed(10)) used++;
3444       }
3445       else 
3446         continue;
3447       if (used>1)  continue;
3448       if (found<3) continue;       
3449       //
3450       Double_t x2,y2,z2;
3451       x2 = xm;
3452       y2 = kcm->GetY();
3453       z2 = kcm->GetZ();
3454       //
3455                         
3456       x[0]=y1;
3457       x[1]=z1;
3458       x[4]=F1(x1,y1,x2,y2,x3,y3);
3459       //if (TMath::Abs(x[4]) >= cuts[0]) continue;
3460       nin0++;
3461       //
3462       x[2]=F2(x1,y1,x2,y2,x3,y3);
3463       nin1++;
3464       //
3465       x[3]=F3n(x1,y1,x2,y2,z1,z2,x[4]);
3466       //if (TMath::Abs(x[3]) > cuts[3]) continue;
3467       nin2++;
3468       //
3469       //
3470       Double_t sy1=0.1,  sz1=0.1;
3471       Double_t sy2=0.1,  sz2=0.1;
3472       Double_t sy3=0.1,  sy=0.1, sz=0.1;
3473       
3474       Double_t f40=(F1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
3475       Double_t f42=(F1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
3476       Double_t f43=(F1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
3477       Double_t f20=(F2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
3478       Double_t f22=(F2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
3479       Double_t f23=(F2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
3480       
3481       Double_t f30=(F3(x1,y1+sy,x2,y2,z1,z2)-x[3])/sy;
3482       Double_t f31=(F3(x1,y1,x2,y2,z1+sz,z2)-x[3])/sz;
3483       Double_t f32=(F3(x1,y1,x2,y2+sy,z1,z2)-x[3])/sy;
3484       Double_t f34=(F3(x1,y1,x2,y2,z1,z2+sz)-x[3])/sz;
3485       
3486       c[0]=sy1;
3487       c[1]=0.;       c[2]=sz1; 
3488       c[3]=f20*sy1;  c[4]=0.;       c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
3489       c[6]=f30*sy1;  c[7]=f31*sz1;  c[8]=f30*sy1*f20+f32*sy2*f22;
3490       c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
3491       c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
3492       c[13]=f30*sy1*f40+f32*sy2*f42;
3493       c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
3494       
3495       //        if (!BuildSeed(kr1[is],kcl,0,x1,x2,x3,x,c)) continue;
3496       
3497       index=kr1.GetIndex(is);
3498       seed->~AliTPCseed();
3499       AliTPCseed *track=new(seed) AliTPCseed(x1, sec*alpha+shift, x, c, index);
3500       
3501       track->SetIsSeeding(kTRUE);
3502
3503       nin++;      
3504       FollowProlongation(*track, i1-7,1);
3505       if (track->GetNumberOfClusters() < track->GetNFoundable()*0.75 || 
3506           track->GetNShared()>0.6*track->GetNumberOfClusters() || ( track->GetSigmaY2()+ track->GetSigmaZ2())>0.6){
3507         seed->Reset();
3508         seed->~AliTPCseed();
3509         continue;
3510       }
3511       nout1++;
3512       nout2++;  
3513       //Int_t rc = 1;
3514       FollowProlongation(*track, i2,1);
3515       track->SetBConstrain(0);
3516       track->SetLastPoint(i1+fInnerSec->GetNRows());  // first cluster in track position
3517       track->SetFirstPoint(track->GetLastPoint());
3518       
3519       if (track->GetNumberOfClusters()<(i1-i2)*0.5 || 
3520           track->GetNumberOfClusters()<track->GetNFoundable()*0.7 || 
3521           track->GetNShared()>2. || track->GetChi2()/track->GetNumberOfClusters()>6 || ( track->GetSigmaY2()+ track->GetSigmaZ2())>0.5 ) {
3522         seed->Reset();
3523         seed->~AliTPCseed();
3524         continue;
3525       }
3526    
3527       {
3528         FollowProlongation(*track, TMath::Max(i2-10,0),1);
3529         AliTPCseed * track2 = MakeSeed(track,0.2,0.5,0.9);
3530         FollowProlongation(*track2, i2,1);
3531         track2->SetBConstrain(kFALSE);
3532         track2->SetSeedType(4);
3533         arr->AddLast(track2); 
3534         seed->Reset();
3535         seed->~AliTPCseed();
3536       }
3537       
3538    
3539       //arr->AddLast(track); 
3540       //seed = new AliTPCseed;  
3541       nout3++;
3542     }
3543   }
3544   
3545   if (fDebug>3){
3546     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);
3547   }
3548   delete seed;
3549 }
3550
3551
3552 //_____________________________________________________________________________
3553 void AliTPCtrackerMI::MakeSeeds2(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t */*cuts[4]*/,
3554                                  Float_t deltay, Bool_t /*bconstrain*/) {
3555   //-----------------------------------------------------------------
3556   // This function creates track seeds - without vertex constraint
3557   //-----------------------------------------------------------------
3558   // cuts[0]   - fP4 cut        - not applied
3559   // cuts[1]   - tan(phi)  cut
3560   // cuts[2]   - zvertex cut    - not applied 
3561   // cuts[3]   - fP3 cut
3562   Int_t nin0=0;
3563   Int_t nin1=0;
3564   Int_t nin2=0;
3565   Int_t nin3=0;
3566   //  Int_t nin4=0;
3567   //Int_t nin5=0;
3568
3569   
3570
3571   Double_t alpha=fOuterSec->GetAlpha(), shift=fOuterSec->GetAlphaShift();
3572   //  Double_t cs=cos(alpha), sn=sin(alpha);
3573   Int_t row0 = (i1+i2)/2;
3574   Int_t drow = (i1-i2)/2;
3575   const AliTPCtrackerRow& kr0=fSectors[sec][row0];
3576   AliTPCtrackerRow * kr=0;
3577
3578   AliTPCpolyTrack polytrack;
3579   Int_t nclusters=fSectors[sec][row0];
3580   AliTPCseed * seed = new AliTPCseed;
3581
3582   Int_t sumused=0;
3583   Int_t cused=0;
3584   Int_t cnused=0;
3585   for (Int_t is=0; is < nclusters; is++) {  //LOOP over clusters
3586     Int_t nfound =0;
3587     Int_t nfoundable =0;
3588     for (Int_t iter =1; iter<2; iter++){   //iterations
3589       const AliTPCtrackerRow& krm=fSectors[sec][row0-iter];
3590       const AliTPCtrackerRow& krp=fSectors[sec][row0+iter];      
3591       const AliTPCclusterMI * cl= kr0[is];
3592       
3593       if (cl->IsUsed(10)) {
3594         cused++;
3595       }
3596       else{
3597         cnused++;
3598       }
3599       Double_t x = kr0.GetX();
3600       // Initialization of the polytrack
3601       nfound =0;
3602       nfoundable =0;
3603       polytrack.Reset();
3604       //
3605       Double_t y0= cl->GetY();
3606       Double_t z0= cl->GetZ();
3607       Float_t erry = 0;
3608       Float_t errz = 0;
3609       
3610       Double_t ymax = fSectors->GetMaxY(row0)-kr0.GetDeadZone()-1.5;
3611       if (deltay>0 && TMath::Abs(ymax-TMath::Abs(y0))> deltay ) continue;  // seed only at the edge
3612       
3613       erry = (0.5)*cl->GetSigmaY2()/TMath::Sqrt(cl->GetQ())*6;      
3614       errz = (0.5)*cl->GetSigmaZ2()/TMath::Sqrt(cl->GetQ())*6;      
3615       polytrack.AddPoint(x,y0,z0,erry, errz);
3616
3617       sumused=0;
3618       if (cl->IsUsed(10)) sumused++;
3619
3620
3621       Float_t roady = (5*TMath::Sqrt(cl->GetSigmaY2()+0.2)+1.)*iter;
3622       Float_t roadz = (5*TMath::Sqrt(cl->GetSigmaZ2()+0.2)+1.)*iter;
3623       //
3624       x = krm.GetX();
3625       AliTPCclusterMI * cl1 = krm.FindNearest(y0,z0,roady,roadz);
3626       if (cl1 && TMath::Abs(ymax-TMath::Abs(y0))) {
3627         erry = (0.5)*cl1->GetSigmaY2()/TMath::Sqrt(cl1->GetQ())*3;          
3628         errz = (0.5)*cl1->GetSigmaZ2()/TMath::Sqrt(cl1->GetQ())*3;
3629         if (cl1->IsUsed(10))  sumused++;
3630         polytrack.AddPoint(x,cl1->GetY(),cl1->GetZ(),erry,errz);
3631       }
3632       //
3633       x = krp.GetX();
3634       AliTPCclusterMI * cl2 = krp.FindNearest(y0,z0,roady,roadz);
3635       if (cl2) {
3636         erry = (0.5)*cl2->GetSigmaY2()/TMath::Sqrt(cl2->GetQ())*3;          
3637         errz = (0.5)*cl2->GetSigmaZ2()/TMath::Sqrt(cl2->GetQ())*3;
3638         if (cl2->IsUsed(10)) sumused++;  
3639         polytrack.AddPoint(x,cl2->GetY(),cl2->GetZ(),erry,errz);
3640       }
3641       //
3642       if (sumused>0) continue;
3643       nin0++;
3644       polytrack.UpdateParameters();
3645       // follow polytrack
3646       roadz = 1.2;
3647       roady = 1.2;
3648       //
3649       Double_t yn,zn;
3650       nfoundable = polytrack.GetN();
3651       nfound     = nfoundable; 
3652       //
3653       for (Int_t ddrow = iter+1; ddrow<drow;ddrow++){
3654         Float_t maxdist = 0.8*(1.+3./(ddrow));
3655         for (Int_t delta = -1;delta<=1;delta+=2){
3656           Int_t row = row0+ddrow*delta;
3657           kr = &(fSectors[sec][row]);
3658           Double_t xn = kr->GetX();
3659           Double_t ymax1 = fSectors->GetMaxY(row)-kr->GetDeadZone()-1.5;
3660           polytrack.GetFitPoint(xn,yn,zn);
3661           if (TMath::Abs(yn)>ymax1) continue;
3662           nfoundable++;
3663           AliTPCclusterMI * cln = kr->FindNearest(yn,zn,roady,roadz);
3664           if (cln) {
3665             Float_t dist =  TMath::Sqrt(  (yn-cln->GetY())*(yn-cln->GetY())+(zn-cln->GetZ())*(zn-cln->GetZ()));
3666             if (dist<maxdist){
3667               /*
3668               erry = (dist+0.3)*cln->GetSigmaY2()/TMath::Sqrt(cln->GetQ())*(1.+1./(ddrow));         
3669               errz = (dist+0.3)*cln->GetSigmaZ2()/TMath::Sqrt(cln->GetQ())*(1.+1./(ddrow));
3670               if (cln->IsUsed(10)) {
3671                 //      printf("used\n");
3672                 sumused++;
3673                 erry*=2;
3674                 errz*=2;
3675               }
3676               */
3677               erry=0.1;
3678               errz=0.1;
3679               polytrack.AddPoint(xn,cln->GetY(),cln->GetZ(),erry, errz);
3680               nfound++;
3681             }
3682           }
3683         }
3684         if ( (sumused>3) || (sumused>0.5*nfound) || (nfound<0.6*nfoundable))  break;     
3685         polytrack.UpdateParameters();
3686       }           
3687     }
3688     if ( (sumused>3) || (sumused>0.5*nfound))  {
3689       //printf("sumused   %d\n",sumused);
3690       continue;
3691     }
3692     nin1++;
3693     Double_t dy,dz;
3694     polytrack.GetFitDerivation(kr0.GetX(),dy,dz);
3695     AliTPCpolyTrack track2;
3696     
3697     polytrack.Refit(track2,0.5+TMath::Abs(dy)*0.3,0.4+TMath::Abs(dz)*0.3);
3698     if (track2.GetN()<0.5*nfoundable) continue;
3699     nin2++;
3700
3701     if ((nfound>0.6*nfoundable) &&( nfoundable>0.4*(i1-i2))) {
3702       //
3703       // test seed with and without constrain
3704       for (Int_t constrain=0; constrain<=0;constrain++){
3705         // add polytrack candidate
3706
3707         Double_t x[5], c[15];
3708         Double_t x1,x2,x3,y1,y2,y3,z1,z2,z3;
3709         track2.GetBoundaries(x3,x1);    
3710         x2 = (x1+x3)/2.;
3711         track2.GetFitPoint(x1,y1,z1);
3712         track2.GetFitPoint(x2,y2,z2);
3713         track2.GetFitPoint(x3,y3,z3);
3714         //
3715         //is track pointing to the vertex ?
3716         Double_t x0,y0,z0;
3717         x0=0;
3718         polytrack.GetFitPoint(x0,y0,z0);
3719
3720         if (constrain) {
3721           x2 = x3;
3722           y2 = y3;
3723           z2 = z3;
3724           
3725           x3 = 0;
3726           y3 = 0;
3727           z3 = 0;
3728         }
3729         x[0]=y1;
3730         x[1]=z1;
3731         x[4]=F1(x1,y1,x2,y2,x3,y3);
3732                 
3733         //      if (TMath::Abs(x[4]) >= cuts[0]) continue;  //
3734         x[2]=F2(x1,y1,x2,y2,x3,y3);
3735         
3736         //if (TMath::Abs(x[4]*x1-x[2]) >= cuts[1]) continue;
3737         //x[3]=F3(x1,y1,x2,y2,z1,z2);
3738         x[3]=F3n(x1,y1,x3,y3,z1,z3,x[4]);
3739         //if (TMath::Abs(x[3]) > cuts[3]) continue;
3740
3741         
3742         Double_t sy =0.1, sz =0.1;
3743         Double_t sy1=0.02, sz1=0.02;
3744         Double_t sy2=0.02, sz2=0.02;
3745         Double_t sy3=0.02;
3746
3747         if (constrain){
3748           sy3=25000*x[4]*x[4]+0.1, sy=0.1, sz=0.1;
3749         }
3750         
3751         Double_t f40=(F1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
3752         Double_t f42=(F1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
3753         Double_t f43=(F1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
3754         Double_t f20=(F2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
3755         Double_t f22=(F2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
3756         Double_t f23=(F2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
3757
3758         Double_t f30=(F3(x1,y1+sy,x3,y3,z1,z3)-x[3])/sy;
3759         Double_t f31=(F3(x1,y1,x3,y3,z1+sz,z3)-x[3])/sz;
3760         Double_t f32=(F3(x1,y1,x3,y3+sy,z1,z3)-x[3])/sy;
3761         Double_t f34=(F3(x1,y1,x3,y3,z1,z3+sz)-x[3])/sz;
3762
3763         
3764         c[0]=sy1;
3765         c[1]=0.;       c[2]=sz1;
3766         c[3]=f20*sy1;  c[4]=0.;       c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
3767         c[6]=f30*sy1;  c[7]=f31*sz1;  c[8]=f30*sy1*f20+f32*sy2*f22;
3768         c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
3769         c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
3770         c[13]=f30*sy1*f40+f32*sy2*f42;
3771         c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
3772         
3773         //Int_t row1 = fSectors->GetRowNumber(x1);
3774         Int_t row1 = GetRowNumber(x1);
3775
3776         UInt_t index=0;
3777         //kr0.GetIndex(is);
3778         seed->~AliTPCseed();
3779         AliTPCseed *track=new(seed) AliTPCseed(x1,sec*alpha+shift,x,c,index);
3780         track->SetIsSeeding(kTRUE);
3781         Int_t rc=FollowProlongation(*track, i2);        
3782         if (constrain) track->SetBConstrain(1);
3783         else
3784           track->SetBConstrain(0);
3785         track->SetLastPoint(row1+fInnerSec->GetNRows());  // first cluster in track position
3786         track->SetFirstPoint(track->GetLastPoint());
3787
3788         if (rc==0 || track->GetNumberOfClusters()<(i1-i2)*0.5 || 
3789             track->GetNumberOfClusters() < track->GetNFoundable()*0.6 || 
3790             track->GetNShared()>0.4*track->GetNumberOfClusters()) {
3791           //delete track;
3792           seed->Reset();
3793           seed->~AliTPCseed();
3794         }
3795         else {
3796           arr->AddLast(track);
3797           seed = new AliTPCseed;
3798         }
3799         nin3++;
3800       }
3801     }  // if accepted seed
3802   }
3803   if (fDebug>3){
3804     Info("MakeSeeds2","\nSeeding statiistic:\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin3);
3805   }
3806   delete seed;
3807 }
3808
3809
3810 AliTPCseed *AliTPCtrackerMI::MakeSeed(AliTPCseed *const track, Float_t r0, Float_t r1, Float_t r2)
3811 {
3812   //
3813   //
3814   //reseed using track points
3815   Int_t p0 = int(r0*track->GetNumberOfClusters());     // point 0 
3816   Int_t p1 = int(r1*track->GetNumberOfClusters());
3817   Int_t p2 = int(r2*track->GetNumberOfClusters());   // last point
3818   Int_t pp2=0;
3819   Double_t  x0[3],x1[3],x2[3];
3820   for (Int_t i=0;i<3;i++){
3821     x0[i]=-1;
3822     x1[i]=-1;
3823     x2[i]=-1;
3824   }
3825
3826   // find track position at given ratio of the length
3827   Int_t  sec0=0, sec1=0, sec2=0;
3828   Int_t index=-1;
3829   Int_t clindex;
3830   for (Int_t i=0;i<160;i++){
3831     if (track->GetClusterPointer(i)){
3832       index++;
3833       AliTPCTrackerPoint   *trpoint =track->GetTrackPoint(i);
3834       if ( (index<p0) || x0[0]<0 ){
3835         if (trpoint->GetX()>1){
3836           clindex = track->GetClusterIndex2(i);
3837           if (clindex>0){       
3838             x0[0] = trpoint->GetX();
3839             x0[1] = trpoint->GetY();
3840             x0[2] = trpoint->GetZ();
3841             sec0  = ((clindex&0xff000000)>>24)%18;
3842           }
3843         }
3844       }
3845
3846       if ( (index<p1) &&(trpoint->GetX()>1)){
3847         clindex = track->GetClusterIndex2(i);
3848         if (clindex>0){
3849           x1[0] = trpoint->GetX();
3850           x1[1] = trpoint->GetY();
3851           x1[2] = trpoint->GetZ();
3852           sec1  = ((clindex&0xff000000)>>24)%18;
3853         }
3854       }
3855       if ( (index<p2) &&(trpoint->GetX()>1)){
3856         clindex = track->GetClusterIndex2(i);
3857         if (clindex>0){
3858           x2[0] = trpoint->GetX();
3859           x2[1] = trpoint->GetY();
3860           x2[2] = trpoint->GetZ(); 
3861           sec2  = ((clindex&0xff000000)>>24)%18;
3862           pp2 = i;
3863         }
3864       }
3865     }
3866   }
3867   
3868   Double_t alpha, cs,sn, xx2,yy2;
3869   //
3870   alpha = (sec1-sec2)*fSectors->GetAlpha();
3871   cs = TMath::Cos(alpha);
3872   sn = TMath::Sin(alpha); 
3873   xx2= x1[0]*cs-x1[1]*sn;
3874   yy2= x1[0]*sn+x1[1]*cs;
3875   x1[0] = xx2;
3876   x1[1] = yy2;
3877   //
3878   alpha = (sec0-sec2)*fSectors->GetAlpha();
3879   cs = TMath::Cos(alpha);
3880   sn = TMath::Sin(alpha); 
3881   xx2= x0[0]*cs-x0[1]*sn;
3882   yy2= x0[0]*sn+x0[1]*cs;
3883   x0[0] = xx2;
3884   x0[1] = yy2;
3885   //
3886   //
3887   //
3888   Double_t x[5],c[15];
3889   //
3890   x[0]=x2[1];
3891   x[1]=x2[2];
3892   x[4]=F1(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]);
3893   //  if (x[4]>1) return 0;
3894   x[2]=F2(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]);
3895   x[3]=F3n(x2[0],x2[1],x0[0],x0[1],x2[2],x0[2],x[4]);
3896   //if (TMath::Abs(x[3]) > 2.2)  return 0;
3897   //if (TMath::Abs(x[2]) > 1.99) return 0;
3898   //  
3899   Double_t sy =0.1,  sz =0.1;
3900   //
3901   Double_t sy1=0.02+track->GetSigmaY2(), sz1=0.02+track->GetSigmaZ2();
3902   Double_t sy2=0.01+track->GetSigmaY2(), sz2=0.01+track->GetSigmaZ2();
3903   Double_t sy3=0.01+track->GetSigmaY2();
3904   //
3905   Double_t f40=(F1(x2[0],x2[1]+sy,x1[0],x1[1],x0[0],x0[1])-x[4])/sy;
3906   Double_t f42=(F1(x2[0],x2[1],x1[0],x1[1]+sy,x0[0],x0[1])-x[4])/sy;
3907   Double_t f43=(F1(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]+sy)-x[4])/sy;
3908   Double_t f20=(F2(x2[0],x2[1]+sy,x1[0],x1[1],x0[0],x0[1])-x[2])/sy;
3909   Double_t f22=(F2(x2[0],x2[1],x1[0],x1[1]+sy,x0[0],x0[1])-x[2])/sy;
3910   Double_t f23=(F2(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]+sy)-x[2])/sy;
3911   //
3912   Double_t f30=(F3(x2[0],x2[1]+sy,x0[0],x0[1],x2[2],x0[2])-x[3])/sy;
3913   Double_t f31=(F3(x2[0],x2[1],x0[0],x0[1],x2[2]+sz,x0[2])-x[3])/sz;
3914   Double_t f32=(F3(x2[0],x2[1],x0[0],x0[1]+sy,x2[2],x0[2])-x[3])/sy;
3915   Double_t f34=(F3(x2[0],x2[1],x0[0],x0[1],x2[2],x0[2]+sz)-x[3])/sz;
3916   
3917   
3918   c[0]=sy1;
3919   c[1]=0.;       c[2]=sz1;
3920   c[3]=f20*sy1;  c[4]=0.;       c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
3921   c[6]=f30*sy1;  c[7]=f31*sz1;  c[8]=f30*sy1*f20+f32*sy2*f22;
3922   c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
3923   c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
3924   c[13]=f30*sy1*f40+f32*sy2*f42;
3925   c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
3926   
3927   //  Int_t row1 = fSectors->GetRowNumber(x2[0]);
3928   AliTPCseed *seed=new  AliTPCseed(x2[0], sec2*fSectors->GetAlpha()+fSectors->GetAlphaShift(), x, c, 0);
3929   //  Double_t y0,z0,y1,z1, y2,z2;
3930   //seed->GetProlongation(x0[0],y0,z0);
3931   // seed->GetProlongation(x1[0],y1,z1);
3932   //seed->GetProlongation(x2[0],y2,z2);
3933   //  seed =0;
3934   seed->SetLastPoint(pp2);
3935   seed->SetFirstPoint(pp2);
3936   
3937
3938   return seed;
3939 }
3940
3941
3942 AliTPCseed *AliTPCtrackerMI::ReSeed(const AliTPCseed *track, Float_t r0, Float_t r1, Float_t r2)
3943 {
3944   //
3945   //
3946   //reseed using founded clusters 
3947   //
3948   // Find the number of clusters
3949   Int_t nclusters = 0;
3950   for (Int_t irow=0;irow<160;irow++){
3951     if (track->GetClusterIndex(irow)>0) nclusters++;
3952   }
3953   //
3954   Int_t ipos[3];
3955   ipos[0] = TMath::Max(int(r0*nclusters),0);             // point 0 cluster
3956   ipos[1] = TMath::Min(int(r1*nclusters),nclusters-1);   // 
3957   ipos[2] = TMath::Min(int(r2*nclusters),nclusters-1);   // last point
3958   //
3959   //
3960   Double_t  xyz[3][3]={{0}};
3961   Int_t     row[3]={0},sec[3]={0,0,0};
3962   //
3963   // find track row position at given ratio of the length
3964   Int_t index=-1;
3965   for (Int_t irow=0;irow<160;irow++){    
3966     if (track->GetClusterIndex2(irow)<0) continue;
3967     index++;
3968     for (Int_t ipoint=0;ipoint<3;ipoint++){
3969       if (index<=ipos[ipoint]) row[ipoint] = irow;
3970     }        
3971   }
3972   //
3973   //Get cluster and sector position
3974   for (Int_t ipoint=0;ipoint<3;ipoint++){
3975     Int_t clindex = track->GetClusterIndex2(row[ipoint]);
3976     AliTPCclusterMI * cl = GetClusterMI(clindex);
3977     if (cl==0) {
3978       //Error("Bug\n");
3979       //      AliTPCclusterMI * cl = GetClusterMI(clindex);
3980       return 0;
3981     }
3982     sec[ipoint]     = ((clindex&0xff000000)>>24)%18;
3983     xyz[ipoint][0]  = GetXrow(row[ipoint]);
3984     xyz[ipoint][1]  = cl->GetY();
3985     xyz[ipoint][2]  = cl->GetZ();
3986   }
3987   //
3988   //
3989   // Calculate seed state vector and covariance matrix
3990
3991   Double_t alpha, cs,sn, xx2,yy2;
3992   //
3993   alpha = (sec[1]-sec[2])*fSectors->GetAlpha();
3994   cs = TMath::Cos(alpha);
3995   sn = TMath::Sin(alpha); 
3996   xx2= xyz[1][0]*cs-xyz[1][1]*sn;
3997   yy2= xyz[1][0]*sn+xyz[1][1]*cs;
3998   xyz[1][0] = xx2;
3999   xyz[1][1] = yy2;
4000   //
4001   alpha = (sec[0]-sec[2])*fSectors->GetAlpha();
4002   cs = TMath::Cos(alpha);
4003   sn = TMath::Sin(alpha); 
4004   xx2= xyz[0][0]*cs-xyz[0][1]*sn;
4005   yy2= xyz[0][0]*sn+xyz[0][1]*cs;
4006   xyz[0][0] = xx2;
4007   xyz[0][1] = yy2;
4008   //
4009   //
4010   //
4011   Double_t x[5],c[15];
4012   //
4013   x[0]=xyz[2][1];
4014   x[1]=xyz[2][2];
4015   x[4]=F1(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
4016   x[2]=F2(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
4017   x[3]=F3n(xyz[2][0],xyz[2][1],xyz[0][0],xyz[0][1],xyz[2][2],xyz[0][2],x[4]);
4018   //  
4019   Double_t sy =0.1,  sz =0.1;
4020   //
4021   Double_t sy1=0.2, sz1=0.2;
4022   Double_t sy2=0.2, sz2=0.2;
4023   Double_t sy3=0.2;
4024   //
4025   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;
4026   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;
4027   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;
4028   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;
4029   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;
4030   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;
4031   //
4032   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;
4033   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;
4034   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;
4035   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;
4036   
4037   
4038   c[0]=sy1;
4039   c[1]=0.;       c[2]=sz1;
4040   c[3]=f20*sy1;  c[4]=0.;       c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
4041   c[6]=f30*sy1;  c[7]=f31*sz1;  c[8]=f30*sy1*f20+f32*sy2*f22;
4042   c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
4043   c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
4044   c[13]=f30*sy1*f40+f32*sy2*f42;
4045   c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
4046   
4047   //  Int_t row1 = fSectors->GetRowNumber(xyz[2][0]);
4048   AliTPCseed *seed=new  AliTPCseed(xyz[2][0], sec[2]*fSectors->GetAlpha()+fSectors->GetAlphaShift(), x, c, 0);
4049   seed->SetLastPoint(row[2]);
4050   seed->SetFirstPoint(row[2]);  
4051   return seed;
4052 }
4053
4054
4055 AliTPCseed *AliTPCtrackerMI::ReSeed(AliTPCseed *track,Int_t r0, Bool_t forward)
4056 {
4057   //
4058   //
4059   //reseed using founded clusters 
4060   //
4061   Double_t  xyz[3][3];
4062   Int_t     row[3]={0,0,0};
4063   Int_t     sec[3]={0,0,0};
4064   //
4065   // forward direction
4066   if (forward){
4067     for (Int_t irow=r0;irow<160;irow++){
4068       if (track->GetClusterIndex(irow)>0){
4069         row[0] = irow;
4070         break;
4071       }
4072     }
4073     for (Int_t irow=160;irow>r0;irow--){
4074       if (track->GetClusterIndex(irow)>0){
4075         row[2] = irow;
4076         break;
4077       }
4078     }
4079     for (Int_t irow=row[2]-15;irow>row[0];irow--){
4080       if (track->GetClusterIndex(irow)>0){
4081         row[1] = irow;
4082         break;
4083       }
4084     }
4085     //
4086   }
4087   if (!forward){
4088     for (Int_t irow=0;irow<r0;irow++){
4089       if (track->GetClusterIndex(irow)>0){
4090         row[0] = irow;
4091         break;
4092       }
4093     }
4094     for (Int_t irow=r0;irow>0;irow--){
4095       if (track->GetClusterIndex(irow)>0){
4096         row[2] = irow;
4097         break;
4098       }
4099     }    
4100     for (Int_t irow=row[2]-15;irow>row[0];irow--){
4101       if (track->GetClusterIndex(irow)>0){
4102         row[1] = irow;
4103         break;
4104       }
4105     } 
4106   }
4107   //
4108   if ((row[2]-row[0])<20) return 0;
4109   if (row[1]==0) return 0;
4110   //
4111   //
4112   //Get cluster and sector position
4113   for (Int_t ipoint=0;ipoint<3;ipoint++){
4114     Int_t clindex = track->GetClusterIndex2(row[ipoint]);
4115     AliTPCclusterMI * cl = GetClusterMI(clindex);
4116     if (cl==0) {
4117       //Error("Bug\n");
4118       //      AliTPCclusterMI * cl = GetClusterMI(clindex);
4119       return 0;
4120     }
4121     sec[ipoint]     = ((clindex&0xff000000)>>24)%18;
4122     xyz[ipoint][0]  = GetXrow(row[ipoint]);
4123     AliTPCTrackerPoint * point = track->GetTrackPoint(row[ipoint]);    
4124     if (point&&ipoint<2){
4125       //
4126        xyz[ipoint][1]  = point->GetY();
4127        xyz[ipoint][2]  = point->GetZ();
4128     }
4129     else{
4130       xyz[ipoint][1]  = cl->GetY();
4131       xyz[ipoint][2]  = cl->GetZ();
4132     }
4133   }
4134   //
4135   //
4136   //
4137   //
4138   // Calculate seed state vector and covariance matrix
4139
4140   Double_t alpha, cs,sn, xx2,yy2;
4141   //
4142   alpha = (sec[1]-sec[2])*fSectors->GetAlpha();
4143   cs = TMath::Cos(alpha);
4144   sn = TMath::Sin(alpha); 
4145   xx2= xyz[1][0]*cs-xyz[1][1]*sn;
4146   yy2= xyz[1][0]*sn+xyz[1][1]*cs;
4147   xyz[1][0] = xx2;
4148   xyz[1][1] = yy2;
4149   //
4150   alpha = (sec[0]-sec[2])*fSectors->GetAlpha();
4151   cs = TMath::Cos(alpha);
4152   sn = TMath::Sin(alpha); 
4153   xx2= xyz[0][0]*cs-xyz[0][1]*sn;
4154   yy2= xyz[0][0]*sn+xyz[0][1]*cs;
4155   xyz[0][0] = xx2;
4156   xyz[0][1] = yy2;
4157   //
4158   //
4159   //
4160   Double_t x[5],c[15];
4161   //
4162   x[0]=xyz[2][1];
4163   x[1]=xyz[2][2];
4164   x[4]=F1(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
4165   x[2]=F2(xyz[2][0],xyz[2][1],xyz[1][0],xyz[1][1],xyz[0][0],xyz[0][1]);
4166   x[3]=F3n(xyz[2][0],xyz[2][1],xyz[0][0],xyz[0][1],xyz[2][2],xyz[0][2],x[4]);
4167   //  
4168   Double_t sy =0.1,  sz =0.1;
4169   //
4170   Double_t sy1=0.2, sz1=0.2;
4171   Double_t sy2=0.2, sz2=0.2;
4172   Double_t sy3=0.2;
4173   //
4174   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;
4175   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;
4176   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;
4177   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;
4178   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;
4179   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;
4180   //
4181   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;
4182   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;
4183   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;
4184   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;
4185   
4186   
4187   c[0]=sy1;
4188   c[1]=0.;       c[2]=sz1;
4189   c[3]=f20*sy1;  c[4]=0.;       c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
4190   c[6]=f30*sy1;  c[7]=f31*sz1;  c[8]=f30*sy1*f20+f32*sy2*f22;
4191   c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
4192   c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
4193   c[13]=f30*sy1*f40+f32*sy2*f42;
4194   c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
4195   
4196   //  Int_t row1 = fSectors->GetRowNumber(xyz[2][0]);
4197   AliTPCseed *seed=new  AliTPCseed(xyz[2][0], sec[2]*fSectors->GetAlpha()+fSectors->GetAlphaShift(), x, c, 0);
4198   seed->SetLastPoint(row[2]);
4199   seed->SetFirstPoint(row[2]);  
4200   for (Int_t i=row[0];i<row[2];i++){
4201     seed->SetClusterIndex(i, track->GetClusterIndex(i));
4202   }
4203
4204   return seed;
4205 }
4206
4207
4208
4209 void  AliTPCtrackerMI::FindMultiMC(const TObjArray * array, AliESDEvent */*esd*/, Int_t iter)
4210 {
4211   //
4212   //  find multi tracks - THIS FUNCTION IS ONLY FOR DEBUG PURPOSES
4213   //                      USES MC LABELS
4214   //  Use AliTPCReconstructor::StreamLevel()>2 if you want to tune parameters - cuts
4215   //
4216   //  Two reasons to have multiple find tracks
4217   //  1. Curling tracks can be find more than once
4218   //  2. Splitted tracks 
4219   //     a.) Multiple seeding to increase tracking efficiency - (~ 100% reached)        
4220   //     b.) Edge effect on the sector boundaries
4221   //
4222   //
4223   //  Algorithm done in 2 phases - because of CPU consumption
4224   //  it is n^2 algorithm - for lead-lead 20000x20000 combination are investigated                           
4225   //
4226   //  Algorihm for curling tracks sign:
4227   //    1 phase -makes a very rough fast cuts to minimize combinatorics
4228   //                 a.) opposite sign
4229   //                 b.) one of the tracks - not pointing to the primary vertex - 
4230   //                 c.) delta tan(theta)
4231   //                 d.) delta phi
4232   //    2 phase - calculates DCA between tracks  - time consument
4233
4234   //
4235   //    fast cuts 
4236   //
4237   //    General cuts    - for splitted tracks and for curling tracks
4238   //
4239   const Float_t kMaxdPhi      = 0.2;  // maximal distance in phi
4240   //
4241   //    Curling tracks cuts
4242   //
4243   //
4244   //
4245   //
4246   Int_t nentries = array->GetEntriesFast();  
4247   AliHelix *helixes      = new AliHelix[nentries];
4248   Float_t  *xm           = new Float_t[nentries];
4249   Float_t  *dz0           = new Float_t[nentries];
4250   Float_t  *dz1           = new Float_t[nentries];
4251   //
4252   //
4253   TStopwatch timer;
4254   timer.Start();
4255   //
4256   // Find track COG in x direction - point with best defined parameters
4257   //
4258   for (Int_t i=0;i<nentries;i++){
4259     AliTPCseed* track = (AliTPCseed*)array->At(i);    
4260     if (!track) continue;
4261     track->SetCircular(0);
4262     new (&helixes[i]) AliHelix(*track);
4263     Int_t ncl=0;
4264     xm[i]=0;
4265     Float_t dz[2];
4266     track->GetDZ(GetX(),GetY(),GetZ(),GetBz(),dz);
4267     dz0[i]=dz[0];
4268     dz1[i]=dz[1];
4269     for (Int_t icl=0; icl<160; icl++){
4270       AliTPCclusterMI * cl =  track->GetClusterPointer(icl);
4271       if (cl) {
4272         xm[i]+=cl->GetX();
4273         ncl++;
4274       }
4275     }
4276     if (ncl>0) xm[i]/=Float_t(ncl);
4277   }  
4278   //
4279   for (Int_t i0=0;i0<nentries;i0++){
4280     AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
4281     if (!track0) continue;    
4282     Float_t xc0 = helixes[i0].GetHelix(6);
4283     Float_t yc0 = helixes[i0].GetHelix(7);
4284     Float_t r0  = helixes[i0].GetHelix(8);
4285     Float_t rc0 = TMath::Sqrt(xc0*xc0+yc0*yc0);
4286     Float_t fi0 = TMath::ATan2(yc0,xc0);
4287     
4288     for (Int_t i1=i0+1;i1<nentries;i1++){
4289       AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
4290       if (!track1) continue;      
4291       Int_t lab0=track0->GetLabel();
4292       Int_t lab1=track1->GetLabel();
4293       if (TMath::Abs(lab0)!=TMath::Abs(lab1)) continue;
4294       //
4295       Float_t xc1 = helixes[i1].GetHelix(6);
4296       Float_t yc1 = helixes[i1].GetHelix(7);
4297       Float_t r1  = helixes[i1].GetHelix(8);
4298       Float_t rc1 = TMath::Sqrt(xc1*xc1+yc1*yc1);
4299       Float_t fi1 = TMath::ATan2(yc1,xc1);
4300       //
4301       Float_t dfi = fi0-fi1;
4302       //
4303       //
4304       if (dfi>1.5*TMath::Pi())  dfi-=TMath::Pi();  // take care about edge effect 
4305       if (dfi<-1.5*TMath::Pi()) dfi+=TMath::Pi();  // 
4306       if (TMath::Abs(dfi)>kMaxdPhi&&helixes[i0].GetHelix(4)*helixes[i1].GetHelix(4)<0){
4307         //
4308         // if short tracks with undefined sign 
4309         fi1 =  -TMath::ATan2(yc1,-xc1);
4310         dfi = fi0-fi1;
4311       }
4312       Float_t dtheta = TMath::Abs(track0->GetTgl()-track1->GetTgl())<TMath::Abs(track0->GetTgl()+track1->GetTgl())? track0->GetTgl()-track1->GetTgl():track0->GetTgl()+track1->GetTgl();
4313       
4314       //
4315       // debug stream to tune "fast cuts" 
4316       //
4317       Double_t dist[3];   // distance at X 
4318       Double_t mdist[3]={0,0,0};  // mean distance X+-40cm
4319       track0->GetDistance(track1,0.5*(xm[i0]+xm[i1])-40.,dist,AliTracker::GetBz());
4320       for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[i]);
4321       track0->GetDistance(track1,0.5*(xm[i0]+xm[i1])+40.,dist,AliTracker::GetBz());
4322       for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[i]);
4323       track0->GetDistance(track1,0.5*(xm[i0]+xm[i1]),dist,AliTracker::GetBz());
4324       for (Int_t i=0;i<3;i++) mdist[i]+=TMath::Abs(dist[i]);
4325       for (Int_t i=0;i<3;i++) mdist[i]*=0.33333;
4326       
4327       Float_t sum =0;
4328       Float_t sums=0;
4329       for (Int_t icl=0; icl<160; icl++){
4330         AliTPCclusterMI * cl0 =  track0->GetClusterPointer(icl);
4331         AliTPCclusterMI * cl1 =  track1->GetClusterPointer(icl);
4332         if (cl0&&cl1) {
4333           sum++;
4334           if (cl0==cl1) sums++;
4335         }
4336       }
4337       //
4338       if (AliTPCReconstructor::StreamLevel()>5) {
4339       TTreeSRedirector &cstream = *fDebugStreamer;
4340       cstream<<"Multi"<<
4341         "iter="<<iter<<
4342         "lab0="<<lab0<<
4343         "lab1="<<lab1<<   
4344         "Tr0.="<<track0<<       // seed0
4345         "Tr1.="<<track1<<       // seed1
4346         "h0.="<<&helixes[i0]<<
4347         "h1.="<<&helixes[i1]<<
4348         //
4349         "sum="<<sum<<           //the sum of rows with cl in both
4350         "sums="<<sums<<         //the sum of shared clusters
4351         "xm0="<<xm[i0]<<        // the center of track
4352         "xm1="<<xm[i1]<<        // the x center of track
4353         // General cut variables                   
4354         "dfi="<<dfi<<           // distance in fi angle
4355         "dtheta="<<dtheta<<     // distance int theta angle
4356         //
4357         "dz00="<<dz0[i0]<<
4358         "dz01="<<dz0[i1]<<
4359         "dz10="<<dz1[i1]<<
4360         "dz11="<<dz1[i1]<<
4361         "dist0="<<dist[0]<<     //distance x
4362         "dist1="<<dist[1]<<     //distance y
4363         "dist2="<<dist[2]<<     //distance z
4364         "mdist0="<<mdist[0]<<   //distance x
4365         "mdist1="<<mdist[1]<<   //distance y
4366         "mdist2="<<mdist[2]<<   //distance z
4367         //
4368         "r0="<<r0<<
4369         "rc0="<<rc0<<
4370         "fi0="<<fi0<<
4371         "fi1="<<fi1<<
4372         "r1="<<r1<<
4373         "rc1="<<rc1<<
4374         "\n";
4375         }
4376     }
4377   }    
4378   delete [] helixes;
4379   delete [] xm;
4380   delete [] dz0;
4381   delete [] dz1;
4382   if (AliTPCReconstructor::StreamLevel()>1) {
4383     AliInfo("Time for curling tracks removal DEBUGGING MC");
4384     timer.Print();
4385   }
4386 }
4387
4388
4389
4390 void  AliTPCtrackerMI::FindSplitted(TObjArray * array, AliESDEvent */*esd*/, Int_t /*iter*/){
4391   //
4392   // Find Splitted tracks and remove the one with worst quality  
4393   // Corresponding debug streamer to tune selections - "Splitted2"
4394   // Algorithm:
4395   // 0. Sort tracks according quility
4396   // 1. Propagate the tracks to the reference radius
4397   // 2. Double_t loop to select close tracks (only to speed up process)
4398   // 3. Calculate cluster overlap ratio - and remove the track if bigger than a threshold
4399   // 4. Delete temporary parameters
4400   // 
4401   const Double_t xref=GetXrow(63);  // reference radius -IROC/OROC boundary
4402   //    rough cuts
4403   const Double_t kCutP1=10;       // delta Z cut 10 cm 
4404   const Double_t kCutP2=0.15;     // delta snp(fi) cut 0.15 
4405   const Double_t kCutP3=0.15;     // delta tgl(theta) cut 0.15
4406   const Double_t kCutAlpha=0.15;  // delta alpha cut
4407   Int_t firstpoint = 0;
4408   Int_t lastpoint = 160;
4409   //
4410   Int_t nentries = array->GetEntriesFast();  
4411   AliExternalTrackParam *params      = new AliExternalTrackParam[nentries];
4412   //
4413   //
4414   TStopwatch timer;
4415   timer.Start();
4416   //
4417   //0.  Sort tracks according quality
4418   //1.  Propagate the ext. param to reference radius
4419   Int_t nseed = array->GetEntriesFast();  
4420   if (nseed<=0) return;
4421   Float_t * quality = new Float_t[nseed];
4422   Int_t   * indexes = new Int_t[nseed];
4423   for (Int_t i=0; i<nseed; i++) {
4424     AliTPCseed *pt=(AliTPCseed*)array->UncheckedAt(i);    
4425     if (!pt){
4426       quality[i]=-1;
4427       continue;
4428     }
4429     pt->UpdatePoints();    //select first last max dens points
4430     Float_t * points = pt->GetPoints();
4431     if (points[3]<0.8) quality[i] =-1;
4432     quality[i] = (points[2]-points[0])+pt->GetNumberOfClusters();
4433     //prefer high momenta tracks if overlaps
4434     quality[i] *= TMath::Sqrt(TMath::Abs(pt->Pt())+0.5);
4435     params[i]=(*pt);
4436     AliTracker::PropagateTrackToBxByBz(&(params[i]),xref,pt->GetMass(),5.,kTRUE);
4437     AliTracker::PropagateTrackToBxByBz(&(params[i]),xref,pt->GetMass(),1.,kTRUE);
4438   }
4439   TMath::Sort(nseed,quality,indexes);
4440   //
4441   // 3. Loop over pair of tracks
4442   //
4443   for (Int_t i0=0; i0<nseed; i0++) {
4444     Int_t index0=indexes[i0];
4445     if (!(array->UncheckedAt(index0))) continue;
4446     AliTPCseed *s1 = (AliTPCseed*)array->UncheckedAt(index0);  
4447     if (!s1->IsActive()) continue;
4448     AliExternalTrackParam &par0=params[index0];
4449     for (Int_t i1=i0+1; i1<nseed; i1++) {
4450       Int_t index1=indexes[i1];
4451       if (!(array->UncheckedAt(index1))) continue;
4452       AliTPCseed *s2 = (AliTPCseed*)array->UncheckedAt(index1);  
4453       if (!s2->IsActive()) continue;
4454       if (s2->GetKinkIndexes()[0]!=0)
4455         if (s2->GetKinkIndexes()[0] == -s1->GetKinkIndexes()[0]) continue;
4456       AliExternalTrackParam &par1=params[index1];
4457       if (TMath::Abs(par0.GetParameter()[3]-par1.GetParameter()[3])>kCutP3) continue;
4458       if (TMath::Abs(par0.GetParameter()[1]-par1.GetParameter()[1])>kCutP1) continue;
4459       if (TMath::Abs(par0.GetParameter()[2]-par1.GetParameter()[2])>kCutP2) continue;
4460       Double_t dAlpha= TMath::Abs(par0.GetAlpha()-par1.GetAlpha());
4461       if (dAlpha>TMath::Pi()) dAlpha-=TMath::Pi();
4462       if (TMath::Abs(dAlpha)>kCutAlpha) continue;
4463       //
4464       Int_t sumShared=0;
4465       Int_t nall0=0;
4466       Int_t nall1=0;
4467       Int_t firstShared=lastpoint, lastShared=firstpoint;
4468       Int_t firstRow=lastpoint, lastRow=firstpoint;
4469       //
4470       for (Int_t i=firstpoint;i<lastpoint;i++){
4471         if (s1->GetClusterIndex2(i)>0) nall0++;
4472         if (s2->GetClusterIndex2(i)>0) nall1++;
4473         if  (s1->GetClusterIndex2(i)>0 && s2->GetClusterIndex2(i)>0) {
4474           if (i<firstRow) firstRow=i;
4475           if (i>lastRow)  lastRow=i;
4476         }
4477         if ( (s1->GetClusterIndex2(i))==(s2->GetClusterIndex2(i)) && s1->GetClusterIndex2(i)>0) {
4478           if (i<firstShared) firstShared=i;
4479           if (i>lastShared)  lastShared=i;
4480           sumShared++;
4481         }
4482       }
4483       Double_t ratio0 = Float_t(sumShared)/Float_t(TMath::Min(nall0+1,nall1+1));
4484       Double_t ratio1 = Float_t(sumShared)/Float_t(TMath::Max(nall0+1,nall1+1));
4485       
4486       if( AliTPCReconstructor::StreamLevel()>1){
4487         TTreeSRedirector &cstream = *fDebugStreamer;
4488         Int_t n0=s1->GetNumberOfClusters();
4489         Int_t n1=s2->GetNumberOfClusters();
4490         Int_t n0F=s1->GetNFoundable();
4491         Int_t n1F=s2->GetNFoundable();
4492         Int_t lab0=s1->GetLabel();
4493         Int_t lab1=s2->GetLabel();
4494
4495         cstream<<"Splitted2"<<
4496           "iter="<<fIteration<<
4497           "lab0="<<lab0<<        // MC label if exist
4498           "lab1="<<lab1<<        // MC label if exist
4499           "index0="<<index0<<
4500           "index1="<<index1<<
4501           "ratio0="<<ratio0<<      // shared ratio
4502           "ratio1="<<ratio1<<      // shared ratio
4503           "p0.="<<&par0<<        // track parameters
4504           "p1.="<<&par1<<
4505           "s0.="<<s1<<           // full seed
4506           "s1.="<<s2<<
4507           "n0="<<n0<<     // number of clusters track 0
4508           "n1="<<n1<<     // number of clusters track 1
4509           "nall0="<<nall0<<     // number of clusters track 0
4510           "nall1="<<nall1<<     // number of clusters track 1
4511           "n0F="<<n0F<<   // number of findable
4512           "n1F="<<n1F<<   // number of findable
4513           "shared="<<sumShared<<    // number of shared clusters
4514           "firstS="<<firstShared<<  // first and the last shared row
4515           "lastS="<<lastShared<<
4516           "firstRow="<<firstRow<<   // first and the last row with cluster
4517           "lastRow="<<lastRow<<     //
4518           "\n";
4519       }
4520       //
4521       // remove track with lower quality
4522       //
4523       if (ratio0>AliTPCReconstructor::GetRecoParam()->GetCutSharedClusters(0) ||
4524           ratio1>AliTPCReconstructor::GetRecoParam()->GetCutSharedClusters(1)){
4525         //
4526         //
4527         //
4528         delete array->RemoveAt(index1);
4529       }
4530     }
4531   }
4532   //
4533   // 4. Delete temporary array
4534   //
4535   delete [] params; 
4536   delete [] quality;
4537   delete [] indexes;
4538
4539 }
4540
4541
4542
4543 void  AliTPCtrackerMI::FindCurling(const TObjArray * array, AliESDEvent */*esd*/, Int_t iter)
4544 {
4545   //
4546   //  find Curling tracks
4547   //  Use AliTPCReconstructor::StreamLevel()>1 if you want to tune parameters - cuts
4548   //
4549   //
4550   //  Algorithm done in 2 phases - because of CPU consumption
4551   //  it is n^2 algorithm - for lead-lead 20000x20000 combination are investigated                           
4552   //  see detal in MC part what can be used to cut
4553   //
4554   //    
4555   //
4556   const Float_t kMaxC         = 400;  // maximal curvature to of the track
4557   const Float_t kMaxdTheta    = 0.15;  // maximal distance in theta
4558   const Float_t kMaxdPhi      = 0.15;  // maximal distance in phi
4559   const Float_t kPtRatio      = 0.3; // ratio between pt
4560   const Float_t kMinDCAR      = 2.;   // distance to the primary vertex in r - see cpipe cut      
4561
4562   //
4563   //    Curling tracks cuts
4564   //
4565   //
4566   const Float_t kMaxDeltaRMax = 40;   // distance in outer radius
4567   const Float_t kMaxDeltaRMin = 5.;   // distance in lower radius - see cpipe cut
4568   const Float_t kMinAngle     = 2.9;  // angle between tracks
4569   const Float_t kMaxDist      = 5;    // biggest distance 
4570   //
4571   // The cuts can be tuned using the "MC information stored in Multi tree ==> see FindMultiMC
4572   /* 
4573      Fast cuts:
4574      TCut csign("csign","Tr0.fP[4]*Tr1.fP[4]<0"); //opposite sign
4575      TCut cmax("cmax","abs(Tr0.GetC())>1/400");
4576      TCut cda("cda","sqrt(dtheta^2+dfi^2)<0.15");
4577      TCut ccratio("ccratio","abs((Tr0.fP[4]+Tr1.fP[4])/(abs(Tr0.fP[4])+abs(Tr1.fP[4])))<0.3");
4578      TCut cpipe("cpipe", "min(abs(r0-rc0),abs(r1-rc1))>5");    
4579      //
4580      TCut cdrmax("cdrmax","abs(abs(rc0+r0)-abs(rc1+r1))<40")
4581      TCut cdrmin("cdrmin","abs(abs(rc0+r0)-abs(rc1+r1))<10")
4582      //
4583      Multi->Draw("dfi","iter==0"+csign+cmax+cda+ccratio); ~94% of curling tracks fulfill 
4584      Multi->Draw("min(abs(r0-rc0),abs(r1-rc1))","iter==0&&abs(lab1)==abs(lab0)"+csign+cmax+cda+ccratio+cpipe+cdrmin+cdrmax); //80%
4585      //
4586      Curling2->Draw("dfi","iter==0&&abs(lab0)==abs(lab1)"+csign+cmax+cdtheta+cdfi+ccratio)
4587
4588   */
4589   //  
4590   //
4591   //
4592   Int_t nentries = array->GetEntriesFast();  
4593   AliHelix *helixes      = new AliHelix[nentries];
4594   for (Int_t i=0;i<nentries;i++){
4595     AliTPCseed* track = (AliTPCseed*)array->At(i);    
4596     if (!track) continue;
4597     track->SetCircular(0);
4598     new (&helixes[i]) AliHelix(*track);
4599   }
4600   //
4601   //
4602   TStopwatch timer;
4603   timer.Start();
4604   Double_t phase[2][2]={{0,0},{0,0}},radius[2]={0,0};
4605
4606   //
4607   // Find tracks
4608   //
4609   //
4610   for (Int_t i0=0;i0<nentries;i0++){
4611     AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
4612     if (!track0) continue;    
4613     if (TMath::Abs(track0->GetC())<1/kMaxC) continue;
4614     Float_t xc0 = helixes[i0].GetHelix(6);
4615     Float_t yc0 = helixes[i0].GetHelix(7);
4616     Float_t r0  = helixes[i0].GetHelix(8);
4617     Float_t rc0 = TMath::Sqrt(xc0*xc0+yc0*yc0);
4618     Float_t fi0 = TMath::ATan2(yc0,xc0);
4619     
4620     for (Int_t i1=i0+1;i1<nentries;i1++){
4621       AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
4622       if (!track1) continue;      
4623       if (TMath::Abs(track1->GetC())<1/kMaxC) continue;    
4624       Float_t xc1 = helixes[i1].GetHelix(6);
4625       Float_t yc1 = helixes[i1].GetHelix(7);
4626       Float_t r1  = helixes[i1].GetHelix(8);
4627       Float_t rc1 = TMath::Sqrt(xc1*xc1+yc1*yc1);
4628       Float_t fi1 = TMath::ATan2(yc1,xc1);
4629       //
4630       Float_t dfi = fi0-fi1;
4631       //
4632       //
4633       if (dfi>1.5*TMath::Pi())  dfi-=TMath::Pi();  // take care about edge effect 
4634       if (dfi<-1.5*TMath::Pi()) dfi+=TMath::Pi();  // 
4635       Float_t dtheta = TMath::Abs(track0->GetTgl()-track1->GetTgl())<TMath::Abs(track0->GetTgl()+track1->GetTgl())? track0->GetTgl()-track1->GetTgl():track0->GetTgl()+track1->GetTgl();
4636       //
4637       //
4638       // FIRST fast cuts
4639       if (track0->GetBConstrain()&&track1->GetBConstrain())  continue;  // not constrained
4640       if (track1->GetSigned1Pt()*track0->GetSigned1Pt()>0)   continue; // not the same sign
4641       if ( TMath::Abs(track1->GetTgl()+track0->GetTgl())>kMaxdTheta) continue; //distance in the Theta
4642       if ( TMath::Abs(dfi)>kMaxdPhi) continue;  //distance in phi
4643       if ( TMath::Sqrt(dfi*dfi+dtheta*dtheta)>kMaxdPhi) continue; //common angular offset
4644       //
4645       Float_t pt0 = track0->GetSignedPt();
4646       Float_t pt1 = track1->GetSignedPt();
4647       if ((TMath::Abs(pt0+pt1)/(TMath::Abs(pt0)+TMath::Abs(pt1)))>kPtRatio) continue;      
4648       if ((iter==1) && TMath::Abs(TMath::Abs(rc0+r0)-TMath::Abs(rc1+r1))>kMaxDeltaRMax) continue;
4649       if ((iter!=1) &&TMath::Abs(TMath::Abs(rc0-r0)-TMath::Abs(rc1-r1))>kMaxDeltaRMin) continue;
4650       if (TMath::Min(TMath::Abs(rc0-r0),TMath::Abs(rc1-r1))<kMinDCAR) continue;
4651       //
4652       //
4653       // Now find closest approach
4654       //
4655       //
4656       //
4657       Int_t npoints = helixes[i0].GetRPHIintersections(helixes[i1], phase, radius,10);
4658       if (npoints==0) continue;
4659       helixes[i0].GetClosestPhases(helixes[i1], phase);
4660       //
4661       Double_t xyz0[3];
4662       Double_t xyz1[3];
4663       Double_t hangles[3];
4664       helixes[i0].Evaluate(phase[0][0],xyz0);
4665       helixes[i1].Evaluate(phase[0][1],xyz1);
4666
4667       helixes[i0].GetAngle(phase[0][0],helixes[i1],phase[0][1],hangles);
4668       Double_t deltah[2],deltabest;
4669       if (TMath::Abs(hangles[2])<kMinAngle) continue;
4670
4671       if (npoints>0){
4672         Int_t ibest=0;
4673         helixes[i0].ParabolicDCA(helixes[i1],phase[0][0],phase[0][1],radius[0],deltah[0],2);
4674         if (npoints==2){
4675           helixes[i0].ParabolicDCA(helixes[i1],phase[1][0],phase[1][1],radius[1],deltah[1],2);
4676           if (deltah[1]<deltah[0]) ibest=1;
4677         }
4678         deltabest  = TMath::Sqrt(deltah[ibest]);
4679         helixes[i0].Evaluate(phase[ibest][0],xyz0);
4680         helixes[i1].Evaluate(phase[ibest][1],xyz1);
4681         helixes[i0].GetAngle(phase[ibest][0],helixes[i1],phase[ibest][1],hangles);
4682         Double_t radiusbest = TMath::Sqrt(radius[ibest]);
4683         //
4684         if (deltabest>kMaxDist) continue;
4685         //      if (mindcar+mindcaz<40 && (TMath::Abs(hangles[2])<kMinAngle ||deltabest>3)) continue;
4686         Bool_t sign =kFALSE;
4687         if (hangles[2]>kMinAngle) sign =kTRUE;
4688         //
4689         if (sign){
4690           //      circular[i0] = kTRUE;
4691           //      circular[i1] = kTRUE;
4692           if (track0->OneOverPt()<track1->OneOverPt()){
4693             track0->SetCircular(track0->GetCircular()+1);
4694             track1->SetCircular(track1->GetCircular()+2);
4695           }
4696           else{
4697             track1->SetCircular(track1->GetCircular()+1);
4698             track0->SetCircular(track0->GetCircular()+2);
4699           }
4700         }               
4701         if (AliTPCReconstructor::StreamLevel()>2){        
4702           //
4703           //debug stream to tune "fine" cuts      
4704           Int_t lab0=track0->GetLabel();
4705           Int_t lab1=track1->GetLabel();
4706           TTreeSRedirector &cstream = *fDebugStreamer;
4707           cstream<<"Curling2"<<
4708             "iter="<<iter<<
4709             "lab0="<<lab0<<
4710             "lab1="<<lab1<<   
4711             "Tr0.="<<track0<<
4712             "Tr1.="<<track1<<
4713             //
4714             "r0="<<r0<<
4715             "rc0="<<rc0<<
4716             "fi0="<<fi0<<
4717             "r1="<<r1<<
4718             "rc1="<<rc1<<
4719             "fi1="<<fi1<<
4720             "dfi="<<dfi<<
4721             "dtheta="<<dtheta<<
4722             //
4723             "npoints="<<npoints<<                      
4724             "hangles0="<<hangles[0]<<
4725             "hangles1="<<hangles[1]<<
4726             "hangles2="<<hangles[2]<<                    
4727             "xyz0="<<xyz0[2]<<
4728             "xyzz1="<<xyz1[2]<<
4729             "radius="<<radiusbest<<
4730             "deltabest="<<deltabest<< 
4731             "phase0="<<phase[ibest][0]<<
4732             "phase1="<<phase[ibest][1]<<
4733             "\n";                 
4734
4735         }
4736       }
4737     }
4738   }
4739   delete [] helixes;
4740   if (AliTPCReconstructor::StreamLevel()>1) {
4741     AliInfo("Time for curling tracks removal");
4742     timer.Print();
4743   }
4744 }
4745
4746
4747
4748
4749
4750 void  AliTPCtrackerMI::FindKinks(TObjArray * array, AliESDEvent *esd)
4751 {
4752   //
4753   //  find kinks
4754   //
4755   //
4756
4757   TObjArray *kinks= new TObjArray(10000);
4758   //  TObjArray *v0s= new TObjArray(10000);
4759   Int_t nentries = array->GetEntriesFast();
4760   AliHelix *helixes      = new AliHelix[nentries];
4761   Int_t    *sign         = new Int_t[nentries];
4762   Int_t    *nclusters    = new Int_t[nentries];
4763   Float_t  *alpha        = new Float_t[nentries];
4764   AliKink  *kink         = new AliKink();
4765   Int_t      * usage     = new Int_t[nentries];
4766   Float_t  *zm           = new Float_t[nentries];
4767   Float_t  *z0           = new Float_t[nentries]; 
4768   Float_t  *fim          = new Float_t[nentries];
4769   Float_t  *shared       = new Float_t[nentries];
4770   Bool_t   *circular     = new Bool_t[nentries];
4771   Float_t *dca          = new Float_t[nentries];
4772   //const AliESDVertex * primvertex = esd->GetVertex();
4773   //
4774   //  nentries = array->GetEntriesFast();
4775   //
4776   
4777   //
4778   //
4779   for (Int_t i=0;i<nentries;i++){
4780     sign[i]=0;
4781     usage[i]=0;
4782     AliTPCseed* track = (AliTPCseed*)array->At(i);    
4783     if (!track) continue;
4784     track->SetCircular(0);
4785     shared[i] = kFALSE;
4786     track->UpdatePoints();
4787     if (( track->GetPoints()[2]- track->GetPoints()[0])>5 && track->GetPoints()[3]>0.8){
4788     }
4789     nclusters[i]=track->GetNumberOfClusters();
4790     alpha[i] = track->GetAlpha();
4791     new (&helixes[i]) AliHelix(*track);
4792     Double_t xyz[3];
4793     helixes[i].Evaluate(0,xyz);
4794     sign[i] = (track->GetC()>0) ? -1:1;
4795     Double_t x,y,z;
4796     x=160;
4797     if (track->GetProlongation(x,y,z)){
4798       zm[i]  = z;
4799       fim[i] = alpha[i]+TMath::ATan2(y,x);
4800     }
4801     else{
4802       zm[i]  = track->GetZ();
4803       fim[i] = alpha[i];
4804     }   
4805     z0[i]=1000;
4806     circular[i]= kFALSE;
4807     if (track->GetProlongation(0,y,z))  z0[i] = z;
4808     dca[i] = track->GetD(0,0);    
4809   }
4810   //
4811   //
4812   TStopwatch timer;
4813   timer.Start();
4814   Int_t ncandidates =0;
4815   Int_t nall =0;
4816   Int_t ntracks=0; 
4817   Double_t phase[2][2]={{0,0},{0,0}},radius[2]={0,0};
4818
4819   //
4820   // Find circling track
4821   //
4822   for (Int_t i0=0;i0<nentries;i0++){
4823     AliTPCseed * track0 = (AliTPCseed*)array->At(i0);
4824     if (!track0) continue;    
4825     if (track0->GetNumberOfClusters()<40) continue;
4826     if (TMath::Abs(1./track0->GetC())>200) continue;
4827     for (Int_t i1=i0+1;i1<nentries;i1++){
4828       AliTPCseed * track1 = (AliTPCseed*)array->At(i1);
4829       if (!track1) continue;
4830       if (track1->GetNumberOfClusters()<40)                  continue;
4831       if ( TMath::Abs(track1->GetTgl()+track0->GetTgl())>0.1) continue;
4832       if (track0->GetBConstrain()&&track1->GetBConstrain()) continue;
4833       if (TMath::Abs(1./track1->GetC())>200) continue;
4834       if (track1->GetSigned1Pt()*track0->GetSigned1Pt()>0)      continue;
4835       if (track1->GetTgl()*track0->GetTgl()>0)      continue;
4836       if (TMath::Max(TMath::Abs(1./track0->GetC()),TMath::Abs(1./track1->GetC()))>190) continue;
4837       if (track0->GetBConstrain()&&track1->OneOverPt()<track0->OneOverPt()) continue; //returning - lower momenta
4838       if (track1->GetBConstrain()&&track0->OneOverPt()<track1->OneOverPt()) continue; //returning - lower momenta
4839       //
4840       Float_t mindcar = TMath::Min(TMath::Abs(dca[i0]),TMath::Abs(dca[i1]));
4841       if (mindcar<5)   continue;
4842       Float_t mindcaz = TMath::Min(TMath::Abs(z0[i0]-GetZ()),TMath::Abs(z0[i1]-GetZ()));
4843       if (mindcaz<5) continue;
4844       if (mindcar+mindcaz<20) continue;
4845       //
4846       //
4847       Float_t xc0 = helixes[i0].GetHelix(6);
4848       Float_t yc0 = helixes[i0].GetHelix(7);
4849       Float_t r0  = helixes[i0].GetHelix(8);
4850       Float_t xc1 = helixes[i1].GetHelix(6);
4851       Float_t yc1 = helixes[i1].GetHelix(7);
4852       Float_t r1  = helixes[i1].GetHelix(8);
4853         
4854       Float_t rmean = (r0+r1)*0.5;
4855       Float_t delta =TMath::Sqrt((xc1-xc0)*(xc1-xc0)+(yc1-yc0)*(yc1-yc0));
4856       //if (delta>30) continue;
4857       if (delta>rmean*0.25) continue;
4858       if (TMath::Abs(r0-r1)/rmean>0.3) continue; 
4859       //
4860       Int_t npoints = helixes[i0].GetRPHIintersections(helixes[i1], phase, radius,10);
4861       if (npoints==0) continue;
4862       helixes[i0].GetClosestPhases(helixes[i1], phase);
4863       //
4864       Double_t xyz0[3];
4865       Double_t xyz1[3];
4866       Double_t hangles[3];
4867       helixes[i0].Evaluate(phase[0][0],xyz0);
4868       helixes[i1].Evaluate(phase[0][1],xyz1);
4869
4870       helixes[i0].GetAngle(phase[0][0],helixes[i1],phase[0][1],hangles);
4871       Double_t deltah[2],deltabest;
4872       if (hangles[2]<2.8) continue;
4873       if (npoints>0){
4874         Int_t ibest=0;
4875         helixes[i0].ParabolicDCA(helixes[i1],phase[0][0],phase[0][1],radius[0],deltah[0],2);
4876         if (npoints==2){
4877           helixes[i0].ParabolicDCA(helixes[i1],phase[1][0],phase[1][1],radius[1],deltah[1],2);
4878           if (deltah[1]<deltah[0]) ibest=1;
4879         }
4880         deltabest  = TMath::Sqrt(deltah[ibest]);
4881         helixes[i0].Evaluate(phase[ibest][0],xyz0);
4882         helixes[i1].Evaluate(phase[ibest][1],xyz1);
4883         helixes[i0].GetAngle(phase[ibest][0],helixes[i1],phase[ibest][1],hangles);
4884         Double_t radiusbest = TMath::Sqrt(radius[ibest]);
4885         //
4886         if (deltabest>6) continue;
4887         if (mindcar+mindcaz<40 && (hangles[2]<3.12||deltabest>3)) continue;
4888         Bool_t lsign =kFALSE;
4889         if (hangles[2]>3.06) lsign =kTRUE;
4890         //
4891         if (lsign){
4892           circular[i0] = kTRUE;
4893           circular[i1] = kTRUE;
4894           if (track0->OneOverPt()<track1->OneOverPt()){
4895             track0->SetCircular(track0->GetCircular()+1);
4896             track1->SetCircular(track1->GetCircular()+2);
4897           }
4898           else{
4899             track1->SetCircular(track1->GetCircular()+1);
4900             track0->SetCircular(track0->GetCircular()+2);
4901           }
4902         }               
4903         if (lsign&&AliTPCReconstructor::StreamLevel()>1){         
4904           //debug stream          
4905           Int_t lab0=track0->GetLabel();
4906           Int_t lab1=track1->GetLabel();
4907           TTreeSRedirector &cstream = *fDebugStreamer;
4908           cstream<<"Curling"<<
4909             "lab0="<<lab0<<
4910             "lab1="<<lab1<<   
4911             "Tr0.="<<track0<<
4912             "Tr1.="<<track1<<      
4913             "dca0="<<dca[i0]<<
4914             "dca1="<<dca[i1]<<
4915             "mindcar="<<mindcar<<
4916             "mindcaz="<<mindcaz<<
4917             "delta="<<delta<<
4918             "rmean="<<rmean<<
4919             "npoints="<<npoints<<                      
4920             "hangles0="<<hangles[0]<<
4921             "hangles2="<<hangles[2]<<                    
4922             "xyz0="<<xyz0[2]<<
4923             "xyzz1="<<xyz1[2]<<
4924             "z0="<<z0[i0]<<
4925             "z1="<<z0[i1]<<
4926             "radius="<<radiusbest<<
4927             "deltabest="<<deltabest<< 
4928             "phase0="<<phase[ibest][0]<<
4929             "phase1="<<phase[ibest][1]<<
4930             "\n";                 
4931         }
4932       }
4933     }
4934   }
4935   //
4936   //  Finf kinks loop
4937   // 
4938   //
4939   for (Int_t i =0;i<nentries;i++){
4940     if (sign[i]==0) continue;
4941     AliTPCseed * track0 = (AliTPCseed*)array->At(i);
4942     if (track0==0) {
4943       AliInfo("seed==0");
4944       continue;
4945     }
4946     ntracks++;
4947     //
4948     Double_t cradius0 = 40*40;
4949     Double_t cradius1 = 270*270;
4950     Double_t cdist1=8.;
4951     Double_t cdist2=8.;
4952     Double_t cdist3=0.55; 
4953     for (Int_t j =i+1;j<nentries;j++){
4954       nall++;
4955       if (sign[j]*sign[i]<1) continue;
4956       if ( (nclusters[i]+nclusters[j])>200) continue;
4957       if ( (nclusters[i]+nclusters[j])<80) continue;
4958       if ( TMath::Abs(zm[i]-zm[j])>60.) continue;
4959       if ( TMath::Abs(fim[i]-fim[j])>0.6 && TMath::Abs(fim[i]-fim[j])<5.7 ) continue;
4960       //AliTPCseed * track1 = (AliTPCseed*)array->At(j);  Double_t phase[2][2],radius[2];    
4961       Int_t npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,20);
4962       if (npoints<1) continue;
4963       // cuts on radius      
4964       if (npoints==1){
4965         if (radius[0]<cradius0||radius[0]>cradius1) continue;
4966       }
4967       else{
4968         if ( (radius[0]<cradius0||radius[0]>cradius1) && (radius[1]<cradius0||radius[1]>cradius1) ) continue;
4969       }
4970       //      
4971       Double_t delta1=10000,delta2=10000;
4972       // cuts on the intersection radius
4973       helixes[i].LinearDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta1);
4974       if (radius[0]<20&&delta1<1) continue; //intersection at vertex
4975       if (radius[0]<10&&delta1<3) continue; //intersection at vertex
4976       if (npoints==2){ 
4977         helixes[i].LinearDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta2);
4978         if (radius[1]<20&&delta2<1) continue;  //intersection at vertex
4979         if (radius[1]<10&&delta2<3) continue;  //intersection at vertex 
4980       }
4981       //
4982       Double_t distance1 = TMath::Min(delta1,delta2);
4983       if (distance1>cdist1) continue;  // cut on DCA linear approximation
4984       //
4985       npoints = helixes[i].GetRPHIintersections(helixes[j], phase, radius,20);
4986       helixes[i].ParabolicDCA(helixes[j],phase[0][0],phase[0][1],radius[0],delta1);
4987       if (radius[0]<20&&delta1<1) continue; //intersection at vertex
4988       if (radius[0]<10&&delta1<3) continue; //intersection at vertex
4989       //
4990       if (npoints==2){ 
4991         helixes[i].ParabolicDCA(helixes[j],phase[1][0],phase[1][1],radius[1],delta2);   
4992         if (radius[1]<20&&delta2<1) continue;  //intersection at vertex
4993         if (radius[1]<10&&delta2<3) continue;  //intersection at vertex 
4994       }            
4995       distance1 = TMath::Min(delta1,delta2);
4996       Float_t rkink =0;
4997       if (delta1<delta2){
4998         rkink = TMath::Sqrt(radius[0]);
4999       }
5000       else{
5001         rkink = TMath::Sqrt(radius[1]);
5002       }
5003       if (distance1>cdist2) continue;
5004       //
5005       //
5006       AliTPCseed * track1 = (AliTPCseed*)array->At(j);
5007       //
5008       //
5009       Int_t row0 = GetRowNumber(rkink); 
5010       if (row0<10)  continue;
5011       if (row0>150) continue;
5012       //
5013       //
5014       Float_t dens00=-1,dens01=-1;
5015       Float_t dens10=-1,dens11=-1;
5016       //
5017       Int_t found,foundable,ishared;
5018       track0->GetClusterStatistic(0,row0-5, found, foundable,ishared,kFALSE);
5019       if (foundable>5) dens00 = Float_t(found)/Float_t(foundable);
5020       track0->GetClusterStatistic(row0+5,155, found, foundable,ishared,kFALSE);
5021       if (foundable>5) dens01 = Float_t(found)/Float_t(foundable);
5022       //
5023       track1->GetClusterStatistic(0,row0-5, found, foundable,ishared,kFALSE);
5024       if (foundable>10) dens10 = Float_t(found)/Float_t(foundable);
5025       track1->GetClusterStatistic(row0+5,155, found, foundable,ishared,kFALSE);
5026       if (foundable>10) dens11 = Float_t(found)/Float_t(foundable);
5027       //     
5028       if (dens00<dens10 && dens01<dens11) continue;
5029       if (dens00>dens10 && dens01>dens11) continue;
5030       if (TMath::Max(dens00,dens10)<0.1)  continue;
5031       if (TMath::Max(dens01,dens11)<0.3)  continue;
5032       //
5033       if (TMath::Min(dens00,dens10)>0.6)  continue;
5034       if (TMath::Min(dens01,dens11)>0.6)  continue;
5035
5036       //
5037       AliTPCseed * ktrack0, *ktrack1;
5038       if (dens00>dens10){
5039         ktrack0 = track0;
5040         ktrack1 = track1;
5041       }
5042       else{
5043         ktrack0 = track1;
5044         ktrack1 = track0;
5045       }
5046       if (TMath::Abs(ktrack0->GetC())>5) continue; // cut on the curvature for mother particle
5047       AliExternalTrackParam paramm(*ktrack0);
5048       AliExternalTrackParam paramd(*ktrack1);
5049       if (row0>60&&ktrack1->GetReference().GetX()>90.)new (&paramd) AliExternalTrackParam(ktrack1->GetReference()); 
5050       //
5051       //
5052       kink->SetMother(paramm);
5053       kink->SetDaughter(paramd);
5054       kink->Update();
5055
5056       Float_t x[3] = { kink->GetPosition()[0],kink->GetPosition()[1],kink->GetPosition()[2]};
5057       Int_t index[4];
5058       fkParam->Transform0to1(x,index);
5059       fkParam->Transform1to2(x,index);
5060       row0 = GetRowNumber(x[0]); 
5061
5062       if (kink->GetR()<100) continue;
5063       if (kink->GetR()>240) continue;
5064       if (kink->GetPosition()[2]/kink->GetR()>AliTPCReconstructor::GetCtgRange()) continue;  //out of fiducial volume
5065       if (kink->GetDistance()>cdist3) continue;
5066       Float_t dird = kink->GetDaughterP()[0]*kink->GetPosition()[0]+kink->GetDaughterP()[1]*kink->GetPosition()[1];  // rough direction estimate
5067       if (dird<0) continue;
5068
5069       Float_t dirm = kink->GetMotherP()[0]*kink->GetPosition()[0]+kink->GetMotherP()[1]*kink->GetPosition()[1];  // rough direction estimate
5070       if (dirm<0) continue;
5071       Float_t mpt = TMath::Sqrt(kink->GetMotherP()[0]*kink->GetMotherP()[0]+kink->GetMotherP()[1]*kink->GetMotherP()[1]);
5072       if (mpt<0.2) continue;
5073
5074       if (mpt<1){
5075         //for high momenta momentum not defined well in first iteration
5076         Double_t qt   =  TMath::Sin(kink->GetAngle(2))*ktrack1->GetP();
5077         if (qt>0.35) continue; 
5078       }
5079       
5080       kink->SetLabel(CookLabel(ktrack0,0.4,0,row0),0);
5081       kink->SetLabel(CookLabel(ktrack1,0.4,row0,160),1);
5082       if (dens00>dens10){
5083         kink->SetTPCDensity(dens00,0,0);
5084         kink->SetTPCDensity(dens01,0,1);
5085         kink->SetTPCDensity(dens10,1,0);
5086         kink->SetTPCDensity(dens11,1,1);
5087         kink->SetIndex(i,0);
5088         kink->SetIndex(j,1);
5089       }
5090       else{
5091         kink->SetTPCDensity(dens10,0,0);
5092         kink->SetTPCDensity(dens11,0,1);
5093         kink->SetTPCDensity(dens00,1,0);
5094         kink->SetTPCDensity(dens01,1,1);
5095         kink->SetIndex(j,0);
5096         kink->SetIndex(i,1);
5097       }
5098
5099       if (mpt<1||kink->GetAngle(2)>0.1){
5100         //      angle and densities  not defined yet
5101         if (kink->GetTPCDensityFactor()<0.8) continue;
5102         if ((2-kink->GetTPCDensityFactor())*kink->GetDistance() >0.25) continue;
5103         if (kink->GetAngle(2)*ktrack0->GetP()<0.003) continue; //too small angle
5104         if (kink->GetAngle(2)>0.2&&kink->GetTPCDensityFactor()<1.15) continue;
5105         if (kink->GetAngle(2)>0.2&&kink->GetTPCDensity(0,1)>0.05) continue;
5106
5107         Float_t criticalangle = track0->GetSigmaSnp2()+track0->GetSigmaTgl2();
5108         criticalangle+= track1->GetSigmaSnp2()+track1->GetSigmaTgl2();
5109         criticalangle= 3*TMath::Sqrt(criticalangle);
5110         if (criticalangle>0.02) criticalangle=0.02;
5111         if (kink->GetAngle(2)<criticalangle) continue;
5112       }
5113       //
5114       Int_t drow = Int_t(2.+0.5/(0.05+kink->GetAngle(2)));  // overlap region defined
5115       Float_t shapesum =0;
5116       Float_t sum = 0;
5117       for ( Int_t row = row0-drow; row<row0+drow;row++){
5118         if (row<0) continue;
5119         if (row>155) continue;
5120         if (ktrack0->GetClusterPointer(row)){
5121           AliTPCTrackerPoint *point =ktrack0->GetTrackPoint(row);
5122           shapesum+=point->GetSigmaY()+point->GetSigmaZ();
5123           sum++;
5124         }
5125         if (ktrack1->GetClusterPointer(row)){
5126           AliTPCTrackerPoint *point =ktrack1->GetTrackPoint(row);
5127           shapesum+=point->GetSigmaY()+point->GetSigmaZ();
5128           sum++;
5129         }       
5130       }
5131       if (sum<4){
5132         kink->SetShapeFactor(-1.);
5133       }
5134       else{
5135         kink->SetShapeFactor(shapesum/sum);
5136       }      
5137       //      esd->AddKink(kink);
5138       //
5139       //      kink->SetMother(paramm);
5140       //kink->SetDaughter(paramd);
5141  
5142       Double_t chi2P2 = paramm.GetParameter()[2]-paramd.GetParameter()[2];
5143       chi2P2*=chi2P2;
5144       chi2P2/=paramm.GetCovariance()[5]+paramd.GetCovariance()[5];
5145       Double_t chi2P3 = paramm.GetParameter()[3]-paramd.GetParameter()[3];
5146       chi2P3*=chi2P3;
5147       chi2P3/=paramm.GetCovariance()[9]+paramd.GetCovariance()[9];
5148       //
5149       if (AliTPCReconstructor::StreamLevel()>1) {
5150         (*fDebugStreamer)<<"kinkLpt"<<
5151           "chi2P2="<<chi2P2<<
5152           "chi2P3="<<chi2P3<<
5153           "p0.="<<&paramm<<
5154           "p1.="<<&paramd<<
5155           "k.="<<kink<<
5156           "\n";
5157       }
5158       if ( chi2P2+chi2P3<AliTPCReconstructor::GetRecoParam()->GetKinkAngleCutChi2(0)){
5159         continue;
5160       }
5161       //
5162       kinks->AddLast(kink);
5163       kink = new AliKink;
5164       ncandidates++;
5165     }
5166   }
5167   //
5168   // sort the kinks according quality - and refit them towards vertex
5169   //
5170   Int_t       nkinks    = kinks->GetEntriesFast();
5171   Float_t    *quality   = new Float_t[nkinks];
5172   Int_t      *indexes   = new Int_t[nkinks];
5173   AliTPCseed *mothers   = new AliTPCseed[nkinks];
5174   AliTPCseed *daughters = new AliTPCseed[nkinks];
5175   //
5176   //
5177   for (Int_t i=0;i<nkinks;i++){
5178     quality[i] =100000;
5179     AliKink *kinkl = (AliKink*)kinks->At(i);
5180     //
5181     // refit kinks towards vertex
5182     // 
5183     Int_t index0 = kinkl->GetIndex(0);
5184     Int_t index1 = kinkl->GetIndex(1);
5185     AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
5186     AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
5187     //
5188     Int_t sumn=ktrack0->GetNumberOfClusters()+ktrack1->GetNumberOfClusters();
5189     //
5190     // Refit Kink under if too small angle
5191     //
5192     if (kinkl->GetAngle(2)<0.05){
5193       kinkl->SetTPCRow0(GetRowNumber(kinkl->GetR()));
5194       Int_t row0 = kinkl->GetTPCRow0();
5195       Int_t drow = Int_t(2.+0.5/(0.05+kinkl->GetAngle(2)));
5196       //
5197       //
5198       Int_t last  = row0-drow;
5199       if (last<40) last=40;
5200       if (last<ktrack0->GetFirstPoint()+25) last = ktrack0->GetFirstPoint()+25;
5201       AliTPCseed* seed0 = ReSeed(ktrack0,last,kFALSE);
5202       //
5203       //
5204       Int_t first = row0+drow;
5205       if (first>130) first=130;
5206       if (first>ktrack1->GetLastPoint()-25) first = TMath::Max(ktrack1->GetLastPoint()-25,30);
5207       AliTPCseed* seed1 = ReSeed(ktrack1,first,kTRUE);
5208       //
5209       if (seed0 && seed1){
5210         kinkl->SetStatus(1,8);
5211         if (RefitKink(*seed0,*seed1,*kinkl)) kinkl->SetStatus(1,9);
5212         row0 = GetRowNumber(kinkl->GetR());
5213         sumn = seed0->GetNumberOfClusters()+seed1->GetNumberOfClusters();
5214         mothers[i] = *seed0;
5215         daughters[i] = *seed1;
5216       }
5217       else{
5218         delete kinks->RemoveAt(i);
5219         if (seed0) delete seed0;
5220         if (seed1) delete seed1;
5221         continue;
5222       }
5223       if (kinkl->GetDistance()>0.5 || kinkl->GetR()<110 || kinkl->GetR()>240) {
5224         delete kinks->RemoveAt(i);
5225         if (seed0) delete seed0;
5226         if (seed1) delete seed1;
5227         continue;
5228       }
5229       //
5230       delete seed0;
5231       delete seed1;            
5232     }
5233     //
5234     if (kinkl) quality[i] = 160*((0.1+kinkl->GetDistance())*(2.-kinkl->GetTPCDensityFactor()))/(sumn+40.);  //the longest -clossest will win
5235   }
5236   TMath::Sort(nkinks,quality,indexes,kFALSE);
5237   //
5238   //remove double find kinks
5239   //
5240   for (Int_t ikink0=1;ikink0<nkinks;ikink0++){
5241     AliKink * kink0 = (AliKink*) kinks->At(indexes[ikink0]);
5242     if (!kink0) continue;
5243     //
5244     for (Int_t ikink1=0;ikink1<ikink0;ikink1++){ 
5245       kink0 = (AliKink*) kinks->At(indexes[ikink0]);
5246       if (!kink0) continue;
5247       AliKink * kink1 = (AliKink*) kinks->At(indexes[ikink1]);
5248       if (!kink1) continue;
5249       // if not close kink continue
5250       if (TMath::Abs(kink1->GetPosition()[2]-kink0->GetPosition()[2])>10) continue;
5251       if (TMath::Abs(kink1->GetPosition()[1]-kink0->GetPosition()[1])>10) continue;
5252       if (TMath::Abs(kink1->GetPosition()[0]-kink0->GetPosition()[0])>10) continue;
5253       //
5254       AliTPCseed &mother0   = mothers[indexes[ikink0]];
5255       AliTPCseed &daughter0 = daughters[indexes[ikink0]];
5256       AliTPCseed &mother1   = mothers[indexes[ikink1]];
5257       AliTPCseed &daughter1 = daughters[indexes[ikink1]];
5258       Int_t row0 = (kink0->GetTPCRow0()+kink1->GetTPCRow0())/2;
5259       //
5260       Int_t same  = 0;
5261       Int_t both  = 0;
5262       Int_t samem = 0;
5263       Int_t bothm = 0;
5264       Int_t samed = 0;
5265       Int_t bothd = 0;
5266       //
5267       for (Int_t i=0;i<row0;i++){
5268         if (mother0.GetClusterIndex(i)>0 && mother1.GetClusterIndex(i)>0){
5269           both++;
5270           bothm++;
5271           if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
5272             same++;
5273             samem++;
5274           }
5275         }
5276       }
5277
5278       for (Int_t i=row0;i<158;i++){
5279         if (daughter0.GetClusterIndex(i)>0 && daughter0.GetClusterIndex(i)>0){
5280           both++;
5281           bothd++;
5282           if (mother0.GetClusterIndex(i)==mother1.GetClusterIndex(i)){
5283             same++;
5284             samed++;
5285           }
5286         }
5287       }
5288       Float_t ratio = Float_t(same+1)/Float_t(both+1);
5289       Float_t ratiom = Float_t(samem+1)/Float_t(bothm+1);
5290       Float_t ratiod = Float_t(samed+1)/Float_t(bothd+1);
5291       if (ratio>0.3 && ratiom>0.5 &&ratiod>0.5) {
5292         Int_t sum0 = mother0.GetNumberOfClusters()+daughter0.GetNumberOfClusters();
5293         Int_t sum1 = mother1.GetNumberOfClusters()+daughter1.GetNumberOfClusters();
5294         if (sum1>sum0){
5295           shared[kink0->GetIndex(0)]= kTRUE;
5296           shared[kink0->GetIndex(1)]= kTRUE;      
5297           delete kinks->RemoveAt(indexes[ikink0]);
5298           break;
5299         }
5300         else{
5301           shared[kink1->GetIndex(0)]= kTRUE;
5302           shared[kink1->GetIndex(1)]= kTRUE;      
5303           delete kinks->RemoveAt(indexes[ikink1]);
5304         }
5305       }
5306     }
5307   }
5308
5309
5310   for (Int_t i=0;i<nkinks;i++){
5311     AliKink * kinkl = (AliKink*) kinks->At(indexes[i]);
5312     if (!kinkl) continue;
5313     kinkl->SetTPCRow0(GetRowNumber(kinkl->GetR()));
5314     Int_t index0 = kinkl->GetIndex(0);
5315     Int_t index1 = kinkl->GetIndex(1);
5316     if (circular[index0]||(circular[index1]&&kinkl->GetDistance()>0.2)) continue;
5317     kinkl->SetMultiple(usage[index0],0);
5318     kinkl->SetMultiple(usage[index1],1);
5319     if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>2) continue;
5320     if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>0 && quality[indexes[i]]>0.2) continue;
5321     if (kinkl->GetMultiple()[0]+kinkl->GetMultiple()[1]>0 && kinkl->GetDistance()>0.2) continue;
5322     if (circular[index0]||(circular[index1]&&kinkl->GetDistance()>0.1)) continue;
5323
5324     AliTPCseed * ktrack0 = (AliTPCseed*)array->At(index0);
5325     AliTPCseed * ktrack1 = (AliTPCseed*)array->At(index1);
5326     if (!ktrack0 || !ktrack1) continue;
5327     Int_t index = esd->AddKink(kinkl);
5328     //
5329     //
5330     if ( ktrack0->GetKinkIndex(0)==0 && ktrack1->GetKinkIndex(0)==0) {  //best kink
5331       if (mothers[indexes[i]].GetNumberOfClusters()>20 && daughters[indexes[i]].GetNumberOfClusters()>20 && (mothers[indexes[i]].GetNumberOfClusters()+daughters[indexes[i]].GetNumberOfClusters())>100){
5332         *ktrack0 = mothers[indexes[i]];
5333         *ktrack1 = daughters[indexes[i]];
5334       }
5335     }
5336     //
5337     ktrack0->SetKinkIndex(usage[index0],-(index+1));
5338     ktrack1->SetKinkIndex(usage[index1], (index+1));
5339     usage[index0]++;
5340     usage[index1]++;
5341   }
5342   //
5343   // Remove tracks corresponding to shared kink's
5344   //
5345   for (Int_t i=0;i<nentries;i++){
5346     AliTPCseed * track0 = (AliTPCseed*)array->At(i);
5347     if (!track0) continue;
5348     if (track0->GetKinkIndex(0)!=0) continue;
5349     if (shared[i]) delete array->RemoveAt(i);
5350   }
5351
5352   //
5353   //
5354   RemoveUsed2(array,0.5,0.4,30);
5355   UnsignClusters();
5356   for (Int_t i=0;i<nentries;i++){
5357     AliTPCseed * track0 = (AliTPCseed*)array->At(i);
5358     if (!track0) continue;
5359     track0->CookdEdx(0.02,0.6);
5360     track0->CookPID();
5361   }
5362   //
5363   for (Int_t i=0;i<nentries;i++){
5364     AliTPCseed * track0 = (AliTPCseed*)array->At(i);
5365     if (!track0) continue;
5366     if (track0->Pt()<1.4) continue;
5367     //remove double high momenta tracks - overlapped with kink candidates
5368     Int_t ishared=0;
5369     Int_t all   =0;
5370     for (Int_t icl=track0->GetFirstPoint();icl<track0->GetLastPoint(); icl++){
5371       if (track0->GetClusterPointer(icl)!=0){
5372         all++;
5373         if (track0->GetClusterPointer(icl)->IsUsed(10)) ishared++;
5374       }
5375     }
5376     if (Float_t(ishared+1)/Float_t(all+1)>0.5) {  
5377       delete array->RemoveAt(i);
5378       continue;
5379     }
5380     //
5381     if (track0->GetKinkIndex(0)!=0) continue;
5382     if (track0->GetNumberOfClusters()<80) continue;
5383
5384     AliTPCseed *pmother = new AliTPCseed();
5385     AliTPCseed *pdaughter = new AliTPCseed();
5386     AliKink *pkink = new AliKink;
5387
5388     AliTPCseed & mother = *pmother;
5389     AliTPCseed & daughter = *pdaughter;
5390     AliKink & kinkl = *pkink;
5391     if (CheckKinkPoint(track0,mother,daughter, kinkl)){
5392       if (mother.GetNumberOfClusters()<30||daughter.GetNumberOfClusters()<20) {
5393         delete pmother;
5394         delete pdaughter;
5395         delete pkink;
5396         continue;  //too short tracks
5397       }
5398       if (mother.Pt()<1.4) {
5399         delete pmother;
5400         delete pdaughter;
5401         delete pkink;
5402         continue;
5403       }
5404       Int_t row0= kinkl.GetTPCRow0();
5405       if (kinkl.GetDistance()>0.5 || kinkl.GetR()<110. || kinkl.GetR()>240.) {
5406         delete pmother;
5407         delete pdaughter;
5408         delete pkink;
5409         continue;
5410       }
5411       //
5412       Int_t index = esd->AddKink(&kinkl);      
5413       mother.SetKinkIndex(0,-(index+1));
5414       daughter.SetKinkIndex(0,index+1);
5415       if (mother.GetNumberOfClusters()>50) {
5416         delete array->RemoveAt(i);
5417         array->AddAt(new AliTPCseed(mother),i);
5418       }
5419       else{
5420         array->AddLast(new AliTPCseed(mother));
5421       }
5422       array->AddLast(new AliTPCseed(daughter));      
5423       for (Int_t icl=0;icl<row0;icl++) {
5424         if (mother.GetClusterPointer(icl)) mother.GetClusterPointer(icl)->Use(20);
5425       }
5426       //
5427       for (Int_t icl=row0;icl<158;icl++) {
5428         if (daughter.GetClusterPointer(icl)) daughter.GetClusterPointer(icl)->Use(20);
5429       }
5430       //
5431     }
5432     delete pmother;
5433     delete pdaughter;
5434     delete pkink;
5435   }
5436
5437   delete [] daughters;
5438   delete [] mothers;
5439   //
5440   //
5441   delete [] dca;
5442   delete []circular;
5443   delete []shared;
5444   delete []quality;
5445   delete []indexes;
5446   //
5447   delete kink;
5448   delete[]fim;
5449   delete[] zm;
5450   delete[] z0;
5451   delete [] usage;
5452   delete[] alpha;
5453   delete[] nclusters;
5454   delete[] sign;
5455   delete[] helixes;
5456   kinks->Delete();
5457   delete kinks;
5458
5459   AliInfo(Form("Ncandidates=\t%d\t%d\t%d\t%d\n",esd->GetNumberOfKinks(),ncandidates,ntracks,nall));
5460   timer.Print();
5461 }
5462
5463
5464 Int_t AliTPCtrackerMI::RefitKink(AliTPCseed &mother, AliTPCseed &daughter, const AliESDkink &knk)
5465 {
5466   //
5467   // refit kink towards to the vertex
5468   //
5469   //
5470   AliKink &kink=(AliKink &)knk;
5471
5472   Int_t row0 = GetRowNumber(kink.GetR());
5473   FollowProlongation(mother,0);
5474   mother.Reset(kFALSE);
5475   //
5476   FollowProlongation(daughter,row0);
5477   daughter.Reset(kFALSE);
5478   FollowBackProlongation(daughter,158);
5479   daughter.Reset(kFALSE);
5480   Int_t first = TMath::Max(row0-20,30); 
5481   Int_t last  = TMath::Min(row0+20,140);
5482   //
5483   const Int_t kNdiv =5;
5484   AliTPCseed  param0[kNdiv];  // parameters along the track
5485   AliTPCseed  param1[kNdiv];  // parameters along the track
5486   AliKink     kinks[kNdiv];   // corresponding kink parameters
5487   //
5488   Int_t rows[kNdiv];
5489   for (Int_t irow=0; irow<kNdiv;irow++){
5490     rows[irow] = first +((last-first)*irow)/(kNdiv-1);
5491   }
5492   // store parameters along the track
5493   //
5494   for (Int_t irow=0;irow<kNdiv;irow++){
5495     FollowBackProlongation(mother, rows[irow]);
5496     FollowProlongation(daughter,rows[kNdiv-1-irow]);       
5497     param0[irow] = mother;
5498     param1[kNdiv-1-irow] = daughter;
5499   }
5500   //
5501   // define kinks 
5502   for (Int_t irow=0; irow<kNdiv-1;irow++){
5503     if (param0[irow].GetNumberOfClusters()<kNdiv||param1[irow].GetNumberOfClusters()<kNdiv) continue;
5504     kinks[irow].SetMother(param0[irow]);
5505     kinks[irow].SetDaughter(param1[irow]);
5506     kinks[irow].Update();
5507   }
5508   //
5509   // choose kink with best "quality"
5510   Int_t index =-1;
5511   Double_t mindist = 10000;
5512   for (Int_t irow=0;irow<kNdiv;irow++){
5513     if (param0[irow].GetNumberOfClusters()<20||param1[irow].GetNumberOfClusters()<20) continue;
5514     if (TMath::Abs(kinks[irow].GetR())>240.) continue;
5515     if (TMath::Abs(kinks[irow].GetR())<100.) continue;
5516     //
5517     Float_t normdist = TMath::Abs(param0[irow].GetX()-kinks[irow].GetR())*(0.1+kink.GetDistance());
5518     normdist/= (param0[irow].GetNumberOfClusters()+param1[irow].GetNumberOfClusters()+40.);
5519     if (normdist < mindist){
5520       mindist = normdist;
5521       index = irow;
5522     }
5523   }
5524   //
5525   if (index==-1) return 0;
5526   //
5527   //
5528   param0[index].Reset(kTRUE);
5529   FollowProlongation(param0[index],0);
5530   //
5531   mother = param0[index];
5532   daughter = param1[index];  // daughter in vertex
5533   //
5534   kink.SetMother(mother);
5535   kink.SetDaughter(daughter);
5536   kink.Update();
5537   kink.SetTPCRow0(GetRowNumber(kink.GetR()));
5538   kink.SetTPCncls(param0[index].GetNumberOfClusters(),0);
5539   kink.SetTPCncls(param1[index].GetNumberOfClusters(),1);
5540   kink.SetLabel(CookLabel(&mother,0.4, 0,kink.GetTPCRow0()),0);
5541   kink.SetLabel(CookLabel(&daughter,0.4, kink.GetTPCRow0(),160),1);
5542   mother.SetLabel(kink.GetLabel(0));
5543   daughter.SetLabel(kink.GetLabel(1));
5544
5545   return 1;
5546 }
5547
5548
5549 void AliTPCtrackerMI::UpdateKinkQualityM(AliTPCseed * seed){
5550   //
5551   // update Kink quality information for mother after back propagation
5552   //
5553   if (seed->GetKinkIndex(0)>=0) return; 
5554   for (Int_t ikink=0;ikink<3;ikink++){
5555     Int_t index = seed->GetKinkIndex(ikink);
5556     if (index>=0) break;
5557     index = TMath::Abs(index)-1;
5558     AliESDkink * kink = fEvent->GetKink(index);
5559     kink->SetTPCDensity(-1,0,0);
5560     kink->SetTPCDensity(1,0,1);
5561     //
5562     Int_t row0 = kink->GetTPCRow0() - 2 - Int_t( 0.5/ (0.05+kink->GetAngle(2)));
5563     if (row0<15) row0=15;
5564     //
5565     Int_t row1 = kink->GetTPCRow0() + 2 +  Int_t( 0.5/ (0.05+kink->GetAngle(2)));
5566     if (row1>145) row1=145;
5567     //
5568     Int_t found,foundable,shared;
5569     seed->GetClusterStatistic(0,row0, found, foundable,shared,kFALSE);
5570     if (foundable>5)   kink->SetTPCDensity(Float_t(found)/Float_t(foundable),0,0);
5571     seed->GetClusterStatistic(row1,155, found, foundable,shared,kFALSE);
5572     if (foundable>5)   kink->SetTPCDensity(Float_t(found)/Float_t(foundable),0,1);
5573   }
5574     
5575 }
5576
5577 void AliTPCtrackerMI::UpdateKinkQualityD(AliTPCseed * seed){
5578   //
5579   // update Kink quality information for daughter after refit
5580   //
5581   if (seed->GetKinkIndex(0)<=0) return; 
5582   for (Int_t ikink=0;ikink<3;ikink++){
5583     Int_t index = seed->GetKinkIndex(ikink);
5584     if (index<=0) break;
5585     index = TMath::Abs(index)-1;
5586     AliESDkink * kink = fEvent->GetKink(index);
5587     kink->SetTPCDensity(-1,1,0);
5588     kink->SetTPCDensity(-1,1,1);
5589     //
5590     Int_t row0 = kink->GetTPCRow0() -2 - Int_t( 0.5/ (0.05+kink->GetAngle(2)));
5591     if (row0<15) row0=15;
5592     //
5593     Int_t row1 = kink->GetTPCRow0() +2 +  Int_t( 0.5/ (0.05+kink->GetAngle(2)));
5594     if (row1>145) row1=145;
5595     //
5596     Int_t found,foundable,shared;
5597     seed->GetClusterStatistic(0,row0, found, foundable,shared,kFALSE);
5598     if (foundable>5)   kink->SetTPCDensity(Float_t(found)/Float_t(foundable),1,0);
5599     seed->GetClusterStatistic(row1,155, found, foundable,shared,kFALSE);
5600     if (foundable>5)   kink->SetTPCDensity(Float_t(found)/Float_t(foundable),1,1);
5601   }
5602     
5603 }
5604
5605
5606 Int_t  AliTPCtrackerMI::CheckKinkPoint(AliTPCseed*seed,AliTPCseed &mother, AliTPCseed &daughter, const AliESDkink &knk)
5607 {
5608   //
5609   // check kink point for given track
5610   // if return value=0 kink point not found
5611   // otherwise seed0 correspond to mother particle
5612   //           seed1 correspond to daughter particle
5613   //           kink  parameter of kink point
5614   AliKink &kink=(AliKink &)knk;
5615
5616   Int_t middlerow = (seed->GetFirstPoint()+seed->GetLastPoint())/2;
5617   Int_t first = seed->GetFirstPoint(); 
5618   Int_t last  = seed->GetLastPoint();
5619   if (last-first<20) return 0;          // shortest length - 2*30 = 60 pad-rows
5620
5621   
5622   AliTPCseed *seed1 = ReSeed(seed,middlerow+20, kTRUE);  //middle of chamber
5623   if (!seed1) return 0;
5624   FollowProlongation(*seed1,seed->GetLastPoint()-20);
5625   seed1->Reset(kTRUE);
5626   FollowProlongation(*seed1,158);
5627   seed1->Reset(kTRUE);  
5628   last = seed1->GetLastPoint();
5629   //
5630   AliTPCseed *seed0 = new AliTPCseed(*seed);
5631   seed0->Reset(kFALSE);
5632   seed0->Reset();
5633   //
5634   AliTPCseed  param0[20];  // parameters along the track
5635   AliTPCseed  param1[20];  // parameters along the track
5636   AliKink     kinks[20];   // corresponding kink parameters
5637   Int_t rows[20];
5638   for (Int_t irow=0; irow<20;irow++){
5639     rows[irow] = first +((last-first)*irow)/19;
5640   }
5641   // store parameters along the track
5642   //
5643   for (Int_t irow=0;irow<20;irow++){
5644     FollowBackProlongation(*seed0, rows[irow]);
5645     FollowProlongation(*seed1,rows[19-irow]);       
5646     param0[irow] = *seed0;
5647     param1[19-irow] = *seed1;
5648   }
5649   //
5650   // define kinks 
5651   for (Int_t irow=0; irow<19;irow++){
5652     kinks[irow].SetMother(param0[irow]);
5653     kinks[irow].SetDaughter(param1[irow]);
5654     kinks[irow].Update();
5655   }
5656   //
5657   // choose kink with biggest change of angle
5658   Int_t index =-1;
5659   Double_t maxchange= 0;
5660   for (Int_t irow=1;irow<19;irow++){
5661     if (TMath::Abs(kinks[irow].GetR())>240.) continue;
5662     if (TMath::Abs(kinks[irow].GetR())<110.) continue;
5663     Float_t quality = TMath::Abs(kinks[irow].GetAngle(2))/(3.+TMath::Abs(kinks[irow].GetR()-param0[irow].GetX()));
5664     if ( quality > maxchange){
5665       maxchange = quality;
5666       index = irow;
5667       //
5668     }
5669   }
5670   delete seed0;
5671   delete seed1;
5672   if (index<0) return 0;
5673   //
5674   Int_t row0    = GetRowNumber(kinks[index].GetR());   //row 0 estimate
5675   seed0 = new AliTPCseed(param0[index]);
5676   seed1 = new AliTPCseed(param1[index]);
5677   seed0->Reset(kFALSE);
5678   seed1->Reset(kFALSE);
5679   seed0->ResetCovariance(10.);
5680   seed1->ResetCovariance(10.);
5681   FollowProlongation(*seed0,0);
5682   FollowBackProlongation(*seed1,158);
5683   mother = *seed0; // backup mother at position 0
5684   seed0->Reset(kFALSE);  
5685   seed1->Reset(kFALSE);
5686   seed0->ResetCovariance(10.);
5687   seed1->ResetCovariance(10.);
5688   //
5689   first = TMath::Max(row0-20,0);
5690   last  = TMath::Min(row0+20,158);
5691   //
5692   for (Int_t irow=0; irow<20;irow++){
5693     rows[irow] = first +((last-first)*irow)/19;
5694   }
5695   // store parameters along the track
5696   //
5697   for (Int_t irow=0;irow<20;irow++){
5698     FollowBackProlongation(*seed0, rows[irow]);
5699     FollowProlongation(*seed1,rows[19-irow]);       
5700     param0[irow] = *seed0;
5701     param1[19-irow] = *seed1;
5702   }
5703   //
5704   // define kinks 
5705   for (Int_t irow=0; irow<19;irow++){
5706     kinks[irow].SetMother(param0[irow]);
5707     kinks[irow].SetDaughter(param1[irow]);
5708     //    param0[irow].Dump();
5709     //param1[irow].Dump();
5710     kinks[irow].Update();
5711   }
5712   //
5713   // choose kink with biggest change of angle
5714   index =-1;
5715   maxchange= 0;
5716   for (Int_t irow=0;irow<20;irow++){
5717     if (TMath::Abs(kinks[irow].GetR())>250.) continue;
5718     if (TMath::Abs(kinks[irow].GetR())<90.) continue;
5719     Float_t quality = TMath::Abs(kinks[irow].GetAngle(2))/(3.+TMath::Abs(kinks[irow].GetR()-param0[irow].GetX()));
5720     if ( quality > maxchange){
5721       maxchange = quality;
5722       index = irow;
5723       //
5724     }
5725   }
5726   //
5727   //
5728   if (index==-1 || param0[index].GetNumberOfClusters()+param1[index].GetNumberOfClusters()<100){
5729     delete seed0;
5730     delete seed1;
5731     return 0;
5732   }
5733
5734   //  Float_t anglesigma = TMath::Sqrt(param0[index].fC22+param0[index].fC33+param1[index].fC22+param1[index].fC33);
5735   
5736   kink.SetMother(param0[index]);
5737   kink.SetDaughter(param1[index]);
5738   kink.Update();
5739
5740   Double_t chi2P2 = param0[index].GetParameter()[2]-param1[index].GetParameter()[2];
5741   chi2P2*=chi2P2;
5742   chi2P2/=param0[index].GetCovariance()[5]+param1[index].GetCovariance()[5];
5743   Double_t chi2P3 = param0[index].GetParameter()[3]-param1[index].GetParameter()[3];
5744   chi2P3*=chi2P3;
5745   chi2P3/=param0[index].GetCovariance()[9]+param1[index].GetCovariance()[9];
5746   //
5747   if (AliTPCReconstructor::StreamLevel()>1) {
5748     (*fDebugStreamer)<<"kinkHpt"<<
5749       "chi2P2="<<chi2P2<<
5750       "chi2P3="<<chi2P3<<
5751       "p0.="<<&param0[index]<<
5752       "p1.="<<&param1[index]<<
5753       "k.="<<&kink<<
5754       "\n";
5755   }
5756   if ( chi2P2+chi2P3<AliTPCReconstructor::GetRecoParam()->GetKinkAngleCutChi2(0)){
5757     delete seed0;
5758     delete seed1;
5759     return 0; 
5760   }
5761
5762
5763   row0    = GetRowNumber(kink.GetR());   
5764   kink.SetTPCRow0(row0);
5765   kink.SetLabel(CookLabel(seed0,0.5,0,row0),0);
5766   kink.SetLabel(CookLabel(seed1,0.5,row0,158),1);
5767   kink.SetIndex(-10,0);
5768   kink.SetIndex(int(param0[index].GetNumberOfClusters()+param1[index].GetNumberOfClusters()),1);
5769   kink.SetTPCncls(param0[index].GetNumberOfClusters(),0);
5770   kink.SetTPCncls(param1[index].GetNumberOfClusters(),1);
5771   //
5772   //
5773   //  new (&mother) AliTPCseed(param0[index]);
5774   daughter = param1[index];
5775   daughter.SetLabel(kink.GetLabel(1));  
5776   param0[index].Reset(kTRUE);
5777   FollowProlongation(param0[index],0);    
5778   mother = param0[index];
5779   mother.SetLabel(kink.GetLabel(0));
5780   if ( chi2P2+chi2P3<AliTPCReconstructor::GetRecoParam()->GetKinkAngleCutChi2(1)){
5781     mother=*seed;
5782   }
5783   delete seed0;
5784   delete seed1;
5785   //
5786   return 1;
5787 }
5788
5789
5790
5791
5792 AliTPCseed*  AliTPCtrackerMI::ReSeed(AliTPCseed *t)
5793 {
5794   //
5795   // reseed - refit -  track
5796   //
5797   Int_t first = 0;
5798   //  Int_t last  = fSectors->GetNRows()-1;
5799   //
5800   if (fSectors == fOuterSec){
5801     first = TMath::Max(first, t->GetFirstPoint()-fInnerSec->GetNRows());
5802     //last  = 
5803   }
5804   else
5805     first = t->GetFirstPoint();
5806   //
5807   AliTPCseed * seed = MakeSeed(t,0.1,0.5,0.9);
5808   FollowBackProlongation(*t,fSectors->GetNRows()-1);
5809   t->Reset(kFALSE);
5810   FollowProlongation(*t,first);
5811   return seed;
5812 }
5813
5814
5815
5816
5817
5818
5819
5820 //_____________________________________________________________________________
5821 Int_t AliTPCtrackerMI::ReadSeeds(const TFile *inp) {
5822   //-----------------------------------------------------------------
5823   // This function reades track seeds.
5824   //-----------------------------------------------------------------
5825   TDirectory *savedir=gDirectory; 
5826
5827   TFile *in=(TFile*)inp;
5828   if (!in->IsOpen()) {
5829      cerr<<"AliTPCtrackerMI::ReadSeeds(): input file is not open !\n";
5830      return 1;
5831   }
5832
5833   in->cd();
5834   TTree *seedTree=(TTree*)in->Get("Seeds");
5835   if (!seedTree) {
5836      cerr<<"AliTPCtrackerMI::ReadSeeds(): ";
5837      cerr<<"can't get a tree with track seeds !\n";
5838      return 2;
5839   }
5840   AliTPCtrack *seed=new AliTPCtrack; 
5841   seedTree->SetBranchAddress("tracks",&seed);
5842   
5843   if (fSeeds==0) fSeeds=new TObjArray(15000);
5844
5845   Int_t n=(Int_t)seedTree->GetEntries();
5846   for (Int_t i=0; i<n; i++) {
5847      seedTree->GetEvent(i);
5848      fSeeds->AddLast(new AliTPCseed(*seed/*,seed->GetAlpha()*/));
5849   }
5850   
5851   delete seed;
5852   delete seedTree; 
5853   savedir->cd();
5854   return 0;
5855 }
5856
5857 Int_t AliTPCtrackerMI::Clusters2Tracks (AliESDEvent *const esd)
5858 {
5859   //
5860   
5861   if (fSeeds) DeleteSeeds();
5862   fEvent = esd;
5863   Clusters2Tracks();
5864   if (!fSeeds) return 1;
5865   FillESD(fSeeds);
5866   if (AliTPCReconstructor::StreamLevel()>3)  DumpClusters(0,fSeeds);
5867   return 0;
5868   //
5869 }
5870
5871
5872 //_____________________________________________________________________________
5873 Int_t AliTPCtrackerMI::Clusters2Tracks() {
5874   //-----------------------------------------------------------------
5875   // This is a track finder.
5876   //-----------------------------------------------------------------
5877   TDirectory *savedir=gDirectory; 
5878   TStopwatch timer;
5879
5880   fIteration = 0;
5881   fSeeds = Tracking();
5882
5883   if (fDebug>0){
5884     Info("Clusters2Tracks","Time for tracking: \t");timer.Print();timer.Start();
5885   }
5886   //activate again some tracks
5887   for (Int_t i=0; i<fSeeds->GetEntriesFast(); i++) {
5888     AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;    
5889     if (!pt) continue;    
5890     Int_t nc=t.GetNumberOfClusters();
5891     if (nc<20) {
5892       delete fSeeds->RemoveAt(i);
5893       continue;
5894     } 
5895     CookLabel(pt,0.1); 
5896     if (pt->GetRemoval()==10) {
5897       if (pt->GetDensityFirst(20)>0.8 || pt->GetDensityFirst(30)>0.8 || pt->GetDensityFirst(40)>0.7)
5898         pt->Desactivate(10);  // make track again active
5899       else{
5900         pt->Desactivate(20);    
5901         delete fSeeds->RemoveAt(i);
5902       }
5903     } 
5904   }
5905   //
5906   RemoveUsed2(fSeeds,0.85,0.85,0);
5907   if (AliTPCReconstructor::GetRecoParam()->GetDoKinks()) FindKinks(fSeeds,fEvent);
5908   //FindCurling(fSeeds, fEvent,0);  
5909   if (AliTPCReconstructor::StreamLevel()>5)  FindMultiMC(fSeeds, fEvent,-1); // find multi found tracks
5910   RemoveUsed2(fSeeds,0.5,0.4,20);
5911   FindSplitted(fSeeds, fEvent,0); // find multi found tracks
5912   if (AliTPCReconstructor::StreamLevel()>5)  FindMultiMC(fSeeds, fEvent,0); // find multi found tracks
5913
5914  //  //
5915 //   // refit short tracks
5916 //   //
5917   Int_t nseed=fSeeds->GetEntriesFast();
5918   //
5919   Int_t found = 0;
5920   for (Int_t i=0; i<nseed; i++) {
5921     AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;    
5922     if (!pt) continue;    
5923     Int_t nc=t.GetNumberOfClusters();
5924     if (nc<15) {
5925       delete fSeeds->RemoveAt(i);
5926       continue;
5927     }
5928     CookLabel(pt,0.1); //For comparison only
5929     //if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
5930     if ((pt->IsActive() || (pt->GetRemoval()==10) )){
5931       found++;      
5932       if (fDebug>0) cerr<<found<<'\r';      
5933       pt->SetLab2(i);
5934     }
5935     else
5936       delete fSeeds->RemoveAt(i);
5937   }
5938
5939   
5940   //RemoveOverlap(fSeeds,0.99,7,kTRUE);  
5941   SignShared(fSeeds);  
5942   //RemoveUsed(fSeeds,0.9,0.9,6);
5943   // 
5944   nseed=fSeeds->GetEntriesFast();
5945   found = 0;
5946   for (Int_t i=0; i<nseed; i++) {
5947     AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;    
5948     if (!pt) continue;    
5949     Int_t nc=t.GetNumberOfClusters();
5950     if (nc<15) {
5951       delete fSeeds->RemoveAt(i);
5952       continue;
5953     }
5954     t.SetUniqueID(i);
5955     t.CookdEdx(0.02,0.6);
5956     //    CheckKinkPoint(&t,0.05);
5957     //if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
5958     if ((pt->IsActive() || (pt->GetRemoval()==10) )){
5959       found++;
5960       if (fDebug>0){
5961         cerr<<found<<'\r';      
5962       }
5963       pt->SetLab2(i);
5964     }
5965     else
5966       delete fSeeds->RemoveAt(i);
5967     //AliTPCseed * seed1 = ReSeed(pt,0.05,0.5,1);
5968     //if (seed1){
5969     //  FollowProlongation(*seed1,0);
5970     //  Int_t n = seed1->GetNumberOfClusters();
5971     //  printf("fP4\t%f\t%f\n",seed1->GetC(),pt->GetC());
5972     //  printf("fN\t%d\t%d\n", seed1->GetNumberOfClusters(),pt->GetNumberOfClusters());
5973     //
5974     //}
5975     //AliTPCseed * seed2 = ReSeed(pt,0.95,0.5,0.05);
5976     
5977   }
5978
5979   SortTracks(fSeeds, 1);
5980   
5981   /*    
5982   fIteration = 1;
5983   PrepareForBackProlongation(fSeeds,5.);
5984   PropagateBack(fSeeds);
5985   printf("Time for back propagation: \t");timer.Print();timer.Start();
5986   
5987   fIteration = 2;
5988   
5989   PrepareForProlongation(fSeeds,5.);
5990   PropagateForward2(fSeeds);
5991    
5992   printf("Time for FORWARD propagation: \t");timer.Print();timer.Start();
5993   // RemoveUsed(fSeeds,0.7,0.7,6);
5994   //RemoveOverlap(fSeeds,0.9,7,kTRUE);
5995    
5996   nseed=fSeeds->GetEntriesFast();
5997   found = 0;
5998   for (Int_t i=0; i<nseed; i++) {
5999     AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;    
6000     if (!pt) continue;    
6001     Int_t nc=t.GetNumberOfClusters();
6002     if (nc<15) {
6003       delete fSeeds->RemoveAt(i);
6004       continue;
6005     }
6006     t.CookdEdx(0.02,0.6);
6007     //    CookLabel(pt,0.1); //For comparison only
6008     //if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
6009     if ((pt->IsActive() || (pt->fRemoval==10) )){
6010       cerr<<found++<<'\r';      
6011     }
6012     else
6013       delete fSeeds->RemoveAt(i);
6014     pt->fLab2 = i;
6015   }
6016   */
6017  
6018   //  fNTracks = found;
6019   if (fDebug>0){
6020     Info("Clusters2Tracks","Time for overlap removal, track writing and dedx cooking: \t"); timer.Print();timer.Start();
6021   }
6022   //
6023   //  cerr<<"Number of found tracks : "<<"\t"<<found<<endl;  
6024   Info("Clusters2Tracks","Number of found tracks %d",found);  
6025   savedir->cd();
6026   //  UnloadClusters();
6027   //  
6028   return 0;
6029 }
6030
6031 void AliTPCtrackerMI::Tracking(TObjArray * arr)
6032 {
6033   //
6034   // tracking of the seeds
6035   //
6036
6037   fSectors = fOuterSec;
6038   ParallelTracking(arr,150,63);
6039   fSectors = fOuterSec;
6040   ParallelTracking(arr,63,0);
6041 }
6042
6043 TObjArray * AliTPCtrackerMI::Tracking(Int_t seedtype, Int_t i1, Int_t i2, Float_t cuts[4], Float_t dy, Int_t dsec)
6044 {
6045   //
6046   //
6047   //tracking routine
6048   TObjArray * arr = new TObjArray;
6049   // 
6050   fSectors = fOuterSec;
6051   TStopwatch timer;
6052   timer.Start();
6053   for (Int_t sec=0;sec<fkNOS;sec++){
6054     if (seedtype==3) MakeSeeds3(arr,sec,i1,i2,cuts,dy, dsec);
6055     if (seedtype==4) MakeSeeds5(arr,sec,i1,i2,cuts,dy);    
6056     if (seedtype==2) MakeSeeds2(arr,sec,i1,i2,cuts,dy);
6057   }
6058   if (fDebug>0){
6059     Info("Tracking","\nSeeding - %d\t%d\t%d\t%d\n",seedtype,i1,i2,arr->GetEntriesFast());
6060     timer.Print();
6061     timer.Start();
6062   }
6063   Tracking(arr);  
6064   if (fDebug>0){
6065     timer.Print();
6066   }
6067
6068   return arr;
6069 }
6070
6071 TObjArray * AliTPCtrackerMI::Tracking()
6072 {
6073   //
6074   //
6075   if (AliTPCReconstructor::GetRecoParam()->GetSpecialSeeding()) return TrackingSpecial();
6076   TStopwatch timer;
6077   timer.Start();
6078   Int_t nup=fOuterSec->GetNRows()+fInnerSec->GetNRows();
6079
6080   TObjArray * seeds = new TObjArray;
6081   TObjArray * arr=0;
6082   Int_t fLastSeedRowSec=AliTPCReconstructor::GetRecoParam()->GetLastSeedRowSec();
6083   Int_t gapPrim = AliTPCReconstructor::GetRecoParam()->GetSeedGapPrim();
6084   Int_t gapSec = AliTPCReconstructor::GetRecoParam()->GetSeedGapSec();
6085   
6086   Int_t gap =20;
6087   Float_t cuts[4];
6088   cuts[0] = 0.002;
6089   cuts[1] = 1.5;
6090   cuts[2] = 3.;
6091   cuts[3] = 3.;
6092   Float_t fnumber  = 3.0;
6093   Float_t fdensity = 3.0;
6094   
6095   //  
6096   //find primaries  
6097   cuts[0]=0.0066;
6098   for (Int_t delta = 0; delta<18; delta+=gapPrim){
6099     //
6100     cuts[0]=0.0070;
6101     cuts[1] = 1.5;
6102     arr = Tracking(3,nup-1-delta,nup-1-delta-gap,cuts,-1,1);
6103     SumTracks(seeds,arr);   
6104     SignClusters(seeds,fnumber,fdensity); 
6105     //
6106     for (Int_t i=2;i<6;i+=2){
6107       // seed high pt tracks
6108       cuts[0]=0.0022;
6109       cuts[1]=0.3;
6110       arr = Tracking(3,nup-i-delta,nup-i-delta-gap,cuts,-1,0);
6111       SumTracks(seeds,arr);   
6112       SignClusters(seeds,fnumber,fdensity);        
6113     }
6114   }
6115   fnumber  = 4;
6116   fdensity = 4.;
6117   //  RemoveUsed(seeds,0.9,0.9,1);
6118   //  UnsignClusters();
6119   //  SignClusters(seeds,fnumber,fdensity);    
6120
6121   //find primaries  
6122   cuts[0]=0.0077;
6123   for (Int_t delta = 20; delta<120; delta+=gapPrim){
6124     //
6125     // seed high pt tracks
6126     cuts[0]=0.0060;
6127     cuts[1]=0.3;
6128     cuts[2]=6.;
6129     arr = Tracking(3,nup-delta,nup-delta-gap,cuts,-1);
6130     SumTracks(seeds,arr);   
6131     SignClusters(seeds,fnumber,fdensity);            
6132
6133     cuts[0]=0.003;
6134     cuts[1]=0.3;
6135     cuts[2]=6.;
6136     arr = Tracking(3,nup-delta-5,nup-delta-5-gap,cuts,-1);
6137     SumTracks(seeds,arr);   
6138     SignClusters(seeds,fnumber,fdensity);            
6139   }
6140
6141   cuts[0] = 0.01;
6142   cuts[1] = 2.0;
6143   cuts[2] = 3.;
6144   cuts[3] = 2.0;
6145   fnumber  = 2.;
6146   fdensity = 2.;
6147   
6148   if (fDebug>0){
6149     Info("Tracking()","\n\nPrimary seeding\t%d\n\n",seeds->GetEntriesFast());
6150     timer.Print();
6151     timer.Start();
6152   }
6153   //  RemoveUsed(seeds,0.75,0.75,1);
6154   //UnsignClusters();
6155   //SignClusters(seeds,fnumber,fdensity);
6156   
6157   // find secondaries
6158
6159   cuts[0] = 0.3;
6160   cuts[1] = 1.5;
6161   cuts[2] = 3.;
6162   cuts[3] = 1.5;
6163
6164   arr = Tracking(4,nup-1,nup-1-gap,cuts,-1);
6165   SumTracks(seeds,arr);   
6166   SignClusters(seeds,fnumber,fdensity);   
6167   //
6168   arr = Tracking(4,nup-2,nup-2-gap,cuts,-1);
6169   SumTracks(seeds,arr);   
6170   SignClusters(seeds,fnumber,fdensity);   
6171   //
6172   arr = Tracking(4,nup-3,nup-3-gap,cuts,-1);
6173   SumTracks(seeds,arr);   
6174   SignClusters(seeds,fnumber,fdensity);   
6175   //
6176   arr = Tracking(4,nup-5,nup-5-gap,cuts,-1);
6177   SumTracks(seeds,arr);   
6178   SignClusters(seeds,fnumber,fdensity);   
6179   //
6180   arr = Tracking(4,nup-7,nup-7-gap,cuts,-1);
6181   SumTracks(seeds,arr);   
6182   SignClusters(seeds,fnumber,fdensity);   
6183   //
6184   //
6185   arr = Tracking(4,nup-9,nup-9-gap,cuts,-1);
6186   SumTracks(seeds,arr);   
6187   SignClusters(seeds,fnumber,fdensity);   
6188   //
6189
6190
6191   for (Int_t delta = 9; delta<30; delta+=gapSec){
6192     //
6193     cuts[0] = 0.3;
6194     cuts[1] = 1.5;
6195     cuts[2] = 3.;
6196     cuts[3] = 1.5;
6197     arr = Tracking(4,nup-1-delta,nup-1-delta-gap,cuts,-1);
6198     SumTracks(seeds,arr);   
6199     SignClusters(seeds,fnumber,fdensity);   
6200     //
6201     arr = Tracking(4,nup-3-delta,nup-5-delta-gap,cuts,4);
6202     SumTracks(seeds,arr);   
6203     SignClusters(seeds,fnumber,fdensity); 
6204     //
6205   } 
6206   fnumber  = 1;
6207   fdensity = 1;
6208   //
6209   // change cuts
6210   fnumber  = 2.;
6211   fdensity = 2.;
6212   cuts[0]=0.0080;
6213
6214
6215   // find secondaries
6216   for (Int_t delta = 30; delta<fLastSeedRowSec; delta+=gapSec){
6217     //
6218     cuts[0] = 0.3;
6219     cuts[1] = 3.5;
6220     cuts[2] = 3.;
6221     cuts[3] = 3.5;
6222     arr = Tracking(4,nup-1-delta,nup-1-delta-gap,cuts,-1);
6223     SumTracks(seeds,arr);   
6224     SignClusters(seeds,fnumber,fdensity);   
6225     //
6226     arr = Tracking(4,nup-5-delta,nup-5-delta-gap,cuts,5 );
6227     SumTracks(seeds,arr);   
6228     SignClusters(seeds,fnumber,fdensity);   
6229   }
6230  
6231   if (fDebug>0){
6232     Info("Tracking()","\n\nSecondary seeding\t%d\n\n",seeds->GetEntriesFast());
6233     timer.Print();
6234     timer.Start();
6235   }
6236
6237   return seeds;
6238   //
6239       
6240 }
6241
6242
6243 TObjArray * AliTPCtrackerMI::TrackingSpecial()
6244 {
6245   //
6246   // seeding adjusted for laser and cosmic tests - short tracks with big inclination angle
6247   // no primary vertex seeding tried
6248   //
6249   TStopwatch timer;
6250   timer.Start();
6251   Int_t nup=fOuterSec->GetNRows()+fInnerSec->GetNRows();
6252
6253   TObjArray * seeds = new TObjArray;
6254   TObjArray * arr=0;
6255   
6256   Int_t   gap  = 15;
6257   Float_t cuts[4];
6258   Float_t fnumber  = 3.0;
6259   Float_t fdensity = 3.0;
6260   
6261   // find secondaries
6262   cuts[0] = AliTPCReconstructor::GetRecoParam()->GetMaxC();   // max curvature
6263   cuts[1] = 3.5;    // max tan(phi) angle for seeding
6264   cuts[2] = 3.;     // not used (cut on z primary vertex)     
6265   cuts[3] = 3.5;    // max tan(theta) angle for seeding
6266
6267   for (Int_t delta = 0; nup-delta-gap-1>0; delta+=3){
6268     //
6269     arr = Tracking(4,nup-1-delta,nup-1-delta-gap,cuts,-1);
6270     SumTracks(seeds,arr);   
6271     SignClusters(seeds,fnumber,fdensity);   
6272   } 
6273  
6274   if (fDebug>0){
6275     Info("Tracking()","\n\nSecondary seeding\t%d\n\n",seeds->GetEntriesFast());
6276     timer.Print();
6277     timer.Start();
6278   }
6279
6280   return seeds;
6281   //
6282       
6283 }
6284
6285
6286 void AliTPCtrackerMI::SumTracks(TObjArray *arr1,TObjArray *&arr2) const
6287 {
6288   //
6289   //sum tracks to common container
6290   //remove suspicious tracks
6291   Int_t nseed = arr2->GetEntriesFast();
6292   for (Int_t i=0;i<nseed;i++){
6293     AliTPCseed *pt=(AliTPCseed*)arr2->UncheckedAt(i);    
6294     if (pt){
6295       //
6296       // remove tracks with too big curvature
6297       //
6298       if (TMath::Abs(pt->GetC())>AliTPCReconstructor::GetRecoParam()->GetMaxC()){
6299         delete arr2->RemoveAt(i);
6300         continue;
6301       }
6302        // REMOVE VERY SHORT  TRACKS
6303       if (pt->GetNumberOfClusters()<20){ 
6304         delete arr2->RemoveAt(i);
6305         continue;
6306       }// patch 28 fev06
6307       // NORMAL ACTIVE TRACK
6308       if (pt->IsActive()){
6309         arr1->AddLast(arr2->RemoveAt(i));
6310         continue;
6311       }
6312       //remove not usable tracks
6313       if (pt->GetRemoval()!=10){
6314         delete arr2->RemoveAt(i);
6315         continue;
6316       }
6317      
6318       // ENABLE ONLY ENOUGH GOOD STOPPED TRACKS
6319       if (pt->GetDensityFirst(20)>0.8 || pt->GetDensityFirst(30)>0.8 || pt->GetDensityFirst(40)>0.7)
6320         arr1->AddLast(arr2->RemoveAt(i));
6321       else{      
6322         delete arr2->RemoveAt(i);
6323       }
6324     }
6325   }
6326   delete arr2;  arr2 = 0;
6327 }
6328
6329
6330
6331 void  AliTPCtrackerMI::ParallelTracking(TObjArray *const arr, Int_t rfirst, Int_t rlast)
6332 {
6333   //
6334   // try to track in parralel
6335
6336   Int_t nseed=arr->GetEntriesFast();
6337   //prepare seeds for tracking
6338   for (Int_t i=0; i<nseed; i++) {
6339     AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i), &t=*pt; 
6340     if (!pt) continue;
6341     if (!t.IsActive()) continue;
6342     // follow prolongation to the first layer
6343     if ( (fSectors ==fInnerSec) || (t.GetFirstPoint()-fkParam->GetNRowLow()>rfirst+1) )  
6344       FollowProlongation(t, rfirst+1);
6345   }
6346
6347
6348   //
6349   for (Int_t nr=rfirst; nr>=rlast; nr--){ 
6350     if (nr<fInnerSec->GetNRows()) 
6351       fSectors = fInnerSec;
6352     else
6353       fSectors = fOuterSec;
6354     // make indexes with the cluster tracks for given       
6355
6356     // find nearest cluster
6357     for (Int_t i=0; i<nseed; i++) {
6358       AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i), &t=*pt;       
6359       if (!pt) continue;
6360       if (nr==80) pt->UpdateReference();
6361       if (!pt->IsActive()) continue;
6362       //      if ( (fSectors ==fOuterSec) && (pt->fFirstPoint-fkParam->GetNRowLow())<nr) continue;
6363       if (pt->GetRelativeSector()>17) {
6364         continue;
6365       }
6366       UpdateClusters(t,nr);
6367     }
6368     // prolonagate to the nearest cluster - if founded
6369     for (Int_t i=0; i<nseed; i++) {
6370       AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i); 
6371       if (!pt) continue;
6372       if (!pt->IsActive()) continue; 
6373       // if ((fSectors ==fOuterSec) && (pt->fFirstPoint-fkParam->GetNRowLow())<nr) continue;
6374       if (pt->GetRelativeSector()>17) {
6375         continue;
6376       }
6377       FollowToNextCluster(*pt,nr);
6378     }
6379   }    
6380 }
6381
6382 void AliTPCtrackerMI::PrepareForBackProlongation(TObjArray *const arr,Float_t fac) const
6383 {
6384   //
6385   //
6386   // if we use TPC track itself we have to "update" covariance
6387   //
6388   Int_t nseed= arr->GetEntriesFast();
6389   for (Int_t i=0;i<nseed;i++){
6390     AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
6391     if (pt) {
6392       pt->Modify(fac);
6393       //
6394       //rotate to current local system at first accepted  point    
6395       Int_t index  = pt->GetClusterIndex2(pt->GetFirstPoint()); 
6396       Int_t sec    = (index&0xff000000)>>24;
6397       sec = sec%18;
6398       Float_t angle1 = fInnerSec->GetAlpha()*sec+fInnerSec->GetAlphaShift();
6399       if (angle1>TMath::Pi()) 
6400         angle1-=2.*TMath::Pi();
6401       Float_t angle2 = pt->GetAlpha();
6402       
6403       if (TMath::Abs(angle1-angle2)>0.001){
6404         pt->Rotate(angle1-angle2);
6405         //angle2 = pt->GetAlpha();
6406         //pt->fRelativeSector = pt->GetAlpha()/fInnerSec->GetAlpha();
6407         //if (pt->GetAlpha()<0) 
6408         //  pt->fRelativeSector+=18;
6409         //sec = pt->fRelativeSector;
6410       }
6411         
6412     }
6413     
6414   }
6415
6416
6417 }
6418 void AliTPCtrackerMI::PrepareForProlongation(TObjArray *const arr, Float_t fac) const
6419 {
6420   //
6421   //
6422   // if we use TPC track itself we have to "update" covariance
6423   //
6424   Int_t nseed= arr->GetEntriesFast();
6425   for (Int_t i=0;i<nseed;i++){
6426     AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
6427     if (pt) {
6428       pt->Modify(fac);
6429       pt->SetFirstPoint(pt->GetLastPoint()); 
6430     }
6431     
6432   }
6433
6434
6435 }
6436
6437 Int_t AliTPCtrackerMI::PropagateBack(TObjArray *const arr)
6438 {
6439   //
6440   // make back propagation
6441   //
6442   Int_t nseed= arr->GetEntriesFast();
6443   for (Int_t i=0;i<nseed;i++){
6444     AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
6445     if (pt&& pt->GetKinkIndex(0)<=0) { 
6446       //AliTPCseed *pt2 = new AliTPCseed(*pt);
6447       fSectors = fInnerSec;
6448       //FollowBackProlongation(*pt,fInnerSec->GetNRows()-1);
6449       //fSectors = fOuterSec;
6450       FollowBackProlongation(*pt,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1);     
6451       //if (pt->GetNumberOfClusters()<(pt->fEsd->GetTPCclusters(0)) ){
6452       //        Error("PropagateBack","Not prolonged track %d",pt->GetLabel());
6453       //        FollowBackProlongation(*pt2,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1);
6454       //}
6455     }
6456     if (pt&& pt->GetKinkIndex(0)>0) {
6457       AliESDkink * kink = fEvent->GetKink(pt->GetKinkIndex(0)-1);
6458       pt->SetFirstPoint(kink->GetTPCRow0());
6459       fSectors = fInnerSec;
6460       FollowBackProlongation(*pt,fInnerSec->GetNRows()+fOuterSec->GetNRows()-1);  
6461     }
6462     CookLabel(pt,0.3);
6463   }
6464   return 0;
6465 }
6466
6467
6468 Int_t AliTPCtrackerMI::PropagateForward2(TObjArray *const arr)
6469 {
6470   //
6471   // make forward propagation
6472   //
6473   Int_t nseed= arr->GetEntriesFast();
6474   //
6475   for (Int_t i=0;i<nseed;i++){
6476     AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
6477     if (pt) { 
6478       FollowProlongation(*pt,0);
6479       CookLabel(pt,0.3);
6480     }
6481     
6482   }
6483   return 0;
6484 }
6485
6486
6487 Int_t AliTPCtrackerMI::PropagateForward()
6488 {
6489   //
6490   // propagate track forward
6491   //UnsignClusters();
6492   Int_t nseed = fSeeds->GetEntriesFast();
6493   for (Int_t i=0;i<nseed;i++){
6494     AliTPCseed *pt = (AliTPCseed*)fSeeds->UncheckedAt(i);
6495     if (pt){
6496       AliTPCseed &t = *pt;
6497       Double_t alpha=t.GetAlpha() - fSectors->GetAlphaShift();
6498       if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();  
6499       if (alpha < 0.            ) alpha += 2.*TMath::Pi();  
6500       t.SetRelativeSector(Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN);
6501     }
6502   }
6503   
6504   fSectors = fOuterSec;
6505   ParallelTracking(fSeeds,fOuterSec->GetNRows()+fInnerSec->GetNRows()-1,fInnerSec->GetNRows());
6506   fSectors = fInnerSec;
6507   ParallelTracking(fSeeds,fInnerSec->GetNRows()-1,0);
6508   return 1;
6509 }
6510
6511
6512
6513
6514
6515
6516 Int_t AliTPCtrackerMI::PropagateBack(AliTPCseed *const pt, Int_t row0, Int_t row1)
6517 {
6518   //
6519   // make back propagation, in between row0 and row1
6520   //
6521   
6522   if (pt) { 
6523     fSectors = fInnerSec;
6524     Int_t  r1;
6525     //
6526     if (row1<fSectors->GetNRows()) 
6527       r1 = row1;
6528     else 
6529       r1 = fSectors->GetNRows()-1;
6530
6531     if (row0<fSectors->GetNRows()&& r1>0 )
6532       FollowBackProlongation(*pt,r1);
6533     if (row1<=fSectors->GetNRows())
6534       return 0;
6535     //
6536     r1 = row1 - fSectors->GetNRows();
6537     if (r1<=0) return 0;
6538     if (r1>=fOuterSec->GetNRows()) return 0;
6539     fSectors = fOuterSec;
6540     return FollowBackProlongation(*pt,r1);
6541   }        
6542   return 0;
6543 }
6544
6545
6546
6547
6548 void  AliTPCtrackerMI::GetShape(AliTPCseed * seed, Int_t row)
6549 {
6550   //
6551   // 
6552   AliTPCClusterParam * clparam = AliTPCcalibDB::Instance()->GetClusterParam();
6553   Float_t zdrift = TMath::Abs((fkParam->GetZLength(0)-TMath::Abs(seed->GetZ())));
6554   Int_t type = (seed->GetSector() < fkParam->GetNSector()/2) ? 0: (row>126) ? 1:2;
6555   Double_t angulary  = seed->GetSnp();
6556
6557   if (TMath::Abs(angulary)>AliTPCReconstructor::GetMaxSnpTracker()) {
6558     angulary = TMath::Sign(AliTPCReconstructor::GetMaxSnpTracker(),angulary);
6559   }
6560
6561   angulary = angulary*angulary/((1.-angulary)*(1.+angulary));
6562   Double_t angularz  = seed->GetTgl()*seed->GetTgl()*(1.+angulary);
6563   
6564   Double_t sigmay =  clparam->GetRMS0(0,type,zdrift,TMath::Sqrt(TMath::Abs(angulary)));
6565   Double_t sigmaz =  clparam->GetRMS0(1,type,zdrift,TMath::Sqrt(TMath::Abs(angularz)));
6566   seed->SetCurrentSigmaY2(sigmay*sigmay);
6567   seed->SetCurrentSigmaZ2(sigmaz*sigmaz);
6568   // Float_t sd2 = TMath::Abs((fkParam->GetZLength(0)-TMath::Abs(seed->GetZ())))*fkParam->GetDiffL()*fkParam->GetDiffL();
6569 //   //  Float_t padlength =  fkParam->GetPadPitchLength(seed->fSector);
6570 //   Float_t padlength =  GetPadPitchLength(row);
6571 //   //
6572 //   Float_t sresy = (seed->GetSector() < fkParam->GetNSector()/2) ? 0.2 :0.3;
6573 //   seed->SetCurrentSigmaY2(sd2+padlength*padlength*angulary/12.+sresy*sresy);  
6574 //   //
6575 //   Float_t sresz = fkParam->GetZSigma();
6576 //   seed->SetCurrentSigmaZ2(sd2+padlength*padlength*angularz*angularz*(1+angulary)/12.+sresz*sresz);
6577   /*
6578   Float_t wy = GetSigmaY(seed);
6579   Float_t wz = GetSigmaZ(seed);
6580   wy*=wy;
6581   wz*=wz;
6582   if (TMath::Abs(wy/seed->fCurrentSigmaY2-1)>0.0001 || TMath::Abs(wz/seed->fCurrentSigmaZ2-1)>0.0001 ){
6583     printf("problem\n");
6584   }
6585   */
6586 }
6587
6588
6589
6590 //__________________________________________________________________________
6591 void AliTPCtrackerMI::CookLabel(AliKalmanTrack *tk, Float_t wrong) const {
6592   //--------------------------------------------------------------------
6593   //This function "cooks" a track label. If label<0, this track is fake.
6594   //--------------------------------------------------------------------
6595   AliTPCseed * t = dynamic_cast<AliTPCseed*>(tk);
6596   if(!t){
6597     printf("%s:%d wrong type \n",(char*)__FILE__,__LINE__);
6598     return;
6599   }
6600
6601   Int_t noc=t->GetNumberOfClusters();
6602   if (noc<10){
6603     //printf("\nnot founded prolongation\n\n\n");
6604     //t->Dump();
6605     return ;
6606   }
6607   Int_t lb[160];
6608   Int_t mx[160];
6609   AliTPCclusterMI *clusters[160];
6610   //
6611   for (Int_t i=0;i<160;i++) {
6612     clusters[i]=0;
6613     lb[i]=mx[i]=0;
6614   }
6615
6616   Int_t i;
6617   Int_t current=0;
6618   for (i=0; i<160 && current<noc; i++) {
6619      
6620      Int_t index=t->GetClusterIndex2(i);
6621      if (index<=0) continue; 
6622      if (index&0x8000) continue;
6623      //     
6624      //clusters[current]=GetClusterMI(index);
6625      if (t->GetClusterPointer(i)){
6626        clusters[current]=t->GetClusterPointer(i);     
6627        current++;
6628      }
6629   }
6630   noc = current;
6631
6632   Int_t lab=123456789;
6633   for (i=0; i<noc; i++) {
6634     AliTPCclusterMI *c=clusters[i];
6635     if (!c) continue;
6636     lab=TMath::Abs(c->GetLabel(0));
6637     Int_t j;
6638     for (j=0; j<noc; j++) if (lb[j]==lab || mx[j]==0) break;
6639     lb[j]=lab;
6640     (mx[j])++;
6641   }
6642
6643   Int_t max=0;
6644   for (i=0; i<noc; i++) if (mx[i]>max) {max=mx[i]; lab=lb[i];}
6645     
6646   for (i=0; i<noc; i++) {
6647     AliTPCclusterMI *c=clusters[i]; 
6648     if (!c) continue;
6649     if (TMath::Abs(c->GetLabel(1)) == lab ||
6650         TMath::Abs(c->GetLabel(2)) == lab ) max++;
6651   }
6652   if (noc<=0) { lab=-1; return;}
6653   if ((1.- Float_t(max)/(noc)) > wrong) lab=-lab;
6654
6655   else {
6656      Int_t tail=Int_t(0.10*noc);
6657      max=0;
6658      Int_t ind=0;
6659      for (i=1; i<160&&ind<tail; i++) {
6660        //       AliTPCclusterMI *c=clusters[noc-i];
6661        AliTPCclusterMI *c=clusters[i];
6662        if (!c) continue;
6663        if (lab == TMath::Abs(c->GetLabel(0)) ||
6664            lab == TMath::Abs(c->GetLabel(1)) ||
6665            lab == TMath::Abs(c->GetLabel(2))) max++;
6666        ind++;
6667      }
6668      if (max < Int_t(0.5*tail)) lab=-lab;
6669   }
6670
6671   t->SetLabel(lab);
6672
6673   //  delete[] lb;
6674   //delete[] mx;
6675   //delete[] clusters;
6676 }
6677
6678
6679 //__________________________________________________________________________
6680 Int_t AliTPCtrackerMI::CookLabel(AliTPCseed *const t, Float_t wrong,Int_t first, Int_t last) const {
6681   //--------------------------------------------------------------------
6682   //This function "cooks" a track label. If label<0, this track is fake.
6683   //--------------------------------------------------------------------
6684   Int_t noc=t->GetNumberOfClusters();
6685   if (noc<10){
6686     //printf("\nnot founded prolongation\n\n\n");
6687     //t->Dump();
6688     return -1;
6689   }
6690   Int_t lb[160];
6691   Int_t mx[160];
6692   AliTPCclusterMI *clusters[160];
6693   //
6694   for (Int_t i=0;i<160;i++) {
6695     clusters[i]=0;
6696     lb[i]=mx[i]=0;
6697   }
6698
6699   Int_t i;
6700   Int_t current=0;
6701   for (i=0; i<160 && current<noc; i++) {
6702     if (i<first) continue;
6703     if (i>last)  continue;
6704      Int_t index=t->GetClusterIndex2(i);
6705      if (index<=0) continue; 
6706      if (index&0x8000) continue;
6707      //     
6708      //clusters[current]=GetClusterMI(index);
6709      if (t->GetClusterPointer(i)){
6710        clusters[current]=t->GetClusterPointer(i);     
6711        current++;
6712      }
6713   }
6714   noc = current;
6715   if (noc<5) return -1;
6716   Int_t lab=123456789;
6717   for (i=0; i<noc; i++) {
6718     AliTPCclusterMI *c=clusters[i];
6719     if (!c) continue;
6720     lab=TMath::Abs(c->GetLabel(0));
6721     Int_t j;
6722     for (j=0; j<noc; j++) if (lb[j]==lab || mx[j]==0) break;
6723     lb[j]=lab;
6724     (mx[j])++;
6725   }
6726
6727   Int_t max=0;
6728   for (i=0; i<noc; i++) if (mx[i]>max) {max=mx[i]; lab=lb[i];}
6729     
6730   for (i=0; i<noc; i++) {
6731     AliTPCclusterMI *c=clusters[i]; 
6732     if (!c) continue;
6733     if (TMath::Abs(c->GetLabel(1)) == lab ||
6734         TMath::Abs(c->GetLabel(2)) == lab ) max++;
6735   }
6736   if (noc<=0) { lab=-1; return -1;}
6737   if ((1.- Float_t(max)/(noc)) > wrong) lab=-lab;
6738
6739   else {
6740      Int_t tail=Int_t(0.10*noc);
6741      max=0;
6742      Int_t ind=0;
6743      for (i=1; i<160&&ind<tail; i++) {
6744        //       AliTPCclusterMI *c=clusters[noc-i];
6745        AliTPCclusterMI *c=clusters[i];
6746        if (!c) continue;
6747        if (lab == TMath::Abs(c->GetLabel(0)) ||
6748            lab == TMath::Abs(c->GetLabel(1)) ||
6749            lab == TMath::Abs(c->GetLabel(2))) max++;
6750        ind++;
6751      }
6752      if (max < Int_t(0.5*tail)) lab=-lab;
6753   }
6754
6755   //  t->SetLabel(lab);
6756   return lab;
6757   //  delete[] lb;
6758   //delete[] mx;
6759   //delete[] clusters;
6760 }
6761
6762
6763 Int_t  AliTPCtrackerMI::GetRowNumber(Double_t x[3]) const 
6764 {
6765   //return pad row number for given x vector
6766   Float_t phi = TMath::ATan2(x[1],x[0]);
6767   if(phi<0) phi=2.*TMath::Pi()+phi;
6768   //  Get the local angle in the sector philoc
6769   const Float_t kRaddeg = 180/3.14159265358979312;
6770   Float_t phiangle   = (Int_t (phi*kRaddeg/20.) + 0.5)*20./kRaddeg;
6771   Double_t localx    = x[0]*TMath::Cos(phiangle)-x[1]*TMath::Sin(phiangle);
6772   return GetRowNumber(localx);
6773 }
6774
6775
6776
6777 void AliTPCtrackerMI::MakeBitmaps(AliTPCseed *t)
6778 {
6779   //-----------------------------------------------------------------------
6780   // Fill the cluster and sharing bitmaps of the track
6781   //-----------------------------------------------------------------------
6782
6783   Int_t firstpoint = 0;
6784   Int_t lastpoint = 159;
6785   AliTPCTrackerPoint *point;
6786   AliTPCclusterMI    *cluster;
6787   
6788   for (int iter=firstpoint; iter<lastpoint; iter++) {
6789     // Change to cluster pointers to see if we have a cluster at given padrow
6790     cluster = t->GetClusterPointer(iter);
6791     if (cluster) {
6792       t->SetClusterMapBit(iter, kTRUE);
6793       point = t->GetTrackPoint(iter);
6794       if (point->IsShared())
6795         t->SetSharedMapBit(iter,kTRUE);
6796       else
6797         t->SetSharedMapBit(iter, kFALSE);
6798     }
6799     else {
6800       t->SetClusterMapBit(iter, kFALSE);
6801       t->SetSharedMapBit(iter, kFALSE);
6802     }
6803   }
6804 }
6805
6806 Bool_t AliTPCtrackerMI::IsFindable(AliTPCseed & track){
6807   //
6808   // return flag if there is findable cluster at given position
6809   //
6810   Float_t kDeltaZ=10;
6811   Float_t z = track.GetZ();
6812   
6813   if (TMath::Abs(z)<(AliTPCReconstructor::GetCtgRange()*track.GetX()+kDeltaZ) && 
6814       TMath::Abs(z)<fkParam->GetZLength(0) && 
6815       (TMath::Abs(track.GetSnp())<AliTPCReconstructor::GetMaxSnpTracker()))
6816     return kTRUE;
6817   return kFALSE;      
6818 }
6819
6820
6821 void AliTPCtrackerMI::AddCovariance(AliTPCseed * seed){
6822   //
6823   // Adding systematic error
6824   // !!!! the systematic error for element 4 is in 1/cm not in pt 
6825
6826   const Double_t *param = AliTPCReconstructor::GetRecoParam()->GetSystematicError();
6827   Double_t *covarIn= (Double_t*)seed->GetCovariance();
6828   Double_t covar[15];
6829   for (Int_t i=0;i<15;i++) covar[i]=0;
6830   // 0
6831   // 1    2
6832   // 3    4    5
6833   // 6    7    8    9 
6834   // 10   11   12   13   14
6835   covar[0] = param[0]*param[0];
6836   covar[2] = param[1]*param[1];
6837   covar[5] = param[2]*param[2];
6838   covar[9] = param[3]*param[3];
6839   Double_t facC =  AliTracker::GetBz()*kB2C;
6840   covar[14]= param[4]*param[4]*facC*facC;
6841   //
6842   covar[1]=TMath::Sqrt((covar[0]*covar[2]))*covarIn[1]/TMath::Sqrt((covarIn[0]*covarIn[2]));
6843   //
6844   covar[3]=TMath::Sqrt((covar[0]*covar[5]))*covarIn[3]/TMath::Sqrt((covarIn[0]*covarIn[5]));
6845   covar[4]=TMath::Sqrt((covar[2]*covar[5]))*covarIn[4]/TMath::Sqrt((covarIn[2]*covarIn[5]));
6846   //
6847   covar[6]=TMath::Sqrt((covar[0]*covar[9]))*covarIn[6]/TMath::Sqrt((covarIn[0]*covarIn[9]));
6848   covar[7]=TMath::Sqrt((covar[2]*covar[9]))*covarIn[7]/TMath::Sqrt((covarIn[2]*covarIn[9]));
6849   covar[8]=TMath::Sqrt((covar[5]*covar[9]))*covarIn[8]/TMath::Sqrt((covarIn[5]*covarIn[9]));
6850   //
6851   covar[10]=TMath::Sqrt((covar[0]*covar[14]))*covarIn[10]/TMath::Sqrt((covarIn[0]*covarIn[14]));
6852   covar[11]=TMath::Sqrt((covar[2]*covar[14]))*covarIn[11]/TMath::Sqrt((covarIn[2]*covarIn[14]));
6853   covar[12]=TMath::Sqrt((covar[5]*covar[14]))*covarIn[12]/TMath::Sqrt((covarIn[5]*covarIn[14]));
6854   covar[13]=TMath::Sqrt((covar[9]*covar[14]))*covarIn[13]/TMath::Sqrt((covarIn[9]*covarIn[14]));
6855   //
6856   seed->AddCovariance(covar);
6857 }