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