Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-15 10:28:12

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