]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ITS/AliITStrackerMI.cxx
New version of the V0 finder (M.Ivanov)
[u/mrichter/AliRoot.git] / ITS / AliITStrackerMI.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 //               Implementation of the ITS tracker class
18 //    It reads AliITSclusterV2 clusters and creates AliITStrackMI tracks
19 //                   and fills with them the ESD
20 //          Origin: Marian Ivanov, CERN, Marian.Ivanov@cern.ch 
21 //     dEdx analysis by: Boris Batyunya, JINR, Boris.Batiounia@cern.ch
22 //     
23 //-------------------------------------------------------------------------
24 #include "AliITSrecoV2.h"
25 #include <TTree.h>
26 #include "AliITSgeom.h"
27 #include "AliESD.h"
28 #include "AliITSclusterV2.h"
29 #include "AliITStrackerMI.h"
30 #include "TMatrixD.h"
31 #include "TFile.h"
32 #include "TTree.h"
33 #include "AliHelix.h"
34 #include "AliESDV0MI.h"
35 #include "AliLog.h"
36 #include "TTreeStream.h"
37
38 ClassImp(AliITStrackerMI)
39
40
41
42 AliITStrackerMI::AliITSlayer AliITStrackerMI::fgLayers[kMaxLayer]; // ITS layers
43
44 AliITStrackerMI::AliITStrackerMI(const AliITSgeom *geom) : AliTracker() {
45   //--------------------------------------------------------------------
46   //This is the AliITStrackerMI constructor
47   //--------------------------------------------------------------------
48   fCoeficients = 0;
49   fAfterV0     = kFALSE;
50   AliITSgeom *g=(AliITSgeom*)geom;
51   Float_t x,y,z;
52   Int_t i;
53   for (i=1; i<kMaxLayer+1; i++) {
54     Int_t nlad=g->GetNladders(i);
55     Int_t ndet=g->GetNdetectors(i);
56
57     g->GetTrans(i,1,1,x,y,z); 
58     Double_t r=TMath::Sqrt(x*x + y*y);
59     Double_t poff=TMath::ATan2(y,x);
60     Double_t zoff=z;
61
62     g->GetTrans(i,1,2,x,y,z);
63     r += TMath::Sqrt(x*x + y*y);
64     g->GetTrans(i,2,1,x,y,z);
65     r += TMath::Sqrt(x*x + y*y);
66     g->GetTrans(i,2,2,x,y,z);
67     r += TMath::Sqrt(x*x + y*y);
68     r*=0.25;
69
70     new (fgLayers+i-1) AliITSlayer(r,poff,zoff,nlad,ndet);
71
72     for (Int_t j=1; j<nlad+1; j++) {
73       for (Int_t k=1; k<ndet+1; k++) { //Fill this layer with detectors
74         Float_t x,y,zshift; g->GetTrans(i,j,k,x,y,zshift); 
75         Double_t rot[9]; g->GetRotMatrix(i,j,k,rot);
76
77         Double_t phi=TMath::ATan2(rot[1],rot[0])+TMath::Pi();
78         phi+=TMath::Pi()/2;
79         if (i==1) phi+=TMath::Pi();
80         Double_t cp=TMath::Cos(phi), sp=TMath::Sin(phi);
81         Double_t r=x*cp+y*sp;
82
83         AliITSdetector &det=fgLayers[i-1].GetDetector((j-1)*ndet + k-1); 
84         new(&det) AliITSdetector(r,phi); 
85       } 
86     }  
87
88   }
89
90   fI=kMaxLayer;
91
92   fPass=0;
93   fConstraint[0]=1; fConstraint[1]=0;
94
95   Double_t xyz[]={kXV,kYV,kZV}, ers[]={kSigmaXV,kSigmaYV,kSigmaZV}; 
96   SetVertex(xyz,ers);
97
98   for (Int_t i=0; i<kMaxLayer; i++) fLayersNotToSkip[i]=kLayersNotToSkip[i];
99   fLastLayerToTrackTo=kLastLayerToTrackTo;
100   for (Int_t i=0;i<100000;i++){
101     fBestTrackIndex[i]=0;
102   }
103   //
104   fDebugStreamer = new TTreeSRedirector("ITSdebug.root");
105
106 }
107
108 AliITStrackerMI::~AliITStrackerMI()
109 {
110   //
111   //destructor
112   //
113   if (fCoeficients) delete []fCoeficients;
114   if (fDebugStreamer) {
115     //fDebugStreamer->Close();
116     delete fDebugStreamer;
117   }
118 }
119
120 void AliITStrackerMI::SetLayersNotToSkip(Int_t *l) {
121   //--------------------------------------------------------------------
122   //This function set masks of the layers which must be not skipped
123   //--------------------------------------------------------------------
124   for (Int_t i=0; i<kMaxLayer; i++) fLayersNotToSkip[i]=l[i];
125 }
126
127 Int_t AliITStrackerMI::LoadClusters(TTree *cTree) {
128   //--------------------------------------------------------------------
129   //This function loads ITS clusters
130   //--------------------------------------------------------------------
131   TBranch *branch=cTree->GetBranch("Clusters");
132   if (!branch) { 
133     Error("LoadClusters"," can't get the branch !\n");
134     return 1;
135   }
136
137   TClonesArray dummy("AliITSclusterV2",10000), *clusters=&dummy;
138   branch->SetAddress(&clusters);
139
140   Int_t j=0;
141   Int_t detector=0;
142   for (Int_t i=0; i<kMaxLayer; i++) {
143     Int_t ndet=fgLayers[i].GetNdetectors();
144     Int_t jmax = j + fgLayers[i].GetNladders()*ndet;
145     for (; j<jmax; j++) {           
146       if (!cTree->GetEvent(j)) continue;
147       Int_t ncl=clusters->GetEntriesFast();
148       SignDeltas(clusters,GetZ());
149       while (ncl--) {
150         AliITSclusterV2 *c=(AliITSclusterV2*)clusters->UncheckedAt(ncl);
151         detector = c->GetDetectorIndex();
152         fgLayers[i].InsertCluster(new AliITSclusterV2(*c));
153       }
154       clusters->Delete();
155       //add dead zone virtual "cluster"      
156       if (i<2){
157         for (Float_t ydead = 0; ydead < 1.31 ; ydead+=(i+1.)*0.018){     
158           Int_t lab[4] = {0,0,0,detector};
159           Int_t info[3] = {0,0,0};
160           Float_t hit[5]={0,0,0.004/12.,0.001/12.,0};
161           if (i==0) hit[0] =ydead-0.4;
162           if (i==1) hit[0]=ydead-3.75; 
163           hit[1] =-0.04;
164           if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<2.) 
165             fgLayers[i].InsertCluster(new AliITSclusterV2(lab, hit, info));
166           hit[1]=-7.05;
167           if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<2.) 
168             fgLayers[i].InsertCluster(new AliITSclusterV2(lab, hit, info));
169           hit[1]=-7.15;
170           if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<2.) 
171             fgLayers[i].InsertCluster(new AliITSclusterV2(lab, hit, info));
172           hit[1] =0.06;
173           if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<2.) 
174             fgLayers[i].InsertCluster(new AliITSclusterV2(lab, hit, info));
175           hit[1]=7.05;
176           if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<2.) 
177             fgLayers[i].InsertCluster(new AliITSclusterV2(lab, hit, info));
178           hit[1]=7.25;
179           if (TMath::Abs(fgLayers[i].GetDetector(detector).GetZmax()-hit[1])<2.) 
180             fgLayers[i].InsertCluster(new AliITSclusterV2(lab, hit, info));       
181         }
182       }
183       
184     }
185     //
186     fgLayers[i].ResetRoad(); //road defined by the cluster density
187     fgLayers[i].SortClusters();
188   }
189
190   return 0;
191 }
192
193 void AliITStrackerMI::UnloadClusters() {
194   //--------------------------------------------------------------------
195   //This function unloads ITS clusters
196   //--------------------------------------------------------------------
197   for (Int_t i=0; i<kMaxLayer; i++) fgLayers[i].ResetClusters();
198 }
199
200 static Int_t CorrectForDeadZoneMaterial(AliITStrackMI *t) {
201   //--------------------------------------------------------------------
202   // Correction for the material between the TPC and the ITS
203   // (should it belong to the TPC code ?)
204   //--------------------------------------------------------------------
205   Double_t riw=80., diw=0.0053, x0iw=30; // TPC inner wall ? 
206   Double_t rcd=61., dcd=0.0053, x0cd=30; // TPC "central drum" ?
207   Double_t yr=12.8, dr=0.03; // rods ?
208   Double_t zm=0.2, dm=0.40;  // membrane
209   //Double_t rr=52., dr=0.19, x0r=24., yyr=7.77; //rails
210   Double_t rs=50., ds=0.001; // something belonging to the ITS (screen ?)
211
212   if (t->GetX() > riw) {
213      if (!t->PropagateTo(riw,diw,x0iw)) return 1;
214      if (TMath::Abs(t->GetY())>yr) t->CorrectForMaterial(dr); 
215      if (TMath::Abs(t->GetZ())<zm) t->CorrectForMaterial(dm); 
216      if (!t->PropagateTo(rcd,dcd,x0cd)) return 1;
217      //Double_t x,y,z; t->GetGlobalXYZat(rr,x,y,z);
218      //if (TMath::Abs(y)<yyr) t->PropagateTo(rr,dr,x0r); 
219      if (!t->PropagateTo(rs,ds)) return 1;
220   } else if (t->GetX() < rs) {
221      if (!t->PropagateTo(rs,-ds)) return 1;
222      //Double_t x,y,z; t->GetGlobalXYZat(rr,x,y,z);
223      //if (TMath::Abs(y)<yyr) t->PropagateTo(rr,-dr,x0r); 
224      if (!t->PropagateTo(rcd,-dcd,x0cd)) return 1;
225      if (!t->PropagateTo(riw+0.001,-diw,x0iw)) return 1;
226   } else {
227   ::Error("CorrectForDeadZoneMaterial","track is already in the dead zone !");
228     return 1;
229   }
230   
231   return 0;
232 }
233
234 Int_t AliITStrackerMI::Clusters2Tracks(AliESD *event) {
235   //--------------------------------------------------------------------
236   // This functions reconstructs ITS tracks
237   // The clusters must be already loaded !
238   //--------------------------------------------------------------------
239   TObjArray itsTracks(15000);
240   fOriginal.Clear();
241   fEsd = event;         // store pointer to the esd 
242   {/* Read ESD tracks */
243     Int_t nentr=event->GetNumberOfTracks();
244     Info("Clusters2Tracks", "Number of ESD tracks: %d\n", nentr);
245     while (nentr--) {
246       AliESDtrack *esd=event->GetTrack(nentr);
247
248       if ((esd->GetStatus()&AliESDtrack::kTPCin)==0) continue;
249       if (esd->GetStatus()&AliESDtrack::kTPCout) continue;
250       if (esd->GetStatus()&AliESDtrack::kITSin) continue;
251       if (esd->GetKinkIndex(0)>0) continue;   //kink daughter
252       AliITStrackMI *t=0;
253       try {
254         t=new AliITStrackMI(*esd);
255       } catch (const Char_t *msg) {
256         //Warning("Clusters2Tracks",msg);
257         delete t;
258         continue;
259       }
260       t->fD[0] = t->GetD(GetX(),GetY());
261       t->fD[1] = t->GetZat(GetX())-GetZ(); 
262       Double_t vdist = TMath::Sqrt(t->fD[0]*t->fD[0]+t->fD[1]*t->fD[1]);
263       if (t->GetMass()<0.13) t->SetMass(0.13957); // MI look to the esd - mass hypothesys  !!!!!!!!!!!
264       // write expected q
265       t->fExpQ = TMath::Max(0.8*t->fESDtrack->GetTPCsignal(),30.);
266
267       if (esd->GetV0Index(0)>0 && t->fD[0]<30){
268         //track - can be  V0 according to TPC
269       }
270       else{     
271         if (TMath::Abs(t->fD[0])>10) {
272           delete t;
273           continue;
274         }
275         
276         if (TMath::Abs(vdist)>20) {
277           delete t;
278           continue;
279         }
280         if (TMath::Abs(1/t->Get1Pt())<0.120) {
281           delete t;
282           continue;
283         }
284         
285         if (CorrectForDeadZoneMaterial(t)!=0) {
286           //Warning("Clusters2Tracks",
287           //        "failed to correct for the material in the dead zone !\n");
288           delete t;
289           continue;
290         }
291       }
292       t->fReconstructed = kFALSE;
293       itsTracks.AddLast(t);
294       fOriginal.AddLast(t);
295     }
296   } /* End Read ESD tracks */
297
298   itsTracks.Sort();
299   fOriginal.Sort();
300   Int_t nentr=itsTracks.GetEntriesFast();
301   fTrackHypothesys.Expand(nentr);
302   fBestHypothesys.Expand(nentr);
303   MakeCoeficients(nentr);
304   Int_t ntrk=0;
305   for (fPass=0; fPass<2; fPass++) {
306      Int_t &constraint=fConstraint[fPass]; if (constraint<0) continue;
307      for (Int_t i=0; i<nentr; i++) {
308 //       cerr<<fPass<<"    "<<i<<'\r';
309        fCurrentEsdTrack = i;
310        AliITStrackMI *t=(AliITStrackMI*)itsTracks.UncheckedAt(i);
311        if (t==0) continue;              //this track has been already tracked
312        if (t->fReconstructed&&(t->fNUsed<1.5)) continue;  //this track was  already  "succesfully" reconstructed
313        if ( (TMath::Abs(t->GetD(GetX(),GetY()))  >3.) && fConstraint[fPass]) continue;
314        if ( (TMath::Abs(t->GetZat(GetX())-GetZ())>3.) && fConstraint[fPass]) continue;
315
316        Int_t tpcLabel=t->GetLabel(); //save the TPC track label       
317        fI = 6;
318        ResetTrackToFollow(*t);
319        ResetBestTrack();
320        FollowProlongationTree(t,i,fConstraint[fPass]);
321
322        SortTrackHypothesys(fCurrentEsdTrack,20,0);  //MI change
323        //
324        AliITStrackMI * besttrack = GetBestHypothesys(fCurrentEsdTrack,t,15);
325        if (!besttrack) continue;
326        besttrack->SetLabel(tpcLabel);
327        //       besttrack->CookdEdx();
328        CookdEdx(besttrack);
329        besttrack->fFakeRatio=1.;
330        CookLabel(besttrack,0.); //For comparison only
331        UpdateESDtrack(besttrack,AliESDtrack::kITSin);
332
333        /*       
334        if ( besttrack->GetNumberOfClusters()<6 && fConstraint[fPass]) {  
335          continue;
336        }
337        if (besttrack->fChi2MIP[0]+besttrack->fNUsed>3.5) continue;
338        if ( (TMath::Abs(besttrack->fD[0]*besttrack->fD[0]+besttrack->fD[1]*besttrack->fD[1])>0.1) && fConstraint[fPass])  continue;      
339        //delete itsTracks.RemoveAt(i);
340        */
341        if (fConstraint[fPass]&&(!besttrack->IsGoldPrimary())) continue;  //to be tracked also without vertex constrain 
342
343
344        t->fReconstructed = kTRUE;
345        ntrk++;                     
346      }
347      GetBestHypothesysMIP(itsTracks); 
348   }
349
350   //GetBestHypothesysMIP(itsTracks);
351   UpdateTPCV0(event);
352   FindV02(event);
353   fAfterV0 = kTRUE;
354   //GetBestHypothesysMIP(itsTracks);
355   //
356   itsTracks.Delete();
357   //
358   Int_t entries = fTrackHypothesys.GetEntriesFast();
359   for (Int_t ientry=0;ientry<entries;ientry++){
360     TObjArray * array =(TObjArray*)fTrackHypothesys.UncheckedAt(ientry);
361     if (array) array->Delete();
362     delete fTrackHypothesys.RemoveAt(ientry); 
363   }
364
365   fTrackHypothesys.Delete();
366   fBestHypothesys.Delete();
367   fOriginal.Clear();
368   delete []fCoeficients;
369   fCoeficients=0;
370   Info("Clusters2Tracks","Number of prolonged tracks: %d\n",ntrk);
371   
372   return 0;
373 }
374
375
376 Int_t AliITStrackerMI::PropagateBack(AliESD *event) {
377   //--------------------------------------------------------------------
378   // This functions propagates reconstructed ITS tracks back
379   // The clusters must be loaded !
380   //--------------------------------------------------------------------
381   Int_t nentr=event->GetNumberOfTracks();
382   Info("PropagateBack", "Number of ESD tracks: %d\n", nentr);
383
384   Int_t ntrk=0;
385   for (Int_t i=0; i<nentr; i++) {
386      AliESDtrack *esd=event->GetTrack(i);
387
388      if ((esd->GetStatus()&AliESDtrack::kITSin)==0) continue;
389      if (esd->GetStatus()&AliESDtrack::kITSout) continue;
390
391      AliITStrackMI *t=0;
392      try {
393         t=new AliITStrackMI(*esd);
394      } catch (const Char_t *msg) {
395        //Warning("PropagateBack",msg);
396         delete t;
397         continue;
398      }
399      t->fExpQ = TMath::Max(0.8*t->fESDtrack->GetTPCsignal(),30.);
400
401      ResetTrackToFollow(*t);
402
403      // propagete to vertex [SR, GSI 17.02.2003]
404      // Start Time measurement [SR, GSI 17.02.2003], corrected by I.Belikov
405      if (fTrackToFollow.PropagateTo(3.,0.0028,65.19)) {
406        if (fTrackToFollow.PropagateToVertex()) {
407           fTrackToFollow.StartTimeIntegral();
408        }
409        fTrackToFollow.PropagateTo(3.,-0.0028,65.19);
410      }
411
412      fTrackToFollow.ResetCovariance(); fTrackToFollow.ResetClusters();
413      if (RefitAt(49.,&fTrackToFollow,t)) {
414         if (CorrectForDeadZoneMaterial(&fTrackToFollow)!=0) {
415           //Warning("PropagateBack",
416           //        "failed to correct for the material in the dead zone !\n");
417           delete t;
418           continue;
419         }
420         fTrackToFollow.SetLabel(t->GetLabel());
421         //fTrackToFollow.CookdEdx();
422         CookLabel(&fTrackToFollow,0.); //For comparison only
423         fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSout);
424         //UseClusters(&fTrackToFollow);
425         ntrk++;
426      }
427      delete t;
428   }
429
430   Info("PropagateBack","Number of back propagated ITS tracks: %d\n",ntrk);
431
432   return 0;
433 }
434
435 Int_t AliITStrackerMI::RefitInward(AliESD *event) {
436   //--------------------------------------------------------------------
437   // This functions refits ITS tracks using the 
438   // "inward propagated" TPC tracks
439   // The clusters must be loaded !
440   //--------------------------------------------------------------------
441   Int_t nentr=event->GetNumberOfTracks();
442   Info("RefitInward", "Number of ESD tracks: %d\n", nentr);
443
444   Int_t ntrk=0;
445   for (Int_t i=0; i<nentr; i++) {
446     AliESDtrack *esd=event->GetTrack(i);
447
448     if ((esd->GetStatus()&AliESDtrack::kITSout) == 0) continue;
449     if (esd->GetStatus()&AliESDtrack::kITSrefit) continue;
450     if (esd->GetStatus()&AliESDtrack::kTPCout)
451       if ((esd->GetStatus()&AliESDtrack::kTPCrefit)==0) continue;
452
453     AliITStrackMI *t=0;
454     try {
455         t=new AliITStrackMI(*esd);
456     } catch (const Char_t *msg) {
457       //Warning("RefitInward",msg);
458         delete t;
459         continue;
460     }
461     t->fExpQ = TMath::Max(0.8*t->fESDtrack->GetTPCsignal(),30.);
462     if (CorrectForDeadZoneMaterial(t)!=0) {
463       //Warning("RefitInward",
464       //         "failed to correct for the material in the dead zone !\n");
465        delete t;
466        continue;
467     }
468
469     ResetTrackToFollow(*t);
470     fTrackToFollow.ResetClusters();
471
472     if ((esd->GetStatus()&AliESDtrack::kTPCin)==0)
473       fTrackToFollow.ResetCovariance();
474
475     //Refitting...
476     if (RefitAt(3.7, &fTrackToFollow, t)) {
477        fTrackToFollow.SetLabel(t->GetLabel());
478        //       fTrackToFollow.CookdEdx();
479        CookdEdx(&fTrackToFollow);
480
481        CookLabel(&fTrackToFollow,0.0); //For comparison only
482
483        if (fTrackToFollow.PropagateTo(3.,0.0028,65.19)) {//The beam pipe    
484          Double_t a=fTrackToFollow.GetAlpha();
485          Double_t cs=TMath::Cos(a),sn=TMath::Sin(a);
486          Double_t xv= GetX()*cs + GetY()*sn;
487          Double_t yv=-GetX()*sn + GetY()*cs;
488          
489          Double_t c=fTrackToFollow.GetC(), snp=fTrackToFollow.GetSnp();
490          Double_t x=fTrackToFollow.GetX(), y=fTrackToFollow.GetY();
491          Double_t tgfv=-(c*(x-xv)-snp)/(c*(y-yv) + TMath::Sqrt(1.-snp*snp));
492          Double_t fv=TMath::ATan(tgfv);
493
494          cs=TMath::Cos(fv); sn=TMath::Sin(fv);
495          x = xv*cs + yv*sn;
496          yv=-xv*sn + yv*cs; xv=x;
497
498          if (fTrackToFollow.Propagate(fv+a,xv)) {
499             fTrackToFollow.UpdateESDtrack(AliESDtrack::kITSrefit);
500             //UseClusters(&fTrackToFollow);
501             {
502             AliITSclusterV2 c; c.SetY(yv); c.SetZ(GetZ());
503             c.SetSigmaY2(GetSigmaY()*GetSigmaY());
504             c.SetSigmaZ2(GetSigmaZ()*GetSigmaZ());
505             Double_t chi2=fTrackToFollow.GetPredictedChi2(&c);
506             //Double_t chi2=GetPredictedChi2MI(&fTrackToFollow,&c,fI);
507             if (chi2<kMaxChi2)
508               if (fTrackToFollow.Update(&c,-chi2,0))
509                 //if (UpdateMI(&fTrackToFollow,&c,-chi2,0))
510                 fTrackToFollow.SetConstrainedESDtrack(chi2);            
511             }
512             ntrk++;
513          }
514        }
515     }
516     delete t;
517   }
518
519   Info("RefitInward","Number of refitted tracks: %d\n",ntrk);
520
521   return 0;
522 }
523
524 AliCluster *AliITStrackerMI::GetCluster(Int_t index) const {
525   //--------------------------------------------------------------------
526   //       Return pointer to a given cluster
527   //--------------------------------------------------------------------
528   Int_t l=(index & 0xf0000000) >> 28;
529   Int_t c=(index & 0x0fffffff) >> 00;
530   return fgLayers[l].GetCluster(c);
531 }
532
533
534 void AliITStrackerMI::FollowProlongationTree(AliITStrackMI * otrack, Int_t esdindex, Bool_t constrain) 
535 {
536   //--------------------------------------------------------------------
537   // Follow prolongation tree
538   //--------------------------------------------------------------------
539   //
540   AliESDtrack * esd = otrack->fESDtrack;
541   if (esd->GetV0Index(0)>0){
542     //
543     // TEMPORARY SOLLUTION: map V0 indexes to point to proper track
544     //                      mapping of esd track is different as its track in Containers
545     //                      Need something more stable
546     //                      Indexes are set back againg to the ESD track indexes in UpdateTPCV0
547     for (Int_t i=0;i<3;i++){
548       Int_t  index = esd->GetV0Index(i);
549       if (index==0) break;
550       AliESDV0MI * vertex = fEsd->GetV0MI(index);
551       if (vertex->GetStatus()<0) continue;     // rejected V0
552       //
553       if (esd->GetSign()>0) {
554         vertex->SetIndex(0,esdindex);
555       }
556       else{
557         vertex->SetIndex(1,esdindex);
558       }
559     }
560   }
561   TObjArray *bestarray = (TObjArray*)fBestHypothesys.At(esdindex);
562   if (!bestarray){
563     bestarray = new TObjArray(5);
564     fBestHypothesys.AddAt(bestarray,esdindex);
565   }
566
567   //
568   //setup tree of the prolongations
569   //
570   static AliITStrackMI tracks[7][100];
571   AliITStrackMI *currenttrack;
572   static AliITStrackMI currenttrack1;
573   static AliITStrackMI currenttrack2;  
574   static AliITStrackMI backuptrack;
575   Int_t ntracks[7];
576   Int_t nindexes[7][100];
577   Float_t normalizedchi2[100];
578   for (Int_t ilayer=0;ilayer<6;ilayer++) ntracks[ilayer]=0;
579   otrack->fNSkipped=0;
580   new (&(tracks[6][0])) AliITStrackMI(*otrack);
581   ntracks[6]=1;
582   for (Int_t i=0;i<7;i++) nindexes[i][0]=0;
583   // 
584   //
585   // follow prolongations
586   for (Int_t ilayer=5;ilayer>=0;ilayer--){
587     //
588     AliITSlayer &layer=fgLayers[ilayer]; 
589     Double_t r=layer.GetR();
590     ntracks[ilayer]=0;
591     //
592     //
593    Int_t nskipped=0;
594     Float_t nused =0;
595     for (Int_t itrack =0;itrack<ntracks[ilayer+1];itrack++){
596       //set current track
597       if (ntracks[ilayer]>=100) break;  
598       if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].fNSkipped>0) nskipped++;
599       if (tracks[ilayer+1][nindexes[ilayer+1][itrack]].fNUsed>2.) nused++;
600       if (ntracks[ilayer]>15+ilayer){
601         if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].fNSkipped>0 && nskipped>4+ilayer) continue;
602         if (itrack>1&&tracks[ilayer+1][nindexes[ilayer+1][itrack]].fNUsed>2. && nused>3) continue;
603       }
604
605       new(&currenttrack1)  AliITStrackMI(tracks[ilayer+1][nindexes[ilayer+1][itrack]]);
606       if (ilayer==3 || ilayer==1) {
607         Double_t rs=0.5*(fgLayers[ilayer+1].GetR() + r);
608         Double_t d=0.0034, x0=38.6;
609         if (ilayer==1) {rs=9.; d=0.0097; x0=42;}
610         if (!currenttrack1.PropagateTo(rs,d,x0)) {
611           continue;
612         }
613       }
614       //
615       //find intersection with layer
616       Double_t x,y,z;  
617       if (!currenttrack1.GetGlobalXYZat(r,x,y,z)) {
618         continue;
619       }
620       Double_t phi=TMath::ATan2(y,x);
621       Int_t idet=layer.FindDetectorIndex(phi,z);
622       if (idet<0) {
623         continue;
624       }
625       //propagate to the intersection
626       const AliITSdetector &det=layer.GetDetector(idet);
627       phi=det.GetPhi();
628       new(&currenttrack2)  AliITStrackMI(currenttrack1);
629       if (!currenttrack1.Propagate(phi,det.GetR())) {   
630         continue;
631       }
632       currenttrack2.Propagate(phi,det.GetR());  //
633       currenttrack1.SetDetectorIndex(idet);
634       currenttrack2.SetDetectorIndex(idet);
635       
636       //
637       //
638       Double_t dz=7.5*TMath::Sqrt(currenttrack1.GetSigmaZ2() + 16.*kSigmaZ2[ilayer]);
639       Double_t dy=7.5*TMath::Sqrt(currenttrack1.GetSigmaY2() + 16.*kSigmaY2[ilayer]);
640       //
641       Bool_t isBoundary=kFALSE;
642       if (currenttrack1.GetY()-dy< det.GetYmin()+0.2) isBoundary = kTRUE;  
643       if (currenttrack1.GetY()+dy> det.GetYmax()-0.2) isBoundary = kTRUE;
644       if (currenttrack1.GetZ()-dz< det.GetZmin()+0.2) isBoundary = kTRUE;
645       if (currenttrack1.GetZ()+dz> det.GetZmax()-0.2) isBoundary = kTRUE;
646       
647       if (isBoundary){ // track at boundary between detectors
648         Float_t maxtgl = TMath::Abs(currenttrack1.GetTgl());
649         if (maxtgl>1) maxtgl=1;
650         dz = TMath::Sqrt(dz*dz+0.25*maxtgl*maxtgl);
651         //
652         Float_t maxsnp = TMath::Abs(currenttrack1.GetSnp());
653         if (maxsnp>0.95) continue;
654         //if (maxsnp>0.5) maxsnp=0.5;
655         dy=TMath::Sqrt(dy*dy+0.25*maxsnp*maxsnp);
656       }
657       
658       Double_t zmin=currenttrack1.GetZ() - dz; 
659       Double_t zmax=currenttrack1.GetZ() + dz;
660       Double_t ymin=currenttrack1.GetY() + r*phi - dy;
661       Double_t ymax=currenttrack1.GetY() + r*phi + dy;
662       layer.SelectClusters(zmin,zmax,ymin,ymax); 
663       //
664       // loop over all possible prolongations
665       //
666       Double_t msz=1./((currenttrack1.GetSigmaZ2() + 16.*kSigmaZ2[ilayer]));
667       Double_t msy=1./((currenttrack1.GetSigmaY2() + 16.*kSigmaY2[ilayer]));
668       if (constrain){
669         msy/=60; msz/=60.;
670       }
671       else{
672         msy/=50; msz/=50.;
673       }
674       //
675       const AliITSclusterV2 *c=0; Int_t ci=-1;
676       Double_t chi2=12345.;
677       Int_t deadzone=0;
678       currenttrack = &currenttrack1;
679       while ((c=layer.GetNextCluster(ci))!=0) { 
680         if (ntracks[ilayer]>95) break; //space for skipped clusters  
681         Bool_t change =kFALSE;  
682         if (c->GetQ()==0 && (deadzone==1)) continue;
683         Int_t idet=c->GetDetectorIndex();
684         if (currenttrack->GetDetectorIndex()!=idet) {
685           const AliITSdetector &det=layer.GetDetector(idet);
686           Double_t y,z;
687           if (!currenttrack2.GetProlongationFast(det.GetPhi(),det.GetR(),y,z)) continue;
688           Float_t pz = (z - c->GetZ()) , py=(y - c->GetY());
689           if (pz*pz*msz+py*py*msy>1.) continue;
690           //
691           new (&backuptrack) AliITStrackMI(currenttrack2);
692           change = kTRUE;
693           currenttrack =&currenttrack2;
694           if (!currenttrack->Propagate(det.GetPhi(),det.GetR())) {
695             new (currenttrack) AliITStrackMI(backuptrack);
696             change = kFALSE;
697             continue;
698           }
699           currenttrack->SetDetectorIndex(idet);
700         }
701         else{
702           Float_t pz = (currenttrack->GetZ() - c->GetZ()) , py=(currenttrack->GetY() - c->GetY());
703           if (pz*pz*msz+py*py*msy>1.) continue;
704         }
705
706         chi2=GetPredictedChi2MI(currenttrack,c,ilayer); 
707         if (chi2<kMaxChi2s[ilayer]){
708           if (c->GetQ()==0) deadzone=1;     // take dead zone only once   
709           if (ntracks[ilayer]>=100) continue;
710           AliITStrackMI * updatetrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(*currenttrack);
711           updatetrack->fClIndex[ilayer]=0;
712           if (change){
713             new (&currenttrack2) AliITStrackMI(backuptrack);
714           }
715           if (c->GetQ()!=0){
716             if (!UpdateMI(updatetrack,c,chi2,(ilayer<<28)+ci)) continue; 
717             updatetrack->SetSampledEdx(c->GetQ(),updatetrack->GetNumberOfClusters()-1); //b.b.
718           }
719           else {
720             updatetrack->fNDeadZone++;
721             updatetrack->fDeadZoneProbability=GetDeadZoneProbability(updatetrack->GetZ(),TMath::Sqrt(updatetrack->GetSigmaZ2()));
722           }
723           if (c->IsUsed()){
724             updatetrack->fNUsed++;
725           }
726           Double_t x0;
727           Double_t d=layer.GetThickness(updatetrack->GetY(),updatetrack->GetZ(),x0);
728           updatetrack->CorrectForMaterial(d,x0);          
729           if (constrain) {
730             updatetrack->fConstrain = constrain;
731             fI = ilayer;
732             Double_t d=GetEffectiveThickness(0,0); //Think of this !!!!
733             Double_t xyz[]={GetX(),GetY(),GetZ()};
734             Double_t ptfactor = 1;
735             Double_t ers[]={GetSigmaX()*ptfactor,GetSigmaY()*ptfactor,GetSigmaZ()};
736             Bool_t isPrim = kTRUE;
737             if (ilayer<4){
738               updatetrack->fD[0] = updatetrack->GetD(GetX(),GetY());
739               updatetrack->fD[1] = updatetrack->GetZat(GetX())-GetZ();
740               if ( TMath::Abs(updatetrack->fD[0]/(1.+ilayer))>0.4 ||  TMath::Abs(updatetrack->fD[1]/(1.+ilayer))>0.4) isPrim=kFALSE;
741             }
742             if (isPrim) updatetrack->Improve(d,xyz,ers);
743           } //apply vertex constrain              
744           ntracks[ilayer]++;
745         }  // create new hypothesy 
746       } // loop over possible cluster prolongation      
747       //      if (constrain&&itrack<2&&currenttrack1.fNSkipped==0 && deadzone==0){      
748       if (constrain&&itrack<2&&currenttrack1.fNSkipped==0 && deadzone==0&&ntracks[ilayer]<100){ 
749         AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
750         vtrack->fClIndex[ilayer]=0;
751         fI = ilayer;
752         Double_t d=GetEffectiveThickness(0,0); //Think of this !!!!
753         Double_t xyz[]={GetX(),GetY(),GetZ()};
754         Double_t ers[]={GetSigmaX(),GetSigmaY(),GetSigmaZ()};
755         vtrack->Improve(d,xyz,ers);
756         vtrack->fNSkipped++;
757         ntracks[ilayer]++;
758       }
759
760       if (constrain&&itrack<1&&TMath::Abs(currenttrack1.fP3)>1.1){  //big theta -- for low mult. runs
761         AliITStrackMI* vtrack = new (&tracks[ilayer][ntracks[ilayer]]) AliITStrackMI(currenttrack1);
762         vtrack->fClIndex[ilayer]=0;
763         fI = ilayer;
764         Double_t d=GetEffectiveThickness(0,0); //Think of this !!!!
765         Double_t xyz[]={GetX(),GetY(),GetZ()};
766         Double_t ers[]={GetSigmaX(),GetSigmaY(),GetSigmaZ()};
767         vtrack->Improve(d,xyz,ers);
768         vtrack->fNDeadZone++;
769         ntracks[ilayer]++;
770       }
771      
772       
773     } //loop over track candidates
774     //
775     //
776     Int_t accepted=0;
777     
778     Int_t golds=0;
779     for (Int_t itrack=0;itrack<ntracks[ilayer];itrack++){
780       normalizedchi2[itrack] = NormalizedChi2(&tracks[ilayer][itrack],ilayer); 
781       if ( normalizedchi2[itrack]<3+0.5*ilayer) golds++;
782       if (ilayer>4) accepted++;
783       else{
784         if ( constrain && normalizedchi2[itrack]<kMaxNormChi2C[ilayer]+1) accepted++;
785         if (!constrain && normalizedchi2[itrack]<kMaxNormChi2NonC[ilayer]+1) accepted++;
786       }
787     }
788     TMath::Sort(ntracks[ilayer],normalizedchi2,nindexes[ilayer],kFALSE);
789     ntracks[ilayer] = TMath::Min(accepted,7+2*ilayer);
790     if (ntracks[ilayer]<golds+2+ilayer) ntracks[ilayer]=TMath::Min(golds+2+ilayer,accepted);
791     if (ntracks[ilayer]>90) ntracks[ilayer]=90; 
792   } //loop over layers
793   //printf("%d\t%d\t%d\t%d\t%d\t%d\n",ntracks[0],ntracks[1],ntracks[2],ntracks[3],ntracks[4],ntracks[5]);
794   Int_t max = constrain? 20: 5;
795
796   for (Int_t i=0;i<TMath::Min(max,ntracks[0]);i++) {
797     AliITStrackMI & track= tracks[0][nindexes[0][i]];
798     if (track.GetNumberOfClusters()<2) continue;
799     if (!constrain&&track.fNormChi2[0]>7.)continue;
800     AddTrackHypothesys(new AliITStrackMI(track), esdindex);
801   }
802   for (Int_t i=0;i<TMath::Min(2,ntracks[1]);i++) {
803     AliITStrackMI & track= tracks[1][nindexes[1][i]];
804     if (track.GetNumberOfClusters()<4) continue;
805     if (!constrain&&track.fNormChi2[1]>7.)continue;
806     if (constrain) track.fNSkipped+=1;
807     if (!constrain) {
808       track.fD[0] = track.GetD(GetX(),GetY());   
809       track.fNSkipped+=4./(4.+8.*TMath::Abs(track.fD[0]));
810       if (track.fN+track.fNDeadZone+track.fNSkipped>6) {
811         track.fNSkipped = 6-track.fN+track.fNDeadZone;
812       }
813     }
814     AddTrackHypothesys(new AliITStrackMI(track), esdindex);
815   }
816   //}
817   
818   if (!constrain){  
819     for (Int_t i=0;i<TMath::Min(2,ntracks[2]);i++) {
820       AliITStrackMI & track= tracks[2][nindexes[2][i]];
821       if (track.GetNumberOfClusters()<3) continue;
822       if (!constrain&&track.fNormChi2[2]>7.)continue;
823       if (constrain) track.fNSkipped+=2;      
824       if (!constrain){
825         track.fD[0] = track.GetD(GetX(),GetY());
826         track.fNSkipped+= 7./(7.+8.*TMath::Abs(track.fD[0]));
827         if (track.fN+track.fNDeadZone+track.fNSkipped>6) {
828           track.fNSkipped = 6-track.fN+track.fNDeadZone;
829         }
830       }
831       AddTrackHypothesys(new AliITStrackMI(track), esdindex);
832     }
833   }
834   
835   if (!constrain){
836     //
837     // register best tracks - important for V0 finder
838     //
839     for (Int_t ilayer=0;ilayer<5;ilayer++){
840       if (ntracks[ilayer]==0) continue;
841       AliITStrackMI & track= tracks[ilayer][nindexes[ilayer][0]];
842       if (track.GetNumberOfClusters()<1) continue;
843       CookLabel(&track,0);
844       bestarray->AddAt(new AliITStrackMI(track),ilayer);
845     }
846   }
847   //
848   // update TPC V0 information
849   //
850   if (otrack->fESDtrack->GetV0Index(0)>0){    
851     Float_t fprimvertex[3]={GetX(),GetY(),GetZ()};
852     for (Int_t i=0;i<3;i++){
853       Int_t  index = otrack->fESDtrack->GetV0Index(i); 
854       if (index==0) break;
855       AliESDV0MI * vertex = fEsd->GetV0MI(index);
856       if (vertex->GetStatus()<0) continue;     // rejected V0
857       //
858       if (otrack->fP4>0) {
859         vertex->SetIndex(0,esdindex);
860       }
861       else{
862         vertex->SetIndex(1,esdindex);
863       }
864       //find nearest layer with track info
865       Int_t nearestold  = GetNearestLayer(vertex->GetXrp());
866       Int_t nearest     = nearestold; 
867       for (Int_t ilayer =nearest;ilayer<8;ilayer++){
868         if (ntracks[nearest]==0){
869           nearest = ilayer;
870         }
871       }
872       //
873       AliITStrackMI & track= tracks[nearest][nindexes[nearest][0]];
874       if (nearestold<5&&nearest<5){
875         Bool_t accept = track.fNormChi2[nearest]<10; 
876         if (accept){
877           if (track.fP4>0) {
878             vertex->SetP(track);
879             vertex->Update(fprimvertex);
880             //      vertex->SetIndex(0,track.fESDtrack->GetID()); 
881             if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
882           }else{
883             vertex->SetM(track);
884             vertex->Update(fprimvertex);
885             //vertex->SetIndex(1,track.fESDtrack->GetID());
886             if (track.GetNumberOfClusters()>2) AddTrackHypothesys(new AliITStrackMI(track), esdindex);
887           }
888           vertex->SetStatus(vertex->GetStatus()+1);
889         }else{
890           //  vertex->SetStatus(-2);  // reject V0  - not enough clusters
891         }
892       }
893       // if (nearestold>3){
894 //      Int_t indexlayer = (ntracks[0]>0)? 0:1;
895 //      if (ntracks[indexlayer]>0){
896 //        AliITStrackMI & track= tracks[indexlayer][nindexes[indexlayer][0]];
897 //        if (track.GetNumberOfClusters()>4&&track.fNormChi2[indexlayer]<4){
898 //          vertex->SetStatus(-1);  // reject V0 - clusters before
899 //        }
900 //      }
901 //      }
902     }
903   }  
904 }
905
906
907 AliITStrackerMI::AliITSlayer & AliITStrackerMI::GetLayer(Int_t layer) const
908 {
909   //--------------------------------------------------------------------
910   //
911   //
912   return fgLayers[layer];
913 }
914 AliITStrackerMI::AliITSlayer::AliITSlayer() {
915   //--------------------------------------------------------------------
916   //default AliITSlayer constructor
917   //--------------------------------------------------------------------
918   fN=0;
919   fDetectors=0;
920   fSkip = 0;
921   fCurrentSlice=-1;
922   for (Int_t i=0; i<kMaxClusterPerLayer;i++) {
923     fClusterWeight[i]=0;
924     fClusterTracks[0][i]=-1;
925     fClusterTracks[1][i]=-1;
926     fClusterTracks[2][i]=-1;    
927     fClusterTracks[3][i]=-1;    
928   }
929 }
930
931 AliITStrackerMI::AliITSlayer::
932 AliITSlayer(Double_t r,Double_t p,Double_t z,Int_t nl,Int_t nd) {
933   //--------------------------------------------------------------------
934   //main AliITSlayer constructor
935   //--------------------------------------------------------------------
936   fR=r; fPhiOffset=p; fZOffset=z;
937   fNladders=nl; fNdetectors=nd;
938   fDetectors=new AliITSdetector[fNladders*fNdetectors];
939
940   fN=0;
941   fI=0;
942   fSkip = 0;
943   fRoad=2*fR*TMath::Sqrt(3.14/1.);//assuming that there's only one cluster
944 }
945
946 AliITStrackerMI::AliITSlayer::~AliITSlayer() {
947   //--------------------------------------------------------------------
948   // AliITSlayer destructor
949   //--------------------------------------------------------------------
950   delete[] fDetectors;
951   for (Int_t i=0; i<fN; i++) delete fClusters[i];
952   for (Int_t i=0; i<kMaxClusterPerLayer;i++) {
953     fClusterWeight[i]=0;
954     fClusterTracks[0][i]=-1;
955     fClusterTracks[1][i]=-1;
956     fClusterTracks[2][i]=-1;    
957     fClusterTracks[3][i]=-1;    
958   }
959 }
960
961 void AliITStrackerMI::AliITSlayer::ResetClusters() {
962   //--------------------------------------------------------------------
963   // This function removes loaded clusters
964   //--------------------------------------------------------------------
965   for (Int_t i=0; i<fN; i++) delete fClusters[i];
966   for (Int_t i=0; i<kMaxClusterPerLayer;i++){
967     fClusterWeight[i]=0;
968     fClusterTracks[0][i]=-1;
969     fClusterTracks[1][i]=-1;
970     fClusterTracks[2][i]=-1;    
971     fClusterTracks[3][i]=-1;  
972   }
973   
974   fN=0;
975   fI=0;
976 }
977
978 void AliITStrackerMI::AliITSlayer::ResetWeights() {
979   //--------------------------------------------------------------------
980   // This function reset weights of the clusters
981   //--------------------------------------------------------------------
982   for (Int_t i=0; i<kMaxClusterPerLayer;i++) {
983     fClusterWeight[i]=0;
984     fClusterTracks[0][i]=-1;
985     fClusterTracks[1][i]=-1;
986     fClusterTracks[2][i]=-1;    
987     fClusterTracks[3][i]=-1;  
988   }
989   for (Int_t i=0; i<fN;i++) {
990     AliITSclusterV2 * cl = (AliITSclusterV2*)GetCluster(i);
991     if (cl&&cl->IsUsed()) cl->Use();
992   }
993
994 }
995
996 void AliITStrackerMI::AliITSlayer::ResetRoad() {
997   //--------------------------------------------------------------------
998   // This function calculates the road defined by the cluster density
999   //--------------------------------------------------------------------
1000   Int_t n=0;
1001   for (Int_t i=0; i<fN; i++) {
1002      if (TMath::Abs(fClusters[i]->GetZ())<fR) n++;
1003   }
1004   //if (n>1) fRoad=2*fR*TMath::Sqrt(3.14/n);
1005   if (n>1) fRoad=2*fR*TMath::Sqrt(3.14/n);
1006 }
1007
1008
1009 Int_t AliITStrackerMI::AliITSlayer::InsertCluster(AliITSclusterV2 *c) {
1010   //--------------------------------------------------------------------
1011   //This function adds a cluster to this layer
1012   //--------------------------------------------------------------------
1013   if (fN==kMaxClusterPerLayer) {
1014     ::Error("InsertCluster","Too many clusters !\n");
1015     return 1;
1016   }
1017   fCurrentSlice=-1;
1018   fClusters[fN]=c;
1019   fN++;
1020   AliITSdetector &det=GetDetector(c->GetDetectorIndex());    
1021   if (c->GetY()<det.GetYmin()) det.SetYmin(c->GetY());
1022   if (c->GetY()>det.GetYmax()) det.SetYmax(c->GetY());
1023   if (c->GetZ()<det.GetZmin()) det.SetZmin(c->GetZ());
1024   if (c->GetZ()>det.GetZmax()) det.SetZmax(c->GetZ());
1025                              
1026   return 0;
1027 }
1028
1029 void  AliITStrackerMI::AliITSlayer::SortClusters()
1030 {
1031   //
1032   //sort clusters
1033   //
1034   AliITSclusterV2 **clusters = new AliITSclusterV2*[fN];
1035   Float_t *z                = new Float_t[fN];
1036   Int_t   * index           = new Int_t[fN];
1037   //
1038   for (Int_t i=0;i<fN;i++){
1039     z[i] = fClusters[i]->GetZ();
1040   }
1041   TMath::Sort(fN,z,index,kFALSE);
1042   for (Int_t i=0;i<fN;i++){
1043     clusters[i] = fClusters[index[i]];
1044   }
1045   //
1046   for (Int_t i=0;i<fN;i++){
1047     fClusters[i] = clusters[i];
1048     fZ[i]        = fClusters[i]->GetZ();
1049     AliITSdetector &det=GetDetector(fClusters[i]->GetDetectorIndex());    
1050     Double_t y=fR*det.GetPhi() + fClusters[i]->GetY();
1051     if (y>2.*fR*TMath::Pi()) y -= 2.*fR*TMath::Pi();
1052     fY[i] = y;
1053   }
1054   delete[] index;
1055   delete[] z;
1056   delete[] clusters;
1057   //
1058
1059   fYB[0]=10000000;
1060   fYB[1]=-10000000;
1061   for (Int_t i=0;i<fN;i++){
1062     if (fY[i]<fYB[0]) fYB[0]=fY[i];
1063     if (fY[i]>fYB[1]) fYB[1]=fY[i];
1064     fClusterIndex[i] = i;
1065   }
1066   //
1067   // fill slices
1068   fDy5 = (fYB[1]-fYB[0])/5.;
1069   fDy10 = (fYB[1]-fYB[0])/10.;
1070   fDy20 = (fYB[1]-fYB[0])/20.;
1071   for (Int_t i=0;i<6;i++)  fN5[i] =0;  
1072   for (Int_t i=0;i<11;i++) fN10[i]=0;  
1073   for (Int_t i=0;i<21;i++) fN20[i]=0;
1074   //  
1075   for (Int_t i=0;i<6;i++) {fBy5[i][0] =  fYB[0]+(i-0.75)*fDy5; fBy5[i][1] =  fYB[0]+(i+0.75)*fDy5;}
1076   for (Int_t i=0;i<11;i++) {fBy10[i][0] =  fYB[0]+(i-0.75)*fDy10; fBy10[i][1] =  fYB[0]+(i+0.75)*fDy10;} 
1077   for (Int_t i=0;i<21;i++) {fBy20[i][0] =  fYB[0]+(i-0.75)*fDy20; fBy20[i][1] =  fYB[0]+(i+0.75)*fDy20;}
1078   //
1079   //
1080   for (Int_t i=0;i<fN;i++)
1081     for (Int_t irot=-1;irot<=1;irot++){
1082       Float_t curY = fY[i]+irot*TMath::TwoPi()*fR; 
1083       // slice 5
1084       for (Int_t slice=0; slice<6;slice++){
1085         if (fBy5[slice][0]<curY && curY<fBy5[slice][1]&&fN5[slice]<kMaxClusterPerLayer5){
1086           fClusters5[slice][fN5[slice]] = fClusters[i];
1087           fY5[slice][fN5[slice]] = curY;
1088           fZ5[slice][fN5[slice]] = fZ[i];
1089           fClusterIndex5[slice][fN5[slice]]=i;
1090           fN5[slice]++;
1091         }
1092       }
1093       // slice 10
1094       for (Int_t slice=0; slice<11;slice++){
1095         if (fBy10[slice][0]<curY && curY<fBy10[slice][1]&&fN10[slice]<kMaxClusterPerLayer10){
1096           fClusters10[slice][fN10[slice]] = fClusters[i];
1097           fY10[slice][fN10[slice]] = curY;
1098           fZ10[slice][fN10[slice]] = fZ[i];
1099           fClusterIndex10[slice][fN10[slice]]=i;
1100           fN10[slice]++;
1101         }
1102       }
1103       // slice 20
1104       for (Int_t slice=0; slice<21;slice++){
1105         if (fBy20[slice][0]<curY && curY<fBy20[slice][1]&&fN20[slice]<kMaxClusterPerLayer20){
1106           fClusters20[slice][fN20[slice]] = fClusters[i];
1107           fY20[slice][fN20[slice]] = curY;
1108           fZ20[slice][fN20[slice]] = fZ[i];
1109           fClusterIndex20[slice][fN20[slice]]=i;
1110           fN20[slice]++;
1111         }
1112       }      
1113     }
1114
1115   //
1116   // consistency check
1117   //
1118   for (Int_t i=0;i<fN-1;i++){
1119     if (fZ[i]>fZ[i+1]){
1120       printf("Bugg\n");
1121     }
1122   }
1123   //
1124   for (Int_t slice=0;slice<21;slice++)
1125   for (Int_t i=0;i<fN20[slice]-1;i++){
1126     if (fZ20[slice][i]>fZ20[slice][i+1]){
1127       printf("Bugg\n");
1128     }
1129   }
1130
1131
1132 }
1133
1134
1135 Int_t AliITStrackerMI::AliITSlayer::FindClusterIndex(Float_t z) const {
1136   //--------------------------------------------------------------------
1137   // This function returns the index of the nearest cluster 
1138   //--------------------------------------------------------------------
1139   Int_t ncl=0;
1140   const Float_t *zcl;  
1141   if (fCurrentSlice<0) {
1142     ncl = fN;
1143     zcl   = fZ;
1144   }
1145   else{
1146     ncl   = fNcs;
1147     zcl   = fZcs;;
1148   }
1149   
1150   if (ncl==0) return 0;
1151   Int_t b=0, e=ncl-1, m=(b+e)/2;
1152   for (; b<e; m=(b+e)/2) {
1153     //    if (z > fClusters[m]->GetZ()) b=m+1;
1154     if (z > zcl[m]) b=m+1;
1155     else e=m; 
1156   }
1157   return m;
1158 }
1159
1160
1161 void AliITStrackerMI::AliITSlayer::
1162 SelectClusters(Double_t zmin,Double_t zmax,Double_t ymin, Double_t ymax) {
1163   //--------------------------------------------------------------------
1164   // This function sets the "window"
1165   //--------------------------------------------------------------------
1166  
1167   Double_t circle=2*TMath::Pi()*fR;
1168   fYmin = ymin; fYmax =ymax;
1169   Float_t ymiddle = (fYmin+fYmax)*0.5;
1170   if (ymiddle<fYB[0]) {fYmin+=circle; fYmax+=circle;ymiddle+=circle;}
1171   else{
1172     if (ymiddle>fYB[1]) {fYmin-=circle; fYmax-=circle;ymiddle-=circle;}
1173   }
1174   //
1175   fCurrentSlice =-1;
1176   // defualt take all
1177   fClustersCs = fClusters;
1178   fClusterIndexCs = fClusterIndex;
1179   fYcs  = fY;
1180   fZcs  = fZ;
1181   fNcs  = fN;
1182   //
1183   //is in 20 slice?
1184   if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy20){
1185     Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy20);
1186     if (slice<0) slice=0;
1187     if (slice>20) slice=20;
1188     Bool_t isOK = (fYmin>fBy20[slice][0]&&fYmax<fBy20[slice][1]);
1189     if (isOK) {
1190       fCurrentSlice=slice;
1191       fClustersCs = fClusters20[fCurrentSlice];
1192       fClusterIndexCs = fClusterIndex20[fCurrentSlice];
1193       fYcs  = fY20[fCurrentSlice];
1194       fZcs  = fZ20[fCurrentSlice];
1195       fNcs  = fN20[fCurrentSlice];
1196     }
1197   }  
1198   //
1199   //is in 10 slice?
1200   if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy10){
1201     Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy10);
1202     if (slice<0) slice=0;
1203     if (slice>10) slice=10;
1204     Bool_t isOK = (fYmin>fBy10[slice][0]&&fYmax<fBy10[slice][1]);
1205     if (isOK) {
1206       fCurrentSlice=slice;
1207       fClustersCs = fClusters10[fCurrentSlice];
1208       fClusterIndexCs = fClusterIndex10[fCurrentSlice];
1209       fYcs  = fY10[fCurrentSlice];
1210       fZcs  = fZ10[fCurrentSlice];
1211       fNcs  = fN10[fCurrentSlice];
1212     }
1213   }  
1214   //
1215   //is in 5 slice?
1216   if (fCurrentSlice<0&&TMath::Abs(fYmax-fYmin)<1.49*fDy5){
1217     Int_t slice = int(0.5+(ymiddle-fYB[0])/fDy5);
1218     if (slice<0) slice=0;
1219     if (slice>5) slice=5;
1220     Bool_t isOK = (fYmin>fBy5[slice][0]&&fYmax<fBy5[slice][1]);
1221     if ( isOK){
1222       fCurrentSlice=slice;
1223       fClustersCs = fClusters5[fCurrentSlice];
1224       fClusterIndexCs = fClusterIndex5[fCurrentSlice];
1225       fYcs  = fY5[fCurrentSlice];
1226       fZcs  = fZ5[fCurrentSlice];
1227       fNcs  = fN5[fCurrentSlice];
1228     }
1229   }  
1230   //  
1231   fI=FindClusterIndex(zmin); fZmax=zmax;
1232   fImax = TMath::Min(FindClusterIndex(zmax)+1,fNcs);
1233   fSkip = 0;
1234   fAccepted =0;
1235 }
1236
1237
1238
1239
1240 Int_t AliITStrackerMI::AliITSlayer::
1241 FindDetectorIndex(Double_t phi, Double_t z) const {
1242   //--------------------------------------------------------------------
1243   //This function finds the detector crossed by the track
1244   //--------------------------------------------------------------------
1245   Double_t dphi=-(phi-fPhiOffset);
1246   if      (dphi <  0) dphi += 2*TMath::Pi();
1247   else if (dphi >= 2*TMath::Pi()) dphi -= 2*TMath::Pi();
1248   Int_t np=Int_t(dphi*fNladders*0.5/TMath::Pi()+0.5);
1249   if (np>=fNladders) np-=fNladders;
1250   if (np<0)          np+=fNladders;
1251
1252   Double_t dz=fZOffset-z;
1253   Int_t nz=Int_t(dz*(fNdetectors-1)*0.5/fZOffset+0.5);
1254   if (nz>=fNdetectors) return -1;
1255   if (nz<0)            return -1;
1256
1257   return np*fNdetectors + nz;
1258 }
1259
1260
1261 const AliITSclusterV2 *AliITStrackerMI::AliITSlayer::GetNextCluster(Int_t &ci){
1262   //--------------------------------------------------------------------
1263   // This function returns clusters within the "window" 
1264   //--------------------------------------------------------------------
1265
1266   if (fCurrentSlice<0){
1267     Double_t rpi2 = 2.*fR*TMath::Pi();
1268     for (Int_t i=fI; i<fImax; i++) {
1269       Double_t y = fY[i];
1270       if (fYmax<y) y -= rpi2;
1271       if (fYmin>y) y += rpi2;
1272       if (y<fYmin) continue;
1273       if (y>fYmax) continue;
1274       if (fClusters[i]->GetQ()==0&&fSkip==2) continue;
1275       ci=i;
1276       fI=i+1;
1277       return fClusters[i];
1278     }
1279   }
1280   else{
1281     for (Int_t i=fI; i<fImax; i++) {
1282       if (fYcs[i]<fYmin) continue;
1283       if (fYcs[i]>fYmax) continue;
1284       if (fClustersCs[i]->GetQ()==0&&fSkip==2) continue;
1285       ci=fClusterIndexCs[i];
1286       fI=i+1;
1287       return fClustersCs[i];
1288     }
1289   }
1290   return 0;
1291 }
1292
1293
1294
1295 Double_t AliITStrackerMI::AliITSlayer::GetThickness(Double_t y,Double_t z,Double_t &x0)
1296 const {
1297   //--------------------------------------------------------------------
1298   //This function returns the layer thickness at this point (units X0)
1299   //--------------------------------------------------------------------
1300   Double_t d=0.0085;
1301   x0=21.82;
1302   if (43<fR&&fR<45) { //SSD2
1303      Double_t dd=0.0034;
1304      d=dd;
1305      if (TMath::Abs(y-0.00)>3.40) d+=dd;
1306      if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
1307      if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
1308      for (Int_t i=0; i<12; i++) {
1309        if (TMath::Abs(z-3.9*(i+0.5))<0.15) {
1310           if (TMath::Abs(y-0.00)>3.40) d+=dd;
1311           d+=0.0034; 
1312           break;
1313        }
1314        if (TMath::Abs(z+3.9*(i+0.5))<0.15) {
1315           if (TMath::Abs(y-0.00)>3.40) d+=dd;
1316           d+=0.0034; 
1317           break;
1318        }         
1319        if (TMath::Abs(z-3.4-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1320        if (TMath::Abs(z+0.5+3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1321      }
1322   } else 
1323   if (37<fR&&fR<41) { //SSD1
1324      Double_t dd=0.0034;
1325      d=dd;
1326      if (TMath::Abs(y-0.00)>3.40) d+=dd;
1327      if (TMath::Abs(y-1.90)<0.45) {d+=(0.013-0.0034);}
1328      if (TMath::Abs(y+1.90)<0.45) {d+=(0.013-0.0034);}
1329      for (Int_t i=0; i<11; i++) {
1330        if (TMath::Abs(z-3.9*i)<0.15) {
1331           if (TMath::Abs(y-0.00)>3.40) d+=dd;
1332           d+=dd; 
1333           break;
1334        }
1335        if (TMath::Abs(z+3.9*i)<0.15) {
1336           if (TMath::Abs(y-0.00)>3.40) d+=dd;
1337           d+=dd; 
1338           break;
1339        }         
1340        if (TMath::Abs(z-1.85-3.9*i)<0.50) {d+=(0.016-0.0034); break;}
1341        if (TMath::Abs(z+2.05+3.9*i)<0.50) {d+=(0.016-0.0034); break;}         
1342      }
1343   } else
1344   if (13<fR&&fR<26) { //SDD
1345      Double_t dd=0.0033;
1346      d=dd;
1347      if (TMath::Abs(y-0.00)>3.30) d+=dd;
1348
1349      if (TMath::Abs(y-1.80)<0.55) {
1350         d+=0.016;
1351         for (Int_t j=0; j<20; j++) {
1352           if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
1353           if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
1354         } 
1355      }
1356      if (TMath::Abs(y+1.80)<0.55) {
1357         d+=0.016;
1358         for (Int_t j=0; j<20; j++) {
1359           if (TMath::Abs(z-0.7-1.47*j)<0.12) {d+=0.08; x0=9.; break;}
1360           if (TMath::Abs(z+0.7+1.47*j)<0.12) {d+=0.08; x0=9.; break;}
1361         } 
1362      }
1363
1364      for (Int_t i=0; i<4; i++) {
1365        if (TMath::Abs(z-7.3*i)<0.60) {
1366           d+=dd;
1367           if (TMath::Abs(y-0.00)>3.30) d+=dd; 
1368           break;
1369        }
1370        if (TMath::Abs(z+7.3*i)<0.60) {
1371           d+=dd; 
1372           if (TMath::Abs(y-0.00)>3.30) d+=dd; 
1373           break;
1374        }
1375      }
1376   } else
1377   if (6<fR&&fR<8) {   //SPD2
1378      Double_t dd=0.0063; x0=21.5;
1379      d=dd;
1380      if (TMath::Abs(y-3.08)>0.5) d+=dd;
1381      //if (TMath::Abs(y-3.08)>0.45) d+=dd;
1382      if (TMath::Abs(y-3.03)<0.10) {d+=0.014;}
1383   } else
1384   if (3<fR&&fR<5) {   //SPD1
1385      Double_t dd=0.0063; x0=21.5;
1386      d=dd;
1387      if (TMath::Abs(y+0.21)>0.6) d+=dd;
1388      //if (TMath::Abs(y+0.21)>0.45) d+=dd;
1389      if (TMath::Abs(y+0.10)<0.10) {d+=0.014;}
1390   }
1391
1392   return d;
1393 }
1394
1395 Double_t AliITStrackerMI::GetEffectiveThickness(Double_t y,Double_t z) const
1396 {
1397   //--------------------------------------------------------------------
1398   //Returns the thickness between the current layer and the vertex (units X0)
1399   //--------------------------------------------------------------------
1400   Double_t d=0.0028*3*3; //beam pipe
1401   Double_t x0=0;
1402
1403   Double_t xn=fgLayers[fI].GetR();
1404   for (Int_t i=0; i<fI; i++) {
1405     Double_t xi=fgLayers[i].GetR();
1406     d+=fgLayers[i].GetThickness(y,z,x0)*xi*xi;
1407   }
1408
1409   if (fI>1) {
1410     Double_t xi=9.;
1411     d+=0.0097*xi*xi;
1412   }
1413
1414   if (fI>3) {
1415     Double_t xi=0.5*(fgLayers[3].GetR()+fgLayers[4].GetR());
1416     d+=0.0034*xi*xi;
1417   }
1418
1419   return d/(xn*xn);
1420 }
1421
1422 Int_t AliITStrackerMI::AliITSlayer::InRoad() const {
1423   //--------------------------------------------------------------------
1424   // This function returns number of clusters within the "window" 
1425   //--------------------------------------------------------------------
1426   Int_t ncl=0;
1427   for (Int_t i=fI; i<fN; i++) {
1428     const AliITSclusterV2 *c=fClusters[i];
1429     if (c->GetZ() > fZmax) break;
1430     if (c->IsUsed()) continue;
1431     const AliITSdetector &det=GetDetector(c->GetDetectorIndex());    
1432     Double_t y=fR*det.GetPhi() + c->GetY();
1433
1434     if (y>2.*fR*TMath::Pi()) y -= 2*fR*TMath::Pi();
1435     if (y>1.*fR*TMath::Pi() && fYmax<y) y -= 2*fR*TMath::Pi();
1436
1437     if (y<fYmin) continue;
1438     if (y>fYmax) continue;
1439     ncl++;
1440   }
1441   return ncl;
1442 }
1443
1444 Bool_t 
1445 AliITStrackerMI::RefitAt(Double_t xx,AliITStrackMI *t,const AliITStrackMI *c) {
1446   //--------------------------------------------------------------------
1447   // This function refits the track "t" at the position "x" using
1448   // the clusters from "c"
1449   //--------------------------------------------------------------------
1450   Int_t index[kMaxLayer];
1451   Int_t k;
1452   for (k=0; k<kMaxLayer; k++) index[k]=-1;
1453   Int_t nc=c->GetNumberOfClusters();
1454   for (k=0; k<nc; k++) { 
1455     Int_t idx=c->GetClusterIndex(k),nl=(idx&0xf0000000)>>28;
1456     index[nl]=idx; 
1457   }
1458
1459   Int_t from, to, step;
1460   if (xx > t->GetX()) {
1461       from=0; to=kMaxLayer;
1462       step=+1;
1463   } else {
1464       from=kMaxLayer-1; to=-1;
1465       step=-1;
1466   }
1467
1468   for (Int_t i=from; i != to; i += step) {
1469      AliITSlayer &layer=fgLayers[i];
1470      Double_t r=layer.GetR();
1471  
1472      {
1473      Double_t hI=i-0.5*step; 
1474      if (TMath::Abs(hI-1.5)<0.01 || TMath::Abs(hI-3.5)<0.01) {             
1475         Double_t rs=0.5*(fgLayers[i-step].GetR() + r);
1476         Double_t d=0.0034, x0=38.6; 
1477         if (TMath::Abs(hI-1.5)<0.01) {rs=9.; d=0.0097; x0=42;}
1478         if (!t->PropagateTo(rs,-step*d,x0)) {
1479           return kFALSE;
1480         }
1481      }
1482      }
1483
1484      // remember old position [SR, GSI 18.02.2003]
1485      Double_t oldX=0., oldY=0., oldZ=0.;
1486      if (t->IsStartedTimeIntegral() && step==1) {
1487         t->GetGlobalXYZat(t->GetX(),oldX,oldY,oldZ);
1488      }
1489      //
1490
1491      Double_t x,y,z;
1492      if (!t->GetGlobalXYZat(r,x,y,z)) { 
1493        return kFALSE;
1494      }
1495      Double_t phi=TMath::ATan2(y,x);
1496      Int_t idet=layer.FindDetectorIndex(phi,z);
1497      if (idet<0) { 
1498        return kFALSE;
1499      }
1500      const AliITSdetector &det=layer.GetDetector(idet);
1501      phi=det.GetPhi();
1502      if (!t->Propagate(phi,det.GetR())) {
1503        return kFALSE;
1504      }
1505      t->SetDetectorIndex(idet);
1506
1507      const AliITSclusterV2 *cl=0;
1508      Double_t maxchi2=1000.*kMaxChi2;
1509
1510      Int_t idx=index[i];
1511      if (idx>0) {
1512         const AliITSclusterV2 *c=(AliITSclusterV2 *)GetCluster(idx); 
1513         if (idet != c->GetDetectorIndex()) {
1514            idet=c->GetDetectorIndex();
1515            const AliITSdetector &det=layer.GetDetector(idet);
1516            if (!t->Propagate(det.GetPhi(),det.GetR())) {
1517              return kFALSE;
1518            }
1519            t->SetDetectorIndex(idet);
1520         }
1521         //Double_t chi2=t->GetPredictedChi2(c);
1522         Int_t layer = (idx & 0xf0000000) >> 28;;
1523         Double_t chi2=GetPredictedChi2MI(t,c,layer);
1524         if (chi2<maxchi2) { 
1525           cl=c; 
1526           maxchi2=chi2; 
1527         } else {
1528           return kFALSE;
1529         }
1530      }
1531      /*
1532      if (cl==0)
1533      if (t->GetNumberOfClusters()>2) {
1534         Double_t dz=4*TMath::Sqrt(t->GetSigmaZ2()+kSigmaZ2[i]);
1535         Double_t dy=4*TMath::Sqrt(t->GetSigmaY2()+kSigmaY2[i]);
1536         Double_t zmin=t->GetZ() - dz;
1537         Double_t zmax=t->GetZ() + dz;
1538         Double_t ymin=t->GetY() + phi*r - dy;
1539         Double_t ymax=t->GetY() + phi*r + dy;
1540         layer.SelectClusters(zmin,zmax,ymin,ymax);
1541
1542         const AliITSclusterV2 *c=0; Int_t ci=-1;
1543         while ((c=layer.GetNextCluster(ci))!=0) {
1544            if (idet != c->GetDetectorIndex()) continue;
1545            Double_t chi2=t->GetPredictedChi2(c);
1546            if (chi2<maxchi2) { cl=c; maxchi2=chi2; idx=ci; }
1547         }
1548      }
1549      */
1550      if (cl) {
1551        //if (!t->Update(cl,maxchi2,idx)) {
1552        if (!UpdateMI(t,cl,maxchi2,idx)) {
1553           return kFALSE;
1554        }
1555        t->SetSampledEdx(cl->GetQ(),t->GetNumberOfClusters()-1);
1556      }
1557
1558      {
1559      Double_t x0;
1560      Double_t d=layer.GetThickness(t->GetY(),t->GetZ(),x0);
1561      t->CorrectForMaterial(-step*d,x0);
1562      }
1563                  
1564      // track time update [SR, GSI 17.02.2003]
1565      if (t->IsStartedTimeIntegral() && step==1) {
1566         Double_t newX, newY, newZ;
1567         t->GetGlobalXYZat(t->GetX(),newX,newY,newZ);
1568         Double_t dL2 = (oldX-newX)*(oldX-newX) + (oldY-newY)*(oldY-newY) + 
1569                        (oldZ-newZ)*(oldZ-newZ);
1570         t->AddTimeStep(TMath::Sqrt(dL2));
1571      }
1572      //
1573
1574   }
1575
1576   if (!t->PropagateTo(xx,0.,0.)) return kFALSE;
1577   return kTRUE;
1578 }
1579
1580
1581 Double_t AliITStrackerMI::GetNormalizedChi2(AliITStrackMI * track, Int_t mode)
1582 {
1583   //
1584   // calculate normalized chi2
1585   //  return NormalizedChi2(track,0);
1586   Float_t chi2 = 0;
1587   Float_t sum=0;
1588   Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
1589   //  track->fdEdxMismatch=0;
1590   Float_t dedxmismatch =0;
1591   Float_t *ny = GetNy(fCurrentEsdTrack), *nz = GetNz(fCurrentEsdTrack); 
1592   if (mode<100){
1593     for (Int_t i = 0;i<6;i++){
1594       if (track->fClIndex[i]>0){
1595         Float_t cerry, cerrz;
1596         if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
1597         else 
1598           { cerry= track->fSigmaY[i]; cerrz = track->fSigmaZ[i];}
1599         cerry*=cerry;
1600         cerrz*=cerrz;   
1601         Float_t cchi2 = (track->fDy[i]*track->fDy[i]/cerry)+(track->fDz[i]*track->fDz[i]/cerrz);
1602         if (i>1){
1603           Float_t ratio = track->fNormQ[i]/track->fExpQ;
1604           if (ratio<0.5) {
1605             cchi2+=(0.5-ratio)*10.;
1606             //track->fdEdxMismatch+=(0.5-ratio)*10.;
1607             dedxmismatch+=(0.5-ratio)*10.;          
1608           }
1609         }
1610         if (i<2 ||i>3){
1611           AliITSclusterV2 * cl = (AliITSclusterV2*)GetCluster( track->fClIndex[i]);  
1612           Double_t delta = cl->GetNy()+cl->GetNz()-ny[i]-nz[i];
1613           if (delta>1) chi2 +=0.5*TMath::Min(delta/2,2.); 
1614           if (i<2) chi2+=2*cl->GetDeltaProbability();
1615         }
1616         chi2+=cchi2;
1617         sum++;
1618       }
1619     }
1620     if (TMath::Abs(track->fdEdxMismatch-dedxmismatch)>0.0001){
1621       track->fdEdxMismatch = dedxmismatch;
1622     }
1623   }
1624   else{
1625     for (Int_t i = 0;i<4;i++){
1626       if (track->fClIndex[i]>0){
1627         Float_t cerry, cerrz;
1628         if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
1629         else { cerry= track->fSigmaY[i]; cerrz = track->fSigmaZ[i];}
1630         cerry*=cerry;
1631         cerrz*=cerrz;
1632         chi2+= (track->fDy[i]*track->fDy[i]/cerry);
1633         chi2+= (track->fDz[i]*track->fDz[i]/cerrz);      
1634         sum++;
1635       }
1636     }
1637     for (Int_t i = 4;i<6;i++){
1638       if (track->fClIndex[i]>0){        
1639         Float_t cerry, cerrz;
1640         if (ny[i]>0) {cerry = erry[i]; cerrz=errz[i];}
1641         else { cerry= track->fSigmaY[i]; cerrz = track->fSigmaZ[i];}
1642         cerry*=cerry;
1643         cerrz*=cerrz;   
1644         Float_t cerryb, cerrzb;
1645         if (ny[i+6]>0) {cerryb = erry[i+6]; cerrzb=errz[i+6];}
1646         else { cerryb= track->fSigmaY[i+6]; cerrzb = track->fSigmaZ[i+6];}
1647         cerryb*=cerryb;
1648         cerrzb*=cerrzb;
1649         chi2+= TMath::Min((track->fDy[i+6]*track->fDy[i+6]/cerryb),track->fDy[i]*track->fDy[i]/cerry);
1650         chi2+= TMath::Min((track->fDz[i+6]*track->fDz[i+6]/cerrzb),track->fDz[i]*track->fDz[i]/cerrz);      
1651         sum++;
1652       }
1653     }
1654   }
1655   if (track->fESDtrack->GetTPCsignal()>85){
1656     Float_t ratio = track->fdEdx/track->fESDtrack->GetTPCsignal();
1657     if (ratio<0.5) {
1658       chi2+=(0.5-ratio)*5.;      
1659     }
1660     if (ratio>2){
1661       chi2+=(ratio-2.0)*3; 
1662     }
1663   }
1664   //
1665   Double_t match = TMath::Sqrt(track->fChi22);
1666   if (track->fConstrain)  match/=track->GetNumberOfClusters();
1667   if (!track->fConstrain) match/=track->GetNumberOfClusters()-2.;
1668   if (match<0) match=0;
1669   Float_t deadzonefactor = (track->fNDeadZone>0) ? 3*(1.1-track->fDeadZoneProbability):0.;
1670   Double_t normchi2 = 2*track->fNSkipped+match+deadzonefactor+(1+(2*track->fNSkipped+deadzonefactor)/track->GetNumberOfClusters())*
1671     (chi2)/TMath::Max(double(sum-track->fNSkipped),
1672                                 1./(1.+track->fNSkipped));     
1673  
1674  return normchi2;
1675 }
1676
1677
1678 Double_t AliITStrackerMI::GetMatchingChi2(AliITStrackMI * track1, AliITStrackMI * track2)
1679 {
1680   //
1681   // return matching chi2 between two tracks
1682   AliITStrackMI track3(*track2);
1683   track3.Propagate(track1->GetAlpha(),track1->GetX());
1684   TMatrixD vec(5,1);
1685   vec(0,0)=track1->fP0-track3.fP0;
1686   vec(1,0)=track1->fP1-track3.fP1;
1687   vec(2,0)=track1->fP2-track3.fP2;
1688   vec(3,0)=track1->fP3-track3.fP3;
1689   vec(4,0)=track1->fP4-track3.fP4;
1690   //
1691   TMatrixD cov(5,5);
1692   cov(0,0) = track1->fC00+track3.fC00;
1693   cov(1,1) = track1->fC11+track3.fC11;
1694   cov(2,2) = track1->fC22+track3.fC22;
1695   cov(3,3) = track1->fC33+track3.fC33;
1696   cov(4,4) = track1->fC44+track3.fC44;
1697   
1698   cov(0,1)=cov(1,0) = track1->fC10+track3.fC10;
1699   cov(0,2)=cov(2,0) = track1->fC20+track3.fC20;
1700   cov(0,3)=cov(3,0) = track1->fC30+track3.fC30;
1701   cov(0,4)=cov(4,0) = track1->fC40+track3.fC40;
1702   //
1703   cov(1,2)=cov(2,1) = track1->fC21+track3.fC21;
1704   cov(1,3)=cov(3,1) = track1->fC31+track3.fC31;
1705   cov(1,4)=cov(4,1) = track1->fC41+track3.fC41;
1706   //
1707   cov(2,3)=cov(3,2) = track1->fC32+track3.fC32;
1708   cov(2,4)=cov(4,2) = track1->fC42+track3.fC42;
1709   //
1710   cov(3,4)=cov(4,3) = track1->fC43+track3.fC43;
1711   
1712   cov.Invert();
1713   TMatrixD vec2(cov,TMatrixD::kMult,vec);
1714   TMatrixD chi2(vec2,TMatrixD::kTransposeMult,vec);
1715   return chi2(0,0);
1716 }
1717
1718 Double_t  AliITStrackerMI::GetDeadZoneProbability(Double_t zpos, Double_t zerr)
1719 {
1720   //
1721   //  return probability that given point - characterized by z position and error  is in dead zone
1722   //
1723   Double_t probability =0;
1724   Double_t absz = TMath::Abs(zpos);
1725   Double_t nearestz = (absz<2)? 0.:7.1;
1726   if (TMath::Abs(absz-nearestz)>0.25+3*zerr) return 0;
1727   Double_t zmin=0, zmax=0;   
1728   if (zpos<-6.){
1729     zmin = -7.25; zmax = -6.95; 
1730   }
1731   if (zpos>6){
1732     zmin = 7.0; zmax =7.3;
1733   }
1734   if (absz<2){
1735     zmin = -0.75; zmax = 1.5;
1736   }
1737   probability = (TMath::Erf((zpos-zmin)/zerr) - TMath::Erf((zpos-zmax)/zerr))*0.5;
1738   return probability;
1739 }
1740
1741
1742 Double_t AliITStrackerMI::GetTruncatedChi2(AliITStrackMI * track, Float_t fac)
1743 {
1744   //
1745   // calculate normalized chi2
1746   Float_t chi2[6];
1747   Float_t *erry = GetErrY(fCurrentEsdTrack), *errz = GetErrZ(fCurrentEsdTrack);
1748   Float_t ncl = 0;
1749   for (Int_t i = 0;i<6;i++){
1750     if (TMath::Abs(track->fDy[i])>0){      
1751       chi2[i]= (track->fDy[i]/erry[i])*(track->fDy[i]/erry[i]);
1752       chi2[i]+= (track->fDz[i]/errz[i])*(track->fDz[i]/errz[i]);
1753       ncl++;
1754     }
1755     else{chi2[i]=10000;}
1756   }
1757   Int_t index[6];
1758   TMath::Sort(6,chi2,index,kFALSE);
1759   Float_t max = float(ncl)*fac-1.;
1760   Float_t sumchi=0, sumweight=0; 
1761   for (Int_t i=0;i<max+1;i++){
1762     Float_t weight = (i<max)?1.:(max+1.-i);
1763     sumchi+=weight*chi2[index[i]];
1764     sumweight+=weight;
1765   }
1766   Double_t normchi2 = sumchi/sumweight;
1767   return normchi2;
1768 }
1769
1770
1771 Double_t AliITStrackerMI::GetInterpolatedChi2(AliITStrackMI * forwardtrack, AliITStrackMI * backtrack)
1772 {
1773   //
1774   // calculate normalized chi2
1775   //  if (forwardtrack->fNUsed>0.3*float(forwardtrack->GetNumberOfClusters())) return 10000;
1776   Int_t npoints = 0;
1777   Double_t res =0;
1778   for (Int_t i=0;i<6;i++){
1779     if ( (backtrack->fSigmaY[i]<0.000000001) || (forwardtrack->fSigmaY[i]<0.000000001)) continue;
1780     Double_t sy1 = forwardtrack->fSigmaY[i];
1781     Double_t sz1 = forwardtrack->fSigmaZ[i];
1782     Double_t sy2 = backtrack->fSigmaY[i];
1783     Double_t sz2 = backtrack->fSigmaZ[i];
1784     if (i<2){ sy2=1000.;sz2=1000;}
1785     //    
1786     Double_t dy0 = (forwardtrack->fDy[i]/(sy1*sy1) +backtrack->fDy[i]/(sy2*sy2))/(1./(sy1*sy1)+1./(sy2*sy2));
1787     Double_t dz0 = (forwardtrack->fDz[i]/(sz1*sz1) +backtrack->fDz[i]/(sz2*sz2))/(1./(sz1*sz1)+1./(sz2*sz2));
1788     // 
1789     Double_t nz0 = dz0*TMath::Sqrt((1./(sz1*sz1)+1./(sz2*sz2)));
1790     Double_t ny0 = dy0*TMath::Sqrt((1./(sy1*sy1)+1./(sy2*sy2)));
1791     //
1792     res+= nz0*nz0+ny0*ny0;
1793     npoints++;
1794   }
1795   if (npoints>1) return 
1796                    TMath::Max(TMath::Abs(0.3*forwardtrack->Get1Pt())-0.5,0.)+
1797                    //2*forwardtrack->fNUsed+
1798                    res/TMath::Max(double(npoints-forwardtrack->fNSkipped),
1799                                   1./(1.+forwardtrack->fNSkipped));
1800   return 1000;
1801 }
1802    
1803
1804
1805
1806
1807 Float_t  *AliITStrackerMI::GetWeight(Int_t index) {
1808   //--------------------------------------------------------------------
1809   //       Return pointer to a given cluster
1810   //--------------------------------------------------------------------
1811   Int_t l=(index & 0xf0000000) >> 28;
1812   Int_t c=(index & 0x0fffffff) >> 00;
1813   return fgLayers[l].GetWeight(c);
1814 }
1815
1816 void AliITStrackerMI::RegisterClusterTracks(AliITStrackMI* track,Int_t id)
1817 {
1818   //---------------------------------------------
1819   // register track to the list
1820   //
1821   if (track->fESDtrack->GetKinkIndex(0)!=0) return;  //don't register kink tracks
1822   //
1823   //
1824   for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
1825     Int_t index = track->GetClusterIndex(icluster);
1826     Int_t l=(index & 0xf0000000) >> 28;
1827     Int_t c=(index & 0x0fffffff) >> 00;
1828     if (c>fgLayers[l].fN) continue;
1829     for (Int_t itrack=0;itrack<4;itrack++){
1830       if (fgLayers[l].fClusterTracks[itrack][c]<0){
1831         fgLayers[l].fClusterTracks[itrack][c]=id;
1832         break;
1833       }
1834     }
1835   }
1836 }
1837 void AliITStrackerMI::UnRegisterClusterTracks(AliITStrackMI* track, Int_t id)
1838 {
1839   //---------------------------------------------
1840   // unregister track from the list
1841   for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
1842     Int_t index = track->GetClusterIndex(icluster);
1843     Int_t l=(index & 0xf0000000) >> 28;
1844     Int_t c=(index & 0x0fffffff) >> 00;
1845     if (c>fgLayers[l].fN) continue;
1846     for (Int_t itrack=0;itrack<4;itrack++){
1847       if (fgLayers[l].fClusterTracks[itrack][c]==id){
1848         fgLayers[l].fClusterTracks[itrack][c]=-1;
1849       }
1850     }
1851   }
1852 }
1853 Float_t AliITStrackerMI::GetNumberOfSharedClusters(AliITStrackMI* track,Int_t id, Int_t list[6], AliITSclusterV2 *clist[6])
1854 {
1855   //-------------------------------------------------------------
1856   //get number of shared clusters
1857   //-------------------------------------------------------------
1858   Float_t shared=0;
1859   for (Int_t i=0;i<6;i++) { list[i]=-1, clist[i]=0;}
1860   // mean  number of clusters
1861   Float_t *ny = GetNy(id), *nz = GetNz(id); 
1862
1863  
1864   for (Int_t icluster=0;icluster<track->GetNumberOfClusters();icluster++){
1865     Int_t index = track->GetClusterIndex(icluster);
1866     Int_t l=(index & 0xf0000000) >> 28;
1867     Int_t c=(index & 0x0fffffff) >> 00;
1868     if (c>fgLayers[l].fN) continue;
1869     if (ny[l]==0){
1870       printf("problem\n");
1871     }
1872     AliITSclusterV2 *cl = (AliITSclusterV2*)GetCluster(index);
1873     Float_t weight=1;
1874     //
1875     Float_t deltan = 0;
1876     if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
1877     if (l>2&&track->fNormQ[l]/track->fExpQ>3.5) continue;
1878     if (l<2 || l>3){      
1879       deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
1880     }
1881     else{
1882       deltan = (cl->GetNz()-nz[l]);
1883     }
1884     if (deltan>2.0) continue;  // extended - highly probable shared cluster
1885     weight = 2./TMath::Max(3.+deltan,2.);
1886     //
1887     for (Int_t itrack=0;itrack<4;itrack++){
1888       if (fgLayers[l].fClusterTracks[itrack][c]>=0 && fgLayers[l].fClusterTracks[itrack][c]!=id){
1889         list[l]=index;
1890         clist[l] = (AliITSclusterV2*)GetCluster(index);
1891         shared+=weight; 
1892         break;
1893       }
1894     }
1895   }
1896   track->fNUsed=shared;
1897   return shared;
1898 }
1899
1900 Int_t AliITStrackerMI::GetOverlapTrack(AliITStrackMI *track, Int_t trackID, Int_t &shared, Int_t clusterlist[6],Int_t overlist[6])
1901 {
1902   //
1903   // find first shared track 
1904   //
1905   // mean  number of clusters
1906   Float_t *ny = GetNy(trackID), *nz = GetNz(trackID); 
1907   //
1908   for (Int_t i=0;i<6;i++) overlist[i]=-1;
1909   Int_t sharedtrack=100000;
1910   Int_t tracks[24],trackindex=0;
1911   for (Int_t i=0;i<24;i++) {tracks[i]=-1;}
1912   //
1913   for (Int_t icluster=0;icluster<6;icluster++){
1914     if (clusterlist[icluster]<0) continue;
1915     Int_t index = clusterlist[icluster];
1916     Int_t l=(index & 0xf0000000) >> 28;
1917     Int_t c=(index & 0x0fffffff) >> 00;
1918     if (ny[l]==0){
1919       printf("problem\n");
1920     }
1921     if (c>fgLayers[l].fN) continue;
1922     //if (l>3) continue;
1923     AliITSclusterV2 *cl = (AliITSclusterV2*)GetCluster(index);
1924     //
1925     Float_t deltan = 0;
1926     if (l>3&&cl->GetNy()+cl->GetNz()>6) continue;
1927     if (l>2&&track->fNormQ[l]/track->fExpQ>3.5) continue;
1928     if (l<2 || l>3){      
1929       deltan = (cl->GetNy()+cl->GetNz()-ny[l]-nz[l]);
1930     }
1931     else{
1932       deltan = (cl->GetNz()-nz[l]);
1933     }
1934     if (deltan>2.0) continue;  // extended - highly probable shared cluster
1935     //
1936     for (Int_t itrack=3;itrack>=0;itrack--){
1937       if (fgLayers[l].fClusterTracks[itrack][c]<0) continue;
1938       if (fgLayers[l].fClusterTracks[itrack][c]!=trackID){
1939        tracks[trackindex]  = fgLayers[l].fClusterTracks[itrack][c];
1940        trackindex++;
1941       }
1942     }
1943   }
1944   if (trackindex==0) return -1;
1945   if (trackindex==1){    
1946     sharedtrack = tracks[0];
1947   }else{
1948     if (trackindex==2) sharedtrack =TMath::Min(tracks[0],tracks[1]);
1949     else{
1950       //
1951       Int_t track[24], cluster[24];
1952       for (Int_t i=0;i<trackindex;i++){ track[i]=-1; cluster[i]=0;}
1953       Int_t index =0;
1954       //
1955       for (Int_t i=0;i<trackindex;i++){
1956         if (tracks[i]<0) continue;
1957         track[index] = tracks[i];
1958         cluster[index]++;       
1959         for (Int_t j=i+1;j<trackindex;j++){
1960           if (tracks[j]<0) continue;
1961           if (tracks[j]==tracks[i]){
1962             cluster[index]++;
1963             tracks[j]=-1;
1964           }
1965         }
1966         index++;
1967       }
1968       Int_t max=0;
1969       for (Int_t i=0;i<index;i++){
1970         if (cluster[index]>max) {
1971           sharedtrack=track[index];
1972           max=cluster[index];
1973         }
1974       }
1975     }
1976   }
1977   
1978   if (sharedtrack>=100000) return -1;
1979   //
1980   // make list of overlaps
1981   shared =0;
1982   for (Int_t icluster=0;icluster<6;icluster++){
1983     if (clusterlist[icluster]<0) continue;
1984     Int_t index = clusterlist[icluster];
1985     Int_t l=(index & 0xf0000000) >> 28;
1986     Int_t c=(index & 0x0fffffff) >> 00;
1987     if (c>fgLayers[l].fN) continue;
1988     AliITSclusterV2 *cl = (AliITSclusterV2*)GetCluster(index);
1989     if (l==0 || l==1){
1990       if (cl->GetNy()>2) continue;
1991       if (cl->GetNz()>2) continue;
1992     }
1993     if (l==4 || l==5){
1994       if (cl->GetNy()>3) continue;
1995       if (cl->GetNz()>3) continue;
1996     }
1997     //
1998     for (Int_t itrack=3;itrack>=0;itrack--){
1999       if (fgLayers[l].fClusterTracks[itrack][c]<0) continue;
2000       if (fgLayers[l].fClusterTracks[itrack][c]==sharedtrack){
2001         overlist[l]=index;
2002         shared++;      
2003       }
2004     }
2005   }
2006   return sharedtrack;
2007 }
2008
2009
2010 AliITStrackMI *  AliITStrackerMI::GetBest2Tracks(Int_t trackID1, Int_t trackID2, Float_t th0, Float_t th1){
2011   //
2012   // try to find track hypothesys without conflicts
2013   // with minimal chi2;
2014   TClonesArray *arr1 = (TClonesArray*)fTrackHypothesys.At(trackID1);
2015   Int_t entries1 = arr1->GetEntriesFast();
2016   TClonesArray *arr2 = (TClonesArray*)fTrackHypothesys.At(trackID2);
2017   if (!arr2) return (AliITStrackMI*) arr1->UncheckedAt(0);
2018   Int_t entries2 = arr2->GetEntriesFast();
2019   if (entries2<=0) return (AliITStrackMI*) arr1->UncheckedAt(0);
2020   //
2021   AliITStrackMI * track10=(AliITStrackMI*) arr1->UncheckedAt(0);
2022   AliITStrackMI * track20=(AliITStrackMI*) arr2->UncheckedAt(0);
2023   if (TMath::Abs(1./track10->Get1Pt())>0.5+TMath::Abs(1/track20->Get1Pt())) return track10;
2024
2025   for (Int_t itrack=0;itrack<entries1;itrack++){
2026     AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
2027     UnRegisterClusterTracks(track,trackID1);
2028   }
2029   //
2030   for (Int_t itrack=0;itrack<entries2;itrack++){
2031     AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
2032     UnRegisterClusterTracks(track,trackID2);
2033   }
2034   Int_t index1=0;
2035   Int_t index2=0;
2036   Float_t maxconflicts=6;
2037   Double_t maxchi2 =1000.;
2038   //
2039   // get weight of hypothesys - using best hypothesy
2040   Double_t w1,w2;
2041  
2042   Int_t list1[6],list2[6];
2043   AliITSclusterV2 *clist1[6], *clist2[6] ;
2044   RegisterClusterTracks(track10,trackID1);
2045   RegisterClusterTracks(track20,trackID2);
2046   Float_t conflict1 = GetNumberOfSharedClusters(track10,trackID1,list1,clist1);
2047   Float_t conflict2 = GetNumberOfSharedClusters(track20,trackID2,list2,clist2);
2048   UnRegisterClusterTracks(track10,trackID1);
2049   UnRegisterClusterTracks(track20,trackID2);
2050   //
2051   // normalized chi2
2052   Float_t chi21 =0,chi22=0,ncl1=0,ncl2=0;
2053   Float_t nerry[6],nerrz[6];
2054   Float_t *erry1=GetErrY(trackID1),*errz1 = GetErrZ(trackID1);
2055   Float_t *erry2=GetErrY(trackID2),*errz2 = GetErrZ(trackID2);
2056   for (Int_t i=0;i<6;i++){
2057      if ( (erry1[i]>0) && (erry2[i]>0)) {
2058        nerry[i] = TMath::Min(erry1[i],erry2[i]);
2059        nerrz[i] = TMath::Min(errz1[i],errz2[i]);
2060      }else{
2061        nerry[i] = TMath::Max(erry1[i],erry2[i]);
2062        nerrz[i] = TMath::Max(errz1[i],errz2[i]);
2063      }
2064      if (TMath::Abs(track10->fDy[i])>0.000000000000001){
2065        chi21 += track10->fDy[i]*track10->fDy[i]/(nerry[i]*nerry[i]);
2066        chi21 += track10->fDz[i]*track10->fDz[i]/(nerrz[i]*nerrz[i]);
2067        ncl1++;
2068      }
2069      if (TMath::Abs(track20->fDy[i])>0.000000000000001){
2070        chi22 += track20->fDy[i]*track20->fDy[i]/(nerry[i]*nerry[i]);
2071        chi22 += track20->fDz[i]*track20->fDz[i]/(nerrz[i]*nerrz[i]);
2072        ncl2++;
2073      }
2074   }
2075   chi21/=ncl1;
2076   chi22/=ncl2;
2077   //
2078   // 
2079   Float_t d1 = TMath::Sqrt(track10->fD[0]*track10->fD[0]+track10->fD[1]*track10->fD[1])+0.1;
2080   Float_t d2 = TMath::Sqrt(track20->fD[0]*track20->fD[0]+track20->fD[1]*track20->fD[1])+0.1;
2081   Float_t s1 = TMath::Sqrt(track10->GetSigmaY2()*track10->GetSigmaZ2());
2082   Float_t s2 = TMath::Sqrt(track20->GetSigmaY2()*track20->GetSigmaZ2());
2083   //
2084   w1 = (d2/(d1+d2)+ 2*s2/(s1+s2)+
2085         +s2/(s1+s2)*0.5*(chi22+2.)/(chi21+chi22+4.)
2086         +1.*TMath::Abs(1./track10->Get1Pt())/(TMath::Abs(1./track10->Get1Pt())+TMath::Abs(1./track20->Get1Pt()))
2087         );
2088   w2 = (d1/(d1+d2)+ 2*s1/(s1+s2)+
2089         s1/(s1+s2)*0.5*(chi21+2.)/(chi21+chi22+4.)
2090         +1.*TMath::Abs(1./track20->Get1Pt())/(TMath::Abs(1./track10->Get1Pt())+TMath::Abs(1./track20->Get1Pt()))
2091         );
2092
2093   Double_t sumw = w1+w2;
2094   w1/=sumw;
2095   w2/=sumw;
2096   if (w1<w2*0.5) {
2097     w1 = (d2+0.5)/(d1+d2+1.);
2098     w2 = (d1+0.5)/(d1+d2+1.);
2099   }
2100   //  Float_t maxmax       = w1*track10->fChi2MIP[0]+w2*track20->fChi2MIP[0]+w1*conflict1+w2*conflict2+1.;
2101   //Float_t maxconflicts0 = w1*conflict1+w2*conflict2;
2102   //
2103   // get pair of "best" hypothesys
2104   //  
2105   Float_t * ny1 = GetNy(trackID1), * nz1 = GetNz(trackID1); 
2106   Float_t * ny2 = GetNy(trackID2), * nz2 = GetNz(trackID2); 
2107
2108   for (Int_t itrack1=0;itrack1<entries1;itrack1++){
2109     AliITStrackMI * track1=(AliITStrackMI*) arr1->UncheckedAt(itrack1);
2110     //if (track1->fFakeRatio>0) continue;
2111     RegisterClusterTracks(track1,trackID1);
2112     for (Int_t itrack2=0;itrack2<entries2;itrack2++){
2113       AliITStrackMI * track2=(AliITStrackMI*) arr2->UncheckedAt(itrack2);
2114
2115       //      Float_t current = w1*track1->fChi2MIP[0]+w2*track2->fChi2MIP[0];
2116       //if (track2->fFakeRatio>0) continue;
2117       Float_t nskipped=0;            
2118       RegisterClusterTracks(track2,trackID2);
2119       Int_t list1[6],list2[6];
2120       AliITSclusterV2 *clist1[6], *clist2[6] ;
2121       Float_t cconflict1 = GetNumberOfSharedClusters(track1,trackID1,list1,clist1);
2122       Float_t cconflict2 = GetNumberOfSharedClusters(track2,trackID2,list2,clist2);
2123       UnRegisterClusterTracks(track2,trackID2);
2124       //
2125       if (track1->fConstrain) nskipped+=w1*track1->fNSkipped;
2126       if (track2->fConstrain) nskipped+=w2*track2->fNSkipped;
2127       if (nskipped>0.5) continue;
2128       //
2129       //if ( w1*conflict1+w2*conflict2>maxconflicts0) continue;
2130       if (conflict1+1<cconflict1) continue;
2131       if (conflict2+1<cconflict2) continue;
2132       Float_t conflict=0;
2133       Float_t sumchi2=0;
2134       Float_t sum=0;
2135       for (Int_t i=0;i<6;i++){
2136         //
2137         Float_t c1 =0.; // conflict coeficients
2138         Float_t c2 =0.; 
2139         if (clist1[i]&&clist2[i]){
2140           Float_t deltan = 0;
2141           if (i<2 || i>3){      
2142             deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-TMath::Max(ny1[i],ny2[i])-TMath::Max(nz1[i],nz2[i]));
2143           }
2144           else{
2145             deltan = (clist1[i]->GetNz()-TMath::Max(nz1[i],nz2[i]));
2146           }
2147           c1  = 2./TMath::Max(3.+deltan,2.);      
2148           c2  = 2./TMath::Max(3.+deltan,2.);      
2149         }
2150         else{
2151           if (clist1[i]){
2152             Float_t deltan = 0;
2153             if (i<2 || i>3){      
2154               deltan = (clist1[i]->GetNy()+clist1[i]->GetNz()-ny1[i]-nz1[i]);
2155             }
2156             else{
2157               deltan = (clist1[i]->GetNz()-nz1[i]);
2158             }
2159             c1  = 2./TMath::Max(3.+deltan,2.);    
2160             c2  = 0;
2161           }
2162
2163           if (clist2[i]){
2164             Float_t deltan = 0;
2165             if (i<2 || i>3){      
2166               deltan = (clist2[i]->GetNy()+clist2[i]->GetNz()-ny2[i]-nz2[i]);
2167             }
2168             else{
2169               deltan = (clist2[i]->GetNz()-nz2[i]);
2170             }
2171             c2  = 2./TMath::Max(3.+deltan,2.);    
2172             c1  = 0;
2173           }       
2174         }
2175         //
2176         Double_t chi21=0,chi22=0;
2177         if (TMath::Abs(track1->fDy[i])>0.) {
2178           chi21 = (track1->fDy[i]/track1->fSigmaY[i])*(track1->fDy[i]/track1->fSigmaY[i])+
2179             (track1->fDz[i]/track1->fSigmaZ[i])*(track1->fDz[i]/track1->fSigmaZ[i]);
2180           //chi21 = (track1->fDy[i]*track1->fDy[i])/(nerry[i]*nerry[i])+
2181           //  (track1->fDz[i]*track1->fDz[i])/(nerrz[i]*nerrz[i]);
2182         }else{
2183           if (TMath::Abs(track1->fSigmaY[i]>0.)) c1=1;
2184         }
2185         //
2186         if (TMath::Abs(track2->fDy[i])>0.) {
2187           chi22 = (track2->fDy[i]/track2->fSigmaY[i])*(track2->fDy[i]/track2->fSigmaY[i])+
2188             (track2->fDz[i]/track2->fSigmaZ[i])*(track2->fDz[i]/track2->fSigmaZ[i]);
2189           //chi22 = (track2->fDy[i]*track2->fDy[i])/(nerry[i]*nerry[i])+
2190           //  (track2->fDz[i]*track2->fDz[i])/(nerrz[i]*nerrz[i]);
2191         }
2192         else{
2193           if (TMath::Abs(track2->fSigmaY[i]>0.)) c2=1;
2194         }
2195         sumchi2+=w1*(1.+c1)*(1+c1)*(chi21+c1)+w2*(1.+c2)*(1+c2)*(chi22+c2);
2196         if (chi21>0) sum+=w1;
2197         if (chi22>0) sum+=w2;
2198         conflict+=(c1+c2);
2199       }
2200       Double_t norm = sum-w1*track1->fNSkipped-w2*track2->fNSkipped;
2201       if (norm<0) norm =1/(w1*track1->fNSkipped+w2*track2->fNSkipped);
2202       Double_t normchi2 = 2*conflict+sumchi2/sum;
2203       if ( normchi2 <maxchi2 ){   
2204         index1 = itrack1;
2205         index2 = itrack2;
2206         maxconflicts = conflict;
2207         maxchi2 = normchi2;
2208       }      
2209     }
2210     UnRegisterClusterTracks(track1,trackID1);
2211   }
2212   //
2213   //  if (maxconflicts<4 && maxchi2<th0){   
2214   if (maxchi2<th0*2.){   
2215     Float_t orig = track10->fFakeRatio*track10->GetNumberOfClusters();
2216     AliITStrackMI* track1=(AliITStrackMI*) arr1->UncheckedAt(index1);
2217     track1->fChi2MIP[5] = maxconflicts;
2218     track1->fChi2MIP[6] = maxchi2;
2219     track1->fChi2MIP[7] = 0.01+orig-(track1->fFakeRatio*track1->GetNumberOfClusters());
2220     //    track1->UpdateESDtrack(AliESDtrack::kITSin);
2221     track1->fChi2MIP[8] = index1;
2222     fBestTrackIndex[trackID1] =index1;
2223     UpdateESDtrack(track1, AliESDtrack::kITSin);
2224   }  
2225   else if (track10->fChi2MIP[0]<th1){
2226     track10->fChi2MIP[5] = maxconflicts;
2227     track10->fChi2MIP[6] = maxchi2;    
2228     //    track10->UpdateESDtrack(AliESDtrack::kITSin);
2229     UpdateESDtrack(track10,AliESDtrack::kITSin);
2230   }   
2231   
2232   for (Int_t itrack=0;itrack<entries1;itrack++){
2233     AliITStrackMI * track=(AliITStrackMI*) arr1->UncheckedAt(itrack);
2234     UnRegisterClusterTracks(track,trackID1);
2235   }
2236   //
2237   for (Int_t itrack=0;itrack<entries2;itrack++){
2238     AliITStrackMI * track=(AliITStrackMI*) arr2->UncheckedAt(itrack);
2239     UnRegisterClusterTracks(track,trackID2);
2240   }
2241
2242   if (track10->fConstrain&&track10->fChi2MIP[0]<kMaxChi2PerCluster[0]&&track10->fChi2MIP[1]<kMaxChi2PerCluster[1]
2243       &&track10->fChi2MIP[2]<kMaxChi2PerCluster[2]&&track10->fChi2MIP[3]<kMaxChi2PerCluster[3]){ 
2244     //  if (track10->fChi2MIP[0]<kMaxChi2PerCluster[0]&&track10->fChi2MIP[1]<kMaxChi2PerCluster[1]
2245   //    &&track10->fChi2MIP[2]<kMaxChi2PerCluster[2]&&track10->fChi2MIP[3]<kMaxChi2PerCluster[3]){ 
2246     RegisterClusterTracks(track10,trackID1);
2247   }
2248   if (track20->fConstrain&&track20->fChi2MIP[0]<kMaxChi2PerCluster[0]&&track20->fChi2MIP[1]<kMaxChi2PerCluster[1]
2249       &&track20->fChi2MIP[2]<kMaxChi2PerCluster[2]&&track20->fChi2MIP[3]<kMaxChi2PerCluster[3]){ 
2250     //if (track20->fChi2MIP[0]<kMaxChi2PerCluster[0]&&track20->fChi2MIP[1]<kMaxChi2PerCluster[1]
2251     //  &&track20->fChi2MIP[2]<kMaxChi2PerCluster[2]&&track20->fChi2MIP[3]<kMaxChi2PerCluster[3]){ 
2252     RegisterClusterTracks(track20,trackID2);  
2253   }
2254   return track10; 
2255  
2256 }
2257
2258 void AliITStrackerMI::UseClusters(const AliKalmanTrack *t, Int_t from) const {
2259   //--------------------------------------------------------------------
2260   // This function marks clusters assigned to the track
2261   //--------------------------------------------------------------------
2262   AliTracker::UseClusters(t,from);
2263
2264   AliITSclusterV2 *c=(AliITSclusterV2 *)GetCluster(t->GetClusterIndex(0));
2265   //if (c->GetQ()>2) c->Use();
2266   if (c->GetSigmaZ2()>0.1) c->Use();
2267   c=(AliITSclusterV2 *)GetCluster(t->GetClusterIndex(1));
2268   //if (c->GetQ()>2) c->Use();
2269   if (c->GetSigmaZ2()>0.1) c->Use();
2270
2271 }
2272
2273
2274 void AliITStrackerMI::AddTrackHypothesys(AliITStrackMI * track, Int_t esdindex)
2275 {
2276   //------------------------------------------------------------------
2277   // add track to the list of hypothesys
2278   //------------------------------------------------------------------
2279
2280   if (esdindex>=fTrackHypothesys.GetEntriesFast()) fTrackHypothesys.Expand(esdindex*2+10);
2281   //
2282   TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
2283   if (!array) {
2284     array = new TObjArray(10);
2285     fTrackHypothesys.AddAt(array,esdindex);
2286   }
2287   array->AddLast(track);
2288 }
2289
2290 void AliITStrackerMI::SortTrackHypothesys(Int_t esdindex, Int_t maxcut, Int_t mode)
2291 {
2292   //-------------------------------------------------------------------
2293   // compress array of track hypothesys
2294   // keep only maxsize best hypothesys
2295   //-------------------------------------------------------------------
2296   if (esdindex>fTrackHypothesys.GetEntriesFast()) return;
2297   if (! (fTrackHypothesys.At(esdindex)) ) return;
2298   TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
2299   Int_t entries = array->GetEntriesFast();
2300   //
2301   //- find preliminary besttrack as a reference
2302   Float_t minchi2=10000;
2303   Int_t maxn=0;
2304   AliITStrackMI * besttrack=0;
2305   for (Int_t itrack=0;itrack<array->GetEntriesFast();itrack++){
2306     AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
2307     if (!track) continue;
2308     Float_t chi2 = NormalizedChi2(track,0);
2309     //
2310     Int_t tpcLabel=track->fESDtrack->GetTPCLabel();
2311     track->SetLabel(tpcLabel);
2312     CookdEdx(track);
2313     track->fFakeRatio=1.;
2314     CookLabel(track,0.); //For comparison only
2315     //
2316     //if (chi2<kMaxChi2PerCluster[0]&&track->fFakeRatio==0){
2317     if (chi2<kMaxChi2PerCluster[0]){
2318       if (track->GetNumberOfClusters()<maxn) continue;
2319       maxn = track->GetNumberOfClusters();
2320       if (chi2<minchi2){
2321         minchi2=chi2;
2322         besttrack=track;
2323       }
2324     }
2325     else{
2326       if (track->fConstrain || track->fN>5){  //keep best short tracks - without vertex constrain
2327         delete array->RemoveAt(itrack);
2328       }  
2329     }
2330   }
2331   if (!besttrack) return;
2332   //
2333   //
2334   //take errors of best track as a reference
2335   Float_t *erry = GetErrY(esdindex), *errz = GetErrZ(esdindex);
2336   Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
2337   for (Int_t i=0;i<6;i++) {
2338     if (besttrack->fClIndex[i]>0){
2339       erry[i] = besttrack->fSigmaY[i]; erry[i+6] = besttrack->fSigmaY[i+6];
2340       errz[i] = besttrack->fSigmaZ[i]; errz[i+6] = besttrack->fSigmaZ[i+6];
2341       ny[i]   = besttrack->fNy[i];
2342       nz[i]   = besttrack->fNz[i];
2343     }
2344   }
2345   //
2346   // calculate normalized chi2
2347   //
2348   Float_t * chi2        = new Float_t[entries];
2349   Int_t * index         = new Int_t[entries];  
2350   for (Int_t i=0;i<entries;i++) chi2[i] =10000;
2351   for (Int_t itrack=0;itrack<entries;itrack++){
2352     AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
2353     if (track){
2354       track->fChi2MIP[0] = GetNormalizedChi2(track, mode);            
2355       if (track->fChi2MIP[0]<kMaxChi2PerCluster[0]) 
2356         chi2[itrack] = track->fChi2MIP[0];
2357       else{
2358         if (track->fConstrain || track->fN>5){  //keep best short tracks - without vertex constrain
2359           delete array->RemoveAt(itrack);            
2360         }
2361       }
2362     }
2363   }
2364   //
2365   TMath::Sort(entries,chi2,index,kFALSE);
2366   besttrack = (AliITStrackMI*)array->At(index[0]);
2367   if (besttrack&&besttrack->fChi2MIP[0]<kMaxChi2PerCluster[0]){
2368     for (Int_t i=0;i<6;i++){
2369       if (besttrack->fClIndex[i]>0){
2370         erry[i] = besttrack->fSigmaY[i]; erry[i+6] = besttrack->fSigmaY[i+6];
2371         errz[i] = besttrack->fSigmaZ[i]; erry[i+6] = besttrack->fSigmaY[i+6];
2372         ny[i]   = besttrack->fNy[i];
2373         nz[i]   = besttrack->fNz[i];
2374       }
2375     }
2376   }
2377   //
2378   // calculate one more time with updated normalized errors
2379   for (Int_t i=0;i<entries;i++) chi2[i] =10000;  
2380   for (Int_t itrack=0;itrack<entries;itrack++){
2381     AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
2382     if (track){      
2383       track->fChi2MIP[0] = GetNormalizedChi2(track,mode);            
2384       if (track->fChi2MIP[0]<kMaxChi2PerCluster[0]) 
2385         chi2[itrack] = track->fChi2MIP[0]-0*(track->GetNumberOfClusters()+track->fNDeadZone); 
2386       else
2387         {
2388           if (track->fConstrain || track->fN>5){  //keep best short tracks - without vertex constrain
2389             delete array->RemoveAt(itrack);     
2390           }
2391         }
2392     }   
2393   }
2394   entries = array->GetEntriesFast();  
2395   //
2396   //
2397   if (entries>0){
2398     TObjArray * newarray = new TObjArray();  
2399     TMath::Sort(entries,chi2,index,kFALSE);
2400     besttrack = (AliITStrackMI*)array->At(index[0]);
2401     if (besttrack){
2402       //
2403       for (Int_t i=0;i<6;i++){
2404         if (besttrack->fNz[i]>0&&besttrack->fNy[i]>0){
2405           erry[i] = besttrack->fSigmaY[i]; erry[i+6] = besttrack->fSigmaY[i+6];
2406           errz[i] = besttrack->fSigmaZ[i]; errz[i+6] = besttrack->fSigmaZ[i+6];
2407           ny[i]   = besttrack->fNy[i];
2408           nz[i]   = besttrack->fNz[i];
2409         }
2410       }
2411       besttrack->fChi2MIP[0] = GetNormalizedChi2(besttrack,mode);
2412       Float_t minchi2 = TMath::Min(besttrack->fChi2MIP[0]+5.+besttrack->fNUsed, double(kMaxChi2PerCluster[0]));
2413       Float_t minn = besttrack->GetNumberOfClusters()-3;
2414       Int_t accepted=0;
2415       for (Int_t i=0;i<entries;i++){
2416         AliITStrackMI * track = (AliITStrackMI*)array->At(index[i]);    
2417         if (!track) continue;
2418         if (accepted>maxcut) break;
2419         track->fChi2MIP[0] = GetNormalizedChi2(track,mode);
2420         if (track->fConstrain || track->fN>5){  //keep best short tracks - without vertex constrain
2421           if (track->GetNumberOfClusters()<6 && (track->fChi2MIP[0]+track->fNUsed>minchi2)){
2422             delete array->RemoveAt(index[i]);
2423             continue;
2424           }
2425         }
2426         Bool_t shortbest = !track->fConstrain && track->fN<6;
2427         if ((track->fChi2MIP[0]+track->fNUsed<minchi2 && track->GetNumberOfClusters()>=minn) ||shortbest){
2428           if (!shortbest) accepted++;
2429           //
2430           newarray->AddLast(array->RemoveAt(index[i]));      
2431           for (Int_t i=0;i<6;i++){
2432             if (nz[i]==0){
2433               erry[i] = track->fSigmaY[i]; erry[i+6] = track->fSigmaY[i+6];
2434               errz[i] = track->fSigmaZ[i]; errz[i]   = track->fSigmaZ[i+6];
2435               ny[i]   = track->fNy[i];
2436               nz[i]   = track->fNz[i];
2437             }
2438           }
2439         }
2440         else{
2441           delete array->RemoveAt(index[i]);
2442         }
2443       }
2444       array->Delete();
2445       delete fTrackHypothesys.RemoveAt(esdindex);
2446       fTrackHypothesys.AddAt(newarray,esdindex);
2447     }
2448     else{
2449       array->Delete();
2450       delete fTrackHypothesys.RemoveAt(esdindex);
2451     }
2452   }
2453   delete [] chi2;
2454   delete [] index;
2455 }
2456
2457
2458
2459 AliITStrackMI * AliITStrackerMI::GetBestHypothesys(Int_t esdindex, AliITStrackMI * original, Int_t checkmax)
2460 {
2461   //-------------------------------------------------------------
2462   // try to find best hypothesy
2463   // currently - minimal chi2 of track+backpropagated track+matching to the tpc track
2464   //-------------------------------------------------------------
2465   if (fTrackHypothesys.GetEntriesFast()<=esdindex) return 0;
2466   TObjArray * array = (TObjArray*) fTrackHypothesys.At(esdindex);
2467   if (!array) return 0;
2468   Int_t entries = array->GetEntriesFast();
2469   if (!entries) return 0;  
2470   Float_t minchi2 = 100000;
2471   AliITStrackMI * besttrack=0;
2472   //
2473   AliITStrackMI * backtrack    = new AliITStrackMI(*original);
2474   AliITStrackMI * forwardtrack = new AliITStrackMI(*original);
2475   Double_t xyzv[]={GetX(),GetY(),GetZ()};       
2476   Double_t ersv[]={GetSigmaX()/3.,GetSigmaY()/3.,GetSigmaZ()/3.};
2477   //
2478   for (Int_t i=0;i<entries;i++){    
2479     AliITStrackMI * track = (AliITStrackMI*)array->At(i);    
2480     if (!track) continue;
2481     Float_t sigmarfi,sigmaz;
2482     GetDCASigma(track,sigmarfi,sigmaz);
2483     track->fDnorm[0] = sigmarfi;
2484     track->fDnorm[1] = sigmaz;
2485     //
2486     track->fChi2MIP[1] = 1000000;
2487     track->fChi2MIP[2] = 1000000;
2488     track->fChi2MIP[3] = 1000000;
2489     //
2490     // backtrack
2491     backtrack = new(backtrack) AliITStrackMI(*track); 
2492     if (track->fConstrain){
2493       if (!backtrack->PropagateTo(3.,0.0028,65.19)) continue;
2494       if (!backtrack->Improve(0,xyzv,ersv))         continue;      
2495       if (!backtrack->PropagateTo(2.,0.0028,0))     continue;
2496       if (!backtrack->Improve(0,xyzv,ersv))         continue;
2497       if (!backtrack->PropagateTo(1.,0.0028,0))     continue;
2498       if (!backtrack->Improve(0,xyzv,ersv))         continue;                     
2499       if (!backtrack->PropagateToVertex())          continue;
2500       backtrack->ResetCovariance();      
2501       if (!backtrack->Improve(0,xyzv,ersv))         continue;                           
2502     }else{
2503       backtrack->ResetCovariance();
2504     }
2505     backtrack->ResetClusters();
2506
2507     Double_t x = original->GetX();
2508     if (!RefitAt(x,backtrack,track)) continue;
2509     //
2510     track->fChi2MIP[1] = NormalizedChi2(backtrack,0);
2511     //for (Int_t i=2;i<6;i++){track->fDy[i]+=backtrack->fDy[i]; track->fDz[i]+=backtrack->fDz[i];}
2512     if (track->fChi2MIP[1]>kMaxChi2PerCluster[1]*6.)  continue;
2513     track->fChi22 = GetMatchingChi2(backtrack,original);
2514
2515     if ((track->fConstrain) && track->fChi22>90.)  continue;
2516     if ((!track->fConstrain) && track->fChi22>30.)  continue;
2517     if ( track->fChi22/track->GetNumberOfClusters()>11.)  continue;
2518
2519
2520     if  (!(track->fConstrain)&&track->fChi2MIP[1]>kMaxChi2PerCluster[1])  continue;
2521     Bool_t isOK=kTRUE;
2522     if(!isOK) continue;
2523     //
2524     //forward track - without constraint
2525     forwardtrack = new(forwardtrack) AliITStrackMI(*original);
2526     forwardtrack->ResetClusters();
2527     x = track->GetX();
2528     RefitAt(x,forwardtrack,track);
2529     track->fChi2MIP[2] = NormalizedChi2(forwardtrack,0);    
2530     if  (track->fChi2MIP[2]>kMaxChi2PerCluster[2]*6.0)  continue;
2531     if  (!(track->fConstrain)&&track->fChi2MIP[2]>kMaxChi2PerCluster[2])  continue;
2532     
2533     track->fD[0] = forwardtrack->GetD(GetX(),GetY());
2534     track->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
2535     forwardtrack->fD[0] = track->fD[0];
2536     forwardtrack->fD[1] = track->fD[1];    
2537     {
2538       Int_t list[6];
2539       AliITSclusterV2* clist[6];
2540       track->fChi2MIP[4] = GetNumberOfSharedClusters(track,esdindex,list,clist);      
2541       if ( (!track->fConstrain) && track->fChi2MIP[4]>1.0) continue;
2542     }
2543     
2544     track->fChi2MIP[3] = GetInterpolatedChi2(forwardtrack,backtrack);
2545     if  ( (track->fChi2MIP[3]>6.*kMaxChi2PerCluster[3])) continue;    
2546     if  ( (!track->fConstrain) && (track->fChi2MIP[3]>2*kMaxChi2PerCluster[3])) {
2547       track->fChi2MIP[3]=1000;
2548       continue; 
2549     }
2550     Double_t chi2 = track->fChi2MIP[0]+track->fNUsed;    
2551     //
2552     for (Int_t ichi=0;ichi<5;ichi++){
2553       forwardtrack->fChi2MIP[ichi] = track->fChi2MIP[ichi];
2554     }
2555     if (chi2 < minchi2){
2556       //besttrack = new AliITStrackMI(*forwardtrack);
2557       besttrack = track;
2558       besttrack->SetLabel(track->GetLabel());
2559       besttrack->fFakeRatio = track->fFakeRatio;
2560       minchi2   = chi2;
2561       original->fD[0] = forwardtrack->GetD(GetX(),GetY());
2562       original->fD[1] = forwardtrack->GetZat(GetX())-GetZ();
2563     }    
2564   }
2565   delete backtrack;
2566   delete forwardtrack;
2567   Int_t accepted=0;
2568   for (Int_t i=0;i<entries;i++){    
2569     AliITStrackMI * track = (AliITStrackMI*)array->At(i);   
2570     if (!track) continue;
2571     
2572     if (accepted>checkmax || track->fChi2MIP[3]>kMaxChi2PerCluster[3]*6. || 
2573         (track->GetNumberOfClusters()<besttrack->GetNumberOfClusters()-1.)||
2574         track->fChi2MIP[0]>besttrack->fChi2MIP[0]+2.*besttrack->fNUsed+3.){
2575       if (track->fConstrain || track->fN>5){  //keep best short tracks - without vertex constrain
2576         delete array->RemoveAt(i);    
2577         continue;
2578       }
2579     }
2580     else{
2581       accepted++;
2582     }
2583   }
2584   //
2585   array->Compress();
2586   SortTrackHypothesys(esdindex,checkmax,1);
2587   array = (TObjArray*) fTrackHypothesys.At(esdindex);
2588   besttrack = (AliITStrackMI*)array->At(0);  
2589   if (!besttrack)  return 0;
2590   besttrack->fChi2MIP[8]=0;
2591   fBestTrackIndex[esdindex]=0;
2592   entries = array->GetEntriesFast();
2593   AliITStrackMI *longtrack =0;
2594   minchi2 =1000;
2595   Float_t minn=besttrack->GetNumberOfClusters()+besttrack->fNDeadZone;
2596   for (Int_t itrack=entries-1;itrack>0;itrack--){
2597     AliITStrackMI * track = (AliITStrackMI*)array->At(itrack);
2598     if (!track->fConstrain) continue;
2599     if (track->GetNumberOfClusters()+track->fNDeadZone<minn) continue;
2600     if (track->fChi2MIP[0]-besttrack->fChi2MIP[0]>0.0) continue;
2601     if (track->fChi2MIP[0]>4.) continue;
2602     minn = track->GetNumberOfClusters()+track->fNDeadZone;
2603     longtrack =track;
2604   }
2605   //if (longtrack) besttrack=longtrack;
2606
2607   Int_t list[6];
2608   AliITSclusterV2 * clist[6];
2609   Float_t shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
2610   if (besttrack->fConstrain&&besttrack->fChi2MIP[0]<kMaxChi2PerCluster[0]&&besttrack->fChi2MIP[1]<kMaxChi2PerCluster[1]
2611       &&besttrack->fChi2MIP[2]<kMaxChi2PerCluster[2]&&besttrack->fChi2MIP[3]<kMaxChi2PerCluster[3]){ 
2612     RegisterClusterTracks(besttrack,esdindex);
2613   }
2614   //
2615   //
2616   if (shared>0.0){
2617     Int_t nshared;
2618     Int_t overlist[6];
2619     Int_t sharedtrack = GetOverlapTrack(besttrack, esdindex, nshared, list, overlist);
2620     if (sharedtrack>=0){
2621       //
2622       besttrack = GetBest2Tracks(esdindex,sharedtrack,10,5.5);     
2623       if (besttrack){
2624         shared = GetNumberOfSharedClusters(besttrack,esdindex,list,clist);
2625       }
2626       else return 0;
2627     }
2628   }  
2629   
2630   if (shared>2.5) return 0;
2631   if (shared>1.0) return besttrack;
2632   //
2633   // Don't sign clusters if not gold track
2634   //
2635   if (!besttrack->IsGoldPrimary()) return besttrack;
2636   if (besttrack->fESDtrack->GetKinkIndex(0)!=0) return besttrack;   //track belong to kink
2637   //
2638   if (fConstraint[fPass]){
2639     //
2640     // sign clusters
2641     //
2642     Float_t *ny = GetNy(esdindex), *nz = GetNz(esdindex);
2643     for (Int_t i=0;i<6;i++){
2644       Int_t index = besttrack->fClIndex[i];
2645       if (index<=0) continue; 
2646       Int_t ilayer =  (index & 0xf0000000) >> 28;
2647       if (besttrack->fSigmaY[ilayer]<0.00000000001) continue;
2648       AliITSclusterV2 *c = (AliITSclusterV2*)GetCluster(index);     
2649       if (!c) continue;
2650       if (ilayer>3&&c->GetNy()+c->GetNz()>6) continue;
2651       if ( (c->GetNy()+c->GetNz() )> ny[i]+nz[i]+0.7) continue; //shared track
2652       if (  c->GetNz()> nz[i]+0.7) continue; //shared track
2653       if ( ilayer>2&& besttrack->fNormQ[ilayer]/besttrack->fExpQ>1.5) continue;
2654       //if (  c->GetNy()> ny[i]+0.7) continue; //shared track
2655
2656       Bool_t cansign = kTRUE;
2657       for (Int_t itrack=0;itrack<entries; itrack++){
2658         AliITStrackMI * track = (AliITStrackMI*)array->At(i);   
2659         if (!track) continue;
2660         if (track->fChi2MIP[0]>besttrack->fChi2MIP[0]+2.*shared+1.) break;
2661         if ( (track->fClIndex[ilayer]>0) && (track->fClIndex[ilayer]!=besttrack->fClIndex[ilayer])){
2662           cansign = kFALSE;
2663           break;
2664         }
2665       }
2666       if (cansign){
2667         if (TMath::Abs(besttrack->fDy[ilayer]/besttrack->fSigmaY[ilayer])>3.) continue;
2668         if (TMath::Abs(besttrack->fDz[ilayer]/besttrack->fSigmaZ[ilayer])>3.) continue;    
2669         if (!c->IsUsed()) c->Use();
2670       }
2671     }
2672   }
2673   return besttrack;
2674
2675
2676
2677
2678 void  AliITStrackerMI::GetBestHypothesysMIP(TObjArray &itsTracks)
2679 {
2680   //
2681   // get "best" hypothesys
2682   //
2683
2684   Int_t nentries = itsTracks.GetEntriesFast();
2685   for (Int_t i=0;i<nentries;i++){
2686     AliITStrackMI* track = (AliITStrackMI*)itsTracks.At(i);
2687     if (!track) continue;
2688     TObjArray * array = (TObjArray*) fTrackHypothesys.At(i);
2689     if (!array) continue;
2690     if (array->GetEntriesFast()<=0) continue;
2691     //
2692     AliITStrackMI* longtrack=0;
2693     Float_t minn=0;
2694     Float_t maxchi2=1000;
2695     for (Int_t j=0;j<array->GetEntriesFast();j++){
2696       AliITStrackMI* track = (AliITStrackMI*)array->At(j);
2697       if (!track) continue;
2698       if (track->fGoldV0) {
2699         longtrack = track;   //gold V0 track taken
2700         break;
2701       }
2702       if (track->GetNumberOfClusters()+track->fNDeadZone<minn) continue;
2703       Float_t chi2 = track->fChi2MIP[0];
2704       if (fAfterV0){
2705         if (!track->fGoldV0&&track->fConstrain==kFALSE) chi2+=5;
2706       }
2707       if (track->GetNumberOfClusters()+track->fNDeadZone>minn) maxchi2 = track->fChi2MIP[0];       
2708       //
2709       if (chi2 > maxchi2) continue;
2710       minn= track->GetNumberOfClusters()+track->fNDeadZone;
2711       maxchi2 = chi2;
2712       longtrack=track;
2713     }    
2714     //
2715     //
2716     //
2717     AliITStrackMI * besttrack = (AliITStrackMI*)array->At(0);
2718     if (!longtrack) {longtrack = besttrack;}
2719     else besttrack= longtrack;
2720     //
2721     if (besttrack){
2722       Int_t list[6];
2723       AliITSclusterV2 * clist[6];
2724       Float_t shared = GetNumberOfSharedClusters(longtrack,i,list,clist);
2725       //
2726       track->fNUsed = shared;      
2727       track->fNSkipped = besttrack->fNSkipped;
2728       track->fChi2MIP[0] = besttrack->fChi2MIP[0];
2729       if (shared>0){
2730         Int_t nshared;
2731         Int_t overlist[6]; 
2732         //
2733         Int_t sharedtrack = GetOverlapTrack(longtrack, i, nshared, list, overlist);
2734         //if (sharedtrack==-1) sharedtrack=0;
2735         if (sharedtrack>=0){       
2736           besttrack = GetBest2Tracks(i,sharedtrack,10,5.5);                       
2737         }
2738       }   
2739       if (besttrack&&fAfterV0){
2740         UpdateESDtrack(besttrack,AliESDtrack::kITSin);
2741       }
2742       if (besttrack&&fConstraint[fPass]) 
2743         UpdateESDtrack(besttrack,AliESDtrack::kITSin);
2744       //if (besttrack&&besttrack->fConstrain) 
2745       //        UpdateESDtrack(besttrack,AliESDtrack::kITSin);
2746       if (besttrack->fChi2MIP[0]+besttrack->fNUsed>1.5){
2747         if ( (TMath::Abs(besttrack->fD[0])>0.1) && fConstraint[fPass]) {
2748           track->fReconstructed= kFALSE;
2749         }
2750         if ( (TMath::Abs(besttrack->fD[1])>0.1) && fConstraint[fPass]){
2751           track->fReconstructed= kFALSE;
2752         }
2753       }       
2754
2755     }    
2756   }
2757
2758
2759
2760 void AliITStrackerMI::CookLabel(AliITStrackMI *track,Float_t wrong) const {
2761   //--------------------------------------------------------------------
2762   //This function "cooks" a track label. If label<0, this track is fake.
2763   //--------------------------------------------------------------------
2764   Int_t tpcLabel=-1; 
2765      
2766   if ( track->fESDtrack)   tpcLabel =  TMath::Abs(track->fESDtrack->GetTPCLabel());
2767
2768    track->fChi2MIP[9]=0;
2769    Int_t nwrong=0;
2770    for (Int_t i=0;i<track->GetNumberOfClusters();i++){
2771      Int_t cindex = track->GetClusterIndex(i);
2772      Int_t l=(cindex & 0xf0000000) >> 28;
2773      AliITSclusterV2 *cl = (AliITSclusterV2*)GetCluster(cindex);
2774      Int_t isWrong=1;
2775      for (Int_t ind=0;ind<3;ind++){
2776        if (tpcLabel>0)
2777          if (cl->GetLabel(ind)==tpcLabel) isWrong=0;
2778      }
2779      track->fChi2MIP[9]+=isWrong*(2<<l);
2780      nwrong+=isWrong;
2781    }
2782    track->fFakeRatio = double(nwrong)/double(track->GetNumberOfClusters());
2783    if (tpcLabel>0){
2784      if (track->fFakeRatio>wrong) track->fLab = -tpcLabel;
2785      else
2786        track->fLab = tpcLabel;
2787    }
2788    
2789 }
2790
2791
2792
2793 void AliITStrackerMI::CookdEdx(AliITStrackMI* track)
2794 {
2795   //
2796   //
2797   //  Int_t list[6];
2798   //AliITSclusterV2 * clist[6];
2799   //  Int_t shared = GetNumberOfSharedClusters(track,index,list,clist);
2800   Float_t dedx[4];
2801   Int_t accepted=0;
2802   track->fChi2MIP[9]=0;
2803   for (Int_t i=0;i<track->GetNumberOfClusters();i++){
2804     Int_t cindex = track->GetClusterIndex(i);
2805     Int_t l=(cindex & 0xf0000000) >> 28;
2806     AliITSclusterV2 *cl = (AliITSclusterV2*)GetCluster(cindex);
2807     Int_t lab = TMath::Abs(track->fESDtrack->GetTPCLabel());
2808     Int_t isWrong=1;
2809     for (Int_t ind=0;ind<3;ind++){
2810       if (cl->GetLabel(ind)==lab) isWrong=0;
2811     }
2812     track->fChi2MIP[9]+=isWrong*(2<<l);
2813     if (l<2) continue;
2814     //if (l>3 && (cl->GetNy()>4) || (cl->GetNz()>4)) continue;  //shared track
2815     //if (l>3&& !(cl->GetType()==1||cl->GetType()==10)) continue;
2816     //if (l<4&& !(cl->GetType()==1)) continue;   
2817     dedx[accepted]= track->fdEdxSample[i];
2818     //dedx[accepted]= track->fNormQ[l];
2819     accepted++;
2820   }
2821   if (accepted<1) {
2822     track->SetdEdx(0);
2823     return;
2824   }
2825   Int_t indexes[4];
2826   TMath::Sort(accepted,dedx,indexes,kFALSE);
2827   Double_t low=0.;
2828   Double_t up=0.51;    
2829   Double_t nl=low*accepted, nu =up*accepted;  
2830   Float_t sumamp = 0;
2831   Float_t sumweight =0;
2832   for (Int_t i=0; i<accepted; i++) {
2833     Float_t weight =1;
2834     if (i<nl+0.1)     weight = TMath::Max(1.-(nl-i),0.);
2835     if (i>nu-1)     weight = TMath::Max(nu-i,0.);
2836     sumamp+= dedx[indexes[i]]*weight;
2837     sumweight+=weight;
2838   }
2839   track->SetdEdx(sumamp/sumweight);
2840 }
2841
2842
2843 void  AliITStrackerMI::MakeCoeficients(Int_t ntracks){
2844   //
2845   //
2846   if (fCoeficients) delete []fCoeficients;
2847   fCoeficients = new Float_t[ntracks*48];
2848   for (Int_t i=0;i<ntracks*48;i++) fCoeficients[i]=-1.;
2849 }
2850
2851
2852 Double_t AliITStrackerMI::GetPredictedChi2MI(AliITStrackMI* track, const AliITSclusterV2 *cluster,Int_t layer) 
2853 {
2854   //
2855   //
2856   //
2857   Float_t erry,errz;
2858   Float_t theta = track->GetTgl();
2859   Float_t phi   = track->GetSnp();
2860   phi = TMath::Sqrt(phi*phi/(1.-phi*phi));
2861   GetError(layer,cluster,theta,phi,track->fExpQ,erry,errz);
2862   Double_t chi2 = track->GetPredictedChi2MI(cluster->GetY(),cluster->GetZ(),erry,errz);
2863   Float_t ny,nz;
2864   GetNTeor(layer,cluster, theta,phi,ny,nz);  
2865   Double_t delta = cluster->GetNy()+cluster->GetNz()-nz-ny;
2866   if (delta>1){
2867     chi2+=0.5*TMath::Min(delta/2,2.);
2868     chi2+=2.*cluster->GetDeltaProbability();
2869   }
2870   //
2871   track->fNy[layer] =ny;
2872   track->fNz[layer] =nz;
2873   track->fSigmaY[layer] = erry;
2874   track->fSigmaZ[layer] = errz;
2875   //track->fNormQ[layer] = cluster->GetQ()/TMath::Sqrt(1+theta*theta+phi*phi);
2876   track->fNormQ[layer] = cluster->GetQ()/TMath::Sqrt((1.+ track->fP3*track->fP3)/(1.- track->fP2*track->fP2));
2877   return chi2;
2878
2879 }
2880
2881 Int_t    AliITStrackerMI::UpdateMI(AliITStrackMI* track, const AliITSclusterV2* cl,Double_t chi2,Int_t index) const 
2882 {
2883   //
2884   //
2885   //
2886   Int_t layer = (index & 0xf0000000) >> 28;
2887   track->fClIndex[layer] = index;
2888   if ( (layer>1) &&track->fNormQ[layer]/track->fExpQ<0.5 ) {
2889     chi2+= (0.5-track->fNormQ[layer]/track->fExpQ)*10.;
2890     track->fdEdxMismatch+=(0.5-track->fNormQ[layer]/track->fExpQ)*10.;
2891   }
2892   return track->UpdateMI(cl->GetY(),cl->GetZ(),track->fSigmaY[layer],track->fSigmaZ[layer],chi2,index);
2893 }
2894
2895 void AliITStrackerMI::GetNTeor(Int_t layer, const AliITSclusterV2* /*cl*/, Float_t theta, Float_t phi, Float_t &ny, Float_t &nz)
2896 {
2897   //
2898   //get "mean shape"
2899   //
2900   if (layer==0){
2901     ny = 1.+TMath::Abs(phi)*3.2;
2902     nz = 1.+TMath::Abs(theta)*0.34;
2903     return;
2904   }
2905   if (layer==1){
2906     ny = 1.+TMath::Abs(phi)*3.2;
2907     nz = 1.+TMath::Abs(theta)*0.28;
2908     return;
2909   }
2910   
2911   if (layer>3){
2912     ny = 2.02+TMath::Abs(phi)*1.95;
2913     nz = 2.02+TMath::Abs(phi)*2.35;
2914     return;
2915   }
2916   ny  = 6.6-2.7*TMath::Abs(phi);
2917   nz  = 2.8-3.11*TMath::Abs(phi)+0.45*TMath::Abs(theta);
2918 }
2919
2920
2921
2922 Int_t AliITStrackerMI::GetError(Int_t layer, const AliITSclusterV2*cl, Float_t theta, Float_t phi,Float_t expQ, Float_t &erry, Float_t &errz)
2923 {
2924   //calculate cluster position error
2925   //
2926   Float_t nz,ny;
2927   GetNTeor(layer, cl,theta,phi,ny,nz);  
2928   erry   = TMath::Sqrt(cl->GetSigmaY2()); 
2929   errz   = TMath::Sqrt(cl->GetSigmaZ2()); 
2930   //
2931   // PIXELS
2932   if (layer<2){
2933     
2934     if (TMath::Abs(ny-cl->GetNy())>0.6)  {
2935       if (ny<cl->GetNy()){
2936         erry*=0.4+TMath::Abs(ny-cl->GetNy());
2937         errz*=0.4+TMath::Abs(ny-cl->GetNy());
2938       }else{
2939         erry*=0.7+0.5*TMath::Abs(ny-cl->GetNy());
2940         errz*=0.7+0.5*TMath::Abs(ny-cl->GetNy());
2941       }
2942     }
2943     if (TMath::Abs(nz-cl->GetNz())>1.)  {
2944       erry*=TMath::Abs(nz-cl->GetNz());
2945       errz*=TMath::Abs(nz-cl->GetNz());       
2946     }
2947     erry*=0.85;
2948     errz*=0.85;
2949     erry= TMath::Min(erry,float(0.005));
2950     errz= TMath::Min(errz,float(0.03));
2951     return 10;
2952   }
2953
2954 //STRIPS
2955   if (layer>3){ 
2956     //factor 1.8 appears in new simulation
2957     //
2958     Float_t scale=1.8;
2959     if (cl->GetNy()==100||cl->GetNz()==100){
2960       erry = 0.004*scale;
2961       errz = 0.2*scale;
2962       return 100;
2963     }
2964     if (cl->GetNy()+cl->GetNz()>12){
2965       erry = 0.06*scale;
2966       errz = 0.57*scale;
2967       return 100;
2968     }
2969     Float_t normq = cl->GetQ()/(TMath::Sqrt(1+theta*theta+phi*phi));
2970     Float_t chargematch = TMath::Max(double(normq/expQ),2.);
2971     //
2972     if (cl->GetType()==1 || cl->GetType()==10 ){                                                               
2973       if (chargematch<1.0 || (cl->GetNy()+cl->GetNz()<nz+ny+0.5)){
2974         errz = 0.043*scale;
2975         erry = 0.00094*scale;
2976         return 101;
2977       }
2978       if (cl->GetNy()+cl->GetNz()<nz+ny+1.2){
2979         errz = 0.06*scale;
2980         erry =0.0013*scale;
2981         return 102;
2982       }
2983       erry = 0.0027*scale;
2984       errz = TMath::Min(0.028*(chargematch+cl->GetNy()+cl->GetNz()-nz+ny),0.15)*scale;
2985       return 103;
2986     }
2987     if (cl->GetType()==2 || cl->GetType()==11 ){ 
2988       erry = TMath::Min(0.0010*(1+chargematch+cl->GetNy()+cl->GetNz()-nz+ny),0.05)*scale;
2989       errz = TMath::Min(0.025*(1+chargematch+cl->GetNy()+cl->GetNz()-nz+ny),0.5)*scale;
2990       return 104;
2991     }
2992     
2993     if (cl->GetType()>100 ){                                                                   
2994       if ((chargematch+cl->GetNy()+cl->GetNz()-nz-ny<1.5)){
2995         errz = 0.05*scale;
2996         erry = 0.00096*scale;
2997         return 105;
2998       }
2999       if (cl->GetNy()+cl->GetNz()-nz-ny<1){
3000         errz = 0.10*scale;
3001         erry = 0.0025*scale;
3002         return 106;
3003       }
3004
3005       errz = TMath::Min(0.05*(chargematch+cl->GetNy()+cl->GetNz()-nz-ny),0.4)*scale;
3006       erry = TMath::Min(0.003*(chargematch+cl->GetNy()+cl->GetNz()-nz-ny),0.05)*scale;
3007       return 107;
3008     }    
3009     Float_t diff = cl->GetNy()+cl->GetNz()-ny-nz;
3010     if (diff<1) diff=1;
3011     if (diff>4) diff=4;
3012         
3013     if (cl->GetType()==5||cl->GetType()==6||cl->GetType()==7||cl->GetType()==8){
3014       errz = 0.14*diff;
3015       erry = 0.003*diff;
3016       return 108;
3017     }  
3018     erry = 0.04*diff;
3019     errz = 0.06*diff;
3020     return 109;
3021   }
3022   //DRIFTS
3023   Float_t normq = cl->GetQ()/(TMath::Sqrt(1+theta*theta+phi*phi));
3024   Float_t chargematch = normq/expQ;
3025   Float_t factorz=1;
3026   Int_t   cnz = cl->GetNz()%10;
3027   //charge match
3028   if (cl->GetType()==1){
3029     if (chargematch<1.25){
3030       erry =  0.0028*(1.+6./cl->GetQ());  // gold clusters
3031     }
3032     else{
3033       erry = 0.003*chargematch;
3034       if (cl->GetNz()==3) erry*=1.5;
3035     }
3036     if (chargematch<1.0){
3037       errz =  0.0011*(1.+6./cl->GetQ());
3038     }
3039     else{
3040       errz = 0.002*(1+2*(chargematch-1.));
3041     }
3042     if (cnz>nz+0.6) {
3043       erry*=(cnz-nz+0.5);
3044       errz*=1.4*(cnz-nz+0.5);
3045     }
3046   }
3047   if (cl->GetType()>1){
3048     if (chargematch<1){
3049       erry =  0.00385*(1.+6./cl->GetQ());  // gold clusters
3050       errz =  0.0016*(1.+6./cl->GetQ());
3051     }
3052     else{
3053       errz = 0.0014*(1+3*(chargematch-1.));
3054       erry = 0.003*(1+3*(chargematch-1.));
3055     } 
3056     if (cnz>nz+0.6) {
3057       erry*=(cnz-nz+0.5);
3058       errz*=1.4*(cnz-nz+0.5);
3059     }
3060   }
3061
3062   if (TMath::Abs(cl->GetY())>2.5){
3063     factorz*=1+2*(TMath::Abs(cl->GetY())-2.5);
3064   }
3065   if (TMath::Abs(cl->GetY())<1){
3066     factorz*=1.+0.5*TMath::Abs(TMath::Abs(cl->GetY())-1.);
3067   }
3068   factorz= TMath::Min(factorz,float(4.));  
3069   errz*=factorz;
3070
3071   erry= TMath::Min(erry,float(0.05));
3072   errz= TMath::Min(errz,float(0.05));  
3073   return 200;
3074 }
3075
3076
3077
3078 void   AliITStrackerMI::GetDCASigma(AliITStrackMI* track, Float_t & sigmarfi, Float_t &sigmaz)
3079 {
3080   //
3081   //DCA sigmas parameterization
3082   //to be paramterized using external parameters in future 
3083   //
3084   // 
3085   sigmarfi = 0.004+1.4 *TMath::Abs(track->fP4)+332.*track->fP4*track->fP4;
3086   sigmaz   = 0.011+4.37*TMath::Abs(track->fP4);
3087 }
3088
3089
3090 void AliITStrackerMI::SignDeltas( TObjArray *ClusterArray, Float_t vz)
3091 {
3092   //
3093   //  
3094   Int_t entries = ClusterArray->GetEntriesFast();
3095   if (entries<4) return;
3096   AliITSclusterV2* cluster = (AliITSclusterV2*)ClusterArray->At(0);
3097   Int_t layer = cluster->GetLayer();
3098   if (layer>1) return;
3099   Int_t index[10000];
3100   Int_t ncandidates=0;
3101   Float_t r = (layer>0)? 7:4;
3102   // 
3103   for (Int_t i=0;i<entries;i++){
3104     AliITSclusterV2* cl0 = (AliITSclusterV2*)ClusterArray->At(i);
3105     Float_t nz = 1+TMath::Abs((cl0->GetZ()-vz)/r);
3106     if (cl0->GetNy()+cl0->GetNz()<=5+2*layer+nz) continue;
3107     index[ncandidates] = i;  //candidate to belong to delta electron track
3108     ncandidates++;
3109     if (cl0->GetNy()+cl0->GetNz()>9+2*layer+nz) {
3110       cl0->SetDeltaProbability(1);
3111     }
3112   }
3113   //
3114   //  
3115   //
3116   for (Int_t i=0;i<ncandidates;i++){
3117     AliITSclusterV2* cl0 = (AliITSclusterV2*)ClusterArray->At(index[i]);
3118     if (cl0->GetDeltaProbability()>0.8) continue;
3119     // 
3120     Int_t ncl = 0;
3121     Float_t y[100],z[100],sumy,sumz,sumy2, sumyz, sumw;
3122     sumy=sumz=sumy2=sumyz=sumw=0.0;
3123     for (Int_t j=0;j<ncandidates;j++){
3124       if (i==j) continue;
3125       AliITSclusterV2* cl1 = (AliITSclusterV2*)ClusterArray->At(index[j]);
3126       //
3127       Float_t dz = cl0->GetZ()-cl1->GetZ();
3128       Float_t dy = cl0->GetY()-cl1->GetY();
3129       if (TMath::Sqrt(dz*dz+dy*dy)<0.2){
3130         Float_t weight = cl1->GetNy()+cl1->GetNz()-2;
3131         y[ncl] = cl1->GetY();
3132         z[ncl] = cl1->GetZ();
3133         sumy+= y[ncl]*weight;
3134         sumz+= z[ncl]*weight;
3135         sumy2+=y[ncl]*y[ncl]*weight;
3136         sumyz+=y[ncl]*z[ncl]*weight;
3137         sumw+=weight;
3138         ncl++;
3139       }
3140     }
3141     if (ncl<4) continue;
3142     Float_t det = sumw*sumy2  - sumy*sumy;
3143     Float_t delta=1000;
3144     if (TMath::Abs(det)>0.01){
3145       Float_t z0  = (sumy2*sumz - sumy*sumyz)/det;
3146       Float_t k   = (sumyz*sumw - sumy*sumz)/det;
3147       delta = TMath::Abs(cl0->GetZ()-(z0+k*cl0->GetY()));
3148     }
3149     else{
3150       Float_t z0  = sumyz/sumy;
3151       delta = TMath::Abs(cl0->GetZ()-z0);
3152     }
3153     if ( delta<0.05) {
3154       cl0->SetDeltaProbability(1-20.*delta);
3155     }   
3156   }
3157 }
3158
3159
3160 void AliITStrackerMI::UpdateESDtrack(AliITStrackMI* track, ULong_t flags) const
3161 {
3162   //
3163   //
3164   track->UpdateESDtrack(flags);
3165   AliITStrackMI * oldtrack = (AliITStrackMI*)(track->fESDtrack->GetITStrack());
3166   if (oldtrack) delete oldtrack; 
3167   track->fESDtrack->SetITStrack(new AliITStrackMI(*track));
3168   if (TMath::Abs(track->fDnorm[1])<0.000000001){
3169     printf("Problem\n");
3170   }
3171 }
3172
3173
3174
3175 Int_t AliITStrackerMI::GetNearestLayer(const Double_t *xr) const{
3176   //
3177   //Get nearest upper layer close to the point xr.
3178   // rough approximation 
3179   //
3180   const Float_t radiuses[6]={4,6.5,15.03,24.,38.5,43.7};
3181   Float_t radius = TMath::Sqrt(xr[0]*xr[0]+xr[1]*xr[1]);
3182   Int_t res =6;
3183   for (Int_t i=0;i<6;i++){
3184     if (radius<radiuses[i]){
3185       res =i;
3186       break;
3187     }
3188   }
3189   return res;
3190 }
3191
3192
3193 void AliITStrackerMI::UpdateTPCV0(AliESD *event){
3194   //
3195   //try to update, or reject TPC  V0s
3196   //
3197   Int_t nv0s = event->GetNumberOfV0MIs();
3198   Int_t nitstracks = fTrackHypothesys.GetEntriesFast();
3199
3200   for (Int_t i=0;i<nv0s;i++){
3201     AliESDV0MI * vertex = event->GetV0MI(i);
3202     Int_t ip = vertex->GetIndex(0);
3203     Int_t im = vertex->GetIndex(1);
3204     //
3205     TObjArray * arrayp = (ip<nitstracks) ? (TObjArray*)fTrackHypothesys.At(ip):0;
3206     TObjArray * arraym = (im<nitstracks) ? (TObjArray*)fTrackHypothesys.At(im):0;
3207     AliITStrackMI * trackp = (arrayp!=0) ? (AliITStrackMI*)arrayp->At(0):0;
3208     AliITStrackMI * trackm = (arraym!=0) ? (AliITStrackMI*)arraym->At(0):0;
3209     //
3210     //
3211     if (trackp){
3212       if (trackp->fN+trackp->fNDeadZone>5.5){
3213         if (trackp->fConstrain&&trackp->fChi2MIP[0]<3) vertex->SetStatus(-100);
3214         if (!trackp->fConstrain&&trackp->fChi2MIP[0]<2) vertex->SetStatus(-100); 
3215       }
3216     }
3217
3218     if (trackm){
3219       if (trackm->fN+trackm->fNDeadZone>5.5){
3220         if (trackm->fConstrain&&trackm->fChi2MIP[0]<3) vertex->SetStatus(-100);
3221         if (!trackm->fConstrain&&trackm->fChi2MIP[0]<2) vertex->SetStatus(-100); 
3222       }
3223     }
3224     if (vertex->GetStatus()==-100) continue;
3225     //
3226     Int_t clayer = GetNearestLayer(vertex->GetXrp());
3227     vertex->SetNBefore(clayer);        //
3228     vertex->SetChi2Before(9*clayer);   //
3229     vertex->SetNAfter(6-clayer);       //
3230     vertex->SetChi2After(0);           //
3231     //
3232     if (clayer >1 ){ // calculate chi2 before vertex
3233       Float_t chi2p = 0, chi2m=0;  
3234       //
3235       if (trackp){
3236         for (Int_t ilayer=0;ilayer<clayer;ilayer++){
3237           if (trackp->fClIndex[ilayer]>0){
3238             chi2p+=trackp->fDy[ilayer]*trackp->fDy[ilayer]/(trackp->fSigmaY[ilayer]*trackp->fSigmaY[ilayer])+
3239               trackp->fDz[ilayer]*trackp->fDz[ilayer]/(trackp->fSigmaZ[ilayer]*trackp->fSigmaZ[ilayer]);
3240           }
3241           else{
3242             chi2p+=9;
3243           }
3244         }
3245       }else{
3246         chi2p = 9*clayer;
3247       }
3248       //
3249       if (trackm){
3250         for (Int_t ilayer=0;ilayer<clayer;ilayer++){
3251           if (trackm->fClIndex[ilayer]>0){
3252             chi2m+=trackm->fDy[ilayer]*trackm->fDy[ilayer]/(trackm->fSigmaY[ilayer]*trackm->fSigmaY[ilayer])+
3253               trackm->fDz[ilayer]*trackm->fDz[ilayer]/(trackm->fSigmaZ[ilayer]*trackm->fSigmaZ[ilayer]);
3254           }
3255           else{
3256             chi2m+=9;
3257           }
3258         }
3259       }else{
3260         chi2m = 9*clayer;
3261       }
3262       vertex->SetChi2Before(TMath::Min(chi2p,chi2m));
3263       if (TMath::Min(chi2p,chi2m)/Float_t(clayer)<4) vertex->SetStatus(-10);  // track exist before vertex
3264     }
3265     
3266     if (clayer < 5 ){ // calculate chi2 after vertex
3267       Float_t chi2p = 0, chi2m=0;  
3268       //
3269       if (trackp&&TMath::Abs(trackp->fP3)<1.){
3270         for (Int_t ilayer=clayer;ilayer<6;ilayer++){
3271           if (trackp->fClIndex[ilayer]>0){
3272             chi2p+=trackp->fDy[ilayer]*trackp->fDy[ilayer]/(trackp->fSigmaY[ilayer]*trackp->fSigmaY[ilayer])+
3273               trackp->fDz[ilayer]*trackp->fDz[ilayer]/(trackp->fSigmaZ[ilayer]*trackp->fSigmaZ[ilayer]);
3274           }
3275           else{
3276             chi2p+=9;
3277           }
3278         }
3279       }else{
3280         chi2p = 0;
3281       }
3282       //
3283       if (trackm&&TMath::Abs(trackm->fP3)<1.){
3284         for (Int_t ilayer=clayer;ilayer<6;ilayer++){
3285           if (trackm->fClIndex[ilayer]>0){
3286             chi2m+=trackm->fDy[ilayer]*trackm->fDy[ilayer]/(trackm->fSigmaY[ilayer]*trackm->fSigmaY[ilayer])+
3287               trackm->fDz[ilayer]*trackm->fDz[ilayer]/(trackm->fSigmaZ[ilayer]*trackm->fSigmaZ[ilayer]);
3288           }
3289           else{
3290             chi2m+=9;
3291           }
3292         }
3293       }else{
3294         chi2m = 0;
3295       }
3296       vertex->SetChi2After(TMath::Max(chi2p,chi2m));
3297       if (TMath::Max(chi2m,chi2p)/Float_t(6-clayer)>9) vertex->SetStatus(-20);  // track not found in ITS
3298     }
3299   }
3300   //
3301 }
3302
3303 void  AliITStrackerMI::FindV02(AliESD *event)
3304 {
3305   //
3306   // V0 finder
3307   //
3308   //  Cuts on DCA -  R dependent
3309   //          max distance DCA between 2 tracks cut 
3310   //          maxDist = TMath::Min(kMaxDist,kMaxDist0+pvertex->GetRr()*kMaxDist);
3311   //
3312   const Float_t kMaxDist0      = 0.1;    
3313   const Float_t kMaxDist1      = 0.1;     
3314   const Float_t kMaxDist       = 1;
3315   const Float_t kMinPointAngle  = 0.85;
3316   const Float_t kMinPointAngle2 = 0.99;
3317   const Float_t kMinR           = 0.5;
3318   const Float_t kMaxR           = 220;
3319   //const Float_t kCausality0Cut   = 0.19;
3320   //const Float_t kLikelihood01Cut = 0.25;
3321   //const Float_t kPointAngleCut   = 0.9996;
3322   const Float_t kCausality0Cut   = 0.19;
3323   const Float_t kLikelihood01Cut = 0.45;
3324   const Float_t kLikelihood1Cut  = 0.5;
3325   const Float_t kCombinedCut     = 0.55;
3326
3327   //
3328   //
3329   TTreeSRedirector &cstream = *fDebugStreamer;
3330   Int_t ntracks    = event->GetNumberOfTracks(); 
3331   Int_t nitstracks = fTrackHypothesys.GetEntriesFast();
3332   fOriginal.Expand(ntracks);
3333   fTrackHypothesys.Expand(ntracks);
3334   fBestHypothesys.Expand(ntracks);
3335   //
3336   AliHelix * helixes   = new AliHelix[ntracks+2];
3337   TObjArray trackarray(ntracks+2);     //array with tracks - with vertex constrain
3338   TObjArray trackarrayc(ntracks+2);    //array of "best    tracks" - without vertex constrain
3339   TObjArray trackarrayl(ntracks+2);    //array of "longest tracks" - without vertex constrain
3340   Bool_t * forbidden   = new Bool_t [ntracks+2];
3341   Int_t   *itsmap      = new Int_t  [ntracks+2];
3342   Float_t *dist        = new Float_t[ntracks+2];
3343   Float_t *normdist0   = new Float_t[ntracks+2];
3344   Float_t *normdist1   = new Float_t[ntracks+2];
3345   Float_t *normdist    = new Float_t[ntracks+2];
3346   Float_t *norm        = new Float_t[ntracks+2];
3347   Float_t *maxr        = new Float_t[ntracks+2];
3348   Float_t *minr        = new Float_t[ntracks+2];
3349   Float_t *minPointAngle= new Float_t[ntracks+2];
3350   //
3351   AliESDV0MI *pvertex      = new AliESDV0MI;
3352   AliITStrackMI * dummy= new AliITStrackMI;
3353   dummy->SetLabel(0);
3354   AliITStrackMI  trackat0;    //temporary track for DCA calculation
3355   //
3356   Float_t primvertex[3]={GetX(),GetY(),GetZ()};
3357   //
3358   // make its -  esd map
3359   //
3360   for (Int_t itrack=0;itrack<ntracks+2;itrack++) {
3361     itsmap[itrack]        = -1;
3362     forbidden[itrack]     = kFALSE;
3363     maxr[itrack]          = kMaxR;
3364     minr[itrack]          = kMinR;
3365     minPointAngle[itrack] = kMinPointAngle;
3366   }
3367   for (Int_t itrack=0;itrack<nitstracks;itrack++){
3368     AliITStrackMI * original =   (AliITStrackMI*)(fOriginal.At(itrack));
3369     Int_t           esdindex =   original->fESDtrack->GetID();
3370     itsmap[esdindex]         =   itrack;
3371   }
3372   //
3373   // create its tracks from esd tracks if not done before
3374   //
3375   for (Int_t itrack=0;itrack<ntracks;itrack++){
3376     if (itsmap[itrack]>=0) continue;
3377     AliITStrackMI * tpctrack = new AliITStrackMI(*(event->GetTrack(itrack)));
3378     tpctrack->fD[0] = tpctrack->GetD(GetX(),GetY());
3379     tpctrack->fD[1] = tpctrack->GetZat(GetX())-GetZ(); 
3380     if (tpctrack->fD[0]<20 && tpctrack->fD[1]<20){
3381       // tracks which can reach inner part of ITS
3382       // propagate track to outer its volume - with correction for material
3383       CorrectForDeadZoneMaterial(tpctrack);  
3384     }
3385     itsmap[itrack] = nitstracks;
3386     fOriginal.AddAt(tpctrack,nitstracks);
3387     nitstracks++;
3388   }
3389   //
3390   // fill temporary arrays
3391   //
3392   for (Int_t itrack=0;itrack<ntracks;itrack++){
3393     AliESDtrack *  esdtrack = event->GetTrack(itrack);
3394     Int_t          itsindex = itsmap[itrack];
3395     AliITStrackMI *original = (AliITStrackMI*)fOriginal.At(itsmap[itrack]);
3396     if (!original) continue;
3397     AliITStrackMI *bestConst  = 0;
3398     AliITStrackMI *bestLong   = 0;
3399     AliITStrackMI *best       = 0;    
3400     //
3401     //
3402     TObjArray * array    = (TObjArray*)  fTrackHypothesys.At(itsindex);
3403     Int_t       hentries = (array==0) ?  0 : array->GetEntriesFast();
3404     // Get best track with vertex constrain
3405     for (Int_t ih=0;ih<hentries;ih++){
3406       AliITStrackMI * trackh = (AliITStrackMI*)array->At(ih);
3407       if (!trackh->fConstrain) continue;
3408       if (!bestConst) bestConst = trackh;
3409       if (trackh->fN>5.0){
3410         bestConst  = trackh;                         // full track -  with minimal chi2
3411         break;
3412       }
3413       if (trackh->fN+trackh->fNDeadZone<=bestConst->fN+bestConst->fNDeadZone)  continue;      
3414       bestConst = trackh;
3415       break;
3416     }
3417     // Get best long track without vertex constrain and best track without vertex constrain
3418     for (Int_t ih=0;ih<hentries;ih++){
3419       AliITStrackMI * trackh = (AliITStrackMI*)array->At(ih);
3420       if (trackh->fConstrain) continue;
3421       if (!best)     best     = trackh;
3422       if (!bestLong) bestLong = trackh;
3423       if (trackh->fN>5.0){
3424         bestLong  = trackh;                         // full track -  with minimal chi2
3425         break;
3426       }
3427       if (trackh->fN+trackh->fNDeadZone<=bestLong->fN+bestLong->fNDeadZone)  continue;      
3428       bestLong = trackh;        
3429     }
3430     if (!best) {
3431       best     = original;
3432       bestLong = original;
3433     }
3434     trackat0 = *bestLong;
3435     Double_t xx,yy,zz,alpha; 
3436     bestLong->GetGlobalXYZat(bestLong->GetX(),xx,yy,zz);
3437     alpha = TMath::ATan2(yy,xx);    
3438     trackat0.Propagate(alpha,0);      
3439     // calculate normalized distances to the vertex 
3440     //
3441     if ( bestLong->fN>3 ){
3442       dist[itsindex]      = trackat0.fP0;
3443       norm[itsindex]      = TMath::Sqrt(trackat0.fC00);
3444       normdist0[itsindex] = TMath::Abs(trackat0.fP0/norm[itsindex]);
3445       normdist1[itsindex] = TMath::Abs((trackat0.fP1-primvertex[2])/TMath::Sqrt(trackat0.fC11));
3446       normdist[itsindex]  = TMath::Sqrt(normdist0[itsindex]*normdist0[itsindex]+normdist1[itsindex]*normdist1[itsindex]);
3447     }
3448     else{      
3449       if (bestConst&&bestConst->fN+bestConst->fNDeadZone>4.5){
3450         dist[itsindex] = bestConst->fD[0];
3451         norm[itsindex] = bestConst->fDnorm[0];
3452         normdist0[itsindex] = TMath::Abs(bestConst->fD[0]/norm[itsindex]);
3453         normdist1[itsindex] = TMath::Abs(bestConst->fD[0]/norm[itsindex]);
3454         normdist[itsindex]  = TMath::Sqrt(normdist0[itsindex]*normdist0[itsindex]+normdist1[itsindex]*normdist1[itsindex]);
3455       }else{
3456         dist[itsindex]      = trackat0.fP0;
3457         norm[itsindex]      = TMath::Sqrt(trackat0.fC00);
3458         normdist0[itsindex] = TMath::Abs(trackat0.fP0/norm[itsindex]);
3459         normdist1[itsindex] = TMath::Abs((trackat0.fP1-primvertex[2])/TMath::Sqrt(trackat0.fC11));
3460         normdist[itsindex]  = TMath::Sqrt(normdist0[itsindex]*normdist0[itsindex]+normdist1[itsindex]*normdist1[itsindex]);
3461         if (TMath::Abs(trackat0.fP3)>1.1){
3462           if (normdist[itsindex]<10) forbidden[itsindex]=kTRUE;
3463         }
3464       }
3465     }
3466     //
3467     //-----------------------------------------------------------
3468     //Forbid primary track candidates - 
3469     //
3470     //treetr->SetAlias("forbidden0","Tr0.fN<4&&Tr1.fN+Tr1.fNDeadZone>4.5");
3471     //treetr->SetAlias("forbidden1","ND<3&&Tr1.fN+Tr1.fNDeadZone>5.5");
3472     //treetr->SetAlias("forbidden2","ND<2&&Tr1.fClIndex[0]>0&&Tr1.fClIndex[0]>0");
3473     //treetr->SetAlias("forbidden3","ND<1&&Tr1.fClIndex[0]>0");
3474     //treetr->SetAlias("forbidden4","ND<4&&Tr1.fNormChi2[0]<2");
3475     //treetr->SetAlias("forbidden5","ND<5&&Tr1.fNormChi2[0]<1");
3476     //-----------------------------------------------------------
3477     if (bestConst){
3478       if (bestLong->fN<4       && bestConst->fN+bestConst->fNDeadZone>4.5)               forbidden[itsindex]=kTRUE;
3479       if (normdist[itsindex]<3 && bestConst->fN+bestConst->fNDeadZone>5.5)               forbidden[itsindex]=kTRUE;
3480       if (normdist[itsindex]<2 && bestConst->fClIndex[0]>0 && bestConst->fClIndex[1]>0 ) forbidden[itsindex]=kTRUE;
3481       if (normdist[itsindex]<1 && bestConst->fClIndex[0]>0)                              forbidden[itsindex]=kTRUE;
3482       if (normdist[itsindex]<4 && bestConst->fNormChi2[0]<2)                             forbidden[itsindex]=kTRUE;
3483       if (normdist[itsindex]<5 && bestConst->fNormChi2[0]<1)                             forbidden[itsindex]=kTRUE;      
3484       if (bestConst->fNormChi2[0]<2.5) {
3485         minPointAngle[itsindex]= 0.9999;
3486         maxr[itsindex]         = 10;
3487       }
3488     }
3489     //
3490     //forbid daughter kink candidates
3491     //
3492     if (esdtrack->GetKinkIndex(0)>0) forbidden[itsindex] = kTRUE;
3493     Bool_t isElectron = kTRUE;
3494     Double_t pid[5];
3495     esdtrack->GetESDpid(pid);
3496     for (Int_t i=1;i<5;i++){
3497       if (pid[0]<pid[i]) isElectron= kFALSE;
3498     }
3499     if (isElectron){
3500       forbidden[itsindex]=kFALSE;       
3501       normdist[itsindex]+=4;
3502     }
3503     //
3504     // Causality cuts in TPC volume
3505     //
3506     if (esdtrack->GetTPCdensity(0,10) >0.6)  maxr[itsindex] = TMath::Min(Float_t(110),maxr[itsindex]);
3507     if (esdtrack->GetTPCdensity(10,30)>0.6)  maxr[itsindex] = TMath::Min(Float_t(120),maxr[itsindex]);
3508     if (esdtrack->GetTPCdensity(20,40)>0.6)  maxr[itsindex] = TMath::Min(Float_t(130),maxr[itsindex]);
3509     if (esdtrack->GetTPCdensity(30,50)>0.6)  maxr[itsindex] = TMath::Min(Float_t(140),maxr[itsindex]);
3510     //
3511     if (esdtrack->GetTPCdensity(0,60)<0.4&&bestLong->fN<3) minr[itsindex]=100;    
3512     //
3513     //
3514     if (0){
3515       cstream<<"Track"<<
3516         "Tr0.="<<best<<
3517         "Tr1.="<<((bestConst)? bestConst:dummy)<<
3518         "Tr2.="<<bestLong<<
3519         "Tr3.="<<&trackat0<<
3520         "Esd.="<<esdtrack<<
3521         "Dist="<<dist[itsindex]<<
3522         "ND0="<<normdist0[itsindex]<<
3523         "ND1="<<normdist1[itsindex]<<
3524         "ND="<<normdist[itsindex]<<
3525         "Pz="<<primvertex[2]<<
3526         "Forbid="<<forbidden[itsindex]<<
3527         "\n";
3528       //
3529     }
3530     trackarray.AddAt(best,itsindex);
3531     trackarrayc.AddAt(bestConst,itsindex);
3532     trackarrayl.AddAt(bestLong,itsindex);
3533     new (&helixes[itsindex]) AliHelix(*best);
3534   }
3535   //
3536   //
3537   //
3538   // first iterration of V0 finder
3539   //
3540   for (Int_t iesd0=0;iesd0<ntracks;iesd0++){
3541     Int_t itrack0 = itsmap[iesd0];
3542     if (forbidden[itrack0]) continue;
3543     AliITStrackMI * btrack0 = (AliITStrackMI*)trackarray.At(itrack0);
3544     if (!btrack0) continue;    
3545     if (btrack0->fP4>0) continue;
3546     AliITStrackMI *trackc0 = (AliITStrackMI*)trackarrayc.At(itrack0);
3547     //
3548     for (Int_t iesd1=0;iesd1<ntracks;iesd1++){
3549       Int_t itrack1 = itsmap[iesd1];
3550       if (forbidden[itrack1]) continue;
3551
3552       AliITStrackMI * btrack1 = (AliITStrackMI*)trackarray.At(itrack1); 
3553       if (!btrack1) continue;
3554       if (btrack1->fP4<0) continue;
3555       Bool_t isGold = kFALSE;
3556       if (TMath::Abs(TMath::Abs(btrack0->GetLabel())-TMath::Abs(btrack1->GetLabel()))==1){
3557         isGold = kTRUE;
3558       }
3559       AliITStrackMI *trackc1 = (AliITStrackMI*)trackarrayc.At(itrack1);
3560       AliHelix &h1 = helixes[itrack0];
3561       AliHelix &h2 = helixes[itrack1];
3562       //
3563       // find linear distance
3564       Double_t rmin =0;
3565       //
3566       //
3567       //
3568       Double_t phase[2][2],radius[2];
3569       Int_t  points = h1.GetRPHIintersections(h2, phase, radius);
3570       if    (points==0)  continue;
3571       Double_t delta[2]={1000,1000};        
3572       rmin = radius[0];
3573       h1.ParabolicDCA(h2,phase[0][0],phase[0][1],radius[0],delta[0]);
3574       if (points==2){    
3575         if (radius[1]<rmin) rmin = radius[1];
3576         h1.ParabolicDCA(h2,phase[1][0],phase[1][1],radius[1],delta[1]);
3577       }
3578       rmin = TMath::Sqrt(rmin);
3579       Double_t distance = 0;
3580       Double_t radiusC  = 0;
3581       Int_t    iphase   = 0;
3582       if (delta[0]<delta[1]){
3583         distance = TMath::Sqrt(delta[0]);
3584         radiusC  = TMath::Sqrt(radius[0]);
3585       }else{
3586         distance = TMath::Sqrt(delta[1]);
3587         radiusC  = TMath::Sqrt(radius[1]);
3588         iphase=1;
3589       }
3590       if (radiusC<TMath::Max(minr[itrack0],minr[itrack1]))    continue;
3591       if (radiusC>TMath::Min(maxr[itrack0],maxr[itrack1]))     continue; 
3592       Float_t maxDist  = TMath::Min(kMaxDist,Float_t(kMaxDist0+radiusC*kMaxDist1));      
3593       if (distance>maxDist) continue;
3594       Float_t pointAngle = h1.GetPointAngle(h2,phase[iphase],primvertex);
3595       if (pointAngle<TMath::Max(minPointAngle[itrack0],minPointAngle[itrack1])) continue;
3596       //
3597       //
3598       //      Double_t distance = TestV0(h1,h2,pvertex,rmin);
3599       //
3600       //       if (distance>maxDist)           continue;
3601       //       if (pvertex->GetRr()<kMinR)     continue;
3602       //       if (pvertex->GetRr()>kMaxR)     continue;
3603       AliITStrackMI * track0=btrack0;
3604       AliITStrackMI * track1=btrack1;
3605       //      if (pvertex->GetRr()<3.5){  
3606       if (radiusC<3.5){  
3607         //use longest tracks inside the pipe
3608         track0 = (AliITStrackMI*)trackarrayl.At(itrack0);
3609         track1 = (AliITStrackMI*)trackarrayl.At(itrack1);
3610       }      
3611       //
3612       //
3613       pvertex->SetM(*track0);
3614       pvertex->SetP(*track1);
3615       pvertex->Update(primvertex);
3616       if (pvertex->GetRr()<kMinR) continue;
3617       if (pvertex->GetRr()>kMaxR) continue;
3618       if (pvertex->GetPointAngle()<kMinPointAngle) continue;
3619       if (pvertex->GetDist2()>maxDist) continue;
3620       pvertex->SetLab(0,track0->GetLabel());
3621       pvertex->SetLab(1,track1->GetLabel());
3622       
3623       //      
3624       AliITStrackMI * htrackc0 = trackc0 ? trackc0:dummy;      
3625       AliITStrackMI * htrackc1 = trackc1 ? trackc1:dummy;
3626
3627       //
3628       //
3629       TObjArray * array0b     = (TObjArray*)fBestHypothesys.At(itrack0);
3630       if (!array0b&&pvertex->GetRr()<40 && TMath::Abs(track0->fP3)<1.1) 
3631         FollowProlongationTree((AliITStrackMI*)fOriginal.At(itrack0),itrack0, kFALSE);
3632       TObjArray * array1b    = (TObjArray*)fBestHypothesys.At(itrack1);
3633       if (!array1b&&pvertex->GetRr()<40 && TMath::Abs(track1->fP3)<1.1) 
3634         FollowProlongationTree((AliITStrackMI*)fOriginal.At(itrack1),itrack1, kFALSE);
3635       //
3636       AliITStrackMI * track0b = (AliITStrackMI*)fOriginal.At(itrack0);       
3637       AliITStrackMI * track1b = (AliITStrackMI*)fOriginal.At(itrack1);
3638       AliITStrackMI * track0l = (AliITStrackMI*)fOriginal.At(itrack0);       
3639       AliITStrackMI * track1l = (AliITStrackMI*)fOriginal.At(itrack1);
3640       
3641       Float_t minchi2before0=16;
3642       Float_t minchi2before1=16;
3643       Float_t minchi2after0 =16;
3644       Float_t minchi2after1 =16;
3645       Int_t maxLayer = GetNearestLayer(pvertex->GetXrp());
3646       
3647       if (array0b) for (Int_t i=0;i<5;i++){
3648         // best track after vertex
3649         AliITStrackMI * btrack = (AliITStrackMI*)array0b->At(i);
3650         if (!btrack) continue;
3651         if (btrack->fN>track0l->fN) track0l = btrack;     
3652         if (btrack->fX<pvertex->GetRr()-2) {
3653           if (maxLayer>i+2 && btrack->fN==(6-i)&&i<2){
3654             Float_t sumchi2= 0;
3655             Float_t sumn   = 0;
3656             for (Int_t ilayer=i;ilayer<maxLayer;ilayer++){
3657               sumn+=1.;
3658               if (!btrack->fClIndex[ilayer]){
3659                 sumchi2+=25;
3660                 continue;
3661               }else{
3662                 sumchi2+=btrack->fDy[ilayer]*btrack->fDy[ilayer]/(btrack->fSigmaY[ilayer]*btrack->fSigmaY[ilayer]);
3663                 sumchi2+=btrack->fDz[ilayer]*btrack->fDz[ilayer]/(btrack->fSigmaZ[ilayer]*btrack->fSigmaZ[ilayer]);            
3664               }
3665             }
3666             sumchi2/=sumn;
3667             if (sumchi2<minchi2before0) minchi2before0=sumchi2; 
3668           }
3669           continue;   //safety space - Geo manager will give exact layer
3670         }
3671         track0b       = btrack;
3672         minchi2after0 = btrack->fNormChi2[i];
3673         break;
3674       }
3675       if (array1b) for (Int_t i=0;i<5;i++){
3676         // best track after vertex
3677         AliITStrackMI * btrack = (AliITStrackMI*)array1b->At(i);
3678         if (!btrack) continue;
3679         if (btrack->fN>track1l->fN) track1l = btrack;     
3680         if (btrack->fX<pvertex->GetRr()-2){
3681           if (maxLayer>i+2&&btrack->fN==(6-i)&&(i<2)){
3682             Float_t sumchi2= 0;
3683             Float_t sumn   = 0;
3684             for (Int_t ilayer=i;ilayer<maxLayer;ilayer++){
3685               sumn+=1.;
3686               if (!btrack->fClIndex[ilayer]){
3687                 sumchi2+=30;
3688                 continue;
3689               }else{
3690                 sumchi2+=btrack->fDy[ilayer]*btrack->fDy[ilayer]/(btrack->fSigmaY[ilayer]*btrack->fSigmaY[ilayer]);
3691                 sumchi2+=btrack->fDz[ilayer]*btrack->fDz[ilayer]/(btrack->fSigmaZ[ilayer]*btrack->fSigmaZ[ilayer]);            
3692               }
3693             }
3694             sumchi2/=sumn;
3695             if (sumchi2<minchi2before1) minchi2before1=sumchi2; 
3696           }
3697           continue;   //safety space - Geo manager will give exact layer           
3698         }
3699         track1b = btrack;
3700         minchi2after1 = btrack->fNormChi2[i];
3701         break;
3702       }
3703       //
3704       // position resolution - used for DCA cut
3705       Float_t sigmad = track0b->fC00+track0b->fC11+track1b->fC00+track1b->fC11+
3706         (track0b->fX-pvertex->GetRr())*(track0b->fX-pvertex->GetRr())*(track0b->fC22+track0b->fC33)+
3707         (track1b->fX-pvertex->GetRr())*(track1b->fX-pvertex->GetRr())*(track1b->fC22+track1b->fC33);
3708       sigmad =TMath::Sqrt(sigmad)+0.04;
3709       if (pvertex->GetRr()>50){
3710         Double_t cov0[15],cov1[15];
3711         track0b->fESDtrack->GetInnerExternalCovariance(cov0);
3712         track1b->fESDtrack->GetInnerExternalCovariance(cov1);
3713         sigmad = cov0[0]+cov0[2]+cov1[0]+cov1[2]+
3714           (80.-pvertex->GetRr())*(80.-pvertex->GetRr())*(cov0[5]+cov0[9])+
3715           (80.-pvertex->GetRr())*(80.-pvertex->GetRr())*(cov1[5]+cov1[9]);
3716         sigmad =TMath::Sqrt(sigmad)+0.05;
3717       }
3718       //       
3719       AliESDV0MI vertex2;
3720       vertex2.SetM(*track0b);
3721       vertex2.SetP(*track1b);
3722       vertex2.Update(primvertex);
3723       if (vertex2.GetDist2()<=pvertex->GetDist2()&&(vertex2.GetPointAngle()>=pvertex->GetPointAngle())){
3724         pvertex->SetM(*track0b);
3725         pvertex->SetP(*track1b);
3726         pvertex->Update(primvertex);
3727       }
3728       pvertex->SetDistSigma(sigmad);
3729       pvertex->SetDistNorm(pvertex->GetDist2()/sigmad);       
3730       //
3731       // define likelihhod and causalities
3732       //
3733       Float_t pa0=1, pa1=1, pb0=0.26, pb1=0.26;      
3734       if (maxLayer<2){
3735         if (pvertex->GetAnglep()[2]>0.2){
3736           pb0    =  TMath::Exp(-TMath::Min(normdist[itrack0],Float_t(16.))/12.);
3737           pb1    =  TMath::Exp(-TMath::Min(normdist[itrack1],Float_t(16.))/12.);
3738         }
3739         pvertex->SetChi2Before(normdist[itrack0]);
3740         pvertex->SetChi2After(normdist[itrack1]);       
3741         pvertex->SetNAfter(0);
3742         pvertex->SetNBefore(0);
3743       }else{
3744         pvertex->SetChi2Before(minchi2before0);
3745         pvertex->SetChi2After(minchi2before1);
3746         if (pvertex->GetAnglep()[2]>0.2){
3747           pb0    =  TMath::Exp(-TMath::Min(minchi2before0,Float_t(16))/12.);
3748           pb1    =  TMath::Exp(-TMath::Min(minchi2before1,float_t(16))/12.);
3749         }
3750         pvertex->SetNAfter(maxLayer);
3751         pvertex->SetNBefore(maxLayer);
3752       }
3753       if (pvertex->GetRr()<90){
3754         pa0  *= TMath::Min(track0->fESDtrack->GetTPCdensity(0,60),Float_t(1.));
3755         pa1  *= TMath::Min(track1->fESDtrack->GetTPCdensity(0,60),Float_t(1.));
3756       }
3757       if (pvertex->GetRr()<20){
3758         pa0  *= (0.2+TMath::Exp(-TMath::Min(minchi2after0,Float_t(16))/8.))/1.2;
3759         pa1  *= (0.2+TMath::Exp(-TMath::Min(minchi2after1,Float_t(16))/8.))/1.2;
3760       }
3761       //
3762       pvertex->SetCausality(pb0,pb1,pa0,pa1);
3763       //
3764       //  Likelihood calculations  - apply cuts
3765       //         
3766       Bool_t v0OK = kTRUE;
3767       Float_t p12 = pvertex->GetParamP()->GetParameter()[4]*pvertex->GetParamP()->GetParameter()[4];
3768       p12        += pvertex->GetParamM()->GetParameter()[4]*pvertex->GetParamM()->GetParameter()[4];
3769       p12         = TMath::Sqrt(p12);                             // "mean" momenta
3770       Float_t    sigmap0   = 0.0001+0.001/(0.1+pvertex->GetRr()); 
3771       Float_t    sigmap    = 0.5*sigmap0*(0.6+0.4*p12);           // "resolution: of point angle - as a function of radius and momenta
3772
3773       Float_t CausalityA  = (1.0-pvertex->GetCausalityP()[0])*(1.0-pvertex->GetCausalityP()[1]);
3774       Float_t CausalityB  = TMath::Sqrt(TMath::Min(pvertex->GetCausalityP()[2],Float_t(0.7))*
3775                                         TMath::Min(pvertex->GetCausalityP()[3],Float_t(0.7)));
3776       //
3777       Float_t Likelihood0 = (TMath::Exp(-pvertex->GetDistNorm())+0.1) *(pvertex->GetDist2()<0.5)*(pvertex->GetDistNorm()<5);
3778
3779       Float_t Likelihood1 = TMath::Exp(-(1.0001-pvertex->GetPointAngle())/sigmap)+
3780         0.4*TMath::Exp(-(1.0001-pvertex->GetPointAngle())/(4.*sigmap))+
3781         0.4*TMath::Exp(-(1.0001-pvertex->GetPointAngle())/(8.*sigmap))+
3782         0.1*TMath::Exp(-(1.0001-pvertex->GetPointAngle())/0.01);
3783       //
3784       if (CausalityA<kCausality0Cut)                                          v0OK = kFALSE;
3785       if (TMath::Sqrt(Likelihood0*Likelihood1)<kLikelihood01Cut)              v0OK = kFALSE;
3786       if (Likelihood1<kLikelihood1Cut)                                        v0OK = kFALSE;
3787       if (TMath::Power(Likelihood0*Likelihood1*CausalityB,0.33)<kCombinedCut) v0OK = kFALSE;
3788       
3789       //
3790       //
3791       if (kTRUE){       
3792         Bool_t gold = TMath::Abs(TMath::Abs(track0->GetLabel())-TMath::Abs(track1->GetLabel()))==1;
3793         cstream<<"It0"<<
3794           "Tr0.="<<track0<<                       //best without constrain
3795           "Tr1.="<<track1<<                       //best without constrain  
3796           "Tr0B.="<<track0b<<                     //best without constrain  after vertex
3797           "Tr1B.="<<track1b<<                     //best without constrain  after vertex 
3798           "Tr0C.="<<htrackc0<<                    //best with constrain     if exist
3799           "Tr1C.="<<htrackc1<<                    //best with constrain     if exist
3800           "Tr0L.="<<track0l<<                     //longest best           
3801           "Tr1L.="<<track1l<<                     //longest best
3802           "Esd0.="<<track0->fESDtrack<<           // esd track0 params
3803           "Esd1.="<<track1->fESDtrack<<           // esd track1 params
3804           "V0.="<<pvertex<<                       //vertex properties
3805           "V0b.="<<&vertex2<<                       //vertex properties at "best" track
3806           "ND0="<<normdist[itrack0]<<             //normalize distance for track0
3807           "ND1="<<normdist[itrack1]<<             //normalize distance for track1
3808           "Gold="<<gold<<                         //
3809           //      "RejectBase="<<rejectBase<<             //rejection in First itteration
3810           "OK="<<v0OK<<
3811           "rmin="<<rmin<<
3812           "sigmad="<<sigmad<<
3813           "\n";
3814       }      
3815       //if (rejectBase) continue;
3816       //
3817       pvertex->SetStatus(0);
3818       //      if (rejectBase) {
3819       //        pvertex->SetStatus(-100);
3820       //}
3821       if (pvertex->GetPointAngle()>kMinPointAngle2) {
3822         if (v0OK){
3823           AliV0vertex vertexjuri(*track0,*track1);
3824           vertexjuri.SetESDindexes(track0->fESDtrack->GetID(),track1->fESDtrack->GetID());
3825           pvertex->SetESDindexes(track0->fESDtrack->GetID(),track1->fESDtrack->GetID());
3826           event->AddV0(&vertexjuri);
3827           pvertex->SetStatus(100);
3828         }
3829         event->AddV0MI(pvertex);
3830       }
3831     }
3832   }
3833   //
3834   //
3835   // delete temporary arrays
3836   //  
3837   delete[] minPointAngle;
3838   delete[] maxr;
3839   delete[] minr;
3840   delete[] norm;
3841   delete[] normdist;
3842   delete[] normdist1;
3843   delete[] normdist0;
3844   delete[] dist;
3845   delete[] itsmap;
3846   delete[] helixes;
3847   delete   pvertex;
3848 }
3849
3850
3851
3852
3853
3854
3855
3856
3857
3858
3859
3860