// LCDVToplVRT.h
// August   15,2000 Masako & Toshi, original version copied from D.Jackson's
//                  ZVTOP3
// December  1,2000 Toshi, switch to Kalman Filter fitting.
// 
#ifndef LCDVTOPLVRT_H
#define LCDVTOPLVRT_H

#include "TObject.h"
#include "TObjArray.h"
#include "TVector3.h"
#include "TLorentzVector.h"
#include "TMatrixD.h"

#include "LCDVToplTRK.h"

class LCDVToplVRT: public TObject {

public:
  //constructor & deconstructor
  LCDVToplVRT();
  LCDVToplVRT(TVector3 xinit);
  LCDVToplVRT(TObjArray*);
  LCDVToplVRT(TObjArray*,TVector3);
  LCDVToplVRT(const LCDVToplVRT& vrt);
  ~LCDVToplVRT() {}

  Int_t AddTrack(LCDVToplTRK*);        //Add track
  Int_t AddTrack(LCDVToplTRK*,Int_t f_fit);        //Add track
  void AddTracks(TObjArray*);         //Add tracks
  void AddTracks(TObjArray*,Int_t f_fit);         //Add tracks

  void CalcFourVector();              //Calcurate four vector @ vertex

  void Clean();

  void CompressTracksList();          //Compress track list

  void DeleteTracks() { 
    for (Int_t itrk=0 ; itrk < m_ntrk ; itrk++) {
      delete track_list[itrk];
    }
  }

  Int_t FilteringToAddTrack(LCDVToplTRK* trk);
  Int_t FilteringToRemoveTrack(LCDVToplTRK* trk);

  Double_t  GetChi2() { return chisquared; } //Get chi2 of the vertex fit.
  Double_t  GetDecayLength(TVector3 x_from);  //Get decay length
  Double_t  GetEpscut()       { return epscut; }     //Get eps. cut
  TMatrixD* GetError() { return &m_error; }
  Double_t  GetErrorDecayLength(TVector3 x_from, TMatrixD& err_from);
  //Get error of decay length
  void      GetErrorMatrixVertex(TMatrixD& em); //Get Error Matrix(position)

  TMatrixD*      GetFitParm() { return &m_fitparm; }

  TLorentzVector GetFourVector()   { return a4vec; }      //Get Vertex 4 Vect.
  Double_t       GetFourVectorPx() { return a4vec.Px(); } //Get Vertex Px
  Double_t       GetFourVectorPy() { return a4vec.Py(); } //Get Vertex Py
  Double_t       GetFourVectorPz() { return a4vec.Pz(); } //Get Vertex Pz
  Double_t       GetFourVectorE()  { return a4vec.E(); }  //Get Vertex E  

  Double_t       GetMass()         { return a4vec.M(); }  //Get Vertex mass
  Int_t          GetMaxtry()       { return maxtry; }     //Get max. # of try

  Double_t       GetPchi2(Int_t itrk); //Get chi2 contrib. of the given trk.

  TLorentzVector GetTrack4MomentumVector(Int_t itrk);
  Int_t          GetTrackEntries()        // Get # of Tracks in the vertex.
  { return m_ntrk; }
  LCDVToplTRK* GetTrackAt(Int_t itrk)  //Get LCDVToplTRK
  { return (LCDVToplTRK*)track_list[itrk]; }
  //Int_t          GetNsig(Double_t nsigma, TVector3 axis, TVector3 ipv,
  //			 TMatrixD& eipv); //Get # of significance track
  TVector3       GetTrackMomentumVector(Int_t itrk);

  Double_t GetVertexCharge() { return qvtx; }       //Get Vertex charge
  TVector3 GetVertexVector();  //Get Vertex Position(Vector)
  Double_t GetVertexX(){ return m_fitparm(0,0); }//Get Vertex Position(X)
  Double_t GetVertexY(){ return m_fitparm(1,0); }//Get Vertex Position(Y)
  Double_t GetVertexZ(){ return m_fitparm(2,0); }//Get Vertex Position(Z)
  Double_t GetVsig()         { return vsig; };      //Get Vertex sig.

  Int_t IndexOfTrack(LCDVToplTRK* trk);

  void linearizeChargedTrack(TMatrixD& a, TMatrixD& b, TMatrixD& h0, 
			     TMatrixD& x, TMatrixD& q);

  Int_t RemoveTrackAt(Int_t itrk);     //Remove track
  Int_t RemoveTrackAt(Int_t itrk, Int_t f_fit);     //Remove track
  Int_t RemoveTrack(LCDVToplTRK* trk); //Remove track
  Int_t RemoveTrack(LCDVToplTRK* trk, Int_t f_fit); //Remove track

  void SetEpsCut(Double_t a) {epscut = a;}  //Set eps. cut
  void SetMaxtry(Int_t a)    {maxtry = a;}  //Set max. # of try
  void SetVertex(Double_t*);  //Set Vertex
  void SetVertex(TVector3);  //Set Vertex
  void SetVsig(Double_t v) { vsig=v; }  //Set Vertex   significance

  void SmoothingParameters(LCDVToplTRK* trk,TMatrixD& q);

  TObject**   Tracks() { return track_list; }

  Int_t VertexFit();//Vertex Fitter
  Int_t VertexFit(TVector3 xvinit);//Vertex Fitter

  LCDVToplVRT & operator = (const LCDVToplVRT &);

  //---Sort related part.
  Bool_t IsSortable() const { return kTRUE; }
  Int_t  Compare(const TObject *obj) const {
    if        (vsig < ((LCDVToplVRT*)obj)->GetVsig()) {
      return -1;
    } else if (vsig > ((LCDVToplVRT*)obj)->GetVsig()) {
      return +1;
    } else {
      return 0;
    }
  }

private:
  Int_t          maxtry;    // maximum iteration number
  Double_t       epscut;    // control convergence of fitting
  Int_t          m_ntrk;
  TObject*       track_list[100];// pointer array of tracks
  TMatrixD       m_fitparm; // vertex position
  TMatrixD       m_error;   // error matrix of vertex position
  TLorentzVector a4vec;     // vertex momentum vector
  Double_t       qvtx;
  Double_t       chisquared;// chisquare of vertex fitting
  Double_t       vsig;      // Vertex SIGnificance func. value
  
  //initialize above variables
  void Init(TVector3 xinit);
  void Init(TObjArray* tracks, TVector3 xinit);
  
  //Filtering with Kalman filter
  Int_t Filtering(LCDVToplTRK* trk);
  
public:
  ClassDef(LCDVToplVRT,2)// A vertex class for topological vertexing.
};

#endif
