f27d88a092b318c91481012f02f974f376565d24
[u/mrichter/AliRoot.git] / STEER / AliCascadeVertexer.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 //-------------------------------------------------------------------------
17 //               Implementation of the cascade vertexer class
18 //          Reads V0s and tracks, writes out cascade vertices
19 //                     Fills the ESD with the cascades 
20 //    Origin: Christian Kuhn, IReS, Strasbourg, christian.kuhn@ires.in2p3.fr
21 //-------------------------------------------------------------------------
22
23 //modified by R. Vernet 30/6/2006 : daughter label
24 //modified by R. Vernet  3/7/2006 : causality
25
26
27 #include <TObjArray.h>
28 #include <TTree.h>
29
30 #include "AliESD.h"
31 #include "AliESDv0.h"
32 #include "AliESDcascade.h"
33 #include "AliCascadeVertexer.h"
34
35 ClassImp(AliCascadeVertexer)
36
37 Int_t AliCascadeVertexer::V0sTracks2CascadeVertices(AliESD *event) {
38   //--------------------------------------------------------------------
39   // This function reconstructs cascade vertices
40   //      Adapted to the ESD by I.Belikov (Jouri.Belikov@cern.ch)
41   //--------------------------------------------------------------------
42    Double_t b=event->GetMagneticField();
43    Int_t nV0=(Int_t)event->GetNumberOfV0s();
44
45    //stores relevant V0s in an array
46    TObjArray vtcs(nV0);
47    Int_t i;
48    for (i=0; i<nV0; i++) {
49        AliESDv0 *v=event->GetV0(i);
50        if (v->GetOnFlyStatus()) continue;
51        if (v->GetD(fX,fY,fZ)<fDV0min) continue;
52        vtcs.AddLast(v);
53    }
54    nV0=vtcs.GetEntriesFast();
55
56    // stores relevant tracks in another array
57    Int_t nentr=(Int_t)event->GetNumberOfTracks();
58    TArrayI trk(nentr); Int_t ntr=0;
59    for (i=0; i<nentr; i++) {
60        AliESDtrack *esdtr=event->GetTrack(i);
61        UInt_t status=esdtr->GetStatus();
62        UInt_t flags=AliESDtrack::kITSin|AliESDtrack::kTPCin|
63                     AliESDtrack::kTPCpid|AliESDtrack::kESDpid;
64
65        if ((status&AliESDtrack::kITSrefit)==0)
66           if (flags!=status) continue;
67
68        if (TMath::Abs(esdtr->GetD(fX,fY,b))<fDBachMin) continue;
69
70        trk[ntr++]=i;
71    }   
72
73    Double_t massLambda=1.11568;
74    Int_t ncasc=0;
75
76    // Looking for the cascades...
77
78    for (i=0; i<nV0; i++) { //loop on V0s
79
80       AliESDv0 *v=(AliESDv0*)vtcs.UncheckedAt(i);
81       v->ChangeMassHypothesis(kLambda0); // the v0 must be Lambda 
82       if (TMath::Abs(v->GetEffMass()-massLambda)>fMassWin) continue; 
83
84       for (Int_t j=0; j<ntr; j++) {//loop on tracks
85          Int_t bidx=trk[j];
86          if (bidx==v->GetNindex()) continue; //bachelor and v0's negative tracks must be different
87          AliESDtrack *btrk=event->GetTrack(bidx);
88          if (btrk->GetSign()>0) continue;  // bachelor's charge 
89           
90          AliESDv0 v0(*v), *pv0=&v0;
91          AliExternalTrackParam bt(*btrk), *pbt=&bt;
92
93          Double_t dca=PropagateToDCA(pv0,pbt,b);
94          if (dca > fDCAmax) continue;
95
96          AliESDcascade cascade(*pv0,*pbt,bidx);//constucts a cascade candidate
97          if (cascade.GetChi2Xi() > fChi2max) continue;
98
99          Double_t x,y,z; cascade.GetXYZ(x,y,z); 
100          Double_t r2=x*x + y*y; 
101          if (r2 > fRmax*fRmax) continue;   // condition on fiducial zone
102          if (r2 < fRmin*fRmin) continue;
103
104          Double_t pxV0,pyV0,pzV0;
105          pv0->GetPxPyPz(pxV0,pyV0,pzV0);
106          if (x*pxV0+y*pyV0+z*pzV0 < 0) continue; //causality
107
108          Double_t x1,y1,z1; pv0->GetXYZ(x1,y1,z1);
109          if (r2 > (x1*x1+y1*y1)) continue;
110
111          if (cascade.GetCascadeCosineOfPointingAngle(fX,fY,fZ) <fCPAmax) continue; //condition on the cascade pointing angle 
112          
113          event->AddCascade(&cascade);
114          ncasc++;
115       } // end loop tracks
116    } // end loop V0s
117
118    // Looking for the anti-cascades...
119
120    for (i=0; i<nV0; i++) { //loop on V0s
121       AliESDv0 *v=(AliESDv0*)vtcs.UncheckedAt(i);
122       v->ChangeMassHypothesis(kLambda0Bar); //the v0 must be anti-Lambda 
123       if (TMath::Abs(v->GetEffMass()-massLambda)>fMassWin) continue; 
124
125       for (Int_t j=0; j<ntr; j++) {//loop on tracks
126          Int_t bidx=trk[j];
127          if (bidx==v->GetPindex()) continue; //bachelor and v0's positive tracks must be different
128          AliESDtrack *btrk=event->GetTrack(bidx);
129          if (btrk->GetSign()<0) continue;  // bachelor's charge 
130           
131          AliESDv0 v0(*v), *pv0=&v0;
132          AliESDtrack bt(*btrk), *pbt=&bt;
133
134          Double_t dca=PropagateToDCA(pv0,pbt,b);
135          if (dca > fDCAmax) continue;
136
137          AliESDcascade cascade(*pv0,*pbt,bidx); //constucts a cascade candidate
138          if (cascade.GetChi2Xi() > fChi2max) continue;
139
140          Double_t x,y,z; cascade.GetXYZ(x,y,z); 
141          Double_t r2=x*x + y*y; 
142          if (r2 > fRmax*fRmax) continue;   // condition on fiducial zone
143          if (r2 < fRmin*fRmin) continue;
144
145          Double_t pxV0,pyV0,pzV0;
146          pv0->GetPxPyPz(pxV0,pyV0,pzV0);
147          if (x*pxV0+y*pyV0+z*pzV0 < 0) continue; //causality
148
149          Double_t x1,y1,z1; pv0->GetXYZ(x1,y1,z1);
150          if (r2 > (x1*x1+y1*y1)) continue;
151          if (z*z > z1*z1) continue;
152
153          if (cascade.GetCascadeCosineOfPointingAngle(fX,fY,fZ) < fCPAmax) continue; //condition on the cascade pointing angle 
154          event->AddCascade(&cascade);
155          ncasc++;
156
157       } // end loop tracks
158    } // end loop V0s
159
160 Info("V0sTracks2CascadeVertices","Number of reconstructed cascades: %d",ncasc);
161
162    return 0;
163 }
164
165
166 Double_t det(Double_t a00, Double_t a01, Double_t a10, Double_t a11){
167   // determinant 2x2
168   return a00*a11 - a01*a10;
169 }
170
171 Double_t det (Double_t a00,Double_t a01,Double_t a02,
172                      Double_t a10,Double_t a11,Double_t a12,
173                      Double_t a20,Double_t a21,Double_t a22) {
174   // determinant 3x3
175   return 
176   a00*det(a11,a12,a21,a22)-a01*det(a10,a12,a20,a22)+a02*det(a10,a11,a20,a21);
177 }
178
179
180
181
182 Double_t AliCascadeVertexer::
183 PropagateToDCA(AliESDv0 *v, AliExternalTrackParam *t, Double_t b) {
184   //--------------------------------------------------------------------
185   // This function returns the DCA between the V0 and the track
186   //--------------------------------------------------------------------
187   Double_t alpha=t->GetAlpha(), cs1=TMath::Cos(alpha), sn1=TMath::Sin(alpha);
188   Double_t r[3]; t->GetXYZ(r);
189   Double_t x1=r[0], y1=r[1], z1=r[2];
190   Double_t p[3]; t->GetPxPyPz(p);
191   Double_t px1=p[0], py1=p[1], pz1=p[2];
192   
193   Double_t x2,y2,z2;     // position and momentum of V0
194   Double_t px2,py2,pz2;
195   
196   v->GetXYZ(x2,y2,z2);
197   v->GetPxPyPz(px2,py2,pz2);
198  
199 // calculation dca
200    
201   Double_t dd= det(x2-x1,y2-y1,z2-z1,px1,py1,pz1,px2,py2,pz2);
202   Double_t ax= det(py1,pz1,py2,pz2);
203   Double_t ay=-det(px1,pz1,px2,pz2);
204   Double_t az= det(px1,py1,px2,py2);
205
206   Double_t dca=TMath::Abs(dd)/TMath::Sqrt(ax*ax + ay*ay + az*az);
207
208 //points of the DCA
209   Double_t t1 = det(x2-x1,y2-y1,z2-z1,px2,py2,pz2,ax,ay,az)/
210                 det(px1,py1,pz1,px2,py2,pz2,ax,ay,az);
211   
212   x1 += px1*t1; y1 += py1*t1; //z1 += pz1*t1;
213   
214
215   //propagate track to the points of DCA
216
217   x1=x1*cs1 + y1*sn1;
218   if (!t->PropagateTo(x1,b)) {
219     Error("PropagateToDCA","Propagation failed !");
220     return 1.e+33;
221   }  
222
223   return dca;
224 }
225
226
227
228
229
230
231
232
233
234
235