]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ITS/AliITSV0Finder.cxx
Changes related to the extraction of the V0 finder into a separate class (A. Dainese...
[u/mrichter/AliRoot.git] / ITS / AliITSV0Finder.cxx
1 /**************************************************************************\r
2  * Copyright(c) 2007-2009, ALICE Experiment at CERN, All rights reserved. *\r
3  *                                                                        *\r
4  * Author: The ALICE Off-line Project.                                    *\r
5  * Contributors are mentioned in the code where appropriate.              *\r
6  *                                                                        *\r
7  * Permission to use, copy, modify and distribute this software and its   *\r
8  * documentation strictly for non-commercial purposes is hereby granted   *\r
9  * without fee, provided that the above copyright notice appears in all   *\r
10  * copies and that both the copyright notice and this permission notice   *\r
11  * appear in the supporting documentation. The authors make no claims     *\r
12  * about the suitability of this software for any purpose. It is          *\r
13  * provided "as is" without express or implied warranty.                  *\r
14  **************************************************************************/\r
15 /* $Id$ */\r
16 \r
17 //-------------------------------------------------------------------------\r
18 //      Implementation of the on-the-fly v0 finder for ITS tracker MI\r
19 //          Origin: Marian Ivanov, CERN, Marian.Ivanov@cern.ch \r
20 //          Extraction from AliITStrackerMI: Andrea Dainese\r
21 //          Current support and development: \r
22 //-------------------------------------------------------------------------\r
23 \r
24 #include <TMatrixD.h>\r
25 #include <TTree.h>\r
26 #include <TString.h>\r
27 #include <TRandom.h>\r
28 #include <TTreeStream.h>\r
29 \r
30 \r
31 #include "AliLog.h"\r
32 #include "AliESDVertex.h"\r
33 #include "AliESDEvent.h"\r
34 #include "AliESDtrack.h"\r
35 #include "AliV0.h"\r
36 #include "AliHelix.h"\r
37 #include "AliITSRecPoint.h"\r
38 #include "AliITSReconstructor.h"\r
39 #include "AliITStrackerMI.h"\r
40 #include "AliITSV0Finder.h"\r
41 \r
42 ClassImp(AliITSV0Finder)\r
43 \r
44 AliITSV0Finder::AliITSV0Finder() {\r
45   //Default constructor\r
46 }\r
47 //------------------------------------------------------------------------\r
48 void AliITSV0Finder::UpdateTPCV0(const AliESDEvent *event,\r
49                                    AliITStrackerMI *tracker)\r
50 {\r
51   //\r
52   //try to update, or reject TPC  V0s\r
53   //\r
54   TObjArray *trackHypothesys = tracker->GetTrackHypothesys();\r
55 \r
56   Int_t nv0s = event->GetNumberOfV0s();\r
57   Int_t nitstracks = trackHypothesys->GetEntriesFast();\r
58 \r
59   for (Int_t i=0;i<nv0s;i++){\r
60     AliESDv0 * vertex = event->GetV0(i);\r
61     Int_t ip = vertex->GetIndex(0);\r
62     Int_t im = vertex->GetIndex(1);\r
63     //\r
64     TObjArray * arrayp = (ip<nitstracks) ? (TObjArray*)trackHypothesys->At(ip):0;\r
65     TObjArray * arraym = (im<nitstracks) ? (TObjArray*)trackHypothesys->At(im):0;\r
66     AliITStrackMI * trackp = (arrayp!=0) ? (AliITStrackMI*)arrayp->At(0):0;\r
67     AliITStrackMI * trackm = (arraym!=0) ? (AliITStrackMI*)arraym->At(0):0;\r
68     //\r
69     //\r
70     if (trackp){\r
71       if (trackp->GetNumberOfClusters()+trackp->GetNDeadZone()>5.5){\r
72         if (trackp->GetConstrain()&&trackp->GetChi2MIP(0)<3) vertex->SetStatus(-100);\r
73         if (!trackp->GetConstrain()&&trackp->GetChi2MIP(0)<2) vertex->SetStatus(-100); \r
74       }\r
75     }\r
76 \r
77     if (trackm){\r
78       if (trackm->GetNumberOfClusters()+trackm->GetNDeadZone()>5.5){\r
79         if (trackm->GetConstrain()&&trackm->GetChi2MIP(0)<3) vertex->SetStatus(-100);\r
80         if (!trackm->GetConstrain()&&trackm->GetChi2MIP(0)<2) vertex->SetStatus(-100); \r
81       }\r
82     }\r
83     if (vertex->GetStatus()==-100) continue;\r
84     //\r
85     Double_t xrp[3]; vertex->GetXYZ(xrp[0],xrp[1],xrp[2]);  //I.B.\r
86     Int_t clayer = tracker->GetNearestLayer(xrp);                    //I.B.\r
87     vertex->SetNBefore(clayer);        //\r
88     vertex->SetChi2Before(9*clayer);   //\r
89     vertex->SetNAfter(6-clayer);       //\r
90     vertex->SetChi2After(0);           //\r
91     //\r
92     if (clayer >1 ){ // calculate chi2 before vertex\r
93       Float_t chi2p = 0, chi2m=0;  \r
94       //\r
95       if (trackp){\r
96         for (Int_t ilayer=0;ilayer<clayer;ilayer++){\r
97           if (trackp->GetClIndex(ilayer)>=0){\r
98             chi2p+=trackp->GetDy(ilayer)*trackp->GetDy(ilayer)/(trackp->GetSigmaY(ilayer)*trackp->GetSigmaY(ilayer))+\r
99               trackp->GetDz(ilayer)*trackp->GetDz(ilayer)/(trackp->GetSigmaZ(ilayer)*trackp->GetSigmaZ(ilayer));\r
100           }\r
101           else{\r
102             chi2p+=9;\r
103           }\r
104         }\r
105       }else{\r
106         chi2p = 9*clayer;\r
107       }\r
108       //\r
109       if (trackm){\r
110         for (Int_t ilayer=0;ilayer<clayer;ilayer++){\r
111           if (trackm->GetClIndex(ilayer)>=0){\r
112             chi2m+=trackm->GetDy(ilayer)*trackm->GetDy(ilayer)/(trackm->GetSigmaY(ilayer)*trackm->GetSigmaY(ilayer))+\r
113               trackm->GetDz(ilayer)*trackm->GetDz(ilayer)/(trackm->GetSigmaZ(ilayer)*trackm->GetSigmaZ(ilayer));\r
114           }\r
115           else{\r
116             chi2m+=9;\r
117           }\r
118         }\r
119       }else{\r
120         chi2m = 9*clayer;\r
121       }\r
122       vertex->SetChi2Before(TMath::Min(chi2p,chi2m));\r
123       if (TMath::Min(chi2p,chi2m)/Float_t(clayer)<4) vertex->SetStatus(-10);  // track exist before vertex\r
124     }\r
125     \r
126     if (clayer < 5 ){ // calculate chi2 after vertex\r
127       Float_t chi2p = 0, chi2m=0;  \r
128       //\r
129       if (trackp&&TMath::Abs(trackp->GetTgl())<1.){\r
130         for (Int_t ilayer=clayer;ilayer<6;ilayer++){\r
131           if (trackp->GetClIndex(ilayer)>=0){\r
132             chi2p+=trackp->GetDy(ilayer)*trackp->GetDy(ilayer)/(trackp->GetSigmaY(ilayer)*trackp->GetSigmaY(ilayer))+\r
133               trackp->GetDz(ilayer)*trackp->GetDz(ilayer)/(trackp->GetSigmaZ(ilayer)*trackp->GetSigmaZ(ilayer));\r
134           }\r
135           else{\r
136             chi2p+=9;\r
137           }\r
138         }\r
139       }else{\r
140         chi2p = 0;\r
141       }\r
142       //\r
143       if (trackm&&TMath::Abs(trackm->GetTgl())<1.){\r
144         for (Int_t ilayer=clayer;ilayer<6;ilayer++){\r
145           if (trackm->GetClIndex(ilayer)>=0){\r
146             chi2m+=trackm->GetDy(ilayer)*trackm->GetDy(ilayer)/(trackm->GetSigmaY(ilayer)*trackm->GetSigmaY(ilayer))+\r
147               trackm->GetDz(ilayer)*trackm->GetDz(ilayer)/(trackm->GetSigmaZ(ilayer)*trackm->GetSigmaZ(ilayer));\r
148           }\r
149           else{\r
150             chi2m+=9;\r
151           }\r
152         }\r
153       }else{\r
154         chi2m = 0;\r
155       }\r
156       vertex->SetChi2After(TMath::Max(chi2p,chi2m));\r
157       if (TMath::Max(chi2m,chi2p)/Float_t(6-clayer)>9) vertex->SetStatus(-20);  // track not found in ITS\r
158     }\r
159   }\r
160   //\r
161 }\r
162 //------------------------------------------------------------------------\r
163 void AliITSV0Finder::FindV02(AliESDEvent *event,\r
164                                AliITStrackerMI *tracker) \r
165 {\r
166   //\r
167   // V0 finder\r
168   //\r
169   //  Cuts on DCA -  R dependent\r
170   //          max distance DCA between 2 tracks cut \r
171   //          maxDist = TMath::Min(kMaxDist,kMaxDist0+pvertex->GetRr()*kMaxDist);\r
172   //\r
173   const Float_t kMaxDist0      = 0.1;    \r
174   const Float_t kMaxDist1      = 0.1;     \r
175   const Float_t kMaxDist       = 1;\r
176   const Float_t kMinPointAngle  = 0.85;\r
177   const Float_t kMinPointAngle2 = 0.99;\r
178   const Float_t kMinR           = 0.5;\r
179   const Float_t kMaxR           = 220;\r
180   //const Float_t kCausality0Cut   = 0.19;\r
181   //const Float_t kLikelihood01Cut = 0.25;\r
182   //const Float_t kPointAngleCut   = 0.9996;\r
183   const Float_t kCausality0Cut   = 0.19;\r
184   const Float_t kLikelihood01Cut = 0.45;\r
185   const Float_t kLikelihood1Cut  = 0.5;\r
186   const Float_t kCombinedCut     = 0.55;\r
187 \r
188   TObjArray *trackHypothesys = tracker->GetTrackHypothesys();\r
189   TObjArray *bestHypothesys  = tracker->GetBestHypothesys();\r
190   TObjArray *originalTracks  = tracker->GetOriginal();\r
191   //\r
192   //\r
193   TTreeSRedirector &cstream = *(tracker->GetDebugStreamer());\r
194   Int_t ntracks    = event->GetNumberOfTracks(); \r
195   Int_t nitstracks = trackHypothesys->GetEntriesFast();\r
196   originalTracks->Expand(ntracks);\r
197   trackHypothesys->Expand(ntracks);\r
198   bestHypothesys->Expand(ntracks);\r
199   //\r
200   AliHelix * helixes   = new AliHelix[ntracks+2];\r
201   TObjArray trackarray(ntracks+2);     //array with tracks - with vertex constrain\r
202   TObjArray trackarrayc(ntracks+2);    //array of "best    tracks" - without vertex constrain\r
203   TObjArray trackarrayl(ntracks+2);    //array of "longest tracks" - without vertex constrain\r
204   Bool_t * forbidden   = new Bool_t [ntracks+2];\r
205   Int_t   *itsmap      = new Int_t  [ntracks+2];\r
206   Float_t *dist        = new Float_t[ntracks+2];\r
207   Float_t *normdist0   = new Float_t[ntracks+2];\r
208   Float_t *normdist1   = new Float_t[ntracks+2];\r
209   Float_t *normdist    = new Float_t[ntracks+2];\r
210   Float_t *norm        = new Float_t[ntracks+2];\r
211   Float_t *maxr        = new Float_t[ntracks+2];\r
212   Float_t *minr        = new Float_t[ntracks+2];\r
213   Float_t *minPointAngle= new Float_t[ntracks+2];\r
214   //\r
215   AliV0 *pvertex      = new AliV0;\r
216   AliITStrackMI * dummy= new AliITStrackMI;\r
217   dummy->SetLabel(0);\r
218   AliITStrackMI  trackat0;    //temporary track for DCA calculation\r
219   //\r
220   Float_t primvertex[3]={tracker->GetX(),tracker->GetY(),tracker->GetZ()};\r
221   //\r
222   // make ITS -  ESD map\r
223   //\r
224   for (Int_t itrack=0;itrack<ntracks+2;itrack++) {\r
225     itsmap[itrack]        = -1;\r
226     forbidden[itrack]     = kFALSE;\r
227     maxr[itrack]          = kMaxR;\r
228     minr[itrack]          = kMinR;\r
229     minPointAngle[itrack] = kMinPointAngle;\r
230   }\r
231   for (Int_t itrack=0;itrack<nitstracks;itrack++){\r
232     AliITStrackMI * original =   (AliITStrackMI*)(originalTracks->At(itrack));\r
233     Int_t           esdindex =   original->GetESDtrack()->GetID();\r
234     itsmap[esdindex]         =   itrack;\r
235   }\r
236   //\r
237   // create ITS tracks from ESD tracks if not done before\r
238   //\r
239   for (Int_t itrack=0;itrack<ntracks;itrack++){\r
240     if (itsmap[itrack]>=0) continue;\r
241     AliITStrackMI * tpctrack = new AliITStrackMI(*(event->GetTrack(itrack)));\r
242     //tpctrack->fD[0] = tpctrack->GetD(GetX(),GetY());\r
243     //tpctrack->fD[1] = tpctrack->GetZat(GetX())-GetZ(); \r
244     tpctrack->GetDZ(tracker->GetX(),tracker->GetY(),tracker->GetZ(),tpctrack->GetDP());   //I.B.\r
245     if (tpctrack->GetD(0)<20 && tpctrack->GetD(1)<20){\r
246       // tracks which can reach inner part of ITS\r
247       // propagate track to outer its volume - with correction for material\r
248       AliITStrackerMI::CorrectForTPCtoITSDeadZoneMaterial(tpctrack);  \r
249     }\r
250     itsmap[itrack] = nitstracks;\r
251     originalTracks->AddAt(tpctrack,nitstracks);\r
252     nitstracks++;\r
253   }\r
254   //\r
255   // fill temporary arrays\r
256   //\r
257   for (Int_t itrack=0;itrack<ntracks;itrack++){\r
258     AliESDtrack *  esdtrack = event->GetTrack(itrack);\r
259     Int_t          itsindex = itsmap[itrack];\r
260     AliITStrackMI *original = (AliITStrackMI*)originalTracks->At(itsmap[itrack]);\r
261     if (!original) continue;\r
262     AliITStrackMI *bestConst  = 0;\r
263     AliITStrackMI *bestLong   = 0;\r
264     AliITStrackMI *best       = 0;    \r
265     //\r
266     //\r
267     TObjArray * array    = (TObjArray*)  trackHypothesys->At(itsindex);\r
268     Int_t       hentries = (array==0) ?  0 : array->GetEntriesFast();\r
269     // Get best track with vertex constrain\r
270     for (Int_t ih=0;ih<hentries;ih++){\r
271       AliITStrackMI * trackh = (AliITStrackMI*)array->At(ih);\r
272       if (!trackh->GetConstrain()) continue;\r
273       if (!bestConst) bestConst = trackh;\r
274       if (trackh->GetNumberOfClusters()>5.0){\r
275         bestConst  = trackh;                         // full track -  with minimal chi2\r
276         break;\r
277       }\r
278       if (trackh->GetNumberOfClusters()+trackh->GetNDeadZone()<=bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone())  continue;      \r
279       bestConst = trackh;\r
280       break;\r
281     }\r
282     // Get best long track without vertex constrain and best track without vertex constrain\r
283     for (Int_t ih=0;ih<hentries;ih++){\r
284       AliITStrackMI * trackh = (AliITStrackMI*)array->At(ih);\r
285       if (trackh->GetConstrain()) continue;\r
286       if (!best)     best     = trackh;\r
287       if (!bestLong) bestLong = trackh;\r
288       if (trackh->GetNumberOfClusters()>5.0){\r
289         bestLong  = trackh;                         // full track -  with minimal chi2\r
290         break;\r
291       }\r
292       if (trackh->GetNumberOfClusters()+trackh->GetNDeadZone()<=bestLong->GetNumberOfClusters()+bestLong->GetNDeadZone())  continue;      \r
293       bestLong = trackh;        \r
294     }\r
295     if (!best) {\r
296       best     = original;\r
297       bestLong = original;\r
298     }\r
299     //I.B. trackat0 = *bestLong;\r
300     new (&trackat0) AliITStrackMI(*bestLong);\r
301     Double_t xx,yy,zz,alpha; \r
302     if (!bestLong->GetGlobalXYZat(bestLong->GetX(),xx,yy,zz)) continue;\r
303     alpha = TMath::ATan2(yy,xx);    \r
304     //    if (!trackat0.Propagate(alpha,0)) continue;    \r
305     trackat0.Propagate(alpha,0); //PH The check on the return value is temporarily disabled (bug 45751) \r
306     // calculate normalized distances to the vertex \r
307     //\r
308     Float_t ptfac  = (1.+100.*TMath::Abs(trackat0.GetC()));\r
309     if ( bestLong->GetNumberOfClusters()>3 ){      \r
310       dist[itsindex]      = trackat0.GetY();\r
311       norm[itsindex]      = ptfac*TMath::Sqrt(trackat0.GetSigmaY2());\r
312       normdist0[itsindex] = TMath::Abs(trackat0.GetY()/norm[itsindex]);\r
313       normdist1[itsindex] = TMath::Abs((trackat0.GetZ()-primvertex[2])/(ptfac*TMath::Sqrt(trackat0.GetSigmaZ2())));\r
314       normdist[itsindex]  = TMath::Sqrt(normdist0[itsindex]*normdist0[itsindex]+normdist1[itsindex]*normdist1[itsindex]);\r
315       if (!bestConst){\r
316         if (bestLong->GetNumberOfClusters()+bestLong->GetNDeadZone()<6) normdist[itsindex]*=2.;\r
317         if (bestLong->GetNumberOfClusters()+bestLong->GetNDeadZone()<5) normdist[itsindex]*=2.;\r
318         if (bestLong->GetNumberOfClusters()+bestLong->GetNDeadZone()<4) normdist[itsindex]*=2.;\r
319       }else{\r
320         if (bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()<6) normdist[itsindex]*=1.5;\r
321         if (bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()<5) normdist[itsindex]*=1.5;\r
322       }\r
323     }\r
324     else{      \r
325       if (bestConst&&bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()>4.5){\r
326         dist[itsindex] = bestConst->GetD(0);\r
327         norm[itsindex] = bestConst->GetDnorm(0);\r
328         normdist0[itsindex] = TMath::Abs(bestConst->GetD(0)/norm[itsindex]);\r
329         normdist1[itsindex] = TMath::Abs(bestConst->GetD(0)/norm[itsindex]);\r
330         normdist[itsindex]  = TMath::Sqrt(normdist0[itsindex]*normdist0[itsindex]+normdist1[itsindex]*normdist1[itsindex]);\r
331       }else{\r
332         dist[itsindex]      = trackat0.GetY();\r
333         norm[itsindex]      = ptfac*TMath::Sqrt(trackat0.GetSigmaY2());\r
334         normdist0[itsindex] = TMath::Abs(trackat0.GetY()/norm[itsindex]);\r
335         normdist1[itsindex] = TMath::Abs((trackat0.GetZ()-primvertex[2])/(ptfac*TMath::Sqrt(trackat0.GetSigmaZ2())));\r
336         normdist[itsindex]  = TMath::Sqrt(normdist0[itsindex]*normdist0[itsindex]+normdist1[itsindex]*normdist1[itsindex]);\r
337         if (TMath::Abs(trackat0.GetTgl())>1.05){\r
338           if (normdist[itsindex]<3) forbidden[itsindex]=kTRUE;\r
339           if (normdist[itsindex]>3) {\r
340             minr[itsindex] = TMath::Max(Float_t(40.),minr[itsindex]);\r
341           }\r
342         }\r
343       }\r
344     }\r
345     //\r
346     //-----------------------------------------------------------\r
347     //Forbid primary track candidates - \r
348     //\r
349     //treetr->SetAlias("forbidden0","Tr0.fN<4&&Tr1.fN+Tr1.fNDeadZone>4.5");\r
350     //treetr->SetAlias("forbidden1","ND<3&&Tr1.fN+Tr1.fNDeadZone>5.5");\r
351     //treetr->SetAlias("forbidden2","ND<2&&Tr1.fClIndex[0]>0&&Tr1.fClIndex[0]>0");\r
352     //treetr->SetAlias("forbidden3","ND<1&&Tr1.fClIndex[0]>0");\r
353     //treetr->SetAlias("forbidden4","ND<4&&Tr1.fNormChi2[0]<2");\r
354     //treetr->SetAlias("forbidden5","ND<5&&Tr1.fNormChi2[0]<1");\r
355     //-----------------------------------------------------------\r
356     if (bestConst){\r
357       if (bestLong->GetNumberOfClusters()<4       && bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()>4.5)               forbidden[itsindex]=kTRUE;\r
358       if (normdist[itsindex]<3 && bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()>5.5)               forbidden[itsindex]=kTRUE;\r
359       if (normdist[itsindex]<2 && bestConst->GetClIndex(0)>=0 && bestConst->GetClIndex(1)>=0 ) forbidden[itsindex]=kTRUE;\r
360       if (normdist[itsindex]<1 && bestConst->GetClIndex(0)>=0)                              forbidden[itsindex]=kTRUE;\r
361       if (normdist[itsindex]<4 && bestConst->GetNormChi2(0)<2)                             forbidden[itsindex]=kTRUE;\r
362       if (normdist[itsindex]<5 && bestConst->GetNormChi2(0)<1)                             forbidden[itsindex]=kTRUE;      \r
363       if (bestConst->GetNormChi2(0)<2.5) {\r
364         minPointAngle[itsindex]= 0.9999;\r
365         maxr[itsindex]         = 10;\r
366       }\r
367     }\r
368     //\r
369     //forbid daughter kink candidates\r
370     //\r
371     if (esdtrack->GetKinkIndex(0)>0) forbidden[itsindex] = kTRUE;\r
372     Bool_t isElectron = kTRUE;\r
373     Bool_t isProton   = kTRUE;\r
374     Double_t pid[5];\r
375     esdtrack->GetESDpid(pid);\r
376     for (Int_t i=1;i<5;i++){\r
377       if (pid[0]<pid[i]) isElectron= kFALSE;\r
378       if (pid[4]<pid[i]) isProton= kFALSE;\r
379     }\r
380     if (isElectron){\r
381       forbidden[itsindex]=kFALSE;       \r
382       normdist[itsindex]*=-1;\r
383     }\r
384     if (isProton){\r
385       if (normdist[itsindex]>2) forbidden[itsindex]=kFALSE;     \r
386       normdist[itsindex]*=-1;\r
387     }\r
388 \r
389     //\r
390     // Causality cuts in TPC volume\r
391     //\r
392     if (esdtrack->GetTPCdensity(0,10) >0.6)  maxr[itsindex] = TMath::Min(Float_t(110),maxr[itsindex]);\r
393     if (esdtrack->GetTPCdensity(10,30)>0.6)  maxr[itsindex] = TMath::Min(Float_t(120),maxr[itsindex]);\r
394     if (esdtrack->GetTPCdensity(20,40)>0.6)  maxr[itsindex] = TMath::Min(Float_t(130),maxr[itsindex]);\r
395     if (esdtrack->GetTPCdensity(30,50)>0.6)  maxr[itsindex] = TMath::Min(Float_t(140),maxr[itsindex]);\r
396     //\r
397     if (esdtrack->GetTPCdensity(0,60)<0.4&&bestLong->GetNumberOfClusters()<3) minr[itsindex]=100;    \r
398     //\r
399     //\r
400     if (kFALSE){\r
401       cstream<<"Track"<<\r
402         "Tr0.="<<best<<\r
403         "Tr1.="<<((bestConst)? bestConst:dummy)<<\r
404         "Tr2.="<<bestLong<<\r
405         "Tr3.="<<&trackat0<<\r
406         "Esd.="<<esdtrack<<\r
407         "Dist="<<dist[itsindex]<<\r
408         "ND0="<<normdist0[itsindex]<<\r
409         "ND1="<<normdist1[itsindex]<<\r
410         "ND="<<normdist[itsindex]<<\r
411         "Pz="<<primvertex[2]<<\r
412         "Forbid="<<forbidden[itsindex]<<\r
413         "\n";\r
414       //\r
415     }\r
416     trackarray.AddAt(best,itsindex);\r
417     trackarrayc.AddAt(bestConst,itsindex);\r
418     trackarrayl.AddAt(bestLong,itsindex);\r
419     new (&helixes[itsindex]) AliHelix(*best);\r
420   }\r
421   //\r
422   //\r
423   //\r
424   // first iterration of V0 finder\r
425   //\r
426   for (Int_t iesd0=0;iesd0<ntracks;iesd0++){\r
427     Int_t itrack0 = itsmap[iesd0];\r
428     if (forbidden[itrack0]) continue;\r
429     AliITStrackMI * btrack0 = (AliITStrackMI*)trackarray.At(itrack0);\r
430     if (!btrack0) continue;    \r
431     if (btrack0->GetSign()>0 && !AliITSReconstructor::GetRecoParam()->GetStoreLikeSignV0s()) continue;\r
432     AliITStrackMI *trackc0 = (AliITStrackMI*)trackarrayc.At(itrack0);\r
433     //\r
434     for (Int_t iesd1=iesd0+1;iesd1<ntracks;iesd1++){\r
435       Int_t itrack1 = itsmap[iesd1];\r
436       if (forbidden[itrack1]) continue;\r
437 \r
438       AliITStrackMI * btrack1 = (AliITStrackMI*)trackarray.At(itrack1); \r
439       if (!btrack1) continue;\r
440       if (btrack1->GetSign()<0 && !AliITSReconstructor::GetRecoParam()->GetStoreLikeSignV0s()) continue;\r
441       Bool_t isGold = kFALSE;\r
442       if (TMath::Abs(TMath::Abs(btrack0->GetLabel())-TMath::Abs(btrack1->GetLabel()))==1){\r
443         isGold = kTRUE;\r
444       }\r
445       AliITStrackMI *trackc1 = (AliITStrackMI*)trackarrayc.At(itrack1);\r
446       AliHelix &h1 = helixes[itrack0];\r
447       AliHelix &h2 = helixes[itrack1];\r
448       //\r
449       // find linear distance\r
450       Double_t rmin =0;\r
451       //\r
452       //\r
453       //\r
454       Double_t phase[2][2],radius[2];\r
455       Int_t  points = h1.GetRPHIintersections(h2, phase, radius);\r
456       if    (points==0)  continue;\r
457       Double_t delta[2]={1000000,1000000};        \r
458       rmin = radius[0];\r
459       h1.ParabolicDCA(h2,phase[0][0],phase[0][1],radius[0],delta[0]);\r
460       if (points==2){    \r
461         if (radius[1]<rmin) rmin = radius[1];\r
462         h1.ParabolicDCA(h2,phase[1][0],phase[1][1],radius[1],delta[1]);\r
463       }\r
464       rmin = TMath::Sqrt(rmin);\r
465       Double_t distance = 0;\r
466       Double_t radiusC  = 0;\r
467       Int_t    iphase   = 0;\r
468       if (points==1 || delta[0]<delta[1]){\r
469         distance = TMath::Sqrt(delta[0]);\r
470         radiusC  = TMath::Sqrt(radius[0]);\r
471       }else{\r
472         distance = TMath::Sqrt(delta[1]);\r
473         radiusC  = TMath::Sqrt(radius[1]);\r
474         iphase=1;\r
475       }\r
476       if (radiusC<TMath::Max(minr[itrack0],minr[itrack1]))    continue;\r
477       if (radiusC>TMath::Min(maxr[itrack0],maxr[itrack1]))     continue; \r
478       Float_t maxDist  = TMath::Min(kMaxDist,Float_t(kMaxDist0+radiusC*kMaxDist1));      \r
479       if (distance>maxDist) continue;\r
480       Float_t pointAngle = h1.GetPointAngle(h2,phase[iphase],primvertex);\r
481       if (pointAngle<TMath::Max(minPointAngle[itrack0],minPointAngle[itrack1])) continue;\r
482       //\r
483       //\r
484       //      Double_t distance = TestV0(h1,h2,pvertex,rmin);\r
485       //\r
486       //       if (distance>maxDist)           continue;\r
487       //       if (pvertex->GetRr()<kMinR)     continue;\r
488       //       if (pvertex->GetRr()>kMaxR)     continue;\r
489       AliITStrackMI * track0=btrack0;\r
490       AliITStrackMI * track1=btrack1;\r
491       //      if (pvertex->GetRr()<3.5){  \r
492       if (radiusC<3.5){  \r
493         //use longest tracks inside the pipe\r
494         track0 = (AliITStrackMI*)trackarrayl.At(itrack0);\r
495         track1 = (AliITStrackMI*)trackarrayl.At(itrack1);\r
496       }      \r
497       //\r
498       //\r
499       pvertex->SetParamN(*track0);\r
500       pvertex->SetParamP(*track1);\r
501       pvertex->Update(primvertex);\r
502       pvertex->SetClusters(track0->ClIndex(),track1->ClIndex());  // register clusters\r
503 \r
504       if (pvertex->GetRr()<kMinR) continue;\r
505       if (pvertex->GetRr()>kMaxR) continue;\r
506       if (pvertex->GetV0CosineOfPointingAngle()<kMinPointAngle) continue;\r
507 //Bo:      if (pvertex->GetDist2()>maxDist) continue;\r
508       if (pvertex->GetDcaV0Daughters()>maxDist) continue;\r
509 //Bo:        pvertex->SetLab(0,track0->GetLabel());\r
510 //Bo:        pvertex->SetLab(1,track1->GetLabel());\r
511       pvertex->SetIndex(0,track0->GetESDtrack()->GetID());\r
512       pvertex->SetIndex(1,track1->GetESDtrack()->GetID());\r
513       //      \r
514       AliITStrackMI * htrackc0 = trackc0 ? trackc0:dummy;      \r
515       AliITStrackMI * htrackc1 = trackc1 ? trackc1:dummy;\r
516 \r
517       //\r
518       //\r
519       TObjArray * array0b     = (TObjArray*)bestHypothesys->At(itrack0);\r
520       if (!array0b&&pvertex->GetRr()<40 && TMath::Abs(track0->GetTgl())<1.1) {\r
521         tracker->SetCurrentEsdTrack(itrack0);\r
522         tracker->FollowProlongationTree((AliITStrackMI*)originalTracks->At(itrack0),itrack0, kFALSE);\r
523       }\r
524       TObjArray * array1b    = (TObjArray*)bestHypothesys->At(itrack1);\r
525       if (!array1b&&pvertex->GetRr()<40 && TMath::Abs(track1->GetTgl())<1.1) { \r
526         tracker->SetCurrentEsdTrack(itrack1);\r
527         tracker->FollowProlongationTree((AliITStrackMI*)originalTracks->At(itrack1),itrack1, kFALSE);\r
528       }\r
529       //\r
530       AliITStrackMI * track0b = (AliITStrackMI*)originalTracks->At(itrack0);\r
531       AliITStrackMI * track1b = (AliITStrackMI*)originalTracks->At(itrack1);\r
532       AliITStrackMI * track0l = (AliITStrackMI*)originalTracks->At(itrack0);\r
533       AliITStrackMI * track1l = (AliITStrackMI*)originalTracks->At(itrack1);\r
534       \r
535       Float_t minchi2before0=16;\r
536       Float_t minchi2before1=16;\r
537       Float_t minchi2after0 =16;\r
538       Float_t minchi2after1 =16;\r
539       Double_t xrp[3]; pvertex->GetXYZ(xrp[0],xrp[1],xrp[2]);  //I.B.\r
540       Int_t maxLayer = tracker->GetNearestLayer(xrp);                   //I.B.\r
541       \r
542       if (array0b) for (Int_t i=0;i<5;i++){\r
543         // best track after vertex\r
544         AliITStrackMI * btrack = (AliITStrackMI*)array0b->At(i);\r
545         if (!btrack) continue;\r
546         if (btrack->GetNumberOfClusters()>track0l->GetNumberOfClusters()) track0l = btrack;     \r
547         //      if (btrack->fX<pvertex->GetRr()-2.-0.5/(0.1+pvertex->GetAnglep()[2])) {\r
548         if (btrack->GetX()<pvertex->GetRr()-2.) {\r
549           if ( (maxLayer>i+2|| (i==0)) && btrack->GetNumberOfClusters()==(6-i)&&i<3){\r
550             Float_t sumchi2= 0;\r
551             Float_t sumn   = 0;\r
552             if (maxLayer<3){   // take prim vertex as additional measurement\r
553               if (normdist[itrack0]>0 && htrackc0){\r
554                 sumchi2 += TMath::Min((3.-maxLayer)*normdist[itrack0]*normdist[itrack0],16.);\r
555               }else{\r
556                 sumchi2 +=  TMath::Min((3.-maxLayer)*(3*normdist[itrack0]*normdist[itrack0]+3.),16.);\r
557               }\r
558               sumn    +=  3-maxLayer;\r
559             }\r
560             for (Int_t ilayer=i;ilayer<maxLayer;ilayer++){\r
561               sumn+=1.;       \r
562               if (btrack->GetClIndex(ilayer)<0){\r
563                 sumchi2+=25;\r
564                 continue;\r
565               }else{\r
566                 Int_t c=( btrack->GetClIndex(ilayer) & 0x0fffffff);\r
567                 for (Int_t itrack=0;itrack<4;itrack++){\r
568                   AliITStrackerMI::AliITSlayer &layer=tracker->GetLayer(ilayer);\r
569                   if (layer.GetClusterTracks(itrack,c)>=0 && layer.GetClusterTracks(itrack,c)!=itrack0){\r
570                     sumchi2+=18.;  //shared cluster\r
571                     break;\r
572                   }\r
573                 }\r
574                 sumchi2+=btrack->GetDy(ilayer)*btrack->GetDy(ilayer)/(btrack->GetSigmaY(ilayer)*btrack->GetSigmaY(ilayer));\r
575                 sumchi2+=btrack->GetDz(ilayer)*btrack->GetDz(ilayer)/(btrack->GetSigmaZ(ilayer)*btrack->GetSigmaZ(ilayer));            \r
576               }\r
577             }\r
578             sumchi2/=sumn;\r
579             if (sumchi2<minchi2before0) minchi2before0=sumchi2; \r
580           }\r
581           continue;   //safety space - Geo manager will give exact layer\r
582         }\r
583         track0b       = btrack;\r
584         minchi2after0 = btrack->GetNormChi2(i);\r
585         break;\r
586       }\r
587       if (array1b) for (Int_t i=0;i<5;i++){\r
588         // best track after vertex\r
589         AliITStrackMI * btrack = (AliITStrackMI*)array1b->At(i);\r
590         if (!btrack) continue;\r
591         if (btrack->GetNumberOfClusters()>track1l->GetNumberOfClusters()) track1l = btrack;     \r
592         //      if (btrack->fX<pvertex->GetRr()-2-0.5/(0.1+pvertex->GetAnglep()[2])){\r
593         if (btrack->GetX()<pvertex->GetRr()-2){\r
594           if ((maxLayer>i+2 || (i==0))&&btrack->GetNumberOfClusters()==(6-i)&&(i<3)){\r
595             Float_t sumchi2= 0;\r
596             Float_t sumn   = 0;\r
597             if (maxLayer<3){   // take prim vertex as additional measurement\r
598               if (normdist[itrack1]>0 && htrackc1){\r
599                 sumchi2 +=  TMath::Min((3.-maxLayer)*normdist[itrack1]*normdist[itrack1],16.);\r
600               }else{\r
601                 sumchi2 += TMath::Min((3.-maxLayer)*(3*normdist[itrack1]*normdist[itrack1]+3.),16.);\r
602               }\r
603               sumn    +=  3-maxLayer;\r
604             }\r
605             for (Int_t ilayer=i;ilayer<maxLayer;ilayer++){\r
606               sumn+=1.;\r
607               if (btrack->GetClIndex(ilayer)<0){\r
608                 sumchi2+=30;\r
609                 continue;\r
610               }else{\r
611                 Int_t c=( btrack->GetClIndex(ilayer) & 0x0fffffff);\r
612                 for (Int_t itrack=0;itrack<4;itrack++){\r
613                   AliITStrackerMI::AliITSlayer &layer=tracker->GetLayer(ilayer);\r
614                   if (layer.GetClusterTracks(itrack,c)>=0 && layer.GetClusterTracks(itrack,c)!=itrack1){\r
615                     sumchi2+=18.;  //shared cluster\r
616                     break;\r
617                   }\r
618                 }\r
619                 sumchi2+=btrack->GetDy(ilayer)*btrack->GetDy(ilayer)/(btrack->GetSigmaY(ilayer)*btrack->GetSigmaY(ilayer));\r
620                 sumchi2+=btrack->GetDz(ilayer)*btrack->GetDz(ilayer)/(btrack->GetSigmaZ(ilayer)*btrack->GetSigmaZ(ilayer));            \r
621               }\r
622             }\r
623             sumchi2/=sumn;\r
624             if (sumchi2<minchi2before1) minchi2before1=sumchi2; \r
625           }\r
626           continue;   //safety space - Geo manager will give exact layer           \r
627         }\r
628         track1b = btrack;\r
629         minchi2after1 = btrack->GetNormChi2(i);\r
630         break;\r
631       }\r
632       //\r
633       // position resolution - used for DCA cut\r
634       Float_t sigmad = track0b->GetSigmaY2()+track0b->GetSigmaZ2()+track1b->GetSigmaY2()+track1b->GetSigmaZ2()+\r
635         (track0b->GetX()-pvertex->GetRr())*(track0b->GetX()-pvertex->GetRr())*(track0b->GetSigmaSnp2()+track0b->GetSigmaTgl2())+\r
636         (track1b->GetX()-pvertex->GetRr())*(track1b->GetX()-pvertex->GetRr())*(track1b->GetSigmaSnp2()+track1b->GetSigmaTgl2());\r
637       sigmad =TMath::Sqrt(sigmad)+0.04;\r
638       if (pvertex->GetRr()>50){\r
639         Double_t cov0[15],cov1[15];\r
640         track0b->GetESDtrack()->GetInnerExternalCovariance(cov0);\r
641         track1b->GetESDtrack()->GetInnerExternalCovariance(cov1);\r
642         sigmad = cov0[0]+cov0[2]+cov1[0]+cov1[2]+\r
643           (80.-pvertex->GetRr())*(80.-pvertex->GetRr())*(cov0[5]+cov0[9])+\r
644           (80.-pvertex->GetRr())*(80.-pvertex->GetRr())*(cov1[5]+cov1[9]);\r
645         sigmad =TMath::Sqrt(sigmad)+0.05;\r
646       }\r
647       //       \r
648       AliV0 vertex2;\r
649       vertex2.SetParamN(*track0b);\r
650       vertex2.SetParamP(*track1b);\r
651       vertex2.Update(primvertex);\r
652       //Bo:      if (vertex2.GetDist2()<=pvertex->GetDist2()&&(vertex2.GetV0CosineOfPointingAngle()>=pvertex->GetV0CosineOfPointingAngle())){\r
653       if (vertex2.GetDcaV0Daughters()<=pvertex->GetDcaV0Daughters()&&(vertex2.GetV0CosineOfPointingAngle()>=pvertex->GetV0CosineOfPointingAngle())){\r
654         pvertex->SetParamN(*track0b);\r
655         pvertex->SetParamP(*track1b);\r
656         pvertex->Update(primvertex);\r
657         pvertex->SetClusters(track0b->ClIndex(),track1b->ClIndex());  // register clusters\r
658         pvertex->SetIndex(0,track0->GetESDtrack()->GetID());\r
659         pvertex->SetIndex(1,track1->GetESDtrack()->GetID());\r
660       }\r
661       pvertex->SetDistSigma(sigmad);\r
662       //Bo:      pvertex->SetDistNorm(pvertex->GetDist2()/sigmad);       \r
663       pvertex->SetNormDCAPrim(normdist[itrack0],normdist[itrack1]);\r
664       //\r
665       // define likelihhod and causalities\r
666       //\r
667       Float_t pa0=1, pa1=1, pb0=0.26, pb1=0.26;      \r
668       if (maxLayer<1){\r
669         Float_t fnorm0 = normdist[itrack0];\r
670         if (fnorm0<0) fnorm0*=-3;\r
671         Float_t fnorm1 = normdist[itrack1];\r
672         if (fnorm1<0) fnorm1*=-3;\r
673         if ((pvertex->GetAnglep()[2]>0.1) || ( (pvertex->GetRr()<10.5)&& pvertex->GetAnglep()[2]>0.05 ) || (pvertex->GetRr()<3)){\r
674           pb0    =  TMath::Exp(-TMath::Min(fnorm0,Float_t(16.))/12.);\r
675           pb1    =  TMath::Exp(-TMath::Min(fnorm1,Float_t(16.))/12.);\r
676         }\r
677         pvertex->SetChi2Before(normdist[itrack0]);\r
678         pvertex->SetChi2After(normdist[itrack1]);       \r
679         pvertex->SetNAfter(0);\r
680         pvertex->SetNBefore(0);\r
681       }else{\r
682         pvertex->SetChi2Before(minchi2before0);\r
683         pvertex->SetChi2After(minchi2before1);\r
684          if (pvertex->GetAnglep()[2]>0.1 || ( pvertex->GetRr()<10.5 && pvertex->GetAnglep()[2]>0.05) || pvertex->GetRr()<3){\r
685            pb0    =  TMath::Exp(-TMath::Min(minchi2before0,Float_t(16))/12.);\r
686            pb1    =  TMath::Exp(-TMath::Min(minchi2before1,Float_t(16))/12.);\r
687          }\r
688          pvertex->SetNAfter(maxLayer);\r
689          pvertex->SetNBefore(maxLayer);      \r
690       }\r
691       if (pvertex->GetRr()<90){\r
692         pa0  *= TMath::Min(track0->GetESDtrack()->GetTPCdensity(0,60),Double_t(1.));\r
693         pa1  *= TMath::Min(track1->GetESDtrack()->GetTPCdensity(0,60),Double_t(1.));\r
694       }\r
695       if (pvertex->GetRr()<20){\r
696         pa0  *= (0.2+TMath::Exp(-TMath::Min(minchi2after0,Float_t(16))/8.))/1.2;\r
697         pa1  *= (0.2+TMath::Exp(-TMath::Min(minchi2after1,Float_t(16))/8.))/1.2;\r
698       }\r
699       //\r
700       pvertex->SetCausality(pb0,pb1,pa0,pa1);\r
701       //\r
702       //  Likelihood calculations  - apply cuts\r
703       //         \r
704       Bool_t v0OK = kTRUE;\r
705       Float_t p12 = pvertex->GetParamP()->GetParameter()[4]*pvertex->GetParamP()->GetParameter()[4];\r
706       p12        += pvertex->GetParamN()->GetParameter()[4]*pvertex->GetParamN()->GetParameter()[4];\r
707       p12         = TMath::Sqrt(p12);                             // "mean" momenta\r
708       Float_t    sigmap0   = 0.0001+0.001/(0.1+pvertex->GetRr()); \r
709       Float_t    sigmap    = 0.5*sigmap0*(0.6+0.4*p12);           // "resolution: of point angle - as a function of radius and momenta\r
710 \r
711       Float_t causalityA  = (1.0-pvertex->GetCausalityP()[0])*(1.0-pvertex->GetCausalityP()[1]);\r
712       Float_t causalityB  = TMath::Sqrt(TMath::Min(pvertex->GetCausalityP()[2],Double_t(0.7))*\r
713                                         TMath::Min(pvertex->GetCausalityP()[3],Double_t(0.7)));\r
714       //\r
715       //Bo:      Float_t likelihood0 = (TMath::Exp(-pvertex->GetDistNorm())+0.1) *(pvertex->GetDist2()<0.5)*(pvertex->GetDistNorm()<5);\r
716       Float_t lDistNorm = pvertex->GetDcaV0Daughters()/pvertex->GetDistSigma();\r
717       Float_t likelihood0 = (TMath::Exp(-lDistNorm)+0.1) *(pvertex->GetDcaV0Daughters()<0.5)*(lDistNorm<5);\r
718 \r
719       Float_t likelihood1 = TMath::Exp(-(1.0001-pvertex->GetV0CosineOfPointingAngle())/sigmap)+\r
720         0.4*TMath::Exp(-(1.0001-pvertex->GetV0CosineOfPointingAngle())/(4.*sigmap))+\r
721         0.4*TMath::Exp(-(1.0001-pvertex->GetV0CosineOfPointingAngle())/(8.*sigmap))+\r
722         0.1*TMath::Exp(-(1.0001-pvertex->GetV0CosineOfPointingAngle())/0.01);\r
723       //\r
724       if (causalityA<kCausality0Cut)                                          v0OK = kFALSE;\r
725       if (TMath::Sqrt(likelihood0*likelihood1)<kLikelihood01Cut)              v0OK = kFALSE;\r
726       if (likelihood1<kLikelihood1Cut)                                        v0OK = kFALSE;\r
727       if (TMath::Power(likelihood0*likelihood1*causalityB,0.33)<kCombinedCut) v0OK = kFALSE;\r
728       \r
729       //\r
730       //\r
731       if (kFALSE){      \r
732         Bool_t gold = TMath::Abs(TMath::Abs(track0->GetLabel())-TMath::Abs(track1->GetLabel()))==1;\r
733         cstream<<"It0"<<\r
734           "Tr0.="<<track0<<                       //best without constrain\r
735           "Tr1.="<<track1<<                       //best without constrain  \r
736           "Tr0B.="<<track0b<<                     //best without constrain  after vertex\r
737           "Tr1B.="<<track1b<<                     //best without constrain  after vertex \r
738           "Tr0C.="<<htrackc0<<                    //best with constrain     if exist\r
739           "Tr1C.="<<htrackc1<<                    //best with constrain     if exist\r
740           "Tr0L.="<<track0l<<                     //longest best           \r
741           "Tr1L.="<<track1l<<                     //longest best\r
742           "Esd0.="<<track0->GetESDtrack()<<           // esd track0 params\r
743           "Esd1.="<<track1->GetESDtrack()<<           // esd track1 params\r
744           "V0.="<<pvertex<<                       //vertex properties\r
745           "V0b.="<<&vertex2<<                       //vertex properties at "best" track\r
746           "ND0="<<normdist[itrack0]<<             //normalize distance for track0\r
747           "ND1="<<normdist[itrack1]<<             //normalize distance for track1\r
748           "Gold="<<gold<<                         //\r
749           //      "RejectBase="<<rejectBase<<             //rejection in First itteration\r
750           "OK="<<v0OK<<\r
751           "rmin="<<rmin<<\r
752           "sigmad="<<sigmad<<\r
753           "\n";\r
754       }      \r
755       //if (rejectBase) continue;\r
756       //\r
757       pvertex->SetStatus(0);\r
758       //      if (rejectBase) {\r
759       //        pvertex->SetStatus(-100);\r
760       //}\r
761       if (pvertex->GetV0CosineOfPointingAngle()>kMinPointAngle2) {\r
762         //Bo:     pvertex->SetESDindexes(track0->GetESDtrack()->GetID(),track1->GetESDtrack()->GetID());\r
763         pvertex->SetIndex(0,track0->GetESDtrack()->GetID());//Bo: consistency 0 for neg\r
764         pvertex->SetIndex(1,track1->GetESDtrack()->GetID());//Bo: consistency 1 for pos\r
765         if (v0OK){\r
766           //      AliV0vertex vertexjuri(*track0,*track1);\r
767           //      vertexjuri.SetESDindexes(track0->fESDtrack->GetID(),track1->fESDtrack->GetID());\r
768           //      event->AddV0(&vertexjuri);\r
769           pvertex->SetStatus(100);\r
770         }\r
771         pvertex->SetOnFlyStatus(kTRUE);\r
772         pvertex->ChangeMassHypothesis(kK0Short);\r
773         event->AddV0(pvertex);\r
774       }\r
775     }\r
776   }\r
777   //\r
778   //\r
779   // delete temporary arrays\r
780   //  \r
781   delete[] forbidden;\r
782   delete[] minPointAngle;\r
783   delete[] maxr;\r
784   delete[] minr;\r
785   delete[] norm;\r
786   delete[] normdist;\r
787   delete[] normdist1;\r
788   delete[] normdist0;\r
789   delete[] dist;\r
790   delete[] itsmap;\r
791   delete[] helixes;\r
792   delete   pvertex;\r
793 }\r
794 //------------------------------------------------------------------------\r
795 void AliITSV0Finder::RefitV02(const AliESDEvent *event,\r
796                                 AliITStrackerMI *tracker) \r
797 {\r
798   //\r
799   //try to refit  V0s in the third path of the reconstruction\r
800   //\r
801   TTreeSRedirector &cstream = *(tracker->GetDebugStreamer());\r
802   //\r
803   Int_t  nv0s = event->GetNumberOfV0s();\r
804   Float_t primvertex[3]={tracker->GetX(),tracker->GetY(),tracker->GetZ()};\r
805   AliV0 v0temp;\r
806   for (Int_t iv0 = 0; iv0<nv0s;iv0++){\r
807     AliV0 * v0mi = (AliV0*)event->GetV0(iv0);\r
808     if (!v0mi) continue;\r
809     Int_t     itrack0   = v0mi->GetIndex(0);\r
810     Int_t     itrack1   = v0mi->GetIndex(1);\r
811     AliESDtrack *esd0   = event->GetTrack(itrack0);\r
812     AliESDtrack *esd1   = event->GetTrack(itrack1);\r
813     if (!esd0||!esd1) continue;\r
814     AliITStrackMI tpc0(*esd0);  \r
815     AliITStrackMI tpc1(*esd1);\r
816     Double_t x,y,z; v0mi->GetXYZ(x,y,z); //I.B. \r
817     Double_t alpha =TMath::ATan2(y,x);   //I.B.\r
818     if (v0mi->GetRr()>85){\r
819       if (tpc0.Propagate(alpha,v0mi->GetRr())&&tpc1.Propagate(alpha,v0mi->GetRr())){\r
820         v0temp.SetParamN(tpc0);\r
821         v0temp.SetParamP(tpc1);\r
822         v0temp.Update(primvertex);\r
823         if (kFALSE) cstream<<"Refit"<<\r
824           "V0.="<<v0mi<<\r
825           "V0refit.="<<&v0temp<<\r
826           "Tr0.="<<&tpc0<<\r
827           "Tr1.="<<&tpc1<<\r
828           "\n";\r
829         //Bo:   if (v0temp.GetDist2()<v0mi->GetDist2() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){\r
830         if (v0temp.GetDcaV0Daughters()<v0mi->GetDcaV0Daughters() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){\r
831           v0mi->SetParamN(tpc0);\r
832           v0mi->SetParamP(tpc1);\r
833           v0mi->Update(primvertex);\r
834         }\r
835       }\r
836       continue;\r
837     }\r
838     if (v0mi->GetRr()>35){\r
839       AliITStrackerMI::CorrectForTPCtoITSDeadZoneMaterial(&tpc0);\r
840       AliITStrackerMI::CorrectForTPCtoITSDeadZoneMaterial(&tpc1);\r
841       if (tpc0.Propagate(alpha,v0mi->GetRr())&&tpc1.Propagate(alpha,v0mi->GetRr())){\r
842         v0temp.SetParamN(tpc0);\r
843         v0temp.SetParamP(tpc1);\r
844         v0temp.Update(primvertex);\r
845         if (kFALSE) cstream<<"Refit"<<\r
846           "V0.="<<v0mi<<\r
847           "V0refit.="<<&v0temp<<\r
848           "Tr0.="<<&tpc0<<\r
849           "Tr1.="<<&tpc1<<\r
850           "\n";\r
851         //Bo:   if (v0temp.GetDist2()<v0mi->GetDist2() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){\r
852         if (v0temp.GetDcaV0Daughters()<v0mi->GetDcaV0Daughters() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){\r
853           v0mi->SetParamN(tpc0);\r
854           v0mi->SetParamP(tpc1);\r
855           v0mi->Update(primvertex);\r
856         }       \r
857       }\r
858       continue;\r
859     }\r
860     AliITStrackerMI::CorrectForTPCtoITSDeadZoneMaterial(&tpc0);\r
861     AliITStrackerMI::CorrectForTPCtoITSDeadZoneMaterial(&tpc1);    \r
862     //    if (tpc0.Propagate(alpha,v0mi->GetRr())&&tpc1.Propagate(alpha,v0mi->GetRr())){\r
863     if (tracker->RefitAt(v0mi->GetRr(),&tpc0, v0mi->GetClusters(0)) && \r
864         tracker->RefitAt(v0mi->GetRr(),&tpc1, v0mi->GetClusters(1))){\r
865       v0temp.SetParamN(tpc0);\r
866       v0temp.SetParamP(tpc1);\r
867       v0temp.Update(primvertex);\r
868       if (kFALSE) cstream<<"Refit"<<\r
869         "V0.="<<v0mi<<\r
870         "V0refit.="<<&v0temp<<\r
871         "Tr0.="<<&tpc0<<\r
872         "Tr1.="<<&tpc1<<\r
873         "\n";\r
874       //Bo:      if (v0temp.GetDist2()<v0mi->GetDist2() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){\r
875       if (v0temp.GetDcaV0Daughters()<v0mi->GetDcaV0Daughters() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){\r
876         v0mi->SetParamN(tpc0);\r
877         v0mi->SetParamP(tpc1);\r
878         v0mi->Update(primvertex);\r
879       } \r
880     }    \r
881   }\r
882 }\r
883 //------------------------------------------------------------------------\r