* provided "as is" without express or implied warranty. *
**************************************************************************/
+/* $Id$ */
+
/////////////////////////////////////////////////////////////
//
// Class for AOD reconstructed heavy-flavour cascades
#include <TVector3.h>
#include <TDatabasePDG.h>
+#include <TClonesArray.h>
+#include "AliAODMCParticle.h"
#include "AliAODRecoDecay.h"
#include "AliAODVertex.h"
#include "AliAODRecoDecayHF2Prong.h"
//
// 3 prong invariant mass of the D0 daughters and the soft pion
//
+ Double_t e[3];
+ if (Charge()>0){
+ e[0]=Get2Prong()->EProng(0,211);
+ e[1]=Get2Prong()->EProng(1,321);
+ }else{
+ e[0]=Get2Prong()->EProng(0,321);
+ e[1]=Get2Prong()->EProng(1,211);
+ }
+ e[2]=EProng(0,211);
+
+ Double_t esum = e[0]+e[1]+e[2];
+ Double_t minv = TMath::Sqrt(esum*esum-P()*P());
- Double_t px[3],py[3],pz[3];
- UInt_t pdg[3]={321,211,211};
- pdg[0] = (Charge()>0 ? 211 : 321); // positive daughter of D0
- px[0] = Get2Prong()->PxProng(0);
- py[0] = Get2Prong()->PyProng(0);
- pz[0] = Get2Prong()->PzProng(0);
- pdg[1] = (Charge()>0 ? 321 : 211); // negative daughter of D0
- px[1] = Get2Prong()->PxProng(1);
- py[1] = Get2Prong()->PyProng(1);
- pz[1] = Get2Prong()->PzProng(1);
- pdg[2] = 211; // soft pion
- px[2] = PxProng(0);
- py[2] = PyProng(0);
- pz[2] = PzProng(0);
- Short_t dummycharge=0;
- Double_t dummyd0[3]={0,0,0};
- AliAODRecoDecay *rd = new AliAODRecoDecay(0x0,3,dummycharge,px,py,pz,dummyd0);
-
- Double_t minv = rd->InvMass(3,pdg);
-
- delete rd; rd=NULL;
-
- return minv;
+ return minv;
+}
+//----------------------------------------------------------------------------
+Int_t AliAODRecoCascadeHF::MatchToMC(Int_t pdgabs,Int_t pdgabs2prong,
+ Int_t *pdgDg,Int_t *pdgDg2prong,
+ TClonesArray *mcArray) const
+{
+ //
+ // Check if this candidate is matched to a MC signal
+ // If no, return -1
+ // If yes, return label (>=0) of the AliAODMCParticle
+ //
+
+ Int_t ndg=GetNDaughters();
+ if(!ndg) {
+ AliError("No daughters available");
+ return -1;
+ }
+
+ AliAODRecoDecayHF2Prong *the2Prong = Get2Prong();
+ Int_t lab2Prong = the2Prong->MatchToMC(pdgabs2prong,mcArray,2,pdgDg2prong);
+
+ if(lab2Prong<0) return -1;
+
+ Int_t dgLabels[10]={0,0,0,0,0,0,0,0,0,0};
+
+ // loop on daughters and write labels
+ for(Int_t i=0; i<ndg; i++) {
+ AliVTrack *trk = (AliVTrack*)GetDaughter(i);
+ Int_t lab = trk->GetLabel();
+ if(lab==-1) { // this daughter is the 2prong
+ lab=lab2Prong;
+ } else if(lab<-1) {
+ printf("daughter with negative label\n");
+ continue;
+ }
+ dgLabels[i] = lab;
+ }
+
+ return AliAODRecoDecay::MatchToMC(pdgabs,mcArray,dgLabels,2,2,pdgDg);
}
//-----------------------------------------------------------------------------
Bool_t AliAODRecoCascadeHF::SelectDstar(const Double_t *cutsDstar,
Double_t mD0 = TDatabasePDG::Instance()->GetParticle(421)->Mass();
if(TMath::Abs((mDstar-mD0)-DeltaInvMass())>cutsDstar[1]) return kFALSE;
+ Double_t theta = AngleD0dkpPisoft();
+ if(theta>cutsDstar[4]) return kFALSE;
+
+ return kTRUE;
+}
+//-----------------------------------------------------------------------------
+Bool_t AliAODRecoCascadeHF::SelectLctoV0(const Double_t *cutsLctoV0,
+ Bool_t okLck0sp, Bool_t okLcLpi) const
+{
+ // cuts on Lambdac candidates to V0+bachelor
+ // (to be passed to AliAODRecoDecayHF3Prong::SelectLctoV0())
+ // 0 = inv. mass half width in K0s hypothesis [GeV]
+ // 1 = inv. mass half width in Lambda hypothesis [GeV]
+ // 2 = inv. mass V0 in K0s hypothesis half width [GeV]
+ // 3 = inv. mass V0 in Lambda hypothesis half width [GeV]
+ // 4 = pT min Bachelor track [GeV/c]
+ // 5 = pT min V0-Positive track [GeV/c]
+ // 6 = pT min V0-Negative track [GeV/c]
+ // 7 = dca cut on the V0 (cm)
+ // 8 = dca cut on the cascade (cm)
+
+// if ( !Getv0() || !Getv0PositiveTrack() || !Getv0NegativeTrack() )
+// { AliInfo(Form("Not adapted for ESDv0s, return true...")); return false; }
+
+ Double_t mLck0sp,mLcLpi;
+ okLck0sp=1; okLcLpi=1;
+
+ Double_t mLcPDG = TDatabasePDG::Instance()->GetParticle(4122)->Mass();
+ Double_t mk0sPDG = TDatabasePDG::Instance()->GetParticle(310)->Mass();
+ Double_t mLPDG = TDatabasePDG::Instance()->GetParticle(3122)->Mass();
+
+ // k0s + p
+ double mk0s = Getv0()->MassK0Short();
+ mLck0sp = InvMassLctoK0sP();
+
+ // lambda + pi
+ double mlambda = Getv0()->MassLambda();
+ double malambda = Getv0()->MassAntiLambda();
+ mLcLpi = InvMassLctoLambdaPi();
+
+ // cut on Lc mass
+ // with k0s p hypothesis
+ if(TMath::Abs(mLck0sp-mLcPDG)>cutsLctoV0[0]) okLck0sp = 0;
+ // with Lambda pi hypothesis
+ if(TMath::Abs(mLcLpi-mLcPDG)>cutsLctoV0[1]) okLcLpi = 0;
+
+ // cuts on the v0 mass
+ if(TMath::Abs(mk0s-mk0sPDG)>cutsLctoV0[2]) okLck0sp = 0;
+ if( TMath::Abs(mlambda-mLPDG)>cutsLctoV0[3] &&
+ TMath::Abs(malambda-mLPDG)>cutsLctoV0[3] ) okLcLpi = 0;
+
+ if(!okLck0sp && !okLcLpi) return 0;
+
+ // cuts on the minimum pt of the tracks
+ if(TMath::Abs(GetBachelor()->Pt()) < cutsLctoV0[4]) return 0;
+ if(TMath::Abs(Getv0PositiveTrack()->Pt()) < cutsLctoV0[5]) return 0;
+ if(TMath::Abs(Getv0NegativeTrack()->Pt()) < cutsLctoV0[6]) return 0;
+
+ // cut on the v0 dca
+ if(TMath::Abs(Getv0()->DcaV0Daughters()) > cutsLctoV0[7]) return 0;
+
+ // cut on the cascade dca
+ if( TMath::Abs(GetDCA(0))>cutsLctoV0[8] ||
+ TMath::Abs(Getv0()->DcaPosToPrimVertex())>cutsLctoV0[8] ||
+ TMath::Abs(Getv0()->DcaNegToPrimVertex())>cutsLctoV0[8] ) return 0;
+
+ return true;
+
+}
+//-----------------------------------------------------------------------------
+Double_t AliAODRecoCascadeHF::AngleD0dkpPisoft() const {
+ //
+ // Angle of soft pion to D0 decay plane
+ //
+
TVector3 p3Trk0(Get2Prong()->PxProng(0),Get2Prong()->PyProng(0),Get2Prong()->PzProng(0)); // from D0
TVector3 p3Trk1(Get2Prong()->PxProng(1),Get2Prong()->PyProng(1),Get2Prong()->PzProng(1)); // from D0
TVector3 p3Trk2(PxProng(0),PyProng(0),PzProng(0)); // pi_s
if(theta>(TMath::Pi()-theta)) theta = TMath::Pi() - theta;
theta = TMath::Pi()/2. - theta;
- if(theta>cutsDstar[4]) return kFALSE;
+ return theta;
+}
+//-----------------------------------------------------------------------------
+Bool_t AliAODRecoCascadeHF::TrigonometricalCut() const {
+ //
+ // Trigonometrical constraint
+ //
+ TVector3 p3Trk0(Get2Prong()->PxProng(0),Get2Prong()->PyProng(0),Get2Prong()->PzProng(0)); // from D0
+ TVector3 p3Trk1(Get2Prong()->PxProng(1),Get2Prong()->PyProng(1),Get2Prong()->PzProng(1)); // from D0
+ TVector3 p3Trk2(PxProng(0),PyProng(0),PzProng(0)); // pi_s
Double_t alpha = p3Trk0.Angle(p3Trk2);
- Double_t belta = p3Trk1.Angle(p3Trk2);
+ Double_t beta = p3Trk1.Angle(p3Trk2);
- Double_t cosphi01 = TMath::Cos(alpha) / TMath::Cos(theta);
- Double_t cosphi02 = TMath::Cos(belta) / TMath::Cos(theta);
+ Double_t cosphi01 = TMath::Cos(alpha) / TMath::Cos(AngleD0dkpPisoft());
+ Double_t cosphi02 = TMath::Cos(beta) / TMath::Cos(AngleD0dkpPisoft());
Double_t phi01 = TMath::ACos(cosphi01);
Double_t phi02 = TMath::ACos(cosphi02);
Double_t phi00 = p3Trk0.Angle(p3Trk1);
if((phi01>phi00) || (phi02>phi00)) return kFALSE;
-
return kTRUE;
}
-//-----------------------------------------------------------------------------