#ifndef ROOT_Math_GenVector_LorentzVector 
#define ROOT_Math_GenVector_LorentzVector  1
#ifndef ROOT_Math_GenVector_PxPyPzE4D
#include "Math/GenVector/PxPyPzE4D.h"
#endif
#ifndef ROOT_Math_GenVector_DisplacementVector3D 
#include "Math/GenVector/DisplacementVector3D.h"
#endif
#ifndef ROOT_Math_GenVector_GenVectorIO
#include "Math/GenVector/GenVectorIO.h"
#endif
namespace ROOT {
  namespace Math {
    
    template< class CoordSystem >
    class LorentzVector {
    public:
       
       typedef typename CoordSystem::Scalar Scalar;
       typedef CoordSystem CoordinateType;
       
       LorentzVector ( ) : fCoordinates() { }
       
       LorentzVector(const Scalar & a,
                     const Scalar & b,
                     const Scalar & c,
                     const Scalar & d) :
          fCoordinates(a , b,  c, d)  { }
       
       template< class Coords >
       explicit LorentzVector(const LorentzVector<Coords> & v ) :
          fCoordinates( v.Coordinates() ) { }
       
       template<class ForeignLorentzVector>
       explicit LorentzVector( const ForeignLorentzVector & v) :
          fCoordinates(PxPyPzE4D<Scalar>( v.x(), v.y(), v.z(), v.t()  ) ) { }
#ifdef LATER
       
       template< class LAVector >
       explicit LorentzVector(const LAVector & v, size_t index0 ) {
          fCoordinates = CoordSystem ( v[index0], v[index0+1], v[index0+2], v[index0+3] );
       }
#endif
       
       
       template< class OtherCoords >
       LorentzVector & operator= ( const LorentzVector<OtherCoords> & v) {
          fCoordinates = v.Coordinates();
          return *this;
       }
       
       template<class ForeignLorentzVector>
       LorentzVector & operator = ( const ForeignLorentzVector & v) {
          SetXYZT( v.x(), v.y(), v.z(), v.t() );
          return *this;
       }
#ifdef LATER
       
       template< class LAVector >
       LorentzVector & AssignFrom(const LAVector & v, size_t index0=0 ) {
          fCoordinates.SetCoordinates( v[index0], v[index0+1], v[index0+2], v[index0+3] );
          return *this;
       }
#endif
       
       
       const CoordSystem & Coordinates() const {
          return fCoordinates;
       }
       
       void SetCoordinates( const Scalar src[] )
       { fCoordinates.SetCoordinates(src);  }
       
       void SetCoordinates( Scalar a, Scalar b, Scalar c, Scalar d )
       { fCoordinates.SetCoordinates(a, b, c, d);  }
       
       template< class IT >
       void SetCoordinates( IT begin, IT end  )
       { IT a = begin; IT b = ++begin; IT c = ++begin; IT d = ++begin;
       assert (++begin==end);
       SetCoordinates (*a,*b,*c,*d);
       }
       
       void GetCoordinates( Scalar& a, Scalar& b, Scalar& c, Scalar & d ) const
       { fCoordinates.GetCoordinates(a, b, c, d);  }
       
       void GetCoordinates( Scalar dest[] ) const
       { fCoordinates.GetCoordinates(dest);  }
       
       template <class IT>
       void GetCoordinates( IT begin, IT end ) const
       { IT a = begin; IT b = ++begin; IT c = ++begin; IT d = ++begin;
       assert (++begin==end);
       GetCoordinates (*a,*b,*c,*d);
       }
       
       template <class IT>
       void GetCoordinates( IT begin ) const { 
          Scalar a,b,c,d = 0; 
          GetCoordinates (a,b,c,d);
          *begin++ = a; 
          *begin++ = b; 
          *begin++ = c; 
          *begin   = d; 
       }
       
       void SetXYZT (Scalar x, Scalar y, Scalar z, Scalar t) {
          fCoordinates.SetPxPyPzE(x,y,z,t);
       }
       void SetPxPyPzE (Scalar x, Scalar y, Scalar z, Scalar t) {
          fCoordinates.SetPxPyPzE(x,y,z,t);
       }
       
       
       bool operator==(const LorentzVector & rhs) const {
          return fCoordinates==rhs.fCoordinates;
       }
       bool operator!= (const LorentzVector & rhs) const {
          return !(operator==(rhs));
       }
       
       
       
       Scalar Px() const  { return fCoordinates.Px(); }
       Scalar X()  const  { return fCoordinates.Px(); }
       
       Scalar Py() const { return fCoordinates.Py(); }
       Scalar Y()  const { return fCoordinates.Py(); }
       
       Scalar Pz() const { return fCoordinates.Pz(); }
       Scalar Z()  const { return fCoordinates.Pz(); }
       
       Scalar E()  const { return fCoordinates.E(); }
       Scalar T()  const { return fCoordinates.E(); }
       
       Scalar M2()   const { return fCoordinates.M2(); }
       
       Scalar M() const    { return fCoordinates.M();}
       
       Scalar R() const { return fCoordinates.R(); }
       Scalar P() const { return fCoordinates.R(); }
       
       Scalar P2() const { return P() * P(); }
       
       Scalar Perp2( ) const { return fCoordinates.Perp2();}
       
       Scalar Pt()  const { return fCoordinates.Pt(); }
       Scalar Rho() const { return fCoordinates.Pt(); }
       
       Scalar Mt2() const { return fCoordinates.Mt2(); }
       
       Scalar Mt() const { return fCoordinates.Mt(); }
       
       Scalar Et2() const { return fCoordinates.Et2(); }
       
       Scalar Et() const { return fCoordinates.Et(); }
       
       Scalar Phi() const  { return fCoordinates.Phi();}
       
       Scalar Theta() const { return fCoordinates.Theta(); }
       
       Scalar Eta() const { return fCoordinates.Eta(); }
       
       ::ROOT::Math::DisplacementVector3D<Cartesian3D<Scalar> > Vect() const {
          return ::ROOT::Math::DisplacementVector3D<Cartesian3D<Scalar> >( X(), Y(), Z() );
       }
       
       
       template< class OtherLorentzVector >
       Scalar Dot(const OtherLorentzVector & q) const {
          return t()*q.t() - x()*q.x() - y()*q.y() - z()*q.z();
       }
       
      template< class OtherLorentzVector >
      inline LorentzVector & operator += ( const OtherLorentzVector & q)
       {
          SetXYZT( x() + q.x(), y() + q.y(), z() + q.z(), t() + q.t()  );
          return *this;
       }
       
       template< class OtherLorentzVector >
       LorentzVector & operator -= ( const OtherLorentzVector & q) {
          SetXYZT( x() - q.x(), y() - q.y(), z() - q.z(), t() - q.t()  );
          return *this;
       }
       
       template<class OtherLorentzVector>
       LorentzVector  operator +  ( const OtherLorentzVector & v2) const 
       {
          LorentzVector<CoordinateType> v3(*this);
          v3 += v2;
          return v3;
       }
       
       template<class OtherLorentzVector>
       LorentzVector  operator -  ( const OtherLorentzVector & v2) const {
          LorentzVector<CoordinateType> v3(*this);
          v3 -= v2;
          return v3;
       }
       
       
       LorentzVector & operator *= (Scalar a) {
          fCoordinates.Scale(a);
          return *this;
       }
       
       LorentzVector & operator /= (Scalar a) {
          fCoordinates.Scale(1/a);
          return *this;
       }
       
       LorentzVector operator * ( const Scalar & a) const {
          LorentzVector tmp(*this);
          tmp *= a;
          return tmp;
       }
       
       LorentzVector<CoordSystem> operator / ( const Scalar & a) const {
          LorentzVector<CoordSystem> tmp(*this);
          tmp /= a;
          return tmp;
       }
       
       LorentzVector operator - () const {
          
          
          return operator*( Scalar(-1) );
       }
       LorentzVector operator + () const {
          return *this;
       }
       
       
       Scalar Rapidity() const {
          
          
          
          Scalar e = E();
          Scalar pz = Pz();
          return .5* std::log( (e+pz)/(e-pz) );
       }
       
       Scalar ColinearRapidity() const {
          
          
          Scalar e = E();
          Scalar p = P();
          return .5* std::log( (e+p)/(e-p) );
       }
       
       bool isTimelike( ) const {
          Scalar e = E(); Scalar p = P(); return e*e > p*p;
       }
       
       bool isLightlike( Scalar tolerance
                         = 100*std::numeric_limits<Scalar>::epsilon() ) const {
          Scalar e = E(); Scalar p = P(); Scalar delta = e-p;
          if ( e==0 ) return p==0;
          return delta*delta < tolerance * e*e;
       }
       
       bool isSpacelike( ) const {
          Scalar e = E(); Scalar p = P(); return e*e < p*p;
       }
       typedef DisplacementVector3D< Cartesian3D<Scalar> > BetaVector;
       
       BetaVector BoostToCM( ) const {
          if (E() == 0) {
             if (P() == 0) {
                return BetaVector();
             } else {
                
                
                return -Vect()/E();
             }
          }
          if (M2() <= 0) {
             
             
          }
          return -Vect()/E();
       }
       
       template <class Other4Vector>
       BetaVector BoostToCM(const Other4Vector& v ) const {
          Scalar eSum = E() + v.E();
          DisplacementVector3D< Cartesian3D<Scalar> > vecSum = Vect() + v.Vect();
          if (eSum == 0) {
             if (vecSum.Mag2() == 0) {
                return BetaVector();
             } else {
                
                
                return BetaVector(vecSum/eSum);
             }
             
             
          }
          return BetaVector (vecSum * (-1./eSum));
       }
      
       
       
       Scalar Beta() const { 
          if ( E() == 0 ) { 
             if ( P2() == 0)
                
                return 0; 
             else { 
                GenVector_exception e ("LorentzVector::Beta() - beta computed for LorentzVector with t = 0. Return an Infinite result");
                Throw(e); 
                return 1./E();
             }	  
          }
          if ( M2() <= 0 ) {     
             GenVector_exception e ("LorentzVector::Beta() - beta computed for non-timelike LorentzVector . Result is physically meaningless" );
             Throw(e); 
          }	  
          return P() / E();
       }  
       
       Scalar Gamma() const { 
          Scalar v2 = P2();
          Scalar t2 = E()*E();
          if (E() == 0) {
             if ( P2() == 0) {
                return 1;
             } else {
                GenVector_exception e ("LorentzVector::Gamma() - gamma computed for LorentzVector with t = 0. Return a zero result");
                Throw(e); 
                return 0;
             }
          }
          if ( t2 < v2 ) { 
             GenVector_exception e ("LorentzVector::Gamma() - gamma computed for a spacelike LorentzVector. Imaginary result");
             Throw(e); 
             return 0;
          }
          else if ( t2 == v2 ) {
             GenVector_exception e ("LorentzVector::Gamma() - gamma computed for a lightlike LorentzVector. Infinite result");
             Throw(e); 
          }
          return 1./std::sqrt(1. - v2/t2 );
       } 
       
       Scalar x()     const { return fCoordinates.Px();     }
       Scalar y()     const { return fCoordinates.Py();     }
       Scalar z()     const { return fCoordinates.Pz();     }
       Scalar t()     const { return fCoordinates.E();      }
       Scalar px()    const { return fCoordinates.Px();     }
       Scalar py()    const { return fCoordinates.Py();     }
       Scalar pz()    const { return fCoordinates.Pz();     }
       Scalar e()     const { return fCoordinates.E();      }
       Scalar r()     const { return fCoordinates.R();      }
       Scalar theta() const { return fCoordinates.Theta();  }
       Scalar phi()   const { return fCoordinates.Phi();    }
       Scalar rho()   const { return fCoordinates.Rho();    }
       Scalar eta()   const { return fCoordinates.Eta();    }
       Scalar pt()    const { return fCoordinates.Pt();     }
       Scalar perp2() const { return fCoordinates.Perp2();  }
       Scalar mag2()  const { return fCoordinates.M2();     }
       Scalar mag()   const { return fCoordinates.M();      }
       Scalar mt()    const { return fCoordinates.Mt();     }
       Scalar mt2()   const { return fCoordinates.Mt2();    }
 
       
       Scalar energy() const { return fCoordinates.E();      }
       Scalar mass()   const { return fCoordinates.M();      }
       Scalar mass2()  const { return fCoordinates.M2();     }   
       
       void  SetE  ( Scalar a )  { fCoordinates.SetE  (a); }
       void  SetEta( Scalar a )  { fCoordinates.SetEta(a); }
       void  SetM  ( Scalar a )  { fCoordinates.SetM  (a); }
       void  SetPhi( Scalar a )  { fCoordinates.SetPhi(a); }
       void  SetPt ( Scalar a )  { fCoordinates.SetPt (a); }
       void  SetPx ( Scalar a )  { fCoordinates.SetPx (a); }
       void  SetPy ( Scalar a )  { fCoordinates.SetPy (a); }
       void  SetPz ( Scalar a )  { fCoordinates.SetPz (a); }
    private:
       CoordSystem  fCoordinates;
    };  
  
  
    template< class CoordSystem >
    inline LorentzVector<CoordSystem> operator *
    ( const typename  LorentzVector<CoordSystem>::Scalar & a,
      const LorentzVector<CoordSystem>& v) {
       LorentzVector<CoordSystem> tmp(v);
       tmp *= a;
       return tmp;
    }
     
    
    template< class char_t, class traits_t, class Coords >
    inline
    std::basic_ostream<char_t,traits_t> &
    operator << ( std::basic_ostream<char_t,traits_t> & os
                  , LorentzVector<Coords> const & v
       )
    {
       if( !os )  return os;
       
       typename Coords::Scalar a, b, c, d;
       v.GetCoordinates(a, b, c, d);
       
       if( detail::get_manip( os, detail::bitforbit ) )  {
        detail::set_manip( os, detail::bitforbit, '\00' );
        
       }
       else  {
          os << detail::get_manip( os, detail::open  ) << a
             << detail::get_manip( os, detail::sep   ) << b
             << detail::get_manip( os, detail::sep   ) << c
             << detail::get_manip( os, detail::sep   ) << d
             << detail::get_manip( os, detail::close );
       }
       
       return os;
       
    }  
     
     template< class char_t, class traits_t, class Coords >
     inline
     std::basic_istream<char_t,traits_t> &
     operator >> ( std::basic_istream<char_t,traits_t> & is
                   , LorentzVector<Coords> & v
        )
     {
        if( !is )  return is;
        
        typename Coords::Scalar a, b, c, d;
        
        if( detail::get_manip( is, detail::bitforbit ) )  {
           detail::set_manip( is, detail::bitforbit, '\00' );
           
        }
        else  {
           detail::require_delim( is, detail::open  );  is >> a;
           detail::require_delim( is, detail::sep   );  is >> b;
           detail::require_delim( is, detail::sep   );  is >> c;
           detail::require_delim( is, detail::sep   );  is >> d;
           detail::require_delim( is, detail::close );
        }
        
        if( is )
           v.SetCoordinates(a, b, c, d);
        return is;
        
     }  
     
  } 
} 
#endif
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.