#ifndef ALIESDMUONTRACK_H
#define ALIESDMUONTRACK_H
#include <TMath.h>
#include <TMatrixD.h>
#include <TDatabasePDG.h>
#include <TArrayI.h>
#include "AliVParticle.h"
class AliESDEvent;
class TClonesArray;
class TLorentzVector;
class AliESDMuonTrack : public AliVParticle {
public:
AliESDMuonTrack();
virtual ~AliESDMuonTrack();
AliESDMuonTrack(const AliESDMuonTrack& esdm);
AliESDMuonTrack& operator=(const AliESDMuonTrack& esdm);
virtual void Copy(TObject &obj) const;
virtual void Clear(Option_t* opt = "");
void Reset();
Bool_t ContainTrackerData() const {return (fMuonClusterMap>0) ? kTRUE : kFALSE;}
Bool_t ContainTriggerData() const {return (LoCircuit()>0) ? kTRUE : kFALSE;}
Double_t GetInverseBendingMomentum(void) const {return fInverseBendingMomentum;}
void SetInverseBendingMomentum(Double_t InverseBendingMomentum)
{fInverseBendingMomentum = InverseBendingMomentum;}
Double_t GetThetaX(void) const {return fThetaX;}
void SetThetaX(Double_t ThetaX) {fThetaX = ThetaX;}
Double_t GetThetaY(void) const {return fThetaY;}
void SetThetaY(Double_t ThetaY) {fThetaY = ThetaY;}
Double_t GetZ(void) const {return fZ;}
void SetZ(Double_t Z) {fZ = Z;}
Double_t GetBendingCoor(void) const {return fBendingCoor;}
void SetBendingCoor(Double_t BendingCoor) {fBendingCoor = BendingCoor;}
Double_t GetNonBendingCoor(void) const {return fNonBendingCoor;}
void SetNonBendingCoor(Double_t NonBendingCoor) {fNonBendingCoor = NonBendingCoor;}
Double_t GetInverseBendingMomentumAtDCA(void) const {return fInverseBendingMomentumAtDCA;}
void SetInverseBendingMomentumAtDCA(Double_t InverseBendingMomentum)
{fInverseBendingMomentumAtDCA = InverseBendingMomentum;}
Double_t GetThetaXAtDCA(void) const {return fThetaXAtDCA;}
void SetThetaXAtDCA(Double_t ThetaX) {fThetaXAtDCA = ThetaX;}
Double_t GetThetaYAtDCA(void) const {return fThetaYAtDCA;}
void SetThetaYAtDCA(Double_t ThetaY) {fThetaYAtDCA = ThetaY;}
Double_t GetBendingCoorAtDCA(void) const {return fBendingCoorAtDCA;}
void SetBendingCoorAtDCA(Double_t BendingCoor) {fBendingCoorAtDCA = BendingCoor;}
Double_t GetNonBendingCoorAtDCA(void) const {return fNonBendingCoorAtDCA;}
void SetNonBendingCoorAtDCA(Double_t NonBendingCoor) {fNonBendingCoorAtDCA = NonBendingCoor;}
Double_t GetDCA(void) const {return TMath::Sqrt(fNonBendingCoorAtDCA*fNonBendingCoorAtDCA +
fBendingCoorAtDCA*fBendingCoorAtDCA);}
Double_t GetInverseBendingMomentumUncorrected(void) const {return fInverseBendingMomentumUncorrected;}
void SetInverseBendingMomentumUncorrected(Double_t InverseBendingMomentum)
{fInverseBendingMomentumUncorrected = InverseBendingMomentum;}
Double_t GetThetaXUncorrected(void) const {return fThetaXUncorrected;}
void SetThetaXUncorrected(Double_t ThetaX) {fThetaXUncorrected = ThetaX;}
Double_t GetThetaYUncorrected(void) const {return fThetaYUncorrected;}
void SetThetaYUncorrected(Double_t ThetaY) {fThetaYUncorrected = ThetaY;}
Double_t GetZUncorrected(void) const {return fZUncorrected;}
void SetZUncorrected(Double_t Z) {fZUncorrected = Z;}
Double_t GetBendingCoorUncorrected(void) const {return fBendingCoorUncorrected;}
void SetBendingCoorUncorrected(Double_t BendingCoor) {fBendingCoorUncorrected = BendingCoor;}
Double_t GetNonBendingCoorUncorrected(void) const {return fNonBendingCoorUncorrected;}
void SetNonBendingCoorUncorrected(Double_t NonBendingCoor) {fNonBendingCoorUncorrected = NonBendingCoor;}
void GetCovariances(TMatrixD& cov) const;
void SetCovariances(const TMatrixD& cov);
void GetCovarianceXYZPxPyPz(Double_t cov[21]) const;
Double_t GetRAtAbsorberEnd() const { return fRAtAbsorberEnd; }
void SetRAtAbsorberEnd(Double_t r) { fRAtAbsorberEnd = r; }
Double_t GetChi2(void) const {return fChi2;}
void SetChi2(Double_t Chi2) {fChi2 = Chi2;}
UChar_t GetNHit(void) const {return fNHit;}
Int_t GetNDF() const;
Double_t GetNormalizedChi2() const;
Int_t GetMatchTrigger() const;
Bool_t MatchTriggerDigits(Bool_t fromTrack) const;
Double_t GetChi2MatchTrigger() const {return fChi2MatchTrigger;}
void SetChi2MatchTrigger(Double_t Chi2MatchTrigger) {fChi2MatchTrigger = Chi2MatchTrigger;}
UShort_t GetHitsPatternInTrigCh() const {return fHitsPatternInTrigCh;}
void SetHitsPatternInTrigCh(UShort_t hitsPatternInTrigCh) {fHitsPatternInTrigCh = hitsPatternInTrigCh;}
UInt_t GetHitsPatternInTrigChTrk() const {return fHitsPatternInTrigChTrk;}
void SetHitsPatternInTrigChTrk(UInt_t hitsPatternInTrigChTrk) {fHitsPatternInTrigChTrk = hitsPatternInTrigChTrk;}
void SetLocalTrigger(Int_t locTrig) { fLocalTrigger = locTrig; }
Int_t LoCircuit(void) const { return fLocalTrigger & 0xFF; }
Int_t LoStripX(void) const { return fLocalTrigger >> 8 & 0x1F; }
Int_t LoStripY(void) const { return fLocalTrigger >> 13 & 0x0F; }
Int_t LoDev(void) const { return fLocalTrigger >> 17 & 0x1F; }
Int_t LoLpt(void) const { return fLocalTrigger >> 22 & 0x03; }
Int_t LoHpt(void) const { return fLocalTrigger >> 24 & 0x03; }
Int_t GetTriggerWithoutChamber(void) const { return fLocalTrigger >> 26 & 0xF; }
Bool_t TriggerFiredWithoutChamber(Int_t ich) const { return GetTriggerWithoutChamber() >> (3 - ich) & 0x1; }
Int_t GetMuonTrigDevSign() const;
UShort_t GetTriggerX1Pattern() const { return fX1Pattern; }
UShort_t GetTriggerY1Pattern() const { return fY1Pattern; }
UShort_t GetTriggerX2Pattern() const { return fX2Pattern; }
UShort_t GetTriggerY2Pattern() const { return fY2Pattern; }
UShort_t GetTriggerX3Pattern() const { return fX3Pattern; }
UShort_t GetTriggerY3Pattern() const { return fY3Pattern; }
UShort_t GetTriggerX4Pattern() const { return fX4Pattern; }
UShort_t GetTriggerY4Pattern() const { return fY4Pattern; }
void SetTriggerX1Pattern(UShort_t pat) { fX1Pattern = pat; }
void SetTriggerY1Pattern(UShort_t pat) { fY1Pattern = pat; }
void SetTriggerX2Pattern(UShort_t pat) { fX2Pattern = pat; }
void SetTriggerY2Pattern(UShort_t pat) { fY2Pattern = pat; }
void SetTriggerX3Pattern(UShort_t pat) { fX3Pattern = pat; }
void SetTriggerY3Pattern(UShort_t pat) { fY3Pattern = pat; }
void SetTriggerX4Pattern(UShort_t pat) { fX4Pattern = pat; }
void SetTriggerY4Pattern(UShort_t pat) { fY4Pattern = pat; }
UInt_t GetMuonClusterMap() const {return fMuonClusterMap;}
void SetMuonClusterMap(UInt_t muonClusterMap) {fMuonClusterMap = muonClusterMap;}
void AddInMuonClusterMap(Int_t chamber) {fMuonClusterMap |= BIT(chamber);}
Bool_t IsInMuonClusterMap(Int_t chamber) const {return (Bool_t) ((fMuonClusterMap & BIT(chamber)) != 0);}
void Connected(Bool_t flag = kTRUE) {flag ? SETBIT(fMuonClusterMap,31) : CLRBIT(fMuonClusterMap,31);}
Bool_t IsConnected() const {return TESTBIT(fMuonClusterMap,31);}
void AddClusterId(UInt_t clusterId);
Int_t GetNClusters() const {return static_cast<Int_t>(fNHit);}
UInt_t GetClusterId(Int_t i) const {return (fClustersId && i >= 0 && i < fNHit) ? static_cast<UInt_t>(fClustersId->At(i)) : 0;}
Bool_t IsOldTrack() {return (fClusters);}
void MoveClustersToESD(AliESDEvent &esd);
Double_t Px() const;
Double_t Py() const;
Double_t Pz() const;
Double_t P() const;
Bool_t PxPyPz(Double_t p[3]) const { p[0] = Px(); p[1] = Py(); p[2] = Pz(); return kTRUE; }
void LorentzP(TLorentzVector& vP) const;
Double_t PxAtDCA() const;
Double_t PyAtDCA() const;
Double_t PzAtDCA() const;
Double_t PAtDCA() const;
Bool_t PxPyPzAtDCA(Double_t p[3]) const { p[0] = Px(); p[1] = Py(); p[2] = Pz(); return kTRUE; }
void LorentzPAtDCA(TLorentzVector& vP) const;
Double_t PxUncorrected() const;
Double_t PyUncorrected() const;
Double_t PzUncorrected() const;
Double_t PUncorrected() const;
Bool_t PxPyPzUncorrected(Double_t p[3]) const { p[0] = Px(); p[1] = Py(); p[2] = Pz(); return kTRUE; }
void LorentzPUncorrected(TLorentzVector& vP) const;
Double_t Xv() const {return -999.;}
Double_t Yv() const {return -999.;}
Double_t Zv() const {return -999.;}
Bool_t XvYvZv(Double_t x[3]) const { x[0] = Xv(); x[1] = Yv(); x[2] = Zv(); return kTRUE; }
Double_t Pt() const { return TMath::Sqrt(Px()*Px() + Py()*Py()); }
Double_t OneOverPt() const { return (Pt() != 0.) ? 1./Pt() : FLT_MAX; }
Double_t Phi() const { return TMath::Pi()+TMath::ATan2(-Py(), -Px()); }
Double_t Theta() const { return TMath::ATan2(Pt(), Pz()); }
Double_t E() const { return TMath::Sqrt(M()*M() + P()*P()); }
Double_t M() const { return TDatabasePDG::Instance()->GetParticle("mu-")->Mass(); }
Double_t Eta() const { return -TMath::Log(TMath::Tan(0.5 * Theta()));}
Double_t Y() const { return (Pz()/E() != 1.) ? TMath::ATanH(Pz()/E()) : FLT_MAX; }
Short_t Charge() const { return (Short_t)TMath::Sign(1., GetInverseBendingMomentum()); }
const Double_t *PID() const { return (Double_t*)0x0; }
Int_t PdgCode() const {return 0;}
void SetLabel(Int_t label) {fLabel = label;}
Int_t GetLabel() const {return fLabel;}
enum EAliTriggerChPatternFlag {
kNoEff,
kChEff,
kSlatEff,
kBoardEff
};
enum EAliTriggerChPatternInfo {
kCrossDifferentSlats = 20,
kTrackMatchesManyPads = 21,
kTrackMatchesFewPads = 22,
kTrackOutsideGeometry = 23,
kTrackerTrackPattern = 24,
kTrackMatchesMasks = 25
};
static void SetFiredChamber(UInt_t& pattern, Int_t cathode, Int_t chamber);
static void AddEffInfo(UInt_t& pattern, Int_t slatOrInfo, Int_t board = 0, EAliTriggerChPatternFlag effType = kNoEff);
static Bool_t IsChamberHit(UInt_t pattern, Int_t cathode, Int_t chamber);
static Int_t GetEffFlag(UInt_t pattern);
static Int_t GetSlatOrInfo(UInt_t pattern);
static Int_t GetCrossedBoard(UInt_t pattern);
void AddMuonTrigDevSignInfo(UInt_t& pattern) const;
AliESDEvent* GetESDEvent() const {return fESDEvent;}
void SetESDEvent(AliESDEvent* evt) {fESDEvent = evt;}
protected:
Double32_t fInverseBendingMomentum;
Double32_t fThetaX;
Double32_t fThetaY;
Double32_t fZ;
Double32_t fBendingCoor;
Double32_t fNonBendingCoor;
Double32_t fInverseBendingMomentumAtDCA;
Double32_t fThetaXAtDCA;
Double32_t fThetaYAtDCA;
Double32_t fBendingCoorAtDCA;
Double32_t fNonBendingCoorAtDCA;
Double32_t fInverseBendingMomentumUncorrected;
Double32_t fThetaXUncorrected;
Double32_t fThetaYUncorrected;
Double32_t fZUncorrected;
Double32_t fBendingCoorUncorrected;
Double32_t fNonBendingCoorUncorrected;
Double32_t fCovariances[15];
Double32_t fRAtAbsorberEnd;
Double32_t fChi2;
Double32_t fChi2MatchTrigger;
Int_t fLocalTrigger;
UShort_t fX1Pattern;
UShort_t fY1Pattern;
UShort_t fX2Pattern;
UShort_t fY2Pattern;
UShort_t fX3Pattern;
UShort_t fY3Pattern;
UShort_t fX4Pattern;
UShort_t fY4Pattern;
UInt_t fMuonClusterMap;
UShort_t fHitsPatternInTrigCh;
UInt_t fHitsPatternInTrigChTrk;
UChar_t fNHit;
mutable TClonesArray* fClusters;
TArrayI* fClustersId;
Int_t fLabel;
AliESDEvent* fESDEvent;
ClassDef(AliESDMuonTrack,15)
};
#endif