File indexing completed on 2025-04-19 09:06:47
0001 #ifndef RIVET_MATH_VECTOR4
0002 #define RIVET_MATH_VECTOR4
0003
0004 #include "Rivet/Tools/TypeTraits.hh"
0005 #include "Rivet/Math/MathConstants.hh"
0006 #include "Rivet/Math/MathUtils.hh"
0007 #include "Rivet/Math/VectorN.hh"
0008 #include "Rivet/Math/Vector3.hh"
0009
0010
0011 namespace fastjet { class PseudoJet; }
0012
0013 namespace Rivet {
0014
0015
0016 class FourVector;
0017 typedef FourVector Vector4;
0018 typedef FourVector V4;
0019
0020 class FourMomentum;
0021 typedef FourMomentum P4;
0022
0023 class LorentzTransform;
0024 FourVector transform(const LorentzTransform& lt, const FourVector& v4);
0025
0026
0027
0028
0029
0030 class FourVector : public Vector<4> {
0031 friend FourVector multiply(const double a, const FourVector& v);
0032 friend FourVector multiply(const FourVector& v, const double a);
0033 friend FourVector add(const FourVector& a, const FourVector& b);
0034 friend FourVector transform(const LorentzTransform& lt, const FourVector& v4);
0035
0036 public:
0037
0038 FourVector() : Vector<4>() { }
0039
0040 template<typename V4TYPE, typename std::enable_if<HasXYZT<V4TYPE>::value, int>::type DUMMY=0>
0041 FourVector(const V4TYPE& other) {
0042 this->setT(other.t());
0043 this->setX(other.x());
0044 this->setY(other.y());
0045 this->setZ(other.z());
0046 }
0047
0048 FourVector(const Vector<4>& other)
0049 : Vector<4>(other) { }
0050
0051 FourVector(const double t, const double x, const double y, const double z) {
0052 this->setT(t);
0053 this->setX(x);
0054 this->setY(y);
0055 this->setZ(z);
0056 }
0057
0058 virtual ~FourVector() { }
0059
0060
0061
0062
0063
0064 operator fastjet::PseudoJet () const;
0065
0066
0067 public:
0068
0069 double t() const { return get(0); }
0070 double t2() const { return sqr(t()); }
0071 FourVector& setT(const double t) { set(0, t); return *this; }
0072
0073 double x() const { return get(1); }
0074 double x2() const { return sqr(x()); }
0075 FourVector& setX(const double x) { set(1, x); return *this; }
0076
0077 double y() const { return get(2); }
0078 double y2() const { return sqr(y()); }
0079 FourVector& setY(const double y) { set(2, y); return *this; }
0080
0081 double z() const { return get(3); }
0082 double z2() const { return sqr(z()); }
0083 FourVector& setZ(const double z) { set(3, z); return *this; }
0084
0085 double invariant() const {
0086
0087 return (t() + z())*(t() - z()) - x()*x() - y()*y();
0088 }
0089
0090 bool isNull() const {
0091 return Rivet::isZero(invariant());
0092 }
0093
0094
0095 double angle(const FourVector& v) const {
0096 return vector3().angle( v.vector3() );
0097 }
0098
0099 double angle(const Vector3& v3) const {
0100 return vector3().angle(v3);
0101 }
0102
0103
0104
0105
0106 double polarRadius2() const {
0107 return vector3().polarRadius2();
0108 }
0109
0110 double perp2() const {
0111 return vector3().perp2();
0112 }
0113
0114 double rho2() const {
0115 return vector3().rho2();
0116 }
0117
0118
0119 double polarRadius() const {
0120 return vector3().polarRadius();
0121 }
0122
0123 double perp() const {
0124 return vector3().perp();
0125 }
0126
0127 double rho() const {
0128 return vector3().rho();
0129 }
0130
0131
0132 Vector3 polarVec() const {
0133 return vector3().polarVec();
0134 }
0135
0136 Vector3 perpVec() const {
0137 return vector3().perpVec();
0138 }
0139
0140 Vector3 rhoVec() const {
0141 return vector3().rhoVec();
0142 }
0143
0144
0145 double azimuthalAngle(const PhiMapping mapping=ZERO_2PI) const {
0146 return vector3().azimuthalAngle(mapping);
0147 }
0148
0149 double phi(const PhiMapping mapping=ZERO_2PI) const {
0150 return vector3().phi(mapping);
0151 }
0152
0153
0154 double polarAngle() const {
0155 return vector3().polarAngle();
0156 }
0157
0158 double theta() const {
0159 return vector3().theta();
0160 }
0161
0162
0163 double pseudorapidity() const {
0164 return vector3().pseudorapidity();
0165 }
0166
0167 double eta() const {
0168 return vector3().eta();
0169 }
0170
0171
0172 double abspseudorapidity() const { return fabs(eta()); }
0173
0174 double abseta() const { return fabs(eta()); }
0175
0176
0177 Vector3 vector3() const {
0178 return Vector3(get(1), get(2), get(3));
0179 }
0180
0181
0182 operator Vector3 () const { return vector3(); }
0183
0184
0185 public:
0186
0187
0188 double contract(const FourVector& v) const {
0189 const double result = t()*v.t() - x()*v.x() - y()*v.y() - z()*v.z();
0190 return result;
0191 }
0192
0193
0194 double dot(const FourVector& v) const {
0195 return contract(v);
0196 }
0197
0198
0199 double operator * (const FourVector& v) const {
0200 return contract(v);
0201 }
0202
0203
0204 FourVector& operator *= (double a) {
0205 _vec = multiply(a, *this)._vec;
0206 return *this;
0207 }
0208
0209
0210 FourVector& operator /= (double a) {
0211 _vec = multiply(1.0/a, *this)._vec;
0212 return *this;
0213 }
0214
0215
0216 FourVector& operator += (const FourVector& v) {
0217 _vec = add(*this, v)._vec;
0218 return *this;
0219 }
0220
0221
0222 FourVector& operator -= (const FourVector& v) {
0223 _vec = add(*this, -v)._vec;
0224 return *this;
0225 }
0226
0227
0228 FourVector operator - () const {
0229 FourVector result;
0230 result._vec = -_vec;
0231 return result;
0232 }
0233
0234
0235 FourVector reverse() const {
0236 FourVector result = -*this;
0237 result.setT(-result.t());
0238 return result;
0239 }
0240
0241 };
0242
0243
0244
0245 inline double contract(const FourVector& a, const FourVector& b) {
0246 return a.contract(b);
0247 }
0248
0249
0250 inline double dot(const FourVector& a, const FourVector& b) {
0251 return contract(a, b);
0252 }
0253
0254 inline FourVector multiply(const double a, const FourVector& v) {
0255 FourVector result;
0256 result._vec = a * v._vec;
0257 return result;
0258 }
0259
0260 inline FourVector multiply(const FourVector& v, const double a) {
0261 return multiply(a, v);
0262 }
0263
0264 inline FourVector operator * (const double a, const FourVector& v) {
0265 return multiply(a, v);
0266 }
0267
0268 inline FourVector operator * (const FourVector& v, const double a) {
0269 return multiply(a, v);
0270 }
0271
0272 inline FourVector operator / (const FourVector& v, const double a) {
0273 return multiply(1.0/a, v);
0274 }
0275
0276 inline FourVector add(const FourVector& a, const FourVector& b) {
0277 FourVector result;
0278 result._vec = a._vec + b._vec;
0279 return result;
0280 }
0281
0282 inline FourVector operator+(const FourVector& a, const FourVector& b) {
0283 return add(a, b);
0284 }
0285
0286 inline FourVector operator-(const FourVector& a, const FourVector& b) {
0287 return add(a, -b);
0288 }
0289
0290
0291
0292 inline double invariant(const FourVector& lv) {
0293 return lv.invariant();
0294 }
0295
0296
0297 inline double angle(const FourVector& a, const FourVector& b) {
0298 return a.angle(b);
0299 }
0300
0301
0302 inline double angle(const Vector3& a, const FourVector& b) {
0303 return angle( a, b.vector3() );
0304 }
0305
0306
0307 inline double angle(const FourVector& a, const Vector3& b) {
0308 return a.angle(b);
0309 }
0310
0311
0312
0313
0314
0315
0316 class FourMomentum : public FourVector {
0317 friend FourMomentum multiply(const double a, const FourMomentum& v);
0318 friend FourMomentum multiply(const FourMomentum& v, const double a);
0319 friend FourMomentum add(const FourMomentum& a, const FourMomentum& b);
0320 friend FourMomentum transform(const LorentzTransform& lt, const FourMomentum& v4);
0321
0322 public:
0323 FourMomentum() { }
0324
0325 template<typename V4TYPE, typename std::enable_if<HasXYZT<V4TYPE>::value, int>::type DUMMY=0>
0326 FourMomentum(const V4TYPE& other) {
0327 this->setE(other.t());
0328 this->setPx(other.x());
0329 this->setPy(other.y());
0330 this->setPz(other.z());
0331 }
0332
0333 FourMomentum(const Vector<4>& other)
0334 : FourVector(other) { }
0335
0336 FourMomentum(const double E, const double px, const double py, const double pz) {
0337 this->setE(E);
0338 this->setPx(px);
0339 this->setPy(py);
0340 this->setPz(pz);
0341 }
0342
0343 ~FourMomentum() {}
0344
0345 public:
0346
0347
0348
0349
0350
0351
0352 FourMomentum& setE(double E) {
0353 setT(E);
0354 return *this;
0355 }
0356
0357
0358 FourMomentum& setPx(double px) {
0359 setX(px);
0360 return *this;
0361 }
0362
0363
0364 FourMomentum& setPy(double py) {
0365 setY(py);
0366 return *this;
0367 }
0368
0369
0370 FourMomentum& setPz(double pz) {
0371 setZ(pz);
0372 return *this;
0373 }
0374
0375
0376
0377 FourMomentum& setPE(double px, double py, double pz, double E) {
0378 if (E < 0)
0379 throw std::invalid_argument("Negative energy given as argument: " + to_str(E));
0380 setPx(px); setPy(py); setPz(pz); setE(E);
0381 return *this;
0382 }
0383
0384 FourMomentum& setXYZE(double px, double py, double pz, double E) {
0385 return setPE(px, py, pz, E);
0386 }
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398 FourMomentum& setPM(double px, double py, double pz, double mass) {
0399 if (mass < 0)
0400 throw std::invalid_argument("Negative mass given as argument: " + to_str(mass));
0401 const double E = sqrt( sqr(mass) + sqr(px) + sqr(py) + sqr(pz) );
0402
0403 return setPE(px, py, pz, E);
0404 }
0405
0406 FourMomentum& setXYZM(double px, double py, double pz, double mass) {
0407 return setPM(px, py, pz, mass);
0408 }
0409
0410
0411
0412
0413
0414
0415 FourMomentum& setEtaPhiME(double eta, double phi, double mass, double E) {
0416 if (mass < 0)
0417 throw std::invalid_argument("Negative mass given as argument");
0418 if (E < 0)
0419 throw std::invalid_argument("Negative energy given as argument");
0420 const double theta = 2 * atan(exp(-eta));
0421 if (theta < 0 || theta > M_PI)
0422 throw std::domain_error("Polar angle outside 0..pi in calculation");
0423 setThetaPhiME(theta, phi, mass, E);
0424 return *this;
0425 }
0426
0427
0428
0429
0430
0431 FourMomentum& setEtaPhiMPt(double eta, double phi, double mass, double pt) {
0432 if (mass < 0)
0433 throw std::invalid_argument("Negative mass given as argument");
0434 if (pt < 0)
0435 throw std::invalid_argument("Negative transverse momentum given as argument");
0436 const double theta = 2 * atan(exp(-eta));
0437 if (theta < 0 || theta > M_PI)
0438 throw std::domain_error("Polar angle outside 0..pi in calculation");
0439 const double p = pt / sin(theta);
0440 const double E = sqrt( sqr(p) + sqr(mass) );
0441 setThetaPhiME(theta, phi, mass, E);
0442 return *this;
0443 }
0444
0445
0446
0447
0448
0449
0450
0451
0452
0453 FourMomentum& setRapPhiME(double y, double phi, double mass, double E) {
0454 if (mass < 0)
0455 throw std::invalid_argument("Negative mass given as argument");
0456 if (E < 0)
0457 throw std::invalid_argument("Negative energy given as argument");
0458 const double sqrt_pt2_m2 = E / cosh(y);
0459 const double pt = sqrt( sqr(sqrt_pt2_m2) - sqr(mass) );
0460 if (pt < 0)
0461 throw std::domain_error("Negative transverse momentum in calculation");
0462 const double pz = sqrt_pt2_m2 * sinh(y);
0463 const double px = pt * cos(phi);
0464 const double py = pt * sin(phi);
0465 setPE(px, py, pz, E);
0466 return *this;
0467 }
0468
0469
0470
0471
0472
0473 FourMomentum& setRapPhiMPt(double y, double phi, double mass, double pt) {
0474 if (mass < 0)
0475 throw std::invalid_argument("Negative mass given as argument");
0476 if (pt < 0)
0477 throw std::invalid_argument("Negative transverse mass given as argument");
0478 const double E = sqrt( sqr(pt) + sqr(mass) ) * cosh(y);
0479 if (E < 0)
0480 throw std::domain_error("Negative energy in calculation");
0481 setRapPhiME(y, phi, mass, E);
0482 return *this;
0483 }
0484
0485
0486
0487
0488
0489
0490 FourMomentum& setThetaPhiME(double theta, double phi, double mass, double E) {
0491 if (theta < 0 || theta > M_PI)
0492 throw std::invalid_argument("Polar angle outside 0..pi given as argument");
0493 if (mass < 0)
0494 throw std::invalid_argument("Negative mass given as argument");
0495 if (E < 0)
0496 throw std::invalid_argument("Negative energy given as argument");
0497 const double p = sqrt( sqr(E) - sqr(mass) );
0498 const double pz = p * cos(theta);
0499 const double pt = p * sin(theta);
0500 if (pt < 0)
0501 throw std::invalid_argument("Negative transverse momentum in calculation");
0502 const double px = pt * cos(phi);
0503 const double py = pt * sin(phi);
0504 setPE(px, py, pz, E);
0505 return *this;
0506 }
0507
0508
0509
0510
0511
0512
0513 FourMomentum& setThetaPhiMPt(double theta, double phi, double mass, double pt) {
0514 if (theta < 0 || theta > M_PI)
0515 throw std::invalid_argument("Polar angle outside 0..pi given as argument");
0516 if (mass < 0)
0517 throw std::invalid_argument("Negative mass given as argument");
0518 if (pt < 0)
0519 throw std::invalid_argument("Negative transverse momentum given as argument");
0520 const double p = pt / sin(theta);
0521 const double px = pt * cos(phi);
0522 const double py = pt * sin(phi);
0523 const double pz = p * cos(theta);
0524 const double E = sqrt( sqr(p) + sqr(mass) );
0525 setPE(px, py, pz, E);
0526 return *this;
0527 }
0528
0529
0530
0531
0532 FourMomentum& setPtPhiME(double pt, double phi, double mass, double E) {
0533 if (pt < 0)
0534 throw std::invalid_argument("Negative transverse momentum given as argument");
0535 if (mass < 0)
0536 throw std::invalid_argument("Negative mass given as argument");
0537 if (E < 0)
0538 throw std::invalid_argument("Negative energy given as argument");
0539 const double px = pt * cos(phi);
0540 const double py = pt * sin(phi);
0541 const double pz = sqrt(sqr(E) - sqr(mass) - sqr(pt));
0542 setPE(px, py, pz, E);
0543 return *this;
0544 }
0545
0546
0547
0548
0549
0550
0551
0552
0553 double E() const { return t(); }
0554
0555 double E2() const { return t2(); }
0556
0557
0558 double px() const { return x(); }
0559
0560 double px2() const { return x2(); }
0561
0562
0563 double py() const { return y(); }
0564
0565 double py2() const { return y2(); }
0566
0567
0568 double pz() const { return z(); }
0569
0570 double pz2() const { return z2(); }
0571
0572
0573
0574
0575
0576 double mass() const {
0577
0578
0579
0580
0581
0582
0583 return sign(mass2()) * sqrt(fabs(mass2()));
0584 }
0585
0586
0587 double mass2() const {
0588 return invariant();
0589 }
0590
0591
0592
0593 Vector3 p3() const { return vector3(); }
0594
0595
0596 double p() const {
0597 return p3().mod();
0598 }
0599
0600
0601 double p2() const {
0602 return p3().mod2();
0603 }
0604
0605
0606
0607 double rapidity() const {
0608 if (E() == 0.0) return 0.0;
0609 if (E() == fabs(pz())) return std::copysign(INF, pz());
0610 return 0.5 * std::log( (E() + pz()) / (E() - pz()) );
0611 }
0612
0613 double rap() const {
0614 return rapidity();
0615 }
0616
0617
0618 double absrapidity() const {
0619 return fabs(rapidity());
0620 }
0621
0622 double absrap() const {
0623 return fabs(rap());
0624 }
0625
0626
0627 Vector3 pTvec() const {
0628 return p3().polarVec();
0629 }
0630
0631 Vector3 ptvec() const {
0632 return pTvec();
0633 }
0634
0635
0636 double pT2() const {
0637 return vector3().polarRadius2();
0638 }
0639
0640 double pt2() const {
0641 return vector3().polarRadius2();
0642 }
0643
0644
0645 double pT() const {
0646 return sqrt(pT2());
0647 }
0648
0649 double pt() const {
0650 return sqrt(pT2());
0651 }
0652
0653
0654 double Et2() const {
0655 return Et() * Et();
0656 }
0657
0658 double Et() const {
0659 return E() * sin(polarAngle());
0660 }
0661
0662
0663
0664
0665
0666
0667
0668
0669
0670 double gamma() const {
0671 return sqrt(E2()/mass2());
0672 }
0673
0674
0675
0676 Vector3 gammaVec() const {
0677 return gamma() * p3().unit();
0678 }
0679
0680
0681
0682 double beta() const {
0683 return p()/E();
0684 }
0685
0686
0687
0688 Vector3 betaVec() const {
0689
0690 return p3()/E();
0691 }
0692
0693
0694
0695
0696
0697
0698
0699
0700
0701
0702 FourMomentum& operator*=(double a) {
0703 _vec = multiply(a, *this)._vec;
0704 return *this;
0705 }
0706
0707
0708 FourMomentum& operator/=(double a) {
0709 _vec = multiply(1.0/a, *this)._vec;
0710 return *this;
0711 }
0712
0713
0714 FourMomentum& operator+=(const FourMomentum& v) {
0715 _vec = add(*this, v)._vec;
0716 return *this;
0717 }
0718
0719
0720 FourMomentum& operator-=(const FourMomentum& v) {
0721 _vec = add(*this, -v)._vec;
0722 return *this;
0723 }
0724
0725
0726 FourMomentum operator-() const {
0727 FourMomentum result;
0728 result._vec = -_vec;
0729 return result;
0730 }
0731
0732
0733 FourMomentum reverse() const {
0734 FourMomentum result = -*this;
0735 result.setE(-result.E());
0736 return result;
0737 }
0738
0739
0740
0741
0742
0743
0744
0745
0746
0747
0748
0749 static FourMomentum mkXYZE(double px, double py, double pz, double E) {
0750 return FourMomentum().setPE(px, py, pz, E);
0751 }
0752
0753
0754 static FourMomentum mkXYZM(double px, double py, double pz, double mass) {
0755 return FourMomentum().setPM(px, py, pz, mass);
0756 }
0757
0758
0759 static FourMomentum mkEtaPhiME(double eta, double phi, double mass, double E) {
0760 return FourMomentum().setEtaPhiME(eta, phi, mass, E);
0761 }
0762
0763
0764 static FourMomentum mkEtaPhiMPt(double eta, double phi, double mass, double pt) {
0765 return FourMomentum().setEtaPhiMPt(eta, phi, mass, pt);
0766 }
0767
0768
0769 static FourMomentum mkRapPhiME(double y, double phi, double mass, double E) {
0770 return FourMomentum().setRapPhiME(y, phi, mass, E);
0771 }
0772
0773
0774 static FourMomentum mkRapPhiMPt(double y, double phi, double mass, double pt) {
0775 return FourMomentum().setRapPhiMPt(y, phi, mass, pt);
0776 }
0777
0778
0779 static FourMomentum mkThetaPhiME(double theta, double phi, double mass, double E) {
0780 return FourMomentum().setThetaPhiME(theta, phi, mass, E);
0781 }
0782
0783
0784 static FourMomentum mkThetaPhiMPt(double theta, double phi, double mass, double pt) {
0785 return FourMomentum().setThetaPhiMPt(theta, phi, mass, pt);
0786 }
0787
0788
0789 static FourMomentum mkPtPhiME(double pt, double phi, double mass, double E) {
0790 return FourMomentum().setPtPhiME(pt, phi, mass, E);
0791 }
0792
0793
0794
0795
0796 };
0797
0798
0799 inline FourMomentum multiply(const double a, const FourMomentum& v) {
0800 FourMomentum result;
0801 result._vec = a * v._vec;
0802 return result;
0803 }
0804
0805 inline FourMomentum multiply(const FourMomentum& v, const double a) {
0806 return multiply(a, v);
0807 }
0808
0809 inline FourMomentum operator*(const double a, const FourMomentum& v) {
0810 return multiply(a, v);
0811 }
0812
0813 inline FourMomentum operator*(const FourMomentum& v, const double a) {
0814 return multiply(a, v);
0815 }
0816
0817 inline FourMomentum operator/(const FourMomentum& v, const double a) {
0818 return multiply(1.0/a, v);
0819 }
0820
0821 inline FourMomentum add(const FourMomentum& a, const FourMomentum& b) {
0822 FourMomentum result;
0823 result._vec = a._vec + b._vec;
0824 return result;
0825 }
0826
0827 inline FourMomentum operator+(const FourMomentum& a, const FourMomentum& b) {
0828 return add(a, b);
0829 }
0830
0831 inline FourMomentum operator-(const FourMomentum& a, const FourMomentum& b) {
0832 return add(a, -b);
0833 }
0834
0835
0836
0837
0838
0839
0840
0841
0842
0843
0844
0845
0846
0847
0848
0849
0850 inline double deltaR2(const FourVector& a, const FourVector& b,
0851 RapScheme scheme=PSEUDORAPIDITY) {
0852 switch (scheme) {
0853 case PSEUDORAPIDITY :
0854 return deltaR2(a.vector3(), b.vector3());
0855 case RAPIDITY:
0856 {
0857 const FourMomentum* ma = dynamic_cast<const FourMomentum*>(&a);
0858 const FourMomentum* mb = dynamic_cast<const FourMomentum*>(&b);
0859 if (!ma || !mb) {
0860 string err = "deltaR with scheme RAPIDITY can only be called with FourMomentum objects, not FourVectors";
0861 throw std::runtime_error(err);
0862 }
0863 return deltaR2(*ma, *mb, scheme);
0864 }
0865 default:
0866 throw std::runtime_error("The specified deltaR scheme is not yet implemented");
0867 }
0868 }
0869
0870
0871
0872
0873
0874
0875
0876
0877
0878 inline double deltaR(const FourVector& a, const FourVector& b,
0879 RapScheme scheme=PSEUDORAPIDITY) {
0880 return sqrt(deltaR2(a, b, scheme));
0881 }
0882
0883
0884
0885
0886
0887
0888
0889
0890
0891 inline double deltaR2(const FourVector& v,
0892 double eta2, double phi2,
0893 RapScheme scheme=PSEUDORAPIDITY) {
0894 switch (scheme) {
0895 case PSEUDORAPIDITY :
0896 return deltaR2(v.vector3(), eta2, phi2);
0897 case RAPIDITY:
0898 {
0899 const FourMomentum* mv = dynamic_cast<const FourMomentum*>(&v);
0900 if (!mv) {
0901 string err = "deltaR with scheme RAPIDITY can only be called with FourMomentum objects, not FourVectors";
0902 throw std::runtime_error(err);
0903 }
0904 return deltaR2(*mv, eta2, phi2, scheme);
0905 }
0906 default:
0907 throw std::runtime_error("The specified deltaR scheme is not yet implemented");
0908 }
0909 }
0910
0911
0912
0913
0914
0915
0916
0917 inline double deltaR(const FourVector& v,
0918 double eta2, double phi2,
0919 RapScheme scheme=PSEUDORAPIDITY) {
0920 return sqrt(deltaR2(v, eta2, phi2, scheme));
0921 }
0922
0923
0924
0925
0926
0927
0928
0929
0930 inline double deltaR2(double eta1, double phi1,
0931 const FourVector& v,
0932 RapScheme scheme=PSEUDORAPIDITY) {
0933 switch (scheme) {
0934 case PSEUDORAPIDITY :
0935 return deltaR2(eta1, phi1, v.vector3());
0936 case RAPIDITY:
0937 {
0938 const FourMomentum* mv = dynamic_cast<const FourMomentum*>(&v);
0939 if (!mv) {
0940 string err = "deltaR with scheme RAPIDITY can only be called with FourMomentum objects, not FourVectors";
0941 throw std::runtime_error(err);
0942 }
0943 return deltaR2(eta1, phi1, *mv, scheme);
0944 }
0945 default:
0946 throw std::runtime_error("The specified deltaR scheme is not yet implemented");
0947 }
0948 }
0949
0950
0951
0952
0953
0954
0955
0956 inline double deltaR(double eta1, double phi1,
0957 const FourVector& v,
0958 RapScheme scheme=PSEUDORAPIDITY) {
0959 return sqrt(deltaR2(eta1, phi1, v, scheme));
0960 }
0961
0962
0963
0964
0965
0966
0967
0968
0969 inline double deltaR2(const FourMomentum& a, const FourMomentum& b,
0970 RapScheme scheme=PSEUDORAPIDITY) {
0971 switch (scheme) {
0972 case PSEUDORAPIDITY:
0973 return deltaR2(a.vector3(), b.vector3());
0974 case RAPIDITY:
0975 return deltaR2(a.rapidity(), a.azimuthalAngle(), b.rapidity(), b.azimuthalAngle());
0976 default:
0977 throw std::runtime_error("The specified deltaR scheme is not yet implemented");
0978 }
0979 }
0980
0981
0982
0983
0984
0985
0986
0987 inline double deltaR(const FourMomentum& a, const FourMomentum& b,
0988 RapScheme scheme=PSEUDORAPIDITY) {
0989 return sqrt(deltaR2(a, b, scheme));
0990 }
0991
0992
0993
0994
0995
0996
0997
0998 inline double deltaR2(const FourMomentum& v,
0999 double eta2, double phi2,
1000 RapScheme scheme=PSEUDORAPIDITY) {
1001 switch (scheme) {
1002 case PSEUDORAPIDITY:
1003 return deltaR2(v.vector3(), eta2, phi2);
1004 case RAPIDITY:
1005 return deltaR2(v.rapidity(), v.azimuthalAngle(), eta2, phi2);
1006 default:
1007 throw std::runtime_error("The specified deltaR scheme is not yet implemented");
1008 }
1009 }
1010
1011
1012
1013
1014
1015
1016 inline double deltaR(const FourMomentum& v,
1017 double eta2, double phi2,
1018 RapScheme scheme=PSEUDORAPIDITY) {
1019 return sqrt(deltaR2(v, eta2, phi2, scheme));
1020 }
1021
1022
1023
1024
1025
1026
1027
1028 inline double deltaR2(double eta1, double phi1,
1029 const FourMomentum& v,
1030 RapScheme scheme=PSEUDORAPIDITY) {
1031 switch (scheme) {
1032 case PSEUDORAPIDITY:
1033 return deltaR2(eta1, phi1, v.vector3());
1034 case RAPIDITY:
1035 return deltaR2(eta1, phi1, v.rapidity(), v.azimuthalAngle());
1036 default:
1037 throw std::runtime_error("The specified deltaR scheme is not yet implemented");
1038 }
1039 }
1040
1041
1042
1043
1044
1045
1046 inline double deltaR(double eta1, double phi1,
1047 const FourMomentum& v,
1048 RapScheme scheme=PSEUDORAPIDITY) {
1049 return sqrt(deltaR2(eta1, phi1, v, scheme));
1050 }
1051
1052
1053
1054
1055
1056
1057
1058 inline double deltaR2(const FourMomentum& a, const FourVector& b,
1059 RapScheme scheme=PSEUDORAPIDITY) {
1060 switch (scheme) {
1061 case PSEUDORAPIDITY:
1062 return deltaR2(a.vector3(), b.vector3());
1063 case RAPIDITY:
1064 return deltaR2(a.rapidity(), a.azimuthalAngle(), FourMomentum(b).rapidity(), b.azimuthalAngle());
1065 default:
1066 throw std::runtime_error("The specified deltaR scheme is not yet implemented");
1067 }
1068 }
1069
1070
1071
1072
1073
1074
1075 inline double deltaR(const FourMomentum& a, const FourVector& b,
1076 RapScheme scheme=PSEUDORAPIDITY) {
1077 return sqrt(deltaR2(a, b, scheme));
1078 }
1079
1080
1081
1082
1083
1084
1085
1086 inline double deltaR2(const FourVector& a, const FourMomentum& b,
1087 RapScheme scheme=PSEUDORAPIDITY) {
1088 return deltaR2(b, a, scheme);
1089 }
1090
1091
1092
1093
1094
1095
1096 inline double deltaR(const FourVector& a, const FourMomentum& b,
1097 RapScheme scheme=PSEUDORAPIDITY) {
1098 return deltaR(b, a, scheme);
1099 }
1100
1101
1102
1103
1104 inline double deltaR2(const FourMomentum& a, const Vector3& b) {
1105 return deltaR2(a.vector3(), b);
1106 }
1107
1108
1109
1110 inline double deltaR(const FourMomentum& a, const Vector3& b) {
1111 return deltaR(a.vector3(), b);
1112 }
1113
1114
1115
1116 inline double deltaR2(const Vector3& a, const FourMomentum& b) {
1117 return deltaR2(a, b.vector3());
1118 }
1119
1120
1121
1122 inline double deltaR(const Vector3& a, const FourMomentum& b) {
1123 return deltaR(a, b.vector3());
1124 }
1125
1126
1127
1128 inline double deltaR2(const FourVector& a, const Vector3& b) {
1129 return deltaR2(a.vector3(), b);
1130 }
1131
1132
1133
1134 inline double deltaR(const FourVector& a, const Vector3& b) {
1135 return deltaR(a.vector3(), b);
1136 }
1137
1138
1139
1140 inline double deltaR2(const Vector3& a, const FourVector& b) {
1141 return deltaR2(a, b.vector3());
1142 }
1143
1144
1145
1146 inline double deltaR(const Vector3& a, const FourVector& b) {
1147 return deltaR(a, b.vector3());
1148 }
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160 inline double deltaPhi(const FourMomentum& a, const FourMomentum& b, bool sign=false) {
1161 return deltaPhi(a.vector3(), b.vector3(), sign);
1162 }
1163
1164
1165 inline double deltaPhi(const FourMomentum& v, double phi2, bool sign=false) {
1166 return deltaPhi(v.vector3(), phi2, sign);
1167 }
1168
1169
1170 inline double deltaPhi(double phi1, const FourMomentum& v, bool sign=false) {
1171 return deltaPhi(phi1, v.vector3(), sign);
1172 }
1173
1174
1175 inline double deltaPhi(const FourVector& a, const FourVector& b, bool sign=false) {
1176 return deltaPhi(a.vector3(), b.vector3(), sign);
1177 }
1178
1179
1180 inline double deltaPhi(const FourVector& v, double phi2, bool sign=false) {
1181 return deltaPhi(v.vector3(), phi2, sign);
1182 }
1183
1184
1185 inline double deltaPhi(double phi1, const FourVector& v, bool sign=false) {
1186 return deltaPhi(phi1, v.vector3(), sign);
1187 }
1188
1189
1190 inline double deltaPhi(const FourVector& a, const FourMomentum& b, bool sign=false) {
1191 return deltaPhi(a.vector3(), b.vector3(), sign);
1192 }
1193
1194
1195 inline double deltaPhi(const FourMomentum& a, const FourVector& b, bool sign=false) {
1196 return deltaPhi(a.vector3(), b.vector3(), sign);
1197 }
1198
1199
1200 inline double deltaPhi(const FourVector& a, const Vector3& b, bool sign=false) {
1201 return deltaPhi(a.vector3(), b, sign);
1202 }
1203
1204
1205 inline double deltaPhi(const Vector3& a, const FourVector& b, bool sign=false) {
1206 return deltaPhi(a, b.vector3(), sign);
1207 }
1208
1209
1210 inline double deltaPhi(const FourMomentum& a, const Vector3& b, bool sign=false) {
1211 return deltaPhi(a.vector3(), b, sign);
1212 }
1213
1214
1215 inline double deltaPhi(const Vector3& a, const FourMomentum& b, bool sign=false) {
1216 return deltaPhi(a, b.vector3(), sign);
1217 }
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229 inline double deltaEta(const FourMomentum& a, const FourMomentum& b, bool sign=false) {
1230 return deltaEta(a.vector3(), b.vector3(), sign);
1231 }
1232
1233
1234 inline double deltaEta(const FourMomentum& v, double eta2, bool sign=false) {
1235 return deltaEta(v.vector3(), eta2, sign);
1236 }
1237
1238
1239 inline double deltaEta(double eta1, const FourMomentum& v, bool sign=false) {
1240 return deltaEta(eta1, v.vector3(), sign);
1241 }
1242
1243
1244 inline double deltaEta(const FourVector& a, const FourVector& b, bool sign=false) {
1245 return deltaEta(a.vector3(), b.vector3(), sign);
1246 }
1247
1248
1249 inline double deltaEta(const FourVector& v, double eta2, bool sign=false) {
1250 return deltaEta(v.vector3(), eta2, sign);
1251 }
1252
1253
1254 inline double deltaEta(double eta1, const FourVector& v, bool sign=false) {
1255 return deltaEta(eta1, v.vector3(), sign);
1256 }
1257
1258
1259 inline double deltaEta(const FourVector& a, const FourMomentum& b, bool sign=false) {
1260 return deltaEta(a.vector3(), b.vector3(), sign);
1261 }
1262
1263
1264 inline double deltaEta(const FourMomentum& a, const FourVector& b, bool sign=false) {
1265 return deltaEta(a.vector3(), b.vector3(), sign);
1266 }
1267
1268
1269 inline double deltaEta(const FourVector& a, const Vector3& b, bool sign=false) {
1270 return deltaEta(a.vector3(), b, sign);
1271 }
1272
1273
1274 inline double deltaEta(const Vector3& a, const FourVector& b, bool sign=false) {
1275 return deltaEta(a, b.vector3(), sign);
1276 }
1277
1278
1279 inline double deltaEta(const FourMomentum& a, const Vector3& b, bool sign=false) {
1280 return deltaEta(a.vector3(), b, sign);
1281 }
1282
1283
1284 inline double deltaEta(const Vector3& a, const FourMomentum& b, bool sign=false) {
1285 return deltaEta(a, b.vector3(), sign);
1286 }
1287
1288
1289
1290
1291
1292
1293
1294
1295 inline double deltaRap(const FourMomentum& a, const FourMomentum& b, bool sign=false) {
1296 return deltaRap(a.rapidity(), b.rapidity(), sign);
1297 }
1298
1299
1300 inline double deltaRap(const FourMomentum& v, double y2, bool sign=false) {
1301 return deltaRap(v.rapidity(), y2, sign);
1302 }
1303
1304
1305 inline double deltaRap(double y1, const FourMomentum& v, bool sign=false) {
1306 return deltaRap(y1, v.rapidity(), sign);
1307 }
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322 inline bool cmpMomByPt(const FourMomentum& a, const FourMomentum& b) {
1323 return a.pt() > b.pt();
1324 }
1325
1326 inline bool cmpMomByAscPt(const FourMomentum& a, const FourMomentum& b) {
1327 return a.pt() < b.pt();
1328 }
1329
1330
1331 inline bool cmpMomByP(const FourMomentum& a, const FourMomentum& b) {
1332 return a.vector3().mod() > b.vector3().mod();
1333 }
1334
1335 inline bool cmpMomByAscP(const FourMomentum& a, const FourMomentum& b) {
1336 return a.vector3().mod() < b.vector3().mod();
1337 }
1338
1339
1340 inline bool cmpMomByEt(const FourMomentum& a, const FourMomentum& b) {
1341 return a.Et() > b.Et();
1342 }
1343
1344 inline bool cmpMomByAscEt(const FourMomentum& a, const FourMomentum& b) {
1345 return a.Et() < b.Et();
1346 }
1347
1348
1349 inline bool cmpMomByE(const FourMomentum& a, const FourMomentum& b) {
1350 return a.E() > b.E();
1351 }
1352
1353 inline bool cmpMomByAscE(const FourMomentum& a, const FourMomentum& b) {
1354 return a.E() < b.E();
1355 }
1356
1357
1358 inline bool cmpMomByMass(const FourMomentum& a, const FourMomentum& b) {
1359 return a.mass() > b.mass();
1360 }
1361
1362 inline bool cmpMomByAscMass(const FourMomentum& a, const FourMomentum& b) {
1363 return a.mass() < b.mass();
1364 }
1365
1366
1367 inline bool cmpMomByEta(const FourMomentum& a, const FourMomentum& b) {
1368 return a.eta() < b.eta();
1369 }
1370
1371
1372 inline bool cmpMomByDescEta(const FourMomentum& a, const FourMomentum& b) {
1373 return a.pseudorapidity() > b.pseudorapidity();
1374 }
1375
1376
1377 inline bool cmpMomByAbsEta(const FourMomentum& a, const FourMomentum& b) {
1378 return fabs(a.eta()) < fabs(b.eta());
1379 }
1380
1381
1382 inline bool cmpMomByDescAbsEta(const FourMomentum& a, const FourMomentum& b) {
1383 return fabs(a.eta()) > fabs(b.eta());
1384 }
1385
1386
1387 inline bool cmpMomByRap(const FourMomentum& a, const FourMomentum& b) {
1388 return a.rapidity() < b.rapidity();
1389 }
1390
1391
1392 inline bool cmpMomByDescRap(const FourMomentum& a, const FourMomentum& b) {
1393 return a.rapidity() > b.rapidity();
1394 }
1395
1396
1397 inline bool cmpMomByAbsRap(const FourMomentum& a, const FourMomentum& b) {
1398 return fabs(a.rapidity()) < fabs(b.rapidity());
1399 }
1400
1401
1402 inline bool cmpMomByDescAbsRap(const FourMomentum& a, const FourMomentum& b) {
1403 return fabs(a.rapidity()) > fabs(b.rapidity());
1404 }
1405
1406
1407
1408
1409
1410 template<typename MOMS, typename CMP>
1411 inline MOMS& isortBy(MOMS& pbs, const CMP& cmp) {
1412 std::sort(pbs.begin(), pbs.end(), cmp);
1413 return pbs;
1414 }
1415
1416 template<typename MOMS, typename CMP>
1417 inline MOMS sortBy(const MOMS& pbs, const CMP& cmp) {
1418 MOMS rtn = pbs;
1419 std::sort(rtn.begin(), rtn.end(), cmp);
1420 return rtn;
1421 }
1422
1423
1424 template<typename MOMS>
1425 inline MOMS& isortByPt(MOMS& pbs) {
1426 return isortBy(pbs, cmpMomByPt);
1427 }
1428
1429 template<typename MOMS>
1430 inline MOMS sortByPt(const MOMS& pbs) {
1431 return sortBy(pbs, cmpMomByPt);
1432 }
1433
1434
1435 template<typename MOMS>
1436 inline MOMS& isortByE(MOMS& pbs) {
1437 return isortBy(pbs, cmpMomByE);
1438 }
1439
1440 template<typename MOMS>
1441 inline MOMS sortByE(const MOMS& pbs) {
1442 return sortBy(pbs, cmpMomByE);
1443 }
1444
1445
1446 template<typename MOMS>
1447 inline MOMS& isortByEt(MOMS& pbs) {
1448 return isortBy(pbs, cmpMomByEt);
1449 }
1450
1451 template<typename MOMS>
1452 inline MOMS sortByEt(const MOMS& pbs) {
1453 return sortBy(pbs, cmpMomByEt);
1454 }
1455
1456
1457
1458
1459
1460
1461
1462
1463 inline double mass(const FourMomentum& a, const FourMomentum& b) {
1464 return (a + b).mass();
1465 }
1466
1467
1468 inline double mass2(const FourMomentum& a, const FourMomentum& b) {
1469 return (a + b).mass2();
1470 }
1471
1472
1473
1474
1475
1476 inline double mT(const FourMomentum& vis, const FourMomentum& invis) {
1477 return mT(vis.p3(), invis.p3());
1478 }
1479
1480
1481
1482
1483
1484 inline double mT(const FourMomentum& vis, const Vector3& invis) {
1485 return mT(vis.p3(), invis);
1486 }
1487
1488
1489
1490
1491
1492 inline double mT(const Vector3& vis, const FourMomentum& invis) {
1493 return mT(vis, invis.p3());
1494 }
1495
1496
1497 inline double pT(const FourMomentum& vis, const FourMomentum& invis) {
1498 return pT(vis.p3(), invis.p3());
1499 }
1500
1501
1502 inline double pT(const FourMomentum& vis, const Vector3& invis) {
1503 return pT(vis.p3(), invis);
1504 }
1505
1506
1507 inline double pT(const Vector3& vis, const FourMomentum& invis) {
1508 return pT(vis, invis.p3());
1509 }
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521 inline std::string toString(const FourVector& lv) {
1522 std::ostringstream out;
1523 out << "(" << (fabs(lv.t()) < 1E-30 ? 0.0 : lv.t())
1524 << "; " << (fabs(lv.x()) < 1E-30 ? 0.0 : lv.x())
1525 << ", " << (fabs(lv.y()) < 1E-30 ? 0.0 : lv.y())
1526 << ", " << (fabs(lv.z()) < 1E-30 ? 0.0 : lv.z())
1527 << ")";
1528 return out.str();
1529 }
1530
1531
1532 inline std::ostream& operator<<(std::ostream& out, const FourVector& lv) {
1533 out << toString(lv);
1534 return out;
1535 }
1536
1537
1538
1539
1540
1541 typedef std::vector<FourVector> FourVectors;
1542 typedef std::vector<FourMomentum> FourMomenta;
1543
1544
1545
1546
1547
1548 }
1549
1550 #endif