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