]> git.uio.no Git - u/mrichter/AliRoot.git/blob - PWG1/TRD/info/AliTRDv0Info.cxx
restructured the class AliTRDv0Info
[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 #include "TMath.h"
37
38 #include "AliESDtrack.h"
39 #include "AliESDv0.h"
40 #include "AliLog.h"
41
42 #include "AliTRDv0Info.h"
43 #include "AliTRDtrackInfo.h"
44 #include "AliTRDtrackInfo.h"
45
46 ClassImp(AliTRDv0Info)
47
48 //_________________________________________________
49 AliTRDv0Info::AliTRDv0Info()
50   : TObject()
51   ,fQuality(0)
52   ,fDCA(10)
53   ,fPointingAngle(10)
54   ,fOpenAngle(10)
55   ,fPsiPair(99)
56   ,fMagField(0)
57   ,fRadius(0)
58   ,fV0Momentum(0)
59   ,fTrackP(NULL)
60   ,fTrackN(NULL)
61   ,fNindex(0)
62   ,fPindex(0)
63 {
64   //
65   // Default constructor
66   //
67
68   memset(fPplus, 0, 2*kNlayer*sizeof(Float_t));
69   memset(fPminus, 0, 2*kNlayer*sizeof(Float_t));
70   memset(fDetPID, 0, 2*kNDaughters*kNDetectors*AliPID::kSPECIES*sizeof(Float_t));
71   memset(fComPID, 0, 2*kNDaughters*AliPID::kSPECIES*sizeof(Float_t));
72   memset(fInvMass, 0, kNMomBins*kNDecays*sizeof(Double_t));
73
74   /////////////////////////////////////////////////////////////////////////////
75   //Set Cut values: First specify decay in brackets, then the actual cut value!
76   ///////////////////////////////////////////////////////////////////////////// 
77
78   //Upper limit for distance of closest approach of two daughter tracks :
79   fUpDCA[kGamma] = 1000.;
80   fUpDCA[kK0s] = 0.08;
81   fUpDCA[kLambda] = 0.2;
82   fUpDCA[kAntiLambda] = 0.2;
83
84   //Upper limit for pointing angle (= angle between between vector from primary to secondary vertex and reconstructed momentum of V0 mother particle) :
85   fUpPointingAngle[kGamma] = 0.03;
86   fUpPointingAngle[kK0s] = 0.03;
87   fUpPointingAngle[kLambda] = 0.04;
88   fUpPointingAngle[kAntiLambda] = 0.04;
89
90   //Upper limit for invariant mass of V0 mother :
91   fUpInvMass[kGamma][0] = 0.05;// second pair of brackets is for momentum bin: 0: below mother momentm of 2.5 GeV
92   fUpInvMass[kGamma][1] = 0.07;//1: above 2.5 GeV
93   fUpInvMass[kK0s][0] = fUpInvMass[kK0s][1] = 0.50265;
94   fUpInvMass[kLambda][0] = fUpInvMass[kLambda][1] = 1.1207;
95   fUpInvMass[kAntiLambda][0] = fUpInvMass[kAntiLambda][1] = 1.1207;
96
97   //Lower limit for invariant mass of V0 mother :
98   fDownInvMass[kGamma] = -1.;
99   fDownInvMass[kK0s] = 0.49265;
100   fDownInvMass[kLambda] = 1.107;
101   fDownInvMass[kAntiLambda] = 1.107;
102
103   //Lower limit for distance from secondary vertex to primary vertex in x-y plane :
104   fDownRadius[kGamma] = 6.;
105   fDownRadius[kK0s] = 0.;
106   fDownRadius[kLambda] = 0.;
107   fDownRadius[kAntiLambda] = 0.;
108
109   //Upper limit for distance from secondary vertex to primary vertex in x-y plane :
110   fUpRadius[kGamma] = 1000.;
111   fUpRadius[kK0s] = 20.;
112   fUpRadius[kLambda] = 1000.;
113   fUpRadius[kAntiLambda] = 1000.;
114
115   //Upper limit for opening angle between two daughter tracks (characteristically near zero for conversions) :
116   fUpOpenAngle[kGamma] = 0.1;
117   fUpOpenAngle[kK0s] = 3.15;
118   fUpOpenAngle[kLambda] = 3.15;
119   fUpOpenAngle[kAntiLambda] = 3.15;
120
121   //Upper limit for angle between daughter momentum plane and plane perpendicular to magnetic field (characteristically around zero for conversions) :
122   fUpPsiPair[kGamma] = 0.05;
123   fUpPsiPair[kK0s] = 1.6;
124   fUpPsiPair[kLambda] = 1.6;
125   fUpPsiPair[kAntiLambda] = 1.6;
126
127   //Lower limit for likelihood value of TPC PID :
128   fDownTPCPIDneg[AliPID::kElectron] = 0.21;
129   fDownTPCPIDpos[AliPID::kElectron] = 0.21;
130
131   fDownTPCPIDneg[AliPID::kMuon] = 0.21;
132   fDownTPCPIDpos[AliPID::kMuon] = 0.21;
133
134   fDownTPCPIDneg[AliPID::kPion] = 0.21;
135   fDownTPCPIDpos[AliPID::kPion] = 0.21;
136
137   fDownTPCPIDneg[AliPID::kKaon] = 0.21;
138   fDownTPCPIDpos[AliPID::kKaon] = 0.21;
139
140   fDownTPCPIDneg[AliPID::kProton] = 0.21;
141   fDownTPCPIDpos[AliPID::kProton] = 0.21;
142
143  //Lower limit for likelihood value of combined PID :
144   fDownComPIDneg[AliPID::kElectron] = 0.21;
145   fDownComPIDpos[AliPID::kElectron] = 0.21;
146
147   fDownComPIDneg[AliPID::kMuon] = 0.21;
148   fDownComPIDpos[AliPID::kMuon] = 0.21;
149
150   fDownComPIDneg[AliPID::kPion] = 0.9;
151   fDownComPIDpos[AliPID::kPion] = 0.9;
152
153   fDownComPIDneg[AliPID::kKaon] = 0.21;
154   fDownComPIDpos[AliPID::kKaon] = 0.21;
155
156   fDownComPIDneg[AliPID::kProton] = 0.9;
157   fDownComPIDpos[AliPID::kProton] = 0.9;
158
159  //Lower limit for likelihood value of combined PID for daughter track which doesn't enter reference data (here: pion daughters from Lambda decays:
160   fDownComPIDnegPart[AliPID::kElectron] = 0.05;
161   fDownComPIDposPart[AliPID::kElectron] = 0.05;
162
163   fDownComPIDnegPart[AliPID::kMuon] = 0.05;
164   fDownComPIDposPart[AliPID::kMuon] = 0.05;
165
166   fDownComPIDnegPart[AliPID::kPion] = 0.05;
167   fDownComPIDposPart[AliPID::kPion] = 0.05;
168
169   fDownComPIDnegPart[AliPID::kKaon] = 0.05;
170   fDownComPIDposPart[AliPID::kKaon] = 0.05;
171
172   fDownComPIDnegPart[AliPID::kProton] = 0.05;
173   fDownComPIDposPart[AliPID::kProton] = 0.05;
174 }
175
176 //_________________________________________________
177 AliTRDv0Info::AliTRDv0Info(const AliTRDv0Info &ref)
178   : TObject()
179   ,fQuality(ref.fQuality)
180   ,fDCA(ref.fDCA)
181   ,fPointingAngle(ref.fPointingAngle)
182   ,fOpenAngle(ref.fOpenAngle)
183   ,fPsiPair(ref.fPsiPair)
184   ,fMagField(ref.fMagField)
185   ,fRadius(ref.fMagField)
186   ,fV0Momentum(ref.fV0Momentum)
187   ,fTrackP(ref.fTrackP)
188   ,fTrackN(ref.fTrackN)
189   ,fNindex(ref.fNindex)
190   ,fPindex(ref.fPindex)
191 {
192   //
193   // Copy constructor
194   //
195
196   memcpy(fPplus, ref.fPplus, 2*kNlayer*sizeof(Float_t));
197   memcpy(fPminus, ref.fPminus, 2*kNlayer*sizeof(Float_t));
198   memcpy(fDetPID, ref.fDetPID, 2*kNDaughters*kNDetectors*AliPID::kSPECIES*sizeof(Float_t));
199   memcpy(fComPID, ref.fComPID, 2*kNDaughters*AliPID::kSPECIES*sizeof(Float_t));
200   memcpy(fInvMass, ref.fInvMass, kNMomBins*kNDecays*sizeof(Double_t));
201
202   //Upper limit for distance of closest approach of two daughter tracks :
203   memcpy(fUpDCA, ref.fUpDCA, kNDecays*sizeof(Float_t));
204   memcpy(fUpPointingAngle, ref.fUpPointingAngle, kNDecays*sizeof(Float_t));
205   memcpy(fUpOpenAngle, ref.fUpOpenAngle, kNDecays*sizeof(Float_t));
206   memcpy(fDownOpenAngle, ref.fDownOpenAngle, kNDecays*sizeof(Float_t));
207   memcpy(fUpPsiPair, ref.fUpPsiPair, kNDecays*sizeof(Float_t));
208   memcpy(fDownPsiPair, ref.fDownPsiPair, kNDecays*sizeof(Float_t));
209   memcpy(fUpInvMass, ref.fUpInvMass, kNDecays*kNMomBins*sizeof(Double_t));
210   memcpy(fDownInvMass, ref.fDownInvMass, kNDecays*sizeof(Double_t));
211   memcpy(fUpRadius, ref.fUpRadius, kNDecays*sizeof(Float_t));
212   memcpy(fDownRadius, ref.fDownRadius, kNDecays*sizeof(Float_t));
213   memcpy(fDownTPCPIDneg, ref.fDownTPCPIDneg, AliPID::kSPECIES*sizeof(Float_t));
214   memcpy(fDownTPCPIDpos, ref.fDownTPCPIDpos, AliPID::kSPECIES*sizeof(Float_t));
215   memcpy(fDownComPIDneg, ref.fDownComPIDneg, AliPID::kSPECIES*sizeof(Float_t));
216   memcpy(fDownComPIDpos, ref.fDownComPIDpos, AliPID::kSPECIES*sizeof(Float_t));
217   memcpy(fDownComPIDnegPart, ref.fDownComPIDnegPart, AliPID::kSPECIES*sizeof(Float_t));
218   memcpy(fDownComPIDposPart, ref.fDownComPIDposPart, AliPID::kSPECIES*sizeof(Float_t));
219 }
220
221 //_________________________________________________
222 void AliTRDv0Info::SetV0Info(AliESDv0 *esdv0)
223 {//Gets values of ESDv0 and daughter track properties
224   //See header file for description of variables
225
226   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)    
227
228   fRadius = Radius(esdv0);//distance from secondary vertex to primary vertex in x-y plane
229       
230   fDCA = esdv0->GetDcaV0Daughters();//distance of closest approach of two daughter tracks
231       
232   fPointingAngle = TMath::ACos(esdv0->GetV0CosineOfPointingAngle());// pointing angle (= angle between between vector from primary to secondary vertex and reconstructed momentum of V0 mother particle)
233       
234   fOpenAngle = OpenAngle(esdv0);//Opening angle between two daughter tracks
235       
236   fPsiPair = PsiPair(esdv0);//Angle between daughter momentum plane and plane perpendicular to magnetic field
237
238   fV0Momentum = V0Momentum(esdv0);//Reconstructed momentum of the mother particle
239       
240   //4 decay types : conversions, K0s, Lambda, Anti-Lambda 
241     //five particle types: electrons, muons, pions, kaons, protons (muons and kaons not involved)
242   for(Int_t idecay(0), part1(-1), part2(-1); idecay < kNDecays; idecay++){
243     if(idecay == kLambda){ //protons and pions from Lambda
244       part1 = AliPID::kProton;
245       part2 = AliPID::kPion;
246     } else if(idecay == kAntiLambda) { //antiprotons and pions from Anti-Lambda
247       part1 = AliPID::kPion;
248       part2 = AliPID::kProton;
249     } else if(idecay == kK0s) {//pions from K0s
250       part1 = part2 = AliPID::kPion;
251     } else if(idecay == kGamma) {//electrons from conversions
252       part1 = part2 = AliPID::kElectron;
253     } 
254     fInvMass[idecay] = InvMass(part1, part2, esdv0);//Calculate invariant mass for all of our four supposed decays
255   }
256   //Gets all likelihood values from TPC, TOF and ITS PID for the fDetPID[kNDaughters][kNDetectors][AliPID::kSPECIES] array
257   GetDetectorPID();
258   //Bayesian combination of likelihoods from TPC and TOF
259   CombinePID();
260 }
261 //_________________________________________________
262 Float_t  AliTRDv0Info::V0Momentum(AliESDv0 *esdv0) const
263 {
264   //
265   // Reconstructed momentum of V0 mother particle
266   //
267
268   Double_t mn[3] = {0,0,0};
269   Double_t mp[3] = {0,0,0};
270
271
272   esdv0->GetNPxPyPz(mn[0],mn[1],mn[2]);//reconstructed cartesian momentum components of negative daughter; 
273   esdv0->GetPPxPyPz(mp[0],mp[1],mp[2]);//reconstructed cartesian momentum components of positive daughter;
274   
275   
276   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]));
277 }
278
279 //_________________________________________________
280 Double_t AliTRDv0Info::InvMass(Int_t part1, Int_t part2, AliESDv0 *esdv0) const
281 {
282   //
283   // Invariant mass of reconstructed V0 mother
284   //
285
286   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)};
287   //Masses of electrons, muons, pions, kaons and protons, as implemented in ROOT
288
289
290   Double_t mn[3] = {0,0,0};
291   Double_t mp[3] = {0,0,0};  
292
293   esdv0->GetNPxPyPz(mn[0],mn[1],mn[2]);//reconstructed cartesian momentum components of negative daughter;
294   esdv0->GetPPxPyPz(mp[0],mp[1],mp[2]);//reconstructed cartesian momentum components of positive daughter;
295   
296   Double_t mass1 = kpmass[part1];//sets supposed rest masses for both daughters
297   Double_t mass2 = kpmass[part2];   
298
299   //Calculate daughters' energies :
300   Double_t e1    = TMath::Sqrt(mass1*mass1+
301             mp[0]*mp[0]+
302             mp[1]*mp[1]+
303             mp[2]*mp[2]);
304   Double_t e2    = TMath::Sqrt(mass2*mass2+
305             mn[0]*mn[0]+
306             mn[1]*mn[1]+
307             mn[2]*mn[2]);  
308
309   //Sum of daughter momenta :   
310   Double_t momsum =  
311     (mn[0]+mp[0])*(mn[0]+mp[0])+
312     (mn[1]+mp[1])*(mn[1]+mp[1])+
313     (mn[2]+mp[2])*(mn[2]+mp[2]);
314
315   //invariant mass :                 
316   Double_t mInv = TMath::Sqrt((e1+e2)*(e1+e2)-momsum);
317
318   return mInv;
319   
320 }
321 //_________________________________________________
322 Float_t AliTRDv0Info::OpenAngle(AliESDv0 *esdv0)
323 {//Opening angle between two daughter tracks
324   Double_t mn[3] = {0,0,0};
325   Double_t mp[3] = {0,0,0};
326     
327
328   esdv0->GetNPxPyPz(mn[0],mn[1],mn[2]);//reconstructed cartesian momentum components of negative daughter;
329   esdv0->GetPPxPyPz(mp[0],mp[1],mp[2]);//reconstructed cartesian momentum components of positive daughter;
330
331   
332   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])));
333   
334   return fOpenAngle;
335 }
336
337 //_________________________________________________
338 Float_t AliTRDv0Info::PsiPair(AliESDv0 *esdv0)
339 {//Angle between daughter momentum plane and plane perpendicular to magnetic field
340   Double_t x, y, z;
341   esdv0->GetXYZ(x,y,z);//Reconstructed coordinates of V0; to be replaced by Markus Rammler's method in case of conversions!
342   
343   Double_t mn[3] = {0,0,0};
344   Double_t mp[3] = {0,0,0};
345   
346
347   esdv0->GetNPxPyPz(mn[0],mn[1],mn[2]);//reconstructed cartesian momentum components of negative daughter;
348   esdv0->GetPPxPyPz(mp[0],mp[1],mp[2]);//reconstructed cartesian momentum components of positive daughter; 
349
350
351   Double_t deltat = 1.;
352   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
353
354   Double_t radiussum = TMath::Sqrt(x*x + y*y) + 50;//radius to which tracks shall be propagated
355
356   Double_t momPosProp[3];
357   Double_t momNegProp[3];
358     
359   AliExternalTrackParam nt(*fTrackN), pt(*fTrackP);
360     
361   fPsiPair = 4.;
362
363   if(nt.PropagateTo(radiussum,fMagField) == 0)//propagate tracks to the outside
364     fPsiPair =  -5.;
365   if(pt.PropagateTo(radiussum,fMagField) == 0)
366     fPsiPair = -5.;
367   pt.GetPxPyPz(momPosProp);//Get momentum vectors of tracks after propagation
368   nt.GetPxPyPz(momNegProp);
369   
370   Double_t pEle =
371     TMath::Sqrt(momNegProp[0]*momNegProp[0]+momNegProp[1]*momNegProp[1]+momNegProp[2]*momNegProp[2]);//absolute momentum value of negative daughter
372   Double_t pPos =
373     TMath::Sqrt(momPosProp[0]*momPosProp[0]+momPosProp[1]*momPosProp[1]+momPosProp[2]*momPosProp[2]);//absolute momentum value of positive daughter
374     
375   Double_t scalarproduct =
376     momPosProp[0]*momNegProp[0]+momPosProp[1]*momNegProp[1]+momPosProp[2]*momNegProp[2];//scalar product of propagated positive and negative daughters' momenta
377     
378   Double_t chipair = TMath::ACos(scalarproduct/(pEle*pPos));//Angle between propagated daughter tracks
379
380   fPsiPair =  TMath::Abs(TMath::ASin(deltat/chipair));  
381
382   return fPsiPair; 
383
384 }
385
386 //_________________________________________________
387 Bool_t AliTRDv0Info::HasTrack(AliTRDtrackInfo * const track)
388 {
389 //Checks if track is a secondary vertex daughter (due to V0 finder)
390   
391   Int_t trackID(track->GetTrackId());//index of the track
392
393   //comparing index of track with indices of pos./neg. V0 daughter :
394   if((fNindex == trackID)||(fPindex == trackID)) return kTRUE;
395   return kFALSE;
396 }
397
398 //_________________________________________________
399 void AliTRDv0Info::GetDetectorPID()
400 {//PID likelihoods from TPC, TOF, and ITS, for all particle species
401
402   fTrackN->GetTPCpid(fDetPID[kNeg][kTPC]);
403   fTrackP->GetTPCpid(fDetPID[kPos][kTPC]);
404   fTrackN->GetTOFpid(fDetPID[kNeg][kTOF]);
405   fTrackP->GetTOFpid(fDetPID[kPos][kTOF]);
406   fTrackN->GetITSpid(fDetPID[kNeg][kITS]);
407   fTrackP->GetITSpid(fDetPID[kPos][kITS]);
408
409   Long_t statusN = fTrackN->GetStatus(); 
410   Long_t statusP = fTrackP->GetStatus(); 
411   
412   if(!(statusN & AliESDtrack::kTPCpid)){
413          for(Int_t iPart = 0; iPart < AliPID::kSPECIES; iPart++){
414         fDetPID[kNeg][kTPC][iPart] = 0.2;
415       }    
416   }
417   if(!(statusN & AliESDtrack::kTOFpid)){
418     for(Int_t iPart = 0; iPart < AliPID::kSPECIES; iPart++){
419       fDetPID[kNeg][kTOF][iPart] = 0.2;
420     }    
421     
422   }
423   if(!(statusN & AliESDtrack::kITSpid)){
424     for(Int_t iPart = 0; iPart < AliPID::kSPECIES; iPart++){
425       fDetPID[kNeg][kITS][iPart] = 0.2;
426     }    
427   }
428   if(!(statusP & AliESDtrack::kTPCpid)){
429     for(Int_t iPart = 0; iPart < AliPID::kSPECIES; iPart++){
430       fDetPID[kPos][kTPC][iPart] = 0.2;
431     }    
432   }
433   if(!(statusP & AliESDtrack::kTOFpid)){
434     for(Int_t iPart = 0; iPart < AliPID::kSPECIES; iPart++){
435       fDetPID[kPos][kTOF][iPart] = 0.2;
436     }    
437     
438   }
439   if(!(statusP & AliESDtrack::kITSpid)){
440     for(Int_t iPart = 0; iPart < AliPID::kSPECIES; iPart++){
441       fDetPID[kPos][kITS][iPart] = 0.2;
442     }    
443   }
444
445 }
446 //____________________________________________________________________________________
447 void AliTRDv0Info::CombinePID()
448 {
449   Double_t partrat[AliPID::kSPECIES] = {0.208, 0.010, 0.662, 0.019, 0.101};
450   
451   for(Int_t iSign = 0; iSign < kNDaughters; iSign++)
452     {
453     for(Int_t iPart = 0; iPart < AliPID::kSPECIES; iPart++)
454       {
455       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]));
456       
457       }
458     }
459 }
460 //_________________________________________________
461 Float_t AliTRDv0Info::Radius(AliESDv0 *esdv0)
462 {//distance from secondary vertex to primary vertex in x-y plane
463   Double_t x, y, z;
464   esdv0->GetXYZ(x,y,z); //Reconstructed coordinates of V0; to be replaced by Markus Rammler's method in case of conversions!
465   fRadius = TMath::Sqrt(x*x + y*y);
466   return fRadius;
467
468 }
469
470 //_________________________________________________
471 Int_t AliTRDv0Info::Quality(AliESDv0 *const esdv0)
472
473   //
474   // Checking track and V0 quality status in order to exclude vertices based on poor information
475   //
476
477   Float_t nClsN;
478   nClsN = fTrackN->GetTPCNcls();//number of found clusters in TPC for negative track
479   Float_t nClsFN;
480   nClsFN = fTrackN->GetTPCNclsF();//number of findable clusters in TPC for negative track
481   Float_t nClsP;
482   nClsP = fTrackP->GetTPCNcls();//number of found clusters in TPC for positive track
483   Float_t nClsFP;
484   nClsFP = fTrackP->GetTPCNclsF();//number of findable clusters in TPC for positive track
485   
486   fQuality = 0;
487
488
489   Float_t clsRatioN; 
490   Float_t clsRatioP;
491
492   if((nClsFN == 0) || (nClsFP == 0))
493     return 2;
494     
495   clsRatioN = nClsN/nClsFN; //ratios of found to findable clusters in TPC 
496   clsRatioP = nClsP/nClsFP;
497     
498   if (!(esdv0->GetOnFlyStatus()))//accept only vertices from online V0 finder
499     return 3;
500   if (!((fTrackP->GetStatus() &
501   AliESDtrack::kTPCrefit)))//accept only vertices in which both tracks have TPC refit
502     return 4;
503   if (!((fTrackN->GetStatus() &
504   AliESDtrack::kTPCrefit)))
505     return 5;   
506   if (fTrackP->GetKinkIndex(0)>0  ||
507       fTrackN->GetKinkIndex(0)>0 )//exclude tracks with kinks
508     return 6;
509   if((clsRatioN < 0.6)||(clsRatioP < 0.6))//exclude tracks with low ratio of found to findable TPC clusters
510     return 7;
511   fQuality = 1;
512   return fQuality;
513 }
514 //_________________________________________________
515 Int_t AliTRDv0Info::GetPID(Int_t ipart, AliTRDtrackInfo *track)
516 {
517 // Decides if track is accepted for one of the reference data samples
518   
519   if(!(track)) {
520     AliError("No track info");
521     return 0;
522   }
523   if(!HasTrack(track)){
524     AliDebug(2, "Track not attached to v0.");
525     return 0;
526   }
527   Int_t trackID(track->GetTrackId());
528
529   //translate ipart to decay (Anti-Lambda will be treated separately)
530   Int_t iDecay = -1;
531   switch(ipart){
532   case AliPID::kElectron: iDecay = kGamma; break;
533   case AliPID::kPion: iDecay = kK0s; break;
534   case AliPID::kProton: iDecay = kLambda; break;
535   default:
536     AliWarning(Form("Hypothesis \"ipart=%d\" not handled", ipart));
537     return 0;
538   }
539
540   //... it fulfills our quality criteria
541   if(!(fQuality == 1)) return 0;
542   //... distance of closest approach between daughters is reasonably small
543   if((fDCA > fUpDCA[iDecay])) return 0;
544   //... pointing angle between momentum of mother particle and vector from prim. to sec. vertex is small
545   if((fPointingAngle > fUpPointingAngle[iDecay])) return 0;
546   //... x-y plane distance of decay point to prim. vertex is bigger than a certain minimum value (for conversions)
547   if((fRadius < fDownRadius[iDecay])) return 0;
548   //...or smaller than a maximum value (for K0s)
549   if((fRadius > fUpRadius[iDecay])) return 0;
550   //... opening angle is close enough to zero (for conversions)
551   if((fOpenAngle > fUpOpenAngle[iDecay])) return 0;
552   //... Psi-pair angle is close enough to zero(for conversions)
553   if((TMath::Abs(fPsiPair) > fUpPsiPair[iDecay])) return 0;
554
555
556   //Mother momentum slots above/below 2.5 GeV
557   Int_t iPSlot(fV0Momentum > 2.5);
558
559   //specific cut criteria :
560   if(ipart == AliPID::kProton) {
561     if((fInvMass[kK0s] < fUpInvMass[kK0s][iPSlot]) && (fInvMass[kK0s] > fDownInvMass[kK0s])) return 0;//explicit exclusion of K0s decays
562   
563     //for proton sample: separate treatment of Lamba and Anti-Lambda decays:
564     //for Anti-Lambda:
565     //Combined PID likelihoods high enough for pi+ and anti-proton ; invariant mass calculated postulating these two particle species...
566     if((fComPID[kNeg][AliPID::kProton] > fDownComPIDneg[AliPID::kProton]) && (fComPID[kPos][AliPID::kPion] > fDownComPIDposPart[AliPID::kPion])) {
567       if(fNindex == trackID) {
568         if((fInvMass[kAntiLambda] < fUpInvMass[kAntiLambda][iPSlot]) && (fInvMass[kAntiLambda] > fDownInvMass[kAntiLambda])) return 1;
569       }
570     }
571     //for Lambda:
572     //TPC PID likelihoods high enough for pi- and proton ; invariant mass calculated accordingly
573     if((fComPID[kNeg][AliPID::kPion] > fDownComPIDnegPart[AliPID::kPion]) && (fComPID[kPos][AliPID::kProton] > fDownComPIDpos[AliPID::kProton])) {
574       if(fPindex == trackID) {
575         if((fInvMass[kLambda] < fUpInvMass[kLambda][iPSlot]) && (fInvMass[kLambda] > fDownInvMass[kLambda])) return 1;
576       }
577     }
578   }
579
580   //Invariant mass cut for K0s and photons, assuming two pions/two electrons as daughters:
581   if((fInvMass[iDecay] > fUpInvMass[iDecay][iPSlot]) || (fInvMass[iDecay] < fDownInvMass[iDecay])) return 0;
582
583   //for K0s decays: equal TPC PID likelihood criteria for both daughters ; invariant mass calculated postulating two pions
584   if(ipart == AliPID::kPion) {
585     //explicit exclusion of Lambda decays
586     if((fInvMass[kLambda] < fUpInvMass[kLambda][iPSlot]) && (fInvMass[kLambda] > fDownInvMass[kLambda])) return 0;
587     //explicit exclusion of Anti-Lambda decays
588     if((fInvMass[kAntiLambda] < fUpInvMass[kAntiLambda][iPSlot]) && (fInvMass[kAntiLambda] > fDownInvMass[kAntiLambda])) return 0;
589
590     if((fDetPID[kNeg][kTPC][ipart] > fDownTPCPIDneg[ipart]) && (fDetPID[kPos][kTPC][ipart] > fDownTPCPIDpos[ipart])) return 1;
591   }
592
593   //for photon conversions: equal combined PID likelihood criteria for both daughters ; invariant mass calculated postulating two electrons
594   //No Lambda/K0s exclusion is provided, since these contributions hardly ever interfere with gamma invariant mass!
595   Float_t momentum(track->GetESDinfo()->GetOuterParam()->P());
596   if(ipart == AliPID::kElectron) {
597     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
598       if((fDetPID[kNeg][kTPC][ipart] > fDownTPCPIDneg[ipart]) && (fDetPID[kPos][kTPC][ipart] > fDownTPCPIDpos[ipart])) return 1;
599     } else {//for low momenta, combined PID from TOF and TPC is used to get rid of proton contamination
600       if((fComPID[kNeg][ipart] > fDownComPIDneg[ipart]) && (fComPID[kPos][ipart] > fDownComPIDpos[ipart])) return 1;
601     }
602   }
603   return 0;
604 }
605
606
607 //_________________________________________________
608 void AliTRDv0Info::Print(Option_t */*opt*/) const
609 {
610
611 }