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