#ifndef ROOT_Math_GenVector_CylindricalEta3D
#define ROOT_Math_GenVector_CylindricalEta3D 1
#ifndef ROOT_Math_Math
#include "Math/Math.h"
#endif
#ifndef ROOT_Math_GenVector_etaMax
#include "Math/GenVector/etaMax.h"
#endif
#include <limits>
#include "Math/Math.h"
namespace ROOT {
namespace Math {
template <class T>
class CylindricalEta3D {
public :
typedef T Scalar;
CylindricalEta3D() : fRho(0), fEta(0), fPhi(0) { }
CylindricalEta3D(Scalar rho, Scalar eta, Scalar phi) :
fRho(rho), fEta(eta), fPhi(phi) { Restrict(); }
template <class CoordSystem >
explicit CylindricalEta3D( const CoordSystem & v ) :
fRho(v.Rho() ), fEta(v.Eta() ), fPhi(v.Phi() )
{
static Scalar bigEta =
-.3f *std::log(std::numeric_limits<Scalar>::epsilon());
if ( std::fabs(fEta) > bigEta ) {
fRho *= v.Z()/Z();
}
}
CylindricalEta3D(const CylindricalEta3D & v) :
fRho(v.Rho() ), fEta(v.Eta() ), fPhi(v.Phi() ) { }
CylindricalEta3D & operator= (const CylindricalEta3D & v) {
fRho = v.Rho();
fEta = v.Eta();
fPhi = v.Phi();
return *this;
}
void SetCoordinates( const Scalar src[] )
{ fRho=src[0]; fEta=src[1]; fPhi=src[2]; Restrict(); }
void GetCoordinates( Scalar dest[] ) const
{ dest[0] = fRho; dest[1] = fEta; dest[2] = fPhi; }
void SetCoordinates(Scalar rho, Scalar eta, Scalar phi)
{ fRho=rho; fEta=eta; fPhi=phi; Restrict(); }
void GetCoordinates(Scalar& rho, Scalar& eta, Scalar& phi) const
{rho=fRho; eta=fEta; phi=fPhi;}
private:
inline static Scalar pi() { return M_PI; }
inline void Restrict() {
if ( fPhi <= -pi() || fPhi > pi() )
fPhi = fPhi - std::floor( fPhi/(2*pi()) +.5 ) * 2*pi();
return;
}
public:
T Rho() const { return fRho; }
T Eta() const { return fEta; }
T Phi() const { return fPhi; }
T X() const { return fRho*std::cos(fPhi); }
T Y() const { return fRho*std::sin(fPhi); }
T Z() const { return fRho > 0 ? fRho*std::sinh(fEta) :
fEta == 0 ? 0 :
fEta > 0 ? fEta - etaMax<T>() :
fEta + etaMax<T>() ; }
T R() const { return fRho > 0 ? fRho*std::cosh(fEta) :
fEta > etaMax<T>() ? fEta - etaMax<T>() :
fEta < -etaMax<T>() ? -fEta - etaMax<T>() :
0 ; }
T Mag2() const { return R()*R(); }
T Perp2() const { return fRho*fRho; }
T Theta() const { return fRho > 0 ? 2* std::atan( std::exp( - fEta ) ) :
(fEta >= 0 ? 0 : pi() ); }
void SetRho(T rho) {
fRho = rho;
}
void SetEta(T eta) {
fEta = eta;
}
void SetPhi(T phi) {
fPhi = phi;
Restrict();
}
void SetXYZ(Scalar x, Scalar y, Scalar z);
void Scale (T a) {
if (a < 0) {
Negate();
a = -a;
}
if (fRho > 0) {
fRho *= a;
} else if ( fEta > etaMax<T>() ) {
fEta = ( fEta-etaMax<T>())*a + etaMax<T>();
} else if ( fEta < -etaMax<T>() ) {
fEta = ( fEta+etaMax<T>())*a - etaMax<T>();
}
}
void Negate ( ) {
fPhi = ( fPhi > 0 ? fPhi - pi() : fPhi + pi() );
fEta = -fEta;
}
template <class CoordSystem >
CylindricalEta3D & operator= ( const CoordSystem & c ) {
fRho = c.Rho();
fEta = c.Eta();
fPhi = c.Phi();
return *this;
}
bool operator==(const CylindricalEta3D & rhs) const {
return fRho == rhs.fRho && fEta == rhs.fEta && fPhi == rhs.fPhi;
}
bool operator!= (const CylindricalEta3D & rhs) const
{return !(operator==(rhs));}
T x() const { return X();}
T y() const { return Y();}
T z() const { return Z(); }
#if defined(__MAKECINT__) || defined(G__DICTIONARY)
void SetX(Scalar x);
void SetY(Scalar y);
void SetZ(Scalar z);
void SetR(Scalar r);
void SetTheta(Scalar theta);
#endif
private:
T fRho;
T fEta;
T fPhi;
};
}
}
#ifndef ROOT_Math_GenVector_Cartesian3D
#include "Math/GenVector/Cartesian3D.h"
#endif
#if defined(__MAKECINT__) || defined(G__DICTIONARY)
#ifndef ROOT_Math_GenVector_GenVector_exception
#include "Math/GenVector/GenVector_exception.h"
#endif
#ifndef ROOT_Math_GenVector_Polar3D
#include "Math/GenVector/Polar3D.h"
#endif
#endif
namespace ROOT {
namespace Math {
template <class T>
void CylindricalEta3D<T>::SetXYZ(Scalar xx, Scalar yy, Scalar zz) {
*this = Cartesian3D<Scalar>(xx, yy, zz);
}
#if defined(__MAKECINT__) || defined(G__DICTIONARY)
template <class T>
void CylindricalEta3D<T>::SetX(Scalar xx) {
GenVector_exception e("CylindricalEta3D::SetX() is not supposed to be called");
throw e;
Cartesian3D<Scalar> v(*this); v.SetX(xx);
*this = CylindricalEta3D<Scalar>(v);
}
template <class T>
void CylindricalEta3D<T>::SetY(Scalar yy) {
GenVector_exception e("CylindricalEta3D::SetY() is not supposed to be called");
throw e;
Cartesian3D<Scalar> v(*this); v.SetY(yy);
*this = CylindricalEta3D<Scalar>(v);
}
template <class T>
void CylindricalEta3D<T>::SetZ(Scalar zz) {
GenVector_exception e("CylindricalEta3D::SetZ() is not supposed to be called");
throw e;
Cartesian3D<Scalar> v(*this); v.SetZ(zz);
*this = CylindricalEta3D<Scalar>(v);
}
template <class T>
void CylindricalEta3D<T>::SetR(Scalar r) {
GenVector_exception e("CylindricalEta3D::SetR() is not supposed to be called");
throw e;
Polar3D<Scalar> v(*this); v.SetR(r);
*this = CylindricalEta3D<Scalar>(v);
}
template <class T>
void CylindricalEta3D<T>::SetTheta(Scalar theta) {
GenVector_exception e("CylindricalEta3D::SetTheta() is not supposed to be called");
throw e;
Polar3D<Scalar> v(*this); v.SetTheta(theta);
*this = CylindricalEta3D<Scalar>(v);
}
#endif
}
}
#endif /* ROOT_Math_GenVector_CylindricalEta3D */