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