#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;
       }
       
       LorentzVector<CoordSystem>& SetCoordinates( const Scalar src[] ) { 
          fCoordinates.SetCoordinates(src);  
          return *this;
       }
       
       LorentzVector<CoordSystem>& SetCoordinates( Scalar a, Scalar b, Scalar c, Scalar d ) {
          fCoordinates.SetCoordinates(a, b, c, d);  
          return *this;
       }
       
       template< class IT >
       LorentzVector<CoordSystem>& 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);
          return *this;
       }
       
       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; 
       }
       
       LorentzVector<CoordSystem>& SetXYZT (Scalar xx, Scalar yy, Scalar zz, Scalar tt) {
          fCoordinates.SetPxPyPzE(xx,yy,zz,tt);
          return *this;
       }
       LorentzVector<CoordSystem>& SetPxPyPzE (Scalar xx, Scalar yy, Scalar zz, Scalar ee) {
          fCoordinates.SetPxPyPzE(xx,yy,zz,ee);
          return *this;
       }
       
       
       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 ee = E();
          Scalar ppz = Pz();
          return .5f* std::log( (ee+ppz)/(ee-ppz) );
       }
       
       Scalar ColinearRapidity() const {
          
          
          Scalar ee = E();
          Scalar pp = P();
          return .5f* std::log( (ee+pp)/(ee-pp) );
       }
       
       bool isTimelike( ) const {
          Scalar ee = E(); Scalar pp = P(); return ee*ee > pp*pp;
       }
       
       bool isLightlike( Scalar tolerance
                         = 100*std::numeric_limits<Scalar>::epsilon() ) const {
          Scalar ee = E(); Scalar pp = P(); Scalar delta = ee-pp;
          if ( ee==0 ) return pp==0;
          return delta*delta < tolerance * ee*ee;
       }
       
       bool isSpacelike( ) const {
          Scalar ee = E(); Scalar pp = P(); return ee*ee < pp*pp;
       }
       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::Throw ("LorentzVector::Beta() - beta computed for LorentzVector with t = 0. Return an Infinite result");
                return 1./E();
             }	  
          }
          if ( M2() <= 0 ) {     
             GenVector::Throw ("LorentzVector::Beta() - beta computed for non-timelike LorentzVector . Result is physically meaningless" );
          }	  
          return P() / E();
       }  
       
       Scalar Gamma() const { 
          Scalar v2 = P2();
          Scalar t2 = E()*E();
          if (E() == 0) {
             if ( P2() == 0) {
                return 1;
             } else {
                GenVector::Throw ("LorentzVector::Gamma() - gamma computed for LorentzVector with t = 0. Return a zero result");
             }
          }
          if ( t2 < v2 ) { 
             GenVector::Throw ("LorentzVector::Gamma() - gamma computed for a spacelike LorentzVector. Imaginary result");
             return 0;
          }
          else if ( t2 == v2 ) {
             GenVector::Throw ("LorentzVector::Gamma() - gamma computed for a lightlike LorentzVector. Infinite result");
          }
          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();     }   
       
       LorentzVector<CoordSystem>& SetE  ( Scalar a )  { fCoordinates.SetE  (a); return *this; }
       LorentzVector<CoordSystem>& SetEta( Scalar a )  { fCoordinates.SetEta(a); return *this; }
       LorentzVector<CoordSystem>& SetM  ( Scalar a )  { fCoordinates.SetM  (a); return *this; }
       LorentzVector<CoordSystem>& SetPhi( Scalar a )  { fCoordinates.SetPhi(a); return *this; }
       LorentzVector<CoordSystem>& SetPt ( Scalar a )  { fCoordinates.SetPt (a); return *this; }
       LorentzVector<CoordSystem>& SetPx ( Scalar a )  { fCoordinates.SetPx (a); return *this; }
       LorentzVector<CoordSystem>& SetPy ( Scalar a )  { fCoordinates.SetPy (a); return *this; }
       LorentzVector<CoordSystem>& SetPz ( Scalar a )  { fCoordinates.SetPz (a); return *this; }
    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
Last change: Wed Aug  6 08:06:18 2008
Last generated: 2008-08-06 08:06
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.