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