#ifndef ROOT_Math_GenVector_LorentzRotation 
#define ROOT_Math_GenVector_LorentzRotation  1
#include "Math/GenVector/LorentzRotationfwd.h"
#include "Math/GenVector/LorentzVector.h"
#include "Math/GenVector/PxPyPzE4D.h"
#include "Math/GenVector/Rotation3Dfwd.h"
#include "Math/GenVector/AxisAnglefwd.h"
#include "Math/GenVector/EulerAnglesfwd.h"
#include "Math/GenVector/Quaternionfwd.h"
#include "Math/GenVector/RotationXfwd.h"
#include "Math/GenVector/RotationYfwd.h"
#include "Math/GenVector/RotationZfwd.h"
#include "Math/GenVector/Boost.h"
#include "Math/GenVector/BoostX.h"
#include "Math/GenVector/BoostY.h"
#include "Math/GenVector/BoostZ.h"
namespace ROOT {
  namespace Math {
  
class LorentzRotation {
public:
  typedef double Scalar;
  enum ELorentzRotationMatrixIndex {
      kXX =  0, kXY =  1, kXZ =  2, kXT =  3
    , kYX =  4, kYY =  5, kYZ =  6, kYT =  7
    , kZX =  8, kZY =  9, kZZ = 10, kZT = 11
    , kTX = 12, kTY = 13, kTZ = 14, kTT = 15
  };
  
  
  LorentzRotation();
  
  template<class IT>
  LorentzRotation(IT begin, IT end) { SetComponents(begin,end); }
  
  explicit LorentzRotation( Boost  const & b  ) {  b.GetLorentzRotation( fM+0 ); } 
  explicit LorentzRotation( BoostX const & bx ) { bx.GetLorentzRotation( fM+0 ); }
  explicit LorentzRotation( BoostY const & by ) { by.GetLorentzRotation( fM+0 ); }
  explicit LorentzRotation( BoostZ const & bz ) { bz.GetLorentzRotation( fM+0 ); }
  
  explicit LorentzRotation( Rotation3D  const & r ); 
  explicit LorentzRotation( AxisAngle   const & a ); 
  explicit LorentzRotation( EulerAngles const & e ); 
  explicit LorentzRotation( Quaternion  const & q ); 
  explicit LorentzRotation( RotationX   const & r ); 
  explicit LorentzRotation( RotationY   const & r ); 
  explicit LorentzRotation( RotationZ   const & r ); 
  
  template<class ForeignMatrix>
  explicit LorentzRotation(const ForeignMatrix & m) { SetComponents(m); }
  
  template<class Foreign4Vector>
  LorentzRotation(const Foreign4Vector& v1,
                  const Foreign4Vector& v2,
                  const Foreign4Vector& v3,
                  const Foreign4Vector& v4 ) { SetComponents(v1, v2, v3, v4); }
  
  
  LorentzRotation(Scalar  xx, Scalar  xy, Scalar  xz, Scalar xt,
                  Scalar  yx, Scalar  yy, Scalar  yz, Scalar yt,
                  Scalar  zx, Scalar  zy, Scalar  zz, Scalar zt,
                  Scalar  tx, Scalar  ty, Scalar  tz, Scalar tt)
 {
    SetComponents (xx, xy, xz, xt, 
    		   yx, yy, yz, yt, 
                   zx, zy, zz, zt,
		   tx, ty, tz, tt);
 }
  
  LorentzRotation &
  operator=( Boost  const & b ) { return operator=(LorentzRotation(b)); }
  LorentzRotation &
  operator=( BoostX const & b ) { return operator=(LorentzRotation(b)); }
  LorentzRotation &
  operator=( BoostY const & b ) { return operator=(LorentzRotation(b)); }
  LorentzRotation &
  operator=( BoostZ const & b ) { return operator=(LorentzRotation(b)); }
  
  LorentzRotation &
  operator=( Rotation3D  const & r ) { return operator=(LorentzRotation(r)); }
  LorentzRotation &
  operator=( AxisAngle   const & a ) { return operator=(LorentzRotation(a)); }
  LorentzRotation &
  operator=( EulerAngles const & e ) { return operator=(LorentzRotation(e)); }
  LorentzRotation &
  operator=( Quaternion  const & q ) { return operator=(LorentzRotation(q)); }
  LorentzRotation &
  operator=( RotationZ   const & r ) { return operator=(LorentzRotation(r)); }
  LorentzRotation &
  operator=( RotationY   const & r ) { return operator=(LorentzRotation(r)); }
  LorentzRotation &
  operator=( RotationX   const & r ) { return operator=(LorentzRotation(r)); }
  
  template<class ForeignMatrix>
  LorentzRotation &
  operator=(const ForeignMatrix & m) { SetComponents(m); return *this; }
  
  void Rectify();
  
  
  template<class Foreign4Vector>
  void
  SetComponents (const Foreign4Vector& v1,
                 const Foreign4Vector& v2,
                 const Foreign4Vector& v3,
                 const Foreign4Vector& v4 ) {
    fM[kXX]=v1.x();  fM[kXY]=v2.x();  fM[kXZ]=v3.x();  fM[kXT]=v4.x();
    fM[kYX]=v1.y();  fM[kYY]=v2.y();  fM[kYZ]=v3.y();  fM[kYT]=v4.y();
    fM[kZX]=v1.z();  fM[kZY]=v2.z();  fM[kZZ]=v3.z();  fM[kZT]=v4.z();
    fM[kTX]=v1.t();  fM[kTY]=v2.t();  fM[kTZ]=v3.t();  fM[kTT]=v4.t();
    Rectify();
  }
  
  template<class Foreign4Vector>
  void
  GetComponents ( Foreign4Vector& v1,
                  Foreign4Vector& v2,
                  Foreign4Vector& v3,
                  Foreign4Vector& v4 ) const {
    v1 = Foreign4Vector ( fM[kXX], fM[kYX], fM[kZX], fM[kTX] );
    v2 = Foreign4Vector ( fM[kXY], fM[kYY], fM[kZY], fM[kTY] );
    v3 = Foreign4Vector ( fM[kXZ], fM[kYZ], fM[kZZ], fM[kTZ] );
    v4 = Foreign4Vector ( fM[kXT], fM[kYT], fM[kZT], fM[kTT] );
  }
  
  template<class IT>
  void SetComponents(IT begin, IT end) {
     for (int i = 0; i <16; ++i) { 
        fM[i] = *begin;
        ++begin; 
     }
     assert (end==begin);
  }
  
  template<class IT>
  void GetComponents(IT begin, IT end) const {
     for (int i = 0; i <16; ++i) { 
        *begin = fM[i];
        ++begin;  
     }
     assert (end==begin);
  }
  
  template<class IT>
  void GetComponents(IT begin) const {
    std::copy ( fM+0, fM+16, begin );
  }
  
  template<class ForeignMatrix>
  void
  SetRotationMatrix (const ForeignMatrix & m) {
    fM[kXX]=m(0,0);  fM[kXY]=m(0,1);  fM[kXZ]=m(0,2);  fM[kXT]=m(0,3);
    fM[kYX]=m(1,0);  fM[kYY]=m(1,1);  fM[kYZ]=m(1,2);  fM[kYT]=m(1,3);
    fM[kZX]=m(2,0);  fM[kZY]=m(2,1);  fM[kZZ]=m(2,2);  fM[kZT]=m(2,3);
    fM[kTX]=m(3,0);  fM[kTY]=m(3,1);  fM[kTZ]=m(3,2);  fM[kTT]=m(3,3);
  }
  
  template<class ForeignMatrix>
  void
  GetRotationMatrix (ForeignMatrix & m) const {
    m(0,0)=fM[kXX];  m(0,1)=fM[kXY];  m(0,2)=fM[kXZ]; m(0,3)=fM[kXT];
    m(1,0)=fM[kYX];  m(1,1)=fM[kYY];  m(1,2)=fM[kYZ]; m(1,3)=fM[kYT];
    m(2,0)=fM[kZX];  m(2,1)=fM[kZY];  m(2,2)=fM[kZZ]; m(2,3)=fM[kZT];
    m(3,0)=fM[kTX];  m(3,1)=fM[kTY];  m(3,2)=fM[kTZ]; m(3,3)=fM[kTT];
  }
  
  void
  SetComponents (Scalar  xx, Scalar  xy, Scalar  xz, Scalar  xt,
                 Scalar  yx, Scalar  yy, Scalar  yz, Scalar  yt,
                 Scalar  zx, Scalar  zy, Scalar  zz, Scalar  zt,
                 Scalar  tx, Scalar  ty, Scalar  tz, Scalar  tt) {
                 fM[kXX]=xx;  fM[kXY]=xy;  fM[kXZ]=xz;  fM[kXT]=xt;
                 fM[kYX]=yx;  fM[kYY]=yy;  fM[kYZ]=yz;  fM[kYT]=yt;
                 fM[kZX]=zx;  fM[kZY]=zy;  fM[kZZ]=zz;  fM[kZT]=zt;
                 fM[kTX]=tx;  fM[kTY]=ty;  fM[kTZ]=tz;  fM[kTT]=tt;
  }
  
  void
  GetComponents (Scalar &xx, Scalar &xy, Scalar &xz, Scalar &xt,
                 Scalar &yx, Scalar &yy, Scalar &yz, Scalar &yt,
                 Scalar &zx, Scalar &zy, Scalar &zz, Scalar &zt,
                 Scalar &tx, Scalar &ty, Scalar &tz, Scalar &tt) const {
                 xx=fM[kXX];  xy=fM[kXY];  xz=fM[kXZ];  xt=fM[kXT];
                 yx=fM[kYX];  yy=fM[kYY];  yz=fM[kYZ];  yt=fM[kYT];
                 zx=fM[kZX];  zy=fM[kZY];  zz=fM[kZZ];  zt=fM[kZT];
                 tx=fM[kTX];  ty=fM[kTY];  tz=fM[kTZ];  tt=fM[kTT];
  }
  
  
  LorentzVector< ROOT::Math::PxPyPzE4D<double> >
  operator() (const LorentzVector< ROOT::Math::PxPyPzE4D<double> > & v) const { 
        Scalar x = v.Px();
        Scalar y = v.Py();
        Scalar z = v.Pz();
        Scalar t = v.E();
        return LorentzVector< PxPyPzE4D<double> > 
           ( fM[kXX]*x + fM[kXY]*y + fM[kXZ]*z + fM[kXT]*t 
             , fM[kYX]*x + fM[kYY]*y + fM[kYZ]*z + fM[kYT]*t
             , fM[kZX]*x + fM[kZY]*y + fM[kZZ]*z + fM[kZT]*t
             , fM[kTX]*x + fM[kTY]*y + fM[kTZ]*z + fM[kTT]*t );        
  }
  
  
  template <class CoordSystem>
  LorentzVector<CoordSystem>
  operator() (const LorentzVector<CoordSystem> & v) const {
    LorentzVector< PxPyPzE4D<double> > xyzt(v);
    LorentzVector< PxPyPzE4D<double> > r_xyzt = operator()(xyzt);
    return LorentzVector<CoordSystem> ( r_xyzt );
  }
  
  template <class Foreign4Vector>
  Foreign4Vector
  operator() (const Foreign4Vector & v) const {
    LorentzVector< PxPyPzE4D<double> > xyzt(v);
    LorentzVector< PxPyPzE4D<double> > r_xyzt = operator()(xyzt);
    return Foreign4Vector ( r_xyzt.X(), r_xyzt.Y(), r_xyzt.Z(), r_xyzt.T() );
  }
  
  template <class A4Vector>
  inline
  A4Vector operator* (const A4Vector & v) const
  {
    return operator()(v);
  }
  
  void Invert();
  
  LorentzRotation Inverse() const;
  
  
  LorentzRotation operator * (const LorentzRotation & r) const;
  
  
  
  
  LorentzRotation operator * (const Boost  & b) const  { LorentzRotation tmp(b); return (*this)*tmp; }
  LorentzRotation operator * (const BoostX & b) const  { LorentzRotation tmp(b); return (*this)*tmp; } 
  LorentzRotation operator * (const BoostY & b) const  { LorentzRotation tmp(b); return (*this)*tmp; }
  LorentzRotation operator * (const BoostZ & b) const  { LorentzRotation tmp(b); return (*this)*tmp; }
  
  LorentzRotation operator * (const Rotation3D  & r) const { LorentzRotation tmp(r); return (*this)*tmp; }
  LorentzRotation operator * (const AxisAngle   & a) const { LorentzRotation tmp(a); return (*this)*tmp; }
  LorentzRotation operator * (const EulerAngles & e) const { LorentzRotation tmp(e); return (*this)*tmp; }
  LorentzRotation operator * (const Quaternion  & q) const { LorentzRotation tmp(q); return (*this)*tmp; }
  LorentzRotation operator * (const RotationX  & rx) const { LorentzRotation tmp(rx); return (*this)*tmp; }
  LorentzRotation operator * (const RotationY  & ry) const { LorentzRotation tmp(ry); return (*this)*tmp; }
  LorentzRotation operator * (const RotationZ  & rz) const { LorentzRotation tmp(rz); return (*this)*tmp; }
  
  
  template <class R>
  LorentzRotation & operator *= (const R & r) { return *this = (*this)*r; }
  
  bool operator == (const LorentzRotation & rhs) const {
    for (unsigned int i=0; i < 16; ++i) {
      if( fM[i] != rhs.fM[i] )  return false;
    }
    return true;
  }
  bool operator != (const LorentzRotation & rhs) const {
    return ! operator==(rhs);
  }
private:
  Scalar fM[16];
};  
  
std::ostream & operator<< (std::ostream & os, const LorentzRotation & r);
#ifdef NOTYET
template <class R>
inline
typename Rotation3D::Scalar
Distance ( const Rotation3D& r1, const R & r2) {return gv_detail::dist(r1,r2);}
#endif
} 
} 
#endif /* ROOT_Math_GenVector_LorentzRotation  */
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.