]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TPC/AliTPCtrackerMI.cxx
New version of a macro
[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 $Log$
18 Revision 1.14  2003/09/29 11:39:43  kowal2
19 bug fix
20
21 Revision 1.13  2003/09/29 11:28:19  kowal2
22 completly rewritten
23
24 Revision 1.9.4.3  2003/06/23 14:47:10  hristov
25 Minor fix
26
27 Revision 1.9.4.2  2003/06/23 10:06:13  hristov
28 Updated information about the overlapping clusters (M.Ivanov)
29
30 Revision 1.9.4.1  2003/06/19 06:59:58  hristov
31 Updated version of parallel tracking (M.Ivanov)
32
33 Revision 1.9  2003/03/19 17:14:11  hristov
34 Load/UnloadClusters added to the base class and the derived classes changed correspondingly. Possibility to give 2 input files for ITS and TPC tracks in PropagateBack. TRD tracker uses fEventN from the base class (T.Kuhr)
35
36 Revision 1.8  2003/03/05 11:16:15  kowal2
37 Logs added
38
39 */
40
41
42
43
44
45
46
47 /*
48   AliTPC parallel tracker - 
49   How to use?  - 
50   run AliTPCFindClusters.C macro - clusters neccessary for tracker are founded
51   run AliTPCFindTracksMI.C macro - to find tracks
52   tracks are written to AliTPCtracks.root file
53   for comparison also seeds are written to the same file - to special branch
54 */
55
56 //-------------------------------------------------------
57 //          Implementation of the TPC tracker
58 //
59 //   Origin: Marian Ivanov   Marian.Ivanov@cern.ch
60 // 
61 //-------------------------------------------------------
62 #include <TObjArray.h>
63 #include <TFile.h>
64 #include <TTree.h>
65 #include "Riostream.h"
66
67 #include "AliTPCtrackerMI.h"
68 #include "AliTPCclusterMI.h"
69 #include "AliTPCParam.h"
70 #include "AliTPCClustersRow.h"
71 #include "AliComplexCluster.h"
72 #include "AliTPCpolyTrack.h"
73 #include "TStopwatch.h"
74 #include "AliESD.h"
75 #include "AliHelix.h"
76 #include "TGraph.h"
77 //
78 #include "AliRunLoader.h"
79
80
81
82 ClassImp(AliTPCseed)
83 ClassImp(AliTPCtrackerMI)
84
85
86 class TPCFastMath {
87 public:
88   TPCFastMath();  
89   static Double_t FastAsin(Double_t x);   
90  private: 
91   static Double_t fgFastAsin[20000];
92 };
93
94 Double_t TPCFastMath::fgFastAsin[20000];
95
96 TPCFastMath::TPCFastMath(){
97   for (Int_t i=0;i<10000;i++){
98     fgFastAsin[2*i] = TMath::ASin(i/10000.);
99     fgFastAsin[2*i+1] = (TMath::ASin((i+1)/10000.)-fgFastAsin[2*i]);
100   }
101 }
102
103 Double_t TPCFastMath::FastAsin(Double_t x){
104   if (x>0){
105     Int_t index = int(x*10000);
106     return fgFastAsin[2*index]+(x*10000.-index)*fgFastAsin[2*index+1];
107   }
108   x*=-1;
109   Int_t index = int(x*10000);
110   return -(fgFastAsin[2*index]+(x*10000.-index)*fgFastAsin[2*index+1]);
111 }
112
113 TPCFastMath gTPCMath;
114
115
116
117 Int_t AliTPCtrackerMI::UpdateTrack(AliTPCseed * track, Int_t accept){
118
119   AliTPCclusterMI* c =track->fCurrentCluster;
120   if (accept>0) track->fCurrentClusterIndex1 |=0x8000;  //sign not accepted clusters
121
122   UInt_t i = track->fCurrentClusterIndex1;
123
124   Int_t sec=(i&0xff000000)>>24; 
125   //Int_t row = (i&0x00ff0000)>>16; 
126   track->fRow=(i&0x00ff0000)>>16;
127   track->fSector = sec;
128   //  Int_t index = i&0xFFFF;
129   if (sec>=fParam->GetNInnerSector()) track->fRow += fParam->GetNRowLow(); 
130   track->SetClusterIndex2(track->fRow, i);
131   
132   //track->fFirstPoint = row;
133   //if ( track->fLastPoint<row) track->fLastPoint =row;
134   //  if (track->fRow<0 || track->fRow>160) {
135   //  printf("problem\n");
136   //}
137   if (track->fFirstPoint>track->fRow) 
138     track->fFirstPoint = track->fRow;
139   if (track->fLastPoint<track->fRow) 
140     track->fLastPoint  = track->fRow;
141   
142
143   track->fClusterPointer[track->fRow] = c;  
144   //
145
146   Float_t angle2 = track->GetSnp()*track->GetSnp();
147   angle2 = TMath::Sqrt(angle2/(1-angle2)); 
148   //
149   //SET NEW Track Point
150   //
151   //  if (debug)
152   {
153     AliTPCTrackerPoint   &point =*(track->GetTrackPoint(track->fRow));
154     //
155     point.SetSigmaY(c->GetSigmaY2()/track->fCurrentSigmaY2);
156     point.SetSigmaZ(c->GetSigmaZ2()/track->fCurrentSigmaZ2);
157     point.SetErrY(sqrt(track->fErrorY2));
158     point.SetErrZ(sqrt(track->fErrorZ2));
159     //
160     point.SetX(track->GetX());
161     point.SetY(track->GetY());
162     point.SetZ(track->GetZ());
163     point.SetAngleY(angle2);
164     point.SetAngleZ(track->GetTgl());
165     if (point.fIsShared){
166       track->fErrorY2 *= 4;
167       track->fErrorZ2 *= 4;
168     }
169   }  
170
171   Double_t chi2 = track->GetPredictedChi2(track->fCurrentCluster);
172   //
173   track->fErrorY2 *= 1.3;
174   track->fErrorY2 += 0.01;    
175   track->fErrorZ2 *= 1.3;   
176   track->fErrorZ2 += 0.005;      
177     //}
178   if (accept>0) return 0;
179   if (track->GetNumberOfClusters()%20==0){
180     //    if (track->fHelixIn){
181     //  TClonesArray & larr = *(track->fHelixIn);    
182     //  Int_t ihelix = larr.GetEntriesFast();
183     //  new(larr[ihelix]) AliHelix(*track) ;    
184     //}
185   }
186   track->fNoCluster =0;
187   return track->Update(c,chi2,i);
188 }
189
190
191
192 Int_t AliTPCtrackerMI::AcceptCluster(AliTPCseed * seed, AliTPCclusterMI * cluster, Float_t factor, 
193                                       Float_t cory, Float_t corz)
194 {
195   //
196   // decide according desired precision to accept given 
197   // cluster for tracking
198   Double_t sy2=ErrY2(seed,cluster)*cory;
199   Double_t sz2=ErrZ2(seed,cluster)*corz;
200   //sy2=ErrY2(seed,cluster)*cory;
201   //sz2=ErrZ2(seed,cluster)*cory;
202   
203   Double_t sdistancey2 = sy2+seed->GetSigmaY2();
204   Double_t sdistancez2 = sz2+seed->GetSigmaZ2();
205   
206   Double_t rdistancey2 = (seed->fCurrentCluster->GetY()-seed->GetY())*
207     (seed->fCurrentCluster->GetY()-seed->GetY())/sdistancey2;
208   Double_t rdistancez2 = (seed->fCurrentCluster->GetZ()-seed->GetZ())*
209     (seed->fCurrentCluster->GetZ()-seed->GetZ())/sdistancez2;
210   
211   Double_t rdistance2  = rdistancey2+rdistancez2;
212   //Int_t  accept =0;
213   
214   if (rdistance2>16) return 3;
215   
216   
217   if ((rdistancey2>9.*factor || rdistancez2>9.*factor) && cluster->GetType()==0)  
218     return 2;  //suspisiouce - will be changed
219   
220   if ((rdistancey2>6.25*factor || rdistancez2>6.25*factor) && cluster->GetType()>0)  
221     // strict cut on overlaped cluster
222     return  2;  //suspisiouce - will be changed
223   
224   if ( (rdistancey2>1.*factor || rdistancez2>6.25*factor ) 
225        && cluster->GetType()<0){
226     seed->fNFoundable--;
227     return 2;    
228   }
229   return 0;
230 }
231
232
233
234
235 //_____________________________________________________________________________
236 AliTPCtrackerMI::AliTPCtrackerMI(const AliTPCParam *par): 
237 AliTracker(), fkNIS(par->GetNInnerSector()/2), fkNOS(par->GetNOuterSector()/2)
238 {
239   //---------------------------------------------------------------------
240   // The main TPC tracker constructor
241   //---------------------------------------------------------------------
242   fInnerSec=new AliTPCSector[fkNIS];         
243   fOuterSec=new AliTPCSector[fkNOS];
244  
245   Int_t i;
246   for (i=0; i<fkNIS; i++) fInnerSec[i].Setup(par,0);
247   for (i=0; i<fkNOS; i++) fOuterSec[i].Setup(par,1);
248
249   fN=0;  fSectors=0;
250
251   fSeeds=0;
252   fNtracks = 0;
253   fParam = par;  
254   Int_t nrowlow = par->GetNRowLow();
255   Int_t nrowup = par->GetNRowUp();
256
257   
258   for (Int_t i=0;i<nrowlow;i++){
259     fXRow[i]     = par->GetPadRowRadiiLow(i);
260     fPadLength[i]= par->GetPadPitchLength(0,i);
261     fYMax[i]     = fXRow[i]*TMath::Tan(0.5*par->GetInnerAngle());
262   }
263
264   
265   for (Int_t i=0;i<nrowup;i++){
266     fXRow[i+nrowlow]      = par->GetPadRowRadiiUp(i);
267     fPadLength[i+nrowlow] = par->GetPadPitchLength(60,i);
268     fYMax[i+nrowlow]      = fXRow[i+nrowlow]*TMath::Tan(0.5*par->GetOuterAngle());
269   }
270   fSeeds=0;
271   //
272   fInput    = 0;
273   fOutput   = 0;
274   fSeedTree = 0;
275   fTreeDebug =0;
276   fNewIO     =0;
277   fDebug     =0;
278   fEvent     =0;
279 }
280
281 //_____________________________________________________________________________
282 AliTPCtrackerMI::~AliTPCtrackerMI() {
283   //------------------------------------------------------------------
284   // TPC tracker destructor
285   //------------------------------------------------------------------
286   delete[] fInnerSec;
287   delete[] fOuterSec;
288   if (fSeeds) {
289     fSeeds->Delete(); 
290     delete fSeeds;
291   }
292 }
293
294 void AliTPCtrackerMI::SetIO()
295 {
296   //
297   fNewIO   =  kTRUE;
298   fInput   =  AliRunLoader::GetTreeR("TPC", kFALSE,AliConfig::fgkDefaultEventFolderName);
299   fOutput  =  AliRunLoader::GetTreeT("TPC", kTRUE,AliConfig::fgkDefaultEventFolderName);
300   AliTPCtrack *iotrack= new AliTPCtrack;
301   //    iotrack->fHelixIn   = new TClonesArray("AliHelix");
302   //iotrack->fHelixOut  = new TClonesArray("AliHelix");    
303   fOutput->Branch("tracks","AliTPCtrack",&iotrack,32000,100);
304   delete iotrack;
305 }
306
307 void AliTPCtrackerMI::SetIO(TTree * input, TTree * output, AliESD * event)
308 {
309
310   // set input
311   fNewIO = kFALSE;
312   fInput    = 0;
313   fOutput   = 0;
314   fSeedTree = 0;
315   fTreeDebug =0;
316   fInput = input;
317   if (input==0){
318     return;
319   }  
320   //set output
321   fOutput = output;
322   if (output){
323     AliTPCtrack *iotrack= new AliTPCtrack;
324     //    iotrack->fHelixIn   = new TClonesArray("AliHelix");
325     //iotrack->fHelixOut  = new TClonesArray("AliHelix");    
326     fOutput->Branch("tracks","AliTPCtrack",&iotrack,32000,100);
327     delete iotrack;
328   }
329   if (output && (fDebug&2)){
330     //write the full seed information if specified in debug mode
331     //
332     fSeedTree =  new TTree("Seeds","Seeds");
333     AliTPCseed * vseed = new AliTPCseed;
334     //
335     TClonesArray * arrtr = new TClonesArray("AliTPCTrackPoint",160);
336     arrtr->ExpandCreateFast(160);
337     TClonesArray * arre = new TClonesArray("AliTPCExactPoint",160);
338     //
339     vseed->fPoints = arrtr;
340     vseed->fEPoints = arre;
341     //    vseed->fClusterPoints = arrcl;
342     fSeedTree->Branch("seeds","AliTPCseed",&vseed,32000,99);
343     delete arrtr;
344     delete arre;    
345     fTreeDebug = new TTree("trackDebug","trackDebug");
346     TClonesArray * arrd = new TClonesArray("AliTPCTrackPoint2",0);
347     fTreeDebug->Branch("debug",&arrd,32000,99);
348   }
349
350
351   //set ESD event  
352   fEvent  = event;  
353 }
354
355 void AliTPCtrackerMI::WriteTracks()
356 {
357   //
358   // write tracks to the given output tree -
359   // output specified with SetIO routine
360   if (!fSeeds)  return;
361   if (fEvent){
362     // write tracks to the event
363     // store index of the track
364     Int_t nseed=fSeeds->GetEntriesFast();
365     for (Int_t i=0; i<nseed; i++) {
366       AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i);    
367       if (!pt) continue; 
368       AliESDtrack iotrack;
369       iotrack.UpdateTrackParams(pt,AliESDtrack::kTPCin);        
370       //iotrack.SetTPCindex(i);
371       fEvent->AddTrack(&iotrack);         
372     }
373   }
374
375   
376   if (fOutput){
377     AliTPCtrack *iotrack= 0;
378     Int_t nseed=fSeeds->GetEntriesFast();
379     for (Int_t i=0; i<nseed; i++) {
380       iotrack= (AliTPCtrack*)fSeeds->UncheckedAt(i);
381       if (iotrack) break;      
382     }
383     
384     //TBranch * br = fOutput->Branch("tracks","AliTPCtrack",&iotrack,32000,100);
385     TBranch * br = fOutput->GetBranch("tracks");
386     br->SetAddress(&iotrack);
387     //
388     for (Int_t i=0; i<nseed; i++) {
389       AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i);    
390       if (!pt) continue;    
391       iotrack = pt;
392       pt->fLab2 =i; 
393       //      br->SetAddress(&iotrack);
394       fOutput->Fill();
395       iotrack =0;
396     }
397   }
398     // delete iotrack;
399     //
400   if (fSeedTree){
401     //write the full seed information if specified in debug mode
402       
403     AliTPCseed * vseed = new AliTPCseed;
404     //
405     TClonesArray * arrtr = new TClonesArray("AliTPCTrackPoint",160);
406     arrtr->ExpandCreateFast(160);
407     //TClonesArray * arrcl = new TClonesArray("AliTPCclusterMI",160);
408     //arrcl->ExpandCreateFast(160);
409     TClonesArray * arre = new TClonesArray("AliTPCExactPoint",160);
410     //
411     vseed->fPoints = arrtr;
412     vseed->fEPoints = arre;
413     //    vseed->fClusterPoints = arrcl;
414     //TBranch * brseed = seedtree->Branch("seeds","AliTPCseed",&vseed,32000,99);
415     TBranch * brseed = fSeedTree->GetBranch("seeds");
416     
417     Int_t nseed=fSeeds->GetEntriesFast();
418     
419     for (Int_t i=0; i<nseed; i++) {
420       AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i);    
421       if (!pt) continue;     
422       pt->fPoints = arrtr;
423       //      pt->fClusterPoints = arrcl;
424       pt->fEPoints       = arre;
425       pt->RebuildSeed();
426       vseed = pt;
427       brseed->SetAddress(&vseed);
428       fSeedTree->Fill();
429       pt->fPoints  = 0;
430       pt->fEPoints = 0;
431       //      pt->fClusterPoints = 0;
432     }
433     fSeedTree->Write();
434     if (fTreeDebug) fTreeDebug->Write();
435   }
436
437 }
438   
439
440
441
442 Double_t AliTPCtrackerMI::ErrY2(AliTPCseed* seed, AliTPCclusterMI * cl){
443   //
444   //
445   //seed->SetErrorY2(0.1);
446   //return 0.1;
447   //calculate look-up table at the beginning
448   static Bool_t  ginit = kFALSE;
449   static Float_t gnoise1,gnoise2,gnoise3;
450   static Float_t ggg1[10000];
451   static Float_t ggg2[10000];
452   static Float_t ggg3[10000];
453   static Float_t glandau1[10000];
454   static Float_t glandau2[10000];
455   static Float_t glandau3[10000];
456   //
457   static Float_t gcor01[500];
458   static Float_t gcor02[500];
459   static Float_t gcorp[500];
460   //
461
462   //
463   if (ginit==kFALSE){
464     for (Int_t i=1;i<500;i++){
465       Float_t rsigma = float(i)/100.;
466       gcor02[i] = TMath::Max(0.78 +TMath::Exp(7.4*(rsigma-1.2)),0.6);
467       gcor01[i] = TMath::Max(0.72 +TMath::Exp(3.36*(rsigma-1.2)),0.6);
468       gcorp[i]  = TMath::Max(TMath::Power((rsigma+0.5),1.5),1.2);
469     }
470
471     //
472     for (Int_t i=3;i<10000;i++){
473       //
474       //
475       // inner sector
476       Float_t amp = float(i);
477       Float_t padlength =0.75;
478       gnoise1 = 0.0004/padlength;
479       Float_t nel     = 0.268*amp;
480       Float_t nprim   = 0.155*amp;
481       ggg1[i]          = fParam->GetDiffT()*fParam->GetDiffT()*(2+0.001*nel/(padlength*padlength))/nel;
482       glandau1[i]      = (2.+0.12*nprim)*0.5* (2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
483       if (glandau1[i]>1) glandau1[i]=1;
484       glandau1[i]*=padlength*padlength/12.;      
485       //
486       // outer short
487       padlength =1.;
488       gnoise2   = 0.0004/padlength;
489       nel       = 0.3*amp;
490       nprim     = 0.133*amp;
491       ggg2[i]      = fParam->GetDiffT()*fParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
492       glandau2[i]  = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
493       if (glandau2[i]>1) glandau2[i]=1;
494       glandau2[i]*=padlength*padlength/12.;
495       //
496       //
497       // outer long
498       padlength =1.5;
499       gnoise3   = 0.0004/padlength;
500       nel       = 0.3*amp;
501       nprim     = 0.133*amp;
502       ggg3[i]      = fParam->GetDiffT()*fParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
503       glandau3[i]  = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
504       if (glandau3[i]>1) glandau3[i]=1;
505       glandau3[i]*=padlength*padlength/12.;
506       //
507     }
508     ginit = kTRUE;
509   }
510   //
511   //
512   //
513   Int_t amp = int(TMath::Abs(cl->GetQ()));  
514   if (amp>9999) {
515     seed->SetErrorY2(1.);
516     return 1.;
517   }
518   Float_t snoise2;
519   Float_t z = TMath::Abs(fParam->GetZLength()-TMath::Abs(seed->GetZ()));
520   Int_t ctype = cl->GetType();  
521   Float_t padlength= GetPadPitchLength(seed->fRow);
522   Float_t angle2 = seed->GetSnp()*seed->GetSnp();
523   angle2 = angle2/(1-angle2); 
524   //
525   //cluster "quality"
526   Int_t rsigmay = int(100.*cl->GetSigmaY2()/(seed->fCurrentSigmaY2));
527   Float_t res;
528   //
529   if (fSectors==fInnerSec){
530     snoise2 = gnoise1;
531     res     = ggg1[amp]*z+glandau1[amp]*angle2;     
532     if (ctype==0) res *= gcor01[rsigmay];
533     if ((ctype>0)){
534       res+=0.002;
535       res*= gcorp[rsigmay];
536     }
537   }
538   else {
539     if (padlength<1.1){
540       snoise2 = gnoise2;
541       res     = ggg2[amp]*z+glandau2[amp]*angle2; 
542       if (ctype==0) res *= gcor02[rsigmay];      
543       if ((ctype>0)){
544         res+=0.002;
545         res*= gcorp[rsigmay];
546       }
547     }
548     else{
549       snoise2 = gnoise3;      
550       res     = ggg3[amp]*z+glandau3[amp]*angle2; 
551       if (ctype==0) res *= gcor02[rsigmay];
552       if ((ctype>0)){
553         res+=0.002;
554         res*= gcorp[rsigmay];
555       }
556     }
557   }  
558
559   if (ctype<0){
560     res+=0.005;
561     res*=2.4;  // overestimate error 2 times
562   }
563   res+= snoise2;
564  
565   if (res<2*snoise2)
566     res = 2*snoise2;
567   
568   seed->SetErrorY2(res);
569   return res;
570
571
572 }
573
574
575
576 Double_t AliTPCtrackerMI::ErrZ2(AliTPCseed* seed, AliTPCclusterMI * cl){
577   //
578   //
579   //seed->SetErrorY2(0.1);
580   //return 0.1;
581   //calculate look-up table at the beginning
582   static Bool_t  ginit = kFALSE;
583   static Float_t gnoise1,gnoise2,gnoise3;
584   static Float_t ggg1[10000];
585   static Float_t ggg2[10000];
586   static Float_t ggg3[10000];
587   static Float_t glandau1[10000];
588   static Float_t glandau2[10000];
589   static Float_t glandau3[10000];
590   //
591   static Float_t gcor01[1000];
592   static Float_t gcor02[1000];
593   static Float_t gcorp[1000];
594   //
595
596   //
597   if (ginit==kFALSE){
598     for (Int_t i=1;i<1000;i++){
599       Float_t rsigma = float(i)/100.;
600       gcor02[i] = TMath::Max(0.81 +TMath::Exp(6.8*(rsigma-1.2)),0.6);
601       gcor01[i] = TMath::Max(0.72 +TMath::Exp(2.04*(rsigma-1.2)),0.6);
602       gcorp[i]  = TMath::Max(TMath::Power((rsigma+0.5),1.5),1.2);
603     }
604
605     //
606     for (Int_t i=3;i<10000;i++){
607       //
608       //
609       // inner sector
610       Float_t amp = float(i);
611       Float_t padlength =0.75;
612       gnoise1 = 0.0004/padlength;
613       Float_t nel     = 0.268*amp;
614       Float_t nprim   = 0.155*amp;
615       ggg1[i]          = fParam->GetDiffT()*fParam->GetDiffT()*(2+0.001*nel/(padlength*padlength))/nel;
616       glandau1[i]      = (2.+0.12*nprim)*0.5* (2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
617       if (glandau1[i]>1) glandau1[i]=1;
618       glandau1[i]*=padlength*padlength/12.;      
619       //
620       // outer short
621       padlength =1.;
622       gnoise2   = 0.0004/padlength;
623       nel       = 0.3*amp;
624       nprim     = 0.133*amp;
625       ggg2[i]      = fParam->GetDiffT()*fParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
626       glandau2[i]  = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
627       if (glandau2[i]>1) glandau2[i]=1;
628       glandau2[i]*=padlength*padlength/12.;
629       //
630       //
631       // outer long
632       padlength =1.5;
633       gnoise3   = 0.0004/padlength;
634       nel       = 0.3*amp;
635       nprim     = 0.133*amp;
636       ggg3[i]      = fParam->GetDiffT()*fParam->GetDiffT()*(2+0.0008*nel/(padlength*padlength))/nel;
637       glandau3[i]  = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
638       if (glandau3[i]>1) glandau3[i]=1;
639       glandau3[i]*=padlength*padlength/12.;
640       //
641     }
642     ginit = kTRUE;
643   }
644   //
645   //
646   //
647   Int_t amp = int(TMath::Abs(cl->GetQ()));  
648   if (amp>9999) {
649     seed->SetErrorY2(1.);
650     return 1.;
651   }
652   Float_t snoise2;
653   Float_t z = TMath::Abs(fParam->GetZLength()-TMath::Abs(seed->GetZ()));
654   Int_t ctype = cl->GetType();  
655   Float_t padlength= GetPadPitchLength(seed->fRow);
656   //
657   Float_t angle2 = seed->GetSnp()*seed->GetSnp();
658   //  if (angle2<0.6) angle2 = 0.6;
659   angle2 = seed->GetTgl()*seed->GetTgl()*(1+angle2/(1-angle2)); 
660   //
661   //cluster "quality"
662   Int_t rsigmaz = int(100.*cl->GetSigmaZ2()/(seed->fCurrentSigmaZ2));
663   Float_t res;
664   //
665   if (fSectors==fInnerSec){
666     snoise2 = gnoise1;
667     res     = ggg1[amp]*z+glandau1[amp]*angle2;     
668     if (ctype==0) res *= gcor01[rsigmaz];
669     if ((ctype>0)){
670       res+=0.002;
671       res*= gcorp[rsigmaz];
672     }
673   }
674   else {
675     if (padlength<1.1){
676       snoise2 = gnoise2;
677       res     = ggg2[amp]*z+glandau2[amp]*angle2; 
678       if (ctype==0) res *= gcor02[rsigmaz];      
679       if ((ctype>0)){
680         res+=0.002;
681         res*= gcorp[rsigmaz];
682       }
683     }
684     else{
685       snoise2 = gnoise3;      
686       res     = ggg3[amp]*z+glandau3[amp]*angle2; 
687       if (ctype==0) res *= gcor02[rsigmaz];
688       if ((ctype>0)){
689         res+=0.002;
690         res*= gcorp[rsigmaz];
691       }
692     }
693   }  
694
695   if (ctype<0){
696     res+=0.002;
697     res*=1.3;
698   }
699   if ((ctype<0) &&amp<70){
700     res+=0.002;
701     res*=1.3;  
702   }
703   res += snoise2;
704   if (res<2*snoise2)
705      res = 2*snoise2;
706   if (res>3) res =3;
707   seed->SetErrorZ2(res);
708   return res;
709 }
710
711
712
713 /*
714 Double_t AliTPCtrackerMI::ErrZ2(AliTPCseed* seed, AliTPCclusterMI * cl){
715   //
716   //
717   //seed->SetErrorZ2(0.1);
718   //return 0.1;
719
720   Float_t snoise2;
721   Float_t z = TMath::Abs(fParam->GetZLength()-TMath::Abs(seed->GetZ()));
722   //
723   Float_t rsigmaz = cl->GetSigmaZ2()/(seed->fCurrentSigmaZ2);
724   Int_t ctype = cl->GetType();
725   Float_t amp = TMath::Abs(cl->GetQ());
726   
727   Float_t nel;
728   Float_t nprim;
729   //
730   Float_t landau=2 ;    //landau fluctuation part
731   Float_t gg=2;         // gg fluctuation part
732   Float_t padlength= GetPadPitchLength(seed->GetX());
733  
734   if (fSectors==fInnerSec){
735     snoise2 = 0.0004/padlength;
736     nel     = 0.268*amp;
737     nprim   = 0.155*amp;
738     gg      = (2+0.001*nel/(padlength*padlength))/nel;
739     landau  = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
740     if (landau>1) landau=1;
741   }
742   else {
743     snoise2 = 0.0004/padlength;
744     nel     = 0.3*amp;
745     nprim   = 0.133*amp;
746     gg      = (2+0.0008*nel/(padlength*padlength))/nel;
747     landau  = (2.+0.12*nprim)*0.5*(2.+nprim*nprim*0.001/(padlength*padlength))/nprim;
748     if (landau>1) landau=1;
749   }
750   Float_t sdiff = gg*fParam->GetDiffT()*fParam->GetDiffT()*z;
751
752   //
753   Float_t angle2 = seed->GetSnp()*seed->GetSnp();
754   angle2 = TMath::Sqrt((1-angle2));
755   if (angle2<0.6) angle2 = 0.6;
756   //angle2 = 1;
757
758   Float_t angle = seed->GetTgl()/angle2;
759   Float_t angular = landau*angle*angle*padlength*padlength/12.;
760   Float_t res = sdiff + angular;
761
762   
763   if ((ctype==0) && (fSectors ==fOuterSec))
764     res *= 0.81 +TMath::Exp(6.8*(rsigmaz-1.2));
765
766   if ((ctype==0) && (fSectors ==fInnerSec))
767     res *= 0.72 +TMath::Exp(2.04*(rsigmaz-1.2));
768   
769   if ((ctype>0)){
770     res+=0.005;
771     res*= TMath::Power(rsigmaz+0.5,1.5);  //0.31+0.147*ctype;
772   }
773   if (ctype<0){
774     res+=0.002;
775     res*=1.3;
776   }
777   if ((ctype<0) &&amp<70){
778     res+=0.002;
779     res*=1.3;  
780   }
781   res += snoise2;
782   if (res<2*snoise2)
783      res = 2*snoise2;
784
785   seed->SetErrorZ2(res);
786   return res;
787 }
788 */
789
790
791
792 void AliTPCseed::Reset(Bool_t all)
793 {
794   //
795   //
796   SetNumberOfClusters(0);
797   fNFoundable = 0;
798   SetChi2(0);
799   ResetCovariance();
800   /*
801   if (fTrackPoints){
802     for (Int_t i=0;i<8;i++){
803       delete [] fTrackPoints[i];
804     }
805     delete fTrackPoints;
806     fTrackPoints =0;
807   }
808   */
809
810   if (all){   
811     for (Int_t i=0;i<200;i++) SetClusterIndex2(i,-3);
812     for (Int_t i=0;i<160;i++) fClusterPointer[i]=0;
813   }
814
815 }
816
817
818 void AliTPCseed::Modify(Double_t factor)
819 {
820
821   //------------------------------------------------------------------
822   //This function makes a track forget its history :)  
823   //------------------------------------------------------------------
824   if (factor<=0) {
825     ResetCovariance();
826     return;
827   }
828   fC00*=factor;
829   fC10*=factor;  fC11*=factor;
830   fC20*=factor;  fC21*=factor;  fC22*=factor;
831   fC30*=factor;  fC31*=factor;  fC32*=factor;  fC33*=factor;
832   fC40*=factor;  fC41*=factor;  fC42*=factor;  fC43*=factor;  fC44*=factor;
833   SetNumberOfClusters(0);
834   fNFoundable =0;
835   SetChi2(0);
836   fRemoval = 0;
837   fCurrentSigmaY2 = 0.000005;
838   fCurrentSigmaZ2 = 0.000005;
839   fNoCluster     = 0;
840   //fFirstPoint = 160;
841   //fLastPoint  = 0;
842 }
843
844
845
846
847 Int_t  AliTPCseed::GetProlongation(Double_t xk, Double_t &y, Double_t & z) const
848 {
849   //-----------------------------------------------------------------
850   // This function find proloncation of a track to a reference plane x=xk.
851   // doesn't change internal state of the track
852   //-----------------------------------------------------------------
853   
854   Double_t x1=fX, x2=x1+(xk-x1), dx=x2-x1;
855
856   if (TMath::Abs(fP4*xk - fP2) >= 0.999) {   
857     return 0;
858   }
859
860   //  Double_t y1=fP0, z1=fP1;
861   Double_t c1=fP4*x1 - fP2, r1=sqrt(1.- c1*c1);
862   Double_t c2=fP4*x2 - fP2, r2=sqrt(1.- c2*c2);
863   
864   y = fP0;
865   z = fP1;
866   //y += dx*(c1+c2)/(r1+r2);
867   //z += dx*(c1+c2)/(c1*r2 + c2*r1)*fP3;
868   
869   Double_t dy = dx*(c1+c2)/(r1+r2);
870   Double_t dz = 0;
871   //
872   Double_t delta = fP4*dx*(c1+c2)/(c1*r2 + c2*r1);
873   /*
874   if (TMath::Abs(delta)>0.0001){
875     dz = fP3*TMath::ASin(delta)/fP4;
876   }else{
877     dz = dx*fP3*(c1+c2)/(c1*r2 + c2*r1);
878   }
879   */
880   dz =  fP3*TPCFastMath::FastAsin(delta)/fP4;
881   //
882   y+=dy;
883   z+=dz;
884   
885
886   return 1;  
887 }
888
889
890 //_____________________________________________________________________________
891 Double_t AliTPCseed::GetPredictedChi2(const AliTPCclusterMI *c) const 
892 {
893   //-----------------------------------------------------------------
894   // This function calculates a predicted chi2 increment.
895   //-----------------------------------------------------------------
896   //Double_t r00=c->GetSigmaY2(), r01=0., r11=c->GetSigmaZ2();
897   Double_t r00=fErrorY2, r01=0., r11=fErrorZ2;
898   r00+=fC00; r01+=fC10; r11+=fC11;
899
900   Double_t det=r00*r11 - r01*r01;
901   if (TMath::Abs(det) < 1.e-10) {
902     Int_t n=GetNumberOfClusters();
903     if (n>4) cerr<<n<<" AliKalmanTrack warning: Singular matrix !\n";
904     return 1e10;
905   }
906   Double_t tmp=r00; r00=r11; r11=tmp; r01=-r01;
907   
908   Double_t dy=c->GetY() - fP0, dz=c->GetZ() - fP1;
909   
910   return (dy*r00*dy + 2*r01*dy*dz + dz*r11*dz)/det;
911 }
912
913
914 //_________________________________________________________________________________________
915
916
917 Int_t AliTPCseed::Compare(const TObject *o) const {
918   //-----------------------------------------------------------------
919   // This function compares tracks according to the sector - for given sector according z
920   //-----------------------------------------------------------------
921   AliTPCseed *t=(AliTPCseed*)o;
922
923   if (fSort == 0){
924     if (t->fRelativeSector>fRelativeSector) return -1;
925     if (t->fRelativeSector<fRelativeSector) return 1;
926     Double_t z2 = t->GetZ();
927     Double_t z1 = GetZ();
928     if (z2>z1) return 1;
929     if (z2<z1) return -1;
930     return 0;
931   }
932   else {
933     Float_t f2 =1;
934     f2 = 1-20*TMath::Sqrt(t->fC44)/(TMath::Abs(t->GetC())+0.0066);
935     if (t->fBConstrain) f2=1.2;
936
937     Float_t f1 =1;
938     f1 = 1-20*TMath::Sqrt(fC44)/(TMath::Abs(GetC())+0.0066);
939
940     if (fBConstrain)   f1=1.2;
941  
942     if (t->GetNumberOfClusters()*f2 <GetNumberOfClusters()*f1) return -1;
943     else return +1;
944   }
945 }
946
947 void AliTPCtrackerMI::RotateToLocal(AliTPCseed *seed)
948 {
949   //rotate to track "local coordinata
950   Float_t x = seed->GetX();
951   Float_t y = seed->GetY();
952   Float_t ymax = x*TMath::Tan(0.5*fSectors->GetAlpha());
953   
954   if (y > ymax) {
955     seed->fRelativeSector= (seed->fRelativeSector+1) % fN;
956     if (!seed->Rotate(fSectors->GetAlpha())) 
957       return;
958   } else if (y <-ymax) {
959     seed->fRelativeSector= (seed->fRelativeSector-1+fN) % fN;
960     if (!seed->Rotate(-fSectors->GetAlpha())) 
961       return;
962   }   
963
964 }
965
966
967
968
969 //_____________________________________________________________________________
970 Int_t AliTPCseed::Update(const AliTPCclusterMI *c, Double_t chisq, UInt_t index) {
971   //-----------------------------------------------------------------
972   // This function associates a cluster with this track.
973   //-----------------------------------------------------------------
974   Double_t r00=fErrorY2, r01=0., r11=fErrorZ2;
975
976   r00+=fC00; r01+=fC10; r11+=fC11;
977   Double_t det=r00*r11 - r01*r01;
978   Double_t tmp=r00; r00=r11/det; r11=tmp/det; r01=-r01/det;
979
980   Double_t k00=fC00*r00+fC10*r01, k01=fC00*r01+fC10*r11;
981   Double_t k10=fC10*r00+fC11*r01, k11=fC10*r01+fC11*r11;
982   Double_t k20=fC20*r00+fC21*r01, k21=fC20*r01+fC21*r11;
983   Double_t k30=fC30*r00+fC31*r01, k31=fC30*r01+fC31*r11;
984   Double_t k40=fC40*r00+fC41*r01, k41=fC40*r01+fC41*r11;
985
986   Double_t dy=c->GetY() - fP0, dz=c->GetZ() - fP1;
987   Double_t cur=fP4 + k40*dy + k41*dz, eta=fP2 + k20*dy + k21*dz;
988   if (TMath::Abs(cur*fX-eta) >= 0.9) {
989     return 0;
990   }
991
992   fP0 += k00*dy + k01*dz;
993   fP1 += k10*dy + k11*dz;
994   fP2  = eta;
995   fP3 += k30*dy + k31*dz;
996   fP4  = cur;
997
998   Double_t c01=fC10, c02=fC20, c03=fC30, c04=fC40;
999   Double_t c12=fC21, c13=fC31, c14=fC41;
1000
1001   fC00-=k00*fC00+k01*fC10; fC10-=k00*c01+k01*fC11;
1002   fC20-=k00*c02+k01*c12;   fC30-=k00*c03+k01*c13;
1003   fC40-=k00*c04+k01*c14; 
1004
1005   fC11-=k10*c01+k11*fC11;
1006   fC21-=k10*c02+k11*c12;   fC31-=k10*c03+k11*c13;
1007   fC41-=k10*c04+k11*c14; 
1008
1009   fC22-=k20*c02+k21*c12;   fC32-=k20*c03+k21*c13;
1010   fC42-=k20*c04+k21*c14; 
1011
1012   fC33-=k30*c03+k31*c13;
1013   fC43-=k40*c03+k41*c13; 
1014
1015   fC44-=k40*c04+k41*c14; 
1016
1017   Int_t n=GetNumberOfClusters();
1018   //  fIndex[n]=index;
1019   SetNumberOfClusters(n+1);
1020   SetChi2(GetChi2()+chisq);
1021
1022   return 1;
1023 }
1024
1025
1026
1027 //_____________________________________________________________________________
1028 Double_t AliTPCtrackerMI::f1old(Double_t x1,Double_t y1,
1029                    Double_t x2,Double_t y2,
1030                    Double_t x3,Double_t y3) 
1031 {
1032   //-----------------------------------------------------------------
1033   // Initial approximation of the track curvature
1034   //-----------------------------------------------------------------
1035   Double_t d=(x2-x1)*(y3-y2)-(x3-x2)*(y2-y1);
1036   Double_t a=0.5*((y3-y2)*(y2*y2-y1*y1+x2*x2-x1*x1)-
1037                   (y2-y1)*(y3*y3-y2*y2+x3*x3-x2*x2));
1038   Double_t b=0.5*((x2-x1)*(y3*y3-y2*y2+x3*x3-x2*x2)-
1039                   (x3-x2)*(y2*y2-y1*y1+x2*x2-x1*x1));
1040
1041   Double_t xr=TMath::Abs(d/(d*x1-a)), yr=d/(d*y1-b);
1042   if ( xr*xr+yr*yr<=0.00000000000001) return 100;
1043   return -xr*yr/sqrt(xr*xr+yr*yr); 
1044 }
1045
1046
1047
1048 //_____________________________________________________________________________
1049 Double_t AliTPCtrackerMI::f1(Double_t x1,Double_t y1,
1050                    Double_t x2,Double_t y2,
1051                    Double_t x3,Double_t y3) 
1052 {
1053   //-----------------------------------------------------------------
1054   // Initial approximation of the track curvature
1055   //-----------------------------------------------------------------
1056   x3 -=x1;
1057   x2 -=x1;
1058   y3 -=y1;
1059   y2 -=y1;
1060   //  
1061   Double_t det = x3*y2-x2*y3;
1062   if (det==0) {
1063     return 100;
1064   }
1065   //
1066   Double_t u = 0.5* (x2*(x2-x3)+y2*(y2-y3))/det;
1067   Double_t x0 = x3*0.5-y3*u;
1068   Double_t y0 = y3*0.5+x3*u;
1069   Double_t c2 = 1/TMath::Sqrt(x0*x0+y0*y0);
1070   if (det<0) c2*=-1;
1071   return c2;
1072 }
1073
1074
1075 Double_t AliTPCtrackerMI::f2(Double_t x1,Double_t y1,
1076                    Double_t x2,Double_t y2,
1077                    Double_t x3,Double_t y3) 
1078 {
1079   //-----------------------------------------------------------------
1080   // Initial approximation of the track curvature
1081   //-----------------------------------------------------------------
1082   x3 -=x1;
1083   x2 -=x1;
1084   y3 -=y1;
1085   y2 -=y1;
1086   //  
1087   Double_t det = x3*y2-x2*y3;
1088   if (det==0) {
1089     return 100;
1090   }
1091   //
1092   Double_t u = 0.5* (x2*(x2-x3)+y2*(y2-y3))/det;
1093   Double_t x0 = x3*0.5-y3*u; 
1094   Double_t y0 = y3*0.5+x3*u;
1095   Double_t c2 = 1/TMath::Sqrt(x0*x0+y0*y0);
1096   if (det<0) c2*=-1;
1097   x0+=x1;
1098   x0*=c2;  
1099   return x0;
1100 }
1101
1102
1103
1104 //_____________________________________________________________________________
1105 Double_t AliTPCtrackerMI::f2old(Double_t x1,Double_t y1,
1106                    Double_t x2,Double_t y2,
1107                    Double_t x3,Double_t y3) 
1108 {
1109   //-----------------------------------------------------------------
1110   // Initial approximation of the track curvature times center of curvature
1111   //-----------------------------------------------------------------
1112   Double_t d=(x2-x1)*(y3-y2)-(x3-x2)*(y2-y1);
1113   Double_t a=0.5*((y3-y2)*(y2*y2-y1*y1+x2*x2-x1*x1)-
1114                   (y2-y1)*(y3*y3-y2*y2+x3*x3-x2*x2));
1115   Double_t b=0.5*((x2-x1)*(y3*y3-y2*y2+x3*x3-x2*x2)-
1116                   (x3-x2)*(y2*y2-y1*y1+x2*x2-x1*x1));
1117
1118   Double_t xr=TMath::Abs(d/(d*x1-a)), yr=d/(d*y1-b);
1119   
1120   return -a/(d*y1-b)*xr/sqrt(xr*xr+yr*yr);
1121 }
1122
1123 //_____________________________________________________________________________
1124 Double_t AliTPCtrackerMI::f3(Double_t x1,Double_t y1, 
1125                    Double_t x2,Double_t y2,
1126                    Double_t z1,Double_t z2) 
1127 {
1128   //-----------------------------------------------------------------
1129   // Initial approximation of the tangent of the track dip angle
1130   //-----------------------------------------------------------------
1131   return (z1 - z2)/sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
1132 }
1133
1134
1135 Double_t AliTPCtrackerMI::f3n(Double_t x1,Double_t y1, 
1136                    Double_t x2,Double_t y2,
1137                    Double_t z1,Double_t z2, Double_t c) 
1138 {
1139   //-----------------------------------------------------------------
1140   // Initial approximation of the tangent of the track dip angle
1141   //-----------------------------------------------------------------
1142
1143   //  Double_t angle1;
1144   
1145   //angle1    =  (z1-z2)*c/(TMath::ASin(c*x1-ni)-TMath::ASin(c*x2-ni));
1146   //
1147   Double_t d  =  TMath::Sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
1148   if (TMath::Abs(d*c*0.5)>1) return 0;
1149   //  Double_t   angle2    =  TMath::ASin(d*c*0.5);
1150   //  Double_t   angle2    =  TPCFastMath::FastAsin(d*c*0.5);
1151   Double_t   angle2    = (d*c*0.5>0.1)? TMath::ASin(d*c*0.5): TPCFastMath::FastAsin(d*c*0.5);
1152
1153   angle2  = (z1-z2)*c/(angle2*2.);
1154   return angle2;
1155 }
1156
1157 Bool_t   AliTPCtrackerMI::GetProlongation(Double_t x1, Double_t x2, Double_t x[5], Double_t &y, Double_t &z)
1158 {//-----------------------------------------------------------------
1159   // This function find proloncation of a track to a reference plane x=x2.
1160   //-----------------------------------------------------------------
1161   
1162   Double_t dx=x2-x1;
1163
1164   if (TMath::Abs(x[4]*x1 - x[2]) >= 0.999) {   
1165     return kFALSE;
1166   }
1167
1168   Double_t c1=x[4]*x1 - x[2], r1=sqrt(1.- c1*c1);
1169   Double_t c2=x[4]*x2 - x[2], r2=sqrt(1.- c2*c2);  
1170   y = x[0];
1171   z = x[1];
1172   
1173   Double_t dy = dx*(c1+c2)/(r1+r2);
1174   Double_t dz = 0;
1175   //
1176   Double_t delta = x[4]*dx*(c1+c2)/(c1*r2 + c2*r1);
1177   
1178   if (TMath::Abs(delta)>0.01){
1179     dz = x[3]*TMath::ASin(delta)/x[4];
1180   }else{
1181     dz = x[3]*TPCFastMath::FastAsin(delta)/x[4];
1182   }
1183   
1184   //dz = x[3]*TPCFastMath::FastAsin(delta)/x[4];
1185
1186   y+=dy;
1187   z+=dz;
1188   
1189   return kTRUE;  
1190 }
1191
1192
1193
1194 Int_t  AliTPCtrackerMI::LoadClusters()
1195 {
1196   //
1197   // load clusters to the memory
1198   AliTPCClustersRow *clrow= new AliTPCClustersRow;
1199   clrow->SetClass("AliTPCclusterMI");
1200   clrow->SetArray(0);
1201   clrow->GetArray()->ExpandCreateFast(10000);
1202   //
1203   //  TTree * tree = fClustersArray.GetTree();
1204
1205   TTree * tree = fInput;
1206   TBranch * br = tree->GetBranch("Segment");
1207   br->SetAddress(&clrow);
1208   //
1209   Int_t j=Int_t(tree->GetEntries());
1210   for (Int_t i=0; i<j; i++) {
1211     br->GetEntry(i);
1212     //  
1213     Int_t sec,row;
1214     fParam->AdjustSectorRow(clrow->GetID(),sec,row);
1215     //
1216     AliTPCRow * tpcrow=0;
1217     Int_t left=0;
1218     if (sec<fkNIS*2){
1219       tpcrow = &(fInnerSec[sec%fkNIS][row]);    
1220       left = sec/fkNIS;
1221     }
1222     else{
1223       tpcrow = &(fOuterSec[(sec-fkNIS*2)%fkNOS][row]);
1224       left = (sec-fkNIS*2)/fkNOS;
1225     }
1226     if (left ==0){
1227       tpcrow->fN1 = clrow->GetArray()->GetEntriesFast();
1228       tpcrow->fClusters1 = new AliTPCclusterMI[tpcrow->fN1];
1229       for (Int_t i=0;i<tpcrow->fN1;i++) 
1230         tpcrow->fClusters1[i] = *(AliTPCclusterMI*)(clrow->GetArray()->At(i));
1231     }
1232     if (left ==1){
1233       tpcrow->fN2 = clrow->GetArray()->GetEntriesFast();
1234       tpcrow->fClusters2 = new AliTPCclusterMI[tpcrow->fN2];
1235       for (Int_t i=0;i<tpcrow->fN2;i++) 
1236         tpcrow->fClusters2[i] = *(AliTPCclusterMI*)(clrow->GetArray()->At(i));
1237     }
1238   }
1239   //
1240   delete clrow;
1241   LoadOuterSectors();
1242   LoadInnerSectors();
1243   return 0;
1244 }
1245
1246
1247 void AliTPCtrackerMI::UnloadClusters()
1248 {
1249   //
1250   // unload clusters from the memory
1251   //
1252   Int_t nrows = fOuterSec->GetNRows();
1253   for (Int_t sec = 0;sec<fkNOS;sec++)
1254     for (Int_t row = 0;row<nrows;row++){
1255       AliTPCRow*  tpcrow = &(fOuterSec[sec%fkNOS][row]);
1256       if (tpcrow){
1257         if (tpcrow->fClusters1) delete []tpcrow->fClusters1; 
1258         if (tpcrow->fClusters2) delete []tpcrow->fClusters2; 
1259       }
1260     }
1261   //
1262   nrows = fInnerSec->GetNRows();
1263   for (Int_t sec = 0;sec<fkNIS;sec++)
1264     for (Int_t row = 0;row<nrows;row++){
1265       AliTPCRow*  tpcrow = &(fInnerSec[sec%fkNIS][row]);
1266       if (tpcrow){
1267         if (tpcrow->fClusters1) delete []tpcrow->fClusters1; 
1268         if (tpcrow->fClusters2) delete []tpcrow->fClusters2; 
1269       }
1270     }
1271
1272   return ;
1273 }
1274
1275
1276 //_____________________________________________________________________________
1277 Int_t AliTPCtrackerMI::LoadOuterSectors() {
1278   //-----------------------------------------------------------------
1279   // This function fills outer TPC sectors with clusters.
1280   //-----------------------------------------------------------------
1281   Int_t nrows = fOuterSec->GetNRows();
1282   UInt_t index=0;
1283   for (Int_t sec = 0;sec<fkNOS;sec++)
1284     for (Int_t row = 0;row<nrows;row++){
1285       AliTPCRow*  tpcrow = &(fOuterSec[sec%fkNOS][row]);  
1286       Int_t sec2 = sec+2*fkNIS;
1287       //left
1288       Int_t ncl = tpcrow->fN1;
1289       while (ncl--) {
1290         AliTPCclusterMI *c= &(tpcrow->fClusters1[ncl]);
1291         index=(((sec2<<8)+row)<<16)+ncl;
1292         tpcrow->InsertCluster(c,index);
1293       }
1294       //right
1295       ncl = tpcrow->fN2;
1296       while (ncl--) {
1297         AliTPCclusterMI *c= &(tpcrow->fClusters2[ncl]);
1298         index=((((sec2+fkNOS)<<8)+row)<<16)+ncl;
1299         tpcrow->InsertCluster(c,index);
1300       }
1301       //
1302       // write indexes for fast acces
1303       //
1304       for (Int_t i=0;i<510;i++)
1305         tpcrow->fFastCluster[i]=-1;
1306       for (Int_t i=0;i<tpcrow->GetN();i++){
1307         Int_t zi = Int_t((*tpcrow)[i]->GetZ()+255.);
1308         tpcrow->fFastCluster[zi]=i;  // write index
1309       }
1310       Int_t last = 0;
1311       for (Int_t i=0;i<510;i++){
1312         if (tpcrow->fFastCluster[i]<0)
1313           tpcrow->fFastCluster[i] = last;
1314         else
1315           last = tpcrow->fFastCluster[i];
1316       }
1317     }  
1318   fN=fkNOS;
1319   fSectors=fOuterSec;
1320   return 0;
1321 }
1322
1323
1324 //_____________________________________________________________________________
1325 Int_t  AliTPCtrackerMI::LoadInnerSectors() {
1326   //-----------------------------------------------------------------
1327   // This function fills inner TPC sectors with clusters.
1328   //-----------------------------------------------------------------
1329   Int_t nrows = fInnerSec->GetNRows();
1330   UInt_t index=0;
1331   for (Int_t sec = 0;sec<fkNIS;sec++)
1332     for (Int_t row = 0;row<nrows;row++){
1333       AliTPCRow*  tpcrow = &(fInnerSec[sec%fkNIS][row]);
1334       //
1335       //left
1336       Int_t ncl = tpcrow->fN1;
1337       while (ncl--) {
1338         AliTPCclusterMI *c= &(tpcrow->fClusters1[ncl]);
1339         index=(((sec<<8)+row)<<16)+ncl;
1340         tpcrow->InsertCluster(c,index);
1341       }
1342       //right
1343       ncl = tpcrow->fN2;
1344       while (ncl--) {
1345         AliTPCclusterMI *c= &(tpcrow->fClusters2[ncl]);
1346         index=((((sec+fkNIS)<<8)+row)<<16)+ncl;
1347         tpcrow->InsertCluster(c,index);
1348       }
1349       //
1350       // write indexes for fast acces
1351       //
1352       for (Int_t i=0;i<510;i++)
1353         tpcrow->fFastCluster[i]=-1;
1354       for (Int_t i=0;i<tpcrow->GetN();i++){
1355         Int_t zi = Int_t((*tpcrow)[i]->GetZ()+255.);
1356         tpcrow->fFastCluster[zi]=i;  // write index
1357       }
1358       Int_t last = 0;
1359       for (Int_t i=0;i<510;i++){
1360         if (tpcrow->fFastCluster[i]<0)
1361           tpcrow->fFastCluster[i] = last;
1362         else
1363           last = tpcrow->fFastCluster[i];
1364       }
1365
1366     }  
1367    
1368   fN=fkNIS;
1369   fSectors=fInnerSec;
1370   return 0;
1371 }
1372
1373
1374
1375 //_________________________________________________________________________
1376 AliTPCclusterMI *AliTPCtrackerMI::GetClusterMI(Int_t index) const {
1377   //--------------------------------------------------------------------
1378   //       Return pointer to a given cluster
1379   //--------------------------------------------------------------------
1380   Int_t sec=(index&0xff000000)>>24; 
1381   Int_t row=(index&0x00ff0000)>>16; 
1382   Int_t ncl=(index&0x0000ffff)>>00;
1383
1384   const AliTPCRow * tpcrow=0;
1385   AliTPCclusterMI * clrow =0;
1386   if (sec<fkNIS*2){
1387     tpcrow = &(fInnerSec[sec%fkNIS][row]);
1388     if (sec<fkNIS) 
1389       clrow = tpcrow->fClusters1;
1390     else
1391       clrow = tpcrow->fClusters2;
1392   }
1393   else{
1394     tpcrow = &(fOuterSec[(sec-fkNIS*2)%fkNOS][row]);
1395     if (sec-2*fkNIS<fkNOS)
1396       clrow = tpcrow->fClusters1;
1397     else
1398       clrow = tpcrow->fClusters2;
1399   }
1400   if (tpcrow==0) return 0;
1401   if (tpcrow->GetN()<=ncl) return 0;
1402   //  return (AliTPCclusterMI*)(*tpcrow)[ncl];      
1403   return &(clrow[ncl]);      
1404   
1405 }
1406
1407
1408
1409 Int_t AliTPCtrackerMI::FollowToNext(AliTPCseed& t, Int_t nr) {
1410   //-----------------------------------------------------------------
1411   // This function tries to find a track prolongation to next pad row
1412   //-----------------------------------------------------------------
1413   //
1414   Double_t  x= GetXrow(nr), ymax=GetMaxY(nr);
1415
1416   //  if (t.GetRadius()>x+10 ) return 0;
1417   //  t.PropagateTo(x+0.02);
1418   //t.PropagateTo(x+0.01);
1419   if (!t.PropagateTo(x)) {
1420     t.fRemoval = 10;
1421     return 0;
1422   }
1423   //
1424   Double_t  y=t.GetY(), z=t.GetZ();
1425   if (TMath::Abs(y)>ymax){
1426     if (y > ymax) {
1427       t.fRelativeSector= (t.fRelativeSector+1) % fN;
1428       if (!t.Rotate(fSectors->GetAlpha())) 
1429         return 0;
1430     } else if (y <-ymax) {
1431       t.fRelativeSector= (t.fRelativeSector-1+fN) % fN;
1432       if (!t.Rotate(-fSectors->GetAlpha())) 
1433         return 0;
1434     }
1435     if (!t.PropagateTo(x)) {
1436       return 0;
1437     } 
1438     y=t.GetY();
1439   }
1440   //
1441   // update current shape info every 3 pad-row
1442   if ( (nr%5==0) || t.GetNumberOfClusters()<2 || (t.fCurrentSigmaY2<0.0001) ){
1443     //t.fCurrentSigmaY = GetSigmaY(&t);
1444     //t.fCurrentSigmaZ = GetSigmaZ(&t);
1445     GetShape(&t,nr);    
1446   }
1447   //  
1448   AliTPCclusterMI *cl=0;
1449   UInt_t index=0;
1450   
1451   
1452   //Int_t nr2 = nr;
1453   if (t.GetClusterIndex2(nr)>0){ 
1454     //
1455     //cl = GetClusterMI(t.GetClusterIndex2(nr));
1456     index = t.GetClusterIndex2(nr);    
1457     cl = t.fClusterPointer[nr];
1458     if ( (cl==0) && (index>0)) cl = GetClusterMI(index);
1459     t.fCurrentClusterIndex1 = index; 
1460   }
1461   
1462   const AliTPCRow &krow=GetRow(t.fRelativeSector,nr);
1463   if ( (t.GetSigmaY2()<0) || t.GetSigmaZ2()<0) return 0;
1464   Double_t  roady  =1.;
1465   Double_t  roadz = 1.;
1466   //
1467   if (TMath::Abs(TMath::Abs(y)-ymax)<krow.fDeadZone){
1468     t.fInDead = kTRUE;
1469     t.SetClusterIndex2(nr,-1); 
1470     return 0;
1471   } 
1472   else
1473     {
1474       if (TMath::Abs(z)<(1.05*x+10)) t.fNFoundable++;
1475       else
1476         return 0;
1477     }   
1478   //calculate 
1479   if (cl){
1480     t.fCurrentCluster = cl; 
1481     t.fRow = nr;
1482     Int_t accept = AcceptCluster(&t,t.fCurrentCluster,1.);
1483     if (accept<3) { 
1484       //if founded cluster is acceptible
1485       UpdateTrack(&t,accept);
1486       return 1;
1487     }    
1488   }
1489
1490   if (krow) {
1491     //    cl = krow.FindNearest2(y+10.,z,roady,roadz,index);    
1492     cl = krow.FindNearest2(y,z,roady,roadz,index);    
1493     if (cl) t.fCurrentClusterIndex1 = krow.GetIndex(index);       
1494   }  
1495   //  t.fNoCluster++;
1496
1497   if (cl) {
1498     t.fCurrentCluster = cl; 
1499     t.fRow = nr;
1500     Int_t accept = AcceptCluster(&t,t.fCurrentCluster,1.);
1501     
1502     if (t.fCurrentCluster->IsUsed(10)){
1503       //
1504       //     
1505
1506       t.fNShared++;
1507       if (t.fNShared>0.7*t.GetNumberOfClusters()) {
1508         t.fRemoval =10;
1509         return 0;
1510       }
1511     }
1512     
1513     if (accept<3) UpdateTrack(&t,accept);
1514
1515   } else {  
1516     if (t.fNFoundable*0.5 > t.GetNumberOfClusters()) t.fRemoval=10;
1517     
1518   }
1519   return 1;
1520 }
1521
1522 Int_t AliTPCtrackerMI::FollowToNextFast(AliTPCseed& t, Int_t nr) {
1523   //-----------------------------------------------------------------
1524   // This function tries to find a track prolongation to next pad row
1525   //-----------------------------------------------------------------
1526   //
1527   Double_t  x= GetXrow(nr), ymax=GetMaxY(nr);
1528   Double_t y,z; 
1529   if (!t.GetProlongation(x,y,z)) {
1530     t.fRemoval = 10;
1531     return 0;
1532   }
1533   //
1534   //
1535   if (TMath::Abs(y)>ymax){
1536     return 0;
1537     
1538     if (y > ymax) {
1539       t.fRelativeSector= (t.fRelativeSector+1) % fN;
1540       if (!t.Rotate(fSectors->GetAlpha())) 
1541         return 0;
1542     } else if (y <-ymax) {
1543       t.fRelativeSector= (t.fRelativeSector-1+fN) % fN;
1544       if (!t.Rotate(-fSectors->GetAlpha())) 
1545         return 0;
1546     }
1547     if (!t.PropagateTo(x)) {
1548       return 0;
1549     } 
1550     t.GetProlongation(x,y,z);
1551   }
1552   //
1553   // update current shape info every 3 pad-row
1554   if ( (nr%6==0) || t.GetNumberOfClusters()<2 || (t.fCurrentSigmaY2<0.0001) ){
1555     //    t.fCurrentSigmaY = GetSigmaY(&t);
1556     //t.fCurrentSigmaZ = GetSigmaZ(&t);
1557     GetShape(&t,nr);
1558   }
1559   //  
1560   AliTPCclusterMI *cl=0;
1561   UInt_t index=0;
1562   
1563   
1564   //Int_t nr2 = nr;
1565   const AliTPCRow &krow=GetRow(t.fRelativeSector,nr);
1566   if ( (t.GetSigmaY2()<0) || t.GetSigmaZ2()<0) return 0;
1567   Double_t  roady  =1.;
1568   Double_t  roadz = 1.;
1569   //
1570   Int_t row = nr;
1571   if (TMath::Abs(TMath::Abs(y)-ymax)<krow.fDeadZone){
1572     t.fInDead = kTRUE;
1573     t.SetClusterIndex2(row,-1); 
1574     return 0;
1575   } 
1576   else
1577     {
1578       if (TMath::Abs(z)>(1.05*x+10)) t.SetClusterIndex2(row,-1);
1579     }   
1580   //calculate 
1581   
1582   if ((cl==0)&&(krow)) {
1583     //    cl = krow.FindNearest2(y+10,z,roady,roadz,index);    
1584     cl = krow.FindNearest2(y,z,roady,roadz,index);    
1585
1586     if (cl) t.fCurrentClusterIndex1 = krow.GetIndex(index);       
1587   }  
1588
1589   if (cl) {
1590     t.fCurrentCluster = cl; 
1591     //    Int_t accept = AcceptCluster(&t,t.fCurrentCluster,1.);        
1592     //if (accept<3){
1593       t.SetClusterIndex2(row,index);
1594       t.fClusterPointer[row] = cl;
1595       //}
1596   }
1597   return 1;
1598 }
1599
1600
1601
1602 Int_t AliTPCtrackerMI::UpdateClusters(AliTPCseed& t,  Int_t nr) {
1603   //-----------------------------------------------------------------
1604   // This function tries to find a track prolongation to next pad row
1605   //-----------------------------------------------------------------
1606   t.fCurrentCluster  = 0;
1607   t.fCurrentClusterIndex1 = 0;   
1608    
1609   Double_t xt=t.GetX();
1610   Int_t     row = GetRowNumber(xt)-1; 
1611   Double_t  ymax= GetMaxY(nr);
1612
1613   if (row < nr) return 1; // don't prolongate if not information until now -
1614   if (TMath::Abs(t.GetSnp())>0.9 && t.GetNumberOfClusters()>40. && fIteration!=2) {
1615     t.fRemoval =10;
1616     return 0;  // not prolongate strongly inclined tracks
1617   } 
1618   if (TMath::Abs(t.GetSnp())>0.95) {
1619     t.fRemoval =10;
1620     return 0;  // not prolongate strongly inclined tracks
1621   }
1622
1623   Double_t x= GetXrow(nr);
1624   Double_t y,z;
1625   //t.PropagateTo(x+0.02);
1626   //t.PropagateTo(x+0.01);
1627   if (!t.PropagateTo(x)){
1628     return 0;
1629   }
1630   //
1631   y=t.GetY();
1632   z=t.GetZ();
1633
1634   if (TMath::Abs(y)>ymax){
1635     if (y > ymax) {
1636       t.fRelativeSector= (t.fRelativeSector+1) % fN;
1637       if (!t.Rotate(fSectors->GetAlpha())) 
1638         return 0;
1639     } else if (y <-ymax) {
1640       t.fRelativeSector= (t.fRelativeSector-1+fN) % fN;
1641       if (!t.Rotate(-fSectors->GetAlpha())) 
1642         return 0;
1643     }
1644     if (!t.PropagateTo(x)){
1645       return 0;
1646     }
1647     y = t.GetY();    
1648   }
1649   //
1650
1651   AliTPCRow &krow=GetRow(t.fRelativeSector,nr);
1652
1653   if (TMath::Abs(TMath::Abs(y)-ymax)<krow.fDeadZone){
1654     t.fInDead = kTRUE;
1655     t.SetClusterIndex2(nr,-1); 
1656     return 0;
1657   } 
1658   else
1659     {
1660       if (TMath::Abs(t.GetZ())<(1.05*t.GetX()+10)) t.fNFoundable++;
1661       else
1662         return 0;      
1663     }
1664
1665   // update current
1666   if ( (nr%6==0) || t.GetNumberOfClusters()<2){
1667     //    t.fCurrentSigmaY = GetSigmaY(&t);
1668     //t.fCurrentSigmaZ = GetSigmaZ(&t);
1669     GetShape(&t,nr);
1670   }
1671     
1672   AliTPCclusterMI *cl=0;
1673   UInt_t index=0;
1674   //
1675   Double_t roady = 1.;
1676   Double_t roadz = 1.;
1677   //
1678   if (krow) {    
1679     //cl = krow.FindNearest2(y+10,z,roady,roadz,index);      
1680     cl = krow.FindNearest2(y,z,roady,roadz,index);      
1681   }
1682   t.fCurrentCluster  = cl;
1683   if (cl) t.fCurrentClusterIndex1 = krow.GetIndex(index);   
1684   return 1;
1685 }
1686
1687
1688 Int_t AliTPCtrackerMI::FollowToNextCluster(AliTPCseed & t, Int_t nr) {
1689   //-----------------------------------------------------------------
1690   // This function tries to find a track prolongation to next pad row
1691   //-----------------------------------------------------------------
1692
1693   //update error according neighborhoud
1694
1695   if (t.fCurrentCluster) {
1696     t.fRow = nr; 
1697     Bool_t accept = AcceptCluster(&t,t.fCurrentCluster,1.);
1698     
1699     if (t.fCurrentCluster->IsUsed(10)){
1700       //
1701       //
1702       //  t.fErrorZ2*=2;
1703       //  t.fErrorY2*=2;
1704       t.fNShared++;
1705       if (t.fNShared>0.7*t.GetNumberOfClusters()) {
1706         t.fRemoval =10;
1707         return 0;
1708       }
1709     }
1710     
1711     if (accept<3) UpdateTrack(&t,accept);
1712    
1713   } else {
1714     if (fIteration==0){
1715       if ( ( (t.GetSigmaY2()+t.GetSigmaZ2())>0.16)&& t.GetNumberOfClusters()>18) t.fRemoval=10;      
1716       if (  t.GetChi2()/t.GetNumberOfClusters()>6 &&t.GetNumberOfClusters()>18) t.fRemoval=10;      
1717
1718       if (( (t.fNFoundable*0.5 > t.GetNumberOfClusters()) || t.fNoCluster>15)) t.fRemoval=10;
1719     }
1720   }
1721   return 1;
1722 }
1723
1724
1725
1726 //_____________________________________________________________________________
1727 Int_t AliTPCtrackerMI::FollowProlongation(AliTPCseed& t, Int_t rf, Int_t step) {
1728   //-----------------------------------------------------------------
1729   // This function tries to find a track prolongation.
1730   //-----------------------------------------------------------------
1731   Double_t xt=t.GetX();
1732   //
1733   Double_t alpha=t.GetAlpha() - fSectors->GetAlphaShift();
1734   if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();  
1735   if (alpha < 0.            ) alpha += 2.*TMath::Pi();  
1736   //
1737   t.fRelativeSector = Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN;
1738     
1739   Int_t first = GetRowNumber(xt)-1;
1740   for (Int_t nr= first; nr>=rf; nr-=step) {    
1741     if (FollowToNext(t,nr)==0) 
1742       if (!t.IsActive()) return 0;
1743     
1744   }   
1745   return 1;
1746 }
1747
1748
1749 //_____________________________________________________________________________
1750 Int_t AliTPCtrackerMI::FollowProlongationFast(AliTPCseed& t, Int_t rf, Int_t step) {
1751   //-----------------------------------------------------------------
1752   // This function tries to find a track prolongation.
1753   //-----------------------------------------------------------------
1754   Double_t xt=t.GetX();
1755   //
1756   Double_t alpha=t.GetAlpha() - fSectors->GetAlphaShift();
1757   if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();  
1758   if (alpha < 0.            ) alpha += 2.*TMath::Pi();  
1759   t.fRelativeSector = Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN;
1760     
1761   for (Int_t nr=GetRowNumber(xt)-1; nr>=rf; nr-=step) {
1762     
1763     if (FollowToNextFast(t,nr)==0) 
1764       if (!t.IsActive()) return 0;
1765     
1766   }   
1767   return 1;
1768 }
1769
1770
1771
1772
1773
1774 Int_t AliTPCtrackerMI::FollowBackProlongation(AliTPCseed& t, Int_t rf) {
1775   //-----------------------------------------------------------------
1776   // This function tries to find a track prolongation.
1777   //-----------------------------------------------------------------
1778   //  Double_t xt=t.GetX();  
1779   //
1780   Double_t alpha=t.GetAlpha() - fSectors->GetAlphaShift();
1781   if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();  
1782   if (alpha < 0.            ) alpha += 2.*TMath::Pi();  
1783   t.fRelativeSector = Int_t(alpha/fSectors->GetAlpha()+0.0001)%fN;
1784     
1785   Int_t first = 0;
1786   first = t.fFirstPoint+3;
1787   //
1788   if (first<0) first=0;
1789   for (Int_t nr=first+1; nr<=rf; nr++) {
1790     //if ( (t.GetSnp()<0.9))
1791       FollowToNext(t,nr);                                                             
1792   }   
1793   return 1;
1794 }
1795
1796
1797
1798
1799    
1800 Float_t AliTPCtrackerMI::OverlapFactor(AliTPCseed * s1, AliTPCseed * s2, Int_t &sum1, Int_t & sum2)
1801 {
1802   //
1803   //
1804   sum1=0;
1805   sum2=0;
1806   Int_t sum=0;
1807   //
1808   Float_t dz2 =(s1->GetZ() - s2->GetZ());
1809   dz2*=dz2;  
1810
1811   Float_t dy2 =TMath::Abs((s1->GetY() - s2->GetY()));
1812   dy2*=dy2;
1813   Float_t distance = TMath::Sqrt(dz2+dy2);
1814   if (distance>4.) return 0; // if there are far away  - not overlap - to reduce combinatorics
1815  
1816   //  Int_t offset =0;
1817   Int_t firstpoint = TMath::Min(s1->fFirstPoint,s2->fFirstPoint);
1818   Int_t lastpoint = TMath::Max(s1->fLastPoint,s2->fLastPoint);
1819   if (lastpoint>160) 
1820     lastpoint =160;
1821   if (firstpoint<0) 
1822     firstpoint = 0;
1823   if (firstpoint>lastpoint) {
1824     firstpoint =lastpoint;
1825     //    lastpoint  =160;
1826   }
1827     
1828   
1829   for (Int_t i=firstpoint-1;i<lastpoint+1;i++){
1830     if (s1->GetClusterIndex2(i)>0) sum1++;
1831     if (s2->GetClusterIndex2(i)>0) sum2++;
1832     if (s1->GetClusterIndex2(i)==s2->GetClusterIndex2(i) && s1->GetClusterIndex2(i)>0) {
1833       sum++;
1834     }
1835   }
1836   if (sum<5) return 0;
1837
1838   Float_t summin = TMath::Min(sum1+1,sum2+1);
1839   Float_t ratio = (sum+1)/Float_t(summin);
1840   return ratio;
1841 }
1842
1843 void  AliTPCtrackerMI::SignShared(AliTPCseed * s1, AliTPCseed * s2)
1844 {
1845   //
1846   //
1847   if (TMath::Abs(s1->GetC()-s2->GetC())>0.004) return;
1848   if (TMath::Abs(s1->GetTgl()-s2->GetTgl())>0.6) return;
1849
1850   Float_t dz2 =(s1->GetZ() - s2->GetZ());
1851   dz2*=dz2;
1852   Float_t dy2 =(s1->GetY() - s2->GetY());
1853   dy2*=dy2;
1854   Float_t distance = dz2+dy2;
1855   if (distance>325.) return ; // if there are far away  - not overlap - to reduce combinatorics
1856   
1857   //
1858   Int_t sumshared=0;
1859   //
1860   Int_t firstpoint = TMath::Max(s1->fFirstPoint,s2->fFirstPoint);
1861   Int_t lastpoint = TMath::Min(s1->fLastPoint,s2->fLastPoint);
1862   //
1863   if (firstpoint>=lastpoint-5) return;;
1864
1865   for (Int_t i=firstpoint;i<lastpoint;i++){
1866     //    if ( (s1->GetClusterIndex2(i)&0xFFFF8FFF)==(s2->GetClusterIndex2(i)&0xFFFF8FFF) && s1->GetClusterIndex2(i)>0) {
1867     if ( (s1->GetClusterIndex2(i))==(s2->GetClusterIndex2(i)) && s1->GetClusterIndex2(i)>0) {
1868       sumshared++;
1869     }
1870   }
1871   if (sumshared>4){
1872     // sign clusters
1873     //
1874     for (Int_t i=firstpoint;i<lastpoint;i++){
1875       //      if ( (s1->GetClusterIndex2(i)&0xFFFF8FFF)==(s2->GetClusterIndex2(i)&0xFFFF8FFF) && s1->GetClusterIndex2(i)>0) {
1876       if ( (s1->GetClusterIndex2(i))==(s2->GetClusterIndex2(i)) && s1->GetClusterIndex2(i)>0) {
1877         AliTPCTrackerPoint *p1  = s1->GetTrackPoint(i);
1878         AliTPCTrackerPoint *p2  = s2->GetTrackPoint(i);; 
1879         if (s1->IsActive()&&s2->IsActive()){
1880           p1->fIsShared = kTRUE;
1881           p2->fIsShared = kTRUE;
1882         }       
1883       }
1884     }
1885   }
1886   //  
1887   if (sumshared>10){
1888     for (Int_t i=0;i<4;i++){
1889       if (s1->fOverlapLabels[3*i]==0){
1890         s1->fOverlapLabels[3*i] = s2->GetLabel();
1891         s1->fOverlapLabels[3*i+1] = sumshared;
1892         s1->fOverlapLabels[3*i+2] = s2->GetUniqueID();
1893         break;
1894       } 
1895     }
1896     for (Int_t i=0;i<4;i++){
1897       if (s2->fOverlapLabels[3*i]==0){
1898         s2->fOverlapLabels[3*i] = s1->GetLabel();
1899         s2->fOverlapLabels[3*i+1] = sumshared;
1900         s2->fOverlapLabels[3*i+2] = s1->GetUniqueID();
1901         break;
1902       } 
1903     }    
1904   }
1905   
1906 }
1907
1908 void  AliTPCtrackerMI::SignShared(TObjArray * arr)
1909 {
1910   //
1911   //sort trackss according sectors
1912   //  
1913   for (Int_t i=0; i<arr->GetEntriesFast(); i++) {
1914     AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);    
1915     if (!pt) continue;
1916     //if (pt) RotateToLocal(pt);
1917     pt->fSort = 0;
1918   }
1919   arr->UnSort();
1920   arr->Sort();  // sorting according z
1921   arr->Expand(arr->GetEntries());
1922   //
1923   //
1924   Int_t nseed=arr->GetEntriesFast();
1925   for (Int_t i=0; i<nseed; i++) {
1926     AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);    
1927     if (!pt) continue;
1928     for (Int_t j=0;j<=12;j++){
1929       pt->fOverlapLabels[j] =0;
1930     }
1931   }
1932   for (Int_t i=0; i<nseed; i++) {
1933     AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);    
1934     if (!pt) continue;
1935     if (pt->fRemoval>10) continue;
1936     for (Int_t j=i+1; j<nseed; j++){
1937       AliTPCseed *pt2=(AliTPCseed*)arr->UncheckedAt(j);
1938       //      if (pt2){
1939       if (pt2->fRemoval<=10) {
1940         if ( TMath::Abs(pt->fRelativeSector-pt2->fRelativeSector)>0) break;
1941         SignShared(pt,pt2);
1942       }
1943     }  
1944   }
1945 }
1946
1947 void  AliTPCtrackerMI::RemoveDouble(TObjArray * arr, Float_t factor1, Float_t factor2,  Int_t removalindex)
1948 {
1949   //
1950   //sort trackss according sectors
1951   //
1952   if (fDebug&1) {
1953     printf("Number of tracks before double removal- %d\n",arr->GetEntries());
1954   }
1955   //
1956   for (Int_t i=0; i<arr->GetEntriesFast(); i++) {
1957     AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);    
1958     if (!pt) continue;
1959     pt->fSort = 0;
1960   }
1961   arr->UnSort();
1962   arr->Sort();  // sorting according z
1963   arr->Expand(arr->GetEntries());
1964   //
1965   //reset overlap labels
1966   //
1967   Int_t nseed=arr->GetEntriesFast();
1968   for (Int_t i=0; i<nseed; i++) {
1969     AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);    
1970     if (!pt) continue;
1971     pt->SetUniqueID(i);
1972     for (Int_t j=0;j<=12;j++){
1973       pt->fOverlapLabels[j] =0;
1974     }
1975   }
1976   //
1977   //sign shared tracks
1978   for (Int_t i=0; i<nseed; i++) {
1979     AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);    
1980     if (!pt) continue;
1981     if (pt->fRemoval>10) continue;
1982     Float_t deltac = pt->GetC()*0.1;
1983     for (Int_t j=i+1; j<nseed; j++){
1984       AliTPCseed *pt2=(AliTPCseed*)arr->UncheckedAt(j);
1985       //      if (pt2){
1986       if (pt2->fRemoval<=10) {
1987         if ( TMath::Abs(pt->fRelativeSector-pt2->fRelativeSector)>0) break;
1988         if (TMath::Abs(pt->GetC()  -pt2->GetC())>deltac) continue;
1989         if (TMath::Abs(pt->GetTgl()-pt2->GetTgl())>0.05) continue;
1990         //
1991         SignShared(pt,pt2);
1992       }
1993     }
1994   }
1995   //
1996   // remove highly shared tracks
1997   for (Int_t i=0; i<nseed; i++) {
1998     AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);    
1999     if (!pt) continue;
2000     if (pt->fRemoval>10) continue;
2001     //
2002     Int_t sumshared =0;
2003     for (Int_t j=0;j<4;j++){
2004       sumshared = pt->fOverlapLabels[j*3+1];      
2005     }
2006     Float_t factor = factor1;
2007     if (pt->fRemoval>0) factor = factor2;
2008     if (sumshared/pt->GetNumberOfClusters()>factor){
2009       for (Int_t j=0;j<4;j++){
2010         if (pt->fOverlapLabels[3*j]==0) continue;
2011         if (pt->fOverlapLabels[3*j+1]<5) continue; 
2012         if (pt->fRemoval==removalindex) continue;      
2013         AliTPCseed * pt2 = (AliTPCseed*)arr->UncheckedAt(pt->fOverlapLabels[3*j+2]);
2014         if (!pt2) continue;
2015         if (pt2->GetSigma2C()<pt->GetSigma2C()){
2016           //      pt->fRemoval = removalindex;
2017           delete arr->RemoveAt(i);        
2018           break;
2019         }
2020       }      
2021     }
2022   }
2023   arr->Compress();
2024   if (fDebug&1) {
2025     printf("Number of tracks after double removal- %d\n",arr->GetEntries());
2026   }
2027 }
2028
2029
2030
2031
2032
2033
2034 void AliTPCtrackerMI::SortTracks(TObjArray * arr, Int_t mode)
2035 {
2036   //
2037   //sort tracks in array according mode criteria
2038   Int_t nseed = arr->GetEntriesFast();    
2039   for (Int_t i=0; i<nseed; i++) {
2040     AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);    
2041     if (!pt) {
2042       continue;
2043     }
2044     pt->fSort = mode;
2045   }
2046   arr->UnSort();
2047   arr->Sort();
2048 }
2049
2050 void AliTPCtrackerMI::RemoveUsed(TObjArray * arr, Float_t factor1,  Float_t factor2, Int_t removalindex)
2051 {
2052
2053   //Loop over all tracks and remove "overlaps"
2054   //
2055   //
2056   Int_t nseed = arr->GetEntriesFast();  
2057   Int_t good =0;
2058
2059   for (Int_t i=0; i<nseed; i++) {
2060     AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);    
2061     if (!pt) {
2062       delete arr->RemoveAt(i);
2063     }
2064     else{
2065       pt->fSort =1;
2066       pt->fBSigned = kFALSE;
2067     }
2068   }
2069   arr->Compress();
2070   nseed = arr->GetEntriesFast();
2071   arr->UnSort();
2072   arr->Sort();
2073   //
2074   //unsign used
2075   UnsignClusters();
2076   //
2077   for (Int_t i=0; i<nseed; i++) {
2078     AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);    
2079     if (!pt) {
2080       continue;
2081     }    
2082     Int_t found,foundable,shared;
2083     if (pt->IsActive()) 
2084       pt->GetClusterStatistic(0,160,found, foundable,shared,kFALSE);
2085     else
2086       pt->GetClusterStatistic(0,160,found, foundable,shared,kTRUE); 
2087     //
2088     Double_t factor = factor2;
2089     if (pt->fBConstrain) factor = factor1;
2090
2091     if ((Float_t(shared)/Float_t(found))>factor){
2092       pt->Desactivate(removalindex);
2093       continue;
2094     }
2095
2096     good++;
2097     for (Int_t i=0; i<160; i++) {
2098       Int_t index=pt->GetClusterIndex2(i);
2099       if (index<0 || index&0x8000 ) continue;
2100       AliTPCclusterMI *c= pt->fClusterPointer[i];        
2101       if (!c) continue;
2102       //      if (!c->IsUsed(10)) c->Use(10);
2103       //if (pt->IsActive()) 
2104       c->Use(10);  
2105       //else
2106       //        c->Use(5);
2107     }
2108     
2109   }
2110   fNtracks = good;
2111
2112   printf("\n*****\nNumber of good tracks after shared removal\t%d\n",fNtracks);
2113 }
2114
2115 void AliTPCtrackerMI::UnsignClusters() 
2116 {
2117   //
2118   // loop over all clusters and unsign them
2119   //
2120   
2121   for (Int_t sec=0;sec<fkNIS;sec++){
2122     for (Int_t row=0;row<fInnerSec->GetNRows();row++){
2123       AliTPCclusterMI *cl = fInnerSec[sec][row].fClusters1;
2124       for (Int_t icl =0;icl< fInnerSec[sec][row].fN1;icl++)
2125         //      if (cl[icl].IsUsed(10))         
2126         cl[icl].Use(-1);
2127       cl = fInnerSec[sec][row].fClusters2;
2128       for (Int_t icl =0;icl< fInnerSec[sec][row].fN2;icl++)
2129         //if (cl[icl].IsUsed(10))       
2130           cl[icl].Use(-1);      
2131     }
2132   }
2133   
2134   for (Int_t sec=0;sec<fkNOS;sec++){
2135     for (Int_t row=0;row<fOuterSec->GetNRows();row++){
2136       AliTPCclusterMI *cl = fOuterSec[sec][row].fClusters1;
2137       for (Int_t icl =0;icl< fOuterSec[sec][row].fN1;icl++)
2138         //if (cl[icl].IsUsed(10))       
2139           cl[icl].Use(-1);
2140       cl = fOuterSec[sec][row].fClusters2;
2141       for (Int_t icl =0;icl< fOuterSec[sec][row].fN2;icl++)
2142         //if (cl[icl].IsUsed(10))       
2143         cl[icl].Use(-1);      
2144     }
2145   }
2146   
2147 }
2148
2149
2150
2151 void AliTPCtrackerMI::SignClusters(TObjArray * arr, Float_t fnumber, Float_t fdensity)
2152 {
2153   //
2154   //sign clusters to be "used"
2155   //
2156   // snumber and sdensity sign number of sigmas - bellow mean value to be accepted
2157   // loop over "primaries"
2158   
2159   Float_t sumdens=0;
2160   Float_t sumdens2=0;
2161   Float_t sumn   =0;
2162   Float_t sumn2  =0;
2163   Float_t sumchi =0;
2164   Float_t sumchi2 =0;
2165
2166   Float_t sum    =0;
2167
2168   TStopwatch timer;
2169   timer.Start();
2170
2171   Int_t nseed = arr->GetEntriesFast();
2172   for (Int_t i=0; i<nseed; i++) {
2173     AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);    
2174     if (!pt) {
2175       continue;
2176     }    
2177     if (!(pt->IsActive())) continue;
2178     Float_t dens = pt->GetNumberOfClusters()/Float_t(pt->fNFoundable);
2179     if ( (dens>0.7) && (pt->GetNumberOfClusters()>70)){
2180       sumdens += dens;
2181       sumdens2+= dens*dens;
2182       sumn    += pt->GetNumberOfClusters();
2183       sumn2   += pt->GetNumberOfClusters()*pt->GetNumberOfClusters();
2184       Float_t chi2 = pt->GetChi2()/pt->GetNumberOfClusters();
2185       if (chi2>5) chi2=5;
2186       sumchi  +=chi2;
2187       sumchi2 +=chi2*chi2;
2188       sum++;
2189     }
2190   }
2191
2192   Float_t mdensity = 0.9;
2193   Float_t meann    = 130;
2194   Float_t meanchi  = 1;
2195   Float_t sdensity = 0.1;
2196   Float_t smeann    = 10;
2197   Float_t smeanchi  =0.4;
2198   
2199
2200   if (sum>20){
2201     mdensity = sumdens/sum;
2202     meann    = sumn/sum;
2203     meanchi  = sumchi/sum;
2204     //
2205     sdensity = sumdens2/sum-mdensity*mdensity;
2206     sdensity = TMath::Sqrt(sdensity);
2207     //
2208     smeann   = sumn2/sum-meann*meann;
2209     smeann   = TMath::Sqrt(smeann);
2210     //
2211     smeanchi = sumchi2/sum - meanchi*meanchi;
2212     smeanchi = TMath::Sqrt(smeanchi);
2213   }
2214
2215
2216   //REMOVE  SHORT DELTAS or tracks going out of sensitive volume of TPC
2217   //
2218   for (Int_t i=0; i<nseed; i++) {
2219     AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);    
2220     if (!pt) {
2221       continue;
2222     }
2223     if (pt->fBSigned) continue;
2224     if (pt->fBConstrain) continue;    
2225     //if (!(pt->IsActive())) continue;
2226     /*
2227     Int_t found,foundable,shared;    
2228     pt->GetClusterStatistic(0,160,found, foundable,shared);
2229     if (shared/float(found)>0.3) {
2230       if (shared/float(found)>0.9 ){
2231         //delete arr->RemoveAt(i);
2232       }
2233       continue;
2234     }
2235     */
2236     Bool_t isok =kFALSE;
2237     if ( (pt->fNShared/pt->GetNumberOfClusters()<0.5) &&pt->GetNumberOfClusters()>60)
2238       isok = kTRUE;
2239     if ((TMath::Abs(1/pt->GetC())<100.) && (pt->fNShared/pt->GetNumberOfClusters()<0.7))
2240       isok =kTRUE;
2241     if  (TMath::Abs(pt->GetZ()/pt->GetX())>1.1)
2242       isok =kTRUE;
2243     if ( (TMath::Abs(pt->GetSnp()>0.7) && pt->GetD(0,0)>60.))
2244       isok =kTRUE;
2245     
2246     if (isok)     
2247       for (Int_t i=0; i<160; i++) {     
2248         Int_t index=pt->GetClusterIndex2(i);
2249         if (index<0) continue;
2250         AliTPCclusterMI *c= pt->fClusterPointer[i];
2251         if (!c) continue;
2252         //if (!(c->IsUsed(10))) c->Use();  
2253         c->Use(10);  
2254       }
2255   }
2256   
2257   
2258   //
2259   Double_t maxchi  = meanchi+2.*smeanchi;
2260
2261   for (Int_t i=0; i<nseed; i++) {
2262     AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);    
2263     if (!pt) {
2264       continue;
2265     }    
2266     //if (!(pt->IsActive())) continue;
2267     if (pt->fBSigned) continue;
2268     Double_t chi     = pt->GetChi2()/pt->GetNumberOfClusters();
2269     if (chi>maxchi) continue;
2270
2271     Float_t bfactor=1;
2272     Float_t dens = pt->GetNumberOfClusters()/Float_t(pt->fNFoundable);
2273    
2274     //sign only tracks with enoug big density at the beginning
2275     
2276     if ((pt->GetDensityFirst(40)<0.75) && pt->GetNumberOfClusters()<meann) continue; 
2277     
2278     
2279     Double_t mindens = TMath::Max(double(mdensity-sdensity*fdensity*bfactor),0.65);
2280     Double_t minn    = TMath::Max(Int_t(meann-fnumber*smeann*bfactor),50);
2281    
2282     //    if (pt->fBConstrain) mindens = TMath::Max(mdensity-sdensity*fdensity*bfactor,0.65);
2283     if ( (pt->fRemoval==10) && (pt->GetSnp()>0.8)&&(dens>mindens))
2284       minn=0;
2285
2286     if ((dens>mindens && pt->GetNumberOfClusters()>minn) && chi<maxchi ){
2287       //Int_t noc=pt->GetNumberOfClusters();
2288       pt->fBSigned = kTRUE;
2289       for (Int_t i=0; i<160; i++) {
2290
2291         Int_t index=pt->GetClusterIndex2(i);
2292         if (index<0) continue;
2293         AliTPCclusterMI *c= pt->fClusterPointer[i];
2294         if (!c) continue;
2295         //      if (!(c->IsUsed(10))) c->Use();  
2296         c->Use(10);  
2297       }
2298     }
2299   }
2300   //  gLastCheck = nseed;
2301   //  arr->Compress();
2302   if (fDebug>0){
2303     timer.Print();
2304   }
2305 }
2306
2307
2308 void  AliTPCtrackerMI::StopNotActive(TObjArray * arr, Int_t row0, Float_t th0, Float_t th1, Float_t th2)
2309 {
2310   // stop not active tracks
2311   // take th1 as threshold for number of founded to number of foundable on last 10 active rows
2312   // take th2 as threshold for number of founded to number of foundable on last 20 active rows 
2313   Int_t nseed = arr->GetEntriesFast();  
2314   //
2315   for (Int_t i=0; i<nseed; i++) {
2316     AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i);    
2317     if (!pt) {
2318       continue;
2319     }
2320     if (!(pt->IsActive())) continue;
2321     StopNotActive(pt,row0,th0, th1,th2);
2322   }
2323 }
2324
2325
2326
2327 void  AliTPCtrackerMI::StopNotActive(AliTPCseed * seed, Int_t row0, Float_t th0, Float_t th1,
2328  Float_t th2)
2329 {
2330   // stop not active tracks
2331   // take th1 as threshold for number of founded to number of foundable on last 10 active rows
2332   // take th2 as threshold for number of founded to number of foundable on last 20 active rows 
2333   Int_t sumgood1  = 0;
2334   Int_t sumgood2  = 0;
2335   Int_t foundable = 0;
2336   Int_t maxindex = seed->fLastPoint;  //last foundable row
2337   if (seed->fNFoundable*th0 > seed->GetNumberOfClusters()) {
2338     seed->Desactivate(10) ;
2339     return;
2340   }
2341
2342   for (Int_t i=row0; i<maxindex; i++){
2343     Int_t index = seed->GetClusterIndex2(i);
2344     if (index!=-1) foundable++;
2345     //if (!c) continue;
2346     if (foundable<=30) sumgood1++;
2347     if (foundable<=50) {
2348       sumgood2++;
2349     }
2350     else{ 
2351       break;
2352     }        
2353   }
2354   if (foundable>=30.){ 
2355      if (sumgood1<(th1*30.)) seed->Desactivate(10);
2356   }
2357   if (foundable>=50)
2358     if (sumgood2<(th2*50.)) seed->Desactivate(10);
2359 }
2360
2361
2362
2363 Int_t AliTPCtrackerMI::PropagateBack(AliESD *event)
2364 {
2365   //
2366   // back propagation of ESD tracks
2367   //
2368
2369   fEvent = event;
2370   ReadSeeds(event);
2371   PropagateBack(fSeeds);
2372   Int_t nseed = fSeeds->GetEntriesFast();
2373   for (Int_t i=0;i<nseed;i++){
2374     AliTPCseed * seed = (AliTPCseed*) fSeeds->UncheckedAt(i);
2375     AliESDtrack *esd=event->GetTrack(i);
2376     seed->CookdEdx(0.02,0.06);
2377     CookLabel(seed,0.1); //For comparison only
2378     esd->UpdateTrackParams(seed,AliESDtrack::kTPCout);
2379   }
2380   fEvent =0;
2381   WriteTracks();
2382   return 0;
2383 }
2384
2385
2386 void AliTPCtrackerMI::DeleteSeeds()
2387 {
2388   Int_t nseed = fSeeds->GetEntriesFast();
2389   for (Int_t i=0;i<nseed;i++){
2390     AliTPCseed * seed = (AliTPCseed*)fSeeds->At(i);
2391     if (seed) delete fSeeds->RemoveAt(i);
2392   }
2393   delete fSeeds;
2394   fSeeds =0;
2395 }
2396
2397 void AliTPCtrackerMI::ReadSeeds(AliESD *event)
2398 {
2399   //
2400   //read seeds from the event
2401   
2402   Int_t nentr=event->GetNumberOfTracks();
2403   Info("PropagateBack", "Number of ESD tracks: %d\n", nentr);
2404   if (fSeeds) 
2405     DeleteSeeds();
2406   if (!fSeeds){   
2407     fSeeds = new TObjArray;
2408   }
2409   
2410   //  Int_t ntrk=0;
2411   for (Int_t i=0; i<nentr; i++) {
2412     AliESDtrack *esd=event->GetTrack(i);
2413     ULong_t status=esd->GetStatus();    
2414     const AliTPCtrack t(*esd);
2415     AliTPCseed *seed = new AliTPCseed(t,t.GetAlpha());
2416     if (status==AliESDtrack::kTPCin) seed->Modify(0.8);
2417     //
2418     //
2419     // rotate to the local coordinate system
2420    
2421     fSectors=fInnerSec; fN=fkNIS;
2422     
2423     Double_t alpha=seed->GetAlpha() - fSectors->GetAlphaShift();
2424     if (alpha > 2.*TMath::Pi()) alpha -= 2.*TMath::Pi();
2425     if (alpha < 0.            ) alpha += 2.*TMath::Pi();
2426     Int_t ns=Int_t(alpha/fSectors->GetAlpha())%fN;
2427     alpha =ns*fSectors->GetAlpha() + fSectors->GetAlphaShift();
2428     alpha-=seed->GetAlpha();  
2429     if (!seed->Rotate(alpha)) continue;
2430     //
2431     seed->PropagateTo(fSectors->GetX(0));
2432     //
2433     //    Int_t index = esd->GetTPCindex();
2434     //AliTPCseed * seed2= (AliTPCseed*)fSeeds->At(index);
2435     
2436     fSeeds->AddLast(seed);
2437   }
2438 }
2439
2440
2441
2442 //_____________________________________________________________________________
2443 void AliTPCtrackerMI::MakeSeeds3(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2,  Float_t cuts[4],
2444                                  Float_t deltay, Int_t ddsec) {
2445   //-----------------------------------------------------------------
2446   // This function creates track seeds.
2447   // SEEDING WITH VERTEX CONSTRAIN 
2448   //-----------------------------------------------------------------
2449   // cuts[0]   - fP4 cut
2450   // cuts[1]   - tan(phi)  cut
2451   // cuts[2]   - zvertex cut
2452   // cuts[3]   - fP3 cut
2453   Int_t nin0  = 0;
2454   Int_t nin1  = 0;
2455   Int_t nin2  = 0;
2456   Int_t nin   = 0;
2457   Int_t nout1 = 0;
2458   Int_t nout2 = 0;
2459
2460   Double_t x[5], c[15];
2461   //  Int_t di = i1-i2;
2462   //
2463   AliTPCseed * seed = new AliTPCseed;
2464   Double_t alpha=fSectors->GetAlpha(), shift=fSectors->GetAlphaShift();
2465   Double_t cs=cos(alpha), sn=sin(alpha);
2466   //
2467   //  Double_t x1 =fOuterSec->GetX(i1);
2468   //Double_t xx2=fOuterSec->GetX(i2);
2469   
2470   Double_t x1 =GetXrow(i1);
2471   Double_t xx2=GetXrow(i2);
2472
2473   Double_t x3=GetX(), y3=GetY(), z3=GetZ();
2474
2475   Int_t imiddle = (i2+i1)/2;    //middle pad row index
2476   Double_t xm = GetXrow(imiddle); // radius of middle pad-row
2477   const AliTPCRow& krm=GetRow(sec,imiddle); //middle pad -row
2478   //
2479   Int_t ns =sec;   
2480
2481   const AliTPCRow& kr1=GetRow(ns,i1);
2482   Double_t ymax  = GetMaxY(i1)-kr1.fDeadZone-1.5;  
2483   Double_t ymaxm = GetMaxY(imiddle)-kr1.fDeadZone-1.5;  
2484
2485   //
2486   // change cut on curvature if it can't reach this layer
2487   // maximal curvature set to reach it
2488   Double_t dvertexmax  = TMath::Sqrt((x1-x3)*(x1-x3)+(ymax+5-y3)*(ymax+5-y3));
2489   if (dvertexmax*0.5*cuts[0]>0.85){
2490     cuts[0] = 0.85/(dvertexmax*0.5+1.);
2491   }
2492   Double_t r2min = 1/(cuts[0]*cuts[0]);  //minimal square of radius given by cut
2493
2494   //  Int_t ddsec = 1;
2495   if (deltay>0) ddsec = 0; 
2496   // loop over clusters  
2497   for (Int_t is=0; is < kr1; is++) {
2498     //
2499     if (kr1[is]->IsUsed(10)) continue;
2500     Double_t y1=kr1[is]->GetY(), z1=kr1[is]->GetZ();    
2501     //if (TMath::Abs(y1)>ymax) continue;
2502
2503     if (deltay>0 && TMath::Abs(ymax-TMath::Abs(y1))> deltay ) continue;  // seed only at the edge
2504
2505     // find possible directions    
2506     Float_t anglez = (z1-z3)/(x1-x3); 
2507     Float_t extraz = z1 - anglez*(x1-xx2);  // extrapolated z      
2508     //
2509     //
2510     //find   rotation angles relative to line given by vertex and point 1
2511     Double_t dvertex2 = (x1-x3)*(x1-x3)+(y1-y3)*(y1-y3);
2512     Double_t dvertex  = TMath::Sqrt(dvertex2);
2513     Double_t angle13  = TMath::ATan((y1-y3)/(x1-x3));
2514     Double_t cs13     = cos(-angle13), sn13 = sin(-angle13);            
2515     
2516     //
2517     // loop over 2 sectors
2518     Int_t dsec1=-ddsec;
2519     Int_t dsec2= ddsec;
2520     if (y1<0)  dsec2= 0;
2521     if (y1>0)  dsec1= 0;
2522     
2523     Double_t dddz1=0;  // direction of delta inclination in z axis
2524     Double_t dddz2=0;
2525     if ( (z1-z3)>0)
2526       dddz1 =1;    
2527     else
2528       dddz2 =1;
2529     //
2530     for (Int_t dsec = dsec1; dsec<=dsec2;dsec++){
2531       Int_t sec2 = sec + dsec;
2532       // 
2533       //      AliTPCRow&  kr2  = fOuterSec[(sec2+fkNOS)%fkNOS][i2];
2534       //AliTPCRow&  kr2m = fOuterSec[(sec2+fkNOS)%fkNOS][imiddle];
2535       AliTPCRow&  kr2  = GetRow((sec2+fkNOS)%fkNOS,i2);
2536       AliTPCRow&  kr2m = GetRow((sec2+fkNOS)%fkNOS,imiddle);
2537       Int_t  index1 = TMath::Max(kr2.Find(extraz-0.6-dddz1*TMath::Abs(z1)*0.05)-1,0);
2538       Int_t  index2 = TMath::Min(kr2.Find(extraz+0.6+dddz2*TMath::Abs(z1)*0.05)+1,kr2);
2539
2540       // rotation angles to p1-p3
2541       Double_t cs13r     = cos(-angle13+dsec*alpha)/dvertex, sn13r = sin(-angle13+dsec*alpha)/dvertex;            
2542       Double_t x2,   y2,   z2; 
2543       //
2544       //      Double_t dymax = maxangle*TMath::Abs(x1-xx2);
2545
2546       //
2547       Double_t dxx0 =  (xx2-x3)*cs13r;
2548       Double_t dyy0 =  (xx2-x3)*sn13r;
2549       for (Int_t js=index1; js < index2; js++) {
2550         const AliTPCclusterMI *kcl = kr2[js];
2551         if (kcl->IsUsed(10)) continue;  
2552         //
2553         //calcutate parameters
2554         //      
2555         Double_t yy0 =  dyy0 +(kcl->GetY()-y3)*cs13r;
2556         // stright track
2557         if (TMath::Abs(yy0)<0.000001) continue;
2558         Double_t xx0 =  dxx0 -(kcl->GetY()-y3)*sn13r;
2559         Double_t y0  =  0.5*(xx0*xx0+yy0*yy0-xx0)/yy0;
2560         Double_t r02 = (0.25+y0*y0)*dvertex2;   
2561         //curvature (radius) cut
2562         if (r02<r2min) continue;                
2563        
2564         nin0++; 
2565         //
2566         Double_t c0  = 1/TMath::Sqrt(r02);
2567         if (yy0>0) c0*=-1.;     
2568                
2569        
2570         //Double_t dfi0   = 2.*TMath::ASin(dvertex*c0*0.5);
2571         //Double_t dfi1   = 2.*TMath::ASin(TMath::Sqrt(yy0*yy0+(1-xx0)*(1-xx0))*dvertex*c0*0.5);
2572         Double_t dfi0   = 2.*TPCFastMath::FastAsin(dvertex*c0*0.5);
2573         Double_t dfi1   = 2.*TPCFastMath::FastAsin(TMath::Sqrt(yy0*yy0+(1-xx0)*(1-xx0))*dvertex*c0*0.5);  
2574         //
2575         //
2576         Double_t z0  =  kcl->GetZ();  
2577         Double_t zzzz2    = z1-(z1-z3)*dfi1/dfi0;
2578         if (TMath::Abs(zzzz2-z0)>0.5) continue;       
2579         nin1++;              
2580         //      
2581         Double_t dip    = (z1-z0)*c0/dfi1;        
2582         Double_t x0 = (0.5*cs13+y0*sn13)*dvertex*c0;
2583         //
2584         y2 = kcl->GetY(); 
2585         if (dsec==0){
2586           x2 = xx2; 
2587           z2 = kcl->GetZ();       
2588         }
2589         else
2590           {
2591             // rotation 
2592             z2 = kcl->GetZ();  
2593             x2= xx2*cs-y2*sn*dsec;
2594             y2=+xx2*sn*dsec+y2*cs;
2595           }
2596         
2597         x[0] = y1;
2598         x[1] = z1;
2599         x[2] = x0;
2600         x[3] = dip;
2601         x[4] = c0;
2602         //
2603         //
2604         // do we have cluster at the middle ?
2605         Double_t ym,zm;
2606         GetProlongation(x1,xm,x,ym,zm);
2607         UInt_t dummy; 
2608         AliTPCclusterMI * cm=0;
2609         if (TMath::Abs(ym)-ymaxm<0){      
2610           cm = krm.FindNearest2(ym,zm,1.0,0.6,dummy);
2611           if ((!cm) || (cm->IsUsed(10))) {        
2612             continue;
2613           }
2614         }
2615         else{     
2616           // rotate y1 to system 0
2617           // get state vector in rotated system 
2618           Double_t yr1  = (-0.5*sn13+y0*cs13)*dvertex*c0;
2619           Double_t xr2  =  x0*cs+yr1*sn*dsec;
2620           Double_t xr[5]={kcl->GetY(),kcl->GetZ(), xr2, dip, c0};
2621           //
2622           GetProlongation(xx2,xm,xr,ym,zm);
2623           if (TMath::Abs(ym)-ymaxm<0){
2624             cm = kr2m.FindNearest2(ym,zm,1.0,0.6,dummy);
2625             if ((!cm) || (cm->IsUsed(10))) {      
2626               continue;
2627             }
2628           }
2629         }
2630        
2631
2632         Double_t dym = 0;
2633         Double_t dzm = 0;
2634         if (cm){
2635           dym = ym - cm->GetY();
2636           dzm = zm - cm->GetZ();
2637         }
2638         nin2++;
2639
2640
2641         //
2642         //
2643         Double_t sy1=kr1[is]->GetSigmaY2()*2., sz1=kr1[is]->GetSigmaZ2()*2.;
2644         Double_t sy2=kcl->GetSigmaY2()*2.,     sz2=kcl->GetSigmaZ2()*2.;
2645         //Double_t sy3=400*3./12., sy=0.1, sz=0.1;
2646         Double_t sy3=25000*x[4]*x[4]+0.1, sy=0.1, sz=0.1;
2647         //Double_t sy3=25000*x[4]*x[4]*60+0.5, sy=0.1, sz=0.1;
2648
2649         Double_t f40=(f1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
2650         Double_t f42=(f1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
2651         Double_t f43=(f1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
2652         Double_t f20=(f2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
2653         Double_t f22=(f2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
2654         Double_t f23=(f2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
2655         
2656         Double_t f30=(f3(x1,y1+sy,x2,y2,z1,z2)-x[3])/sy;
2657         Double_t f31=(f3(x1,y1,x2,y2,z1+sz,z2)-x[3])/sz;
2658         Double_t f32=(f3(x1,y1,x2,y2+sy,z1,z2)-x[3])/sy;
2659         Double_t f34=(f3(x1,y1,x2,y2,z1,z2+sz)-x[3])/sz;
2660         
2661         c[0]=sy1;
2662         c[1]=0.;       c[2]=sz1;
2663         c[3]=f20*sy1;  c[4]=0.;       c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
2664         c[6]=f30*sy1;  c[7]=f31*sz1;  c[8]=f30*sy1*f20+f32*sy2*f22;
2665                        c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
2666         c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
2667         c[13]=f30*sy1*f40+f32*sy2*f42;
2668         c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
2669         
2670         //      if (!BuildSeed(kr1[is],kcl,0,x1,x2,x3,x,c)) continue;
2671         
2672         UInt_t index=kr1.GetIndex(is);
2673         AliTPCseed *track=new(seed) AliTPCseed(index, x, c, x1, ns*alpha+shift);
2674         
2675         track->fIsSeeding = kTRUE;
2676         track->fSeed1 = i1;
2677         track->fSeed2 = i2;
2678         track->fSeedType=3;
2679
2680        
2681         //if (dsec==0) {
2682           FollowProlongation(*track, (i1+i2)/2,1);
2683           Int_t foundable,found,shared;
2684           track->GetClusterStatistic((i1+i2)/2,i1, found, foundable, shared, kTRUE);
2685           if ((found<0.55*foundable)  || shared>0.5*found || (track->GetSigmaY2()+track->GetSigmaZ2())>0.5){
2686             seed->Reset();
2687             seed->~AliTPCseed();
2688             continue;
2689           }
2690           //}
2691         
2692         nin++;
2693         FollowProlongation(*track, i2,1);
2694         
2695         
2696         //Int_t rc = 1;
2697         track->fBConstrain =1;
2698         //      track->fLastPoint = i1+fInnerSec->GetNRows();  // first cluster in track position
2699         track->fLastPoint = i1;  // first cluster in track position
2700         track->fFirstPoint = track->fLastPoint;
2701         
2702         if (track->GetNumberOfClusters()<(i1-i2)*0.5 || 
2703             track->GetNumberOfClusters() < track->fNFoundable*0.6 || 
2704             track->fNShared>0.4*track->GetNumberOfClusters() ) {
2705           seed->Reset();
2706           seed->~AliTPCseed();
2707           continue;
2708         }
2709         nout1++;
2710         // Z VERTEX CONDITION
2711         Double_t zv;
2712         zv = track->GetZ()+track->GetTgl()/track->GetC()*
2713           ( asin(-track->GetEta()) - asin(track->GetX()*track->GetC()-track->GetEta()));
2714         if (TMath::Abs(zv-z3)>cuts[2]) {
2715           FollowProlongation(*track, TMath::Max(i2-20,0));
2716           zv = track->GetZ()+track->GetTgl()/track->GetC()*
2717             ( asin(-track->GetEta()) - asin(track->GetX()*track->GetC()-track->GetEta()));
2718           if (TMath::Abs(zv-z3)>cuts[2]){
2719             FollowProlongation(*track, TMath::Max(i2-40,0));
2720             zv = track->GetZ()+track->GetTgl()/track->GetC()*
2721               ( asin(-track->GetEta()) - asin(track->GetX()*track->GetC()-track->GetEta()));
2722             if (TMath::Abs(zv-z3)>cuts[2] &&(track->GetNumberOfClusters() > track->fNFoundable*0.7)){
2723               // make seed without constrain
2724               AliTPCseed * track2 = MakeSeed(track,0.2,0.5,1.);
2725               FollowProlongation(*track2, i2,1);
2726               track2->fBConstrain = kFALSE;
2727               track2->fSeedType = 1;
2728               arr->AddLast(track2); 
2729               seed->Reset();
2730               seed->~AliTPCseed();
2731               continue;         
2732             }
2733             else{
2734               seed->Reset();
2735               seed->~AliTPCseed();
2736               continue;
2737             
2738             }
2739           }
2740         }
2741         
2742         track->fSeedType =0;
2743         arr->AddLast(track); 
2744         seed = new AliTPCseed;  
2745         nout2++;
2746         // don't consider other combinations
2747         if (track->GetNumberOfClusters() > track->fNFoundable*0.8)
2748           break;
2749       }
2750     }
2751   }
2752   if (fDebug>1){
2753     //    printf("\nSeeding statiistic:\t%d\t%d\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin,nout1,nout2);
2754   }
2755   delete seed;
2756 }
2757
2758
2759 void AliTPCtrackerMI::MakeSeeds5(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2,  Float_t cuts[4],
2760                                  Float_t deltay) {
2761   
2762
2763
2764   //-----------------------------------------------------------------
2765   // This function creates track seeds.
2766   //-----------------------------------------------------------------
2767   // cuts[0]   - fP4 cut
2768   // cuts[1]   - tan(phi)  cut
2769   // cuts[2]   - zvertex cut
2770   // cuts[3]   - fP3 cut
2771
2772
2773   Int_t nin0  = 0;
2774   Int_t nin1  = 0;
2775   Int_t nin2  = 0;
2776   Int_t nin   = 0;
2777   Int_t nout1 = 0;
2778   Int_t nout2 = 0;
2779   Int_t nout3 =0;
2780   Double_t x[5], c[15];
2781   //
2782   // make temporary seed
2783   AliTPCseed * seed = new AliTPCseed;
2784   Double_t alpha=fOuterSec->GetAlpha(), shift=fOuterSec->GetAlphaShift();
2785   //  Double_t cs=cos(alpha), sn=sin(alpha);
2786   //
2787   //
2788
2789   // first 3 padrows
2790   Double_t x1 = GetXrow(i1-1);
2791   const    AliTPCRow& kr1=GetRow(sec,i1-1);
2792   Double_t y1max  = GetMaxY(i1-1)-kr1.fDeadZone-1.5;  
2793   //
2794   Double_t x1p = GetXrow(i1);
2795   const    AliTPCRow& kr1p=GetRow(sec,i1);
2796   //
2797   Double_t x1m = GetXrow(i1-2);
2798   const    AliTPCRow& kr1m=GetRow(sec,i1-2);
2799
2800   //
2801   //last 3 padrow for seeding
2802   AliTPCRow&  kr3  = GetRow((sec+fkNOS)%fkNOS,i1-7);
2803   Double_t    x3   =  GetXrow(i1-7);
2804   //  Double_t    y3max= GetMaxY(i1-7)-kr3.fDeadZone-1.5;  
2805   //
2806   AliTPCRow&  kr3p  = GetRow((sec+fkNOS)%fkNOS,i1-6);
2807   Double_t    x3p   = GetXrow(i1-6);
2808   //
2809   AliTPCRow&  kr3m  = GetRow((sec+fkNOS)%fkNOS,i1-8);
2810   Double_t    x3m   = GetXrow(i1-8);
2811
2812   //
2813   //
2814   // middle padrow
2815   Int_t im = i1-4;                           //middle pad row index
2816   Double_t xm         = GetXrow(im);         // radius of middle pad-row
2817   const AliTPCRow& krm=GetRow(sec,im);   //middle pad -row
2818   //  Double_t ymmax = GetMaxY(im)-kr1.fDeadZone-1.5;  
2819   //
2820   //
2821   Double_t deltax  = x1-x3;
2822   Double_t dymax   = deltax*cuts[1];
2823   Double_t dzmax   = deltax*cuts[3];
2824   //
2825   // loop over clusters  
2826   for (Int_t is=0; is < kr1; is++) {
2827     //
2828     if (kr1[is]->IsUsed(10)) continue;
2829     Double_t y1=kr1[is]->GetY(), z1=kr1[is]->GetZ();    
2830     //
2831     if (deltay>0 && TMath::Abs(y1max-TMath::Abs(y1))> deltay ) continue;  // seed only at the edge    
2832     // 
2833     Int_t  index1 = TMath::Max(kr3.Find(z1-dzmax)-1,0);
2834     Int_t  index2 = TMath::Min(kr3.Find(z1+dzmax)+1,kr3);
2835     //    
2836     Double_t y3,   z3;
2837     //
2838     //
2839     UInt_t index;
2840     for (Int_t js=index1; js < index2; js++) {
2841       const AliTPCclusterMI *kcl = kr3[js];
2842       if (kcl->IsUsed(10)) continue;
2843       y3 = kcl->GetY(); 
2844       // apply angular cuts
2845       if (TMath::Abs(y1-y3)>dymax) continue;
2846       x3 = x3; 
2847       z3 = kcl->GetZ(); 
2848       if (TMath::Abs(z1-z3)>dzmax) continue;
2849       //
2850       Double_t angley = (y1-y3)/(x1-x3);
2851       Double_t anglez = (z1-z3)/(x1-x3);
2852       //
2853       Double_t erry = TMath::Abs(angley)*(x1-x1m)*0.5+0.5;
2854       Double_t errz = TMath::Abs(anglez)*(x1-x1m)*0.5+0.5;
2855       //
2856       Double_t yyym = angley*(xm-x1)+y1;
2857       Double_t zzzm = anglez*(xm-x1)+z1;
2858
2859       const AliTPCclusterMI *kcm = krm.FindNearest2(yyym,zzzm,erry,errz,index);
2860       if (!kcm) continue;
2861       if (kcm->IsUsed(10)) continue;
2862       
2863       erry = TMath::Abs(angley)*(x1-x1m)*0.4+0.5;
2864       errz = TMath::Abs(anglez)*(x1-x1m)*0.4+0.5;
2865       //
2866       //
2867       //
2868       Int_t used  =0;
2869       Int_t found =0;
2870       //
2871       // look around first
2872       const AliTPCclusterMI *kc1m = kr1m.FindNearest2(angley*(x1m-x1)+y1,
2873                                                       anglez*(x1m-x1)+z1,
2874                                                       erry,errz,index);
2875       //
2876       if (kc1m){
2877         found++;
2878         if (kc1m->IsUsed(10)) used++;
2879       }
2880       const AliTPCclusterMI *kc1p = kr1p.FindNearest2(angley*(x1p-x1)+y1,
2881                                                       anglez*(x1p-x1)+z1,
2882                                                       erry,errz,index);
2883       //
2884       if (kc1p){
2885         found++;
2886         if (kc1p->IsUsed(10)) used++;
2887       }
2888       if (used>1)  continue;
2889       if (found<1) continue; 
2890
2891       //
2892       // look around last
2893       const AliTPCclusterMI *kc3m = kr3m.FindNearest2(angley*(x3m-x3)+y3,
2894                                                       anglez*(x3m-x3)+z3,
2895                                                       erry,errz,index);
2896       //
2897       if (kc3m){
2898         found++;
2899         if (kc3m->IsUsed(10)) used++;
2900       }
2901       else 
2902         continue;
2903       const AliTPCclusterMI *kc3p = kr3p.FindNearest2(angley*(x3p-x3)+y3,
2904                                                       anglez*(x3p-x3)+z3,
2905                                                       erry,errz,index);
2906       //
2907       if (kc3p){
2908         found++;
2909         if (kc3p->IsUsed(10)) used++;
2910       }
2911       else 
2912         continue;
2913       if (used>1)  continue;
2914       if (found<3) continue;       
2915       //
2916       Double_t x2,y2,z2;
2917       x2 = xm;
2918       y2 = kcm->GetY();
2919       z2 = kcm->GetZ();
2920       //
2921                         
2922       x[0]=y1;
2923       x[1]=z1;
2924       x[4]=f1(x1,y1,x2,y2,x3,y3);
2925       //if (TMath::Abs(x[4]) >= cuts[0]) continue;
2926       nin0++;
2927       //
2928       x[2]=f2(x1,y1,x2,y2,x3,y3);
2929       nin1++;
2930       //
2931       x[3]=f3n(x1,y1,x2,y2,z1,z2,x[4]);
2932       //if (TMath::Abs(x[3]) > cuts[3]) continue;
2933       nin2++;
2934       //
2935       //
2936       Double_t sy1=0.1,  sz1=0.1;
2937       Double_t sy2=0.1,  sz2=0.1;
2938       Double_t sy3=0.1,  sy=0.1, sz=0.1;
2939       
2940       Double_t f40=(f1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
2941       Double_t f42=(f1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
2942       Double_t f43=(f1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
2943       Double_t f20=(f2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
2944       Double_t f22=(f2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
2945       Double_t f23=(f2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
2946       
2947       Double_t f30=(f3(x1,y1+sy,x2,y2,z1,z2)-x[3])/sy;
2948       Double_t f31=(f3(x1,y1,x2,y2,z1+sz,z2)-x[3])/sz;
2949       Double_t f32=(f3(x1,y1,x2,y2+sy,z1,z2)-x[3])/sy;
2950       Double_t f34=(f3(x1,y1,x2,y2,z1,z2+sz)-x[3])/sz;
2951       
2952       c[0]=sy1;
2953       c[1]=0.;       c[2]=sz1; 
2954       c[3]=f20*sy1;  c[4]=0.;       c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
2955       c[6]=f30*sy1;  c[7]=f31*sz1;  c[8]=f30*sy1*f20+f32*sy2*f22;
2956       c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
2957       c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
2958       c[13]=f30*sy1*f40+f32*sy2*f42;
2959       c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
2960       
2961       //        if (!BuildSeed(kr1[is],kcl,0,x1,x2,x3,x,c)) continue;
2962       
2963       UInt_t index=kr1.GetIndex(is);
2964       AliTPCseed *track=new(seed) AliTPCseed(index, x, c, x1, sec*alpha+shift);
2965       
2966       track->fIsSeeding = kTRUE;
2967
2968       nin++;      
2969       FollowProlongation(*track, i1-7,1);
2970       if (track->GetNumberOfClusters() < track->fNFoundable*0.75 || 
2971           track->fNShared>0.6*track->GetNumberOfClusters() || ( track->GetSigmaY2()+ track->GetSigmaZ2())>0.6){
2972         seed->Reset();
2973         seed->~AliTPCseed();
2974         continue;
2975       }
2976       nout1++;
2977       nout2++;  
2978       //Int_t rc = 1;
2979       FollowProlongation(*track, i2,1);
2980       track->fBConstrain =0;
2981       track->fLastPoint = i1+fInnerSec->GetNRows();  // first cluster in track position
2982       track->fFirstPoint = track->fLastPoint;
2983       
2984       if (track->GetNumberOfClusters()<(i1-i2)*0.5 || 
2985           track->GetNumberOfClusters()<track->fNFoundable*0.7 || 
2986           track->fNShared>2. || track->GetChi2()/track->GetNumberOfClusters()>6 || ( track->GetSigmaY2()+ track->GetSigmaZ2())>0.5 ) {
2987         seed->Reset();
2988         seed->~AliTPCseed();
2989         continue;
2990       }
2991    
2992       {
2993         FollowProlongation(*track, TMath::Max(i2-10,0),1);
2994         AliTPCseed * track2 = MakeSeed(track,0.2,0.5,0.9);
2995         FollowProlongation(*track2, i2,1);
2996         track2->fBConstrain = kFALSE;
2997         track2->fSeedType = 4;
2998         arr->AddLast(track2); 
2999         seed->Reset();
3000         seed->~AliTPCseed();
3001       }
3002       
3003    
3004       //arr->AddLast(track); 
3005       //seed = new AliTPCseed;  
3006       nout3++;
3007     }
3008   }
3009   
3010   if (fDebug>1){
3011     //    printf("\nSeeding statiistic:\t%d\t%d\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin,nout1,nout2,nout3);
3012   }
3013   delete seed;
3014 }
3015
3016
3017 //_____________________________________________________________________________
3018 void AliTPCtrackerMI::MakeSeeds2(TObjArray * arr, Int_t sec, Int_t i1, Int_t i2, Float_t cuts[4],
3019                                  Float_t deltay, Bool_t bconstrain) {
3020   //-----------------------------------------------------------------
3021   // This function creates track seeds - without vertex constraint
3022   //-----------------------------------------------------------------
3023   // cuts[0]   - fP4 cut        - not applied
3024   // cuts[1]   - tan(phi)  cut
3025   // cuts[2]   - zvertex cut    - not applied 
3026   // cuts[3]   - fP3 cut
3027   Int_t nin0=0;
3028   Int_t nin1=0;
3029   Int_t nin2=0;
3030   Int_t nin3=0;
3031   //  Int_t nin4=0;
3032   //Int_t nin5=0;
3033
3034   
3035
3036   Double_t alpha=fOuterSec->GetAlpha(), shift=fOuterSec->GetAlphaShift();
3037   //  Double_t cs=cos(alpha), sn=sin(alpha);
3038   Int_t row0 = (i1+i2)/2;
3039   Int_t drow = (i1-i2)/2;
3040   const AliTPCRow& kr0=fSectors[sec][row0];
3041   AliTPCRow * kr=0;
3042
3043   AliTPCpolyTrack polytrack;
3044   Int_t nclusters=fSectors[sec][row0];
3045   AliTPCseed * seed = new AliTPCseed;
3046
3047   Int_t sumused=0;
3048   Int_t cused=0;
3049   Int_t cnused=0;
3050   for (Int_t is=0; is < nclusters; is++) {  //LOOP over clusters
3051     Int_t nfound =0;
3052     Int_t nfoundable =0;
3053     for (Int_t iter =1; iter<2; iter++){   //iterations
3054       const AliTPCRow& krm=fSectors[sec][row0-iter];
3055       const AliTPCRow& krp=fSectors[sec][row0+iter];      
3056       const AliTPCclusterMI * cl= kr0[is];
3057       
3058       if (cl->IsUsed(10)) {
3059         cused++;
3060       }
3061       else{
3062         cnused++;
3063       }
3064       Double_t x = kr0.GetX();
3065       // Initialization of the polytrack
3066       nfound =0;
3067       nfoundable =0;
3068       polytrack.Reset();
3069       //
3070       Double_t y0= cl->GetY();
3071       Double_t z0= cl->GetZ();
3072       Float_t erry = 0;
3073       Float_t errz = 0;
3074       
3075       Double_t ymax = fSectors->GetMaxY(row0)-kr0.fDeadZone-1.5;
3076       if (deltay>0 && TMath::Abs(ymax-TMath::Abs(y0))> deltay ) continue;  // seed only at the edge
3077       
3078       erry = (0.5)*cl->GetSigmaY2()/TMath::Sqrt(cl->GetQ())*6;      
3079       errz = (0.5)*cl->GetSigmaZ2()/TMath::Sqrt(cl->GetQ())*6;      
3080       polytrack.AddPoint(x,y0,z0,erry, errz);
3081
3082       sumused=0;
3083       if (cl->IsUsed(10)) sumused++;
3084
3085
3086       Float_t roady = (5*TMath::Sqrt(cl->GetSigmaY2()+0.2)+1.)*iter;
3087       Float_t roadz = (5*TMath::Sqrt(cl->GetSigmaZ2()+0.2)+1.)*iter;
3088       //
3089       x = krm.GetX();
3090       AliTPCclusterMI * cl1 = krm.FindNearest(y0,z0,roady,roadz);
3091       if (cl1 && TMath::Abs(ymax-TMath::Abs(y0))) {
3092         erry = (0.5)*cl1->GetSigmaY2()/TMath::Sqrt(cl1->GetQ())*3;          
3093         errz = (0.5)*cl1->GetSigmaZ2()/TMath::Sqrt(cl1->GetQ())*3;
3094         if (cl1->IsUsed(10))  sumused++;
3095         polytrack.AddPoint(x,cl1->GetY(),cl1->GetZ(),erry,errz);
3096       }
3097       //
3098       x = krp.GetX();
3099       AliTPCclusterMI * cl2 = krp.FindNearest(y0,z0,roady,roadz);
3100       if (cl2) {
3101         erry = (0.5)*cl2->GetSigmaY2()/TMath::Sqrt(cl2->GetQ())*3;          
3102         errz = (0.5)*cl2->GetSigmaZ2()/TMath::Sqrt(cl2->GetQ())*3;
3103         if (cl2->IsUsed(10)) sumused++;  
3104         polytrack.AddPoint(x,cl2->GetY(),cl2->GetZ(),erry,errz);
3105       }
3106       //
3107       if (sumused>0) continue;
3108       nin0++;
3109       polytrack.UpdateParameters();
3110       // follow polytrack
3111       roadz = 1.2;
3112       roady = 1.2;
3113       //
3114       Double_t yn,zn;
3115       nfoundable = polytrack.GetN();
3116       nfound     = nfoundable; 
3117       //
3118       for (Int_t ddrow = iter+1; ddrow<drow;ddrow++){
3119         Float_t maxdist = 0.8*(1.+3./(ddrow));
3120         for (Int_t delta = -1;delta<=1;delta+=2){
3121           Int_t row = row0+ddrow*delta;
3122           kr = &(fSectors[sec][row]);
3123           Double_t xn = kr->GetX();
3124           Double_t ymax = fSectors->GetMaxY(row)-kr->fDeadZone-1.5;
3125           polytrack.GetFitPoint(xn,yn,zn);
3126           if (TMath::Abs(yn)>ymax) continue;
3127           nfoundable++;
3128           AliTPCclusterMI * cln = kr->FindNearest(yn,zn,roady,roadz);
3129           if (cln) {
3130             Float_t dist =  TMath::Sqrt(  (yn-cln->GetY())*(yn-cln->GetY())+(zn-cln->GetZ())*(zn-cln->GetZ()));
3131             if (dist<maxdist){
3132               /*
3133               erry = (dist+0.3)*cln->GetSigmaY2()/TMath::Sqrt(cln->GetQ())*(1.+1./(ddrow));         
3134               errz = (dist+0.3)*cln->GetSigmaZ2()/TMath::Sqrt(cln->GetQ())*(1.+1./(ddrow));
3135               if (cln->IsUsed(10)) {
3136                 //      printf("used\n");
3137                 sumused++;
3138                 erry*=2;
3139                 errz*=2;
3140               }
3141               */
3142               erry=0.1;
3143               errz=0.1;
3144               polytrack.AddPoint(xn,cln->GetY(),cln->GetZ(),erry, errz);
3145               nfound++;
3146             }
3147           }
3148         }
3149         if ( (sumused>3) || (sumused>0.5*nfound) || (nfound<0.6*nfoundable))  break;     
3150         polytrack.UpdateParameters();
3151       }           
3152     }
3153     if ( (sumused>3) || (sumused>0.5*nfound))  {
3154       //printf("sumused   %d\n",sumused);
3155       continue;
3156     }
3157     nin1++;
3158     Double_t dy,dz;
3159     polytrack.GetFitDerivation(kr0.GetX(),dy,dz);
3160     AliTPCpolyTrack track2;
3161     
3162     polytrack.Refit(track2,0.5+TMath::Abs(dy)*0.3,0.4+TMath::Abs(dz)*0.3);
3163     if (track2.GetN()<0.5*nfoundable) continue;
3164     nin2++;
3165
3166     if ((nfound>0.6*nfoundable) &&( nfoundable>0.4*(i1-i2))) {
3167       //
3168       // test seed with and without constrain
3169       for (Int_t constrain=0; constrain<=0;constrain++){
3170         // add polytrack candidate
3171
3172         Double_t x[5], c[15];
3173         Double_t x1,x2,x3,y1,y2,y3,z1,z2,z3;
3174         track2.GetBoundaries(x3,x1);    
3175         x2 = (x1+x3)/2.;
3176         track2.GetFitPoint(x1,y1,z1);
3177         track2.GetFitPoint(x2,y2,z2);
3178         track2.GetFitPoint(x3,y3,z3);
3179         //
3180         //is track pointing to the vertex ?
3181         Double_t x0,y0,z0;
3182         x0=0;
3183         polytrack.GetFitPoint(x0,y0,z0);
3184
3185         if (constrain) {
3186           x2 = x3;
3187           y2 = y3;
3188           z2 = z3;
3189           
3190           x3 = 0;
3191           y3 = 0;
3192           z3 = 0;
3193         }
3194         x[0]=y1;
3195         x[1]=z1;
3196         x[4]=f1(x1,y1,x2,y2,x3,y3);
3197                 
3198         //      if (TMath::Abs(x[4]) >= cuts[0]) continue;  //
3199         x[2]=f2(x1,y1,x2,y2,x3,y3);
3200         
3201         //if (TMath::Abs(x[4]*x1-x[2]) >= cuts[1]) continue;
3202         //x[3]=f3(x1,y1,x2,y2,z1,z2);
3203         x[3]=f3n(x1,y1,x3,y3,z1,z3,x[4]);
3204         //if (TMath::Abs(x[3]) > cuts[3]) continue;
3205
3206         
3207         Double_t sy =0.1, sz =0.1;
3208         Double_t sy1=0.02, sz1=0.02;
3209         Double_t sy2=0.02, sz2=0.02;
3210         Double_t sy3=0.02;
3211
3212         if (constrain){
3213           sy3=25000*x[4]*x[4]+0.1, sy=0.1, sz=0.1;
3214         }
3215         
3216         Double_t f40=(f1(x1,y1+sy,x2,y2,x3,y3)-x[4])/sy;
3217         Double_t f42=(f1(x1,y1,x2,y2+sy,x3,y3)-x[4])/sy;
3218         Double_t f43=(f1(x1,y1,x2,y2,x3,y3+sy)-x[4])/sy;
3219         Double_t f20=(f2(x1,y1+sy,x2,y2,x3,y3)-x[2])/sy;
3220         Double_t f22=(f2(x1,y1,x2,y2+sy,x3,y3)-x[2])/sy;
3221         Double_t f23=(f2(x1,y1,x2,y2,x3,y3+sy)-x[2])/sy;
3222
3223         Double_t f30=(f3(x1,y1+sy,x3,y3,z1,z3)-x[3])/sy;
3224         Double_t f31=(f3(x1,y1,x3,y3,z1+sz,z3)-x[3])/sz;
3225         Double_t f32=(f3(x1,y1,x3,y3+sy,z1,z3)-x[3])/sy;
3226         Double_t f34=(f3(x1,y1,x3,y3,z1,z3+sz)-x[3])/sz;
3227
3228         
3229         c[0]=sy1;
3230         c[1]=0.;       c[2]=sz1;
3231         c[3]=f20*sy1;  c[4]=0.;       c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
3232         c[6]=f30*sy1;  c[7]=f31*sz1;  c[8]=f30*sy1*f20+f32*sy2*f22;
3233         c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
3234         c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
3235         c[13]=f30*sy1*f40+f32*sy2*f42;
3236         c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
3237         
3238         //Int_t row1 = fSectors->GetRowNumber(x1);
3239         Int_t row1 = GetRowNumber(x1);
3240
3241         UInt_t index=0;
3242         //kr0.GetIndex(is);
3243         AliTPCseed *track=new (seed) AliTPCseed(index, x, c, x1, sec*alpha+shift);
3244         track->fIsSeeding = kTRUE;
3245         Int_t rc=FollowProlongation(*track, i2);        
3246         if (constrain) track->fBConstrain =1;
3247         else
3248           track->fBConstrain =0;
3249         track->fLastPoint = row1+fInnerSec->GetNRows();  // first cluster in track position
3250         track->fFirstPoint = track->fLastPoint;
3251
3252         if (rc==0 || track->GetNumberOfClusters()<(i1-i2)*0.5 || 
3253             track->GetNumberOfClusters() < track->fNFoundable*0.6 || 
3254             track->fNShared>0.4*track->GetNumberOfClusters()) {
3255           //delete track;
3256           seed->Reset();
3257           seed->~AliTPCseed();
3258         }
3259         else {
3260           arr->AddLast(track);
3261           seed = new AliTPCseed;
3262         }
3263         nin3++;
3264       }
3265     }  // if accepted seed
3266   }
3267   if (fDebug>1){
3268     printf("\nSeeding statiistic:\t%d\t%d\t%d\t%d",nin0,nin1,nin2,nin3);
3269   }
3270   delete seed;
3271 }
3272
3273
3274 AliTPCseed *AliTPCtrackerMI::MakeSeed(AliTPCseed *track, Float_t r0, Float_t r1, Float_t r2)
3275 {
3276   //
3277   //
3278   //reseed
3279   Int_t p0 = int(r0*track->GetNumberOfClusters());     // point 0 
3280   Int_t p1 = int(r1*track->GetNumberOfClusters());
3281   Int_t p2 = int(r2*track->GetNumberOfClusters());   // last point
3282   Int_t pp2;
3283   Double_t  x0[3],x1[3],x2[3];
3284   x0[0]=-1;
3285   x0[0]=-1;
3286   x0[0]=-1;
3287
3288   // find track position at given ratio of the length
3289   Int_t  sec0, sec1, sec2;
3290   Int_t index=-1;
3291   Int_t clindex;
3292   for (Int_t i=0;i<160;i++){
3293     if (track->fClusterPointer[i]){
3294       index++;
3295       AliTPCTrackerPoint   *trpoint =track->GetTrackPoint(i);
3296       if ( (index<p0) || x0[0]<0 ){
3297         if (trpoint->GetX()>1){
3298           clindex = track->GetClusterIndex2(i);
3299           if (clindex>0){       
3300             x0[0] = trpoint->GetX();
3301             x0[1] = trpoint->GetY();
3302             x0[2] = trpoint->GetZ();
3303             sec0  = ((clindex&0xff000000)>>24)%18;
3304           }
3305         }
3306       }
3307
3308       if ( (index<p1) &&(trpoint->GetX()>1)){
3309         clindex = track->GetClusterIndex2(i);
3310         if (clindex>0){
3311           x1[0] = trpoint->GetX();
3312           x1[1] = trpoint->GetY();
3313           x1[2] = trpoint->GetZ();
3314           sec1  = ((clindex&0xff000000)>>24)%18;
3315         }
3316       }
3317       if ( (index<p2) &&(trpoint->GetX()>1)){
3318         clindex = track->GetClusterIndex2(i);
3319         if (clindex>0){
3320           x2[0] = trpoint->GetX();
3321           x2[1] = trpoint->GetY();
3322           x2[2] = trpoint->GetZ(); 
3323           sec2  = ((clindex&0xff000000)>>24)%18;
3324           pp2 = i;
3325         }
3326       }
3327     }
3328   }
3329   
3330   Double_t alpha, cs,sn, xx2,yy2;
3331   //
3332   alpha = (sec1-sec2)*fSectors->GetAlpha();
3333   cs = TMath::Cos(alpha);
3334   sn = TMath::Sin(alpha); 
3335   xx2= x1[0]*cs-x1[1]*sn;
3336   yy2= x1[0]*sn+x1[1]*cs;
3337   x1[0] = xx2;
3338   x1[1] = yy2;
3339   //
3340   alpha = (sec0-sec2)*fSectors->GetAlpha();
3341   cs = TMath::Cos(alpha);
3342   sn = TMath::Sin(alpha); 
3343   xx2= x0[0]*cs-x0[1]*sn;
3344   yy2= x0[0]*sn+x0[1]*cs;
3345   x0[0] = xx2;
3346   x0[1] = yy2;
3347   //
3348   //
3349   //
3350   Double_t x[5],c[15];
3351   //
3352   x[0]=x2[1];
3353   x[1]=x2[2];
3354   x[4]=f1(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]);
3355   //  if (x[4]>1) return 0;
3356   x[2]=f2(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]);
3357   x[3]=f3n(x2[0],x2[1],x0[0],x0[1],x2[2],x0[2],x[4]);
3358   //if (TMath::Abs(x[3]) > 2.2)  return 0;
3359   //if (TMath::Abs(x[2]) > 1.99) return 0;
3360   //  
3361   Double_t sy =0.1,  sz =0.1;
3362   //
3363   Double_t sy1=0.02+track->GetSigmaY2(), sz1=0.02+track->GetSigmaZ2();
3364   Double_t sy2=0.01+track->GetSigmaY2(), sz2=0.01+track->GetSigmaZ2();
3365   Double_t sy3=0.01+track->GetSigmaY2();
3366   //
3367   Double_t f40=(f1(x2[0],x2[1]+sy,x1[0],x1[1],x0[0],x0[1])-x[4])/sy;
3368   Double_t f42=(f1(x2[0],x2[1],x1[0],x1[1]+sy,x0[0],x0[1])-x[4])/sy;
3369   Double_t f43=(f1(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]+sy)-x[4])/sy;
3370   Double_t f20=(f2(x2[0],x2[1]+sy,x1[0],x1[1],x0[0],x0[1])-x[2])/sy;
3371   Double_t f22=(f2(x2[0],x2[1],x1[0],x1[1]+sy,x0[0],x0[1])-x[2])/sy;
3372   Double_t f23=(f2(x2[0],x2[1],x1[0],x1[1],x0[0],x0[1]+sy)-x[2])/sy;
3373   //
3374   Double_t f30=(f3(x2[0],x2[1]+sy,x0[0],x0[1],x2[2],x0[2])-x[3])/sy;
3375   Double_t f31=(f3(x2[0],x2[1],x0[0],x0[1],x2[2]+sz,x0[2])-x[3])/sz;
3376   Double_t f32=(f3(x2[0],x2[1],x0[0],x0[1]+sy,x2[2],x0[2])-x[3])/sy;
3377   Double_t f34=(f3(x2[0],x2[1],x0[0],x0[1],x2[2],x0[2]+sz)-x[3])/sz;
3378   
3379   
3380   c[0]=sy1;
3381   c[1]=0.;       c[2]=sz1;
3382   c[3]=f20*sy1;  c[4]=0.;       c[5]=f20*sy1*f20+f22*sy2*f22+f23*sy3*f23;
3383   c[6]=f30*sy1;  c[7]=f31*sz1;  c[8]=f30*sy1*f20+f32*sy2*f22;
3384   c[9]=f30*sy1*f30+f31*sz1*f31+f32*sy2*f32+f34*sz2*f34;
3385   c[10]=f40*sy1; c[11]=0.; c[12]=f40*sy1*f20+f42*sy2*f22+f43*sy3*f23;
3386   c[13]=f30*sy1*f40+f32*sy2*f42;
3387   c[14]=f40*sy1*f40+f42*sy2*f42+f43*sy3*f43;
3388   
3389   //  Int_t row1 = fSectors->GetRowNumber(x2[0]);
3390   AliTPCseed *seed=new  AliTPCseed(0, x, c, x2[0], sec2*fSectors->GetAlpha()+fSectors->GetAlphaShift());
3391   //  Double_t y0,z0,y1,z1, y2,z2;
3392   //seed->GetProlongation(x0[0],y0,z0);
3393   // seed->GetProlongation(x1[0],y1,z1);
3394   //seed->GetProlongation(x2[0],y2,z2);
3395   //  seed =0;
3396   seed->fLastPoint  = pp2;
3397   seed->fFirstPoint = pp2;
3398   
3399
3400   return seed;
3401 }
3402
3403 Int_t  AliTPCtrackerMI::CheckKinkPoint(AliTPCseed*seed, Float_t th)
3404 {
3405   //
3406   //
3407   // 
3408   for (Int_t i=0;i<12;i++) seed->fKinkPoint[i]=0;
3409   //
3410   if (TMath::Abs(seed->GetC())>0.01) return 0;
3411   //
3412
3413   Float_t x[160], y[160], erry[160], z[160], errz[160];
3414   Int_t sec[160];
3415   Float_t xt[160], yt[160], zt[160];
3416   Int_t i1 = 200;
3417   Int_t i2 = 0;
3418   Int_t secm   = -1;
3419   Int_t padm   = -1;
3420   Int_t middle = seed->GetNumberOfClusters()/2;
3421   //
3422   //
3423   // find central sector, get local cooordinates
3424   Int_t count = 0;
3425   for (Int_t i=seed->fFirstPoint;i<=seed->fLastPoint;i++) {
3426     sec[i]= seed->GetClusterSector(i)%18;
3427     x[i]  = GetXrow(i);  
3428     if (sec[i]>=0) {
3429       AliTPCclusterMI * cl = seed->fClusterPointer[i];
3430       //      if (cl==0)        cl = GetClusterMI(seed->GetClusterIndex2(i));
3431       if (cl==0) {
3432         sec[i] = -1;
3433         continue;
3434       }
3435       //
3436       //
3437       if (i>i2)  i2 = i;  //last  point with cluster
3438       if (i2<i1) i1 = i;  //first point with cluster
3439       y[i] = cl->GetY();
3440       z[i] = cl->GetZ();
3441       AliTPCTrackerPoint * point = seed->GetTrackPoint(i);
3442       xt[i] = x[i];
3443       yt[i] = point->GetY();
3444       zt[i] = point->GetZ();
3445   
3446       if (point->GetX()>0){
3447         erry[i] = point->GetErrY();
3448         errz[i] = point->GetErrZ();     
3449       }
3450
3451       count++;
3452       if (count<middle) {
3453         secm = sec[i];  //central sector
3454         padm = i;       //middle point with cluster
3455       }
3456     }
3457   }
3458   //
3459   // rotate position to global coordinate system connected to  sector at last the point
3460   //
3461   for (Int_t i=i1;i<=i2;i++){
3462     //    
3463     if (sec[i]<0) continue;
3464     Double_t alpha = (sec[i2]-sec[i])*fSectors->GetAlpha();
3465     Double_t cs = TMath::Cos(alpha);
3466     Double_t sn = TMath::Sin(alpha);    
3467     Float_t xx2= x[i]*cs+y[i]*sn;
3468     Float_t yy2= -x[i]*sn+y[i]*cs;
3469     x[i] = xx2;
3470     y[i] = yy2;    
3471     //
3472     xx2= xt[i]*cs+yt[i]*sn;
3473     yy2= -xt[i]*sn+yt[i]*cs;
3474     xt[i] = xx2;
3475     yt[i] = yy2;    
3476
3477   }
3478   //get "state" vector
3479   Double_t xh[5],xm = x[padm];  
3480   xh[0]=yt[i2];
3481   xh[1]=zt[i2];
3482   xh[4]=f1(xt[i2],yt[i2],xt[padm],yt[padm],xt[i1],yt[i1]);  
3483   xh[2]=f2(xt[i2],yt[i2],xt[padm],yt[padm],xt[i1],yt[i1]);
3484   xh[3]=f3n(xt[i2],yt[i2],xt[i1],yt[i1],zt[i2],zt[i1],xh[4]);
3485   //
3486   //
3487   for (Int_t i=i1;i<=i2;i++){
3488     Double_t yy,zz;
3489     if (sec[i]<0) continue;    
3490     GetProlongation(x[i2], x[i],xh,yy,zz);
3491     if (TMath::Abs(y[i]-yy)>4||TMath::Abs(z[i]-zz)>4){
3492       //Double_t xxh[5];
3493       //xxh[4]=f1old(x[i2],y[i2],x[padm],y[padm],x[i1],y[i1]);  
3494       //xxh[2]=f2old(x[i2],y[i2],x[padm],y[padm],x[i1],y[i1]);
3495       printf("problem\n");
3496     }
3497     y[i] = y[i] - yy;
3498     z[i] = z[i] - zz;
3499   }
3500   Float_t dyup[160],dydown[160], dzup[160], dzdown[160];
3501   Float_t yup[160], ydown[160],  zup[160],  zdown[160];
3502  
3503   AliTPCpolyTrack ptrack1,ptrack2;
3504   //
3505   // derivation up
3506   for (Int_t i=i1;i<=i2;i++){
3507     AliTPCclusterMI * cl = seed->fClusterPointer[i];
3508     if (!cl) continue;
3509     if (cl->GetType()<0) continue;
3510     if (cl->GetType()>10) continue;
3511
3512     if (sec[i]>=0){
3513       ptrack1.AddPoint(x[i]-xm,y[i],z[i],0.1,0.1);
3514     }
3515     if (ptrack1.GetN()>4.){
3516       ptrack1.UpdateParameters();
3517       Double_t ddy,ddz;
3518       ptrack1.GetFitDerivation(x[i]-xm,ddy,ddz);
3519       Double_t yy,zz;
3520       ptrack1.GetFitPoint(x[i]-xm,yy,zz);
3521
3522       dyup[i] = ddy;
3523       dzup[i] = ddz;
3524       yup[i]  = yy;
3525       zup[i]  = zz;
3526
3527     }
3528     else{
3529       dyup[i]=0.;  //not enough points
3530     }
3531   }
3532   //
3533   // derivation down
3534   for (Int_t i=i2;i>=i1;i--){
3535     AliTPCclusterMI * cl = seed->fClusterPointer[i];
3536     if (!cl) continue;
3537     if (cl->GetType()<0) continue;
3538     if (cl->GetType()>10) continue;
3539     if (sec[i]>=0){
3540       ptrack2.AddPoint(x[i]-xm,y[i],z[i],0.1,0.1);
3541     }
3542     if (ptrack2.GetN()>4){
3543       ptrack2.UpdateParameters();
3544       Double_t ddy,ddz;
3545       ptrack2.GetFitDerivation(x[i]-xm,ddy,ddz);
3546       Double_t yy,zz;
3547       ptrack2.GetFitPoint(x[i]-xm,yy,zz);
3548
3549       dydown[i] = ddy;
3550       dzdown[i] = ddz;
3551       ydown[i]  = yy;
3552       zdown[i]  = zz;
3553     }
3554     else{
3555       dydown[i]=0.;  //not enough points
3556     }
3557   }
3558   //
3559   //
3560   // find maximal difference of the derivation
3561   for (Int_t i=0;i<12;i++) seed->fKinkPoint[i]=0;
3562
3563
3564   for (Int_t i=i1+10;i<i2-10;i++){
3565     if ( (TMath::Abs(dydown[i])<0.00000001)  ||  (TMath::Abs(dyup[i])<0.00000001) ||i<30)continue;
3566     //    printf("%f\t%f\t%f\t%f\t%f\n",x[i],dydown[i],dyup[i],dzdown[i],dzup[i]);
3567     //
3568     Float_t ddy = TMath::Abs(dydown[i]-dyup[i]);
3569     Float_t ddz = TMath::Abs(dzdown[i]-dzup[i]);    
3570     if ( (ddy+ddz)> th){
3571       seed->fKinkPoint[0] = i;
3572       seed->fKinkPoint[1] = ddy;
3573       seed->fKinkPoint[2] = ddz;
3574       th = ddy+ddz;      
3575     }
3576   }
3577
3578   if (fTreeDebug){
3579     //
3580     //write information to the debug tree
3581     TBranch * br = fTreeDebug->GetBranch("debug");
3582     TClonesArray * arr = new TClonesArray("AliTPCTrackPoint2");
3583     arr->ExpandCreateFast(i2-i1);
3584     br->SetAddress(&arr);
3585     //
3586     AliTPCclusterMI cldummy;
3587     cldummy.SetQ(0);
3588     AliTPCTrackPoint2 pdummy;
3589     pdummy.GetTPoint().fIsShared = 10;
3590     //
3591     Double_t alpha = sec[i2]*fSectors->GetAlpha();
3592     Double_t cs    = TMath::Cos(alpha);
3593     Double_t sn    = TMath::Sin(alpha);    
3594
3595     for (Int_t i=i1;i<i2;i++){
3596       AliTPCTrackPoint2 *trpoint = (AliTPCTrackPoint2*)arr->UncheckedAt(i-i1);
3597       //cluster info
3598       AliTPCclusterMI * cl0 = seed->fClusterPointer[i];
3599       //      
3600       AliTPCTrackerPoint * point = seed->GetTrackPoint(i);
3601       
3602       if (cl0){
3603         Double_t x = GetXrow(i);
3604         trpoint->GetTPoint() = *point;
3605         trpoint->GetCPoint() = *cl0;
3606         trpoint->GetCPoint().SetQ(TMath::Abs(cl0->GetQ()));
3607         trpoint->fID    = seed->GetUniqueID();
3608         trpoint->fLab   = seed->GetLabel();
3609         //
3610         trpoint->fGX =  cs *x + sn*point->GetY();
3611         trpoint->fGY = -sn *x + cs*point->GetY() ;
3612         trpoint->fGZ = point->GetZ();
3613         //
3614         trpoint->fDY = y[i];
3615         trpoint->fDZ = z[i];
3616         //
3617         trpoint->fDYU = dyup[i];
3618         trpoint->fDZU = dzup[i];
3619         //
3620         trpoint->fDYD = dydown[i];
3621         trpoint->fDZD = dzdown[i];
3622         //
3623         if (TMath::Abs(dyup[i])>0.00000000001 &&TMath::Abs(dydown[i])>0.00000000001){
3624           trpoint->fDDY = dydown[i]-dyup[i];
3625           trpoint->fDDZ = dzdown[i]-dzup[i];
3626         }else{
3627           trpoint->fDDY = 0.;
3628           trpoint->fDDZ = 0.;
3629         }       
3630       }
3631       else{
3632         *trpoint = pdummy;
3633         trpoint->GetCPoint()= cldummy;
3634         trpoint->fID = -1;
3635       }
3636       //     
3637     }
3638     fTreeDebug->Fill();
3639   }
3640   
3641   
3642   return 0;
3643   
3644 }
3645
3646
3647
3648
3649
3650 AliTPCseed*  AliTPCtrackerMI::ReSeed(AliTPCseed *t)
3651 {
3652   //
3653   // reseed - refit -  track
3654   //
3655   Int_t first = 0;
3656   //  Int_t last  = fSectors->GetNRows()-1;
3657   //
3658   if (fSectors == fOuterSec){
3659     first = TMath::Max(first, t->fFirstPoint-fInnerSec->GetNRows());
3660     //last  = 
3661   }
3662   else
3663     first = t->fFirstPoint;
3664   //
3665   AliTPCseed * seed = MakeSeed(t,0.1,0.5,0.9);
3666   FollowBackProlongation(*t,fSectors->GetNRows()-1);
3667   t->Reset(kFALSE);
3668   FollowProlongation(*t,first);
3669   return seed;
3670 }
3671
3672
3673
3674
3675
3676
3677
3678 //_____________________________________________________________________________
3679 Int_t AliTPCtrackerMI::ReadSeeds(const TFile *inp) {
3680   //-----------------------------------------------------------------
3681   // This function reades track seeds.
3682   //-----------------------------------------------------------------
3683   TDirectory *savedir=gDirectory; 
3684
3685   TFile *in=(TFile*)inp;
3686   if (!in->IsOpen()) {
3687      cerr<<"AliTPCtrackerMI::ReadSeeds(): input file is not open !\n";
3688      return 1;
3689   }
3690
3691   in->cd();
3692   TTree *seedTree=(TTree*)in->Get("Seeds");
3693   if (!seedTree) {
3694      cerr<<"AliTPCtrackerMI::ReadSeeds(): ";
3695      cerr<<"can't get a tree with track seeds !\n";
3696      return 2;
3697   }
3698   AliTPCtrack *seed=new AliTPCtrack; 
3699   seedTree->SetBranchAddress("tracks",&seed);
3700   
3701   if (fSeeds==0) fSeeds=new TObjArray(15000);
3702
3703   Int_t n=(Int_t)seedTree->GetEntries();
3704   for (Int_t i=0; i<n; i++) {
3705      seedTree->GetEvent(i);
3706      fSeeds->AddLast(new AliTPCseed(*seed,seed->GetAlpha()));
3707   }
3708   
3709   delete seed;
3710   delete seedTree; 
3711   savedir->cd();
3712   return 0;
3713 }
3714
3715 //_____________________________________________________________________________
3716 Int_t AliTPCtrackerMI::Clusters2Tracks() {
3717   //-----------------------------------------------------------------
3718   // This is a track finder.
3719   //-----------------------------------------------------------------
3720   TDirectory *savedir=gDirectory; 
3721   TStopwatch timer;
3722   //
3723   if (!fInput) SetIO();  //set default IO using loaders
3724   if (!fInput){
3725      cerr<<"AliTPCtrackerMI::Clusters2Tracks(): input file is not open !\n";
3726      return 1;
3727   }
3728   LoadClusters();
3729   //
3730   fIteration = 0;
3731   fSeeds = Tracking();
3732
3733
3734   printf("Time for tracking: \t");timer.Print();timer.Start();
3735
3736   //activate again some tracks
3737   for (Int_t i=0; i<fSeeds->GetEntriesFast(); i++) {
3738     AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;    
3739     if (!pt) continue;    
3740     Int_t nc=t.GetNumberOfClusters();
3741     if (nc<20) {
3742       delete fSeeds->RemoveAt(i);
3743       continue;
3744     }
3745     if (pt->fRemoval==10) {
3746       if (pt->GetDensityFirst(20)>0.8 || pt->GetDensityFirst(30)>0.8 || pt->GetDensityFirst(40)>0.7)
3747         pt->Desactivate(10);  // make track again active
3748       else{
3749         pt->Desactivate(20);    
3750         delete fSeeds->RemoveAt(i);
3751       }
3752     } 
3753   }
3754   RemoveDouble(fSeeds,0.2,0.6,11);
3755   //RemoveUsed(fSeeds,0.9,0.9,6);
3756   //RemoveUsed(fSeeds,0.8,0.8,6);
3757   //RemoveUsed(fSeeds,0.7,0.7,6);
3758   RemoveUsed(fSeeds,0.5,0.5,6);
3759
3760   //
3761   Int_t nseed=fSeeds->GetEntriesFast();
3762   Int_t found = 0;
3763   for (Int_t i=0; i<nseed; i++) {
3764     AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;    
3765     if (!pt) continue;    
3766     Int_t nc=t.GetNumberOfClusters();
3767     if (nc<15) {
3768       delete fSeeds->RemoveAt(i);
3769       continue;
3770     }
3771     CookLabel(pt,0.1); //For comparison only
3772     //if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
3773     if ((pt->IsActive() || (pt->fRemoval==10) )){
3774       cerr<<found++<<'\r';      
3775     }
3776     else
3777       delete fSeeds->RemoveAt(i);
3778     pt->fLab2 = i;
3779   }
3780
3781   
3782   //RemoveOverlap(fSeeds,0.99,7,kTRUE);  
3783   SignShared(fSeeds);  
3784   //RemoveUsed(fSeeds,0.9,0.9,6);
3785   // 
3786   nseed=fSeeds->GetEntriesFast();
3787   found = 0;
3788   for (Int_t i=0; i<nseed; i++) {
3789     AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;    
3790     if (!pt) continue;    
3791     Int_t nc=t.GetNumberOfClusters();
3792     if (nc<15) {
3793       delete fSeeds->RemoveAt(i);
3794       continue;
3795     }
3796     t.SetUniqueID(i);
3797     t.CookdEdx(0.02,0.6);
3798     //    CheckKinkPoint(&t,0.05);
3799     //if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
3800     if ((pt->IsActive() || (pt->fRemoval==10) )){
3801       cerr<<found++<<'\r';      
3802     }
3803     else
3804       delete fSeeds->RemoveAt(i);
3805     pt->fLab2 = i;
3806   }
3807
3808   SortTracks(fSeeds, 1);
3809   
3810   /*
3811   fIteration = 1;
3812   PrepareForBackProlongation(fSeeds,0.5);
3813   PropagateBack(fSeeds);
3814   printf("Time for back propagation: \t");timer.Print();timer.Start();
3815   
3816   fIteration = 2;
3817   
3818   PrepareForProlongation(fSeeds,1.);
3819   PropagateForward();
3820   
3821   fSectors = fOuterSec;
3822   ParallelTracking(fSeeds,fSectors->GetNRows()-1,0);
3823   fSectors = fInnerSec;
3824   ParallelTracking(fSeeds,fSectors->GetNRows()-1,0);
3825   printf("Time for FORWARD propagation: \t");timer.Print();timer.Start();
3826   // RemoveUsed(fSeeds,0.7,0.7,6);
3827   //RemoveOverlap(fSeeds,0.9,7,kTRUE);
3828  
3829   nseed=fSeeds->GetEntriesFast();
3830   found = 0;
3831   for (Int_t i=0; i<nseed; i++) {
3832     AliTPCseed *pt=(AliTPCseed*)fSeeds->UncheckedAt(i), &t=*pt;    
3833     if (!pt) continue;    
3834     Int_t nc=t.GetNumberOfClusters();
3835     if (nc<15) {
3836       delete fSeeds->RemoveAt(i);
3837       continue;
3838     }
3839     t.CookdEdx(0.02,0.6);
3840     //    CookLabel(pt,0.1); //For comparison only
3841     //if ((pt->IsActive() || (pt->fRemoval==10) )&& nc>50 &&pt->GetNumberOfClusters()>0.4*pt->fNFoundable){
3842     if ((pt->IsActive() || (pt->fRemoval==10) )){
3843       cerr<<found++<<'\r';      
3844     }
3845     else
3846       delete fSeeds->RemoveAt(i);
3847     pt->fLab2 = i;
3848   }
3849   */
3850  
3851   //  fNTracks = found;
3852   printf("Time for overlap removal, track writing and dedx cooking: \t"); timer.Print();timer.Start();
3853   //
3854   if (fOutput) {
3855     WriteTracks();
3856   }
3857   if (!fNewIO)  fOutput->Write();
3858   else
3859     AliRunLoader::GetDetectorLoader("TPC",AliConfig::fgkDefaultEventFolderName)->WriteTracks("OVERWRITE");
3860
3861
3862   cerr<<"Number of found tracks : "<<"\t"<<found<<endl;  
3863   savedir->cd();
3864   //if (seedtree) delete seedtree;
3865   //  UnloadClusters();
3866   //printf("Time for unloading cluster: \t"); timer.Print();timer.Start();
3867   
3868   return 0;
3869 }
3870
3871 void AliTPCtrackerMI::Tracking(TObjArray * arr)
3872 {
3873   //
3874   // tracking of the seeds
3875   //
3876
3877   fSectors = fOuterSec;
3878   ParallelTracking(arr,150,63);
3879   fSectors = fOuterSec;
3880   ParallelTracking(arr,63,0);
3881 }
3882
3883 TObjArray * AliTPCtrackerMI::Tracking(Int_t seedtype, Int_t i1, Int_t i2, Float_t cuts[4], Float_t dy, Int_t dsec)
3884 {
3885   //
3886   //
3887   //tracking routine
3888   TObjArray * arr = new TObjArray;
3889   // 
3890   fSectors = fOuterSec;
3891   TStopwatch timer;
3892   timer.Start();
3893   for (Int_t sec=0;sec<fkNOS;sec++){
3894     if (seedtype==3) MakeSeeds3(arr,sec,i1,i2,cuts,dy, dsec);
3895     if (seedtype==4) MakeSeeds5(arr,sec,i1,i2,cuts,dy);    
3896     if (seedtype==2) MakeSeeds2(arr,sec,i1,i2,cuts,dy);
3897   }
3898   if (fDebug>0){
3899     printf("\nSeeding - %d\t%d\t%d\t%d\n",seedtype,i1,i2,arr->GetEntriesFast());
3900     timer.Print();
3901     timer.Start();
3902   }
3903   Tracking(arr);  
3904   if (fDebug>0){
3905     timer.Print();
3906   }
3907
3908   return arr;
3909 }
3910
3911 TObjArray * AliTPCtrackerMI::Tracking()
3912 {
3913   //
3914   //
3915   TStopwatch timer;
3916   timer.Start();
3917   Int_t nup=fOuterSec->GetNRows()+fInnerSec->GetNRows();
3918
3919   TObjArray * seeds = new TObjArray;
3920   TObjArray * arr=0;
3921   
3922   Int_t gap =20;
3923   Float_t cuts[4];
3924   cuts[0] = 0.002;
3925   cuts[1] = 1.5;
3926   cuts[2] = 3.;
3927   cuts[3] = 3.;
3928   Float_t fnumber  = 3.0;
3929   Float_t fdensity = 3.0;
3930   
3931   //  
3932   //find primaries  
3933   cuts[0]=0.0066;
3934   for (Int_t delta = 0; delta<18; delta+=6){
3935     //
3936     cuts[0]=0.0070;
3937     cuts[1] = 1.5;
3938     arr = Tracking(3,nup-1-delta,nup-1-delta-gap,cuts,-1,1);
3939     SumTracks(seeds,arr);   
3940     SignClusters(seeds,fnumber,fdensity); 
3941     //
3942     for (Int_t i=2;i<6;i+=2){
3943       // seed high pt tracks
3944       cuts[0]=0.0022;
3945       cuts[1]=0.3;
3946       arr = Tracking(3,nup-i-delta,nup-i-delta-gap,cuts,-1,0);
3947       SumTracks(seeds,arr);   
3948       SignClusters(seeds,fnumber,fdensity);        
3949     }
3950   }
3951   fnumber  = 4;
3952   fdensity = 4.;
3953   //  RemoveUsed(seeds,0.9,0.9,1);
3954   //  UnsignClusters();
3955   //  SignClusters(seeds,fnumber,fdensity);    
3956
3957   //find primaries  
3958   cuts[0]=0.0077;
3959   for (Int_t delta = 20; delta<120; delta+=10){
3960     //
3961     // seed high pt tracks
3962     cuts[0]=0.0060;
3963     cuts[1]=0.3;
3964     cuts[2]=6.;
3965     arr = Tracking(3,nup-delta,nup-delta-gap,cuts,-1);
3966     SumTracks(seeds,arr);   
3967     SignClusters(seeds,fnumber,fdensity);            
3968
3969     cuts[0]=0.003;
3970     cuts[1]=0.3;
3971     cuts[2]=6.;
3972     arr = Tracking(3,nup-delta-5,nup-delta-5-gap,cuts,-1);
3973     SumTracks(seeds,arr);   
3974     SignClusters(seeds,fnumber,fdensity);            
3975   }
3976
3977   cuts[0] = 0.01;
3978   cuts[1] = 2.0;
3979   cuts[2] = 3.;
3980   cuts[3] = 2.0;
3981   fnumber  = 2.;
3982   fdensity = 2.;
3983   
3984   if (fDebug>0){
3985     printf("\n\nPrimary seeding\t%d\n\n",seeds->GetEntriesFast());
3986     timer.Print();
3987     timer.Start();
3988   }
3989   //  RemoveUsed(seeds,0.75,0.75,1);
3990   //UnsignClusters();
3991   //SignClusters(seeds,fnumber,fdensity);
3992   
3993   // find secondaries
3994
3995   cuts[0] = 0.3;
3996   cuts[1] = 1.5;
3997   cuts[2] = 3.;
3998   cuts[3] = 1.5;
3999
4000   arr = Tracking(4,nup-1,nup-1-gap,cuts,-1);
4001   SumTracks(seeds,arr);   
4002   SignClusters(seeds,fnumber,fdensity);   
4003   //
4004   arr = Tracking(4,nup-2,nup-2-gap,cuts,-1);
4005   SumTracks(seeds,arr);   
4006   SignClusters(seeds,fnumber,fdensity);   
4007   //
4008   arr = Tracking(4,nup-3,nup-3-gap,cuts,-1);
4009   SumTracks(seeds,arr);   
4010   SignClusters(seeds,fnumber,fdensity);   
4011   //
4012
4013
4014   for (Int_t delta = 3; delta<30; delta+=5){
4015     //
4016     cuts[0] = 0.3;
4017     cuts[1] = 1.5;
4018     cuts[2] = 3.;
4019     cuts[3] = 1.5;
4020     arr = Tracking(4,nup-1-delta,nup-1-delta-gap,cuts,-1);
4021     SumTracks(seeds,arr);   
4022     SignClusters(seeds,fnumber,fdensity);   
4023     //
4024     arr = Tracking(4,nup-3-delta,nup-5-delta-gap,cuts,4);
4025     SumTracks(seeds,arr);   
4026     SignClusters(seeds,fnumber,fdensity); 
4027     //
4028   } 
4029   fnumber  = 1;
4030   fdensity = 1;
4031   //
4032   // change cuts
4033   fnumber  = 2.;
4034   fdensity = 2.;
4035   cuts[0]=0.0080;
4036
4037   // find secondaries
4038   for (Int_t delta = 30; delta<70; delta+=10){
4039     //
4040     cuts[0] = 0.3;
4041     cuts[1] = 1.5;
4042     cuts[2] = 3.;
4043     cuts[3] = 1.5;
4044     arr = Tracking(4,nup-1-delta,nup-1-delta-gap,cuts,-1);
4045     SumTracks(seeds,arr);   
4046     SignClusters(seeds,fnumber,fdensity);   
4047     //
4048     arr = Tracking(4,nup-5-delta,nup-5-delta-gap,cuts,5 );
4049     SumTracks(seeds,arr);   
4050     SignClusters(seeds,fnumber,fdensity);   
4051   }
4052  
4053   if (fDebug>0){
4054     printf("\n\nSecondary seeding\t%d\n\n",seeds->GetEntriesFast());
4055     timer.Print();
4056     timer.Start();
4057   }
4058
4059   return seeds;
4060   //
4061       
4062 }
4063
4064
4065 void AliTPCtrackerMI::SumTracks(TObjArray *arr1,TObjArray *arr2)
4066 {
4067   //
4068   //sum tracks to common container
4069   //remove suspicious tracks
4070   Int_t nseed = arr2->GetEntriesFast();
4071   for (Int_t i=0;i<nseed;i++){
4072     AliTPCseed *pt=(AliTPCseed*)arr2->UncheckedAt(i);    
4073     if (pt){
4074       
4075       // NORMAL ACTIVE TRACK
4076       if (pt->IsActive()){
4077         arr1->AddLast(arr2->RemoveAt(i));
4078         continue;
4079       }
4080       //remove not usable tracks
4081       if (pt->fRemoval!=10){
4082         delete arr2->RemoveAt(i);
4083         continue;
4084       }
4085       // REMOVE VERY SHORT  TRACKS
4086       if (pt->GetNumberOfClusters()<20){ 
4087         delete arr2->RemoveAt(i);
4088         continue;
4089       }
4090       // ENABLE ONLY ENOUGH GOOD STOPPED TRACKS
4091       if (pt->GetDensityFirst(20)>0.8 || pt->GetDensityFirst(30)>0.8 || pt->GetDensityFirst(40)>0.7)
4092         arr1->AddLast(arr2->RemoveAt(i));
4093       else{      
4094         delete arr2->RemoveAt(i);
4095       }
4096     }
4097   }
4098   delete arr2;  
4099 }
4100
4101
4102
4103 void  AliTPCtrackerMI::ParallelTracking(TObjArray * arr, Int_t rfirst, Int_t rlast)
4104 {
4105   //
4106   // try to track in parralel
4107
4108   Int_t nseed=arr->GetEntriesFast();
4109   //prepare seeds for tracking
4110   for (Int_t i=0; i<nseed; i++) {
4111     AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i), &t=*pt; 
4112     if (!pt) continue;
4113     if (!t.IsActive()) continue;
4114     // follow prolongation to the first layer
4115     if ( (fSectors ==fInnerSec) || (t.fFirstPoint-fParam->GetNRowLow()>rfirst+1) )  
4116       FollowProlongation(t, rfirst+1);
4117   }
4118
4119
4120   //
4121   for (Int_t nr=rfirst; nr>=rlast; nr--){      
4122     // make indexes with the cluster tracks for given       
4123
4124     // find nearest cluster
4125     for (Int_t i=0; i<nseed; i++) {
4126       AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i), &t=*pt;       
4127       if (!pt) continue;
4128       if (!pt->IsActive()) continue;
4129       //      if ( (fSectors ==fOuterSec) && (pt->fFirstPoint-fParam->GetNRowLow())<nr) continue;
4130       if (pt->fRelativeSector>17) {
4131         continue;
4132       }
4133       UpdateClusters(t,nr);
4134     }
4135     // prolonagate to the nearest cluster - if founded
4136     for (Int_t i=0; i<nseed; i++) {
4137       AliTPCseed *pt=(AliTPCseed*)arr->UncheckedAt(i); 
4138       if (!pt) continue;
4139       if (!pt->IsActive()) continue; 
4140       // if ((fSectors ==fOuterSec) && (pt->fFirstPoint-fParam->GetNRowLow())<nr) continue;
4141       if (pt->fRelativeSector>17) {
4142         continue;
4143       }
4144       FollowToNextCluster(*pt,nr);
4145     }
4146   }    
4147 }
4148
4149 void AliTPCtrackerMI::PrepareForBackProlongation(TObjArray * arr,Float_t fac)
4150 {
4151   //
4152   //
4153   // if we use TPC track itself we have to "update" covariance
4154   //
4155   Int_t nseed= arr->GetEntriesFast();
4156   for (Int_t i=0;i<nseed;i++){
4157     AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
4158     if (pt) {
4159       pt->Modify(fac);
4160       //
4161       //rotate to current local system at first accepted  point    
4162       Int_t index  = pt->GetClusterIndex2(pt->fFirstPoint); 
4163       Int_t sec    = (index&0xff000000)>>24;
4164       sec = sec%18;
4165       Float_t angle1 = fInnerSec->GetAlpha()*sec+fInnerSec->GetAlphaShift();
4166       if (angle1>TMath::Pi()) 
4167         angle1-=2.*TMath::Pi();
4168       Float_t angle2 = pt->GetAlpha();
4169       
4170       if (TMath::Abs(angle1-angle2)>0.001){
4171         pt->Rotate(angle1-angle2);
4172         //angle2 = pt->GetAlpha();
4173         //pt->fRelativeSector = pt->GetAlpha()/fInnerSec->GetAlpha();
4174         //if (pt->GetAlpha()<0) 
4175         //  pt->fRelativeSector+=18;
4176         //sec = pt->fRelativeSector;
4177       }
4178         
4179     }
4180     
4181   }
4182
4183
4184 }
4185 void AliTPCtrackerMI::PrepareForProlongation(TObjArray * arr, Float_t fac)
4186 {
4187   //
4188   //
4189   // if we use TPC track itself we have to "update" covariance
4190   //
4191   Int_t nseed= arr->GetEntriesFast();
4192   for (Int_t i=0;i<nseed;i++){
4193     AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
4194     if (pt) {
4195       pt->Modify(fac);
4196       pt->fFirstPoint = pt->fLastPoint; 
4197     }
4198     
4199   }
4200
4201
4202 }
4203
4204 Int_t AliTPCtrackerMI::PropagateBack(TObjArray * arr)
4205 {
4206   //
4207   // make back propagation
4208   //
4209   Int_t nseed= arr->GetEntriesFast();
4210   for (Int_t i=0;i<nseed;i++){
4211     AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
4212     if (pt) { 
4213       AliTPCseed *pt2 = new AliTPCseed(*pt);
4214       fSectors = fInnerSec;
4215       FollowBackProlongation(*pt,fSectors->GetNRows()-1);
4216       fSectors = fOuterSec;
4217       FollowBackProlongation(*pt,fSectors->GetNRows()-1);
4218       fSectors = fOuterSec;
4219       if (pt->GetNumberOfClusters()<35 && pt->GetLabel()>0 ){
4220         printf("\n%d",pt->GetLabel());
4221         fSectors = fInnerSec;
4222         FollowBackProlongation(*pt2,fSectors->GetNRows()-1);
4223         fSectors = fOuterSec;
4224         FollowBackProlongation(*pt2,fSectors->GetNRows()-1);
4225         fSectors = fOuterSec;
4226       }
4227     }      
4228   }
4229   return 0;
4230 }
4231
4232
4233 Int_t AliTPCtrackerMI::PropagateForward2(TObjArray * arr)
4234 {
4235   //
4236   // make forward propagation
4237   //
4238   Int_t nseed= arr->GetEntriesFast();
4239   for (Int_t i=0;i<nseed;i++){
4240     AliTPCseed *pt = (AliTPCseed*)arr->UncheckedAt(i);
4241     if (pt) { 
4242       AliTPCseed *pt2 = new AliTPCseed(*pt);
4243       fSectors = fOuterSec;
4244       FollowProlongation(*pt,0);
4245       fSectors = fOuterSec;
4246       FollowProlongation(*pt,0);
4247       fSectors = fInnerSec;
4248       if (pt->GetNumberOfClusters()<35 && pt->GetLabel()>0 ){
4249         printf("\n%d",pt->GetLabel());
4250         fSectors = fOuterSec;
4251         FollowProlongation(*pt2,0);
4252         fSectors = fOuterSec;
4253         FollowProlongation(*pt2,0);
4254         fSectors = fOuterSec;
4255       }
4256     }      
4257   }
4258   return 0;
4259 }
4260
4261
4262 Int_t AliTPCtrackerMI::PropagateForward()
4263 {
4264   fSectors = fOuterSec;
4265   ParallelTracking(fSeeds,fSectors->GetNRows()-1,0);
4266   fSectors = fInnerSec;
4267   ParallelTracking(fSeeds,fSectors->GetNRows()-1,0);
4268   //WriteTracks();
4269   return 1;
4270 }
4271
4272
4273
4274
4275
4276
4277 Int_t AliTPCtrackerMI::PropagateBack(AliTPCseed * pt, Int_t row0, Int_t row1)
4278 {
4279   //
4280   // make back propagation, in between row0 and row1
4281   //
4282   
4283   if (pt) { 
4284     fSectors = fInnerSec;
4285     Int_t  r1;
4286     //
4287     if (row1<fSectors->GetNRows()) 
4288       r1 = row1;
4289     else 
4290       r1 = fSectors->GetNRows()-1;
4291
4292     if (row0<fSectors->GetNRows()&& r1>0 )
4293       FollowBackProlongation(*pt,r1);
4294     if (row1<=fSectors->GetNRows())
4295       return 0;
4296     //
4297     r1 = row1 - fSectors->GetNRows();
4298     if (r1<=0) return 0;
4299     if (r1>=fOuterSec->GetNRows()) return 0;
4300     fSectors = fOuterSec;
4301     return FollowBackProlongation(*pt,r1);
4302   }        
4303   return 0;
4304 }
4305
4306
4307
4308
4309 void  AliTPCtrackerMI::GetShape(AliTPCseed * seed, Int_t row)
4310 {
4311   //
4312   //
4313   Float_t sd2 = TMath::Abs((fParam->GetZLength()-TMath::Abs(seed->GetZ())))*fParam->GetDiffL()*fParam->GetDiffL();
4314   //  Float_t padlength =  fParam->GetPadPitchLength(seed->fSector);
4315   Float_t padlength =  GetPadPitchLength(row);
4316   //
4317   Float_t sresy = (seed->fSector < fParam->GetNSector()/2) ? 0.2 :0.3;
4318   Float_t angulary  = seed->GetSnp();
4319   angulary = angulary*angulary/(1-angulary*angulary);
4320   seed->fCurrentSigmaY2 = sd2+padlength*padlength*angulary/12.+sresy*sresy;  
4321   //
4322   Float_t sresz = fParam->GetZSigma();
4323   Float_t angularz  = seed->GetTgl();
4324   seed->fCurrentSigmaZ2 = sd2+padlength*padlength*angularz*angularz*(1+angulary)/12.+sresz*sresz;
4325   /*
4326   Float_t wy = GetSigmaY(seed);
4327   Float_t wz = GetSigmaZ(seed);
4328   wy*=wy;
4329   wz*=wz;
4330   if (TMath::Abs(wy/seed->fCurrentSigmaY2-1)>0.0001 || TMath::Abs(wz/seed->fCurrentSigmaZ2-1)>0.0001 ){
4331     printf("problem\n");
4332   }
4333   */
4334 }
4335
4336
4337 Float_t  AliTPCtrackerMI::GetSigmaY(AliTPCseed * seed)
4338 {
4339   //
4340   //  
4341   Float_t sd2 = TMath::Abs((fParam->GetZLength()-TMath::Abs(seed->GetZ())))*fParam->GetDiffL()*fParam->GetDiffL();
4342   Float_t padlength =  fParam->GetPadPitchLength(seed->fSector);
4343   Float_t sres = (seed->fSector < fParam->GetNSector()/2) ? 0.2 :0.3;
4344   Float_t angular  = seed->GetSnp();
4345   angular = angular*angular/(1-angular*angular);
4346   //  angular*=angular;
4347   //angular  = TMath::Sqrt(angular/(1-angular));
4348   Float_t res = TMath::Sqrt(sd2+padlength*padlength*angular/12.+sres*sres);
4349   return res;
4350 }
4351 Float_t  AliTPCtrackerMI::GetSigmaZ(AliTPCseed * seed)
4352 {
4353   //
4354   //
4355   Float_t sd2 = TMath::Abs((fParam->GetZLength()-TMath::Abs(seed->GetZ())))*fParam->GetDiffL()*fParam->GetDiffL();
4356   Float_t padlength =  fParam->GetPadPitchLength(seed->fSector);
4357   Float_t sres = fParam->GetZSigma();
4358   Float_t angular  = seed->GetTgl();
4359   Float_t res = TMath::Sqrt(sd2+padlength*padlength*angular*angular/12.+sres*sres);
4360   return res;
4361 }
4362
4363
4364
4365
4366 //__________________________________________________________________________
4367 void AliTPCtrackerMI::CookLabel(AliTPCseed *t, Float_t wrong) const {
4368   //--------------------------------------------------------------------
4369   //This function "cooks" a track label. If label<0, this track is fake.
4370   //--------------------------------------------------------------------
4371   Int_t noc=t->GetNumberOfClusters();
4372   if (noc<10){
4373     printf("\nnot founded prolongation\n\n\n");
4374     t->Dump();
4375     return ;
4376   }
4377   Int_t lb[160];
4378   Int_t mx[160];
4379   AliTPCclusterMI *clusters[160];
4380   //
4381   for (Int_t i=0;i<160;i++) {
4382     clusters[i]=0;
4383     lb[i]=mx[i]=0;
4384   }
4385
4386   Int_t i;
4387   Int_t current=0;
4388   for (i=0; i<160 && current<noc; i++) {
4389      
4390      Int_t index=t->GetClusterIndex2(i);
4391      if (index<=0) continue; 
4392      if (index&0x8000) continue;
4393      //     
4394      //clusters[current]=GetClusterMI(index);
4395      if (t->fClusterPointer[i]){
4396        clusters[current]=t->fClusterPointer[i];     
4397        current++;
4398      }
4399   }
4400   noc = current;
4401
4402   Int_t lab=123456789;
4403   for (i=0; i<noc; i++) {
4404     AliTPCclusterMI *c=clusters[i];
4405     if (!c) continue;
4406     lab=TMath::Abs(c->GetLabel(0));
4407     Int_t j;
4408     for (j=0; j<noc; j++) if (lb[j]==lab || mx[j]==0) break;
4409     lb[j]=lab;
4410     (mx[j])++;
4411   }
4412
4413   Int_t max=0;
4414   for (i=0; i<noc; i++) if (mx[i]>max) {max=mx[i]; lab=lb[i];}
4415     
4416   for (i=0; i<noc; i++) {
4417     AliTPCclusterMI *c=clusters[i]; 
4418     if (!c) continue;
4419     if (TMath::Abs(c->GetLabel(1)) == lab ||
4420         TMath::Abs(c->GetLabel(2)) == lab ) max++;
4421   }
4422
4423   if ((1.- Float_t(max)/noc) > wrong) lab=-lab;
4424
4425   else {
4426      Int_t tail=Int_t(0.10*noc);
4427      max=0;
4428      Int_t ind=0;
4429      for (i=1; i<=160&&ind<tail; i++) {
4430        //       AliTPCclusterMI *c=clusters[noc-i];
4431        AliTPCclusterMI *c=clusters[i];
4432        if (!c) continue;
4433        if (lab == TMath::Abs(c->GetLabel(0)) ||
4434            lab == TMath::Abs(c->GetLabel(1)) ||
4435            lab == TMath::Abs(c->GetLabel(2))) max++;
4436        ind++;
4437      }
4438      if (max < Int_t(0.5*tail)) lab=-lab;
4439   }
4440
4441   t->SetLabel(lab);
4442
4443   //  delete[] lb;
4444   //delete[] mx;
4445   //delete[] clusters;
4446 }
4447
4448 //_________________________________________________________________________
4449 void AliTPCtrackerMI::AliTPCSector::Setup(const AliTPCParam *par, Int_t f) {
4450   //-----------------------------------------------------------------------
4451   // Setup inner sector
4452   //-----------------------------------------------------------------------
4453   if (f==0) {
4454      fAlpha=par->GetInnerAngle();
4455      fAlphaShift=par->GetInnerAngleShift();
4456      fPadPitchWidth=par->GetInnerPadPitchWidth();
4457      fPadPitchLength=par->GetInnerPadPitchLength();
4458      fN=par->GetNRowLow();
4459      fRow=new AliTPCRow[fN];
4460      for (Int_t i=0; i<fN; i++) {
4461        fRow[i].SetX(par->GetPadRowRadiiLow(i));
4462        fRow[i].fDeadZone =1.5;  //1.5 cm of dead zone
4463      }
4464   } else {
4465      fAlpha=par->GetOuterAngle();
4466      fAlphaShift=par->GetOuterAngleShift();
4467      fPadPitchWidth  = par->GetOuterPadPitchWidth();
4468      fPadPitchLength = par->GetOuter1PadPitchLength();
4469      f1PadPitchLength = par->GetOuter1PadPitchLength();
4470      f2PadPitchLength = par->GetOuter2PadPitchLength();
4471
4472      fN=par->GetNRowUp();
4473      fRow=new AliTPCRow[fN];
4474      for (Int_t i=0; i<fN; i++) {
4475        fRow[i].SetX(par->GetPadRowRadiiUp(i)); 
4476        fRow[i].fDeadZone =1.5;  // 1.5 cm of dead zone
4477      }
4478   } 
4479 }
4480
4481
4482 AliTPCtrackerMI::AliTPCRow::~AliTPCRow(){
4483   //
4484 }
4485
4486
4487
4488 //_________________________________________________________________________
4489 void 
4490 AliTPCtrackerMI::AliTPCRow::InsertCluster(const AliTPCclusterMI* c, UInt_t index) {
4491   //-----------------------------------------------------------------------
4492   // Insert a cluster into this pad row in accordence with its y-coordinate
4493   //-----------------------------------------------------------------------
4494   if (fN==kMaxClusterPerRow) {
4495     cerr<<"AliTPCRow::InsertCluster(): Too many clusters !\n"; return;
4496   }
4497   if (fN==0) {fIndex[0]=index; fClusters[fN++]=c; return;}
4498   Int_t i=Find(c->GetZ());
4499   memmove(fClusters+i+1 ,fClusters+i,(fN-i)*sizeof(AliTPCclusterMI*));
4500   memmove(fIndex   +i+1 ,fIndex   +i,(fN-i)*sizeof(UInt_t));
4501   fIndex[i]=index; fClusters[i]=c; fN++;
4502 }
4503
4504
4505 //___________________________________________________________________
4506 Int_t AliTPCtrackerMI::AliTPCRow::Find(Double_t z) const {
4507   //-----------------------------------------------------------------------
4508   // Return the index of the nearest cluster 
4509   //-----------------------------------------------------------------------
4510   if (fN==0) return 0;
4511   if (z <= fClusters[0]->GetZ()) return 0;
4512   if (z > fClusters[fN-1]->GetZ()) return fN;
4513   Int_t b=0, e=fN-1, m=(b+e)/2;
4514   for (; b<e; m=(b+e)/2) {
4515     if (z > fClusters[m]->GetZ()) b=m+1;
4516     else e=m; 
4517   }
4518   return m;
4519 }
4520
4521
4522
4523 //___________________________________________________________________
4524 AliTPCclusterMI * AliTPCtrackerMI::AliTPCRow::FindNearest(Double_t y, Double_t z, Double_t roady, Double_t roadz) const {
4525   //-----------------------------------------------------------------------
4526   // Return the index of the nearest cluster in z y 
4527   //-----------------------------------------------------------------------
4528   Float_t maxdistance = roady*roady + roadz*roadz;
4529
4530   AliTPCclusterMI *cl =0;
4531   for (Int_t i=Find(z-roadz); i<fN; i++) {
4532       AliTPCclusterMI *c=(AliTPCclusterMI*)(fClusters[i]);
4533       if (c->GetZ() > z+roadz) break;
4534       if ( (c->GetY()-y) >  roady ) continue;
4535       Float_t distance = (c->GetZ()-z)*(c->GetZ()-z)+(c->GetY()-y)*(c->GetY()-y);
4536       if (maxdistance>distance) {
4537         maxdistance = distance;
4538         cl=c;       
4539       }
4540   }
4541   return cl;      
4542 }
4543
4544 AliTPCclusterMI * AliTPCtrackerMI::AliTPCRow::FindNearest2(Double_t y, Double_t z, Double_t roady, Double_t roadz,UInt_t & index) const 
4545 {
4546   //-----------------------------------------------------------------------
4547   // Return the index of the nearest cluster in z y 
4548   //-----------------------------------------------------------------------
4549   Float_t maxdistance = roady*roady + roadz*roadz;
4550   Int_t iz1 = TMath::Max(fFastCluster[Int_t(z-roadz+254.5)]-1,0);
4551   Int_t iz2 = TMath::Min(fFastCluster[Int_t(z+roadz+255.5)]+1,fN);
4552
4553   AliTPCclusterMI *cl =0;
4554   //FindNearest3(y,z,roady,roadz,index);
4555   //  for (Int_t i=Find(z-roadz); i<fN; i++) {
4556   for (Int_t i=iz1; i<iz2; i++) {
4557       AliTPCclusterMI *c=(AliTPCclusterMI*)(fClusters[i]);
4558       if (c->GetZ() > z+roadz) break;
4559       if ( c->GetY()-y >  roady ) continue;
4560       if ( y-c->GetY() >  roady ) continue;
4561       Float_t distance = (c->GetZ()-z)*(c->GetZ()-z)+(c->GetY()-y)*(c->GetY()-y);
4562       if (maxdistance>distance) {
4563         maxdistance = distance;
4564         cl=c;       
4565         index =i;
4566         //roady = TMath::Sqrt(maxdistance);
4567       }
4568   }
4569   return cl;      
4570 }
4571
4572
4573
4574 AliTPCclusterMI * AliTPCtrackerMI::AliTPCRow::FindNearest3(Double_t y, Double_t z, Double_t roady, Double_t roadz,UInt_t & index) const 
4575 {
4576   //-----------------------------------------------------------------------
4577   // Return the index of the nearest cluster in z y 
4578   //-----------------------------------------------------------------------
4579   Float_t maxdistance = roady*roady + roadz*roadz;
4580   //  Int_t iz = Int_t(z+255.);
4581   AliTPCclusterMI *cl =0;
4582   for (Int_t i=Find(z-roadz); i<fN; i++) {
4583     //for (Int_t i=fFastCluster[iz-2]; i<fFastCluster[iz+2]; i++) {
4584       AliTPCclusterMI *c=(AliTPCclusterMI*)(fClusters[i]);
4585       if (c->GetZ() > z+roadz) break;
4586       if ( c->GetY()-y >  roady ) continue;
4587       if ( y-c->GetY() >  roady ) continue;
4588       Float_t distance = (c->GetZ()-z)*(c->GetZ()-z)+(c->GetY()-y)*(c->GetY()-y);
4589       if (maxdistance>distance) {
4590         maxdistance = distance;
4591         cl=c;       
4592         index =i;
4593         //roady = TMath::Sqrt(maxdistance);
4594       }
4595   }
4596   return cl;      
4597 }
4598
4599
4600
4601
4602 AliTPCseed::AliTPCseed():AliTPCtrack(){
4603   //
4604   fRow=0; 
4605   fRemoval =0; 
4606   for (Int_t i=0;i<200;i++) SetClusterIndex2(i,-3);
4607   for (Int_t i=0;i<160;i++) fClusterPointer[i]=0;
4608
4609   fPoints = 0;
4610   fEPoints = 0;
4611   fNFoundable =0;
4612   fNShared  =0;
4613   //  fTrackPoints =0;
4614   fRemoval = 0;
4615   fSort =0;
4616   fFirstPoint =0;
4617   fNoCluster =0;
4618   fBSigned = kFALSE;
4619   fSeed1 =-1;
4620   fSeed2 =-1;
4621 }
4622
4623 AliTPCseed::AliTPCseed(const AliTPCtrack &t):AliTPCtrack(t){
4624   fPoints = 0;
4625   fEPoints = 0;
4626   fNShared  =0; 
4627   //  fTrackPoints =0;
4628   fRemoval =0;
4629   fSort =0;
4630   for (Int_t i=0;i<160;i++) {
4631     fClusterPointer[i] = 0;
4632     Int_t index = t.GetClusterIndex(i);
4633     if (index>0) {
4634       SetClusterIndex2(i,index);
4635     }
4636     else{
4637       SetClusterIndex2(i,-3); 
4638     }    
4639   }
4640   fFirstPoint =0;
4641   fNoCluster =0;
4642   fBSigned = kFALSE;
4643   fSeed1 =-1;
4644   fSeed2 =-1;
4645 }
4646
4647 AliTPCseed::AliTPCseed(const AliKalmanTrack &t, Double_t a):AliTPCtrack(t,a){
4648   fRow=0;
4649   for (Int_t i=0;i<160;i++) {
4650     fClusterPointer[i] = 0;
4651     Int_t index = t.GetClusterIndex(i);
4652     SetClusterIndex2(i,index);
4653   }
4654   
4655   fPoints = 0;
4656   fEPoints = 0;
4657   fNFoundable =0; 
4658   fNShared  =0; 
4659   //  fTrackPoints =0;
4660   fRemoval =0;
4661   fSort = 0;
4662   fFirstPoint =0;
4663   fNoCluster =0;
4664   fBSigned = kFALSE;
4665   fSeed1 =-1;
4666   fSeed2 =-1;
4667 }
4668
4669 AliTPCseed::AliTPCseed(UInt_t index, const Double_t xx[5], const Double_t cc[15], 
4670                                         Double_t xr, Double_t alpha):      
4671   AliTPCtrack(index, xx, cc, xr, alpha) {
4672   //
4673   //
4674   fRow =0;
4675   for (Int_t i=0;i<200;i++) SetClusterIndex2(i,-3);
4676   for (Int_t i=0;i<160;i++) fClusterPointer[i]=0;
4677   fPoints = 0;
4678   fEPoints = 0;
4679   fNFoundable =0;
4680   fNShared  = 0;
4681   //  fTrackPoints =0;
4682   fRemoval =0;
4683   fSort =0;
4684   fFirstPoint =0;
4685   //  fHelixIn = new TClonesArray("AliHelix",0);
4686   //fHelixOut = new TClonesArray("AliHelix",0);
4687   fNoCluster =0;
4688   fBSigned = kFALSE;
4689   fSeed1 =-1;
4690   fSeed2 =-1;
4691 }
4692
4693 AliTPCseed::~AliTPCseed(){
4694   if (fPoints) delete fPoints;
4695   fPoints =0;
4696   if (fEPoints) delete fEPoints;
4697   fEPoints = 0;
4698   fNoCluster =0;
4699 }
4700
4701 AliTPCTrackerPoint * AliTPCseed::GetTrackPoint(Int_t i)
4702 {
4703   //
4704   // 
4705   return &fTrackPoints[i];
4706 }
4707
4708 void AliTPCseed::RebuildSeed()
4709 {
4710   //
4711   // rebuild seed to be ready for storing
4712   AliTPCclusterMI cldummy;
4713   cldummy.SetQ(0);
4714   AliTPCTrackPoint pdummy;
4715   pdummy.GetTPoint().fIsShared = 10;
4716   for (Int_t i=0;i<160;i++){
4717     AliTPCclusterMI * cl0 = fClusterPointer[i];
4718     AliTPCTrackPoint *trpoint = (AliTPCTrackPoint*)fPoints->UncheckedAt(i);     
4719     if (cl0){
4720       trpoint->GetTPoint() = *(GetTrackPoint(i));
4721       trpoint->GetCPoint() = *cl0;
4722       trpoint->GetCPoint().SetQ(TMath::Abs(cl0->GetQ()));
4723     }
4724     else{
4725       *trpoint = pdummy;
4726       trpoint->GetCPoint()= cldummy;
4727     }
4728     
4729   }
4730
4731 }
4732
4733
4734 Double_t AliTPCseed::GetDensityFirst(Int_t n)
4735 {
4736   //
4737   //
4738   // return cluster for n rows bellow first point
4739   Int_t nfoundable = 1;
4740   Int_t nfound      = 1;
4741   for (Int_t i=fLastPoint-1;i>0&&nfoundable<n; i--){
4742     Int_t index = GetClusterIndex2(i);
4743     if (index!=-1) nfoundable++;
4744     if (index>0) nfound++;
4745   }
4746   if (nfoundable<n) return 0;
4747   return Double_t(nfound)/Double_t(nfoundable);
4748
4749 }
4750
4751
4752 void AliTPCseed::GetClusterStatistic(Int_t first, Int_t last, Int_t &found, Int_t &foundable, Int_t &shared, Bool_t plus2)
4753 {
4754   // get cluster stat.  on given region
4755   //
4756   found       = 0;
4757   foundable   = 0;
4758   shared      =0;
4759   for (Int_t i=first;i<last; i++){
4760     Int_t index = GetClusterIndex2(i);
4761     if (index!=-1) foundable++;
4762     if (fClusterPointer[i]) {
4763       found++;
4764     }
4765     else 
4766       continue;
4767
4768     if (fClusterPointer[i]->IsUsed(10)) {
4769       shared++;
4770       continue;
4771     }
4772     if (!plus2) continue; //take also neighborhoud
4773     //
4774     if ( (i>0) && fClusterPointer[i-1]){
4775       if (fClusterPointer[i-1]->IsUsed(10)) {
4776         shared++;
4777         continue;
4778       }
4779     }
4780     if ( fClusterPointer[i+1]){
4781       if (fClusterPointer[i+1]->IsUsed(10)) {
4782         shared++;
4783         continue;
4784       }
4785     }
4786     
4787   }
4788   if (shared>found){
4789     printf("problem\n");
4790   }
4791 }
4792
4793 //_____________________________________________________________________________
4794 void AliTPCseed::CookdEdx(Double_t low, Double_t up,Int_t i1, Int_t i2, Bool_t onlyused) {
4795   //-----------------------------------------------------------------
4796   // This funtion calculates dE/dX within the "low" and "up" cuts.
4797   //-----------------------------------------------------------------
4798
4799   Float_t amp[200];
4800   Float_t angular[200];
4801   Float_t weight[200];
4802   Int_t index[200];
4803   //Int_t nc = 0;
4804   //  TClonesArray & arr = *fPoints; 
4805   Float_t meanlog = 100.;
4806   
4807   Float_t mean[4]  = {0,0,0,0};
4808   Float_t sigma[4] = {1000,1000,1000,1000};
4809   Int_t nc[4]      = {0,0,0,0};
4810   Float_t norm[4]    = {1000,1000,1000,1000};
4811   //
4812   //
4813   fNShared =0;
4814
4815   for (Int_t of =0; of<4; of++){    
4816     for (Int_t i=of+i1;i<i2;i+=4)
4817       {
4818         Int_t index = fIndex[i];
4819         if (index<0||index&0x8000) continue;
4820
4821         //AliTPCTrackPoint * point = (AliTPCTrackPoint *) arr.At(i);
4822         AliTPCTrackerPoint * point = GetTrackPoint(i);
4823         //AliTPCTrackerPoint * pointm = GetTrackPoint(i-1);
4824         //AliTPCTrackerPoint * pointp = 0;
4825         //if (i<159) pointp = GetTrackPoint(i+1);
4826
4827         if (point==0) continue;
4828         AliTPCclusterMI * cl = fClusterPointer[i];
4829         if (cl==0) continue;    
4830         if (onlyused && (!cl->IsUsed(10))) continue;
4831         if (cl->IsUsed(11)) {
4832           fNShared++;
4833           continue;
4834         }
4835         Int_t   type   = cl->GetType();
4836         //if (point->fIsShared){
4837         //  fNShared++;
4838         //  continue;
4839         //}
4840         //if (pointm) 
4841         //  if (pointm->fIsShared) continue;
4842         //if (pointp) 
4843         //  if (pointp->fIsShared) continue;
4844
4845         if (type<0) continue;
4846         //if (type>10) continue;       
4847         //if (point->GetErrY()==0) continue;
4848         //if (point->GetErrZ()==0) continue;
4849
4850         //Float_t ddy = (point->GetY()-cl->GetY())/point->GetErrY();
4851         //Float_t ddz = (point->GetZ()-cl->GetZ())/point->GetErrZ();
4852         //if ((ddy*ddy+ddz*ddz)>10) continue; 
4853
4854
4855         //      if (point->GetCPoint().GetMax()<5) continue;
4856         if (cl->GetMax()<5) continue;
4857         Float_t angley = point->GetAngleY();
4858         Float_t anglez = point->GetAngleZ();
4859
4860         Float_t rsigmay2 =  point->GetSigmaY();
4861         Float_t rsigmaz2 =  point->GetSigmaZ();
4862         /*
4863         Float_t ns = 1.;
4864         if (pointm){
4865           rsigmay +=  pointm->GetTPoint().GetSigmaY();
4866           rsigmaz +=  pointm->GetTPoint().GetSigmaZ();
4867           ns+=1.;
4868         }
4869         if (pointp){
4870           rsigmay +=  pointp->GetTPoint().GetSigmaY();
4871           rsigmaz +=  pointp->GetTPoint().GetSigmaZ();
4872           ns+=1.;
4873         }
4874         rsigmay/=ns;
4875         rsigmaz/=ns;
4876         */
4877
4878         Float_t rsigma = TMath::Sqrt(rsigmay2*rsigmaz2);
4879
4880         Float_t ampc   = 0;     // normalization to the number of electrons
4881         if (i>64){
4882           //      ampc = 1.*point->GetCPoint().GetMax();
4883           ampc = 1.*cl->GetMax();
4884           //ampc = 1.*point->GetCPoint().GetQ();          
4885           //      AliTPCClusterPoint & p = point->GetCPoint();
4886           //      Float_t dy = TMath::Abs(Int_t( TMath::Abs(p.GetY()/0.6)) - TMath::Abs(p.GetY()/0.6)+0.5);
4887           // Float_t iz =  (250.0-TMath::Abs(p.GetZ())+0.11)/0.566;
4888           //Float_t dz = 
4889           //  TMath::Abs( Int_t(iz) - iz + 0.5);
4890           //ampc *= 1.15*(1-0.3*dy);
4891           //ampc *= 1.15*(1-0.3*dz);
4892           //      Float_t zfactor = (1.05-0.0004*TMath::Abs(point->GetCPoint().GetZ()));
4893           //ampc               *=zfactor; 
4894         }
4895         else{ 
4896           //ampc = 1.0*point->GetCPoint().GetMax(); 
4897           ampc = 1.0*cl->GetMax(); 
4898           //ampc = 1.0*point->GetCPoint().GetQ(); 
4899           //AliTPCClusterPoint & p = point->GetCPoint();
4900           // Float_t dy = TMath::Abs(Int_t( TMath::Abs(p.GetY()/0.4)) - TMath::Abs(p.GetY()/0.4)+0.5);
4901           //Float_t iz =  (250.0-TMath::Abs(p.GetZ())+0.11)/0.566;
4902           //Float_t dz = 
4903           //  TMath::Abs( Int_t(iz) - iz + 0.5);
4904
4905           //ampc *= 1.15*(1-0.3*dy);
4906           //ampc *= 1.15*(1-0.3*dz);
4907           //    Float_t zfactor = (1.02-0.000*TMath::Abs(point->GetCPoint().GetZ()));
4908           //ampc               *=zfactor; 
4909
4910         }
4911         ampc *= 2.0;     // put mean value to channel 50
4912         //ampc *= 0.58;     // put mean value to channel 50
4913         Float_t w      =  1.;
4914         //      if (type>0)  w =  1./(type/2.-0.5); 
4915         //      Float_t z = TMath::Abs(cl->GetZ());
4916         if (i<64) {
4917           ampc /= 0.6;
4918           //ampc /= (1+0.0008*z);
4919         } else
4920           if (i>128){
4921             ampc /=1.5;
4922             //ampc /= (1+0.0008*z);
4923           }else{
4924             //ampc /= (1+0.0008*z);
4925           }
4926         
4927         if (type<0) {  //amp at the border - lower weight
4928           // w*= 2.;
4929           
4930           continue;
4931         }
4932         if (rsigma>1.5) ampc/=1.3;  // if big backround
4933         amp[nc[of]]        = ampc;
4934         angular[nc[of]]    = TMath::Sqrt(1.+angley*angley+anglez*anglez);
4935         weight[nc[of]]     = w;
4936         nc[of]++;
4937       }
4938     
4939     TMath::Sort(nc[of],amp,index,kFALSE);
4940     Float_t sumamp=0;
4941     Float_t sumamp2=0;
4942     Float_t sumw=0;
4943     //meanlog = amp[index[Int_t(nc[of]*0.33)]];
4944     meanlog = 50;
4945     for (Int_t i=int(nc[of]*low+0.5);i<int(nc[of]*up+0.5);i++){
4946       Float_t ampl      = amp[index[i]]/angular[index[i]];
4947       ampl              = meanlog*TMath::Log(1.+ampl/meanlog);
4948       //
4949       sumw    += weight[index[i]]; 
4950       sumamp  += weight[index[i]]*ampl;
4951       sumamp2 += weight[index[i]]*ampl*ampl;
4952       norm[of]    += angular[index[i]]*weight[index[i]];
4953     }
4954     if (sumw<1){ 
4955       SetdEdx(0);  
4956     }
4957     else {
4958       norm[of] /= sumw;
4959       mean[of]  = sumamp/sumw;
4960       sigma[of] = sumamp2/sumw-mean[of]*mean[of];
4961       if (sigma[of]>0.1) 
4962         sigma[of] = TMath::Sqrt(sigma[of]);
4963       else
4964         sigma[of] = 1000;
4965       
4966     mean[of] = (TMath::Exp(mean[of]/meanlog)-1)*meanlog;
4967     //mean  *=(1-0.02*(sigma/(mean*0.17)-1.));
4968     //mean *=(1-0.1*(norm-1.));
4969     }
4970   }
4971
4972   Float_t dedx =0;
4973   fSdEdx =0;
4974   fMAngular =0;
4975   //  mean[0]*= (1-0.05*(sigma[0]/(0.01+mean[1]*0.18)-1));
4976   //  mean[1]*= (1-0.05*(sigma[1]/(0.01+mean[0]*0.18)-1));
4977
4978   
4979   //  dedx = (mean[0]* TMath::Sqrt((1.+nc[0]))+ mean[1]* TMath::Sqrt((1.+nc[1])) )/ 
4980   //  (  TMath::Sqrt((1.+nc[0]))+TMath::Sqrt((1.+nc[1])));
4981
4982   Int_t norm2 = 0;
4983   Int_t norm3 = 0;
4984   for (Int_t i =0;i<4;i++){
4985     if (nc[i]>2&&nc[i]<1000){
4986       dedx      += mean[i] *nc[i];
4987       fSdEdx    += sigma[i]*(nc[i]-2);
4988       fMAngular += norm[i] *nc[i];    
4989       norm2     += nc[i];
4990       norm3     += nc[i]-2;
4991     }
4992     fDEDX[i]  = mean[i];             
4993     fSDEDX[i] = sigma[i];            
4994     fNCDEDX[i]= nc[i]; 
4995   }
4996
4997   if (norm3>0){
4998     dedx   /=norm2;
4999     fSdEdx /=norm3;
5000     fMAngular/=norm2;
5001   }
5002   else{
5003     SetdEdx(0);
5004     return;
5005   }
5006   //  Float_t dedx1 =dedx;
5007   /*
5008   dedx =0;
5009   for (Int_t i =0;i<4;i++){
5010     if (nc[i]>2&&nc[i]<1000){
5011       mean[i]   = mean[i]*(1-0.12*(sigma[i]/(fSdEdx)-1.));
5012       dedx      += mean[i] *nc[i];
5013     }
5014     fDEDX[i]  = mean[i];                
5015   }
5016   dedx /= norm2;
5017   */
5018
5019   
5020   SetdEdx(dedx);
5021     
5022   //mi deDX
5023
5024
5025
5026   //Very rough PID
5027   Double_t p=TMath::Sqrt((1.+ GetTgl()*GetTgl())/(Get1Pt()*Get1Pt()));
5028
5029   if (p<0.6) {
5030     if (dedx < 39.+ 12./(p+0.25)/(p+0.25)) { SetMass(0.13957); return;}
5031     if (dedx < 39.+ 12./p/p) { SetMass(0.49368); return;}
5032     SetMass(0.93827); return;
5033   }
5034
5035   if (p<1.2) {
5036     if (dedx < 39.+ 12./(p+0.25)/(p+0.25)) { SetMass(0.13957); return;}
5037     SetMass(0.93827); return;
5038   }
5039
5040   SetMass(0.13957); return;
5041
5042 }
5043
5044
5045
5046 /*
5047
5048
5049
5050 void AliTPCseed::CookdEdx2(Double_t low, Double_t up) {
5051   //-----------------------------------------------------------------
5052   // This funtion calculates dE/dX within the "low" and "up" cuts.
5053   //-----------------------------------------------------------------
5054
5055   Float_t amp[200];
5056   Float_t angular[200];
5057   Float_t weight[200];
5058   Int_t index[200];
5059   Bool_t inlimit[200];
5060   for (Int_t i=0;i<200;i++) inlimit[i]=kFALSE;
5061   for (Int_t i=0;i<200;i++) amp[i]=10000;
5062   for (Int_t i=0;i<200;i++) angular[i]= 1;;
5063   
5064
5065   //
5066   Float_t meanlog = 100.;
5067   Int_t indexde[4]={0,64,128,160};
5068
5069   Float_t amean     =0;
5070   Float_t asigma    =0;
5071   Float_t anc       =0;
5072   Float_t anorm     =0;
5073
5074   Float_t mean[4]  = {0,0,0,0};
5075   Float_t sigma[4] = {1000,1000,1000,1000};
5076   Int_t nc[4]      = {0,0,0,0};
5077   Float_t norm[4]    = {1000,1000,1000,1000};
5078   //
5079   //
5080   fNShared =0;
5081
5082   //  for (Int_t of =0; of<3; of++){    
5083   //  for (Int_t i=indexde[of];i<indexde[of+1];i++)
5084   for (Int_t i =0; i<160;i++)
5085     {
5086         AliTPCTrackPoint * point = GetTrackPoint(i);
5087         if (point==0) continue;
5088         if (point->fIsShared){
5089           fNShared++;     
5090           continue;
5091         }
5092         Int_t   type   = point->GetCPoint().GetType();
5093         if (type<0) continue;
5094         if (point->GetCPoint().GetMax()<5) continue;
5095         Float_t angley = point->GetTPoint().GetAngleY();
5096         Float_t anglez = point->GetTPoint().GetAngleZ();
5097         Float_t rsigmay =  point->GetCPoint().GetSigmaY();
5098         Float_t rsigmaz =  point->GetCPoint().GetSigmaZ();
5099         Float_t rsigma = TMath::Sqrt(rsigmay*rsigmaz);
5100
5101         Float_t ampc   = 0;     // normalization to the number of electrons
5102         if (i>64){
5103           ampc =  point->GetCPoint().GetMax();
5104         }
5105         else{ 
5106           ampc = point->GetCPoint().GetMax(); 
5107         }
5108         ampc *= 2.0;     // put mean value to channel 50
5109         //      ampc *= 0.565;     // put mean value to channel 50
5110
5111         Float_t w      =  1.;
5112         Float_t z = TMath::Abs(point->GetCPoint().GetZ());
5113         if (i<64) {
5114           ampc /= 0.63;
5115         } else
5116           if (i>128){
5117             ampc /=1.51;
5118           }             
5119         if (type<0) {  //amp at the border - lower weight                 
5120           continue;
5121         }
5122         if (rsigma>1.5) ampc/=1.3;  // if big backround
5123         angular[i]    = TMath::Sqrt(1.+angley*angley+anglez*anglez);
5124         amp[i]        = ampc/angular[i];
5125         weight[i]     = w;
5126         anc++;
5127     }
5128
5129   TMath::Sort(159,amp,index,kFALSE);
5130   for (Int_t i=int(anc*low+0.5);i<int(anc*up+0.5);i++){      
5131     inlimit[index[i]] = kTRUE;  // take all clusters
5132   }
5133   
5134   //  meanlog = amp[index[Int_t(anc*0.3)]];
5135   meanlog =10000.;
5136   for (Int_t of =0; of<3; of++){    
5137     Float_t sumamp=0;
5138     Float_t sumamp2=0;
5139     Float_t sumw=0;    
5140    for (Int_t i=indexde[of];i<indexde[of+1];i++)
5141       {
5142         if (inlimit[i]==kFALSE) continue;
5143         Float_t ampl      = amp[i];
5144         ///angular[i];
5145         ampl              = meanlog*TMath::Log(1.+ampl/meanlog);
5146         //
5147         sumw    += weight[i]; 
5148         sumamp  += weight[i]*ampl;
5149         sumamp2 += weight[i]*ampl*ampl;
5150         norm[of]    += angular[i]*weight[i];
5151         nc[of]++;
5152       }
5153    if (sumw<1){ 
5154      SetdEdx(0);  
5155    }
5156    else {
5157      norm[of] /= sumw;
5158      mean[of]  = sumamp/sumw;
5159      sigma[of] = sumamp2/sumw-mean[of]*mean[of];
5160      if (sigma[of]>0.1) 
5161        sigma[of] = TMath::Sqrt(sigma[of]);
5162      else
5163        sigma[of] = 1000;      
5164      mean[of] = (TMath::Exp(mean[of]/meanlog)-1)*meanlog;
5165    }
5166   }
5167     
5168   Float_t dedx =0;
5169   fSdEdx =0;
5170   fMAngular =0;
5171   //
5172   Int_t norm2 = 0;
5173   Int_t norm3 = 0;
5174   Float_t www[3] = {12.,14.,17.};
5175   //Float_t www[3] = {1.,1.,1.};
5176
5177   for (Int_t i =0;i<3;i++){
5178     if (nc[i]>2&&nc[i]<1000){
5179       dedx      += mean[i] *nc[i]*www[i]/sigma[i];
5180       fSdEdx    += sigma[i]*(nc[i]-2)*www[i]/sigma[i];
5181       fMAngular += norm[i] *nc[i];    
5182       norm2     += nc[i]*www[i]/sigma[i];
5183       norm3     += (nc[i]-2)*www[i]/sigma[i];
5184     }
5185     fDEDX[i]  = mean[i];             
5186     fSDEDX[i] = sigma[i];            
5187     fNCDEDX[i]= nc[i]; 
5188   }
5189
5190   if (norm3>0){
5191     dedx   /=norm2;
5192     fSdEdx /=norm3;
5193     fMAngular/=norm2;
5194   }
5195   else{
5196     SetdEdx(0);
5197     return;
5198   }
5199   //  Float_t dedx1 =dedx;
5200   
5201   dedx =0;
5202   Float_t norm4 = 0;
5203   for (Int_t i =0;i<3;i++){
5204     if (nc[i]>2&&nc[i]<1000&&sigma[i]>3){
5205       //mean[i]   = mean[i]*(1+0.08*(sigma[i]/(fSdEdx)-1.));
5206       dedx      += mean[i] *(nc[i])/(sigma[i]);
5207       norm4     += (nc[i])/(sigma[i]);
5208     }
5209     fDEDX[i]  = mean[i];                
5210   }
5211   if (norm4>0) dedx /= norm4;
5212   
5213
5214   
5215   SetdEdx(dedx);
5216     
5217   //mi deDX
5218
5219 }
5220
5221 */