File indexing completed on 2025-01-18 10:10:10
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 #ifndef ROOT_Math_GenVector_LorentzVector
0019 #define ROOT_Math_GenVector_LorentzVector 1
0020
0021 #include "Math/GenVector/PxPyPzE4D.h"
0022
0023 #include "Math/GenVector/DisplacementVector3D.h"
0024
0025 #include "Math/GenVector/GenVectorIO.h"
0026
0027 #include <cmath>
0028 #include <string>
0029
0030 namespace ROOT {
0031
0032 namespace Math {
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058 template< class CoordSystem >
0059 class LorentzVector {
0060
0061 public:
0062
0063
0064
0065 typedef typename CoordSystem::Scalar Scalar;
0066 typedef CoordSystem CoordinateType;
0067
0068
0069
0070
0071 LorentzVector ( ) : fCoordinates() { }
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082 LorentzVector(const Scalar & a,
0083 const Scalar & b,
0084 const Scalar & c,
0085 const Scalar & d) :
0086 fCoordinates(a , b, c, d) { }
0087
0088
0089
0090
0091
0092 template< class Coords >
0093 explicit constexpr LorentzVector(const LorentzVector<Coords> & v ) :
0094 fCoordinates( v.Coordinates() ) { }
0095
0096
0097
0098
0099
0100 template<class ForeignLorentzVector,
0101 typename = decltype(std::declval<ForeignLorentzVector>().x()
0102 + std::declval<ForeignLorentzVector>().y()
0103 + std::declval<ForeignLorentzVector>().z()
0104 + std::declval<ForeignLorentzVector>().t())>
0105 explicit constexpr LorentzVector( const ForeignLorentzVector & v) :
0106 fCoordinates(PxPyPzE4D<Scalar>( v.x(), v.y(), v.z(), v.t() ) ) { }
0107
0108 #ifdef LATER
0109
0110
0111
0112
0113
0114
0115
0116
0117 template< class LAVector >
0118 explicit constexpr LorentzVector(const LAVector & v, size_t index0 ) {
0119 fCoordinates = CoordSystem ( v[index0], v[index0+1], v[index0+2], v[index0+3] );
0120 }
0121 #endif
0122
0123
0124
0125
0126
0127
0128
0129 template< class OtherCoords >
0130 LorentzVector & operator= ( const LorentzVector<OtherCoords> & v) {
0131 fCoordinates = v.Coordinates();
0132 return *this;
0133 }
0134
0135
0136
0137
0138
0139 template<class ForeignLorentzVector,
0140 typename = decltype(std::declval<ForeignLorentzVector>().x()
0141 + std::declval<ForeignLorentzVector>().y()
0142 + std::declval<ForeignLorentzVector>().z()
0143 + std::declval<ForeignLorentzVector>().t())>
0144 LorentzVector & operator = ( const ForeignLorentzVector & v) {
0145 SetXYZT( v.x(), v.y(), v.z(), v.t() );
0146 return *this;
0147 }
0148
0149 #ifdef LATER
0150
0151
0152
0153
0154
0155
0156
0157
0158 template< class LAVector >
0159 LorentzVector & AssignFrom(const LAVector & v, size_t index0=0 ) {
0160 fCoordinates.SetCoordinates( v[index0], v[index0+1], v[index0+2], v[index0+3] );
0161 return *this;
0162 }
0163 #endif
0164
0165
0166
0167
0168
0169
0170 const CoordSystem & Coordinates() const {
0171 return fCoordinates;
0172 }
0173
0174
0175
0176
0177 LorentzVector<CoordSystem>& SetCoordinates( const Scalar src[] ) {
0178 fCoordinates.SetCoordinates(src);
0179 return *this;
0180 }
0181
0182
0183
0184
0185 LorentzVector<CoordSystem>& SetCoordinates( Scalar a, Scalar b, Scalar c, Scalar d ) {
0186 fCoordinates.SetCoordinates(a, b, c, d);
0187 return *this;
0188 }
0189
0190
0191
0192
0193 template< class IT >
0194 LorentzVector<CoordSystem>& SetCoordinates( IT begin, IT end ) {
0195 IT a = begin; IT b = ++begin; IT c = ++begin; IT d = ++begin;
0196 (void)end;
0197 assert (++begin==end);
0198 SetCoordinates (*a,*b,*c,*d);
0199 return *this;
0200 }
0201
0202
0203
0204
0205 void GetCoordinates( Scalar& a, Scalar& b, Scalar& c, Scalar & d ) const
0206 { fCoordinates.GetCoordinates(a, b, c, d); }
0207
0208
0209
0210
0211 void GetCoordinates( Scalar dest[] ) const
0212 { fCoordinates.GetCoordinates(dest); }
0213
0214
0215
0216
0217 template <class IT>
0218 void GetCoordinates( IT begin, IT end ) const
0219 { IT a = begin; IT b = ++begin; IT c = ++begin; IT d = ++begin;
0220 (void)end;
0221 assert (++begin==end);
0222 GetCoordinates (*a,*b,*c,*d);
0223 }
0224
0225
0226
0227
0228 template <class IT>
0229 void GetCoordinates( IT begin ) const {
0230 Scalar a,b,c,d = 0;
0231 GetCoordinates (a,b,c,d);
0232 *begin++ = a;
0233 *begin++ = b;
0234 *begin++ = c;
0235 *begin = d;
0236 }
0237
0238
0239
0240
0241
0242
0243 LorentzVector<CoordSystem>& SetXYZT (Scalar xx, Scalar yy, Scalar zz, Scalar tt) {
0244 fCoordinates.SetPxPyPzE(xx,yy,zz,tt);
0245 return *this;
0246 }
0247 LorentzVector<CoordSystem>& SetPxPyPzE (Scalar xx, Scalar yy, Scalar zz, Scalar ee) {
0248 fCoordinates.SetPxPyPzE(xx,yy,zz,ee);
0249 return *this;
0250 }
0251
0252
0253
0254
0255
0256
0257 bool operator==(const LorentzVector & rhs) const {
0258 return fCoordinates==rhs.fCoordinates;
0259 }
0260 bool operator!= (const LorentzVector & rhs) const {
0261 return !(operator==(rhs));
0262 }
0263
0264
0265
0266
0267
0268
0269 unsigned int Dimension() const
0270 {
0271 return fDimension;
0272 };
0273
0274
0275
0276
0277
0278
0279 Scalar Px() const { return fCoordinates.Px(); }
0280 Scalar X() const { return fCoordinates.Px(); }
0281
0282
0283
0284 Scalar Py() const { return fCoordinates.Py(); }
0285 Scalar Y() const { return fCoordinates.Py(); }
0286
0287
0288
0289 Scalar Pz() const { return fCoordinates.Pz(); }
0290 Scalar Z() const { return fCoordinates.Pz(); }
0291
0292
0293
0294 Scalar E() const { return fCoordinates.E(); }
0295 Scalar T() const { return fCoordinates.E(); }
0296
0297
0298
0299
0300 Scalar M2() const { return fCoordinates.M2(); }
0301
0302
0303
0304
0305
0306 Scalar M() const { return fCoordinates.M();}
0307
0308
0309
0310 Scalar R() const { return fCoordinates.R(); }
0311 Scalar P() const { return fCoordinates.R(); }
0312
0313
0314
0315 Scalar P2() const { return P() * P(); }
0316
0317
0318
0319 Scalar Perp2( ) const { return fCoordinates.Perp2();}
0320
0321
0322
0323
0324 Scalar Pt() const { return fCoordinates.Pt(); }
0325 Scalar Rho() const { return fCoordinates.Pt(); }
0326
0327
0328
0329
0330
0331 Scalar Mt2() const { return fCoordinates.Mt2(); }
0332
0333
0334
0335
0336
0337 Scalar Mt() const { return fCoordinates.Mt(); }
0338
0339
0340
0341
0342
0343 Scalar Et2() const { return fCoordinates.Et2(); }
0344
0345
0346
0347
0348
0349 Scalar Et() const { return fCoordinates.Et(); }
0350
0351
0352
0353
0354 Scalar Phi() const { return fCoordinates.Phi();}
0355
0356
0357
0358
0359 Scalar Theta() const { return fCoordinates.Theta(); }
0360
0361
0362
0363
0364
0365 Scalar Eta() const { return fCoordinates.Eta(); }
0366
0367
0368
0369
0370
0371 ::ROOT::Math::DisplacementVector3D<Cartesian3D<Scalar> > Vect() const {
0372 return ::ROOT::Math::DisplacementVector3D<Cartesian3D<Scalar> >( X(), Y(), Z() );
0373 }
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385
0386 template< class OtherLorentzVector >
0387 Scalar Dot(const OtherLorentzVector & q) const {
0388 return t()*q.t() - x()*q.x() - y()*q.y() - z()*q.z();
0389 }
0390
0391
0392
0393
0394
0395
0396
0397 template< class OtherLorentzVector >
0398 inline LorentzVector & operator += ( const OtherLorentzVector & q)
0399 {
0400 SetXYZT( x() + q.x(), y() + q.y(), z() + q.z(), t() + q.t() );
0401 return *this;
0402 }
0403
0404
0405
0406
0407
0408
0409
0410 template< class OtherLorentzVector >
0411 LorentzVector & operator -= ( const OtherLorentzVector & q) {
0412 SetXYZT( x() - q.x(), y() - q.y(), z() - q.z(), t() - q.t() );
0413 return *this;
0414 }
0415
0416
0417
0418
0419
0420
0421
0422
0423 template<class OtherLorentzVector>
0424 LorentzVector operator + ( const OtherLorentzVector & v2) const
0425 {
0426 LorentzVector<CoordinateType> v3(*this);
0427 v3 += v2;
0428 return v3;
0429 }
0430
0431
0432
0433
0434
0435
0436
0437
0438 template<class OtherLorentzVector>
0439 LorentzVector operator - ( const OtherLorentzVector & v2) const {
0440 LorentzVector<CoordinateType> v3(*this);
0441 v3 -= v2;
0442 return v3;
0443 }
0444
0445
0446
0447
0448
0449
0450 LorentzVector & operator *= (Scalar a) {
0451 fCoordinates.Scale(a);
0452 return *this;
0453 }
0454
0455
0456
0457
0458 LorentzVector & operator /= (Scalar a) {
0459 fCoordinates.Scale(1/a);
0460 return *this;
0461 }
0462
0463
0464
0465
0466
0467
0468 LorentzVector operator * ( const Scalar & a) const {
0469 LorentzVector tmp(*this);
0470 tmp *= a;
0471 return tmp;
0472 }
0473
0474
0475
0476
0477
0478
0479 LorentzVector<CoordSystem> operator / ( const Scalar & a) const {
0480 LorentzVector<CoordSystem> tmp(*this);
0481 tmp /= a;
0482 return tmp;
0483 }
0484
0485
0486
0487
0488
0489 LorentzVector operator - () const {
0490
0491
0492 return operator*( Scalar(-1) );
0493 }
0494 LorentzVector operator + () const {
0495 return *this;
0496 }
0497
0498
0499
0500
0501
0502
0503 Scalar Rapidity() const {
0504
0505
0506
0507 const Scalar ee = E();
0508 const Scalar ppz = Pz();
0509 using std::log;
0510 return Scalar(0.5) * log((ee + ppz) / (ee - ppz));
0511 }
0512
0513
0514
0515
0516 Scalar ColinearRapidity() const {
0517
0518
0519 const Scalar ee = E();
0520 const Scalar pp = P();
0521 using std::log;
0522 return Scalar(0.5) * log((ee + pp) / (ee - pp));
0523 }
0524
0525
0526
0527
0528 bool isTimelike( ) const {
0529 Scalar ee = E(); Scalar pp = P(); return ee*ee > pp*pp;
0530 }
0531
0532
0533
0534
0535 bool isLightlike( Scalar tolerance
0536 = 100*std::numeric_limits<Scalar>::epsilon() ) const {
0537 Scalar ee = E(); Scalar pp = P(); Scalar delta = ee-pp;
0538 if ( ee==0 ) return pp==0;
0539 return delta*delta < tolerance * ee*ee;
0540 }
0541
0542
0543
0544
0545 bool isSpacelike( ) const {
0546 Scalar ee = E(); Scalar pp = P(); return ee*ee < pp*pp;
0547 }
0548
0549 typedef DisplacementVector3D< Cartesian3D<Scalar> > BetaVector;
0550
0551
0552
0553
0554
0555 BetaVector BoostToCM( ) const {
0556 if (E() == 0) {
0557 if (P() == 0) {
0558 return BetaVector();
0559 } else {
0560
0561
0562 return -Vect()/E();
0563 }
0564 }
0565 if (M2() <= 0) {
0566
0567
0568 }
0569 return -Vect()/E();
0570 }
0571
0572
0573
0574
0575
0576 template <class Other4Vector>
0577 BetaVector BoostToCM(const Other4Vector& v ) const {
0578 Scalar eSum = E() + v.E();
0579 DisplacementVector3D< Cartesian3D<Scalar> > vecSum = Vect() + v.Vect();
0580 if (eSum == 0) {
0581 if (vecSum.Mag2() == 0) {
0582 return BetaVector();
0583 } else {
0584
0585
0586 return BetaVector(vecSum/eSum);
0587 }
0588
0589
0590 }
0591 return BetaVector (vecSum * (-1./eSum));
0592 }
0593
0594
0595
0596
0597
0598
0599 Scalar Beta() const {
0600 if ( E() == 0 ) {
0601 if ( P2() == 0)
0602
0603 return 0;
0604 else {
0605 GenVector::Throw ("LorentzVector::Beta() - beta computed for LorentzVector with t = 0. Return an Infinite result");
0606 return 1./E();
0607 }
0608 }
0609 if ( M2() <= 0 ) {
0610 GenVector::Throw ("LorentzVector::Beta() - beta computed for non-timelike LorentzVector . Result is physically meaningless" );
0611 }
0612 return P() / E();
0613 }
0614
0615
0616
0617 Scalar Gamma() const {
0618 const Scalar v2 = P2();
0619 const Scalar t2 = E() * E();
0620 if (E() == 0) {
0621 if ( P2() == 0) {
0622 return 1;
0623 } else {
0624 GenVector::Throw ("LorentzVector::Gamma() - gamma computed for LorentzVector with t = 0. Return a zero result");
0625
0626 }
0627 }
0628 if ( t2 < v2 ) {
0629 GenVector::Throw ("LorentzVector::Gamma() - gamma computed for a spacelike LorentzVector. Imaginary result");
0630 return 0;
0631 }
0632 else if ( t2 == v2 ) {
0633 GenVector::Throw ("LorentzVector::Gamma() - gamma computed for a lightlike LorentzVector. Infinite result");
0634 }
0635 using std::sqrt;
0636 return Scalar(1) / sqrt(Scalar(1) - v2 / t2);
0637 }
0638
0639
0640
0641
0642 Scalar x() const { return fCoordinates.Px(); }
0643 Scalar y() const { return fCoordinates.Py(); }
0644 Scalar z() const { return fCoordinates.Pz(); }
0645 Scalar t() const { return fCoordinates.E(); }
0646 Scalar px() const { return fCoordinates.Px(); }
0647 Scalar py() const { return fCoordinates.Py(); }
0648 Scalar pz() const { return fCoordinates.Pz(); }
0649 Scalar e() const { return fCoordinates.E(); }
0650 Scalar r() const { return fCoordinates.R(); }
0651 Scalar theta() const { return fCoordinates.Theta(); }
0652 Scalar phi() const { return fCoordinates.Phi(); }
0653 Scalar rho() const { return fCoordinates.Rho(); }
0654 Scalar eta() const { return fCoordinates.Eta(); }
0655 Scalar pt() const { return fCoordinates.Pt(); }
0656 Scalar perp2() const { return fCoordinates.Perp2(); }
0657 Scalar mag2() const { return fCoordinates.M2(); }
0658 Scalar mag() const { return fCoordinates.M(); }
0659 Scalar mt() const { return fCoordinates.Mt(); }
0660 Scalar mt2() const { return fCoordinates.Mt2(); }
0661
0662
0663
0664 Scalar energy() const { return fCoordinates.E(); }
0665 Scalar mass() const { return fCoordinates.M(); }
0666 Scalar mass2() const { return fCoordinates.M2(); }
0667
0668
0669
0670
0671
0672
0673
0674 LorentzVector<CoordSystem>& SetE ( Scalar a ) { fCoordinates.SetE (a); return *this; }
0675 LorentzVector<CoordSystem>& SetEta( Scalar a ) { fCoordinates.SetEta(a); return *this; }
0676 LorentzVector<CoordSystem>& SetM ( Scalar a ) { fCoordinates.SetM (a); return *this; }
0677 LorentzVector<CoordSystem>& SetPhi( Scalar a ) { fCoordinates.SetPhi(a); return *this; }
0678 LorentzVector<CoordSystem>& SetPt ( Scalar a ) { fCoordinates.SetPt (a); return *this; }
0679 LorentzVector<CoordSystem>& SetPx ( Scalar a ) { fCoordinates.SetPx (a); return *this; }
0680 LorentzVector<CoordSystem>& SetPy ( Scalar a ) { fCoordinates.SetPy (a); return *this; }
0681 LorentzVector<CoordSystem>& SetPz ( Scalar a ) { fCoordinates.SetPz (a); return *this; }
0682
0683 private:
0684
0685 CoordSystem fCoordinates;
0686 static constexpr unsigned int fDimension = CoordinateType::Dimension;
0687
0688 };
0689
0690
0691
0692
0693
0694
0695
0696
0697
0698
0699
0700 template< class CoordSystem >
0701 inline LorentzVector<CoordSystem> operator *
0702 ( const typename LorentzVector<CoordSystem>::Scalar & a,
0703 const LorentzVector<CoordSystem>& v) {
0704 LorentzVector<CoordSystem> tmp(v);
0705 tmp *= a;
0706 return tmp;
0707 }
0708
0709
0710
0711 template< class char_t, class traits_t, class Coords >
0712 inline
0713 std::basic_ostream<char_t,traits_t> &
0714 operator << ( std::basic_ostream<char_t,traits_t> & os
0715 , LorentzVector<Coords> const & v
0716 )
0717 {
0718 if( !os ) return os;
0719
0720 typename Coords::Scalar a, b, c, d;
0721 v.GetCoordinates(a, b, c, d);
0722
0723 if( detail::get_manip( os, detail::bitforbit ) ) {
0724 detail::set_manip( os, detail::bitforbit, '\00' );
0725
0726 }
0727 else {
0728 os << detail::get_manip( os, detail::open ) << a
0729 << detail::get_manip( os, detail::sep ) << b
0730 << detail::get_manip( os, detail::sep ) << c
0731 << detail::get_manip( os, detail::sep ) << d
0732 << detail::get_manip( os, detail::close );
0733 }
0734
0735 return os;
0736
0737 }
0738
0739
0740 template< class char_t, class traits_t, class Coords >
0741 inline
0742 std::basic_istream<char_t,traits_t> &
0743 operator >> ( std::basic_istream<char_t,traits_t> & is
0744 , LorentzVector<Coords> & v
0745 )
0746 {
0747 if( !is ) return is;
0748
0749 typename Coords::Scalar a, b, c, d;
0750
0751 if( detail::get_manip( is, detail::bitforbit ) ) {
0752 detail::set_manip( is, detail::bitforbit, '\00' );
0753
0754 }
0755 else {
0756 detail::require_delim( is, detail::open ); is >> a;
0757 detail::require_delim( is, detail::sep ); is >> b;
0758 detail::require_delim( is, detail::sep ); is >> c;
0759 detail::require_delim( is, detail::sep ); is >> d;
0760 detail::require_delim( is, detail::close );
0761 }
0762
0763 if( is )
0764 v.SetCoordinates(a, b, c, d);
0765 return is;
0766
0767 }
0768
0769
0770
0771 }
0772
0773 }
0774
0775 #include <sstream>
0776 namespace cling
0777 {
0778 template<typename CoordSystem>
0779 std::string printValue(const ROOT::Math::LorentzVector<CoordSystem> *v)
0780 {
0781 std::stringstream s;
0782 s << *v;
0783 return s.str();
0784 }
0785
0786 }
0787
0788 #endif
0789
0790