Back to home page

EIC code displayed by LXR

 
 

    


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

0001 // @(#)root/mathcore:$Id: 04c6d98020d7178ed5f0884f9466bca32b031565 $
0002 // Authors: W. Brown, M. Fischler, L. Moneta    2005
0003 
0004 /**********************************************************************
0005 *                                                                    *
0006 * Copyright (c) 2005 , LCG ROOT MathLib Team                         *
0007 *                                                                    *
0008 *                                                                    *
0009 **********************************************************************/
0010 
0011 // Header file for class PxPyPzE4D
0012 //
0013 // Created by: fischler at Wed Jul 20   2005
0014 //   (starting from PxPyPzE4D by moneta)
0015 //
0016 // Last update: $Id: 04c6d98020d7178ed5f0884f9466bca32b031565 $
0017 //
0018 #ifndef ROOT_Math_GenVector_PxPyPzE4D
0019 #define ROOT_Math_GenVector_PxPyPzE4D  1
0020 
0021 #include "Math/GenVector/eta.h"
0022 
0023 #include "Math/GenVector/GenVector_exception.h"
0024 
0025 
0026 #include <cmath>
0027 
0028 namespace ROOT {
0029 
0030 namespace Math {
0031 
0032 //__________________________________________________________________________________________
0033 /**
0034     Class describing a 4D cartesian coordinate system (x, y, z, t coordinates)
0035     or momentum-energy vectors stored as (Px, Py, Pz, E).
0036     The metric used is (-,-,-,+)
0037 
0038     @ingroup GenVector
0039 
0040     @sa Overview of the @ref GenVector "physics vector library"
0041 */
0042 
0043 template <class ScalarType = double>
0044 class PxPyPzE4D {
0045 
0046 public :
0047 
0048    typedef ScalarType Scalar;
0049    static constexpr unsigned int Dimension = 4U;
0050 
0051    // --------- Constructors ---------------
0052 
0053    /**
0054       Default constructor  with x=y=z=t=0
0055    */
0056    PxPyPzE4D() : fX(0.0), fY(0.0), fZ(0.0), fT(0.0) { }
0057 
0058 
0059    /**
0060       Constructor  from x, y , z , t values
0061    */
0062    PxPyPzE4D(Scalar px, Scalar py, Scalar pz, Scalar e) :
0063       fX(px), fY(py), fZ(pz), fT(e) { }
0064 
0065 
0066    /**
0067       construct from any vector or  coordinate system class
0068       implementing x(), y() and z() and t()
0069    */
0070    template <class CoordSystem>
0071    explicit constexpr PxPyPzE4D(const CoordSystem & v) :
0072       fX( v.x() ), fY( v.y() ), fZ( v.z() ), fT( v.t() )  { }
0073 
0074    // for g++  3.2 and 3.4 on 32 bits found that the compiler generated copy ctor and assignment are much slower
0075    // so we decided to re-implement them ( there is no no need to have them with g++4)
0076    /**
0077       copy constructor
0078     */
0079    PxPyPzE4D(const PxPyPzE4D & v) :
0080       fX(v.fX), fY(v.fY), fZ(v.fZ), fT(v.fT) { }
0081 
0082    /**
0083       assignment operator
0084     */
0085    PxPyPzE4D & operator = (const PxPyPzE4D & v) {
0086       fX = v.fX;
0087       fY = v.fY;
0088       fZ = v.fZ;
0089       fT = v.fT;
0090       return *this;
0091    }
0092 
0093    /**
0094       Set internal data based on an array of 4 Scalar numbers
0095    */
0096    void SetCoordinates( const Scalar src[] )
0097    { fX=src[0]; fY=src[1]; fZ=src[2]; fT=src[3]; }
0098 
0099    /**
0100       get internal data into an array of 4 Scalar numbers
0101    */
0102    void GetCoordinates( Scalar dest[] ) const
0103    { dest[0] = fX; dest[1] = fY; dest[2] = fZ; dest[3] = fT; }
0104 
0105    /**
0106       Set internal data based on 4 Scalar numbers
0107    */
0108    void SetCoordinates(Scalar  px, Scalar  py, Scalar  pz, Scalar e)
0109    { fX=px; fY=py; fZ=pz; fT=e;}
0110 
0111    /**
0112       get internal data into 4 Scalar numbers
0113    */
0114    void GetCoordinates(Scalar& px, Scalar& py, Scalar& pz, Scalar& e) const
0115    { px=fX; py=fY; pz=fZ; e=fT;}
0116 
0117    // --------- Coordinates and Coordinate-like Scalar properties -------------
0118 
0119    // cartesian (Minkowski)coordinate accessors
0120 
0121    Scalar Px() const { return fX;}
0122    Scalar Py() const { return fY;}
0123    Scalar Pz() const { return fZ;}
0124    Scalar E()  const { return fT;}
0125 
0126    Scalar X() const { return fX;}
0127    Scalar Y() const { return fY;}
0128    Scalar Z() const { return fZ;}
0129    Scalar T() const { return fT;}
0130 
0131    // other coordinate representation
0132 
0133    /**
0134       squared magnitude of spatial components
0135    */
0136    Scalar P2() const { return fX*fX + fY*fY + fZ*fZ; }
0137 
0138    /**
0139       magnitude of spatial components (magnitude of 3-momentum)
0140    */
0141    Scalar P() const { using std::sqrt; return sqrt(P2()); }
0142    Scalar R() const { return P(); }
0143 
0144    /**
0145       vector magnitude squared (or mass squared)
0146    */
0147    Scalar M2() const   { return fT*fT - fX*fX - fY*fY - fZ*fZ;}
0148    Scalar Mag2() const { return M2(); }
0149 
0150    /**
0151       invariant mass
0152    */
0153    Scalar M() const
0154    {
0155       const Scalar mm = M2();
0156       if (mm >= 0) {
0157          using std::sqrt;
0158          return sqrt(mm);
0159       } else {
0160          GenVector::Throw ("PxPyPzE4D::M() - Tachyonic:\n"
0161                    "    P^2 > E^2 so the mass would be imaginary");
0162          using std::sqrt;
0163          return -sqrt(-mm);
0164       }
0165    }
0166    Scalar Mag() const    { return M(); }
0167 
0168    /**
0169        transverse spatial component squared
0170    */
0171    Scalar Pt2()   const { return fX*fX + fY*fY;}
0172    Scalar Perp2() const { return Pt2();}
0173 
0174    /**
0175       Transverse spatial component (P_perp or rho)
0176    */
0177    Scalar Pt() const { using std::sqrt; return sqrt(Perp2()); }
0178    Scalar Perp() const { return Pt();}
0179    Scalar Rho()  const { return Pt();}
0180 
0181    /**
0182        transverse mass squared
0183    */
0184    Scalar Mt2() const { return fT*fT - fZ*fZ; }
0185 
0186    /**
0187       transverse mass
0188    */
0189    Scalar Mt() const {
0190       const Scalar mm = Mt2();
0191       if (mm >= 0) {
0192          using std::sqrt;
0193          return sqrt(mm);
0194       } else {
0195          GenVector::Throw ("PxPyPzE4D::Mt() - Tachyonic:\n"
0196                            "    Pz^2 > E^2 so the transverse mass would be imaginary");
0197          using std::sqrt;
0198          return -sqrt(-mm);
0199       }
0200    }
0201 
0202    /**
0203        transverse energy squared
0204    */
0205    Scalar Et2() const {  // is (E^2 * pt ^2) / p^2
0206       // but it is faster to form p^2 from pt^2
0207       Scalar pt2 = Pt2();
0208       return pt2 == 0 ? 0 : fT*fT * pt2/( pt2 + fZ*fZ );
0209    }
0210 
0211    /**
0212       transverse energy
0213    */
0214    Scalar Et() const {
0215       const Scalar etet = Et2();
0216       using std::sqrt;
0217       return fT < 0.0 ? -sqrt(etet) : sqrt(etet);
0218    }
0219 
0220    /**
0221       azimuthal angle
0222    */
0223    Scalar Phi() const { using std::atan2; return (fX == 0.0 && fY == 0.0) ? 0 : atan2(fY, fX); }
0224 
0225    /**
0226       polar angle
0227    */
0228    Scalar Theta() const { using std::atan2; return (fX == 0.0 && fY == 0.0 && fZ == 0.0) ? 0 : atan2(Pt(), fZ); }
0229 
0230    /**
0231        pseudorapidity
0232    */
0233    Scalar Eta() const {
0234       return Impl::Eta_FromRhoZ ( Pt(), fZ);
0235    }
0236 
0237    // --------- Set Coordinates of this system  ---------------
0238 
0239 
0240    /**
0241       set X value
0242    */
0243    void SetPx( Scalar  px) {
0244       fX = px;
0245    }
0246    /**
0247       set Y value
0248    */
0249    void SetPy( Scalar  py) {
0250       fY = py;
0251    }
0252    /**
0253       set Z value
0254    */
0255    void SetPz( Scalar  pz) {
0256       fZ = pz;
0257    }
0258    /**
0259       set T value
0260    */
0261    void SetE( Scalar  e) {
0262       fT = e;
0263    }
0264 
0265    /**
0266        set all values using cartesian coordinates
0267    */
0268    void SetPxPyPzE(Scalar px, Scalar py, Scalar pz, Scalar e) {
0269       fX=px;
0270       fY=py;
0271       fZ=pz;
0272       fT=e;
0273    }
0274 
0275 
0276 
0277    // ------ Manipulations -------------
0278 
0279    /**
0280       negate the 4-vector
0281    */
0282    void Negate( ) { fX = -fX; fY = -fY;  fZ = -fZ; fT = -fT;}
0283 
0284    /**
0285       scale coordinate values by a scalar quantity a
0286    */
0287    void Scale( const Scalar & a) {
0288       fX *= a;
0289       fY *= a;
0290       fZ *= a;
0291       fT *= a;
0292    }
0293 
0294    /**
0295       Assignment from a generic coordinate system implementing
0296       x(), y(), z() and t()
0297    */
0298    template <class AnyCoordSystem>
0299    PxPyPzE4D & operator = (const AnyCoordSystem & v) {
0300       fX = v.x();
0301       fY = v.y();
0302       fZ = v.z();
0303       fT = v.t();
0304       return *this;
0305    }
0306 
0307    /**
0308       Exact equality
0309    */
0310    bool operator == (const PxPyPzE4D & rhs) const {
0311       return fX == rhs.fX && fY == rhs.fY && fZ == rhs.fZ && fT == rhs.fT;
0312    }
0313    bool operator != (const PxPyPzE4D & rhs) const {return !(operator==(rhs));}
0314 
0315 
0316    // ============= Compatibility section ==================
0317 
0318    // The following make this coordinate system look enough like a CLHEP
0319    // vector that an assignment member template can work with either
0320    Scalar x() const { return fX; }
0321    Scalar y() const { return fY; }
0322    Scalar z() const { return fZ; }
0323    Scalar t() const { return fT; }
0324 
0325 
0326 
0327 #if defined(__MAKECINT__) || defined(G__DICTIONARY)
0328 
0329    // ====== Set member functions for coordinates in other systems =======
0330 
0331    void SetPt(Scalar pt);
0332 
0333    void SetEta(Scalar eta);
0334 
0335    void SetPhi(Scalar phi);
0336 
0337    void SetM(Scalar m);
0338 
0339 #endif
0340 
0341 private:
0342 
0343    /**
0344       (contiguous) data containing the coordinate values x,y,z,t
0345    */
0346 
0347    ScalarType fX;
0348    ScalarType fY;
0349    ScalarType fZ;
0350    ScalarType fT;
0351 
0352 };
0353 
0354 } // end namespace Math
0355 } // end namespace ROOT
0356 
0357 
0358 
0359 #if defined(__MAKECINT__) || defined(G__DICTIONARY)
0360 // move implementations here to avoid circle dependencies
0361 
0362 #include "Math/GenVector/PtEtaPhiE4D.h"
0363 #include "Math/GenVector/PtEtaPhiM4D.h"
0364 
0365 namespace ROOT {
0366 
0367 namespace Math {
0368 
0369 
0370     // ====== Set member functions for coordinates in other systems =======
0371     // throw always exceptions  in this case
0372 
0373 template <class ScalarType>
0374 void PxPyPzE4D<ScalarType>::SetPt(Scalar pt) {
0375    GenVector_exception e("PxPyPzE4D::SetPt() is not supposed to be called");
0376    throw e;
0377    PtEtaPhiE4D<Scalar> v(*this); v.SetPt(pt); *this = PxPyPzE4D<Scalar>(v);
0378 }
0379 template <class ScalarType>
0380 void PxPyPzE4D<ScalarType>::SetEta(Scalar eta) {
0381    GenVector_exception e("PxPyPzE4D::SetEta() is not supposed to be called");
0382    throw e;
0383    PtEtaPhiE4D<Scalar> v(*this); v.SetEta(eta); *this = PxPyPzE4D<Scalar>(v);
0384 }
0385 template <class ScalarType>
0386 void PxPyPzE4D<ScalarType>::SetPhi(Scalar phi) {
0387    GenVector_exception e("PxPyPzE4D::SetPhi() is not supposed to be called");
0388    throw e;
0389    PtEtaPhiE4D<Scalar> v(*this); v.SetPhi(phi); *this = PxPyPzE4D<Scalar>(v);
0390 }
0391 
0392 template <class ScalarType>
0393 void PxPyPzE4D<ScalarType>::SetM(Scalar m) {
0394    GenVector_exception e("PxPyPzE4D::SetM() is not supposed to be called");
0395    throw e;
0396    PtEtaPhiM4D<Scalar> v(*this); v.SetM(m);
0397    *this = PxPyPzE4D<Scalar>(v);
0398 }
0399 
0400 
0401 } // end namespace Math
0402 
0403 } // end namespace ROOT
0404 
0405 #endif  // endif __MAKE__CINT || G__DICTIONARY
0406 
0407 
0408 #endif // ROOT_Math_GenVector_PxPyPzE4D