#include "TMath.h"
#include "TDatabasePDG.h"
#include "AliESDtrack.h"
#include "AliESDv0.h"
#include "AliLog.h"
#include "TVector3.h"
#include "AliKFParticle.h"
#include "AliKFVertex.h"
#include "AliTRDv0Info.h"
#include "AliTRDtrackInfo.h"
#include "AliTRDtrackInfo.h"
ClassImp(AliTRDv0Info)
AliTRDv0Info::AliTRDv0Info()
: TObject()
,fQuality(0)
,fDCA(10)
,fPointingAngle(10)
,fOpenAngle(10)
,fPsiPair(99)
,fMagField(0)
,fRadius(0)
,fV0Momentum(0)
,fNindex(0)
,fPindex(0)
,fInputEvent(NULL)
,fPrimaryVertex(NULL)
,fTrackP(NULL)
,fTrackN(NULL)
{
memset(fDetPID, 0, 2*kNDaughters*kNDetectors*AliPID::kSPECIES*sizeof(Float_t));
memset(fComPID, 0, 2*kNDaughters*AliPID::kSPECIES*sizeof(Float_t));
memset(fInvMass, 0, kNDecays*sizeof(Double_t));
memset(fArmenteros, 0, kNDecays*sizeof(Bool_t));
memset(fTPCdEdx, 0, kNDaughters*sizeof(Float_t));
memset(fChi2ndf, 0, kNDecays*sizeof(Double_t));
memset(fDownOpenAngle, 0, kNDecays*sizeof(Float_t));
memset(fDownPsiPair, 0, kNDecays*sizeof(Float_t));
fUpDCA[kGamma] = 1000.;
fUpDCA[kK0s] = 0.08;
fUpDCA[kLambda] = 0.2;
fUpDCA[kAntiLambda] = 0.2;
fUpPointingAngle[kGamma] = 0.03;
fUpPointingAngle[kK0s] = 0.03;
fUpPointingAngle[kLambda] = 0.04;
fUpPointingAngle[kAntiLambda] = 0.04;
fUpInvMass[kGamma][0] = 0.05;
fUpInvMass[kGamma][1] = 0.07;
fUpInvMass[kK0s][0] = fUpInvMass[kK0s][1] = 0.50265;
fUpInvMass[kLambda][0] = fUpInvMass[kLambda][1] = 1.1207;
fUpInvMass[kAntiLambda][0] = fUpInvMass[kAntiLambda][1] = 1.1207;
fDownInvMass[kGamma] = -1.;
fDownInvMass[kK0s] = 0.49265;
fDownInvMass[kLambda] = 1.107;
fDownInvMass[kAntiLambda] = 1.107;
fUpChi2ndf[kGamma] = 10000.;
fUpChi2ndf[kK0s] = 10000.;
fUpChi2ndf[kLambda] = 10000.;
fUpChi2ndf[kAntiLambda] = 10000.;
fDownRadius[kGamma] = 6.;
fDownRadius[kK0s] = 0.;
fDownRadius[kLambda] = 0.;
fDownRadius[kAntiLambda] = 0.;
fUpRadius[kGamma] = 1000.;
fUpRadius[kK0s] = 20.;
fUpRadius[kLambda] = 1000.;
fUpRadius[kAntiLambda] = 1000.;
fUpOpenAngle[kGamma] = 0.1;
fUpOpenAngle[kK0s] = 3.15;
fUpOpenAngle[kLambda] = 3.15;
fUpOpenAngle[kAntiLambda] = 3.15;
fUpPsiPair[kGamma] = 0.05;
fUpPsiPair[kK0s] = 1.6;
fUpPsiPair[kLambda] = 1.6;
fUpPsiPair[kAntiLambda] = 1.6;
fDownTPCPIDneg[AliPID::kElectron] = 0.;
fDownTPCPIDpos[AliPID::kElectron] = 0.;
fDownTPCPIDneg[AliPID::kMuon] = 0.;
fDownTPCPIDpos[AliPID::kMuon] = 0.;
fDownTPCPIDneg[AliPID::kPion] = 0.;
fDownTPCPIDpos[AliPID::kPion] = 0.;
fDownTPCPIDneg[AliPID::kKaon] = 0.;
fDownTPCPIDpos[AliPID::kKaon] = 0.;
fDownTPCPIDneg[AliPID::kProton] = 0.;
fDownTPCPIDpos[AliPID::kProton] = 0.;
fDownComPIDneg[AliPID::kElectron] = 0.;
fDownComPIDpos[AliPID::kElectron] = 0.;
fDownComPIDneg[AliPID::kMuon] = 0.;
fDownComPIDpos[AliPID::kMuon] = 0.;
fDownComPIDneg[AliPID::kPion] = 0.;
fDownComPIDpos[AliPID::kPion] = 0.;
fDownComPIDneg[AliPID::kKaon] = 0.;
fDownComPIDpos[AliPID::kKaon] = 0.;
fDownComPIDneg[AliPID::kProton] = 0.;
fDownComPIDpos[AliPID::kProton] = 0.;
fDownComPIDnegPart[AliPID::kElectron] = 0.;
fDownComPIDposPart[AliPID::kElectron] = 0.;
fDownComPIDnegPart[AliPID::kMuon] = 0.;
fDownComPIDposPart[AliPID::kMuon] = 0.;
fDownComPIDnegPart[AliPID::kPion] = 0.;
fDownComPIDposPart[AliPID::kPion] = 0.;
fDownComPIDnegPart[AliPID::kKaon] = 0.;
fDownComPIDposPart[AliPID::kKaon] = 0.;
fDownComPIDnegPart[AliPID::kProton] = 0.;
fDownComPIDposPart[AliPID::kProton] = 0.;
}
AliTRDv0Info::AliTRDv0Info(const AliTRDv0Info &ref)
: TObject((TObject&)ref)
,fQuality(ref.fQuality)
,fDCA(ref.fDCA)
,fPointingAngle(ref.fPointingAngle)
,fOpenAngle(ref.fOpenAngle)
,fPsiPair(ref.fPsiPair)
,fMagField(ref.fMagField)
,fRadius(ref.fRadius)
,fV0Momentum(ref.fV0Momentum)
,fNindex(ref.fNindex)
,fPindex(ref.fPindex)
,fInputEvent(ref.fInputEvent)
,fPrimaryVertex(ref.fPrimaryVertex)
,fTrackP(ref.fTrackP)
,fTrackN(ref.fTrackN)
{
memcpy(fDetPID, ref.fDetPID, 2*kNDaughters*kNDetectors*AliPID::kSPECIES*sizeof(Float_t));
memcpy(fComPID, ref.fComPID, 2*kNDaughters*AliPID::kSPECIES*sizeof(Float_t));
memcpy(fInvMass, ref.fInvMass, kNDecays*sizeof(Double_t));
memcpy(fArmenteros, ref.fArmenteros, kNDecays*sizeof(Bool_t));
memcpy(fChi2ndf, ref.fChi2ndf, kNDecays*sizeof(Double_t));
memcpy(fTPCdEdx, ref.fTPCdEdx, kNDaughters*sizeof(Float_t));
memcpy(fUpDCA, ref.fUpDCA, kNDecays*sizeof(Float_t));
memcpy(fUpPointingAngle, ref.fUpPointingAngle, kNDecays*sizeof(Float_t));
memcpy(fUpOpenAngle, ref.fUpOpenAngle, kNDecays*sizeof(Float_t));
memcpy(fDownOpenAngle, ref.fDownOpenAngle, kNDecays*sizeof(Float_t));
memcpy(fUpPsiPair, ref.fUpPsiPair, kNDecays*sizeof(Float_t));
memcpy(fDownPsiPair, ref.fDownPsiPair, kNDecays*sizeof(Float_t));
memcpy(fUpInvMass, ref.fUpInvMass, kNDecays*kNMomBins*sizeof(Double_t));
memcpy(fDownInvMass, ref.fDownInvMass, kNDecays*sizeof(Double_t));
memcpy(fUpChi2ndf, ref.fUpChi2ndf, kNDecays*sizeof(Double_t));
memcpy(fUpRadius, ref.fUpRadius, kNDecays*sizeof(Float_t));
memcpy(fDownRadius, ref.fDownRadius, kNDecays*sizeof(Float_t));
memcpy(fDownTPCPIDneg, ref.fDownTPCPIDneg, AliPID::kSPECIES*sizeof(Float_t));
memcpy(fDownTPCPIDpos, ref.fDownTPCPIDpos, AliPID::kSPECIES*sizeof(Float_t));
memcpy(fDownComPIDneg, ref.fDownComPIDneg, AliPID::kSPECIES*sizeof(Float_t));
memcpy(fDownComPIDpos, ref.fDownComPIDpos, AliPID::kSPECIES*sizeof(Float_t));
memcpy(fDownComPIDnegPart, ref.fDownComPIDnegPart, AliPID::kSPECIES*sizeof(Float_t));
memcpy(fDownComPIDposPart, ref.fDownComPIDposPart, AliPID::kSPECIES*sizeof(Float_t));
}
void AliTRDv0Info::SetV0Info(const AliESDv0 *esdv0)
{
fQuality = Quality(esdv0);
fRadius = Radius(esdv0);
fDCA = esdv0->GetDcaV0Daughters();
fPointingAngle = TMath::ACos(esdv0->GetV0CosineOfPointingAngle());
fOpenAngle = OpenAngle(esdv0);
fPsiPair = PsiPair(esdv0);
fV0Momentum = V0Momentum(esdv0);
for(Int_t idecay(0), part1(-1), part2(-1); idecay < kNDecays; idecay++){
fArmenteros[idecay]=Armenteros(esdv0, idecay);
switch(idecay){
case kLambda:
part1 = AliPID::kProton;
part2 = AliPID::kPion;
break;
case kAntiLambda:
part1 = AliPID::kPion;
part2 = AliPID::kProton;
break;
case kK0s:
part1 = part2 = AliPID::kPion;
break;
case kGamma:
part1 = part2 = AliPID::kElectron;
break;
}
fInvMass[idecay] = InvMass(part1, part2, esdv0);
}
GetDetectorPID();
CombinePID();
GetTPCdEdx();
}
Float_t AliTRDv0Info::V0Momentum(const AliESDv0 *esdv0) const
{
Double_t mn[3] = {0,0,0};
Double_t mp[3] = {0,0,0};
esdv0->GetNPxPyPz(mn[0],mn[1],mn[2]);
esdv0->GetPPxPyPz(mp[0],mp[1],mp[2]);
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]));
}
Double_t AliTRDv0Info::InvMass(Int_t part1, Int_t part2, const AliESDv0 *esdv0) const
{
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)};
Double_t mn[3] = {0,0,0};
Double_t mp[3] = {0,0,0};
esdv0->GetNPxPyPz(mn[0],mn[1],mn[2]);
esdv0->GetPPxPyPz(mp[0],mp[1],mp[2]);
Double_t mass1 = kpmass[part1];
Double_t mass2 = kpmass[part2];
Double_t e1 = TMath::Sqrt(mass1*mass1+
mp[0]*mp[0]+
mp[1]*mp[1]+
mp[2]*mp[2]);
Double_t e2 = TMath::Sqrt(mass2*mass2+
mn[0]*mn[0]+
mn[1]*mn[1]+
mn[2]*mn[2]);
Double_t momsum =
(mn[0]+mp[0])*(mn[0]+mp[0])+
(mn[1]+mp[1])*(mn[1]+mp[1])+
(mn[2]+mp[2])*(mn[2]+mp[2]);
Double_t mInv = TMath::Sqrt((e1+e2)*(e1+e2)-momsum);
return mInv;
}
Float_t AliTRDv0Info::OpenAngle(const AliESDv0 *esdv0)
{
Double_t mn[3] = {0,0,0};
Double_t mp[3] = {0,0,0};
esdv0->GetNPxPyPz(mn[0],mn[1],mn[2]);
esdv0->GetPPxPyPz(mp[0],mp[1],mp[2]);
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])));
return fOpenAngle;
}
Float_t AliTRDv0Info::PsiPair(const AliESDv0 *esdv0)
{
Double_t x, y, z;
esdv0->GetXYZ(x,y,z);
Double_t mn[3] = {0,0,0};
Double_t mp[3] = {0,0,0};
esdv0->GetNPxPyPz(mn[0],mn[1],mn[2]);
esdv0->GetPPxPyPz(mp[0],mp[1],mp[2]);
Double_t deltat = 1.;
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));
Double_t radiussum = TMath::Sqrt(x*x + y*y) + 50;
Double_t momPosProp[3];
Double_t momNegProp[3];
AliExternalTrackParam nt(*fTrackN), pt(*fTrackP);
fPsiPair = 4.;
if(nt.PropagateTo(radiussum,fMagField) == 0)
fPsiPair = -5.;
if(pt.PropagateTo(radiussum,fMagField) == 0)
fPsiPair = -5.;
pt.GetPxPyPz(momPosProp);
nt.GetPxPyPz(momNegProp);
Double_t pEle =
TMath::Sqrt(momNegProp[0]*momNegProp[0]+momNegProp[1]*momNegProp[1]+momNegProp[2]*momNegProp[2]);
Double_t pPos =
TMath::Sqrt(momPosProp[0]*momPosProp[0]+momPosProp[1]*momPosProp[1]+momPosProp[2]*momPosProp[2]);
Double_t scalarproduct =
momPosProp[0]*momNegProp[0]+momPosProp[1]*momNegProp[1]+momPosProp[2]*momNegProp[2];
Double_t chipair = TMath::ACos(scalarproduct/(pEle*pPos));
fPsiPair = TMath::Abs(TMath::ASin(deltat/chipair));
return fPsiPair;
}
Double_t AliTRDv0Info::KFChi2ndf(Int_t part1, Int_t part2,Int_t decay){
Int_t mothers[4]={22,310,3122,3122};
const Double_t partMass=TDatabasePDG::Instance()->GetParticle(mothers[decay])->Mass();
const Double_t massWidth[4] = {0.001, 0., 0., 0.};
AliKFParticle *kfMother = CreateMotherParticle(fTrackP, fTrackN, part1, part2);
if(!kfMother) {
return kFALSE;
}
kfMother->SetMassConstraint(partMass, massWidth[decay]);
Double_t chi2ndf = (kfMother->GetChi2()/kfMother->GetNDF());
if(kfMother)delete kfMother;
return chi2ndf;
}
AliKFParticle *AliTRDv0Info::CreateMotherParticle(const AliESDtrack *pdaughter, const AliESDtrack *ndaughter, Int_t pspec, Int_t nspec){
AliKFParticle pkfdaughter(*pdaughter, pspec);
AliKFParticle nkfdaughter(*ndaughter, nspec);
AliKFParticle *m = new AliKFParticle(pkfdaughter, nkfdaughter);
AliKFVertex improvedVertex = *fPrimaryVertex;
improvedVertex += *m;
m->SetProductionVertex(improvedVertex);
return m;
}
Int_t AliTRDv0Info::HasTrack(const AliTRDtrackInfo * const track) const
{
if(!track) return 0;
if(!fTrackP->GetID()) return 0;
if(!fTrackN->GetID()) return 0;
Int_t trackID(track->GetTrackId());
return HasTrack(trackID);
}
Int_t AliTRDv0Info::HasTrack(Int_t trackID) const
{
if(fNindex==trackID) return -1;
else if(fPindex==trackID) return 1;
else return 0;
}
void AliTRDv0Info::GetDetectorPID()
{
fTrackN->GetTPCpid(fDetPID[kNeg][kTPC]);
fTrackP->GetTPCpid(fDetPID[kPos][kTPC]);
fTrackN->GetTOFpid(fDetPID[kNeg][kTOF]);
fTrackP->GetTOFpid(fDetPID[kPos][kTOF]);
fTrackN->GetITSpid(fDetPID[kNeg][kITS]);
fTrackP->GetITSpid(fDetPID[kPos][kITS]);
Long_t statusN = fTrackN->GetStatus();
Long_t statusP = fTrackP->GetStatus();
if(!(statusN & AliESDtrack::kTPCpid)){
for(Int_t iPart = 0; iPart < AliPID::kSPECIES; iPart++){
fDetPID[kNeg][kTPC][iPart] = 0.2;
}
}
if(!(statusN & AliESDtrack::kTOFpid)){
for(Int_t iPart = 0; iPart < AliPID::kSPECIES; iPart++){
fDetPID[kNeg][kTOF][iPart] = 0.2;
}
}
if(!(statusN & AliESDtrack::kITSpid)){
for(Int_t iPart = 0; iPart < AliPID::kSPECIES; iPart++){
fDetPID[kNeg][kITS][iPart] = 0.2;
}
}
if(!(statusP & AliESDtrack::kTPCpid)){
for(Int_t iPart = 0; iPart < AliPID::kSPECIES; iPart++){
fDetPID[kPos][kTPC][iPart] = 0.2;
}
}
if(!(statusP & AliESDtrack::kTOFpid)){
for(Int_t iPart = 0; iPart < AliPID::kSPECIES; iPart++){
fDetPID[kPos][kTOF][iPart] = 0.2;
}
}
if(!(statusP & AliESDtrack::kITSpid)){
for(Int_t iPart = 0; iPart < AliPID::kSPECIES; iPart++){
fDetPID[kPos][kITS][iPart] = 0.2;
}
}
}
void AliTRDv0Info::CombinePID()
{
Double_t partrat[AliPID::kSPECIES] = {0.208, 0.010, 0.662, 0.019, 0.101};
for(Int_t iSign = 0; iSign < kNDaughters; iSign++)
{
for(Int_t iPart = 0; iPart < AliPID::kSPECIES; iPart++)
{
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]));
}
}
}
Bool_t AliTRDv0Info::GetTPCdEdx()
{
if(!fTrackP->GetID()) return 0;
if(!fTrackN->GetID()) return 0;
fTPCdEdx[kNeg] = fTrackN->GetTPCsignal();
fTPCdEdx[kPos] = fTrackP->GetTPCsignal();
return 1;
}
Bool_t AliTRDv0Info::TPCdEdxCuts(Int_t part, const AliTRDtrackInfo * const track)
{
if(!fTrackP->GetID()) return 0;
if(!fTrackN->GetID()) return 0;
Double_t alephParameters[5];
alephParameters[0] = 0.0283086;
alephParameters[1] = 2.63394e+01;
alephParameters[2] = 5.04114e-11;
alephParameters[3] = 2.12543e+00;
alephParameters[4] = 4.88663e+00;
Double_t deposit = 0;
Float_t x = 0;
if(HasTrack(track) == 1){
x = fTrackP->P();
deposit = fTPCdEdx[kPos];
}
else if(HasTrack(track) == -1){
x = fTrackN->P();
deposit = fTPCdEdx[kNeg];
}
else{
printf("No track found");
return 0;
}
if(x < 0.2)return 0;
Double_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.};
Double_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.};
if(x < 0.7){
downLimits[4]=90;
}
if(x < 1.25){
upLimits[0] = 85;
}
else{
downLimits[0] = 64;
}
if(deposit < downLimits[part])
return 0;
if(deposit > upLimits[part])
return 0;
return 1;
}
Float_t AliTRDv0Info::Radius(const AliESDv0 *esdv0)
{
Double_t x, y, z;
esdv0->GetXYZ(x,y,z);
fRadius = TMath::Sqrt(x*x + y*y);
return fRadius;
}
Int_t AliTRDv0Info::Quality(const AliESDv0 *const esdv0)
{
Float_t nClsN;
nClsN = fTrackN->GetTPCNcls();
Float_t nClsFN;
nClsFN = fTrackN->GetTPCNclsF();
Float_t nClsP;
nClsP = fTrackP->GetTPCNcls();
Float_t nClsFP;
nClsFP = fTrackP->GetTPCNclsF();
fQuality = 0;
if (!(esdv0->GetOnFlyStatus()))
return -1;
Float_t clsRatioN;
Float_t clsRatioP;
if((nClsFN < 80) || (nClsFP < 80)) return -2;
Int_t nTPCclustersP = fTrackP->GetTPCclusters(0);
Int_t nTPCclustersN = fTrackN->GetTPCclusters(0);
Float_t chi2perTPCclusterP = fTrackP->GetTPCchi2()/Float_t(nTPCclustersP);
Float_t chi2perTPCclusterN = fTrackN->GetTPCchi2()/Float_t(nTPCclustersN);
if((chi2perTPCclusterN > 3.5)||(chi2perTPCclusterP > 3.5)) return -3;
clsRatioN = nClsN/nClsFN;
clsRatioP = nClsP/nClsFP;
if((clsRatioN < 0.6)||(clsRatioP < 0.6))
return -4;
if (!((fTrackP->GetStatus() &
AliESDtrack::kTPCrefit)))
return -5;
if (!((fTrackN->GetStatus() &
AliESDtrack::kTPCrefit)))
return -6;
if (fTrackP->GetKinkIndex(0)>0 ||
fTrackN->GetKinkIndex(0)>0 )
return -7;
if(!(V0SignCheck()))
return -8;
fQuality = 1;
return fQuality;
}
Bool_t AliTRDv0Info::V0SignCheck(){
Int_t qP = fTrackP->Charge();
Int_t qN = fTrackN->Charge();
if((qP*qN) != -1) return kFALSE;
return kTRUE;
}
Bool_t AliTRDv0Info::Armenteros(const AliESDv0 *esdv0, Int_t decay){
Double_t mn[3] = {0,0,0};
Double_t mp[3] = {0,0,0};
Double_t mm[3] = {0,0,0};
if(V0SignCheck()){
esdv0->GetNPxPyPz(mn[0],mn[1],mn[2]);
esdv0->GetPPxPyPz(mp[0],mp[1],mp[2]);
}
else{
esdv0->GetPPxPyPz(mn[0],mn[1],mn[2]);
esdv0->GetNPxPyPz(mp[0],mp[1],mp[2]);
}
esdv0->GetPxPyPz(mm[0],mm[1],mm[2]);
TVector3 vecN(mn[0],mn[1],mn[2]);
TVector3 vecP(mp[0],mp[1],mp[2]);
TVector3 vecM(mm[0],mm[1],mm[2]);
Double_t thetaP = acos((vecP * vecM)/(vecP.Mag() * vecM.Mag()));
Double_t thetaN = acos((vecN * vecM)/(vecN.Mag() * vecM.Mag()));
Double_t alfa = ((vecP.Mag())*cos(thetaP)-(vecN.Mag())*cos(thetaN))/
((vecP.Mag())*cos(thetaP)+(vecN.Mag())*cos(thetaN)) ;
Double_t qt = vecP.Mag()*sin(thetaP);
Float_t ap[2];
ap[0] = alfa;
ap[1] = qt;
Double_t lCutAP[2];
if(decay == 0){
const Double_t cutAlpha[2] = {0.35, 0.45};
const Double_t cutQT = 0.015;
if(TMath::Abs(ap[0]) > cutAlpha[0] && TMath::Abs(ap[0]) < cutAlpha[1]) return kFALSE;
if(ap[1] > cutQT) return kFALSE;
}
else if(decay == 1){
const Double_t cutQT = 0.1075;
const Double_t cutAP = 0.22 * TMath::Sqrt( TMath::Abs( (1-ap[0]*ap[0]/(0.92*0.92)) ) );
if(ap[1] < cutQT) return kFALSE;
if(ap[1] > cutAP) return kFALSE;
}
else if(decay == 2){
const Double_t cutQT = 0.03;
const Double_t cutAlpha = 0.7;
lCutAP[0] = 1.0 - (ap[0]-0.7 * ap[0]-0.7)*1.1 - 0.87;
if(TMath::Abs(ap[0]) > cutAlpha) return kFALSE;
if(ap[1] < cutQT) return kFALSE;
if(ap[1] > lCutAP[0]) return kFALSE;
}
else if(decay == 3){
const Double_t cutQT = 0.03;
const Double_t cutAlpha = 0.7;
lCutAP[1] = 1.0 - (ap[0]+0.7 * ap[0]+0.7)*1.1 - 0.87;
if(TMath::Abs(ap[0]) > cutAlpha) return kFALSE;
if(ap[1] < cutQT) return kFALSE;
if(ap[1] > lCutAP[1]) return kFALSE;
}
return kTRUE;
}
Int_t AliTRDv0Info::GetPID(Int_t ipart, AliTRDtrackInfo *track)
{
Int_t cutCode = -99;
if(!(track)) {
AliError("No track info");
return -1;
}
if(!HasTrack(track)){
AliDebug(2, "Track not attached to v0.");
return -2;
}
Int_t iDecay = -1;
switch(ipart){
case AliPID::kElectron: iDecay = kGamma; break;
case AliPID::kPion: iDecay = kK0s; break;
case AliPID::kProton: iDecay = kLambda; break;
default:
AliDebug(1, Form("Hypothesis \"ipart=%d\" not handled", ipart));
return -3;
}
if(!(fQuality == 1)) return -4;
if((fDCA > fUpDCA[iDecay])) return -5;
if((fPointingAngle > fUpPointingAngle[iDecay])) return -6;
if((fRadius < fDownRadius[iDecay])) return -7;
if((fRadius > fUpRadius[iDecay])) return -8;
if((fOpenAngle > fUpOpenAngle[iDecay])) return -9;
if((TMath::Abs(fPsiPair) > fUpPsiPair[iDecay])) return -10;
Int_t iPSlot(fV0Momentum > 2.5);
Int_t trackID(track->GetTrackId());
if(ipart == AliPID::kProton) {
if((fInvMass[kK0s] < fUpInvMass[kK0s][iPSlot]) && (fInvMass[kK0s] > fDownInvMass[kK0s])) return -11;
if(fOpenAngle < (0.3 - 0.2*fV0Momentum)) return -9;
if((TPCdEdxCuts(ipart, track))){
if(fNindex == trackID) {
if(fArmenteros[kAntiLambda]){
if(fChi2ndf[kAntiLambda] < fUpChi2ndf[kAntiLambda]){
if((fInvMass[kAntiLambda] < fUpInvMass[kAntiLambda][iPSlot]) && (fInvMass[kAntiLambda] > fDownInvMass[kAntiLambda])){
return 1;
} else cutCode = -15;
} else cutCode =-14;
} else cutCode = -13;
}
} else cutCode = -12;
if((TPCdEdxCuts(ipart, track))){
if(fPindex == trackID) {
if(fArmenteros[kLambda]){
if(fChi2ndf[kLambda] < fUpChi2ndf[kLambda]){
if((fInvMass[kLambda] < fUpInvMass[kLambda][iPSlot]) && (fInvMass[kLambda] > fDownInvMass[kLambda])){
return 1;
} else cutCode = -15;
} else cutCode = -14;
} else cutCode = -13;
}
} else cutCode = -12;
return cutCode;
}
if(ipart == AliPID::kPion) {
if(fOpenAngle < (1.0/(fV0Momentum + 0.3) - 0.1)) return -9;
if((fInvMass[kLambda] < fUpInvMass[kLambda][iPSlot]) && (fInvMass[kLambda] > fDownInvMass[kLambda])) return -11;
if((fInvMass[kAntiLambda] < fUpInvMass[kAntiLambda][iPSlot]) && (fInvMass[kAntiLambda] > fDownInvMass[kAntiLambda])) return -11;
if(!(TPCdEdxCuts(ipart, track))){
return -12;
}
}
if(ipart == AliPID::kElectron) {
if(!(TPCdEdxCuts(ipart, track))){
return -12;
}
}
if(!(fArmenteros[iDecay])) return -13;
if(fChi2ndf[iDecay] > fUpChi2ndf[iDecay]) return -14;
if((fInvMass[iDecay] > fUpInvMass[iDecay][iPSlot]) || (fInvMass[iDecay] < fDownInvMass[iDecay])) return -15;
return 1;
}
void AliTRDv0Info::Print(Option_t *opt) const
{
printf("V0 legs :: %4d[+] %4d[-]\n", fPindex, fNindex);
printf(" Decay :: Gamma[%c] K0s[%c] Lambda[%c] AntiLambda[%c]\n",
IsDecay(kGamma)?'y':'n', IsDecay(kK0s)?'y':'n', IsDecay(kLambda)?'y':'n', IsDecay(kAntiLambda)?'y':'n');
printf(" Kine :: DCA[%5.3f] Radius[%5.3f]\n", fDCA, fRadius);
printf(" Angle :: Pointing[%5.3f] Open[%5.3f] Psi[%5.3f]\n", fPointingAngle, fOpenAngle, fPsiPair);
if(strcmp(opt, "a")!=0) return;
printf(" PID ::\n"
" ITS TPC TOF COM\n");
for(Int_t idt=0; idt<kNDaughters; idt++){
for(Int_t is(0); is<AliPID::kSPECIES; is++){
printf(" %s%c%s", AliPID::ParticleShortName(is), idt?'-':'+', (is==1||is==2)?" ":" ");
for(Int_t id(0); id<kNDetectors; id++){
printf("%5.1f ", 1.e2*fDetPID[idt][id][is]);
}
printf("%5.1f\n", 1.e2*fComPID[idt][is]);
}
}
}
void AliTRDv0Info::SetV0tracks(AliESDtrack *p, AliESDtrack *n)
{
fTrackP = p; fPindex = p->GetID();
fTrackN = n; fNindex = n->GetID();
}
AliESDtrack *AliTRDv0Info::GetV0Daughter(Int_t sign)
{
if(sign>0)
return fTrackP;
else if(sign < 0)
return fTrackN;
return 0;
}