Vector4.hh
Go to the documentation of this file.
00001 #ifndef RIVET_MATH_VECTOR4 00002 #define RIVET_MATH_VECTOR4 00003 00004 #include "Rivet/Math/MathHeader.hh" 00005 #include "Rivet/Math/MathUtils.hh" 00006 #include "Rivet/Math/VectorN.hh" 00007 #include "Rivet/Math/Vector3.hh" 00008 00009 namespace Rivet { 00010 00011 00012 class FourVector; 00013 class FourMomentum; 00014 class LorentzTransform; 00015 typedef FourVector Vector4; 00016 FourVector transform(const LorentzTransform& lt, const FourVector& v4); 00017 00018 00019 /// @brief Specialisation of VectorN to a general (non-momentum) Lorentz 4-vector. 00020 class FourVector : public Vector<4> { 00021 friend FourVector multiply(const double a, const FourVector& v); 00022 friend FourVector multiply(const FourVector& v, const double a); 00023 friend FourVector add(const FourVector& a, const FourVector& b); 00024 friend FourVector transform(const LorentzTransform& lt, const FourVector& v4); 00025 00026 public: 00027 00028 FourVector() : Vector<4>() { } 00029 00030 template<typename V4> 00031 FourVector(const V4& other) { 00032 this->setT(other.t()); 00033 this->setX(other.x()); 00034 this->setY(other.y()); 00035 this->setZ(other.z()); 00036 } 00037 00038 FourVector(const Vector<4>& other) 00039 : Vector<4>(other) { } 00040 00041 FourVector(const double t, const double x, const double y, const double z) { 00042 this->setT(t); 00043 this->setX(x); 00044 this->setY(y); 00045 this->setZ(z); 00046 } 00047 00048 virtual ~FourVector() { } 00049 00050 public: 00051 00052 double t() const { return get(0); } 00053 double x() const { return get(1); } 00054 double y() const { return get(2); } 00055 double z() const { return get(3); } 00056 FourVector& setT(const double t) { set(0, t); return *this; } 00057 FourVector& setX(const double x) { set(1, x); return *this; } 00058 FourVector& setY(const double y) { set(2, y); return *this; } 00059 FourVector& setZ(const double z) { set(3, z); return *this; } 00060 00061 double invariant() const { 00062 // Done this way for numerical precision 00063 return (t() + z())*(t() - z()) - x()*x() - y()*y(); 00064 } 00065 00066 /// Angle between this vector and another 00067 double angle(const FourVector& v) const { 00068 return vector3().angle( v.vector3() ); 00069 } 00070 00071 /// Angle between this vector and another (3-vector) 00072 double angle(const Vector3& v3) const { 00073 return vector3().angle(v3); 00074 } 00075 00076 /// @brief Square of the projection of the 3-vector on to the \f$ x-y \f$ plane 00077 /// This is a more efficient function than @c polarRadius, as it avoids the square root. 00078 /// Use it if you only need the squared value, or e.g. an ordering by magnitude. 00079 double polarRadius2() const { 00080 return vector3().polarRadius2(); 00081 } 00082 00083 /// Synonym for polarRadius2 00084 double perp2() const { 00085 return vector3().perp2(); 00086 } 00087 00088 /// Synonym for polarRadius2 00089 double rho2() const { 00090 return vector3().rho2(); 00091 } 00092 00093 /// Projection of 3-vector on to the \f$ x-y \f$ plane 00094 double polarRadius() const { 00095 return vector3().polarRadius(); 00096 } 00097 00098 /// Synonym for polarRadius 00099 double perp() const { 00100 return vector3().perp(); 00101 } 00102 00103 /// Synonym for polarRadius 00104 double rho() const { 00105 return vector3().rho(); 00106 } 00107 00108 /// Angle subtended by the 3-vector's projection in x-y and the x-axis. 00109 double azimuthalAngle(const PhiMapping mapping=ZERO_2PI) const { 00110 return vector3().azimuthalAngle(mapping); 00111 } 00112 00113 /// Synonym for azimuthalAngle. 00114 double phi(const PhiMapping mapping=ZERO_2PI) const { 00115 return vector3().phi(mapping); 00116 } 00117 00118 /// Angle subtended by the 3-vector and the z-axis. 00119 double polarAngle() const { 00120 return vector3().polarAngle(); 00121 } 00122 00123 /// Synonym for polarAngle. 00124 double theta() const { 00125 return vector3().theta(); 00126 } 00127 00128 /// Pseudorapidity (defined purely by the 3-vector components) 00129 double pseudorapidity() const { 00130 return vector3().pseudorapidity(); 00131 } 00132 00133 /// Synonym for pseudorapidity. 00134 double eta() const { 00135 return vector3().eta(); 00136 } 00137 00138 /// Get the \f$ |\eta| \f$ directly. 00139 double abspseudorapidity() const { return fabs(eta()); } 00140 00141 /// Get the \f$ |\eta| \f$ directly (alias). 00142 double abseta() const { return fabs(eta()); } 00143 00144 /// Get the spatial part of the 4-vector as a 3-vector. 00145 Vector3 vector3() const { 00146 return Vector3(get(1), get(2), get(3)); 00147 } 00148 00149 00150 public: 00151 00152 /// Contract two 4-vectors, with metric signature (+ - - -). 00153 double contract(const FourVector& v) const { 00154 const double result = t()*v.t() - x()*v.x() - y()*v.y() - z()*v.z(); 00155 return result; 00156 } 00157 00158 /// Contract two 4-vectors, with metric signature (+ - - -). 00159 double dot(const FourVector& v) const { 00160 return contract(v); 00161 } 00162 00163 /// Contract two 4-vectors, with metric signature (+ - - -). 00164 double operator*(const FourVector& v) const { 00165 return contract(v); 00166 } 00167 00168 /// Multiply by a scalar. 00169 FourVector& operator*=(double a) { 00170 _vec = multiply(a, *this)._vec; 00171 return *this; 00172 } 00173 00174 /// Divide by a scalar. 00175 FourVector& operator/=(double a) { 00176 _vec = multiply(1.0/a, *this)._vec; 00177 return *this; 00178 } 00179 00180 /// Add to this 4-vector. 00181 FourVector& operator+=(const FourVector& v) { 00182 _vec = add(*this, v)._vec; 00183 return *this; 00184 } 00185 00186 /// Subtract from this 4-vector. NB time as well as space components are subtracted. 00187 FourVector& operator-=(const FourVector& v) { 00188 _vec = add(*this, -v)._vec; 00189 return *this; 00190 } 00191 00192 /// Multiply all components (space and time) by -1. 00193 FourVector operator-() const { 00194 FourVector result; 00195 result._vec = -_vec; 00196 return result; 00197 } 00198 00199 }; 00200 00201 00202 /// Contract two 4-vectors, with metric signature (+ - - -). 00203 inline double contract(const FourVector& a, const FourVector& b) { 00204 return a.contract(b); 00205 } 00206 00207 /// Contract two 4-vectors, with metric signature (+ - - -). 00208 inline double dot(const FourVector& a, const FourVector& b) { 00209 return contract(a, b); 00210 } 00211 00212 inline FourVector multiply(const double a, const FourVector& v) { 00213 FourVector result; 00214 result._vec = a * v._vec; 00215 return result; 00216 } 00217 00218 inline FourVector multiply(const FourVector& v, const double a) { 00219 return multiply(a, v); 00220 } 00221 00222 inline FourVector operator*(const double a, const FourVector& v) { 00223 return multiply(a, v); 00224 } 00225 00226 inline FourVector operator*(const FourVector& v, const double a) { 00227 return multiply(a, v); 00228 } 00229 00230 inline FourVector operator/(const FourVector& v, const double a) { 00231 return multiply(1.0/a, v); 00232 } 00233 00234 inline FourVector add(const FourVector& a, const FourVector& b) { 00235 FourVector result; 00236 result._vec = a._vec + b._vec; 00237 return result; 00238 } 00239 00240 inline FourVector operator+(const FourVector& a, const FourVector& b) { 00241 return add(a, b); 00242 } 00243 00244 inline FourVector operator-(const FourVector& a, const FourVector& b) { 00245 return add(a, -b); 00246 } 00247 00248 /// Calculate the Lorentz self-invariant of a 4-vector. 00249 /// \f$ v_\mu v^\mu = g_{\mu\nu} x^\mu x^\nu \f$. 00250 inline double invariant(const FourVector& lv) { 00251 return lv.invariant(); 00252 } 00253 00254 /// Angle (in radians) between spatial parts of two Lorentz vectors. 00255 inline double angle(const FourVector& a, const FourVector& b) { 00256 return a.angle(b); 00257 } 00258 00259 /// Angle (in radians) between spatial parts of two Lorentz vectors. 00260 inline double angle(const Vector3& a, const FourVector& b) { 00261 return angle( a, b.vector3() ); 00262 } 00263 00264 /// Angle (in radians) between spatial parts of two Lorentz vectors. 00265 inline double angle(const FourVector& a, const Vector3& b) { 00266 return a.angle(b); 00267 } 00268 00269 00270 //////////////////////////////////////////////// 00271 00272 00273 /// Specialized version of the FourVector with momentum/energy functionality. 00274 class FourMomentum : public FourVector { 00275 friend FourMomentum multiply(const double a, const FourMomentum& v); 00276 friend FourMomentum multiply(const FourMomentum& v, const double a); 00277 friend FourMomentum add(const FourMomentum& a, const FourMomentum& b); 00278 friend FourMomentum transform(const LorentzTransform& lt, const FourMomentum& v4); 00279 00280 public: 00281 FourMomentum() { } 00282 00283 template<typename V4> 00284 FourMomentum(const V4& other) { 00285 this->setE(other.t()); 00286 this->setPx(other.x()); 00287 this->setPy(other.y()); 00288 this->setPz(other.z()); 00289 } 00290 00291 FourMomentum(const Vector<4>& other) 00292 : FourVector(other) { } 00293 00294 FourMomentum(const double E, const double px, const double py, const double pz) { 00295 this->setE(E); 00296 this->setPx(px); 00297 this->setPy(py); 00298 this->setPz(pz); 00299 } 00300 00301 ~FourMomentum() {} 00302 00303 public: 00304 /// Get energy \f$ E \f$ (time component of momentum). 00305 double E() const { return t(); } 00306 00307 /// Get 3-momentum part, \f$ p \f$. 00308 Vector3 p3() const { return vector3(); } 00309 /// Get 3-momentum part, \f$ p \f$ (alias). 00310 // Vector3 p() const { return vector3(); } 00311 00312 /// Get x-component of momentum \f$ p_x \f$. 00313 double px() const { return x(); } 00314 00315 /// Get y-component of momentum \f$ p_y \f$. 00316 double py() const { return y(); } 00317 00318 /// Get z-component of momentum \f$ p_z \f$. 00319 double pz() const { return z(); } 00320 00321 /// Set energy \f$ E \f$ (time component of momentum). 00322 FourMomentum& setE(double E) { setT(E); return *this; } 00323 00324 /// Set x-component of momentum \f$ p_x \f$. 00325 FourMomentum& setPx(double px) { setX(px); return *this; } 00326 00327 /// Set y-component of momentum \f$ p_y \f$. 00328 FourMomentum& setPy(double py) { setY(py); return *this; } 00329 00330 /// Set z-component of momentum \f$ p_z \f$. 00331 FourMomentum& setPz(double pz) { setZ(pz); return *this; } 00332 00333 /// @brief Get the mass \f$ m = \sqrt{E^2 - p^2} \f$ (the Lorentz self-invariant). 00334 /// 00335 /// For spacelike momenta, the mass will be -sqrt(|mass2|). 00336 double mass() const { 00337 // assert(Rivet::isZero(mass2()) || mass2() > 0); 00338 // if (Rivet::isZero(mass2())) { 00339 // return 0.0; 00340 // } else { 00341 // return sqrt(mass2()); 00342 // } 00343 return sign(mass2()) * sqrt(fabs(mass2())); 00344 } 00345 00346 /// Get the squared mass \f$ m^2 = E^2 - p^2 \f$ (the Lorentz self-invariant). 00347 double mass2() const { 00348 return invariant(); 00349 } 00350 00351 /// Calculate the rapidity. 00352 double rapidity() const { 00353 return 0.5 * std::log( (E() + pz()) / (E() - pz()) ); 00354 } 00355 00356 /// Alias for rapidity. 00357 double rap() const { 00358 return rapidity(); 00359 } 00360 00361 /// Absolute rapidity. 00362 double absrapidity() const { 00363 return fabs(rapidity()); 00364 } 00365 00366 /// Absolute rapidity. 00367 double absrap() const { 00368 return fabs(rap()); 00369 } 00370 00371 /// Calculate the squared transverse momentum \f$ p_T^2 \f$. 00372 double pT2() const { 00373 return vector3().polarRadius2(); 00374 } 00375 00376 /// Calculate the squared transverse momentum \f$ p_T^2 \f$. 00377 double pt2() const { 00378 return vector3().polarRadius2(); 00379 } 00380 00381 /// Calculate the transverse momentum \f$ p_T \f$. 00382 double pT() const { 00383 return sqrt(pT2()); 00384 } 00385 00386 /// Calculate the transverse momentum \f$ p_T \f$. 00387 double pt() const { 00388 return sqrt(pT2()); 00389 } 00390 00391 /// Calculate the transverse energy \f$ E_T^2 = E^2 \sin^2{\theta} \f$. 00392 double Et2() const { 00393 return Et() * Et(); 00394 } 00395 00396 /// Calculate the transverse energy \f$ E_T = E \sin{\theta} \f$. 00397 double Et() const { 00398 return E() * sin(polarAngle()); 00399 } 00400 00401 /// Calculate the boost vector (in units of \f$ \beta \f$). 00402 Vector3 boostVector() const { 00403 // const Vector3 p3 = vector3(); 00404 // const double m2 = mass2(); 00405 // if (Rivet::isZero(m2)) return p3.unit(); 00406 // else { 00407 // // Could also do this via beta = tanh(rapidity), but that's 00408 // // probably more messy from a numerical hygiene point of view. 00409 // const double p2 = p3.mod2(); 00410 // const double beta = sqrt( p2 / (m2 + p2) ); 00411 // return beta * p3.unit(); 00412 // } 00413 /// @todo Be careful about c=1 convention... 00414 return Vector3(px()/E(), py()/E(), pz()/E()); 00415 } 00416 00417 /// Struct for sorting by increasing energy 00418 struct byEAscending { 00419 bool operator()(const FourMomentum& left, const FourMomentum& right) const{ 00420 double pt2left = left.E(); 00421 double pt2right = right.E(); 00422 return pt2left < pt2right; 00423 } 00424 00425 bool operator()(const FourMomentum* left, const FourMomentum* right) const{ 00426 return (*this)(left, right); 00427 } 00428 }; 00429 00430 /// Struct for sorting by decreasing energy 00431 struct byEDescending { 00432 bool operator()(const FourMomentum& left, const FourMomentum& right) const{ 00433 return byEAscending()(right, left); 00434 } 00435 00436 bool operator()(const FourMomentum* left, const FourVector* right) const{ 00437 return (*this)(left, right); 00438 } 00439 }; 00440 00441 00442 /// Multiply by a scalar 00443 FourMomentum& operator*=(double a) { 00444 _vec = multiply(a, *this)._vec; 00445 return *this; 00446 } 00447 00448 /// Divide by a scalar 00449 FourMomentum& operator/=(double a) { 00450 _vec = multiply(1.0/a, *this)._vec; 00451 return *this; 00452 } 00453 00454 /// Add to this 4-vector. NB time as well as space components are added. 00455 FourMomentum& operator+=(const FourMomentum& v) { 00456 _vec = add(*this, v)._vec; 00457 return *this; 00458 } 00459 00460 /// Subtract from this 4-vector. NB time as well as space components are subtracted. 00461 FourMomentum& operator-=(const FourMomentum& v) { 00462 _vec = add(*this, -v)._vec; 00463 return *this; 00464 } 00465 00466 /// Multiply all components (time and space) by -1. 00467 FourMomentum operator-() const { 00468 FourMomentum result; 00469 result._vec = -_vec; 00470 return result; 00471 } 00472 00473 00474 }; 00475 00476 00477 inline FourMomentum multiply(const double a, const FourMomentum& v) { 00478 FourMomentum result; 00479 result._vec = a * v._vec; 00480 return result; 00481 } 00482 00483 inline FourMomentum multiply(const FourMomentum& v, const double a) { 00484 return multiply(a, v); 00485 } 00486 00487 inline FourMomentum operator*(const double a, const FourMomentum& v) { 00488 return multiply(a, v); 00489 } 00490 00491 inline FourMomentum operator*(const FourMomentum& v, const double a) { 00492 return multiply(a, v); 00493 } 00494 00495 inline FourMomentum operator/(const FourMomentum& v, const double a) { 00496 return multiply(1.0/a, v); 00497 } 00498 00499 inline FourMomentum add(const FourMomentum& a, const FourMomentum& b) { 00500 FourMomentum result; 00501 result._vec = a._vec + b._vec; 00502 return result; 00503 } 00504 00505 inline FourMomentum operator+(const FourMomentum& a, const FourMomentum& b) { 00506 return add(a, b); 00507 } 00508 00509 inline FourMomentum operator-(const FourMomentum& a, const FourMomentum& b) { 00510 return add(a, -b); 00511 } 00512 00513 00514 ////////////////////////////////////////////////////// 00515 00516 00517 /// @name \f$ \Delta R \f$ calculations from 4-vectors 00518 //@{ 00519 00520 /// @brief Calculate the 2D rapidity-azimuthal ("eta-phi") distance between two four-vectors. 00521 /// There is a scheme ambiguity for momentum-type four vectors as to whether 00522 /// the pseudorapidity (a purely geometric concept) or the rapidity (a 00523 /// relativistic energy-momentum quantity) is to be used: this can be chosen 00524 /// via the optional scheme parameter. Use of this scheme option is 00525 /// discouraged in this case since @c RAPIDITY is only a valid option for 00526 /// vectors whose type is really the FourMomentum derived class. 00527 inline double deltaR(const FourVector& a, const FourVector& b, 00528 RapScheme scheme = PSEUDORAPIDITY) { 00529 switch (scheme) { 00530 case PSEUDORAPIDITY : 00531 return deltaR(a.vector3(), b.vector3()); 00532 case RAPIDITY: 00533 { 00534 const FourMomentum* ma = dynamic_cast<const FourMomentum*>(&a); 00535 const FourMomentum* mb = dynamic_cast<const FourMomentum*>(&b); 00536 if (!ma || !mb) { 00537 string err = "deltaR with scheme RAPIDITY can only be called with FourMomentum objects, not FourVectors"; 00538 throw std::runtime_error(err); 00539 } 00540 return deltaR(*ma, *mb, scheme); 00541 } 00542 default: 00543 throw std::runtime_error("The specified deltaR scheme is not yet implemented"); 00544 } 00545 } 00546 00547 00548 /// @brief Calculate the 2D rapidity-azimuthal ("eta-phi") distance between two four-vectors. 00549 /// There is a scheme ambiguity for momentum-type four vectors 00550 /// as to whether the pseudorapidity (a purely geometric concept) or the 00551 /// rapidity (a relativistic energy-momentum quantity) is to be used: this can 00552 /// be chosen via the optional scheme parameter. 00553 inline double deltaR(const FourVector& v, 00554 double eta2, double phi2, 00555 RapScheme scheme = PSEUDORAPIDITY) { 00556 switch (scheme) { 00557 case PSEUDORAPIDITY : 00558 return deltaR(v.vector3(), eta2, phi2); 00559 case RAPIDITY: 00560 { 00561 const FourMomentum* mv = dynamic_cast<const FourMomentum*>(&v); 00562 if (!mv) { 00563 string err = "deltaR with scheme RAPIDITY can only be called with FourMomentum objects, not FourVectors"; 00564 throw std::runtime_error(err); 00565 } 00566 return deltaR(*mv, eta2, phi2, scheme); 00567 } 00568 default: 00569 throw std::runtime_error("The specified deltaR scheme is not yet implemented"); 00570 } 00571 } 00572 00573 00574 /// @brief Calculate the 2D rapidity-azimuthal ("eta-phi") distance between two four-vectors. 00575 /// There is a scheme ambiguity for momentum-type four vectors 00576 /// as to whether the pseudorapidity (a purely geometric concept) or the 00577 /// rapidity (a relativistic energy-momentum quantity) is to be used: this can 00578 /// be chosen via the optional scheme parameter. 00579 inline double deltaR(double eta1, double phi1, 00580 const FourVector& v, 00581 RapScheme scheme = PSEUDORAPIDITY) { 00582 switch (scheme) { 00583 case PSEUDORAPIDITY : 00584 return deltaR(eta1, phi1, v.vector3()); 00585 case RAPIDITY: 00586 { 00587 const FourMomentum* mv = dynamic_cast<const FourMomentum*>(&v); 00588 if (!mv) { 00589 string err = "deltaR with scheme RAPIDITY can only be called with FourMomentum objects, not FourVectors"; 00590 throw std::runtime_error(err); 00591 } 00592 return deltaR(eta1, phi1, *mv, scheme); 00593 } 00594 default: 00595 throw std::runtime_error("The specified deltaR scheme is not yet implemented"); 00596 } 00597 } 00598 00599 00600 /// @brief Calculate the 2D rapidity-azimuthal ("eta-phi") distance between two four-vectors. 00601 /// There is a scheme ambiguity for momentum-type four vectors 00602 /// as to whether the pseudorapidity (a purely geometric concept) or the 00603 /// rapidity (a relativistic energy-momentum quantity) is to be used: this can 00604 /// be chosen via the optional scheme parameter. 00605 inline double deltaR(const FourMomentum& a, const FourMomentum& b, 00606 RapScheme scheme = PSEUDORAPIDITY) { 00607 switch (scheme) { 00608 case PSEUDORAPIDITY: 00609 return deltaR(a.vector3(), b.vector3()); 00610 case RAPIDITY: 00611 return deltaR(a.rapidity(), a.azimuthalAngle(), b.rapidity(), b.azimuthalAngle()); 00612 default: 00613 throw std::runtime_error("The specified deltaR scheme is not yet implemented"); 00614 } 00615 } 00616 00617 /// @brief Calculate the 2D rapidity-azimuthal ("eta-phi") distance between two four-vectors. 00618 /// There is a scheme ambiguity for momentum-type four vectors 00619 /// as to whether the pseudorapidity (a purely geometric concept) or the 00620 /// rapidity (a relativistic energy-momentum quantity) is to be used: this can 00621 /// be chosen via the optional scheme parameter. 00622 inline double deltaR(const FourMomentum& v, 00623 double eta2, double phi2, 00624 RapScheme scheme = PSEUDORAPIDITY) { 00625 switch (scheme) { 00626 case PSEUDORAPIDITY: 00627 return deltaR(v.vector3(), eta2, phi2); 00628 case RAPIDITY: 00629 return deltaR(v.rapidity(), v.azimuthalAngle(), eta2, phi2); 00630 default: 00631 throw std::runtime_error("The specified deltaR scheme is not yet implemented"); 00632 } 00633 } 00634 00635 00636 /// @brief Calculate the 2D rapidity-azimuthal ("eta-phi") distance between two four-vectors. 00637 /// There is a scheme ambiguity for momentum-type four vectors 00638 /// as to whether the pseudorapidity (a purely geometric concept) or the 00639 /// rapidity (a relativistic energy-momentum quantity) is to be used: this can 00640 /// be chosen via the optional scheme parameter. 00641 inline double deltaR(double eta1, double phi1, 00642 const FourMomentum& v, 00643 RapScheme scheme = PSEUDORAPIDITY) { 00644 switch (scheme) { 00645 case PSEUDORAPIDITY: 00646 return deltaR(eta1, phi1, v.vector3()); 00647 case RAPIDITY: 00648 return deltaR(eta1, phi1, v.rapidity(), v.azimuthalAngle()); 00649 default: 00650 throw std::runtime_error("The specified deltaR scheme is not yet implemented"); 00651 } 00652 } 00653 00654 /// @brief Calculate the 2D rapidity-azimuthal ("eta-phi") distance between two four-vectors. 00655 /// There is a scheme ambiguity for momentum-type four vectors 00656 /// as to whether the pseudorapidity (a purely geometric concept) or the 00657 /// rapidity (a relativistic energy-momentum quantity) is to be used: this can 00658 /// be chosen via the optional scheme parameter. 00659 inline double deltaR(const FourMomentum& a, const FourVector& b, 00660 RapScheme scheme = PSEUDORAPIDITY) { 00661 switch (scheme) { 00662 case PSEUDORAPIDITY: 00663 return deltaR(a.vector3(), b.vector3()); 00664 case RAPIDITY: 00665 return deltaR(a.rapidity(), a.azimuthalAngle(), FourMomentum(b).rapidity(), b.azimuthalAngle()); 00666 default: 00667 throw std::runtime_error("The specified deltaR scheme is not yet implemented"); 00668 } 00669 } 00670 00671 /// @brief Calculate the 2D rapidity-azimuthal ("eta-phi") distance between two four-vectors. 00672 /// There is a scheme ambiguity for momentum-type four vectors 00673 /// as to whether the pseudorapidity (a purely geometric concept) or the 00674 /// rapidity (a relativistic energy-momentum quantity) is to be used: this can 00675 /// be chosen via the optional scheme parameter. 00676 inline double deltaR(const FourVector& a, const FourMomentum& b, 00677 RapScheme scheme = PSEUDORAPIDITY) { 00678 return deltaR(b, a, scheme); 00679 } 00680 00681 /// @brief Calculate the 2D rapidity-azimuthal ("eta-phi") distance between a 00682 /// three-vector and a four-vector. 00683 inline double deltaR(const FourMomentum& a, const Vector3& b) { 00684 return deltaR(a.vector3(), b); 00685 } 00686 00687 /// @brief Calculate the 2D rapidity-azimuthal ("eta-phi") distance between a 00688 /// three-vector and a four-vector. 00689 inline double deltaR(const Vector3& a, const FourMomentum& b) { 00690 return deltaR(a, b.vector3()); 00691 } 00692 00693 /// @brief Calculate the 2D rapidity-azimuthal ("eta-phi") distance between a 00694 /// three-vector and a four-vector. 00695 inline double deltaR(const FourVector& a, const Vector3& b) { 00696 return deltaR(a.vector3(), b); 00697 } 00698 00699 /// @brief Calculate the 2D rapidity-azimuthal ("eta-phi") distance between a 00700 /// three-vector and a four-vector. 00701 inline double deltaR(const Vector3& a, const FourVector& b) { 00702 return deltaR(a, b.vector3()); 00703 } 00704 00705 //@} 00706 00707 00708 ////////////////////////////////////////////////////// 00709 00710 00711 /// @name \f$ \Delta phi \f$ calculations from 4-vectors 00712 //@{ 00713 00714 /// Calculate the difference in azimuthal angle between two vectors. 00715 inline double deltaPhi(const FourMomentum& a, const FourMomentum& b) { 00716 return deltaPhi(a.vector3(), b.vector3()); 00717 } 00718 00719 /// Calculate the difference in azimuthal angle between two vectors. 00720 inline double deltaPhi(const FourMomentum& v, double phi2) { 00721 return deltaPhi(v.vector3(), phi2); 00722 } 00723 00724 /// Calculate the difference in azimuthal angle between two vectors. 00725 inline double deltaPhi(double phi1, const FourMomentum& v) { 00726 return deltaPhi(phi1, v.vector3()); 00727 } 00728 00729 /// Calculate the difference in azimuthal angle between two vectors. 00730 inline double deltaPhi(const FourVector& a, const FourVector& b) { 00731 return deltaPhi(a.vector3(), b.vector3()); 00732 } 00733 00734 /// Calculate the difference in azimuthal angle between two vectors. 00735 inline double deltaPhi(const FourVector& v, double phi2) { 00736 return deltaPhi(v.vector3(), phi2); 00737 } 00738 00739 /// Calculate the difference in azimuthal angle between two vectors. 00740 inline double deltaPhi(double phi1, const FourVector& v) { 00741 return deltaPhi(phi1, v.vector3()); 00742 } 00743 00744 /// Calculate the difference in azimuthal angle between two vectors. 00745 inline double deltaPhi(const FourVector& a, const FourMomentum& b) { 00746 return deltaPhi(a.vector3(), b.vector3()); 00747 } 00748 00749 /// Calculate the difference in azimuthal angle between two vectors. 00750 inline double deltaPhi(const FourMomentum& a, const FourVector& b) { 00751 return deltaPhi(a.vector3(), b.vector3()); 00752 } 00753 00754 /// Calculate the difference in azimuthal angle between two vectors. 00755 inline double deltaPhi(const FourVector& a, const Vector3& b) { 00756 return deltaPhi(a.vector3(), b); 00757 } 00758 00759 /// Calculate the difference in azimuthal angle between two vectors. 00760 inline double deltaPhi(const Vector3& a, const FourVector& b) { 00761 return deltaPhi(a, b.vector3()); 00762 } 00763 00764 /// Calculate the difference in azimuthal angle between two vectors. 00765 inline double deltaPhi(const FourMomentum& a, const Vector3& b) { 00766 return deltaPhi(a.vector3(), b); 00767 } 00768 00769 /// Calculate the difference in azimuthal angle between two vectors. 00770 inline double deltaPhi(const Vector3& a, const FourMomentum& b) { 00771 return deltaPhi(a, b.vector3()); 00772 } 00773 00774 //@} 00775 00776 00777 ////////////////////////////////////////////////////// 00778 00779 00780 /// @name \f$ |\Delta eta| \f$ calculations from 4-vectors 00781 //@{ 00782 00783 /// Calculate the difference in pseudorapidity between two vectors. 00784 inline double deltaEta(const FourMomentum& a, const FourMomentum& b) { 00785 return deltaEta(a.vector3(), b.vector3()); 00786 } 00787 00788 /// Calculate the difference in pseudorapidity between two vectors. 00789 inline double deltaEta(const FourMomentum& v, double eta2) { 00790 return deltaEta(v.vector3(), eta2); 00791 } 00792 00793 /// Calculate the difference in pseudorapidity between two vectors. 00794 inline double deltaEta(double eta1, const FourMomentum& v) { 00795 return deltaEta(eta1, v.vector3()); 00796 } 00797 00798 /// Calculate the difference in pseudorapidity between two vectors. 00799 inline double deltaEta(const FourVector& a, const FourVector& b) { 00800 return deltaEta(a.vector3(), b.vector3()); 00801 } 00802 00803 /// Calculate the difference in pseudorapidity between two vectors. 00804 inline double deltaEta(const FourVector& v, double eta2) { 00805 return deltaEta(v.vector3(), eta2); 00806 } 00807 00808 /// Calculate the difference in pseudorapidity between two vectors. 00809 inline double deltaEta(double eta1, const FourVector& v) { 00810 return deltaEta(eta1, v.vector3()); 00811 } 00812 00813 /// Calculate the difference in pseudorapidity between two vectors. 00814 inline double deltaEta(const FourVector& a, const FourMomentum& b) { 00815 return deltaEta(a.vector3(), b.vector3()); 00816 } 00817 00818 /// Calculate the difference in pseudorapidity between two vectors. 00819 inline double deltaEta(const FourMomentum& a, const FourVector& b) { 00820 return deltaEta(a.vector3(), b.vector3()); 00821 } 00822 00823 /// Calculate the difference in pseudorapidity between two vectors. 00824 inline double deltaEta(const FourVector& a, const Vector3& b) { 00825 return deltaEta(a.vector3(), b); 00826 } 00827 00828 /// Calculate the difference in pseudorapidity between two vectors. 00829 inline double deltaEta(const Vector3& a, const FourVector& b) { 00830 return deltaEta(a, b.vector3()); 00831 } 00832 00833 /// Calculate the difference in pseudorapidity between two vectors. 00834 inline double deltaEta(const FourMomentum& a, const Vector3& b) { 00835 return deltaEta(a.vector3(), b); 00836 } 00837 00838 /// Calculate the difference in pseudorapidity between two vectors. 00839 inline double deltaEta(const Vector3& a, const FourMomentum& b) { 00840 return deltaEta(a, b.vector3()); 00841 } 00842 00843 //@} 00844 00845 00846 /// @name \f$ |\Delta y| \f$ calculations from 4-momentum vectors 00847 //@{ 00848 00849 /// Calculate the difference in rapidity between two 4-momentum vectors. 00850 inline double deltaRap(const FourMomentum& a, const FourMomentum& b) { 00851 return deltaRap(a.rapidity(), b.rapidity()); 00852 } 00853 00854 /// Calculate the difference in rapidity between two 4-momentum vectors. 00855 inline double deltaRap(const FourMomentum& v, double y2) { 00856 return deltaRap(v.rapidity(), y2); 00857 } 00858 00859 /// Calculate the difference in rapidity between two 4-momentum vectors. 00860 inline double deltaRap(double y1, const FourMomentum& v) { 00861 return deltaRap(y1, v.rapidity()); 00862 } 00863 00864 //@} 00865 00866 00867 ////////////////////////////////////////////////////// 00868 00869 00870 /// @name 4-vector comparison functions (for sorting) 00871 //@{ 00872 00873 /// Comparison to give a sorting by decreasing pT 00874 inline bool cmpMomByPt(const FourMomentum& a, const FourMomentum& b) { 00875 return a.pt() > b.pt(); 00876 } 00877 /// Comparison to give a sorting by increasing pT 00878 inline bool cmpMomByAscPt(const FourMomentum& a, const FourMomentum& b) { 00879 return a.pt() < b.pt(); 00880 } 00881 00882 /// Comparison to give a sorting by decreasing 3-momentum magnitude |p| 00883 inline bool cmpMomByP(const FourMomentum& a, const FourMomentum& b) { 00884 return a.vector3().mod() > b.vector3().mod(); 00885 } 00886 /// Comparison to give a sorting by increasing 3-momentum magnitude |p| 00887 inline bool cmpMomByAscP(const FourMomentum& a, const FourMomentum& b) { 00888 return a.vector3().mod() < b.vector3().mod(); 00889 } 00890 00891 /// Comparison to give a sorting by decreasing transverse energy 00892 inline bool cmpMomByEt(const FourMomentum& a, const FourMomentum& b) { 00893 return a.Et() > b.Et(); 00894 } 00895 /// Comparison to give a sorting by increasing transverse energy 00896 inline bool cmpMomByAscEt(const FourMomentum& a, const FourMomentum& b) { 00897 return a.Et() < b.Et(); 00898 } 00899 00900 /// Comparison to give a sorting by decreasing energy 00901 inline bool cmpMomByE(const FourMomentum& a, const FourMomentum& b) { 00902 return a.E() > b.E(); 00903 } 00904 /// Comparison to give a sorting by increasing energy 00905 inline bool cmpMomByAscE(const FourMomentum& a, const FourMomentum& b) { 00906 return a.E() < b.E(); 00907 } 00908 00909 /// Comparison to give a sorting by increasing eta (pseudorapidity) 00910 inline bool cmpMomByEta(const FourMomentum& a, const FourMomentum& b) { 00911 return a.eta() < b.eta(); 00912 } 00913 /// Comparison to give a sorting by increasing eta (pseudorapidity) 00914 /// @deprecated Use cmpMomByEta 00915 inline bool cmpMomByAscPseudorapidity(const FourMomentum& a, const FourMomentum& b) { 00916 return cmpMomByEta(a,b); 00917 } 00918 00919 /// Comparison to give a sorting by decreasing eta (pseudorapidity) 00920 inline bool cmpMomByDescEta(const FourMomentum& a, const FourMomentum& b) { 00921 return a.pseudorapidity() > b.pseudorapidity(); 00922 } 00923 /// Comparison to give a sorting by decreasing eta (pseudorapidity) 00924 /// @deprecated Use cmpMomByDescEta 00925 inline bool cmpMomByDescPseudorapidity(const FourMomentum& a, const FourMomentum& b) { 00926 return cmpMomByDescEta(a,b); 00927 } 00928 00929 /// Comparison to give a sorting by increasing absolute eta (pseudorapidity) 00930 inline bool cmpMomByAbsEta(const FourMomentum& a, const FourMomentum& b) { 00931 return fabs(a.eta()) < fabs(b.eta()); 00932 } 00933 /// Comparison to give a sorting by increasing absolute eta (pseudorapidity) 00934 /// @deprecated Use cmpMomByAbsEta 00935 inline bool cmpMomByAscAbsPseudorapidity(const FourMomentum& a, const FourMomentum& b) { 00936 return cmpMomByAbsEta(a,b); 00937 } 00938 00939 /// Comparison to give a sorting by increasing absolute eta (pseudorapidity) 00940 inline bool cmpMomByDescAbsEta(const FourMomentum& a, const FourMomentum& b) { 00941 return fabs(a.eta()) > fabs(b.eta()); 00942 } 00943 /// Comparison to give a sorting by increasing absolute eta (pseudorapidity) 00944 /// @deprecated Use cmpMomByDescAbsEta 00945 inline bool cmpMomByDescAbsPseudorapidity(const FourMomentum& a, const FourMomentum& b) { 00946 return cmpMomByDescAbsEta(a,b); 00947 } 00948 00949 /// Comparison to give a sorting by increasing rapidity 00950 inline bool cmpMomByRap(const FourMomentum& a, const FourMomentum& b) { 00951 return a.rapidity() < b.rapidity(); 00952 } 00953 /// Comparison to give a sorting by increasing rapidity 00954 /// @deprecated Use cmpMomByRap 00955 inline bool cmpMomByAscRapidity(const FourMomentum& a, const FourMomentum& b) { 00956 return cmpMomByRap(a,b); 00957 } 00958 00959 /// Comparison to give a sorting by decreasing rapidity 00960 inline bool cmpMomByDescRap(const FourMomentum& a, const FourMomentum& b) { 00961 return a.rapidity() > b.rapidity(); 00962 } 00963 /// Comparison to give a sorting by decreasing rapidity 00964 /// @deprecated Use cmpMomByDescRap 00965 inline bool cmpMomByDescRapidity(const FourMomentum& a, const FourMomentum& b) { 00966 return cmpMomByDescRap(a,b); 00967 } 00968 00969 /// Comparison to give a sorting by increasing absolute rapidity 00970 inline bool cmpMomByAbsRap(const FourMomentum& a, const FourMomentum& b) { 00971 return fabs(a.rapidity()) < fabs(b.rapidity()); 00972 } 00973 /// Comparison to give a sorting by increasing absolute rapidity 00974 /// @deprecated Use cmpMomByAbsRap 00975 inline bool cmpMomByAscAbsRapidity(const FourMomentum& a, const FourMomentum& b) { 00976 return cmpMomByAbsRap(a,b); 00977 } 00978 00979 /// Comparison to give a sorting by decreasing absolute rapidity 00980 inline bool cmpMomByDescAbsRap(const FourMomentum& a, const FourMomentum& b) { 00981 return fabs(a.rapidity()) > fabs(b.rapidity()); 00982 } 00983 /// Comparison to give a sorting by decreasing absolute rapidity 00984 /// @deprecated Use cmpMomByDescAbsRap 00985 inline bool cmpMomByDescAbsRapidity(const FourMomentum& a, const FourMomentum& b) { 00986 return cmpMomByDescAbsRap(a,b); 00987 } 00988 00989 /// @todo Add sorting by phi [0..2PI] 00990 00991 00992 /// Sort a container of momenta by cmp and return by reference for non-const inputs 00993 template<typename MOMS, typename CMP> 00994 inline MOMS& sortBy(MOMS& pbs, const CMP& cmp) { 00995 std::sort(pbs.begin(), pbs.end(), cmp); 00996 return pbs; 00997 } 00998 /// Sort a container of momenta by cmp and return by value for const inputs 00999 template<typename MOMS, typename CMP> 01000 inline MOMS sortBy(const MOMS& pbs, const CMP& cmp) { 01001 MOMS rtn = pbs; 01002 std::sort(rtn.begin(), rtn.end(), cmp); 01003 return rtn; 01004 } 01005 01006 /// Sort a container of momenta by pT (decreasing) and return by reference for non-const inputs 01007 template<typename MOMS> 01008 inline MOMS& sortByPt(MOMS& pbs) { 01009 return sortBy(pbs, cmpMomByPt); 01010 } 01011 /// Sort a container of momenta by pT (decreasing) and return by value for const inputs 01012 template<typename MOMS> 01013 inline MOMS sortByPt(const MOMS& pbs) { 01014 return sortBy(pbs, cmpMomByPt); 01015 } 01016 01017 /// Sort a container of momenta by E (decreasing) and return by reference for non-const inputs 01018 template<typename MOMS> 01019 inline MOMS& sortByE(MOMS& pbs) { 01020 return sortBy(pbs, cmpMomByE); 01021 } 01022 /// Sort a container of momenta by E (decreasing) and return by value for const inputs 01023 template<typename MOMS> 01024 inline MOMS sortByE(const MOMS& pbs) { 01025 return sortBy(pbs, cmpMomByE); 01026 } 01027 01028 /// Sort a container of momenta by Et (decreasing) and return by reference for non-const inputs 01029 template<typename MOMS> 01030 inline MOMS& sortByEt(MOMS& pbs) { 01031 return sortBy(pbs, cmpMomByEt); 01032 } 01033 /// Sort a container of momenta by Et (decreasing) and return by value for const inputs 01034 template<typename MOMS> 01035 inline MOMS sortByEt(const MOMS& pbs) { 01036 return sortBy(pbs, cmpMomByEt); 01037 } 01038 01039 //@} 01040 01041 01042 ////////////////////////////////////////////////////// 01043 01044 01045 /// @name 4-vector string representations 01046 //@{ 01047 01048 /// Render a 4-vector as a string. 01049 inline std::string toString(const FourVector& lv) { 01050 ostringstream out; 01051 out << "(" << (fabs(lv.t()) < 1E-30 ? 0.0 : lv.t()) 01052 << "; " << (fabs(lv.x()) < 1E-30 ? 0.0 : lv.x()) 01053 << ", " << (fabs(lv.y()) < 1E-30 ? 0.0 : lv.y()) 01054 << ", " << (fabs(lv.z()) < 1E-30 ? 0.0 : lv.z()) 01055 << ")"; 01056 return out.str(); 01057 } 01058 01059 /// Write a 4-vector to an ostream. 01060 inline std::ostream& operator<<(std::ostream& out, const FourVector& lv) { 01061 out << toString(lv); 01062 return out; 01063 } 01064 01065 //@} 01066 01067 01068 } 01069 01070 #endif Generated on Tue Sep 30 2014 19:45:47 for The Rivet MC analysis system by ![]() |