Back to home page

EIC code displayed by LXR

 
 

    


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

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