Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-25 10:03:00

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     @see GenVector
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    constexpr PxPyPzE4D() noexcept = default;
0057 
0058    /**
0059       Constructor  from x, y , z , t values
0060    */
0061    constexpr PxPyPzE4D(Scalar px, Scalar py, Scalar pz, Scalar e) noexcept : fX(px), fY(py), fZ(pz), fT(e) {}
0062 
0063    /**
0064       construct from any vector or  coordinate system class
0065       implementing x(), y() and z() and t()
0066    */
0067    template <class CoordSystem>
0068    explicit constexpr PxPyPzE4D(const CoordSystem & v) :
0069       fX( v.x() ), fY( v.y() ), fZ( v.z() ), fT( v.t() )  { }
0070 
0071    /**
0072       Set internal data based on an array of 4 Scalar numbers
0073    */
0074    void SetCoordinates( const Scalar src[] )
0075    { fX=src[0]; fY=src[1]; fZ=src[2]; fT=src[3]; }
0076 
0077    /**
0078       get internal data into an array of 4 Scalar numbers
0079    */
0080    void GetCoordinates( Scalar dest[] ) const
0081    { dest[0] = fX; dest[1] = fY; dest[2] = fZ; dest[3] = fT; }
0082 
0083    /**
0084       Set internal data based on 4 Scalar numbers
0085    */
0086    void SetCoordinates(Scalar  px, Scalar  py, Scalar  pz, Scalar e)
0087    { fX=px; fY=py; fZ=pz; fT=e;}
0088 
0089    /**
0090       get internal data into 4 Scalar numbers
0091    */
0092    void GetCoordinates(Scalar& px, Scalar& py, Scalar& pz, Scalar& e) const
0093    { px=fX; py=fY; pz=fZ; e=fT;}
0094 
0095    // --------- Coordinates and Coordinate-like Scalar properties -------------
0096 
0097    // cartesian (Minkowski)coordinate accessors
0098 
0099    Scalar Px() const { return fX;}
0100    Scalar Py() const { return fY;}
0101    Scalar Pz() const { return fZ;}
0102    Scalar E()  const { return fT;}
0103 
0104    Scalar X() const { return fX;}
0105    Scalar Y() const { return fY;}
0106    Scalar Z() const { return fZ;}
0107    Scalar T() const { return fT;}
0108 
0109    // other coordinate representation
0110 
0111    /**
0112       squared magnitude of spatial components
0113    */
0114    Scalar P2() const { return fX*fX + fY*fY + fZ*fZ; }
0115 
0116    /**
0117       magnitude of spatial components (magnitude of 3-momentum)
0118    */
0119    Scalar P() const { using std::sqrt; return sqrt(P2()); }
0120    Scalar R() const { return P(); }
0121 
0122    /**
0123       vector magnitude squared (or mass squared)
0124    */
0125    Scalar M2() const   { return fT*fT - fX*fX - fY*fY - fZ*fZ;}
0126    Scalar Mag2() const { return M2(); }
0127 
0128    /**
0129       invariant mass
0130    */
0131    Scalar M() const
0132    {
0133       const Scalar mm = M2();
0134       if (mm >= 0) {
0135          using std::sqrt;
0136          return sqrt(mm);
0137       } else {
0138          GenVector_Throw("PxPyPzE4D::M() - Tachyonic:\n"
0139                          "    P^2 > E^2 so the mass would be imaginary");
0140          using std::sqrt;
0141          return -sqrt(-mm);
0142       }
0143    }
0144    Scalar Mag() const    { return M(); }
0145 
0146    /**
0147        transverse spatial component squared
0148    */
0149    Scalar Pt2()   const { return fX*fX + fY*fY;}
0150    Scalar Perp2() const { return Pt2();}
0151 
0152    /**
0153       Transverse spatial component (P_perp or rho)
0154    */
0155    Scalar Pt() const { using std::sqrt; return sqrt(Perp2()); }
0156    Scalar Perp() const { return Pt();}
0157    Scalar Rho()  const { return Pt();}
0158 
0159    /**
0160        transverse mass squared
0161    */
0162    Scalar Mt2() const { return fT*fT - fZ*fZ; }
0163 
0164    /**
0165       transverse mass
0166    */
0167    Scalar Mt() const {
0168       const Scalar mm = Mt2();
0169       if (mm >= 0) {
0170          using std::sqrt;
0171          return sqrt(mm);
0172       } else {
0173          GenVector_Throw("PxPyPzE4D::Mt() - Tachyonic:\n"
0174                          "    Pz^2 > E^2 so the transverse mass would be imaginary");
0175          using std::sqrt;
0176          return -sqrt(-mm);
0177       }
0178    }
0179 
0180    /**
0181        transverse energy squared
0182    */
0183    Scalar Et2() const {  // is (E^2 * pt ^2) / p^2
0184       // but it is faster to form p^2 from pt^2
0185       Scalar pt2 = Pt2();
0186       return pt2 == 0 ? 0 : fT*fT * pt2/( pt2 + fZ*fZ );
0187    }
0188 
0189    /**
0190       transverse energy
0191    */
0192    Scalar Et() const {
0193       const Scalar etet = Et2();
0194       using std::sqrt;
0195       return fT < 0.0 ? -sqrt(etet) : sqrt(etet);
0196    }
0197 
0198    /**
0199       azimuthal angle
0200    */
0201    Scalar Phi() const { using std::atan2; return (fX == 0.0 && fY == 0.0) ? 0 : atan2(fY, fX); }
0202 
0203    /**
0204       polar angle
0205    */
0206    Scalar Theta() const { using std::atan2; return (fX == 0.0 && fY == 0.0 && fZ == 0.0) ? 0 : atan2(Pt(), fZ); }
0207 
0208    /**
0209        pseudorapidity
0210    */
0211    Scalar Eta() const {
0212       return Impl::Eta_FromRhoZ ( Pt(), fZ);
0213    }
0214 
0215    // --------- Set Coordinates of this system  ---------------
0216 
0217 
0218    /**
0219       set X value
0220    */
0221    void SetPx( Scalar  px) {
0222       fX = px;
0223    }
0224    /**
0225       set Y value
0226    */
0227    void SetPy( Scalar  py) {
0228       fY = py;
0229    }
0230    /**
0231       set Z value
0232    */
0233    void SetPz( Scalar  pz) {
0234       fZ = pz;
0235    }
0236    /**
0237       set T value
0238    */
0239    void SetE( Scalar  e) {
0240       fT = e;
0241    }
0242 
0243    /**
0244        set all values using cartesian coordinates
0245    */
0246    void SetPxPyPzE(Scalar px, Scalar py, Scalar pz, Scalar e) {
0247       fX=px;
0248       fY=py;
0249       fZ=pz;
0250       fT=e;
0251    }
0252 
0253 
0254 
0255    // ------ Manipulations -------------
0256 
0257    /**
0258       negate the 4-vector
0259    */
0260    void Negate( ) { fX = -fX; fY = -fY;  fZ = -fZ; fT = -fT;}
0261 
0262    /**
0263       scale coordinate values by a scalar quantity a
0264    */
0265    void Scale( const Scalar & a) {
0266       fX *= a;
0267       fY *= a;
0268       fZ *= a;
0269       fT *= a;
0270    }
0271 
0272    /**
0273       Assignment from a generic coordinate system implementing
0274       x(), y(), z() and t()
0275    */
0276    template <class AnyCoordSystem>
0277    PxPyPzE4D & operator = (const AnyCoordSystem & v) {
0278       fX = v.x();
0279       fY = v.y();
0280       fZ = v.z();
0281       fT = v.t();
0282       return *this;
0283    }
0284 
0285    /**
0286       Exact equality
0287    */
0288    bool operator == (const PxPyPzE4D & rhs) const {
0289       return fX == rhs.fX && fY == rhs.fY && fZ == rhs.fZ && fT == rhs.fT;
0290    }
0291    bool operator != (const PxPyPzE4D & rhs) const {return !(operator==(rhs));}
0292 
0293 
0294    // ============= Compatibility section ==================
0295 
0296    // The following make this coordinate system look enough like a CLHEP
0297    // vector that an assignment member template can work with either
0298    Scalar x() const { return fX; }
0299    Scalar y() const { return fY; }
0300    Scalar z() const { return fZ; }
0301    Scalar t() const { return fT; }
0302 
0303 
0304 
0305 #if defined(__MAKECINT__) || defined(G__DICTIONARY)
0306 
0307    // ====== Set member functions for coordinates in other systems =======
0308 
0309    void SetPt(Scalar pt);
0310 
0311    void SetEta(Scalar eta);
0312 
0313    void SetPhi(Scalar phi);
0314 
0315    void SetM(Scalar m);
0316 
0317 #endif
0318 
0319 private:
0320 
0321    /**
0322       (contiguous) data containing the coordinate values x,y,z,t
0323    */
0324 
0325    ScalarType fX = 0;
0326    ScalarType fY = 0;
0327    ScalarType fZ = 0;
0328    ScalarType fT = 0;
0329 };
0330 
0331 } // end namespace Math
0332 } // end namespace ROOT
0333 
0334 
0335 
0336 #if defined(__MAKECINT__) || defined(G__DICTIONARY)
0337 // move implementations here to avoid circle dependencies
0338 
0339 #include "Math/GenVector/PtEtaPhiE4D.h"
0340 #include "Math/GenVector/PtEtaPhiM4D.h"
0341 
0342 namespace ROOT {
0343 
0344 namespace Math {
0345 
0346 
0347     // ====== Set member functions for coordinates in other systems =======
0348     // throw always exceptions  in this case
0349 
0350 template <class ScalarType>
0351 void PxPyPzE4D<ScalarType>::SetPt(Scalar pt) {
0352    GenVector_exception e("PxPyPzE4D::SetPt() is not supposed to be called");
0353    throw e;
0354    PtEtaPhiE4D<Scalar> v(*this); v.SetPt(pt); *this = PxPyPzE4D<Scalar>(v);
0355 }
0356 template <class ScalarType>
0357 void PxPyPzE4D<ScalarType>::SetEta(Scalar eta) {
0358    GenVector_exception e("PxPyPzE4D::SetEta() is not supposed to be called");
0359    throw e;
0360    PtEtaPhiE4D<Scalar> v(*this); v.SetEta(eta); *this = PxPyPzE4D<Scalar>(v);
0361 }
0362 template <class ScalarType>
0363 void PxPyPzE4D<ScalarType>::SetPhi(Scalar phi) {
0364    GenVector_exception e("PxPyPzE4D::SetPhi() is not supposed to be called");
0365    throw e;
0366    PtEtaPhiE4D<Scalar> v(*this); v.SetPhi(phi); *this = PxPyPzE4D<Scalar>(v);
0367 }
0368 
0369 template <class ScalarType>
0370 void PxPyPzE4D<ScalarType>::SetM(Scalar m) {
0371    GenVector_exception e("PxPyPzE4D::SetM() is not supposed to be called");
0372    throw e;
0373    PtEtaPhiM4D<Scalar> v(*this); v.SetM(m);
0374    *this = PxPyPzE4D<Scalar>(v);
0375 }
0376 
0377 
0378 } // end namespace Math
0379 
0380 } // end namespace ROOT
0381 
0382 #endif  // endif __MAKE__CINT || G__DICTIONARY
0383 
0384 
0385 #endif // ROOT_Math_GenVector_PxPyPzE4D