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