#ifndef ALIMUONTRACK_H
#define ALIMUONTRACK_H
#include <TObjArray.h>
#include <TMatrixD.h>
class AliMUONVCluster;
class AliMUONObjectPair;
class AliMUONTrackParam;
class AliMUONTrack : public TObject
{
public:
AliMUONTrack();
AliMUONTrack(AliMUONObjectPair *segment, Double_t bendingVertexDispersion);
virtual ~AliMUONTrack();
AliMUONTrack (const AliMUONTrack& track);
AliMUONTrack& operator=(const AliMUONTrack& track);
void Reset();
TObjArray* GetTrackParamAtCluster() const;
void AddTrackParamAtCluster(const AliMUONTrackParam &trackParam, AliMUONVCluster &cluster, Bool_t copy = kFALSE);
void RemoveTrackParamAtCluster(AliMUONTrackParam *trackParam);
Bool_t UpdateTrackParamAtCluster();
Bool_t UpdateCovTrackParamAtCluster();
Bool_t IsValid(UInt_t requestedStationMask, Bool_t request2ChInSameSt45 = kFALSE);
void TagRemovableClusters(UInt_t requestedStationMask);
Int_t GetNClusters() const {return fTrackParamAtCluster ? fTrackParamAtCluster->GetEntriesFast() : 0;}
Bool_t FitWithVertex() const {return fFitWithVertex;}
void FitWithVertex(Bool_t fitWithVertex) { fFitWithVertex = fitWithVertex; }
void GetVertexErrXY2(Double_t &nonBendingErr2, Double_t &bendingErr2) const
{ nonBendingErr2 = fVertexErrXY2[0]; bendingErr2 = fVertexErrXY2[1]; }
void SetVertexErrXY2(Double_t nonBendingErr2, Double_t bendingErr2)
{ fVertexErrXY2[0] = nonBendingErr2; fVertexErrXY2[1] = bendingErr2; }
Bool_t FitWithMCS() const {return fFitWithMCS;}
void FitWithMCS(Bool_t fitWithMCS) {fFitWithMCS = fitWithMCS;}
Bool_t ComputeClusterWeights(TMatrixD* mcsCovariances = 0);
Bool_t ComputeLocalChi2(Bool_t accountForMCS);
Double_t ComputeGlobalChi2(Bool_t accountForMCS);
Double_t GetGlobalChi2() const {return fGlobalChi2;}
void SetGlobalChi2(Double_t chi2) { fGlobalChi2 = chi2;}
Bool_t IsImproved() const {return fImproved;}
void SetImproved(Bool_t improved) { fImproved = improved;}
Int_t GetMatchTrigger(void) const {return fMatchTrigger;}
Int_t GetLoTrgNum(void) const {return LoCircuit();}
void SetMatchTrigger(Int_t matchTrigger) {fMatchTrigger = matchTrigger;}
Double_t GetChi2MatchTrigger(void) const {return fChi2MatchTrigger;}
void SetChi2MatchTrigger(Double_t chi2MatchTrigger) {fChi2MatchTrigger = chi2MatchTrigger;}
Int_t ClustersInCommon(AliMUONTrack* track, Int_t stMin = 0, Int_t stMax = 4) const;
Int_t GetNDF() const;
Double_t GetNormalizedChi2() const;
Int_t FindCompatibleClusters(const AliMUONTrack &track, Double_t sigma2Cut, Bool_t compatibleCluster[10]) const;
Bool_t Match(AliMUONTrack &track, Double_t sigma2Cut, Int_t &nMatchClusters) const;
AliMUONTrackParam* GetTrackParamAtVertex() const {return fTrackParamAtVertex;}
void SetTrackParamAtVertex(const AliMUONTrackParam* trackParam);
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 loCirc, Int_t loStripX, Int_t loStripY, Int_t loDev, Int_t loLpt, Int_t loHpt, UChar_t respWithoutChamber=0);
Int_t GetLocalTrigger(void) const { return fLocalTrigger; }
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; }
void FindMCLabel();
void SetMCLabel(Int_t label) {fTrackID = label;}
Int_t GetMCLabel() const {return fTrackID;}
void RecursiveDump(void) const;
virtual void Print(Option_t* opt="") const;
virtual void Clear(Option_t* opt="");
static Double_t MaxChi2() {return fgkMaxChi2;}
void Connected(Bool_t flag = kTRUE) {fConnected = flag;}
Bool_t IsConnected() const {return fConnected;}
private:
static const Double_t fgkMaxChi2;
mutable TObjArray* fTrackParamAtCluster;
Bool_t fFitWithVertex;
Double_t fVertexErrXY2[2];
Bool_t fFitWithMCS;
TMatrixD* fClusterWeightsNonBending;
TMatrixD* fClusterWeightsBending;
Double_t fGlobalChi2;
Bool_t fImproved;
Int_t fMatchTrigger;
Double_t fChi2MatchTrigger;
Int_t fTrackID;
AliMUONTrackParam* fTrackParamAtVertex;
UShort_t fHitsPatternInTrigCh;
UInt_t fHitsPatternInTrigChTrk;
Int_t fLocalTrigger;
Bool_t fConnected;
Bool_t ComputeClusterWeights(TMatrixD& clusterWeightsNB, TMatrixD& clusterWeightsB,
TMatrixD* mcsCovariances = 0, const AliMUONVCluster* discardedCluster = 0) const;
void ComputeMCSCovariances(TMatrixD& mcsCovariances) const;
ClassDef(AliMUONTrack, 11)
};
#endif