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