TRD nSigma OADB related new codes and modifications and OADB root file -- Xianguo Lu
[u/mrichter/AliRoot.git] / ITS / AliITSV0Finder.cxx
1 /**************************************************************************
2  * Copyright(c) 2007-2009, 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 /* $Id$ */
16
17 //-------------------------------------------------------------------------
18 //      Implementation of the on-the-fly v0 finder for ITS tracker MI
19 //          Origin: Marian Ivanov, CERN, Marian.Ivanov@cern.ch 
20 //          Extraction from AliITStrackerMI: Andrea Dainese
21 //          Current support and development: 
22 //-------------------------------------------------------------------------
23
24 #include <TMatrixD.h>
25 #include <TTree.h>
26 #include <TString.h>
27 #include <TRandom.h>
28 #include <TTreeStream.h>
29
30
31 #include "AliLog.h"
32 #include "AliESDVertex.h"
33 #include "AliESDEvent.h"
34 #include "AliESDtrack.h"
35 #include "AliESDV0Params.h"
36 #include "AliV0.h"
37 #include "AliHelix.h"
38 #include "AliITSRecPoint.h"
39 #include "AliITSReconstructor.h"
40 #include "AliITStrackerMI.h"
41 #include "AliITSV0Finder.h"
42 #include "AliKFParticle.h"
43 #include "AliKFVertex.h"
44
45 ClassImp(AliITSV0Finder)
46
47
48 AliITSV0Finder::AliITSV0Finder():
49 fDebugStreamer(0)
50  {
51   //Default constructor
52
53    if (AliITSReconstructor::GetRecoParam()->GetESDV0Params()->StreamLevel()>0)
54      fDebugStreamer = new TTreeSRedirector("ITSdebug.root");
55
56
57 //------------------------------------------------------------------------
58 void AliITSV0Finder::UpdateTPCV0(const AliESDEvent *event,
59                                    AliITStrackerMI *tracker)
60 {
61   //
62   //try to update, or reject TPC  V0s
63   //
64   const Float_t kMinTgl2= AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetMinTgl2();
65
66   TObjArray *trackHypothesys = tracker->GetTrackHypothesys();
67
68   Int_t nv0s = event->GetNumberOfV0s();
69   Int_t nitstracks = trackHypothesys->GetEntriesFast();
70
71   for (Int_t i=0;i<nv0s;i++){
72     AliESDv0 * vertex = event->GetV0(i);
73     Int_t ip = vertex->GetIndex(0);
74     Int_t im = vertex->GetIndex(1);
75     //
76     TObjArray * arrayp = (ip<nitstracks) ? (TObjArray*)trackHypothesys->At(ip):0;
77     TObjArray * arraym = (im<nitstracks) ? (TObjArray*)trackHypothesys->At(im):0;
78     AliITStrackMI * trackp = (arrayp!=0) ? (AliITStrackMI*)arrayp->At(0):0;
79     AliITStrackMI * trackm = (arraym!=0) ? (AliITStrackMI*)arraym->At(0):0;
80     //
81     //
82     if (trackp){
83       if (trackp->GetNumberOfClusters()+trackp->GetNDeadZone()>5.5){
84         if (trackp->GetConstrain()&&trackp->GetChi2MIP(0)<3) vertex->SetStatus(-100);
85         if (!trackp->GetConstrain()&&trackp->GetChi2MIP(0)<2) vertex->SetStatus(-100); 
86       }
87     }
88
89     if (trackm){
90       if (trackm->GetNumberOfClusters()+trackm->GetNDeadZone()>5.5){
91         if (trackm->GetConstrain()&&trackm->GetChi2MIP(0)<3) vertex->SetStatus(-100);
92         if (!trackm->GetConstrain()&&trackm->GetChi2MIP(0)<2) vertex->SetStatus(-100); 
93       }
94     }
95     if (vertex->GetStatus()==-100) continue;
96     //
97     Double_t xrp[3]; vertex->GetXYZ(xrp[0],xrp[1],xrp[2]);  //I.B.
98     Int_t clayer = tracker->GetNearestLayer(xrp);                    //I.B.
99     vertex->SetNBefore(clayer);        //
100     vertex->SetChi2Before(9*clayer);   //
101     vertex->SetNAfter(6-clayer);       //
102     vertex->SetChi2After(0);           //
103     //
104     if (clayer >1 ){ // calculate chi2 before vertex
105       Float_t chi2p = 0, chi2m=0;  
106       //
107       if (trackp){
108         for (Int_t ilayer=0;ilayer<clayer;ilayer++){
109           if (trackp->GetClIndex(ilayer)>=0){
110             chi2p+=trackp->GetDy(ilayer)*trackp->GetDy(ilayer)/(trackp->GetSigmaY(ilayer)*trackp->GetSigmaY(ilayer))+
111               trackp->GetDz(ilayer)*trackp->GetDz(ilayer)/(trackp->GetSigmaZ(ilayer)*trackp->GetSigmaZ(ilayer));
112           }
113           else{
114             chi2p+=9;
115           }
116         }
117       }else{
118         chi2p = 9*clayer;
119       }
120       //
121       if (trackm){
122         for (Int_t ilayer=0;ilayer<clayer;ilayer++){
123           if (trackm->GetClIndex(ilayer)>=0){
124             chi2m+=trackm->GetDy(ilayer)*trackm->GetDy(ilayer)/(trackm->GetSigmaY(ilayer)*trackm->GetSigmaY(ilayer))+
125               trackm->GetDz(ilayer)*trackm->GetDz(ilayer)/(trackm->GetSigmaZ(ilayer)*trackm->GetSigmaZ(ilayer));
126           }
127           else{
128             chi2m+=9;
129           }
130         }
131       }else{
132         chi2m = 9*clayer;
133       }
134       vertex->SetChi2Before(TMath::Min(chi2p,chi2m));
135       if (TMath::Min(chi2p,chi2m)/Float_t(clayer)<4) vertex->SetStatus(-10);  // track exist before vertex
136     }
137     
138     if (clayer < 5 ){ // calculate chi2 after vertex
139       Float_t chi2p = 0, chi2m=0;  
140       //
141       if (trackp&&TMath::Abs(trackp->GetTgl())<kMinTgl2){
142         for (Int_t ilayer=clayer;ilayer<6;ilayer++){
143           if (trackp->GetClIndex(ilayer)>=0){
144             chi2p+=trackp->GetDy(ilayer)*trackp->GetDy(ilayer)/(trackp->GetSigmaY(ilayer)*trackp->GetSigmaY(ilayer))+
145               trackp->GetDz(ilayer)*trackp->GetDz(ilayer)/(trackp->GetSigmaZ(ilayer)*trackp->GetSigmaZ(ilayer));
146           }
147           else{
148             chi2p+=9;
149           }
150         }
151       }else{
152         chi2p = 0;
153       }
154       //
155       if (trackm&&TMath::Abs(trackm->GetTgl())<kMinTgl2){
156         for (Int_t ilayer=clayer;ilayer<6;ilayer++){
157           if (trackm->GetClIndex(ilayer)>=0){
158             chi2m+=trackm->GetDy(ilayer)*trackm->GetDy(ilayer)/(trackm->GetSigmaY(ilayer)*trackm->GetSigmaY(ilayer))+
159               trackm->GetDz(ilayer)*trackm->GetDz(ilayer)/(trackm->GetSigmaZ(ilayer)*trackm->GetSigmaZ(ilayer));
160           }
161           else{
162             chi2m+=9;
163           }
164         }
165       }else{
166         chi2m = 0;
167       }
168       vertex->SetChi2After(TMath::Max(chi2p,chi2m));
169       if (TMath::Max(chi2m,chi2p)/Float_t(6-clayer)>9) vertex->SetStatus(-20);  // track not found in ITS
170     }
171   }
172   //
173 }
174 //------------------------------------------------------------------------
175 void AliITSV0Finder::FindV02(AliESDEvent *event,
176                                AliITStrackerMI *tracker) 
177 {
178   //
179   // V0 finder
180   //
181   //  Cuts on DCA -  R dependent
182   //          max distance DCA between 2 tracks cut 
183   //          maxDist = TMath::Min(kMaxDist,kMaxDist0+pvertex->GetRr()*kMaxDist);
184   //
185   const Bool_t kCheckPropagate = kFALSE;
186   const Float_t kMaxDist0 = AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetMaxDist0();
187   const Float_t kMaxDist1 = AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetMaxDist1();
188   const Float_t kMaxDist = AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetMaxDist();
189   const Float_t kMinPointAngle = AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetMinPointAngle();
190   const Float_t kMinPointAngle2 = AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetMinPointAngle2();
191   const Float_t kMinR = AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetMinR();
192   const Float_t kMaxR = AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetMaxR();
193   const Float_t kMinPABestConst = AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetMinPABestConst();
194   const Float_t kMaxRBestConst = AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetMaxRBestConst();
195   const Float_t kCausality0Cut = AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetCausality0Cut();
196   const Float_t kLikelihood01Cut = AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetLikelihood01Cut();
197   const Float_t kLikelihood1Cut = AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetLikelihood1Cut();
198   const Float_t kCombinedCut = AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetCombinedCut();
199   const Float_t kMinClFullTrk= AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetMinClFullTrk();
200   const Float_t kMinTgl0= AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetMinTgl0();
201   const Float_t kMinRTgl0= AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetMinRTgl0();
202
203   const Float_t kMinNormDistForbTgl0= AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetMinNormDistForbTgl0();
204   const Float_t kMinClForb0= AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetMinClForb0();
205   const Float_t kMinNormDistForb1= AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetMinNormDistForb1();
206   const Float_t kMinNormDistForb2= AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetMinNormDistForb2();
207   const Float_t kMinNormDistForb3= AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetMinNormDistForb3();
208   const Float_t kMinNormDistForb4= AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetMinNormDistForb4();
209   const Float_t kMinNormDistForb5= AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetMinNormDistForb5();
210   const Float_t kMinNormDistForbProt= AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetMinNormDistForbProt();
211   const Float_t kMaxPidProbPionForb= AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetMaxPidProbPionForb();
212
213   const Float_t kMinRTPCdensity= AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetMinRTPCdensity();
214   const Float_t kMaxRTPCdensity0= AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetMaxRTPCdensity0();
215   const Float_t kMaxRTPCdensity10= AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetMaxRTPCdensity10();
216   const Float_t kMaxRTPCdensity20= AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetMaxRTPCdensity20();
217   const Float_t kMaxRTPCdensity30= AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetMaxRTPCdensity30();
218
219
220   const Float_t kMinTPCdensity= AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetMinTPCdensity();
221   const Float_t kMinTgl1= AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetMinTgl1();
222
223   const Float_t kMinchi2before0= AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetMinchi2before0();
224   const Float_t kMinchi2before1= AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetMinchi2before1();
225   const Float_t kMinchi2after0= AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetMinchi2after0();
226   const Float_t kMinchi2after1= AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetMinchi2after1();
227   const Float_t kAddchi2SharedCl= AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetAddchi2SharedCl();
228   const Float_t kAddchi2NegCl0= AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetAddchi2NegCl0();
229   const Float_t kAddchi2NegCl1= AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetAddchi2NegCl1();
230
231   const Float_t kSigp0Par0= AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetSigp0Par0();
232   const Float_t kSigp0Par1= AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetSigp0Par1();
233   const Float_t kSigp0Par2= AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetSigp0Par2();
234
235   const Float_t kSigpPar0= AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetSigpPar0();
236   const Float_t kSigpPar1= AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetSigpPar1();
237   const Float_t kSigpPar2= AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetSigpPar2();
238   const Float_t kMaxDcaLh0= AliITSReconstructor::GetRecoParam()->GetESDV0Params()->GetMaxDcaLh0();
239
240
241   TObjArray *trackHypothesys = tracker->GetTrackHypothesys();
242   TObjArray *bestHypothesys  = tracker->GetBestHypothesys();
243   TObjArray *originalTracks  = tracker->GetOriginal();
244   //
245   //
246   TTreeSRedirector &cstream = *(tracker->GetDebugStreamer());
247   Int_t ntracks    = event->GetNumberOfTracks(); 
248   Int_t nitstracks = originalTracks->GetEntriesFast();
249   originalTracks->Expand(ntracks);
250   trackHypothesys->Expand(ntracks);
251   bestHypothesys->Expand(ntracks);
252   //
253   AliHelix * helixes   = new AliHelix[ntracks+2];
254   TObjArray trackarray(ntracks+2);     //array with tracks - with vertex constrain
255   TObjArray trackarrayc(ntracks+2);    //array of "best    tracks" - without vertex constrain
256   TObjArray trackarrayl(ntracks+2);    //array of "longest tracks" - without vertex constrain
257   //Change from Bool_t to Int_t for optimization
258   //  Int_t forbN=0;
259   //  Int_t * forbidden   = new Int_t [ntracks+2];
260   Bool_t * forbidden   = new Bool_t [ntracks+2];
261   Int_t   *itsmap      = new Int_t  [ntracks+2];
262   Float_t *dist        = new Float_t[ntracks+2];
263   Float_t *normdist0   = new Float_t[ntracks+2];
264   Float_t *normdist1   = new Float_t[ntracks+2];
265   Float_t *normdist    = new Float_t[ntracks+2];
266   Float_t *norm        = new Float_t[ntracks+2];
267   Float_t *maxr        = new Float_t[ntracks+2];
268   Float_t *minr        = new Float_t[ntracks+2];
269   Float_t *minPointAngle= new Float_t[ntracks+2];
270   //
271   AliV0 *pvertex      = new AliV0;
272   AliITStrackMI * dummy= new AliITStrackMI;
273   dummy->SetLabel(0);
274   AliITStrackMI  trackat0;    //temporary track for DCA calculation
275   //
276   Float_t primvertex[3]={static_cast<Float_t>(tracker->GetX()),static_cast<Float_t>(tracker->GetY()),static_cast<Float_t>(tracker->GetZ())};
277   //
278   // make ITS -  ESD map
279   //
280   for (Int_t itrack=0;itrack<ntracks+2;itrack++) {
281     itsmap[itrack]        = -1;
282     //    forbidden[itrack]     = 0;
283     forbidden[itrack]     = kFALSE;
284     maxr[itrack]          = kMaxR;
285     minr[itrack]          = kMinR;
286     minPointAngle[itrack] = kMinPointAngle;
287   }
288   for (Int_t itrack=0;itrack<nitstracks;itrack++){
289     AliITStrackMI * original =   (AliITStrackMI*)(originalTracks->At(itrack));
290     Int_t           esdindex =   original->GetESDtrack()->GetID();
291     itsmap[esdindex]         =   itrack;
292   }
293   //
294   // create ITS tracks from ESD tracks if not done before
295   //
296   for (Int_t itrack=0;itrack<ntracks;itrack++){
297     if (itsmap[itrack]>=0) continue;
298     AliITStrackMI * tpctrack = new AliITStrackMI(*(event->GetTrack(itrack)));
299     //tpctrack->fD[0] = tpctrack->GetD(GetX(),GetY());
300     //tpctrack->fD[1] = tpctrack->GetZat(GetX())-GetZ(); 
301     tpctrack->GetDZ(tracker->GetX(),tracker->GetY(),tracker->GetZ(),tpctrack->GetDP());   //I.B.
302     if (tpctrack->GetD(0)<20 && tpctrack->GetD(1)<20){
303       // tracks which can reach inner part of ITS
304       // propagate track to outer its volume - with correction for material
305       AliITStrackerMI::CorrectForTPCtoITSDeadZoneMaterial(tpctrack);  
306     }
307     itsmap[itrack] = nitstracks;
308     originalTracks->AddAt(tpctrack,nitstracks);
309     nitstracks++;
310   }
311   //
312   // fill temporary arrays
313   //
314   for (Int_t itrack=0;itrack<ntracks;itrack++){
315     AliESDtrack *  esdtrack = event->GetTrack(itrack);
316     Int_t          itsindex = itsmap[itrack];
317     AliITStrackMI *original = (AliITStrackMI*)originalTracks->At(itsmap[itrack]);
318     if (!original) continue;
319     AliITStrackMI *bestConst  = 0;
320     AliITStrackMI *bestLong   = 0;
321     AliITStrackMI *best       = 0;    
322     //
323     //
324     TObjArray * array    = (TObjArray*)  trackHypothesys->At(itsindex);
325     Int_t       hentries = (array==0) ?  0 : array->GetEntriesFast();
326     // Get best track with vertex constrain
327     for (Int_t ih=0;ih<hentries;ih++){
328       AliITStrackMI * trackh = (AliITStrackMI*)array->At(ih);
329       if (!trackh->GetConstrain()) continue;
330       if (!bestConst) bestConst = trackh;
331       if (trackh->GetNumberOfClusters()>kMinClFullTrk ){
332         bestConst  = trackh;                         // full track -  with minimal chi2
333         break;
334       }
335       if (trackh->GetNumberOfClusters()+trackh->GetNDeadZone()<=bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone())  continue;      
336       bestConst = trackh;
337       break;
338     }
339     // Get best long track without vertex constrain and best track without vertex constrain
340     for (Int_t ih=0;ih<hentries;ih++){
341       AliITStrackMI * trackh = (AliITStrackMI*)array->At(ih);
342       if (trackh->GetConstrain()) continue;
343       if (!best)     best     = trackh;
344       if (!bestLong) bestLong = trackh;
345       if (trackh->GetNumberOfClusters()>kMinClFullTrk){
346         bestLong  = trackh;                         // full track -  with minimal chi2
347         break;
348       }
349       if (trackh->GetNumberOfClusters()+trackh->GetNDeadZone()<=bestLong->GetNumberOfClusters()+bestLong->GetNDeadZone())  continue;      
350       bestLong = trackh;        
351     }
352     if (!best) {
353       best     = original;
354       bestLong = original;
355     }
356     //I.B. trackat0 = *bestLong;
357     new (&trackat0) AliITStrackMI(*bestLong);
358     Double_t xx,yy,zz,alpha; 
359     if (!bestLong->GetGlobalXYZat(bestLong->GetX(),xx,yy,zz)) continue;
360     
361
362     alpha = TMath::ATan2(yy,xx);    
363     //    if (!trackat0.Propagate(alpha,0)) continue;    
364     //    trackat0.Propagate(alpha,0); //PH The check on the return value is temporarily disabled (bug 45751) 
365     if(!trackat0.Propagate(alpha,0) && kCheckPropagate)continue;
366     // calculate normalized distances to the vertex 
367     //
368     Float_t ptfac  = (1.+100.*TMath::Abs(trackat0.GetC()));
369     if ( bestLong->GetNumberOfClusters()>3 ){      
370       dist[itsindex]      = trackat0.GetY();
371       norm[itsindex]      = ptfac*TMath::Sqrt(trackat0.GetSigmaY2());
372       normdist0[itsindex] = TMath::Abs(trackat0.GetY()/norm[itsindex]);
373       normdist1[itsindex] = TMath::Abs((trackat0.GetZ()-primvertex[2])/(ptfac*TMath::Sqrt(trackat0.GetSigmaZ2())));
374       normdist[itsindex]  = TMath::Sqrt(normdist0[itsindex]*normdist0[itsindex]+normdist1[itsindex]*normdist1[itsindex]);
375       if (!bestConst){
376         if (bestLong->GetNumberOfClusters()+bestLong->GetNDeadZone()<6) normdist[itsindex]*=2.;
377         if (bestLong->GetNumberOfClusters()+bestLong->GetNDeadZone()<5) normdist[itsindex]*=2.;
378         if (bestLong->GetNumberOfClusters()+bestLong->GetNDeadZone()<4) normdist[itsindex]*=2.;
379       }else{
380         if (bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()<6) normdist[itsindex]*=1.5;
381         if (bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()<5) normdist[itsindex]*=1.5;
382       }
383     }
384     else{      
385       if (bestConst&&bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()>4.5){
386         dist[itsindex] = bestConst->GetD(0);
387         norm[itsindex] = bestConst->GetDnorm(0);
388         normdist0[itsindex] = TMath::Abs(bestConst->GetD(0)/norm[itsindex]);
389         normdist1[itsindex] = TMath::Abs(bestConst->GetD(0)/norm[itsindex]);
390         normdist[itsindex]  = TMath::Sqrt(normdist0[itsindex]*normdist0[itsindex]+normdist1[itsindex]*normdist1[itsindex]);
391       }else{
392         dist[itsindex]      = trackat0.GetY();
393         norm[itsindex]      = ptfac*TMath::Sqrt(trackat0.GetSigmaY2());
394         normdist0[itsindex] = TMath::Abs(trackat0.GetY()/norm[itsindex]);
395         normdist1[itsindex] = TMath::Abs((trackat0.GetZ()-primvertex[2])/(ptfac*TMath::Sqrt(trackat0.GetSigmaZ2())));
396         normdist[itsindex]  = TMath::Sqrt(normdist0[itsindex]*normdist0[itsindex]+normdist1[itsindex]*normdist1[itsindex]);
397         if (TMath::Abs(trackat0.GetTgl())>kMinTgl0){
398           if (normdist[itsindex]<kMinNormDistForbTgl0){
399             //      forbN=1;
400             //      forbidden[itsindex]+=1<<forbN;
401             forbidden[itsindex]=kTRUE;
402           }
403           if (normdist[itsindex]>kMinNormDistForbTgl0) {
404             minr[itsindex] = TMath::Max(kMinRTgl0,minr[itsindex]);
405           }
406         }
407       }
408     }
409
410
411     //
412     //-----------------------------------------------------------
413     //Forbid primary track candidates - 
414     //
415     //treetr->SetAlias("forbidden0","Tr0.fN<4&&Tr1.fN+Tr1.fNDeadZone>4.5");
416     //treetr->SetAlias("forbidden1","ND<3&&Tr1.fN+Tr1.fNDeadZone>5.5");
417     //treetr->SetAlias("forbidden2","ND<2&&Tr1.fClIndex[0]>0&&Tr1.fClIndex[0]>0");
418     //treetr->SetAlias("forbidden3","ND<1&&Tr1.fClIndex[0]>0");
419     //treetr->SetAlias("forbidden4","ND<4&&Tr1.fNormChi2[0]<2");
420     //treetr->SetAlias("forbidden5","ND<5&&Tr1.fNormChi2[0]<1");
421     //-----------------------------------------------------------
422     if (bestConst){
423       if (bestLong->GetNumberOfClusters()<4 && bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()>kMinClForb0){
424         //      forbN=2;
425         //      forbidden[itsindex]+=1<<forbN;
426         forbidden[itsindex]=kTRUE;
427       }
428       if (normdist[itsindex]<kMinNormDistForb1 && bestConst->GetNumberOfClusters()+bestConst->GetNDeadZone()>5.5){
429         //      forbN=3;
430         //      forbidden[itsindex]+=1<<forbN;
431         forbidden[itsindex]=kTRUE;
432       }
433       if (normdist[itsindex]<kMinNormDistForb2 && bestConst->GetClIndex(0)>=0 && bestConst->GetClIndex(1)>=0 ){
434         //      forbN=4;
435         //      forbidden[itsindex]+=1<<forbN;
436         forbidden[itsindex]=kTRUE;
437       }
438       if (normdist[itsindex]<kMinNormDistForb3 && bestConst->GetClIndex(0)>=0){
439         //      forbN=5;
440         //      forbidden[itsindex]+=1<<forbN;
441         forbidden[itsindex]=kTRUE;
442       }
443       if (normdist[itsindex]<kMinNormDistForb4 && bestConst->GetNormChi2(0)<2){
444         //      forbN=6;
445         //      forbidden[itsindex]+=1<<forbN;
446         forbidden[itsindex]=kTRUE;
447       }
448       if (normdist[itsindex]<kMinNormDistForb5 && bestConst->GetNormChi2(0)<1){
449         //      forbN=7;
450         //      forbidden[itsindex]+=1<<forbN;
451         forbidden[itsindex]=kTRUE;
452       }
453       if (bestConst->GetNormChi2(0)<2.5) {
454         minPointAngle[itsindex]= kMinPABestConst;
455         maxr[itsindex]         = kMaxRBestConst;
456       }
457     }
458     //
459     //forbid daughter kink candidates
460     //
461     if (esdtrack->GetKinkIndex(0)>0) forbidden[itsindex] = kTRUE;
462     Bool_t isElectron = kTRUE;
463     Bool_t isProton   = kTRUE;
464     Double_t pid[5];
465     esdtrack->GetESDpid(pid);
466     for (Int_t i=1;i<5;i++){
467       if (pid[0]<pid[i]) isElectron= kFALSE;
468       if (pid[4]<pid[i]) isProton= kFALSE;
469     }
470     if (isElectron){
471       forbidden[itsindex]=kFALSE;       
472       normdist[itsindex]*=-1;
473     }
474     if (isProton){
475       if (normdist[itsindex]>kMinNormDistForbProt) forbidden[itsindex]=kFALSE;  
476       normdist[itsindex]*=-1;
477     }
478
479     // We allow all tracks that are not pions
480     if( (pid[1]+pid[2])< kMaxPidProbPionForb ){
481       forbidden[itsindex]=kFALSE;
482     }
483
484     //
485     // Causality cuts in TPC volume
486     //
487     if (esdtrack->GetTPCdensity(0,10) >kMinTPCdensity)  maxr[itsindex] = TMath::Min(Float_t(kMaxRTPCdensity0),maxr[itsindex]);
488     if (esdtrack->GetTPCdensity(10,30)>kMinTPCdensity)  maxr[itsindex] = TMath::Min(Float_t(kMaxRTPCdensity10),maxr[itsindex]);
489     if (esdtrack->GetTPCdensity(20,40)>kMinTPCdensity)  maxr[itsindex] = TMath::Min(Float_t(kMaxRTPCdensity20),maxr[itsindex]);
490     if (esdtrack->GetTPCdensity(30,50)>kMinTPCdensity)  maxr[itsindex] = TMath::Min(Float_t(kMaxRTPCdensity30),maxr[itsindex]);
491     //
492     if (esdtrack->GetTPCdensity(0,60)<0.4&&bestLong->GetNumberOfClusters()<3) minr[itsindex]=kMinRTPCdensity;    
493     //
494     //
495
496     if (AliITSReconstructor::GetRecoParam()->GetESDV0Params()->StreamLevel()>0){
497       cstream<<"Track"<<
498         "Tr0.="<<best<<
499         "Tr1.="<<((bestConst)? bestConst:dummy)<<
500         "Tr2.="<<bestLong<<
501         "Tr3.="<<&trackat0<<
502         "Esd.="<<esdtrack<<
503         "Dist="<<dist[itsindex]<<
504         "ND0="<<normdist0[itsindex]<<
505         "ND1="<<normdist1[itsindex]<<
506         "ND="<<normdist[itsindex]<<
507         "Pz="<<primvertex[2]<<
508         "Forbid="<<forbidden[itsindex]<<
509         "\n";
510       //
511     }
512     trackarray.AddAt(best,itsindex);
513     trackarrayc.AddAt(bestConst,itsindex);
514     trackarrayl.AddAt(bestLong,itsindex);
515     new (&helixes[itsindex]) AliHelix(*best);
516   }
517   //
518   //
519   //
520   // first iterration of V0 finder
521   //
522   // AM Comment out for optimization
523   //  Int_t rejectBase=0;
524   //  Int_t cutN=0;
525
526   for (Int_t iesd0=0;iesd0<ntracks;iesd0++){
527     Int_t itrack0 = itsmap[iesd0];
528     //-AM comment for optimization and store the forbidden value in the debug streamer
529     if (forbidden[itrack0]) continue;
530     AliITStrackMI * btrack0 = (AliITStrackMI*)trackarray.At(itrack0);
531     if (!btrack0) continue;    
532     AliITStrackMI *trackc0 = (AliITStrackMI*)trackarrayc.At(itrack0);
533     //
534     for (Int_t iesd1=iesd0+1;iesd1<ntracks;iesd1++){
535       Int_t itrack1 = itsmap[iesd1];
536       //-AM comment for optimization and store the forbidden value in the debug streamer
537       if (forbidden[itrack1]) continue;
538
539       AliITStrackMI * btrack1 = (AliITStrackMI*)trackarray.At(itrack1); 
540       if (!btrack1) continue;
541
542       if ( (btrack0->GetSign()==btrack1->GetSign()) && !AliITSReconstructor::GetRecoParam()->GetStoreLikeSignV0s()) continue;
543
544       Bool_t isGold = kFALSE;
545       if (TMath::Abs(TMath::Abs(btrack0->GetLabel())-TMath::Abs(btrack1->GetLabel()))==1){
546         isGold = kTRUE;
547       }
548       //      rejectBase=0;
549       AliITStrackMI *trackc1 = (AliITStrackMI*)trackarrayc.At(itrack1);
550       AliHelix &h1 = helixes[itrack0];
551       AliHelix &h2 = helixes[itrack1];
552       //
553       // find linear distance
554       Double_t rmin =0;
555       //
556       //
557       //
558       Double_t phase[2][2]={{0.,0.},{0.,0.}};
559       Double_t radius[2]={0.,0.};
560       Int_t  points = h1.GetRPHIintersections(h2, phase, radius);
561       if    (points==0) {
562         //      cutN=1;
563         //      rejectBase+=1<<cutN;
564         continue;
565       }
566       Double_t delta[2]={1000000,1000000};        
567       rmin = radius[0];
568       h1.ParabolicDCA(h2,phase[0][0],phase[0][1],radius[0],delta[0]);
569       if (points==2){    
570         if (radius[1]<rmin) rmin = radius[1];
571         h1.ParabolicDCA(h2,phase[1][0],phase[1][1],radius[1],delta[1]);
572       }
573       rmin = TMath::Sqrt(rmin);
574       Double_t distance = 0;
575       Double_t radiusC  = 0;
576       Int_t    iphase   = 0;
577       if (points==1 || delta[0]<delta[1]){
578         distance = TMath::Sqrt(delta[0]);
579         radiusC  = TMath::Sqrt(radius[0]);
580       }else{
581         distance = TMath::Sqrt(delta[1]);
582         radiusC  = TMath::Sqrt(radius[1]);
583         iphase=1;
584       }
585       if (radiusC<TMath::Max(minr[itrack0],minr[itrack1])){
586         //      cutN=2;
587         //rejectBase+=1<<cutN;
588         continue;
589       }
590       if (radiusC>TMath::Min(maxr[itrack0],maxr[itrack1])){
591         //      cutN=3;
592         //      rejectBase+=1<<cutN;
593         continue;
594       } 
595       Float_t maxDist  = TMath::Min(kMaxDist,Float_t(kMaxDist0+radiusC*kMaxDist1));      
596       if (distance>maxDist){
597         //      cutN=4;
598         //      rejectBase+=1<<cutN;
599         continue;
600       }
601       Float_t pointAngle = h1.GetPointAngle(h2,phase[iphase],primvertex);
602       if (pointAngle<TMath::Max(minPointAngle[itrack0],minPointAngle[itrack1])) {
603         //      cutN=5;
604         //      rejectBase+=1<<cutN;
605         continue;
606       }
607       //
608       //
609       //      Double_t distance = TestV0(h1,h2,pvertex,rmin);
610       //
611       //       if (distance>maxDist)           continue;
612       //       if (pvertex->GetRr()<kMinR)     continue;
613       //       if (pvertex->GetRr()>kMaxR)     continue;
614       AliITStrackMI * track0=btrack0;
615       AliITStrackMI * track1=btrack1;
616       //      if (pvertex->GetRr()<3.5){  
617       if (radiusC<3.5){  
618         //use longest tracks inside the pipe
619         track0 = (AliITStrackMI*)trackarrayl.At(itrack0);
620         track1 = (AliITStrackMI*)trackarrayl.At(itrack1);
621       }      
622       //
623       //
624       
625
626  
627       pvertex->SetParamN(*track0);
628       pvertex->SetParamP(*track1);
629       pvertex->Update(primvertex);
630       pvertex->SetClusters(track0->ClIndex(),track1->ClIndex());  // register clusters
631
632       // Define gamma, K0, lambda and lambda_bar from the decay particles and calculate the chi2      
633       AliKFVertex vertexKF;
634
635       vertexKF.X() = tracker->GetX();
636       vertexKF.Y() = tracker->GetY();
637       vertexKF.Z() = tracker->GetZ();
638       vertexKF.Covariance(0,0) = tracker->GetSigmaX()*tracker->GetSigmaX();
639       vertexKF.Covariance(1,2) = tracker->GetSigmaY()*tracker->GetSigmaY();
640       vertexKF.Covariance(2,2) = tracker->GetSigmaZ()*tracker->GetSigmaZ();
641       
642       AliKFParticle elecKF( *(pvertex->GetParamN()) ,11);
643       AliKFParticle posiKF( *(pvertex->GetParamP()) ,-11);
644       AliKFParticle pipKF( *(pvertex->GetParamN()) , 211);
645       AliKFParticle pinKF( *(pvertex->GetParamP()) ,-211);
646       AliKFParticle protKF( *(pvertex->GetParamP()) ,2212);
647       AliKFParticle aproKF ( *(pvertex->GetParamN()) ,-2212);
648
649
650       // Gamma
651       AliKFParticle gamKF(elecKF,posiKF);
652       gamKF.SetProductionVertex(vertexKF);
653
654       Float_t gamKFchi2 = 1000;
655       if ( gamKF.GetNDF()!=0 ){
656         gamKFchi2 = gamKF.GetChi2()/gamKF.GetNDF();
657       }
658
659       Float_t massG=0.;
660       Float_t sigmaMG=0.001;
661       gamKF.SetMassConstraint(massG,sigmaMG);
662
663       Float_t gamKFchi2C = 1000;
664       if ( gamKF.GetNDF()!=0 ){
665         gamKFchi2C = gamKF.GetChi2()/gamKF.GetNDF();
666       }
667
668       //K0 short
669       AliKFParticle k0KF(pipKF,pinKF);
670       k0KF.SetProductionVertex(vertexKF);
671
672       Float_t k0KFchi2 = 1000;
673       if ( k0KF.GetNDF()!=0 ){
674         k0KFchi2 = k0KF.GetChi2()/k0KF.GetNDF();
675       }
676
677       //Lambda
678       AliKFParticle lambdaKF(protKF,pinKF);
679       lambdaKF.SetProductionVertex(vertexKF);
680
681       Float_t lambdaKFchi2 = 1000;
682       if ( lambdaKF.GetNDF()!=0 ){
683         lambdaKFchi2 = lambdaKF.GetChi2()/lambdaKF.GetNDF();
684       }
685
686       //Lambda_bar
687       AliKFParticle alambKF(aproKF,pipKF);
688       alambKF.SetProductionVertex(vertexKF);
689
690       Float_t alambKFchi2 = 1000;
691       if ( alambKF.GetNDF()!=0 ){
692         alambKFchi2 = alambKF.GetChi2()/alambKF.GetNDF();
693       }
694
695
696
697
698
699       if (pvertex->GetRr()<kMinR){
700         //      cutN=6;
701         //      rejectBase+=1<<cutN;
702         continue;
703       }
704       if (pvertex->GetRr()>kMaxR){
705         //      cutN=7;
706         //      rejectBase+=1<<cutN;
707         continue;
708       }
709       if (pvertex->GetV0CosineOfPointingAngle()<kMinPointAngle){
710         //      cutN=8;
711         //      rejectBase+=1<<cutN;
712         continue;
713       }
714 //Bo:      if (pvertex->GetDist2()>maxDist) continue;
715
716       if (pvertex->GetDcaV0Daughters()>maxDist){
717         //      cutN=9;
718         //      rejectBase+=1<<cutN;
719         continue;
720       }
721 //Bo:        pvertex->SetLab(0,track0->GetLabel());
722 //Bo:        pvertex->SetLab(1,track1->GetLabel());
723       pvertex->SetIndex(0,track0->GetESDtrack()->GetID());
724       pvertex->SetIndex(1,track1->GetESDtrack()->GetID());
725       //      
726       AliITStrackMI * htrackc0 = trackc0 ? trackc0:dummy;      
727       AliITStrackMI * htrackc1 = trackc1 ? trackc1:dummy;
728
729       //
730       //
731       TObjArray * array0b     = (TObjArray*)bestHypothesys->At(itrack0);
732       if (!array0b&&pvertex->GetRr()<40 && TMath::Abs(track0->GetTgl())<kMinTgl1) {
733         tracker->SetCurrentEsdTrack(itrack0);
734         tracker->FollowProlongationTree((AliITStrackMI*)originalTracks->At(itrack0),itrack0, kFALSE);
735       }
736       TObjArray * array1b    = (TObjArray*)bestHypothesys->At(itrack1);
737       if (!array1b&&pvertex->GetRr()<40 && TMath::Abs(track1->GetTgl())<kMinTgl1) { 
738         tracker->SetCurrentEsdTrack(itrack1);
739         tracker->FollowProlongationTree((AliITStrackMI*)originalTracks->At(itrack1),itrack1, kFALSE);
740       }
741       //
742       AliITStrackMI * track0b = (AliITStrackMI*)originalTracks->At(itrack0);
743       AliITStrackMI * track1b = (AliITStrackMI*)originalTracks->At(itrack1);
744       AliITStrackMI * track0l = (AliITStrackMI*)originalTracks->At(itrack0);
745       AliITStrackMI * track1l = (AliITStrackMI*)originalTracks->At(itrack1);
746       
747       Float_t minchi2before0=kMinchi2before0;
748       Float_t minchi2before1=kMinchi2before1;
749       Float_t minchi2after0 =kMinchi2after0;
750       Float_t minchi2after1 =kMinchi2after1;
751       Double_t xrp[3]; pvertex->GetXYZ(xrp[0],xrp[1],xrp[2]);  //I.B.
752       Int_t maxLayer = tracker->GetNearestLayer(xrp);                   //I.B.
753       
754       if (array0b) for (Int_t i=0;i<5;i++){
755         // best track after vertex
756         AliITStrackMI * btrack = (AliITStrackMI*)array0b->At(i);
757         if (!btrack) continue;
758         if (btrack->GetNumberOfClusters()>track0l->GetNumberOfClusters()) track0l = btrack;     
759         //      if (btrack->fX<pvertex->GetRr()-2.-0.5/(0.1+pvertex->GetAnglep()[2])) {
760         if (btrack->GetX()<pvertex->GetRr()-2.) {
761           if ( (maxLayer>i+2|| (i==0)) && btrack->GetNumberOfClusters()==(6-i)&&i<3){
762             Float_t sumchi2= 0;
763             Float_t sumn   = 0;
764             if (maxLayer<3){   // take prim vertex as additional measurement
765               if (normdist[itrack0]>0 && htrackc0){
766                 sumchi2 += TMath::Min((3.-maxLayer)*normdist[itrack0]*normdist[itrack0],16.);
767               }else{
768                 sumchi2 +=  TMath::Min((3.-maxLayer)*(3*normdist[itrack0]*normdist[itrack0]+3.),16.);
769               }
770               sumn    +=  3-maxLayer;
771             }
772             for (Int_t ilayer=i;ilayer<maxLayer;ilayer++){
773               sumn+=1.;       
774               if (btrack->GetClIndex(ilayer)<0){
775                 sumchi2+=kAddchi2NegCl0;
776                 continue;
777               }else{
778                 Int_t c=( btrack->GetClIndex(ilayer) & 0x0fffffff);
779                 for (Int_t itrack=0;itrack<4;itrack++){
780                   AliITStrackerMI::AliITSlayer &layer=tracker->GetLayer(ilayer);
781                   if (layer.GetClusterTracks(itrack,c)>=0 && layer.GetClusterTracks(itrack,c)!=itrack0){
782                     sumchi2+=kAddchi2SharedCl;  //shared cluster
783                     break;
784                   }
785                 }
786                 sumchi2+=btrack->GetDy(ilayer)*btrack->GetDy(ilayer)/(btrack->GetSigmaY(ilayer)*btrack->GetSigmaY(ilayer));
787                 sumchi2+=btrack->GetDz(ilayer)*btrack->GetDz(ilayer)/(btrack->GetSigmaZ(ilayer)*btrack->GetSigmaZ(ilayer));            
788               }
789             }
790             sumchi2/=sumn;
791             if (sumchi2<minchi2before0) minchi2before0=sumchi2; 
792           }
793           continue;   //safety space - Geo manager will give exact layer
794         }
795         track0b       = btrack;
796         minchi2after0 = btrack->GetNormChi2(i);
797         break;
798       }
799       if (array1b) for (Int_t i=0;i<5;i++){
800         // best track after vertex
801         AliITStrackMI * btrack = (AliITStrackMI*)array1b->At(i);
802         if (!btrack) continue;
803         if (btrack->GetNumberOfClusters()>track1l->GetNumberOfClusters()) track1l = btrack;     
804         //      if (btrack->fX<pvertex->GetRr()-2-0.5/(0.1+pvertex->GetAnglep()[2])){
805         if (btrack->GetX()<pvertex->GetRr()-2){
806           if ((maxLayer>i+2 || (i==0))&&btrack->GetNumberOfClusters()==(6-i)&&(i<3)){
807             Float_t sumchi2= 0;
808             Float_t sumn   = 0;
809             if (maxLayer<3){   // take prim vertex as additional measurement
810               if (normdist[itrack1]>0 && htrackc1){
811                 sumchi2 +=  TMath::Min((3.-maxLayer)*normdist[itrack1]*normdist[itrack1],16.);
812               }else{
813                 sumchi2 += TMath::Min((3.-maxLayer)*(3*normdist[itrack1]*normdist[itrack1]+3.),16.);
814               }
815               sumn    +=  3-maxLayer;
816             }
817             for (Int_t ilayer=i;ilayer<maxLayer;ilayer++){
818               sumn+=1.;
819               if (btrack->GetClIndex(ilayer)<0){
820                 sumchi2+=kAddchi2NegCl1;
821                 continue;
822               }else{
823                 Int_t c=( btrack->GetClIndex(ilayer) & 0x0fffffff);
824                 for (Int_t itrack=0;itrack<4;itrack++){
825                   AliITStrackerMI::AliITSlayer &layer=tracker->GetLayer(ilayer);
826                   if (layer.GetClusterTracks(itrack,c)>=0 && layer.GetClusterTracks(itrack,c)!=itrack1){
827                     sumchi2+=kAddchi2SharedCl;  //shared cluster
828                     break;
829                   }
830                 }
831                 sumchi2+=btrack->GetDy(ilayer)*btrack->GetDy(ilayer)/(btrack->GetSigmaY(ilayer)*btrack->GetSigmaY(ilayer));
832                 sumchi2+=btrack->GetDz(ilayer)*btrack->GetDz(ilayer)/(btrack->GetSigmaZ(ilayer)*btrack->GetSigmaZ(ilayer));            
833               }
834             }
835             sumchi2/=sumn;
836             if (sumchi2<minchi2before1) minchi2before1=sumchi2; 
837           }
838           continue;   //safety space - Geo manager will give exact layer           
839         }
840         track1b = btrack;
841         minchi2after1 = btrack->GetNormChi2(i);
842         break;
843       }
844       //
845       // position resolution - used for DCA cut
846       Float_t sigmad = track0b->GetSigmaY2()+track0b->GetSigmaZ2()+track1b->GetSigmaY2()+track1b->GetSigmaZ2()+
847         (track0b->GetX()-pvertex->GetRr())*(track0b->GetX()-pvertex->GetRr())*(track0b->GetSigmaSnp2()+track0b->GetSigmaTgl2())+
848         (track1b->GetX()-pvertex->GetRr())*(track1b->GetX()-pvertex->GetRr())*(track1b->GetSigmaSnp2()+track1b->GetSigmaTgl2());
849       sigmad =TMath::Sqrt(sigmad)+0.04;
850       if (pvertex->GetRr()>50){
851         Double_t cov0[15],cov1[15];
852         track0b->GetESDtrack()->GetInnerExternalCovariance(cov0);
853         track1b->GetESDtrack()->GetInnerExternalCovariance(cov1);
854         sigmad = cov0[0]+cov0[2]+cov1[0]+cov1[2]+
855           (80.-pvertex->GetRr())*(80.-pvertex->GetRr())*(cov0[5]+cov0[9])+
856           (80.-pvertex->GetRr())*(80.-pvertex->GetRr())*(cov1[5]+cov1[9]);
857         sigmad =TMath::Sqrt(sigmad)+0.05;
858       }
859       //       
860       AliV0 vertex2;
861       vertex2.SetParamN(*track0b);
862       vertex2.SetParamP(*track1b);
863       vertex2.Update(primvertex);
864       //Bo:      if (vertex2.GetDist2()<=pvertex->GetDist2()&&(vertex2.GetV0CosineOfPointingAngle()>=pvertex->GetV0CosineOfPointingAngle())){
865       if (vertex2.GetDcaV0Daughters()<=pvertex->GetDcaV0Daughters()&&(vertex2.GetV0CosineOfPointingAngle()>=pvertex->GetV0CosineOfPointingAngle())){
866         pvertex->SetParamN(*track0b);
867         pvertex->SetParamP(*track1b);
868         pvertex->Update(primvertex);
869         pvertex->SetClusters(track0b->ClIndex(),track1b->ClIndex());  // register clusters
870         pvertex->SetIndex(0,track0->GetESDtrack()->GetID());
871         pvertex->SetIndex(1,track1->GetESDtrack()->GetID());
872       }
873       pvertex->SetDistSigma(sigmad);
874       //Bo:      pvertex->SetDistNorm(pvertex->GetDist2()/sigmad);       
875       pvertex->SetNormDCAPrim(normdist[itrack0],normdist[itrack1]);
876       //
877       // define likelihhod and causalities
878       //
879       Float_t pa0=1, pa1=1, pb0=0.26, pb1=0.26;      
880       if (maxLayer<1){
881         Float_t fnorm0 = normdist[itrack0];
882         if (fnorm0<0) fnorm0*=-3;
883         Float_t fnorm1 = normdist[itrack1];
884         if (fnorm1<0) fnorm1*=-3;
885         if ((pvertex->GetAnglep()[2]>0.1) || ( (pvertex->GetRr()<10.5)&& pvertex->GetAnglep()[2]>0.05 ) || (pvertex->GetRr()<3)){
886           pb0    =  TMath::Exp(-TMath::Min(fnorm0,Float_t(16.))/12.);
887           pb1    =  TMath::Exp(-TMath::Min(fnorm1,Float_t(16.))/12.);
888         }
889         pvertex->SetChi2Before(normdist[itrack0]);
890         pvertex->SetChi2After(normdist[itrack1]);       
891         pvertex->SetNAfter(0);
892         pvertex->SetNBefore(0);
893       }else{
894         pvertex->SetChi2Before(minchi2before0);
895         pvertex->SetChi2After(minchi2before1);
896          if (pvertex->GetAnglep()[2]>0.1 || ( pvertex->GetRr()<10.5 && pvertex->GetAnglep()[2]>0.05) || pvertex->GetRr()<3){
897            pb0    =  TMath::Exp(-TMath::Min(minchi2before0,Float_t(16))/12.);
898            pb1    =  TMath::Exp(-TMath::Min(minchi2before1,Float_t(16))/12.);
899          }
900          pvertex->SetNAfter(maxLayer);
901          pvertex->SetNBefore(maxLayer);      
902       }
903       if (pvertex->GetRr()<90){
904         pa0  *= TMath::Min(track0->GetESDtrack()->GetTPCdensity(0,60),Double_t(1.));
905         pa1  *= TMath::Min(track1->GetESDtrack()->GetTPCdensity(0,60),Double_t(1.));
906       }
907       if (pvertex->GetRr()<20){
908         pa0  *= (0.2+TMath::Exp(-TMath::Min(minchi2after0,Float_t(16))/8.))/1.2;
909         pa1  *= (0.2+TMath::Exp(-TMath::Min(minchi2after1,Float_t(16))/8.))/1.2;
910       }
911       //
912       pvertex->SetCausality(pb0,pb1,pa0,pa1);
913       //
914       //  Likelihood calculations  - apply cuts
915       //         
916  
917       // AM - Comment out for optimization and store the v0OK value
918       //      Int_t v0OK = 0;
919       //      Int_t cutOKN=0;
920       Bool_t v0OK = kTRUE;
921
922
923       Float_t p12 = pvertex->GetParamP()->GetParameter()[4]*pvertex->GetParamP()->GetParameter()[4];
924       p12        += pvertex->GetParamN()->GetParameter()[4]*pvertex->GetParamN()->GetParameter()[4];
925       p12         = TMath::Sqrt(p12);                             // "mean" momenta
926
927       Float_t    sigmap0   = kSigp0Par0+kSigp0Par1/(kSigp0Par2+pvertex->GetRr()); 
928       Float_t    sigmap    = kSigpPar0*sigmap0*(kSigpPar1+kSigpPar2*p12);           // "resolution: of point angle - as a function of radius and momenta
929
930
931       Float_t causalityA  = (1.0-pvertex->GetCausalityP()[0])*(1.0-pvertex->GetCausalityP()[1]);
932       Float_t causalityB  = TMath::Sqrt(TMath::Min(pvertex->GetCausalityP()[2],Double_t(0.7))*
933                                         TMath::Min(pvertex->GetCausalityP()[3],Double_t(0.7)));
934       //
935       //Bo:      Float_t likelihood0 = (TMath::Exp(-pvertex->GetDistNorm())+0.1) *(pvertex->GetDist2()<0.5)*(pvertex->GetDistNorm()<5);
936       Float_t lDistNorm = pvertex->GetDcaV0Daughters()/pvertex->GetDistSigma();
937       Float_t likelihood0 = (TMath::Exp(-lDistNorm)+0.1) *(pvertex->GetDcaV0Daughters()<kMaxDcaLh0)*(lDistNorm<5);
938
939       Float_t likelihood1 = TMath::Exp(-(1.0001-pvertex->GetV0CosineOfPointingAngle())/sigmap)+
940         0.4*TMath::Exp(-(1.0001-pvertex->GetV0CosineOfPointingAngle())/(4.*sigmap))+
941         0.4*TMath::Exp(-(1.0001-pvertex->GetV0CosineOfPointingAngle())/(8.*sigmap))+
942         0.1*TMath::Exp(-(1.0001-pvertex->GetV0CosineOfPointingAngle())/0.01);
943       //
944       if (causalityA<kCausality0Cut){
945         //      cutOKN=1;
946         //      v0OK += 1<<cutOKN;
947         v0OK = kFALSE;
948       }
949       if (TMath::Sqrt(likelihood0*likelihood1)<kLikelihood01Cut){
950         //      cutOKN=2;
951         //      v0OK += 1<<cutOKN;
952         v0OK = kFALSE;
953       }
954       if (likelihood1<kLikelihood1Cut){
955         //      cutOKN=3;
956         //      v0OK += 1<<cutOKN;
957         v0OK = kFALSE;
958       }
959       if (TMath::Power(likelihood0*likelihood1*causalityB,0.33)<kCombinedCut){
960         //      cutOKN=4;
961         //      v0OK += 1<<cutOKN;
962         v0OK = kFALSE;
963       }
964       //
965       //
966       if (AliITSReconstructor::GetRecoParam()->GetESDV0Params()->StreamLevel()>0){      
967         Bool_t gold = TMath::Abs(TMath::Abs(track0->GetLabel())-TMath::Abs(track1->GetLabel()))==1;
968         cstream<<"It0"<<
969           "Tr0.="<<track0<<                       //best without constrain
970           "Tr1.="<<track1<<                       //best without constrain  
971           "posiKF.="<<&posiKF<<                       //KF from track0
972           "elecKF.="<<&elecKF<<                       //KF from track1
973           "Tr0B.="<<track0b<<                     //best without constrain  after vertex
974           "Tr1B.="<<track1b<<                     //best without constrain  after vertex 
975           "Tr0C.="<<htrackc0<<                    //best with constrain     if exist
976           "Tr1C.="<<htrackc1<<                    //best with constrain     if exist
977           "Tr0L.="<<track0l<<                     //longest best           
978           "Tr1L.="<<track1l<<                     //longest best
979           "Esd0.="<<track0->GetESDtrack()<<           // esd track0 params
980           "Esd1.="<<track1->GetESDtrack()<<           // esd track1 params
981           "V0.="<<pvertex<<                       //vertex properties
982           "V0b.="<<&vertex2<<                       //vertex properties at "best" track
983           "gamKF.="<<&gamKF<<                          //KF from pvertex
984           "k0KF.="<<&k0KF<<                          //KF from pvertex
985           "lambdaKF.="<<&lambdaKF<<                          //KF from pvertex
986           "alambKF.="<<&lambdaKF<<                          //KF from pvertex
987           "gamKFchi2="<<gamKFchi2<<    //Normalized chi2 from KF assuming gamma momther
988           "gamKFchi2C="<<gamKFchi2C<<    //Normalized chi2 from KF assuming gamma mother+mass constraint
989           "k0KFchi2="<<k0KFchi2<<    //Normalized chi2 from KF assuming K0 mother
990           "lambdaKFchi2="<<lambdaKFchi2<<    //Normalized chi2 from KF assuming Lambda mother
991           "alambKFchi2="<<alambKFchi2<<    //Normalized chi2 from KF assuming lambda_bar mother
992           "ND0="<<normdist[itrack0]<<             //normalize distance for track0
993           "ND1="<<normdist[itrack1]<<             //normalize distance for track1
994           "Gold="<<gold<<                         //
995           // "RejectBase="<<rejectBase<<             //rejection in First itteration
996           "OK="<<v0OK<<
997           "rmin="<<rmin<<
998           "sigmad="<<sigmad<<
999           "Forbid0="<<forbidden[itrack0]<<
1000           "Forbid1="<<forbidden[itrack1]<<
1001           "\n";
1002       }      
1003       //      if (rejectBase>0) continue;
1004       //if (forbidden[itrack0]>0 ||forbidden[itrack1]>0) continue; 
1005       //
1006       pvertex->SetStatus(0);
1007       //      if (rejectBase) {
1008       //        pvertex->SetStatus(-100);
1009       //}
1010       if (pvertex->GetV0CosineOfPointingAngle()>kMinPointAngle2) {
1011         //Bo:     pvertex->SetESDindexes(track0->GetESDtrack()->GetID(),track1->GetESDtrack()->GetID());
1012         pvertex->SetIndex(0,track0->GetESDtrack()->GetID());//Bo: consistency 0 for neg
1013         pvertex->SetIndex(1,track1->GetESDtrack()->GetID());//Bo: consistency 1 for pos
1014         //      if (v0OK==0){
1015         if (v0OK){
1016           //      AliV0vertex vertexjuri(*track0,*track1);
1017           //      vertexjuri.SetESDindexes(track0->fESDtrack->GetID(),track1->fESDtrack->GetID());
1018           //      event->AddV0(&vertexjuri);
1019           pvertex->SetStatus(100);
1020         }
1021         pvertex->SetOnFlyStatus(kTRUE);
1022         pvertex->ChangeMassHypothesis(kK0Short);
1023         event->AddV0(pvertex);
1024       }
1025     }
1026   }
1027   //
1028   //
1029   // delete temporary arrays
1030   //  
1031   delete[] forbidden;
1032   delete[] minPointAngle;
1033   delete[] maxr;
1034   delete[] minr;
1035   delete[] norm;
1036   delete[] normdist;
1037   delete[] normdist1;
1038   delete[] normdist0;
1039   delete[] dist;
1040   delete[] itsmap;
1041   delete[] helixes;
1042   delete   pvertex;
1043   delete   dummy;
1044 }
1045 //------------------------------------------------------------------------
1046 void AliITSV0Finder::RefitV02(const AliESDEvent *event,
1047                                 AliITStrackerMI *tracker) 
1048 {
1049   //
1050   //try to refit  V0s in the third path of the reconstruction
1051   //
1052   TTreeSRedirector &cstream = *(tracker->GetDebugStreamer());
1053   //
1054   Int_t  nv0s = event->GetNumberOfV0s();
1055   Float_t primvertex[3]={static_cast<Float_t>(tracker->GetX()),static_cast<Float_t>(tracker->GetY()),static_cast<Float_t>(tracker->GetZ())};
1056   AliV0 v0temp;
1057   for (Int_t iv0 = 0; iv0<nv0s;iv0++){
1058     AliV0 * v0mi = (AliV0*)event->GetV0(iv0);
1059     if (!v0mi) continue;
1060     Int_t     itrack0   = v0mi->GetIndex(0);
1061     Int_t     itrack1   = v0mi->GetIndex(1);
1062     AliESDtrack *esd0   = event->GetTrack(itrack0);
1063     AliESDtrack *esd1   = event->GetTrack(itrack1);
1064     if (!esd0||!esd1) continue;
1065     AliITStrackMI tpc0(*esd0);  
1066     AliITStrackMI tpc1(*esd1);
1067     Double_t x,y,z; v0mi->GetXYZ(x,y,z); //I.B. 
1068     Double_t alpha =TMath::ATan2(y,x);   //I.B.
1069     if (v0mi->GetRr()>85){
1070       if (tpc0.Propagate(alpha,v0mi->GetRr())&&tpc1.Propagate(alpha,v0mi->GetRr())){
1071         v0temp.SetParamN(tpc0);
1072         v0temp.SetParamP(tpc1);
1073         v0temp.Update(primvertex);
1074         if (AliITSReconstructor::GetRecoParam()->GetESDV0Params()->StreamLevel()>0) cstream<<"Refit"<<
1075           "V0.="<<v0mi<<
1076           "V0refit.="<<&v0temp<<
1077           "Tr0.="<<&tpc0<<
1078           "Tr1.="<<&tpc1<<
1079           "\n";
1080         //Bo:   if (v0temp.GetDist2()<v0mi->GetDist2() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
1081         if (v0temp.GetDcaV0Daughters()<v0mi->GetDcaV0Daughters() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
1082           v0mi->SetParamN(tpc0);
1083           v0mi->SetParamP(tpc1);
1084           v0mi->Update(primvertex);
1085         }
1086       }
1087       continue;
1088     }
1089     if (v0mi->GetRr()>35){
1090       AliITStrackerMI::CorrectForTPCtoITSDeadZoneMaterial(&tpc0);
1091       AliITStrackerMI::CorrectForTPCtoITSDeadZoneMaterial(&tpc1);
1092       if (tpc0.Propagate(alpha,v0mi->GetRr())&&tpc1.Propagate(alpha,v0mi->GetRr())){
1093         v0temp.SetParamN(tpc0);
1094         v0temp.SetParamP(tpc1);
1095         v0temp.Update(primvertex);
1096         if (AliITSReconstructor::GetRecoParam()->GetESDV0Params()->StreamLevel()>0) cstream<<"Refit"<<
1097           "V0.="<<v0mi<<
1098           "V0refit.="<<&v0temp<<
1099           "Tr0.="<<&tpc0<<
1100           "Tr1.="<<&tpc1<<
1101           "\n";
1102         //Bo:   if (v0temp.GetDist2()<v0mi->GetDist2() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
1103         if (v0temp.GetDcaV0Daughters()<v0mi->GetDcaV0Daughters() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
1104           v0mi->SetParamN(tpc0);
1105           v0mi->SetParamP(tpc1);
1106           v0mi->Update(primvertex);
1107         }       
1108       }
1109       continue;
1110     }
1111     AliITStrackerMI::CorrectForTPCtoITSDeadZoneMaterial(&tpc0);
1112     AliITStrackerMI::CorrectForTPCtoITSDeadZoneMaterial(&tpc1);    
1113     //    if (tpc0.Propagate(alpha,v0mi->GetRr())&&tpc1.Propagate(alpha,v0mi->GetRr())){
1114     if (tracker->RefitAt(v0mi->GetRr(),&tpc0, v0mi->GetClusters(0)) && 
1115         tracker->RefitAt(v0mi->GetRr(),&tpc1, v0mi->GetClusters(1))){
1116       v0temp.SetParamN(tpc0);
1117       v0temp.SetParamP(tpc1);
1118       v0temp.Update(primvertex);
1119       if (AliITSReconstructor::GetRecoParam()->GetESDV0Params()->StreamLevel()>0) cstream<<"Refit"<<
1120         "V0.="<<v0mi<<
1121         "V0refit.="<<&v0temp<<
1122         "Tr0.="<<&tpc0<<
1123         "Tr1.="<<&tpc1<<
1124         "\n";
1125       //Bo:      if (v0temp.GetDist2()<v0mi->GetDist2() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
1126       if (v0temp.GetDcaV0Daughters()<v0mi->GetDcaV0Daughters() || v0temp.GetV0CosineOfPointingAngle()>v0mi->GetV0CosineOfPointingAngle()){
1127         v0mi->SetParamN(tpc0);
1128         v0mi->SetParamP(tpc1);
1129         v0mi->Update(primvertex);
1130       } 
1131     }    
1132   }
1133 }
1134 //------------------------------------------------------------------------
1135
1136
1137 AliITSV0Finder::~AliITSV0Finder()
1138 {
1139   //
1140   //destructor
1141   //
1142   if (fDebugStreamer) {
1143     //fDebugStreamer->Close();
1144     delete fDebugStreamer;
1145   }
1146
1147 }