#ifndef ALIFLOWBAYESIANPID_H
#define ALIFLOWBAYESIANPID_H
#include "AliESDpid.h"
#include "AliPIDResponse.h"
class TObject;
class TDatabasePDG;
class AliESDEvent;
class AliESDtrack;
class AliAODEvent;
class AliAODTrack;
class TH2D;
class TSpline3;
class TF1;
class TH1D;
class AliFlowBayesianPID : public AliPIDResponse{
public:
AliFlowBayesianPID(AliESDpid *esdpid=NULL);
virtual ~AliFlowBayesianPID();
void SetDetResponse(AliESDEvent *esd,Float_t centrality=-1.0,EStartTimeType_t flagStart=AliESDpid::kTOF_T0,Bool_t =kFALSE);
void SetDetResponse(AliAODEvent *aod,Float_t centrality=-1.0,EStartTimeType_t flagStart=AliESDpid::kTOF_T0);
void SetNewTrackParam(Bool_t flag=kTRUE){fNewTrackParam=flag;};
void SetDetAND(Int_t idet){if(idet < fgkNdetectors && idet >= 0) fMaskAND[idet] = kTRUE;};
void SetDetOR(Int_t idet){if(idet < fgkNdetectors && idet >= 0) fMaskOR[idet] = kTRUE;};
void ResetDetAND(Int_t idet){if(idet < fgkNdetectors && idet >= 0) fMaskAND[idet] = kFALSE;};
void ResetDetOR(Int_t idet){if(idet < fgkNdetectors && idet >= 0) fMaskOR[idet] = kFALSE;};
void SetPsiCorrectionDeDx(Float_t psi,Float_t res);
void SetMC(Bool_t flag){fIsMC=flag;};
AliESDpid* GetESDpid(){return fPIDesd;};
const TH2D *GetHistoPriors(Int_t specie) const {if(specie >=0 && specie < fgkNspecies) return fghPriors[specie]; else return NULL;};
TSpline3 *GetMismatch();
const TF1 *GetTOFprob() const {return fTOFResponseF;};
const TF1 *GetTPCprob() const {return fTPCResponseF;};
const Float_t *GetWeights(Int_t det) const {if(det < fgkNdetectors && det >= 0){return fWeights[det];} else{return NULL;}};
Float_t *GetProb() {return fProb;};
Float_t GetTOFMismWeight() const {return fWTofMism;};
Float_t GetTOFMismProb() const {return fProbTofMism;};
Float_t GetMassOverZ() const {return fMassTOF;};
Float_t GetZ() const {return fZ;};
Bool_t GetDetANDstatus(Int_t idet) const {if(idet < fgkNdetectors && idet >= 0){return fMaskAND[idet];} else{return kFALSE;} };
Bool_t GetDetORstatus(Int_t idet) const {if(idet < fgkNdetectors && idet >= 0){return fMaskOR[idet];} else{return kFALSE;} };
Bool_t GetCurrentMask(Int_t idet) const {if(idet < fgkNdetectors && idet >= 0){return fMaskCurrent[idet];} else{return kFALSE;} };
Float_t GetExpDeDx(const AliVTrack *t,Int_t iS) const;
Float_t GetExpDeDx(const AliVTrack *t,Float_t m) const;
void ComputeWeights(const AliESDtrack *t);
void ComputeProb(const AliESDtrack *t,Float_t);
void ComputeProb(const AliESDtrack *t){ComputeProb(t,0.0);};
void ComputeWeights(const AliAODTrack *t,const AliAODEvent *aod=NULL);
void ComputeProb(const AliAODTrack *t,const AliAODEvent *aod=NULL);
void SetTOFres(Float_t res){fTOFresolution=res;};
Float_t GetDeDx() const {return fDedx;};
void ForceOldDedx(Bool_t status=kTRUE) {fForceOldDedx=status;};
private:
void SetPriors();
static const Int_t fgkNdetectors = 2;
static const Int_t fgkNspecies = 9;
static TH2D* fghPriors[fgkNspecies];
static TSpline3 *fgMism;
AliESDpid *fPIDesd;
TDatabasePDG *fDB;
Double_t fMass[fgkNspecies];
Bool_t fNewTrackParam;
Float_t fTOFresolution;
AliFlowBayesianPID(const AliFlowBayesianPID&);
AliFlowBayesianPID& operator=(const AliFlowBayesianPID&);
TF1 *fTOFResponseF;
TF1 *fTPCResponseF;
Float_t fWeights[fgkNdetectors][fgkNspecies];
Float_t fProb[fgkNspecies],fWTofMism,fProbTofMism;
Float_t fZ,fMassTOF;
TF1 *fBBdata;
Bool_t fMaskAND[fgkNdetectors],fMaskOR[fgkNdetectors],fMaskCurrent[fgkNdetectors];
Float_t fCurrCentrality;
Float_t fPsi,fPsiRes;
Bool_t fIsMC;
Bool_t fForceOldDedx;
Float_t fDedx;
Bool_t fIsTOFheaderAOD;
static TH1D *fgHtofChannelDist;
ClassDef(AliFlowBayesianPID, 10);
};
#endif