]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWG1/TRD/info/AliTRDv0Info.cxx
new V0 Monitoring task (Markus Heide)
[u/mrichter/AliRoot.git] / PWG1 / TRD / info / AliTRDv0Info.cxx
1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 *                                                                        *
4 * Author: The ALICE Off-line Project.                                    *
5 * Contributors are mentioned in the code where appropriate.              *
6 *                                                                        *
7 * Permission to use, copy, modify and distribute this software and its   *
8 * documentation strictly for non-commercial purposes is hereby granted   *
9 * without fee, provided that the above copyright notice appears in all   *
10 * copies and that both the copyright notice and this permission notice   *
11 * appear in the supporting documentation. The authors make no claims     *
12 * about the suitability of this software for any purpose. It is          *
13 * provided "as is" without express or implied warranty.                  *
14 **************************************************************************/
15
16 /* $Id: AliTRDv0Info.cxx 27496 2008-07-22 08:35:45Z cblume $ */
17
18 ////////////////////////////////////////////////////////////////////////////
19 //                                                                        //
20 //  Reconstruction QA                                                     //
21 //                                                                        //
22 //  Gathers all information necessary for reference data selection about  //
23 //  the track and (in case) its corresponding V0.                         //
24 //  Carries out the selection of electrons (from gamma conversions),      //
25 //  pions (from K0s decays) and protons (from Lambda and Anti-Lambda      //
26 //  decays) by cuts specific for the respective decay and particle        //
27 //  species.                                                              //
28 //  (M.Heide, 2009/10/06)                                                 //
29 //                                                                        //
30 //  Authors:                                                              //
31 //   Alex Bercuci <A.Bercuci@gsi.de>                                      //
32 //   Alex Wilk    <wilka@uni-muenster.de>                                 //
33 //   Markus Heide <mheide@uni-muenster.de>                                //
34 //                                                                        //
35 ////////////////////////////////////////////////////////////////////////////
36
37 #include "TMath.h"
38 #include "TDatabasePDG.h"
39
40 #include "AliESDtrack.h"
41 #include "AliESDv0.h"
42 #include "AliLog.h"
43 #include "TVector3.h"
44 #include "AliKFParticle.h"
45 #include "AliKFVertex.h"
46
47 #include "AliTRDv0Info.h"
48 #include "AliTRDtrackInfo.h"
49 #include "AliTRDtrackInfo.h"
50
51 ClassImp(AliTRDv0Info)
52
53 //_________________________________________________
54 AliTRDv0Info::AliTRDv0Info()
55   : TObject()
56   ,fQuality(0)
57   ,fDCA(10)
58   ,fPointingAngle(10)
59   ,fOpenAngle(10)
60   ,fPsiPair(99)
61   ,fMagField(0)
62   ,fRadius(0)
63   ,fV0Momentum(0)
64   ,fTrackP(NULL)
65   ,fTrackN(NULL)
66   ,fNindex(0)
67   ,fPindex(0)
68   ,fInputEvent(NULL)
69   ,fPrimaryVertex(NULL)
70 {
71   //
72   // Default constructor
73   //
74
75   memset(fPplus, 0, 2*kNlayer*sizeof(Float_t));
76   memset(fPminus, 0, 2*kNlayer*sizeof(Float_t));
77   memset(fDetPID, 0, 2*kNDaughters*kNDetectors*AliPID::kSPECIES*sizeof(Float_t));
78   memset(fComPID, 0, 2*kNDaughters*AliPID::kSPECIES*sizeof(Float_t));
79   memset(fInvMass, 0, kNMomBins*kNDecays*sizeof(Double_t));
80   memset(fArmenteros, 0, kNDecays*sizeof(Bool_t));
81   memset(fTPCdEdx, 0, kNDecays*sizeof(Float_t));
82   memset(fChi2ndf, 0, kNDecays*sizeof(Double_t));
83
84   /////////////////////////////////////////////////////////////////////////////
85   //Set Cut values: First specify decay in brackets, then the actual cut value!
86   ///////////////////////////////////////////////////////////////////////////// 
87
88   //Upper limit for distance of closest approach of two daughter tracks :
89   fUpDCA[kGamma] = 1000.;
90   fUpDCA[kK0s] = 0.08;
91   fUpDCA[kLambda] = 0.2;
92   fUpDCA[kAntiLambda] = 0.2;
93
94   //Upper limit for pointing angle (= angle between between vector from primary to secondary vertex and reconstructed momentum of V0 mother particle) :
95   fUpPointingAngle[kGamma] = 0.03;
96   fUpPointingAngle[kK0s] = 0.03;
97   fUpPointingAngle[kLambda] = 0.04;
98   fUpPointingAngle[kAntiLambda] = 0.04;
99
100   //Upper limit for invariant mass of V0 mother :
101   fUpInvMass[kGamma][0] = 0.05;// second pair of brackets is for momentum bin: 0: below mother momentm of 2.5 GeV
102   fUpInvMass[kGamma][1] = 0.07;//1: above 2.5 GeV
103   fUpInvMass[kK0s][0] = fUpInvMass[kK0s][1] = 0.50265;
104   fUpInvMass[kLambda][0] = fUpInvMass[kLambda][1] = 1.1207;
105   fUpInvMass[kAntiLambda][0] = fUpInvMass[kAntiLambda][1] = 1.1207;
106
107   //Lower limit for invariant mass of V0 mother :
108   fDownInvMass[kGamma] = -1.;
109   fDownInvMass[kK0s] = 0.49265;
110   fDownInvMass[kLambda] = 1.107;
111   fDownInvMass[kAntiLambda] = 1.107;
112
113   //Upper limit for KF Chi2/NDF value;
114   fUpChi2ndf[kGamma] = 10000.;//7.;
115   fUpChi2ndf[kK0s] = 10000.;//5.;
116   fUpChi2ndf[kLambda] = 10000.;//5.;
117   fUpChi2ndf[kAntiLambda] = 10000.;//5.;
118
119   //Lower limit for distance from secondary vertex to primary vertex in x-y plane :
120   fDownRadius[kGamma] = 6.;
121   fDownRadius[kK0s] = 0.;
122   fDownRadius[kLambda] = 0.;
123   fDownRadius[kAntiLambda] = 0.;
124
125   //Upper limit for distance from secondary vertex to primary vertex in x-y plane :
126   fUpRadius[kGamma] = 1000.;
127   fUpRadius[kK0s] = 20.;
128   fUpRadius[kLambda] = 1000.;
129   fUpRadius[kAntiLambda] = 1000.;
130
131   //Upper limit for opening angle between two daughter tracks (characteristically near zero for conversions) :
132   fUpOpenAngle[kGamma] = 0.1;
133   fUpOpenAngle[kK0s] = 3.15;
134   fUpOpenAngle[kLambda] = 3.15;
135   fUpOpenAngle[kAntiLambda] = 3.15;
136
137   //Upper limit for angle between daughter momentum plane and plane perpendicular to magnetic field (characteristically around zero for conversions) :
138   fUpPsiPair[kGamma] = 0.05;
139   fUpPsiPair[kK0s] = 1.6;
140   fUpPsiPair[kLambda] = 1.6;
141   fUpPsiPair[kAntiLambda] = 1.6;
142
143   //Lower limit for likelihood value of TPC PID :
144   fDownTPCPIDneg[AliPID::kElectron] = 0.;
145   fDownTPCPIDpos[AliPID::kElectron] = 0.;
146
147   fDownTPCPIDneg[AliPID::kMuon] = 0.;
148   fDownTPCPIDpos[AliPID::kMuon] = 0.;
149
150   fDownTPCPIDneg[AliPID::kPion] = 0.;
151   fDownTPCPIDpos[AliPID::kPion] = 0.;
152
153   fDownTPCPIDneg[AliPID::kKaon] = 0.;
154   fDownTPCPIDpos[AliPID::kKaon] = 0.;
155
156   fDownTPCPIDneg[AliPID::kProton] = 0.;
157   fDownTPCPIDpos[AliPID::kProton] = 0.;
158
159  //Lower limit for likelihood value of combined PID :
160   fDownComPIDneg[AliPID::kElectron] = 0.;
161   fDownComPIDpos[AliPID::kElectron] = 0.;
162
163   fDownComPIDneg[AliPID::kMuon] = 0.;
164   fDownComPIDpos[AliPID::kMuon] = 0.;
165
166   fDownComPIDneg[AliPID::kPion] = 0.;
167   fDownComPIDpos[AliPID::kPion] = 0.;
168
169   fDownComPIDneg[AliPID::kKaon] = 0.;
170   fDownComPIDpos[AliPID::kKaon] = 0.;
171
172   fDownComPIDneg[AliPID::kProton] = 0.;
173   fDownComPIDpos[AliPID::kProton] = 0.;
174
175  //Lower limit for likelihood value of combined PID for daughter track which doesn't enter reference data (here: pion daughters from Lambda decays:
176   fDownComPIDnegPart[AliPID::kElectron] = 0.;
177   fDownComPIDposPart[AliPID::kElectron] = 0.;
178
179   fDownComPIDnegPart[AliPID::kMuon] = 0.;
180   fDownComPIDposPart[AliPID::kMuon] = 0.;
181
182   fDownComPIDnegPart[AliPID::kPion] = 0.;
183   fDownComPIDposPart[AliPID::kPion] = 0.;
184
185   fDownComPIDnegPart[AliPID::kKaon] = 0.;
186   fDownComPIDposPart[AliPID::kKaon] = 0.;
187
188   fDownComPIDnegPart[AliPID::kProton] = 0.;
189   fDownComPIDposPart[AliPID::kProton] = 0.;
190
191   //Parameters for data with well-calibrated PID (after usage of tender):
192   /* //Lower limit for likelihood value of TPC PID :
193   fDownTPCPIDneg[AliPID::kElectron] = 0.21;
194   fDownTPCPIDpos[AliPID::kElectron] = 0.21;
195
196   fDownTPCPIDneg[AliPID::kMuon] = 0.21;
197   fDownTPCPIDpos[AliPID::kMuon] = 0.21;
198
199   fDownTPCPIDneg[AliPID::kPion] = 0.21;
200   fDownTPCPIDpos[AliPID::kPion] = 0.21;
201
202   fDownTPCPIDneg[AliPID::kKaon] = 0.21;
203   fDownTPCPIDpos[AliPID::kKaon] = 0.21;
204
205   fDownTPCPIDneg[AliPID::kProton] = 0.21;
206   fDownTPCPIDpos[AliPID::kProton] = 0.21;
207
208   //Lower limit for likelihood value of combined PID :
209   fDownComPIDneg[AliPID::kElectron] = 0.21;
210   fDownComPIDpos[AliPID::kElectron] = 0.21;
211
212   fDownComPIDneg[AliPID::kMuon] = 0.21;
213   fDownComPIDpos[AliPID::kMuon] = 0.21;
214
215   fDownComPIDneg[AliPID::kPion] = 0.9;
216   fDownComPIDpos[AliPID::kPion] = 0.9;
217
218   fDownComPIDneg[AliPID::kKaon] = 0.21;
219   fDownComPIDpos[AliPID::kKaon] = 0.21;
220
221   fDownComPIDneg[AliPID::kProton] = 0.9;
222   fDownComPIDpos[AliPID::kProton] = 0.9;
223
224  //Lower limit for likelihood value of combined PID for daughter track which doesn't enter reference data (here: pion daughters from Lambda decays:
225   fDownComPIDnegPart[AliPID::kElectron] = 0.05;
226   fDownComPIDposPart[AliPID::kElectron] = 0.05;
227
228   fDownComPIDnegPart[AliPID::kMuon] = 0.05;
229   fDownComPIDposPart[AliPID::kMuon] = 0.05;
230
231   fDownComPIDnegPart[AliPID::kPion] = 0.05;
232   fDownComPIDposPart[AliPID::kPion] = 0.05;
233
234   fDownComPIDnegPart[AliPID::kKaon] = 0.05;
235   fDownComPIDposPart[AliPID::kKaon] = 0.05;
236
237   fDownComPIDnegPart[AliPID::kProton] = 0.05;
238   fDownComPIDposPart[AliPID::kProton] = 0.05;*/
239 }
240
241 //_________________________________________________
242 AliTRDv0Info::AliTRDv0Info(const AliTRDv0Info &ref)
243   : TObject()
244   ,fQuality(ref.fQuality)
245   ,fDCA(ref.fDCA)
246   ,fPointingAngle(ref.fPointingAngle)
247   ,fOpenAngle(ref.fOpenAngle)
248   ,fPsiPair(ref.fPsiPair)
249   ,fMagField(ref.fMagField)
250   ,fRadius(ref.fRadius)
251   ,fV0Momentum(ref.fV0Momentum)
252   ,fTrackP(ref.fTrackP)
253   ,fTrackN(ref.fTrackN)
254   ,fNindex(ref.fNindex)
255   ,fPindex(ref.fPindex)
256   ,fInputEvent(ref.fInputEvent)
257   ,fPrimaryVertex(ref.fPrimaryVertex)
258 {
259   //
260   // Copy constructor
261   //
262
263   memcpy(fPplus, ref.fPplus, 2*kNlayer*sizeof(Float_t));
264   memcpy(fPminus, ref.fPminus, 2*kNlayer*sizeof(Float_t));
265   memcpy(fDetPID, ref.fDetPID, 2*kNDaughters*kNDetectors*AliPID::kSPECIES*sizeof(Float_t));
266   memcpy(fComPID, ref.fComPID, 2*kNDaughters*AliPID::kSPECIES*sizeof(Float_t));
267   memcpy(fInvMass, ref.fInvMass, kNMomBins*kNDecays*sizeof(Double_t));
268   memcpy(fArmenteros, ref.fArmenteros, kNDecays*sizeof(Bool_t));
269   memcpy(fChi2ndf, ref.fChi2ndf, kNDecays*sizeof(Double_t));
270   memcpy(fTPCdEdx, ref.fTPCdEdx, kNDaughters*sizeof(Float_t));
271
272   //Upper limit for distance of closest approach of two daughter tracks :
273   memcpy(fUpDCA, ref.fUpDCA, kNDecays*sizeof(Float_t));
274   memcpy(fUpPointingAngle, ref.fUpPointingAngle, kNDecays*sizeof(Float_t));
275   memcpy(fUpOpenAngle, ref.fUpOpenAngle, kNDecays*sizeof(Float_t));
276   memcpy(fDownOpenAngle, ref.fDownOpenAngle, kNDecays*sizeof(Float_t));
277   memcpy(fUpPsiPair, ref.fUpPsiPair, kNDecays*sizeof(Float_t));
278   memcpy(fDownPsiPair, ref.fDownPsiPair, kNDecays*sizeof(Float_t));
279   memcpy(fUpInvMass, ref.fUpInvMass, kNDecays*kNMomBins*sizeof(Double_t));
280   memcpy(fDownInvMass, ref.fDownInvMass, kNDecays*sizeof(Double_t));
281   memcpy(fUpChi2ndf, ref.fUpChi2ndf, kNDecays*sizeof(Double_t));
282   memcpy(fUpRadius, ref.fUpRadius, kNDecays*sizeof(Float_t));
283   memcpy(fDownRadius, ref.fDownRadius, kNDecays*sizeof(Float_t));
284   memcpy(fDownTPCPIDneg, ref.fDownTPCPIDneg, AliPID::kSPECIES*sizeof(Float_t));
285   memcpy(fDownTPCPIDpos, ref.fDownTPCPIDpos, AliPID::kSPECIES*sizeof(Float_t));
286   memcpy(fDownComPIDneg, ref.fDownComPIDneg, AliPID::kSPECIES*sizeof(Float_t));
287   memcpy(fDownComPIDpos, ref.fDownComPIDpos, AliPID::kSPECIES*sizeof(Float_t));
288   memcpy(fDownComPIDnegPart, ref.fDownComPIDnegPart, AliPID::kSPECIES*sizeof(Float_t));
289   memcpy(fDownComPIDposPart, ref.fDownComPIDposPart, AliPID::kSPECIES*sizeof(Float_t));
290 }
291
292 //_________________________________________________
293 void AliTRDv0Info::SetV0Info(AliESDv0 *esdv0)
294 {//Gets values of ESDv0 and daughter track properties
295   //See header file for description of variables
296
297   fQuality = Quality(esdv0);//Attributes an Int_t to the V0 due to quality cuts (= 1 if V0 is accepted, other integers depending on cut which excludes the vertex)    
298
299   fRadius = Radius(esdv0);//distance from secondary vertex to primary vertex in x-y plane
300       
301   fDCA = esdv0->GetDcaV0Daughters();//distance of closest approach of two daughter tracks
302       
303   fPointingAngle = TMath::ACos(esdv0->GetV0CosineOfPointingAngle());// pointing angle (= angle between between vector from primary to secondary vertex and reconstructed momentum of V0 mother particle)
304       
305   fOpenAngle = OpenAngle(esdv0);//Opening angle between two daughter tracks
306       
307   fPsiPair = PsiPair(esdv0);//Angle between daughter momentum plane and plane perpendicular to magnetic field
308
309   fV0Momentum = V0Momentum(esdv0);//Reconstructed momentum of the mother particle
310       
311   //4 decay types : conversions, K0s, Lambda, Anti-Lambda 
312     //five particle types: electrons, muons, pions, kaons, protons (muons and kaons not involved)
313   for(Int_t idecay(0), part1(-1), part2(-1); idecay < kNDecays; idecay++){
314
315     fArmenteros[idecay]=Armenteros(esdv0, idecay);//Attribute the Armenteros yes/no decision for every decay type
316     if(idecay == kLambda){ //protons and pions from Lambda
317       part1 = AliPID::kProton;
318       part2 = AliPID::kPion;
319     } else if(idecay == kAntiLambda) { //antiprotons and pions from Anti-Lambda
320       part1 = AliPID::kPion;
321       part2 = AliPID::kProton;
322     } else if(idecay == kK0s) {//pions from K0s
323       part1 = part2 = AliPID::kPion;
324     } else if(idecay == kGamma) {//electrons from conversions
325       part1 = part2 = AliPID::kElectron;
326     } 
327     fInvMass[idecay] = InvMass(part1, part2, esdv0);//Calculate invariant mass for all of our four supposed decays
328     fChi2ndf[idecay] = KFChi2ndf(part1, part2,idecay);
329    
330   }
331   //Gets all likelihood values from TPC, TOF and ITS PID for the fDetPID[kNDaughters][kNDetectors][AliPID::kSPECIES] array
332   GetDetectorPID();
333   //Bayesian combination of likelihoods from TPC and TOF
334   CombinePID();
335   //TPC dE/dx values for both tracks
336   GetTPCdEdx();
337
338 }
339 //_________________________________________________
340 Float_t  AliTRDv0Info::V0Momentum(AliESDv0 *esdv0) const
341 {
342   //
343   // Reconstructed momentum of V0 mother particle
344   //
345
346   Double_t mn[3] = {0,0,0};
347   Double_t mp[3] = {0,0,0};
348
349
350   esdv0->GetNPxPyPz(mn[0],mn[1],mn[2]);//reconstructed cartesian momentum components of negative daughter; 
351   esdv0->GetPPxPyPz(mp[0],mp[1],mp[2]);//reconstructed cartesian momentum components of positive daughter;
352   
353   
354   return TMath::Sqrt((mn[0]+mp[0])*(mn[0]+mp[0]) + (mn[1]+mp[1])*(mn[1]+mp[1])+(mn[2]+mp[2])*(mn[2]+mp[2]));
355 }
356
357 //_________________________________________________
358 Double_t AliTRDv0Info::InvMass(Int_t part1, Int_t part2, AliESDv0 *esdv0) const
359 {
360   //
361   // Invariant mass of reconstructed V0 mother
362   //
363
364   const Double_t kpmass[5] = {AliPID::ParticleMass(AliPID::kElectron),AliPID::ParticleMass(AliPID::kMuon),AliPID::ParticleMass(AliPID::kPion),AliPID::ParticleMass(AliPID::kKaon),AliPID::ParticleMass(AliPID::kProton)};
365   //Masses of electrons, muons, pions, kaons and protons, as implemented in ROOT
366
367
368   Double_t mn[3] = {0,0,0};
369   Double_t mp[3] = {0,0,0};  
370
371   esdv0->GetNPxPyPz(mn[0],mn[1],mn[2]);//reconstructed cartesian momentum components of negative daughter;
372   esdv0->GetPPxPyPz(mp[0],mp[1],mp[2]);//reconstructed cartesian momentum components of positive daughter;
373   
374   Double_t mass1 = kpmass[part1];//sets supposed rest masses for both daughters: positive
375   Double_t mass2 = kpmass[part2];//negative   
376
377   //Calculate daughters' energies :
378   Double_t e1    = TMath::Sqrt(mass1*mass1+
379             mp[0]*mp[0]+
380             mp[1]*mp[1]+
381             mp[2]*mp[2]);
382   Double_t e2    = TMath::Sqrt(mass2*mass2+
383             mn[0]*mn[0]+
384             mn[1]*mn[1]+
385             mn[2]*mn[2]);  
386
387   //Sum of daughter momenta :   
388   Double_t momsum =  
389     (mn[0]+mp[0])*(mn[0]+mp[0])+
390     (mn[1]+mp[1])*(mn[1]+mp[1])+
391     (mn[2]+mp[2])*(mn[2]+mp[2]);
392
393   //invariant mass :                 
394   Double_t mInv = TMath::Sqrt((e1+e2)*(e1+e2)-momsum);
395
396   return mInv;
397   
398 }
399 //_________________________________________________
400 Float_t AliTRDv0Info::OpenAngle(AliESDv0 *esdv0)
401 {//Opening angle between two daughter tracks
402   Double_t mn[3] = {0,0,0};
403   Double_t mp[3] = {0,0,0};
404     
405
406   esdv0->GetNPxPyPz(mn[0],mn[1],mn[2]);//reconstructed cartesian momentum components of negative daughter;
407   esdv0->GetPPxPyPz(mp[0],mp[1],mp[2]);//reconstructed cartesian momentum components of positive daughter;
408
409   
410   fOpenAngle = TMath::ACos((mp[0]*mn[0] + mp[1]*mn[1] + mp[2]*mn[2])/(TMath::Sqrt(mp[0]*mp[0] + mp[1]*mp[1] + mp[2]*mp[2])*TMath::Sqrt(mn[0]*mn[0] + mn[1]*mn[1] + mn[2]*mn[2])));
411   
412   return fOpenAngle;
413 }
414
415 //_________________________________________________
416 Float_t AliTRDv0Info::PsiPair(AliESDv0 *esdv0)
417 {//Angle between daughter momentum plane and plane perpendicular to magnetic field
418   Double_t x, y, z;
419   esdv0->GetXYZ(x,y,z);//Reconstructed coordinates of V0; to be replaced by Markus Rammler's method in case of conversions!
420   
421   Double_t mn[3] = {0,0,0};
422   Double_t mp[3] = {0,0,0};
423   
424
425   esdv0->GetNPxPyPz(mn[0],mn[1],mn[2]);//reconstructed cartesian momentum components of negative daughter;
426   esdv0->GetPPxPyPz(mp[0],mp[1],mp[2]);//reconstructed cartesian momentum components of positive daughter; 
427
428
429   Double_t deltat = 1.;
430   deltat = TMath::ATan(mp[2]/(TMath::Sqrt(mp[0]*mp[0] + mp[1]*mp[1])+1.e-13)) -  TMath::ATan(mn[2]/(TMath::Sqrt(mn[0]*mn[0] + mn[1]*mn[1])+1.e-13));//difference of angles of the two daughter tracks with z-axis
431
432   Double_t radiussum = TMath::Sqrt(x*x + y*y) + 50;//radius to which tracks shall be propagated
433
434   Double_t momPosProp[3];
435   Double_t momNegProp[3];
436     
437   AliExternalTrackParam nt(*fTrackN), pt(*fTrackP);
438     
439   fPsiPair = 4.;
440
441   if(nt.PropagateTo(radiussum,fMagField) == 0)//propagate tracks to the outside
442     fPsiPair =  -5.;
443   if(pt.PropagateTo(radiussum,fMagField) == 0)
444     fPsiPair = -5.;
445   pt.GetPxPyPz(momPosProp);//Get momentum vectors of tracks after propagation
446   nt.GetPxPyPz(momNegProp);
447   
448   Double_t pEle =
449     TMath::Sqrt(momNegProp[0]*momNegProp[0]+momNegProp[1]*momNegProp[1]+momNegProp[2]*momNegProp[2]);//absolute momentum value of negative daughter
450   Double_t pPos =
451     TMath::Sqrt(momPosProp[0]*momPosProp[0]+momPosProp[1]*momPosProp[1]+momPosProp[2]*momPosProp[2]);//absolute momentum value of positive daughter
452     
453   Double_t scalarproduct =
454     momPosProp[0]*momNegProp[0]+momPosProp[1]*momNegProp[1]+momPosProp[2]*momNegProp[2];//scalar product of propagated positive and negative daughters' momenta
455     
456   Double_t chipair = TMath::ACos(scalarproduct/(pEle*pPos));//Angle between propagated daughter tracks
457
458   fPsiPair =  TMath::Abs(TMath::ASin(deltat/chipair));  
459
460   return fPsiPair; 
461
462 }
463 //_________________________________________________
464 Double_t AliTRDv0Info::KFChi2ndf(Int_t part1, Int_t part2,Int_t decay){
465   //Calculates Kalman filter Chi2/NDF
466   Int_t mothers[4]={22,310,3122,3122};
467
468   const Double_t partMass=TDatabasePDG::Instance()->GetParticle(mothers[decay])->Mass();
469   const Double_t massWidth[4] = {0.001, 0., 0., 0.};
470  
471   AliKFParticle *kfMother = CreateMotherParticle(fTrackP, fTrackN, part1, part2);
472  
473   // Lambda
474   if(!kfMother) {
475   return kFALSE;
476   }
477   
478   // production vertex is set in the 'CreateMotherParticle' function
479   kfMother->SetMassConstraint(partMass, massWidth[decay]);
480  
481   Double_t chi2ndf = (kfMother->GetChi2()/kfMother->GetNDF());
482  
483   if(kfMother)delete kfMother;
484   return chi2ndf; 
485 }
486 //________________________________________________________________
487 AliKFParticle *AliTRDv0Info::CreateMotherParticle(AliESDtrack *pdaughter, AliESDtrack *ndaughter, Int_t pspec, Int_t nspec){
488   //
489   // Creates a mother particle
490   //
491   AliKFParticle pkfdaughter(*pdaughter, pspec);
492   AliKFParticle nkfdaughter(*ndaughter, nspec);
493   
494  
495   // Create the mother particle 
496   AliKFParticle *m = new AliKFParticle(pkfdaughter, nkfdaughter);
497  
498   AliKFVertex improvedVertex = *fPrimaryVertex;
499   improvedVertex += *m;
500   m->SetProductionVertex(improvedVertex);
501   
502
503   return m;
504 }
505 //_________________________________________________
506 Int_t AliTRDv0Info::HasTrack(AliTRDtrackInfo * const track)
507 {
508 //Checks if track is a secondary vertex daughter (due to V0 finder)
509   
510   Int_t trackID(track->GetTrackId());//index of the track
511   return HasTrack(trackID);
512 }
513
514 //_________________________________________________
515 Int_t AliTRDv0Info::HasTrack(Int_t trackID)
516 {
517   //comparing index of track with indices of pos./neg. V0 daughter :
518   if(fNindex==trackID) return -1;
519   else if(fPindex==trackID) return 1;
520   else return 0;
521 }
522
523 //_________________________________________________
524 void AliTRDv0Info::GetDetectorPID()
525 {//PID likelihoods from TPC, TOF, and ITS, for all particle species
526
527   fTrackN->GetTPCpid(fDetPID[kNeg][kTPC]);
528   fTrackP->GetTPCpid(fDetPID[kPos][kTPC]);
529   fTrackN->GetTOFpid(fDetPID[kNeg][kTOF]);
530   fTrackP->GetTOFpid(fDetPID[kPos][kTOF]);
531   fTrackN->GetITSpid(fDetPID[kNeg][kITS]);
532   fTrackP->GetITSpid(fDetPID[kPos][kITS]);
533
534   Long_t statusN = fTrackN->GetStatus(); 
535   Long_t statusP = fTrackP->GetStatus(); 
536   
537   if(!(statusN & AliESDtrack::kTPCpid)){
538          for(Int_t iPart = 0; iPart < AliPID::kSPECIES; iPart++){
539         fDetPID[kNeg][kTPC][iPart] = 0.2;
540       }    
541   }
542   if(!(statusN & AliESDtrack::kTOFpid)){
543     for(Int_t iPart = 0; iPart < AliPID::kSPECIES; iPart++){
544       fDetPID[kNeg][kTOF][iPart] = 0.2;
545     }    
546     
547   }
548   if(!(statusN & AliESDtrack::kITSpid)){
549     for(Int_t iPart = 0; iPart < AliPID::kSPECIES; iPart++){
550       fDetPID[kNeg][kITS][iPart] = 0.2;
551     }    
552   }
553   if(!(statusP & AliESDtrack::kTPCpid)){
554     for(Int_t iPart = 0; iPart < AliPID::kSPECIES; iPart++){
555       fDetPID[kPos][kTPC][iPart] = 0.2;
556     }    
557   }
558   if(!(statusP & AliESDtrack::kTOFpid)){
559     for(Int_t iPart = 0; iPart < AliPID::kSPECIES; iPart++){
560       fDetPID[kPos][kTOF][iPart] = 0.2;
561     }    
562     
563   }
564   if(!(statusP & AliESDtrack::kITSpid)){
565     for(Int_t iPart = 0; iPart < AliPID::kSPECIES; iPart++){
566       fDetPID[kPos][kITS][iPart] = 0.2;
567     }    
568   }
569
570 }
571 //____________________________________________________________________________________
572 void AliTRDv0Info::CombinePID()
573 {
574   Double_t partrat[AliPID::kSPECIES] = {0.208, 0.010, 0.662, 0.019, 0.101};
575   
576   for(Int_t iSign = 0; iSign < kNDaughters; iSign++)
577     {
578     for(Int_t iPart = 0; iPart < AliPID::kSPECIES; iPart++)
579       {
580       fComPID[iSign][iPart] = (partrat[iPart]*fDetPID[iSign][kTPC][iPart]*fDetPID[iSign][kTOF][iPart])/((partrat[0]*fDetPID[iSign][kTPC][0]*fDetPID[iSign][kTOF][0])+(partrat[1]*fDetPID[iSign][kTPC][1]*fDetPID[iSign][kTOF][1])+(partrat[2]*fDetPID[iSign][kTPC][2]*fDetPID[iSign][kTOF][2])+(partrat[3]*fDetPID[iSign][kTPC][3]*fDetPID[iSign][kTOF][3])+(partrat[4]*fDetPID[iSign][kTPC][4]*fDetPID[iSign][kTOF][4]));
581       
582       }
583     }
584 }
585 //_________________________________________________
586 void AliTRDv0Info::GetTPCdEdx()
587 {
588   fTPCdEdx[kNeg] = fTrackN->GetTPCsignal();
589   fTPCdEdx[kPos] = fTrackP->GetTPCsignal();
590
591 }
592 //_________________________________________________
593 Bool_t AliTRDv0Info::TPCdEdxCuts(Int_t part, AliTRDtrackInfo * const track)
594 {
595   //Bethe-Bloch lines
596   Double_t alephParameters[5];
597   
598   // data
599   alephParameters[0] = 0.0283086;
600   alephParameters[1] = 2.63394e+01;
601   alephParameters[2] = 5.04114e-11;
602   alephParameters[3] = 2.12543e+00;
603   alephParameters[4] = 4.88663e+00;
604   
605
606   Double_t deposit = 0;
607   Float_t x = 0;
608   if(HasTrack(track) == 1){
609     x = fTrackP->P();
610     deposit = fTPCdEdx[kPos];
611   }
612   else if(HasTrack(track) == -1){
613     x = fTrackN->P();
614     deposit = fTPCdEdx[kNeg];
615   }
616   else{
617     printf("No track found");
618     return 0;
619   }
620   if(x < 0.2)return 0;
621
622   Float_t upLimits[5]={85,1000,50*AliExternalTrackParam::BetheBlochAleph(x/0.13957, alephParameters[0], alephParameters[1], alephParameters[2], alephParameters[3],  alephParameters[4])+6,1000,50*AliExternalTrackParam::BetheBlochAleph(x/0.93827, alephParameters[0], alephParameters[1], alephParameters[2], alephParameters[3],  alephParameters[4])+10};
623   Float_t downLimits[5]={62,40,50*AliExternalTrackParam::BetheBlochAleph(x/0.13957, alephParameters[0], alephParameters[1], alephParameters[2], alephParameters[3],  alephParameters[4])-6,40,50*AliExternalTrackParam::BetheBlochAleph(x/0.93827, alephParameters[0], alephParameters[1], alephParameters[2], alephParameters[3],  alephParameters[4])-11};
624   
625   
626   if(x < 0.7){
627     downLimits[4]=90;
628   }
629   if(x < 1.25){
630     upLimits[0] = 85;
631   }
632   else{
633     downLimits[0] = 64;
634   }
635
636
637   if(deposit < downLimits[part])
638     return 0;
639   if(deposit > upLimits[part])
640     return 0;
641
642  
643   return 1;
644
645 }
646 //_________________________________________________
647 Float_t AliTRDv0Info::Radius(AliESDv0 *esdv0)
648 {//distance from secondary vertex to primary vertex in x-y plane
649   Double_t x, y, z;
650   esdv0->GetXYZ(x,y,z); //Reconstructed coordinates of V0
651   fRadius = TMath::Sqrt(x*x + y*y);
652   return fRadius;
653
654 }
655
656 //_________________________________________________
657 Int_t AliTRDv0Info::Quality(AliESDv0 *const esdv0)
658
659   //
660   // Checking track and V0 quality status in order to exclude vertices based on poor information
661   //
662
663   Float_t nClsN;
664   nClsN = fTrackN->GetTPCNcls();//number of found clusters in TPC for negative track
665   Float_t nClsFN;
666   nClsFN = fTrackN->GetTPCNclsF();//number of findable clusters in TPC for negative track
667   Float_t nClsP;
668   nClsP = fTrackP->GetTPCNcls();//number of found clusters in TPC for positive track
669   Float_t nClsFP;
670   nClsFP = fTrackP->GetTPCNclsF();//number of findable clusters in TPC for positive track
671   
672   fQuality = 0;
673
674
675   if (!(esdv0->GetOnFlyStatus()))//accept only vertices from online V0 finder
676     return -1;
677
678   Float_t clsRatioN; 
679   Float_t clsRatioP;
680
681   if((nClsFN < 80) || (nClsFP < 80)) return -2;//reject all V0s where at least one track has less than 80 TPC clusters
682
683  // Chi2 per TPC cluster
684   Int_t nTPCclustersP = fTrackP->GetTPCclusters(0);
685   Int_t nTPCclustersN = fTrackN->GetTPCclusters(0);
686   Float_t chi2perTPCclusterP = fTrackP->GetTPCchi2()/Float_t(nTPCclustersP);
687   Float_t chi2perTPCclusterN = fTrackN->GetTPCchi2()/Float_t(nTPCclustersN);
688  
689   if((chi2perTPCclusterN > 3.5)||(chi2perTPCclusterP > 3.5)) return -3;//reject all V0s where at least one track has a chi2 above 3.5
690     
691   clsRatioN = nClsN/nClsFN; //ratios of found to findable clusters in TPC 
692   clsRatioP = nClsP/nClsFP;
693   
694   if((clsRatioN < 0.6)||(clsRatioP < 0.6))//exclude tracks with low ratio of found to findable TPC clusters
695     return -4;
696  
697   if (!((fTrackP->GetStatus() &
698   AliESDtrack::kTPCrefit)))//accept only vertices in which both tracks have TPC refit
699     return -5;
700   if (!((fTrackN->GetStatus() &
701   AliESDtrack::kTPCrefit)))
702     return -6;  
703   if (fTrackP->GetKinkIndex(0)>0  ||
704       fTrackN->GetKinkIndex(0)>0 )//exclude tracks with kinks
705     return -7;
706  
707   if(!(V0SignCheck()))
708        return -8;
709   fQuality = 1;
710   return fQuality;
711 }
712 //________________________________________________________________
713 Bool_t AliTRDv0Info::V0SignCheck(){
714   //
715   // Check if v0 daughters really carry opposite charges
716   //
717  
718   Int_t qP = fTrackP->Charge();
719   Int_t qN = fTrackN->Charge();
720
721   if((qP*qN) != -1) return kFALSE;
722
723   return kTRUE;
724 }
725 //___________________________________________________________________
726 Bool_t AliTRDv0Info::Armenteros(AliESDv0 *esdv0, Int_t decay){
727   //
728   // computes the Armenteros variables for given V0
729   //
730   Double_t mn[3] = {0,0,0};
731   Double_t mp[3] = {0,0,0};  
732   Double_t mm[3] = {0,0,0};  
733  
734   if(V0SignCheck()){
735     esdv0->GetNPxPyPz(mn[0],mn[1],mn[2]); //reconstructed cartesian momentum components of negative daughter
736     esdv0->GetPPxPyPz(mp[0],mp[1],mp[2]); //reconstructed cartesian momentum components of positive daughter
737   }
738   else{
739     esdv0->GetPPxPyPz(mn[0],mn[1],mn[2]); //reconstructed cartesian momentum components of negative daughter
740     esdv0->GetNPxPyPz(mp[0],mp[1],mp[2]); //reconstructed cartesian momentum components of positive daughter
741   }
742   esdv0->GetPxPyPz(mm[0],mm[1],mm[2]); //reconstructed cartesian momentum components of mother
743
744   TVector3 vecN(mn[0],mn[1],mn[2]);
745   TVector3 vecP(mp[0],mp[1],mp[2]);
746   TVector3 vecM(mm[0],mm[1],mm[2]);
747   
748   Double_t thetaP = acos((vecP * vecM)/(vecP.Mag() * vecM.Mag()));
749   Double_t thetaN = acos((vecN * vecM)/(vecN.Mag() * vecM.Mag()));
750   
751   Double_t alfa = ((vecP.Mag())*cos(thetaP)-(vecN.Mag())*cos(thetaN))/
752     ((vecP.Mag())*cos(thetaP)+(vecN.Mag())*cos(thetaN)) ;
753   Double_t qt = vecP.Mag()*sin(thetaP);
754
755   Float_t ap[2];
756   ap[0] = alfa;
757   ap[1] = qt;
758
759   Double_t LcutAP[2];//Lambda/Anti-Lambda cuts
760   if(decay == 0){
761     // armenteros cuts
762     const Double_t cutAlpha[2] = {0.35, 0.45};   // [0.35, 0.45]
763     const Double_t cutQT = 0.015;
764     if(TMath::Abs(ap[0]) > cutAlpha[0] && TMath::Abs(ap[0]) < cutAlpha[1]) return kFALSE;
765    
766     if(ap[1] > cutQT) return kFALSE;
767   }
768   
769   else if(decay == 1){
770     const Double_t cutQT = 0.1075;
771     const Double_t cutAP = 0.22 * TMath::Sqrt( TMath::Abs( (1-ap[0]*ap[0]/(0.92*0.92)) ) );
772     if(ap[1] < cutQT) return kFALSE;
773     if(ap[1] > cutAP) return kFALSE;
774   }
775   else if(decay == 2){
776     const Double_t cutQT = 0.03;
777     const Double_t cutAlpha = 0.7;  // VERY strong - should supress the overlap with K0
778     LcutAP[0] = 1.0 - (ap[0]-0.7 * ap[0]-0.7)*1.1 - 0.87;
779     if(TMath::Abs(ap[0]) > cutAlpha) return kFALSE;
780     if(ap[1] < cutQT) return kFALSE;
781     if(ap[1] > LcutAP[0]) return kFALSE;
782
783   }
784   else if(decay == 3){
785     const Double_t cutQT = 0.03;
786     const Double_t cutAlpha = 0.7;  // VERY strong - should supress the overlap with K0
787     LcutAP[1] = 1.0 - (ap[0]+0.7 * ap[0]+0.7)*1.1 - 0.87;
788     if(TMath::Abs(ap[0]) > cutAlpha) return kFALSE;
789     if(ap[1] < cutQT) return kFALSE;
790     if(ap[1] > LcutAP[1]) return kFALSE;
791   }
792   return kTRUE;
793 }
794 //_________________________________________________
795 Int_t AliTRDv0Info::GetPID(Int_t ipart, AliTRDtrackInfo *track)
796 {
797   // Decides if track is accepted for one of the reference data samples
798   Int_t cutCode = -99;
799   if(!(track)) {
800     AliError("No track info");
801     return -1;
802   }
803   if(!HasTrack(track)){
804     AliDebug(2, "Track not attached to v0.");
805     return -2;
806   }
807
808   //translate ipart to decay (Anti-Lambda will be treated separately)
809   Int_t iDecay = -1;
810   switch(ipart){
811   case AliPID::kElectron: iDecay = kGamma; break;
812   case AliPID::kPion: iDecay = kK0s; break;
813   case AliPID::kProton: iDecay = kLambda; break;
814   default:
815     AliWarning(Form("Hypothesis \"ipart=%d\" not handled", ipart));
816     return -3;
817   }
818
819   //... it fulfills our quality criteria
820   if(!(fQuality == 1)) return -4;
821   //... distance of closest approach between daughters is reasonably small
822   if((fDCA > fUpDCA[iDecay])) return -5;
823   //... pointing angle between momentum of mother particle and vector from prim. to sec. vertex is small
824   if((fPointingAngle > fUpPointingAngle[iDecay])) return -6;
825   //... x-y plane distance of decay point to prim. vertex is bigger than a certain minimum value (for conversions)
826   if((fRadius < fDownRadius[iDecay])) return -7;
827   //...or smaller than a maximum value (for K0s)
828   if((fRadius > fUpRadius[iDecay])) return -8;
829   //... opening angle is close enough to zero (for conversions)
830   if((fOpenAngle > fUpOpenAngle[iDecay])) return -9;
831   //... Psi-pair angle is close enough to zero(for conversions)
832   if((TMath::Abs(fPsiPair) > fUpPsiPair[iDecay])) return -10;
833  
834
835
836   //Mother momentum slots above/below 2.5 GeV
837   Int_t iPSlot(fV0Momentum > 2.5);
838   Int_t trackID(track->GetTrackId());
839
840   //specific cut criteria :
841   if(ipart == AliPID::kProton) {
842     if((fInvMass[kK0s] < fUpInvMass[kK0s][iPSlot]) && (fInvMass[kK0s] > fDownInvMass[kK0s])) return -11;//explicit exclusion of K0s decays
843
844     if(fOpenAngle < (0.3 - 0.2*fV0Momentum))return -9;
845
846  
847
848     //for proton sample: separate treatment of Lamba and Anti-Lambda decays:
849     //for Anti-Lambda:
850     //Combined PID likelihoods high enough for pi+ and anti-proton ; invariant mass calculated postulating these two particle species...
851     //if((fComPID[kNeg][AliPID::kProton] > fDownComPIDneg[AliPID::kProton]) && (fComPID[kPos][AliPID::kPion] > fDownComPIDposPart[AliPID::kPion])) {
852     //if((fDetPID[kNeg][kTPC][AliPID::kProton] > fDownTPCPIDneg[AliPID::kProton]) && (fDetPID[kPos][kTPC][AliPID::kPion] > fDownTPCPIDpos[AliPID::kPion])){
853     if((TPCdEdxCuts(ipart, track))){//momentary solution: direct cut on TPC dE/dx
854       if(fNindex == trackID) {//we're only interested in the anti-proton
855         if(fArmenteros[kAntiLambda]){//Armenteros condition has to be fulfilled   
856           if(fChi2ndf[kAntiLambda] < fUpChi2ndf[kAntiLambda]){//Kalman filter Chi2/NDF not allowed to be too large
857             if((fInvMass[kAntiLambda] < fUpInvMass[kAntiLambda][iPSlot]) && (fInvMass[kAntiLambda] > fDownInvMass[kAntiLambda])){  
858         return 1;
859             } else cutCode = -15;
860           }
861           else cutCode =-14;
862         }
863         else cutCode = -13;
864       }
865     }
866     else cutCode = -12;
867     //for Lambda:
868     //TPC PID likelihoods high enough for pi- and proton ; invariant mass calculated accordingly
869     //if((fComPID[kNeg][AliPID::kPion] > fDownComPIDnegPart[AliPID::kPion]) && (fComPID[kPos][AliPID::kProton] > fDownComPIDpos[AliPID::kProton])) {
870     //if((fDetPID[kNeg][kTPC][AliPID::kPion] > fDownTPCPIDneg[AliPID::kPion]) && (fDetPID[kPos][kTPC][AliPID::kProton] > fDownTPCPIDpos[AliPID::kProton])){
871     if((TPCdEdxCuts(ipart, track))){//momentary solution: direct TPC dE/dx cuts
872       if(fPindex == trackID) {
873         if(fArmenteros[kLambda]){
874           if(fChi2ndf[kLambda] < fUpChi2ndf[kLambda]){
875             if((fInvMass[kLambda] < fUpInvMass[kLambda][iPSlot]) && (fInvMass[kLambda] > fDownInvMass[kLambda])){ 
876         return 1;
877             } else cutCode = -15;
878           }
879           else cutCode = -14;
880         }
881         else cutCode = -13;
882       }
883     }
884     else cutCode = -12;
885     return cutCode;
886   }
887  
888   //for K0s decays: equal TPC PID likelihood criteria for both daughters ; invariant mass calculated postulating two pions
889   if(ipart == AliPID::kPion) {
890     
891     if(fOpenAngle < (1.0/(fV0Momentum + 0.3) - 0.1))
892       return -9;
893     
894     //explicit exclusion of Lambda decays
895     if((fInvMass[kLambda] < fUpInvMass[kLambda][iPSlot]) && (fInvMass[kLambda] > fDownInvMass[kLambda])) return -11;
896     //explicit exclusion of Anti-Lambda decays
897     if((fInvMass[kAntiLambda] < fUpInvMass[kAntiLambda][iPSlot]) && (fInvMass[kAntiLambda] > fDownInvMass[kAntiLambda])) return -11;
898     
899     //if((fDetPID[kNeg][kTPC][ipart] < fDownTPCPIDneg[ipart]) || (fDetPID[kPos][kTPC][ipart] < fDownTPCPIDpos[ipart])) return -12;
900     if(!(TPCdEdxCuts(ipart, track))){//momentary solution: direct TPC dE/dx cuts
901       return -12;
902     }
903   }
904   
905   
906   //for photon conversions: equal combined PID likelihood criteria for both daughters ; invariant mass calculated postulating two electrons
907   //No Lambda/K0s exclusion is provided, since these contributions hardly ever interfere with gamma invariant mass!
908   //Float_t momentum(track->GetESDinfo()->GetOuterParam()->P());
909   if(ipart == AliPID::kElectron) {
910     //if(momentum > 1.75) {//since combined PID performs a little worse in simulations than TPC standalone for higher momenta, ONLY TPC PID is used here
911     //if((fDetPID[kNeg][kTPC][ipart] < fDownTPCPIDneg[ipart]) || (fDetPID[kPos][kTPC][ipart] < fDownTPCPIDpos[ipart])) return -12;
912     //} else {//for low momenta, combined PID from TOF and TPC is used to get rid of proton contamination
913     //if((fComPID[kNeg][ipart] > fDownComPIDneg[ipart]) && (fComPID[kPos][ipart] > fDownComPIDpos[ipart])) return 1;
914     //}
915     if(!(TPCdEdxCuts(ipart, track))){//momentary solution for direct TPC dE/dx cut
916       return -12;
917     }
918     
919   }
920   
921  
922   //Armenteros-Polanski cut
923   if(!(fArmenteros[iDecay])) return -13;
924   
925   //Kalman filter Chi2/NDF cut
926   if(fChi2ndf[iDecay] > fUpChi2ndf[iDecay]) return -14;
927
928   //Invariant mass cut for K0s and photons, assuming two pions/two electrons as daughters:
929  
930   if((fInvMass[iDecay] > fUpInvMass[iDecay][iPSlot]) || (fInvMass[iDecay] < fDownInvMass[iDecay])) {
931     return -15;
932     
933   }
934    
935   return 1;
936 }
937
938
939 //_________________________________________________
940 void AliTRDv0Info::Print(Option_t *opt) const
941 {
942   printf("V0 P[%d] N[%d]\n", fPindex, fNindex);
943   printf("  DCA[%5.3f] Radius[%5.3f]\n", fDCA, fRadius);
944   printf("  Angles : Pointing[%5.3f] Open[%5.3f] Psi[%5.3f]\n", fPointingAngle, fOpenAngle, fPsiPair);
945   if(strcmp(opt, "a")!=0) return;
946   printf("  Reconstructed PID\n"
947          "  sgn spec   ITS   TPC   TOF   COM\n");
948   for(Int_t idt=0; idt<kNDaughters; idt++){
949     printf("   %c", idt?'-':'+');
950     for(Int_t is(0); is<AliPID::kSPECIES; is++){ 
951       printf("%s%s%s", is==0?"   ":"       ", AliPID::ParticleShortName(is), (is==1||is==2)?"  ":"   ");
952       for(Int_t id(0); id<kNDetectors; id++){
953         printf("%5.1f ", 1.e2*fDetPID[idt][id][is]);
954       }
955       printf("%5.1f\n", 1.e2*fComPID[idt][is]);
956     }
957   }
958 }
959
960 //_________________________________________________
961 void AliTRDv0Info::SetV0tracks(AliESDtrack *p, AliESDtrack *n) 
962 {
963   fTrackP = p; fPindex = p->GetID();
964   fTrackN = n; fNindex = n->GetID();
965 }
966
967