]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TRD/qaRec/info/AliTRDv0Info.cxx
Fix compiler warnings
[u/mrichter/AliRoot.git] / TRD / qaRec / info / AliTRDv0Info.cxx
1 #include "TMath.h"
2 #include "AliESDtrack.h"
3 #include "AliESDEvent.h"
4 #include "AliESDv0.h"
5 #include "AliTRDv0Info.h"
6 #include "AliTRDtrackInfo.h"
7 #include "AliESDInputHandler.h"
8 #include "AliAnalysisManager.h"
9 #include "AliTRDtrackInfo.h"
10 #include "AliLog.h"
11
12 //Gathers all information necessary for reference data selection about the
13 //track and (in case) its corresponding V0.
14 //Carries out the selection of electrons (from gamma conversions), pions
15 //(from K0s decays) and protons (from Lambda and Anti-Lambda decays) by
16 //cuts specific for the respective decay and particle species.
17 //(M.Heide, 2009/10/06)
18
19 // Authors:
20 //   Alex Bercuci <A.Bercuci@gsi.de>
21 //   Alex Wilk    <wilka@uni-muenster.de>
22 //   Markus Heide <mheide@uni-muenster.de>
23 // 
24
25
26 ClassImp(AliTRDv0Info)
27
28 //_________________________________________________
29 AliTRDv0Info::AliTRDv0Info()
30   : TObject()
31   ,fESD(0x0)
32   ,fHasV0(0)      
33   ,fQuality(0)
34     
35   ,fMomentum(0)
36   ,fDCA(10)
37   ,fPointingAngle(10)
38   ,fOpenAngle(10)
39   ,fPsiPair(99)
40   ,fMagField(0)
41   ,fRadius(0)
42     
43   ,fTrackID(0)
44   ,fV0Momentum(0)
45
46
47   ,fTrackP(0x0)
48   ,fTrackN(0x0)
49   ,fTrack(0x0)
50   ,fNindex(0)
51   ,fPindex(0)
52   
53 {
54   memset(fPplus, 0, 2*kNlayer*sizeof(Float_t));
55   memset(fPminus, 0, 2*kNlayer*sizeof(Float_t));
56   memset(fDetPID, 0, 2*kNDaughters*kNDetectors*AliPID::kSPECIES*sizeof(Float_t));
57   memset(fInvMass, 0, kNMomBins*kNDecays*sizeof(Double_t));
58
59   /////////////////////////////////////////////////////////////////////////////
60   //Set Cut values: First specify decay in brackets, then the actual cut value!
61   ///////////////////////////////////////////////////////////////////////////// 
62
63   //Upper limit for distance of closest approach of two daughter tracks :
64   fUpDCA[kGamma] = 0.25;
65   fUpDCA[kK0s] = 0.25;
66   fUpDCA[kLambda] = 0.25;
67   fUpDCA[kAntiLambda] = 0.25;
68
69   //Upper limit for pointing angle (= angle between between vector from primary to secondary vertex and reconstructed momentum of V0 mother particle) :
70   fUpPointingAngle[kGamma] = 0.03;
71   fUpPointingAngle[kK0s] = 0.03;
72   fUpPointingAngle[kLambda] = 0.03;
73   fUpPointingAngle[kAntiLambda] = 0.03;
74
75   //Upper limit for invariant mass of V0 mother :
76   fUpInvMass[kGamma][0] = 0.04;// second pair of brackets is for momentum bin: 0: below mother momentm of 2.5 GeV
77   fUpInvMass[kGamma][1] = 0.07;//1: above 2.5 GeV
78   fUpInvMass[kK0s][0] = fUpInvMass[kK0s][1] = 0.51;
79   fUpInvMass[kLambda][0] = fUpInvMass[kLambda][1] = 1.22;
80   fUpInvMass[kAntiLambda][0] = fUpInvMass[kAntiLambda][1] = 1.22;
81
82   //Lower limit for invariant mass of V0 mother :
83   fDownInvMass[kGamma] = -1.;
84   fDownInvMass[kK0s] = 0.49;
85   fDownInvMass[kLambda] = 1.;
86   fDownInvMass[kAntiLambda] = 1.;
87
88   //Lower limit for distance from secondary vertex to primary vertex in x-y plane :
89   fDownRadius[kGamma] = 5.7;
90   fDownRadius[kK0s] = 0.;
91   fDownRadius[kLambda] = 10.;
92   fDownRadius[kAntiLambda] = 10.;
93
94   //Upper limit for distance from secondary vertex to primary vertex in x-y plane :
95   fUpRadius[kGamma] = 1000.;
96   fUpRadius[kK0s] = 1000.;
97   fUpRadius[kLambda] = 1000.;
98   fUpRadius[kAntiLambda] = 1000.;
99
100   //Upper limit for opening angle between two daughter tracks (characteristically near zero for conversions) :
101   fUpOpenAngle[kGamma] = 0.1;
102   fUpOpenAngle[kK0s] = 3.15;
103   fUpOpenAngle[kLambda] = 3.15;
104   fUpOpenAngle[kAntiLambda] = 3.15;
105
106   //Upper limit for angle between daughter momentum plane and plane perpendicular to magnetic field (characteristically around zero for conversions) :
107   fUpPsiPair[kGamma] = 0.1;
108   fUpPsiPair[kK0s] = 1.6;
109   fUpPsiPair[kLambda] = 1.6;
110   fUpPsiPair[kAntiLambda] = 1.6;
111
112   //Lower limit for likelihood value of TPC PID :
113   fDownTPCPIDneg[AliPID::kElectron] = 0.21;
114   fDownTPCPIDpos[AliPID::kElectron] = 0.21;
115
116   fDownTPCPIDneg[AliPID::kMuon] = 0.21;
117   fDownTPCPIDpos[AliPID::kMuon] = 0.21;
118
119   fDownTPCPIDneg[AliPID::kPion] = 0.21;
120   fDownTPCPIDpos[AliPID::kPion] = 0.21;
121
122   fDownTPCPIDneg[AliPID::kKaon] = 0.21;
123   fDownTPCPIDpos[AliPID::kKaon] = 0.21;
124
125   fDownTPCPIDneg[AliPID::kProton] = 0.21;
126   fDownTPCPIDpos[AliPID::kProton] = 0.21;
127   //////////////////////////////////////////////////////////////////////////////////
128
129 }
130
131 //_________________________________________________
132 void AliTRDv0Info::GetESDv0Info(AliESDv0 *esdv0)
133 {//Gets values of ESDv0 and daughter track properties
134   //See header file for description of variables
135
136   Int_t part1 = -1;
137   Int_t part2 = -1;
138
139   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)    
140
141   fRadius = Radius(esdv0);//distance from secondary vertex to primary vertex in x-y plane
142       
143   fDCA = esdv0->GetDcaV0Daughters();//distance of closest approach of two daughter tracks
144       
145   fPointingAngle = TMath::ACos(esdv0->GetV0CosineOfPointingAngle());// pointing angle (= angle between between vector from primary to secondary vertex and reconstructed momentum of V0 mother particle)
146       
147   fOpenAngle = OpenAngle(esdv0);//Opening angle between two daughter tracks
148       
149   fPsiPair = PsiPair(esdv0);//Angle between daughter momentum plane and plane perpendicular to magnetic field
150
151   fV0Momentum = V0Momentum(esdv0);//Reconstructed momentum of the mother particle
152       
153   for(Int_t idecay = 0; idecay < kNDecays; idecay++)//4 decay types : conversions, K0s, Lambda, Anti-Lambda 
154     //five particle types: electrons, muons, pions, kaons, protons (muons and kaons not involved)
155     {
156       if(idecay == kLambda)//protons and pions from Lambda
157   {
158     part1 = AliPID::kProton;
159     part2 = AliPID::kPion;
160   }
161       else if(idecay == kAntiLambda)//antiprotons and pions from Anti-Lambda
162   {
163     part1 = AliPID::kPion;
164     part2 = AliPID::kProton;
165   }
166       else if(idecay == kK0s)//pions from K0s
167   part1 = part2 = AliPID::kPion;
168       else if(idecay == kGamma)//electrons from conversions
169   part1 = part2 = AliPID::kElectron;
170     
171       fInvMass[idecay] = InvMass(part1, part2, esdv0);//Calculate invariant mass for all of our four supposed decays
172     }
173   GetDetectorPID();//Gets all likelihood values from TPC, TOF and ITS PID for the fDetPID[kNDaughters][kNDetectors][AliPID::kSPECIES] array
174
175     
176 }
177 //_________________________________________________
178 Float_t  AliTRDv0Info::V0Momentum(AliESDv0 *esdv0)
179 {//Reconstructed momentum of V0 mother particle
180   Double_t mn[3] = {0,0,0};
181   Double_t mp[3] = {0,0,0};
182
183
184   esdv0->GetNPxPyPz(mn[0],mn[1],mn[2]);//reconstructed cartesian momentum components of negative daughter; 
185   esdv0->GetPPxPyPz(mp[0],mp[1],mp[2]);//reconstructed cartesian momentum components of positive daughter;
186   
187   
188   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]));
189 }
190
191 //_________________________________________________
192 Double_t AliTRDv0Info::InvMass(Int_t part1, Int_t part2, AliESDv0 *esdv0)
193 {//Invariant mass of reconstructed V0 mother
194
195   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)};
196   //Masses of electrons, muons, pions, kaons and protons, as implemented in ROOT
197
198
199   Double_t mn[3] = {0,0,0};
200   Double_t mp[3] = {0,0,0};  
201
202   esdv0->GetNPxPyPz(mn[0],mn[1],mn[2]);//reconstructed cartesian momentum components of negative daughter;
203   esdv0->GetPPxPyPz(mp[0],mp[1],mp[2]);//reconstructed cartesian momentum components of positive daughter;
204   
205   Double_t mass1 = kpmass[part1];//sets supposed rest masses for both daughters
206   Double_t mass2 = kpmass[part2];   
207
208   //Calculate daughters' energies :
209   Double_t e1    = TMath::Sqrt(mass1*mass1+
210             mp[0]*mp[0]+
211             mp[1]*mp[1]+
212             mp[2]*mp[2]);
213   Double_t e2    = TMath::Sqrt(mass2*mass2+
214             mn[0]*mn[0]+
215             mn[1]*mn[1]+
216             mn[2]*mn[2]);  
217
218   //Sum of daughter momenta :   
219   Double_t momsum =  
220     (mn[0]+mp[0])*(mn[0]+mp[0])+
221     (mn[1]+mp[1])*(mn[1]+mp[1])+
222     (mn[2]+mp[2])*(mn[2]+mp[2]);
223
224   //invariant mass :                 
225   Double_t mInv = TMath::Sqrt((e1+e2)*(e1+e2)-momsum);
226
227   return mInv;
228   
229 }
230 //_________________________________________________
231 Float_t AliTRDv0Info::OpenAngle(AliESDv0 *esdv0)
232 {//Opening angle between two daughter tracks
233   Double_t mn[3] = {0,0,0};
234   Double_t mp[3] = {0,0,0};
235     
236
237   esdv0->GetNPxPyPz(mn[0],mn[1],mn[2]);//reconstructed cartesian momentum components of negative daughter;
238   esdv0->GetPPxPyPz(mp[0],mp[1],mp[2]);//reconstructed cartesian momentum components of positive daughter;
239
240   
241   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])));
242   
243   return fOpenAngle;
244 }
245
246 //_________________________________________________
247 Float_t AliTRDv0Info::PsiPair(AliESDv0 *esdv0)
248 {//Angle between daughter momentum plane and plane perpendicular to magnetic field
249   Double_t x, y, z;
250   esdv0->GetXYZ(x,y,z);//Reconstructed coordinates of V0; to be replaced by Markus Rammler's method in case of conversions!
251   
252   Double_t mn[3] = {0,0,0};
253   Double_t mp[3] = {0,0,0};
254   
255
256   esdv0->GetNPxPyPz(mn[0],mn[1],mn[2]);//reconstructed cartesian momentum components of negative daughter;
257   esdv0->GetPPxPyPz(mp[0],mp[1],mp[2]);//reconstructed cartesian momentum components of positive daughter; 
258
259
260   Double_t deltat = 1.;
261   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
262
263   Double_t radiussum = TMath::Sqrt(x*x + y*y) + 50;//radius to which tracks shall be propagated
264
265   Double_t MomPosProp[3];
266   Double_t MomNegProp[3];
267     
268   AliExternalTrackParam nt(*fTrackN), pt(*fTrackP);
269     
270   fPsiPair = 4.;
271
272   if(nt.PropagateTo(radiussum,fMagField) == 0)//propagate tracks to the outside
273     fPsiPair =  -5.;
274   if(pt.PropagateTo(radiussum,fMagField) == 0)
275     fPsiPair = -5.;
276   pt.GetPxPyPz(MomPosProp);//Get momentum vectors of tracks after propagation
277   nt.GetPxPyPz(MomNegProp);
278   
279   Double_t p_ele =
280     TMath::Sqrt(MomNegProp[0]*MomNegProp[0]+MomNegProp[1]*MomNegProp[1]+MomNegProp[2]*MomNegProp[2]);//absolute momentum value of negative daughter
281   Double_t p_pos =
282     TMath::Sqrt(MomPosProp[0]*MomPosProp[0]+MomPosProp[1]*MomPosProp[1]+MomPosProp[2]*MomPosProp[2]);//absolute momentum value of positive daughter
283     
284   Double_t scalarproduct =
285     MomPosProp[0]*MomNegProp[0]+MomPosProp[1]*MomNegProp[1]+MomPosProp[2]*MomNegProp[2];//scalar product of propagated positive and negative daughters' momenta
286     
287   Double_t chipair = TMath::ACos(scalarproduct/(p_ele*p_pos));//Angle between propagated daughter tracks
288
289   fPsiPair =  TMath::Abs(TMath::ASin(deltat/chipair));  
290
291   return fPsiPair; 
292
293 }
294 //_________________________________________________
295 void AliTRDv0Info::V0fromTrack(AliTRDtrackInfo *track, Int_t ivertex)
296 {//Checks if track is a secondary vertex daughter (due to V0 finder)
297   
298   fMagField = fESD->GetMagneticField();
299
300   fTrackID =  track->GetTrackId();//index of the track
301
302   fTrack = fESD->GetTrack(fTrackID);//sets track information
303
304   fHasV0 = 0;
305
306   //comparing index of track with indices of pos./neg. V0 daughter :
307   AliESDv0 * esdv0 = fESD->GetV0(ivertex);
308   if((esdv0->GetIndex(0) == fTrackID)||(esdv0->GetIndex(1) == fTrackID))
309     {
310       fHasV0 = 1;//track belongs to vertex found by V0 finder!
311       fNindex = esdv0->GetIndex(0);
312       fPindex = esdv0->GetIndex(1);
313       fTrackN = fESD->GetTrack(esdv0->GetIndex(0));//providing information about the other of the two daughter tracks 
314       fTrackP = fESD->GetTrack(esdv0->GetIndex(1));
315       GetESDv0Info(esdv0);//gets all the relevant information about our V0
316     }
317 }
318 //_________________________________________________
319 void AliTRDv0Info::GetDetectorPID()
320 {//PID likelihoods from TPC, TOF, and ITS, for all particle species
321
322   fTrackN->GetTPCpid(fDetPID[kNeg][kTPC]);
323   fTrackP->GetTPCpid(fDetPID[kPos][kTPC]);
324   fTrackN->GetTOFpid(fDetPID[kNeg][kTOF]);
325   fTrackP->GetTOFpid(fDetPID[kPos][kTOF]);
326   fTrackN->GetITSpid(fDetPID[kNeg][kITS]);
327   fTrackP->GetITSpid(fDetPID[kPos][kITS]);
328
329 }
330
331 //_________________________________________________
332 Float_t AliTRDv0Info::Radius(AliESDv0 *esdv0)
333 {//distance from secondary vertex to primary vertex in x-y plane
334   Double_t x, y, z;
335   esdv0->GetXYZ(x,y,z); //Reconstructed coordinates of V0; to be replaced by Markus Rammler's method in case of conversions!
336   fRadius = TMath::Sqrt(x*x + y*y);
337   return fRadius;
338
339 }
340 //_________________________________________________
341 Int_t AliTRDv0Info::Quality(AliESDv0 *esdv0)
342 { //Checking track and V0 quality status in order to exclude vertices based on poor information
343   Float_t NclsN;
344   NclsN = fTrackN->GetTPCNcls();//number of found clusters in TPC for negative track
345   Float_t NclsFN;
346   NclsFN = fTrackN->GetTPCNclsF();//number of findable clusters in TPC for negative track
347   Float_t NclsP;
348   NclsP = fTrackP->GetTPCNcls();//number of found clusters in TPC for positive track
349   Float_t NclsFP;
350   NclsFP = fTrackP->GetTPCNclsF();//number of findable clusters in TPC for positive track
351   
352   fQuality = 0;
353
354
355   Float_t ClsRatioN; 
356   Float_t ClsRatioP;
357
358   if((NclsFN == 0) || (NclsFP == 0))
359     return 2;
360     
361   ClsRatioN = NclsN/NclsFN; //ratios of found to findable clusters in TPC 
362   ClsRatioP = NclsP/NclsFP;
363     
364   if (!(esdv0->GetOnFlyStatus()))//accept only vertices from online V0 finder
365     return 3;
366   if (!((fTrackP->GetStatus() &
367   AliESDtrack::kTPCrefit)))//accept only vertices in which both tracks have TPC refit
368     return 4;
369   if (!((fTrackN->GetStatus() &
370   AliESDtrack::kTPCrefit)))
371     return 5;   
372   if (fTrackP->GetKinkIndex(0)>0  ||
373       fTrackN->GetKinkIndex(0)>0 )//exclude tracks with kinks
374     return 6;
375   if((ClsRatioN < 0.6)||(ClsRatioP < 0.6))//exclude tracks with low ratio of found to findable TPC clusters
376     return 7;
377   fQuality = 1;
378   return fQuality;
379 }
380 //_________________________________________________
381 Bool_t AliTRDv0Info::GetV0PID(Int_t ipart, AliTRDtrackInfo *track)
382 {//decides if track is accepted for one of the reference data samples
383   
384   Int_t iDecay = -1;
385
386   //decide which decay has to be considered for which particle sample (Anti-Lambda will be treated separately)
387   if(ipart == AliPID::kElectron)
388     iDecay = kGamma;
389   else if(ipart == AliPID::kPion)
390     iDecay = kK0s;
391   else if(ipart == AliPID::kProton)
392     iDecay = kLambda;
393
394   Int_t iPSlot;//Mother momentum slots above/below 2.5 GeV
395
396   
397   Bool_t pid = 0;//return value for V0 PID decision
398
399   if(!(track))
400     {
401       AliError("AliTRDv0Info::GetV0PID(Int_t ipart, AliTRDtrackInfo *track) : No track info found.\n");
402       return 0;
403     }
404
405   AliESDInputHandler *esdH = dynamic_cast<AliESDInputHandler*>(AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
406   if(!esdH)
407     {
408       AliError("AliTRDv0Info::GetV0PID(Int_t ipart, AliTRDtrackInfo *track) : ERROR - ESD input handler not found");
409       return 0;
410     } 
411       
412   
413   fESD = esdH->GetEvent();
414   
415   for(Int_t ivertex=0; ivertex<fESD->GetNumberOfV0s(); ivertex++)
416     {
417     
418       if(pid == 0)
419   {     
420     V0fromTrack(track, ivertex);//Get the V0 corresponding to the track (if there is a V0)
421     
422     if(fV0Momentum > 2.5)//divide into slots according to reconstructed momentum of the mother particle
423       {iPSlot = 1;}
424     else
425       {iPSlot = 0;}
426     //Accept track for a sample only if...
427
428     if(!(fHasV0))//... there is a V0 found for it
429       continue;
430     if(!(fQuality == 1))//... it fulfills our quality criteria
431       continue;
432     if(!(fDCA < fUpDCA[iDecay]))//... distance of closest approach between daughters is reasonably small
433       continue;
434     if(!(fPointingAngle < fUpPointingAngle[iDecay]))//... pointing angle between momentum of mother particle and vector from prim. to sec. vertex is small
435       continue;                           
436     if(!(fRadius > fDownRadius[iDecay]))//... x-y plane distance of decay point to prim. vertex is bigger than a certain minimum value (for conversions)
437       continue;
438     if(!(fOpenAngle < fUpOpenAngle[iDecay]))//... opening angle is close enough to zero (for conversions)
439       continue;
440     if(!(TMath::Abs(fPsiPair) < fUpPsiPair[iDecay]))//... Psi-pair angle is close enough to zero(for conversions)
441       continue;
442
443     //specific cut criteria :
444     if(ipart == AliPID::kProton)
445       {//for proton sample: separate treatment of Lamba and Anti-Lambda decays:
446         //for Anti-Lambda:
447         //TPC PID likelihoods high enough for pi+ and anti-proton ; invariant mass calculated postulating these two particle species...
448         if((fDetPID[kNeg][kTPC][AliPID::kProton] > fDownTPCPIDneg[AliPID::kProton]) && (fDetPID[kPos][kTPC][AliPID::kPion] > fDownTPCPIDpos[AliPID::kPion]))
449     {
450       if(fNindex == fTrackID)
451         {
452           if((fInvMass[kAntiLambda] < fUpInvMass[kAntiLambda][iPSlot]) && (fInvMass[kAntiLambda] > fDownInvMass[kAntiLambda]))
453       {
454         pid = 1;
455       }
456         }
457     }
458         //for Lambda:
459         //TPC PID likelihoods high enough for pi- and proton ; invariant mass calculated accordingly
460         if((fDetPID[kNeg][kTPC][AliPID::kPion] > fDownTPCPIDneg[AliPID::kPion]) && (fDetPID[kPos][kTPC][AliPID::kProton] > fDownTPCPIDpos[AliPID::kProton]))
461     {
462       if(fPindex == fTrackID)
463         {
464           if((fInvMass[kLambda] < fUpInvMass[kLambda][iPSlot]) && (fInvMass[kLambda] > fDownInvMass[kLambda]))
465       {
466         pid = 1;
467       }
468         }
469     }
470       }
471     //for photon and K0s decays: equal TPC PID likelihood criteria for both daughters ; invariant mass calculated postulating two electrons/two pions
472     else                  
473       if((fDetPID[kNeg][kTPC][ipart] > fDownTPCPIDneg[ipart]) && (fDetPID[kPos][kTPC][ipart] > fDownTPCPIDpos[ipart]))
474         {
475     if((fInvMass[iDecay] < fUpInvMass[iDecay][iPSlot]) && (fInvMass[iDecay] > fDownInvMass[iDecay]))
476       {
477         pid = 1;                                                  
478       }
479         }
480   }
481     }
482
483   return pid;
484   
485 }
486 //_________________________________________________
487 void AliTRDv0Info::Print(Option_t */*opt*/) const
488 {
489
490 }