#ifndef ALIAODRECODECAYLF_H
#define ALIAODRECODECAYLF_H
#include <TRef.h>
#include <TList.h>
#include "AliAODTrack.h"
#include "AliAODRecoDecay.h"
class AliAODEvent;
class AliKFParticle;
class AliAODRecoDecayLF : public AliAODRecoDecay {
public:
AliAODRecoDecayLF();
AliAODRecoDecayLF(AliAODVertex *vtx2,Int_t nprongs,Short_t charge,
Double_t *px,Double_t *py,Double_t *pz,
Double_t *d0,Double_t *d0err);
AliAODRecoDecayLF(AliAODVertex *vtx2,Int_t nprongs,Short_t charge,
Double_t *d0,Double_t *d0err);
AliAODRecoDecayLF(Double_t vtx1[3],Double_t vtx2[3],
Int_t nprongs,Short_t charge,
Double_t *px,Double_t *py,Double_t *pz,Double_t *d0);
virtual ~AliAODRecoDecayLF();
AliAODRecoDecayLF(const AliAODRecoDecayLF& source);
AliAODRecoDecayLF& operator=(const AliAODRecoDecayLF& source);
void SetPrimaryVtxRef(TObject *vtx) { fEventPrimaryVtx = vtx; }
AliAODVertex* GetPrimaryVtxRef() const { return (AliAODVertex*)(fEventPrimaryVtx.GetObject()); }
void SetOwnPrimaryVtx(const AliAODVertex *vtx) { UnsetOwnPrimaryVtx(); fOwnPrimaryVtx = new AliAODVertex(*vtx);}
void CheckOwnPrimaryVtx() const
{if(!fOwnPrimaryVtx) printf("fOwnPrimaryVtx not set"); return;}
AliAODVertex* GetOwnPrimaryVtx() const {return fOwnPrimaryVtx;}
void GetOwnPrimaryVtx(Double_t vtx[3]) const
{CheckOwnPrimaryVtx();fOwnPrimaryVtx->GetPosition(vtx);}
void UnsetOwnPrimaryVtx() {if(fOwnPrimaryVtx) {delete fOwnPrimaryVtx; fOwnPrimaryVtx=0;} return;}
AliAODVertex* GetPrimaryVtx() const { return (GetOwnPrimaryVtx() ? GetOwnPrimaryVtx() : GetPrimaryVtxRef()); }
AliAODVertex* RemoveDaughtersFromPrimaryVtx(AliAODEvent *aod);
void RecalculateImpPars(AliAODVertex *vtxAODNew,AliAODEvent *aod);
Double_t DecayLength2() const
{ return AliAODRecoDecay::DecayLength2(GetPrimaryVtx());}
Double_t DecayLength() const
{ return AliAODRecoDecay::DecayLength(GetPrimaryVtx());}
Double_t DecayLengthError() const
{ return AliAODRecoDecay::DecayLengthError(GetPrimaryVtx());}
Double_t NormalizedDecayLength() const
{ return AliAODRecoDecay::NormalizedDecayLength(GetPrimaryVtx());}
Double_t NormalizedDecayLength2() const
{ return AliAODRecoDecay::NormalizedDecayLength2(GetPrimaryVtx());}
Double_t DecayLengthXY() const
{ return AliAODRecoDecay::DecayLengthXY(GetPrimaryVtx());}
Double_t DecayLengthXYError() const
{ return AliAODRecoDecay::DecayLengthXYError(GetPrimaryVtx());}
Double_t NormalizedDecayLengthXY() const
{ return AliAODRecoDecay::NormalizedDecayLengthXY(GetPrimaryVtx());}
Double_t Ct(UInt_t pdg) const
{ return AliAODRecoDecay::Ct(pdg,GetPrimaryVtx());}
Double_t CosPointingAngle() const
{ return AliAODRecoDecay::CosPointingAngle(GetPrimaryVtx());}
Double_t CosPointingAngleXY() const
{ return AliAODRecoDecay::CosPointingAngleXY(GetPrimaryVtx());}
Double_t ImpParXY() const
{ return AliAODRecoDecay::ImpParXY(GetPrimaryVtx());}
Double_t QtProngFlightLine(Int_t ip) const
{ return AliAODRecoDecay::QtProngFlightLine(ip,GetPrimaryVtx());}
Double_t QlProngFlightLine(Int_t ip) const
{ return AliAODRecoDecay::QlProngFlightLine(ip,GetPrimaryVtx());}
Double_t Getd0errProng(Int_t ip) const {return fd0err[ip];}
void Setd0errProngs(Int_t nprongs,Double_t *d0);
Double_t Normalizedd0Prong(Int_t ip) const
{return Getd0Prong(ip)/Getd0errProng(ip);}
void SetProngIDs(Int_t nIDs,UShort_t *id);
UShort_t GetProngID(Int_t ip) const
{if(fProngID) {return fProngID[ip];} else {return 9999;}}
Bool_t DaughterHasPointOnITSLayer(Int_t dg,Int_t l) const;
Bool_t IsLikeSign() const;
AliKFParticle *ApplyVertexingKF(Int_t *iprongs,Int_t nprongs,Int_t *pdgs,
Bool_t topoCostraint,Double_t bzkG,
Double_t *mass) const;
void Misalign(TString misal="null");
void SetSelectionBit(Int_t i) {SETBIT(fSelectionMap,i); return;}
Bool_t HasSelectionBit(Int_t i) const {return TESTBIT(fSelectionMap,i);}
ULong_t GetSelectionMap() const {return fSelectionMap;}
Int_t NumberOfFakeDaughters() const;
Bool_t HasBadDaughters() const;
protected:
AliAODVertex *fOwnPrimaryVtx;
TRef fEventPrimaryVtx;
TRef fListOfCuts;
Double_t *fd0err;
UShort_t *fProngID;
ULong_t fSelectionMap;
ClassDef(AliAODRecoDecayLF,5)
};
inline void AliAODRecoDecayLF::SetProngIDs(Int_t nIDs,UShort_t *id)
{
if(nIDs!=GetNProngs()) {
printf("Wrong number of IDs, must be nProngs\n");
return;
}
if(fProngID) delete [] fProngID;
fProngID = new UShort_t[nIDs];
for(Int_t i=0;i<nIDs;i++)
fProngID[i] = id[i];
return;
}
inline Bool_t AliAODRecoDecayLF::IsLikeSign() const
{
Int_t ndg=GetNDaughters();
if(!ndg) {
printf("Daughters not available\n");
return kFALSE;
}
Int_t chargeDg0 = ((AliAODTrack*)GetDaughter(0))->Charge();
for(Int_t i=1; i<ndg; i++) {
if(chargeDg0!=((AliAODTrack*)GetDaughter(i))->Charge()) return kFALSE;
}
return kTRUE;
}
inline Bool_t AliAODRecoDecayLF::DaughterHasPointOnITSLayer(Int_t dg,Int_t l) const
{
if(l<0 || l>5) {
printf("ERROR: layer has to be in the range 0-5\n");
return kFALSE;
}
AliAODTrack *t = (AliAODTrack*)GetDaughter(dg);
if(!t) return kFALSE;
return TESTBIT(t->GetITSClusterMap(),l);
}
inline Int_t AliAODRecoDecayLF::NumberOfFakeDaughters() const
{
Int_t nfakes=0;
for(Int_t i=0; i<GetNDaughters(); i++) {
AliAODTrack *track=(AliAODTrack*)GetDaughter(i);
if(track->Charge()==0) {
AliAODRecoDecay *rd=(AliAODRecoDecay*)GetDaughter(i);
for(Int_t j=0; j<rd->GetNDaughters(); j++) {
AliAODTrack *track2=(AliAODTrack*)GetDaughter(j);
if(track2->GetLabel()<0) nfakes++;
}
continue;
}
if(track->GetLabel()<0) nfakes++;
}
return nfakes;
}
inline void AliAODRecoDecayLF::Setd0errProngs(Int_t nprongs,Double_t *d0err)
{
if(nprongs!=GetNProngs()) {
printf("Wrong number of momenta, must be nProngs");
return;
}
if(!fd0) {
fd0err = new Double32_t[nprongs];
}
for(Int_t i=0;i<nprongs;i++) {
fd0err[i] = d0err[i];
}
return;
}
inline Bool_t AliAODRecoDecayLF::HasBadDaughters() const {
for(Int_t iDau=0; iDau<GetNDaughters(); iDau++){
if (GetDaughter(iDau)==NULL) continue;
AliAODTrack* at=dynamic_cast<AliAODTrack*>(GetDaughter(iDau));
if (!at) continue;
if(at->Charge()==0) continue;
if(at->GetTPCNcls()==0) continue;
if(!(at->TestFilterMask(BIT(4)))) return kTRUE;
}
return kFALSE;
}
#endif