// LCDTrack.h
// 04-06-2000 T.Abe     Change track parameter definition.
// 07-26-1999 M.Iwasaki Remove momntum, charge, position inputs in Track().
// 05-13-1999 Richard   add track pars, error matrix, ndf, chi2
// Sept 10,1998 Rob Shanks, Stanford Linear Accelerator Center
// 

#ifndef LCDTRACK_H
#define LCDTRACK_H

#include "TObject.h"
#include "TClonesArray.h"
#include "TVector3.h"
#include "TMatrixD.h"

class LCDTrack: public TObject {

public: 
  LCDTrack(){m_index = 0;};
  LCDTrack(Int_t index,Int_t index0,Double_t bfld_z,Int_t ndf,Double_t chi2, 
	   Double_t* par, Double_t* errMat);
  LCDTrack(Int_t index,Int_t index0,Double_t bfld_z,Int_t ndf,Double_t chi2, 
	   Double_t qMC, TVector3 xvt, TVector3 pvt, Double_t* errMat);
  LCDTrack(TClonesArray* mclist,Int_t index,Double_t bfld_z,
	   Int_t ndf,Double_t chi2, Double_t* errMat);
  LCDTrack(LCDTrack* trk);
  ~LCDTrack();

  void SetLCDTrack(Int_t index,Int_t index0,Double_t bfld_z,Int_t ndf,
		   Double_t chi2,Double_t* par, Double_t* errMat);

  void     WriteTrack(FILE* ofile) const; 
  //Output track information to ascii file

  Double_t  GetCharge()                { return m_charge       ; }
  Int_t     GetParticle()              { return m_index        ; }
  Int_t     GetParent()                { return m_index0       ; }
  Double_t  GetChi2()                  { return m_chisquared   ; }
  Int_t     GetNdf()                   { return m_ndf          ; }
  Double_t  GetMagneticField()         { return m_magneticfield; }

  Double_t  GetTrackParameter(Int_t i);
  Double_t* GetTrackParameters();
  Double_t  GetPositionX(Double_t l);
  Double_t  GetPositionY(Double_t l);
  Double_t  GetPositionZ(Double_t l);
  TVector3  GetPositionVector(Double_t l);
  Double_t* GetPosition();
  Double_t* GetPosition(Double_t l);
  Double_t  GetMomentumPx(Double_t l);
  Double_t  GetMomentumPy(Double_t l);
  Double_t  GetMomentumPz(Double_t l);
  TVector3  GetMomentumVector(Double_t l);
  Double_t* GetMomentum();
  Double_t* GetMomentum(Double_t l);
  Double_t  GetDistance(Double_t l,
			Double_t x_from,Double_t y_from,Double_t z_from);
  Double_t  GetDistance(Double_t x_from,Double_t y_from,Double_t z_from);
  Double_t  GetDistance(TVector3 x_from);

  Double_t  GetErrorMatrixElement(Int_t i,Int_t j);
  void      GetErrorMatrix(TMatrixD& em);
  Double_t* GetErrorMatrix() { return m_trackErrorMatrix; }
  void      GetErrorMatrixPosition(Double_t l,TMatrixD& em);
  void      GetErrorMatrixMomentum(Double_t l,TMatrixD& em);
  Double_t  GetErrorDistance(Double_t l,
			     Double_t x_from,Double_t y_from,Double_t z_from);
  Double_t  GetErrorDistance(Double_t x_from,Double_t y_from,Double_t z_from);
  Double_t  GetErrorDistance(TVector3 x_from);

  void      Getdxda(Double_t l,TMatrixD& dxda);
  void      Getdpda(Double_t l,TMatrixD& dpda);
  void      Getddda(Double_t l,
		    Double_t x_from,Double_t y_from,Double_t z_from,
		    TMatrixD& ddda);
  void      Getd2xd2l(Double_t l,TMatrixD& d2xd2l);
  void      Getdxdl(Double_t l,TMatrixD& dxdl);

  Double_t CalcPOCA3(TVector3 x_point); //return l

  Double_t dlen2(Double_t l, TVector3 x_from);
  Double_t ddlen2dl(Double_t l,TVector3 x_from);
  Double_t d2dlen2d2l(Double_t l, TVector3 x_from);

private:
  Double_t m_trackPar[5]; // helix parameters
  /* helix parameter[i]  
     i=0     d0
     1     phi0
     2   omega=(-Q/rho) <0  charge +   
     >0  charge -
     3     z0
     4     s(=tan_L)                       */
  
  Double_t m_trackErrorMatrix[15]; // error matrix of helix parameters
  // m_trackErrorMatrix[ 0] = sigma(0)*sigma(0)
  // m_trackErrorMatrix[ 1] = sigma(1)*sigma(0)
  // m_trackErrorMatrix[ 2] = sigma(1)*sigma(1)
  // m_trackErrorMatrix[ 3] = sigma(2)*sigma(0)
  // m_trackErrorMatrix[ 4] = sigma(2)*sigma(1)
  // m_trackErrorMatrix[ 5] = sigma(2)*sigma(2)
  // m_trackErrorMatrix[ 6] = sigma(3)*sigma(0)
  // m_trackErrorMatrix[ 7] = sigma(3)*sigma(1)
  // m_trackErrorMatrix[ 8] = sigma(3)*sigma(2)
  // m_trackErrorMatrix[ 9] = sigma(3)*sigma(3)
  // m_trackErrorMatrix[10] = sigma(4)*sigma(0)
  // m_trackErrorMatrix[11] = sigma(4)*sigma(1)
  // m_trackErrorMatrix[12] = sigma(4)*sigma(2)
  // m_trackErrorMatrix[13] = sigma(4)*sigma(3)
  // m_trackErrorMatrix[14] = sigma(4)*sigma(4)

  Double_t m_charge;     // Charge of the particle
  Double_t m_chisquared; // chi-squared of fit
  Double_t m_magneticfield;
  Int_t m_ndf;          // number of degrees of freedom of fit
  Int_t m_index;        // Index to the McPart object responsible for the track
  Int_t m_index0;       // Index to the McPart object responsible for the parent particle

  Double_t m_position[3];
  Double_t m_momentum[3];

  void      CalcPOCA(Double_t  qMC, Double_t  bfld_z,
		     TVector3  p_orig, TVector3  x_orig, 
		     TVector3& p_poca, TVector3& x_poca);

  void      CalcTrackParameters(Double_t qMC,Double_t bfld_z,
				TVector3 pMC, TVector3 xMC, Double_t* tkpar);

public:
  ClassDef(LCDTrack,4)// Instance of energy deposition in track system
}; 

#endif
