Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:10:11

0001 // @(#)root/mathcore:$Id$
0002 // Authors: W. Brown, M. Fischler, L. Moneta    2005
0003 
0004  /**********************************************************************
0005   *                                                                    *
0006   * Copyright (c) 2005 , LCG ROOT MathLib Team  and                    *
0007   *                      FNAL LCG ROOT MathLib Team                    *
0008   *                                                                    *
0009   *                                                                    *
0010   **********************************************************************/
0011 
0012 // Header file for class Polar3D
0013 //
0014 // Created by: Lorenzo Moneta  at Mon May 30 11:40:03 2005
0015 // Major revamp:  M. Fischler  at Wed Jun  8 2005
0016 //
0017 // Last update: $Id$
0018 //
0019 #ifndef ROOT_Math_GenVector_Polar3D
0020 #define ROOT_Math_GenVector_Polar3D  1
0021 
0022 #include "Math/Math.h"
0023 
0024 #include "Math/GenVector/eta.h"
0025 
0026 #include <cmath>
0027 
0028 namespace ROOT {
0029 
0030 namespace Math {
0031 
0032 
0033 //__________________________________________________________________________________________
0034    /**
0035        Class describing a polar coordinate system based on r, theta and phi
0036        Phi is restricted to be in the range [-PI,PI)
0037 
0038        @ingroup GenVector
0039 
0040        @sa Overview of the @ref GenVector "physics vector library"
0041    */
0042 
0043 
0044 template <class T>
0045 class Polar3D {
0046 
0047 public :
0048 
0049    typedef T Scalar;
0050    static constexpr unsigned int Dimension = 3U;
0051 
0052    /**
0053       Default constructor with r=theta=phi=0
0054    */
0055    Polar3D() : fR(0), fTheta(0), fPhi(0) {  }
0056 
0057    /**
0058       Construct from the polar coordinates:  r, theta and phi
0059    */
0060    Polar3D(T r,T theta,T phi) : fR(r), fTheta(theta), fPhi(phi) { Restrict(); }
0061 
0062    /**
0063       Construct from any Vector or coordinate system implementing
0064       R(), Theta() and Phi()
0065    */
0066    template <class CoordSystem >
0067    explicit constexpr Polar3D( const CoordSystem & v ) :
0068       fR(v.R() ),  fTheta(v.Theta() ),  fPhi(v.Phi() )  { Restrict(); }
0069 
0070    // for g++  3.2 and 3.4 on 32 bits found that the compiler generated copy ctor and assignment are much slower
0071    // re-implement them ( there is no no need to have them with g++4)
0072 
0073    /**
0074       copy constructor
0075     */
0076    Polar3D(const Polar3D & v) :
0077       fR(v.R() ),  fTheta(v.Theta() ),  fPhi(v.Phi() )  {   }
0078 
0079    /**
0080       assignment operator
0081     */
0082    Polar3D & operator= (const Polar3D & v) {
0083       fR     = v.R();
0084       fTheta = v.Theta();
0085       fPhi   = v.Phi();
0086       return *this;
0087    }
0088 
0089    /**
0090       Set internal data based on an array of 3 Scalar numbers
0091    */
0092    void SetCoordinates( const Scalar src[] )
0093    { fR=src[0]; fTheta=src[1]; fPhi=src[2]; Restrict(); }
0094 
0095    /**
0096       get internal data into an array of 3 Scalar numbers
0097    */
0098    void GetCoordinates( Scalar dest[] ) const
0099    { dest[0] = fR; dest[1] = fTheta; dest[2] = fPhi; }
0100 
0101    /**
0102       Set internal data based on 3 Scalar numbers
0103    */
0104    void SetCoordinates(Scalar r, Scalar  theta, Scalar  phi)
0105    { fR=r; fTheta=theta; fPhi=phi; Restrict(); }
0106 
0107    /**
0108       get internal data into 3 Scalar numbers
0109    */
0110    void GetCoordinates(Scalar& r, Scalar& theta, Scalar& phi) const {r=fR; theta=fTheta; phi=fPhi;}
0111 
0112 
0113    Scalar R()     const { return fR;}
0114    Scalar Phi()   const { return fPhi; }
0115    Scalar Theta() const { return fTheta; }
0116    Scalar Rho() const { using std::sin; return fR * sin(fTheta); }
0117    Scalar X() const { using std::cos; return Rho() * cos(fPhi); }
0118    Scalar Y() const { using std::sin; return Rho() * sin(fPhi); }
0119    Scalar Z() const { using std::cos; return fR * cos(fTheta); }
0120    Scalar Mag2()  const { return fR*fR;}
0121    Scalar Perp2() const { return Rho() * Rho(); }
0122 
0123    // pseudorapidity
0124    Scalar Eta() const
0125    {
0126       return Impl::Eta_FromTheta(fTheta, fR);
0127    }
0128 
0129    // setters (only for data members)
0130 
0131 
0132    /**
0133        set the r coordinate value keeping theta and phi constant
0134    */
0135    void SetR(const T & r) {
0136       fR = r;
0137    }
0138 
0139    /**
0140        set the theta coordinate value keeping r and phi constant
0141    */
0142    void SetTheta(const T & theta) {
0143       fTheta = theta;
0144    }
0145 
0146    /**
0147        set the phi coordinate value keeping r and theta constant
0148    */
0149    void SetPhi(const T & phi) {
0150       fPhi = phi;
0151       Restrict();
0152    }
0153 
0154    /**
0155        set all values using cartesian coordinates
0156    */
0157    void SetXYZ(Scalar x, Scalar y, Scalar z);
0158 
0159 
0160 private:
0161    inline static Scalar pi()  { return M_PI; }
0162    inline void Restrict() {
0163       using std::floor;
0164       if (fPhi <= -pi() || fPhi > pi()) fPhi = fPhi - floor(fPhi / (2 * pi()) + .5) * 2 * pi();
0165    }
0166 
0167 public:
0168 
0169    /**
0170        scale by a scalar quantity - for polar coordinates r changes
0171    */
0172    void Scale (T a) {
0173       if (a < 0) {
0174          Negate();
0175          a = -a;
0176       }
0177       // angles do not change when scaling by a positive quantity
0178       fR *= a;
0179    }
0180 
0181    /**
0182       negate the vector
0183    */
0184    void Negate ( ) {
0185       fPhi = ( fPhi > 0 ? fPhi - pi() : fPhi + pi() );
0186       fTheta = pi() - fTheta;
0187    }
0188 
0189    // assignment operators
0190    /**
0191       generic assignment operator from any coordinate system
0192    */
0193    template <class CoordSystem >
0194    Polar3D & operator= ( const CoordSystem & c ) {
0195       fR     = c.R();
0196       fTheta = c.Theta();
0197       fPhi   = c.Phi();
0198       return *this;
0199    }
0200 
0201    /**
0202       Exact equality
0203    */
0204    bool operator==(const Polar3D & rhs) const {
0205       return fR == rhs.fR && fTheta == rhs.fTheta && fPhi == rhs.fPhi;
0206    }
0207    bool operator!= (const Polar3D & rhs) const {return !(operator==(rhs));}
0208 
0209 
0210    // ============= Compatibility section ==================
0211 
0212    // The following make this coordinate system look enough like a CLHEP
0213    // vector that an assignment member template can work with either
0214    T x() const { return X(); }
0215    T y() const { return Y(); }
0216    T z() const { return Z(); }
0217 
0218    // ============= Specializations for improved speed ==================
0219 
0220    // (none)
0221 
0222 #if defined(__MAKECINT__) || defined(G__DICTIONARY)
0223 
0224    // ====== Set member functions for coordinates in other systems =======
0225 
0226    void SetX(Scalar x);
0227 
0228    void SetY(Scalar y);
0229 
0230    void SetZ(Scalar z);
0231 
0232    void SetRho(Scalar rho);
0233 
0234    void SetEta(Scalar eta);
0235 
0236 #endif
0237 
0238 private:
0239    T fR;
0240    T fTheta;
0241    T fPhi;
0242 };
0243 
0244 
0245 
0246   } // end namespace Math
0247 
0248 } // end namespace ROOT
0249 
0250 // move implementations here to avoid circle dependencies
0251 
0252 #include "Math/GenVector/Cartesian3D.h"
0253 
0254 #if defined(__MAKECINT__) || defined(G__DICTIONARY)
0255 #include "Math/GenVector/GenVector_exception.h"
0256 #include "Math/GenVector/CylindricalEta3D.h"
0257 #endif
0258 
0259 
0260 namespace ROOT {
0261 
0262   namespace Math {
0263 
0264 template <class T>
0265 void Polar3D<T>::SetXYZ(Scalar xx, Scalar yy, Scalar zz) {
0266    *this = Cartesian3D<Scalar>(xx, yy, zz);
0267 }
0268 
0269 #if defined(__MAKECINT__) || defined(G__DICTIONARY)
0270 
0271   // ====== Set member functions for coordinates in other systems =======
0272 
0273 
0274 template <class T>
0275 void Polar3D<T>::SetX(Scalar xx) {
0276    GenVector_exception e("Polar3D::SetX() is not supposed to be called");
0277    throw e;
0278    Cartesian3D<Scalar> v(*this); v.SetX(xx); *this = Polar3D<Scalar>(v);
0279 }
0280 template <class T>
0281 void Polar3D<T>::SetY(Scalar yy) {
0282    GenVector_exception e("Polar3D::SetY() is not supposed to be called");
0283    throw e;
0284    Cartesian3D<Scalar> v(*this); v.SetY(yy); *this = Polar3D<Scalar>(v);
0285 }
0286 template <class T>
0287 void Polar3D<T>::SetZ(Scalar zz) {
0288    GenVector_exception e("Polar3D::SetZ() is not supposed to be called");
0289    throw e;
0290    Cartesian3D<Scalar> v(*this); v.SetZ(zz); *this = Polar3D<Scalar>(v);
0291 }
0292 template <class T>
0293 void Polar3D<T>::SetRho(Scalar rho) {
0294    GenVector_exception e("Polar3D::SetRho() is not supposed to be called");
0295    throw e;
0296    CylindricalEta3D<Scalar> v(*this); v.SetRho(rho);
0297    *this = Polar3D<Scalar>(v);
0298 }
0299 template <class T>
0300 void Polar3D<T>::SetEta(Scalar eta) {
0301    GenVector_exception e("Polar3D::SetEta() is not supposed to be called");
0302    throw e;
0303    CylindricalEta3D<Scalar> v(*this); v.SetEta(eta);
0304    *this = Polar3D<Scalar>(v);
0305 }
0306 
0307 #endif
0308 
0309 
0310   } // end namespace Math
0311 
0312 } // end namespace ROOT
0313 
0314 
0315 
0316 #endif /* ROOT_Math_GenVector_Polar3D  */