#ifndef ALITRDV0INFO_H
#define ALITRDV0INFO_H
#ifndef Root_TObject
#include "TObject.h"
#endif
#ifndef ALITRDGEOMETRY_H
#include "AliTRDgeometry.h"
#endif
#ifndef ALIPID_H
#include "AliPID.h"
#endif
class AliESDv0;
class AliESDtrack;
class AliKFParticle;
class AliKFVertex;
class AliVEvent;
class AliVTrack;
class AliTRDtrackInfo;
class AliTRDv0Info : public TObject
{
public:
enum ETRDv0Info{
kNV0param = 10
,kNlayer = AliTRDgeometry::kNlayer
,kNMomBins = 2
,kNArmenteros = 2
};
enum EDaughter{
kNeg = 0
,kPos
,kNDaughters
};
enum EDecayType{
kGamma = 0
,kK0s
,kLambda
,kAntiLambda
,kNDecays
};
enum EDetector{
kTPC = 0
,kTOF
,kITS
,kNDetectors
};
AliTRDv0Info();
AliTRDv0Info(const AliTRDv0Info &ref);
virtual ~AliTRDv0Info(){}
Int_t GetQuality() const {return fQuality;}
Float_t GetDCA() const {return fDCA;}
Float_t GetPointingAngle() const {return fPointingAngle;}
Float_t GetOpenAngle() const {return fOpenAngle;}
Float_t GetPsiPair() const {return fPsiPair;}
Float_t GetRadius() const {return fRadius;}
Float_t GetV0Momentum() const {return fV0Momentum;}
Double_t GetInvMass(Int_t iDecay) const {return fInvMass[iDecay];}
Float_t GetDetPID(Int_t iDaughter, Int_t iDetector, Int_t iSpecies) const {return fDetPID[iDaughter][iDetector][iSpecies];}
Float_t GetComPID(Int_t iDaughter, Int_t iSpecies) const {return fComPID[iDaughter][iSpecies];}
Float_t GetTPCdEdx(Int_t iDaughter) const {return fTPCdEdx[iDaughter];}
Float_t GetChi2ndf(Int_t decay) const {return fChi2ndf[decay];}
Float_t GetUpDCA(Int_t iDecay) const {return fUpDCA[iDecay];}
Float_t GetUpPointingAngle(Int_t iDecay) const {return fUpPointingAngle[iDecay];}
Float_t GetUpOpenAngle(Int_t iDecay) const {return fUpOpenAngle[iDecay];}
Float_t GetDownOpenAngle(Int_t iDecay) const {return fDownOpenAngle[iDecay];}
Float_t GetUpPsiPair(Int_t iDecay) const {return fUpPsiPair[iDecay];}
Float_t GetDownPsiPair(Int_t iDecay) const {return fDownPsiPair[iDecay];}
Float_t GetUpRadius(Int_t iDecay) const {return fUpRadius[iDecay];}
Float_t GetDownRadius(Int_t iDecay) const {return fDownRadius[iDecay];}
Double_t GetUpInvMass(Int_t iDecay, Int_t iMomentum) const {return fUpInvMass[iDecay][iMomentum];}
Double_t GetDownInvMass(Int_t iDecay) const {return fDownInvMass[iDecay];}
Float_t GetDownTPCPIDneg(Int_t iPart) const {return fDownTPCPIDneg[iPart];}
Float_t GetDownTPCPIDpos(Int_t iPart) const {return fDownTPCPIDpos[iPart];}
Float_t GetDownComPIDneg(Int_t iPart) const {return fDownComPIDneg[iPart];}
Float_t GetDownComPIDpos(Int_t iPart) const {return fDownComPIDpos[iPart];}
Float_t GetDownComPIDnegPart(Int_t iPart) const {return fDownComPIDnegPart[iPart];}
Float_t GetDownComPIDposPart(Int_t iPart) const {return fDownComPIDposPart[iPart];}
Int_t GetPID(Int_t ipart, AliTRDtrackInfo *track);
AliESDtrack* GetV0Daughter(Int_t sign);
Int_t HasTrack(const AliTRDtrackInfo * const track) const;
Int_t HasTrack(Int_t ti) const;
Bool_t IsDecay(Int_t type) const {if(type<0||type>=Int_t(kNDecays)) return kFALSE; return TestBit(BIT(14+type));}
void Print(Option_t *opt="") const;
void SetMagField(Float_t b) {fMagField = b;}
void SetV0tracks(AliESDtrack *p, AliESDtrack *n);
void SetInputEvent(AliVEvent *e) { fInputEvent = e; };
void SetPrimaryVertex(AliKFVertex *v) { fPrimaryVertex = v; };
void SetQuality(Int_t SQuality){fQuality = SQuality;}
void SetDCA(Float_t SDCA){fDCA = SDCA;}
void SetPointingAngle(Float_t SPointingAngle){fPointingAngle = SPointingAngle;}
void SetOpenAngle(Float_t SOpenAngle){fOpenAngle = SOpenAngle;}
void SetPsiPair(Float_t SPsiPair){fPsiPair = SPsiPair;}
void SetRadius(Float_t SRadius){fRadius = SRadius;}
void SetInvMass(Int_t iDecay, Float_t SInvMass){fInvMass[iDecay] = SInvMass;}
void SetDetPID(Int_t iDaughter, Int_t iDetector, Int_t iSpecies, Float_t SDetPID){fDetPID[iDaughter][iDetector][iSpecies] = SDetPID;}
void SetComPID(Int_t iDaughter, Int_t iSpecies, Float_t SComPID){fComPID[iDaughter][iSpecies] = SComPID;}
void SetTPCdEdx(Int_t iDaughter, Float_t STpcdEdx){fTPCdEdx[iDaughter] = STpcdEdx;}
void SetV0Momentum(Float_t SV0Momentum){fV0Momentum = SV0Momentum;}
void SetChi2ndf(Int_t decay, Float_t SChi2ndf){fChi2ndf[decay]=SChi2ndf;}
void SetUpDCA(Int_t iDecay, Float_t UpDCA){fUpDCA[iDecay] = UpDCA;}
void SetUpPointingAngle(Int_t iDecay, Float_t UpPointingAngle){fUpPointingAngle[iDecay] = UpPointingAngle;}
void SetUpOpenAngle(Int_t iDecay, Float_t UpOpenAngle){fUpOpenAngle[iDecay] = UpOpenAngle;}
void SetDownOpenAngle(Int_t iDecay, Float_t DownOpenAngle){fDownOpenAngle[iDecay] = DownOpenAngle;}
void SetUpPsiPair(Int_t iDecay, Float_t UpPsiPair){fUpPsiPair[iDecay] = UpPsiPair;}
void SetDownPsiPair(Int_t iDecay, Float_t DownPsiPair){fDownPsiPair[iDecay] = DownPsiPair;}
void SetUpRadius(Int_t iDecay, Float_t UpRadius){fUpRadius[iDecay] = UpRadius;}
void SetDownRadius(Int_t iDecay, Float_t DownRadius){fDownRadius[iDecay] = DownRadius;}
void SetUpInvMass(Int_t iDecay, Int_t iMomentum, Double_t UpInvMass){fUpInvMass[iDecay][iMomentum] = UpInvMass;}
void SetDownInvMass(Int_t iDecay, Double_t DownInvMass){fDownInvMass[iDecay] = DownInvMass;}
void SetDownTPCPIDneg(Int_t iPart, Double_t DownTPCPIDneg){fDownTPCPIDneg[iPart] = DownTPCPIDneg;}
void SetDownTPCPIDpos(Int_t iPart, Double_t DownTPCPIDpos){fDownTPCPIDpos[iPart] = DownTPCPIDpos;}
void SetDownComPIDneg(Int_t iPart, Double_t DownComPIDneg){fDownComPIDneg[iPart] = DownComPIDneg;}
void SetDownComPIDpos(Int_t iPart, Double_t DownComPIDpos){fDownComPIDpos[iPart] = DownComPIDpos;}
void SetDownComPIDnegPart(Int_t iPart, Double_t DownComPIDnegPart){fDownComPIDnegPart[iPart] = DownComPIDnegPart;}
void SetDownComPIDposPart(Int_t iPart, Double_t DownComPIDposPart){fDownComPIDposPart[iPart] = DownComPIDposPart;}
void SetV0Info(const AliESDv0 *v0);
void SetDecay(Int_t type, Bool_t s=kTRUE) {SetBit(BIT(14+type), s);}
private:
AliTRDv0Info& operator=(const AliTRDv0Info&);
void GetDetectorPID();
void CombinePID();
Bool_t TPCdEdxCuts(Int_t part, const AliTRDtrackInfo * const track);
Bool_t GetTPCdEdx();
Int_t Quality(const AliESDv0 * const esdv0);
Double_t InvMass(Int_t part1, Int_t part2, const AliESDv0 *esdv0) const;
Float_t PsiPair(const AliESDv0 *esdv0);
Float_t OpenAngle(const AliESDv0 *esdv0);
Float_t Radius(const AliESDv0 *esdv0);
Float_t DCA() const {return fDCA;}
Float_t PointingAngle() const {return fPointingAngle;}
Float_t V0Momentum(const AliESDv0 *esdv0) const;
Bool_t V0SignCheck();
Bool_t Armenteros(const AliESDv0 *esdv0, Int_t species);
Double_t KFChi2ndf(Int_t part1, Int_t part2,Int_t decay);
AliKFParticle* CreateMotherParticle(const AliESDtrack *pdaughter, const AliESDtrack *ndaughter, Int_t pspec, Int_t nspec);
Float_t fUpDCA[kNDecays];
Float_t fUpPointingAngle[kNDecays];
Float_t fUpOpenAngle[kNDecays];
Float_t fDownOpenAngle[kNDecays];
Float_t fUpPsiPair[kNDecays];
Float_t fDownPsiPair[kNDecays];
Double_t fUpChi2ndf[kNDecays];
Float_t fUpRadius[kNDecays];
Float_t fDownRadius[kNDecays];
Float_t fDownTPCPIDneg[AliPID::kSPECIES];
Float_t fDownTPCPIDpos[AliPID::kSPECIES];
Float_t fDownComPIDneg[AliPID::kSPECIES];
Float_t fDownComPIDpos[AliPID::kSPECIES];
Float_t fDownComPIDnegPart[AliPID::kSPECIES];
Float_t fDownComPIDposPart[AliPID::kSPECIES];
Double_t fUpInvMass[kNDecays][kNMomBins];
Double_t fDownInvMass[kNDecays];
Double_t fChi2ndf[kNDecays];
Double_t fInvMass[kNDecays];
Int_t fQuality;
Double_t fDetPID[kNDaughters][kNDetectors][AliPID::kSPECIES];
Double_t fComPID[kNDaughters][AliPID::kSPECIES];
Float_t fDCA;
Float_t fPointingAngle;
Float_t fOpenAngle;
Float_t fPsiPair;
Bool_t fArmenteros[kNDecays];
Double_t fMagField;
Float_t fRadius;
Float_t fV0Momentum;
Int_t fNindex;
Int_t fPindex;
Float_t fTPCdEdx[kNDaughters];
AliVEvent* fInputEvent;
AliKFVertex* fPrimaryVertex;
AliESDtrack* fTrackP;
AliESDtrack* fTrackN;
ClassDef(AliTRDv0Info, 1)
};
#endif