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