File indexing completed on 2025-01-18 10:10:11
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #ifndef ROOT_Math_GenVector_PxPyPzM4D
0019 #define ROOT_Math_GenVector_PxPyPzM4D 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
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048 template <class ScalarType = double>
0049 class PxPyPzM4D {
0050
0051 public :
0052
0053 typedef ScalarType Scalar;
0054 static constexpr unsigned int Dimension = 4U;
0055
0056
0057
0058
0059
0060
0061 PxPyPzM4D() : fX(0.0), fY(0.0), fZ(0.0), fM(0.0) { }
0062
0063
0064
0065
0066
0067 PxPyPzM4D(Scalar px, Scalar py, Scalar pz, Scalar m) :
0068 fX(px), fY(py), fZ(pz), fM(m) {
0069
0070 if (fM < 0) RestrictNegMass();
0071 }
0072
0073
0074
0075
0076
0077 template <class CoordSystem>
0078 explicit constexpr PxPyPzM4D(const CoordSystem & v) :
0079 fX( v.X() ), fY( v.Y() ), fZ( v.Z() ), fM( v.M() )
0080 { }
0081
0082
0083
0084
0085
0086
0087 PxPyPzM4D(const PxPyPzM4D & v) :
0088 fX(v.fX), fY(v.fY), fZ(v.fZ), fM(v.fM) { }
0089
0090
0091
0092
0093 PxPyPzM4D & operator = (const PxPyPzM4D & v) {
0094 fX = v.fX;
0095 fY = v.fY;
0096 fZ = v.fZ;
0097 fM = v.fM;
0098 return *this;
0099 }
0100
0101
0102
0103
0104
0105
0106 template <class AnyCoordSystem>
0107 PxPyPzM4D & operator = (const AnyCoordSystem & v) {
0108 fX = v.X();
0109 fY = v.Y();
0110 fZ = v.Z();
0111 fM = v.M();
0112 return *this;
0113 }
0114
0115
0116
0117
0118 void SetCoordinates( const Scalar src[] ) {
0119 fX=src[0]; fY=src[1]; fZ=src[2]; fM=src[3];
0120 if (fM < 0) RestrictNegMass();
0121 }
0122
0123
0124
0125
0126 void GetCoordinates( Scalar dest[] ) const
0127 { dest[0] = fX; dest[1] = fY; dest[2] = fZ; dest[3] = fM; }
0128
0129
0130
0131
0132 void SetCoordinates(Scalar px, Scalar py, Scalar pz, Scalar m) {
0133 fX=px; fY=py; fZ=pz; fM=m;
0134 if (fM < 0) RestrictNegMass();
0135 }
0136
0137
0138
0139
0140 void GetCoordinates(Scalar& px, Scalar& py, Scalar& pz, Scalar& m) const
0141 { px=fX; py=fY; pz=fZ; m=fM;}
0142
0143
0144
0145
0146
0147 Scalar Px() const { return fX;}
0148 Scalar Py() const { return fY;}
0149 Scalar Pz() const { return fZ;}
0150 Scalar M() const { return fM; }
0151
0152 Scalar X() const { return fX;}
0153 Scalar Y() const { return fY;}
0154 Scalar Z() const { return fZ;}
0155
0156
0157
0158
0159
0160 Scalar E() const { using std::sqrt; return sqrt(E2()); }
0161
0162 Scalar T() const { return E();}
0163
0164
0165
0166
0167 Scalar P2() const { return fX*fX + fY*fY + fZ*fZ; }
0168
0169
0170
0171
0172 Scalar P() const { using std::sqrt; return sqrt(P2()); }
0173 Scalar R() const { return P(); }
0174
0175
0176
0177
0178
0179 Scalar M2() const {
0180 return ( fM >= 0 ) ? fM*fM : -fM*fM;
0181 }
0182 Scalar Mag2() const { return M2(); }
0183
0184 Scalar Mag() const { return M(); }
0185
0186
0187
0188
0189 Scalar E2() const {
0190 Scalar e2 = P2() + M2();
0191
0192 return e2 > 0 ? e2 : 0;
0193 }
0194
0195
0196
0197
0198 Scalar Pt2() const { return fX*fX + fY*fY;}
0199 Scalar Perp2() const { return Pt2();}
0200
0201
0202
0203
0204 Scalar Pt() const { using std::sqrt; return sqrt(Perp2()); }
0205 Scalar Perp() const { return Pt();}
0206 Scalar Rho() const { return Pt();}
0207
0208
0209
0210
0211 Scalar Mt2() const { return E2() - fZ*fZ; }
0212
0213
0214
0215
0216 Scalar Mt() const {
0217 const Scalar mm = Mt2();
0218 if (mm >= 0) {
0219 using std::sqrt;
0220 return sqrt(mm);
0221 } else {
0222 GenVector::Throw ("PxPyPzM4D::Mt() - Tachyonic:\n"
0223 " Pz^2 > E^2 so the transverse mass would be imaginary");
0224 using std::sqrt;
0225 return -sqrt(-mm);
0226 }
0227 }
0228
0229
0230
0231
0232 Scalar Et2() const {
0233
0234 Scalar pt2 = Pt2();
0235 return pt2 == 0 ? 0 : E2() * pt2/( pt2 + fZ*fZ );
0236 }
0237
0238
0239
0240
0241 Scalar Et() const {
0242 const Scalar etet = Et2();
0243 using std::sqrt;
0244 return sqrt(etet);
0245 }
0246
0247
0248
0249
0250 Scalar Phi() const { using std::atan2; return (fX == 0.0 && fY == 0.0) ? 0.0 : atan2(fY, fX); }
0251
0252
0253
0254
0255 Scalar Theta() const { using std::atan2; return (fX == 0.0 && fY == 0.0 && fZ == 0.0) ? 0 : atan2(Pt(), fZ); }
0256
0257
0258
0259
0260 Scalar Eta() const {
0261 return Impl::Eta_FromRhoZ ( Pt(), fZ);
0262 }
0263
0264
0265
0266
0267
0268
0269
0270 void SetPx( Scalar px) {
0271 fX = px;
0272 }
0273
0274
0275
0276 void SetPy( Scalar py) {
0277 fY = py;
0278 }
0279
0280
0281
0282 void SetPz( Scalar pz) {
0283 fZ = pz;
0284 }
0285
0286
0287
0288 void SetM( Scalar m) {
0289 fM = m;
0290 if (fM < 0) RestrictNegMass();
0291 }
0292
0293
0294
0295
0296 void SetPxPyPzE(Scalar px, Scalar py, Scalar pz, Scalar e);
0297
0298
0299
0300
0301
0302
0303
0304
0305 void Negate( ) {
0306 fX = -fX;
0307 fY = -fY;
0308 fZ = -fZ;
0309 GenVector::Throw ("PxPyPzM4D::Negate - cannot negate the energy - can negate only the spatial components");
0310 }
0311
0312
0313
0314
0315 void Scale( const Scalar & a) {
0316 fX *= a;
0317 fY *= a;
0318 fZ *= a;
0319 fM *= a;
0320 }
0321
0322
0323
0324
0325
0326 bool operator == (const PxPyPzM4D & rhs) const {
0327 return fX == rhs.fX && fY == rhs.fY && fZ == rhs.fZ && fM == rhs.fM;
0328 }
0329 bool operator != (const PxPyPzM4D & rhs) const {return !(operator==(rhs));}
0330
0331
0332
0333
0334
0335
0336 Scalar x() const { return X(); }
0337 Scalar y() const { return Y(); }
0338 Scalar z() const { return Z(); }
0339 Scalar t() const { return E(); }
0340
0341
0342
0343 #if defined(__MAKECINT__) || defined(G__DICTIONARY)
0344
0345
0346
0347 void SetPt(Scalar pt);
0348
0349 void SetEta(Scalar eta);
0350
0351 void SetPhi(Scalar phi);
0352
0353 void SetE(Scalar t);
0354
0355 #endif
0356
0357 private:
0358
0359
0360
0361 inline void RestrictNegMass() {
0362 if ( fM >=0 ) return;
0363 if ( P2() - fM*fM < 0 ) {
0364 GenVector::Throw("PxPyPzM4D::unphysical value of mass, set to closest physical value");
0365 fM = - P();
0366 }
0367 return;
0368 }
0369
0370
0371
0372
0373
0374
0375 ScalarType fX;
0376 ScalarType fY;
0377 ScalarType fZ;
0378 ScalarType fM;
0379
0380 };
0381
0382 }
0383 }
0384
0385
0386
0387
0388 #include "Math/GenVector/PxPyPzE4D.h"
0389 #include "Math/GenVector/PtEtaPhiM4D.h"
0390
0391 namespace ROOT {
0392
0393 namespace Math {
0394
0395 template <class ScalarType>
0396 inline void PxPyPzM4D<ScalarType>::SetPxPyPzE(Scalar px, Scalar py, Scalar pz, Scalar e) {
0397 *this = PxPyPzE4D<Scalar> (px, py, pz, e);
0398 }
0399
0400
0401 #if defined(__MAKECINT__) || defined(G__DICTIONARY)
0402
0403
0404
0405
0406
0407 template <class ScalarType>
0408 inline void PxPyPzM4D<ScalarType>::SetPt(ScalarType pt) {
0409 GenVector_exception e("PxPyPzM4D::SetPt() is not supposed to be called");
0410 throw e;
0411 PtEtaPhiE4D<ScalarType> v(*this); v.SetPt(pt); *this = PxPyPzM4D<ScalarType>(v);
0412 }
0413 template <class ScalarType>
0414 inline void PxPyPzM4D<ScalarType>::SetEta(ScalarType eta) {
0415 GenVector_exception e("PxPyPzM4D::SetEta() is not supposed to be called");
0416 throw e;
0417 PtEtaPhiE4D<ScalarType> v(*this); v.SetEta(eta); *this = PxPyPzM4D<ScalarType>(v);
0418 }
0419 template <class ScalarType>
0420 inline void PxPyPzM4D<ScalarType>::SetPhi(ScalarType phi) {
0421 GenVector_exception e("PxPyPzM4D::SetPhi() is not supposed to be called");
0422 throw e;
0423 PtEtaPhiE4D<ScalarType> v(*this); v.SetPhi(phi); *this = PxPyPzM4D<ScalarType>(v);
0424 }
0425 template <class ScalarType>
0426 inline void PxPyPzM4D<ScalarType>::SetE(ScalarType energy) {
0427 GenVector_exception e("PxPyPzM4D::SetE() is not supposed to be called");
0428 throw e;
0429 PxPyPzE4D<ScalarType> v(*this); v.SetE(energy);
0430 *this = PxPyPzM4D<ScalarType>(v);
0431 }
0432
0433
0434 #endif
0435
0436 }
0437
0438 }
0439
0440
0441
0442 #endif