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 /// 00021 /// @todo Add composite set/mk methods from different coord systems 00022 class FourVector : public Vector<4> { 00023 friend FourVector multiply(const double a, const FourVector& v); 00024 friend FourVector multiply(const FourVector& v, const double a); 00025 friend FourVector add(const FourVector& a, const FourVector& b); 00026 friend FourVector transform(const LorentzTransform& lt, const FourVector& v4); 00027 00028 public: 00029 00030 FourVector() : Vector<4>() { } 00031 00032 template<typename V4> 00033 FourVector(const V4& other) { 00034 this->setT(other.t()); 00035 this->setX(other.x()); 00036 this->setY(other.y()); 00037 this->setZ(other.z()); 00038 } 00039 00040 FourVector(const Vector<4>& other) 00041 : Vector<4>(other) { } 00042 00043 FourVector(const double t, const double x, const double y, const double z) { 00044 this->setT(t); 00045 this->setX(x); 00046 this->setY(y); 00047 this->setZ(z); 00048 } 00049 00050 virtual ~FourVector() { } 00051 00052 public: 00053 00054 double t() const { return get(0); } 00055 double t2() const { return sqr(t()); } 00056 FourVector& setT(const double t) { set(0, t); return *this; } 00057 00058 double x() const { return get(1); } 00059 double x2() const { return sqr(x()); } 00060 FourVector& setX(const double x) { set(1, x); return *this; } 00061 00062 double y() const { return get(2); } 00063 double y2() const { return sqr(y()); } 00064 FourVector& setY(const double y) { set(2, y); return *this; } 00065 00066 double z() const { return get(3); } 00067 double z2() const { return sqr(z()); } 00068 FourVector& setZ(const double z) { set(3, z); return *this; } 00069 00070 double invariant() const { 00071 // Done this way for numerical precision 00072 return (t() + z())*(t() - z()) - x()*x() - y()*y(); 00073 } 00074 00075 bool isNull() const { 00076 return Rivet::isZero(invariant()); 00077 } 00078 00079 /// Angle between this vector and another 00080 double angle(const FourVector& v) const { 00081 return vector3().angle( v.vector3() ); 00082 } 00083 /// Angle between this vector and another (3-vector) 00084 double angle(const Vector3& v3) const { 00085 return vector3().angle(v3); 00086 } 00087 00088 /// @brief Square of the projection of the 3-vector on to the \f$ x-y \f$ plane 00089 /// This is a more efficient function than @c polarRadius, as it avoids the square root. 00090 /// Use it if you only need the squared value, or e.g. an ordering by magnitude. 00091 double polarRadius2() const { 00092 return vector3().polarRadius2(); 00093 } 00094 /// Synonym for polarRadius2 00095 double perp2() const { 00096 return vector3().perp2(); 00097 } 00098 /// Synonym for polarRadius2 00099 double rho2() const { 00100 return vector3().rho2(); 00101 } 00102 00103 /// Projection of 3-vector on to the \f$ x-y \f$ plane 00104 double polarRadius() const { 00105 return vector3().polarRadius(); 00106 } 00107 /// Synonym for polarRadius 00108 double perp() const { 00109 return vector3().perp(); 00110 } 00111 /// Synonym for polarRadius 00112 double rho() const { 00113 return vector3().rho(); 00114 } 00115 00116 /// Angle subtended by the 3-vector's projection in x-y and the x-axis. 00117 double azimuthalAngle(const PhiMapping mapping=ZERO_2PI) const { 00118 return vector3().azimuthalAngle(mapping); 00119 } 00120 /// Synonym for azimuthalAngle. 00121 double phi(const PhiMapping mapping=ZERO_2PI) const { 00122 return vector3().phi(mapping); 00123 } 00124 00125 /// Angle subtended by the 3-vector and the z-axis. 00126 double polarAngle() const { 00127 return vector3().polarAngle(); 00128 } 00129 /// Synonym for polarAngle. 00130 double theta() const { 00131 return vector3().theta(); 00132 } 00133 00134 /// Pseudorapidity (defined purely by the 3-vector components) 00135 double pseudorapidity() const { 00136 return vector3().pseudorapidity(); 00137 } 00138 /// Synonym for pseudorapidity. 00139 double eta() const { 00140 return vector3().eta(); 00141 } 00142 00143 /// Get the \f$ |\eta| \f$ directly. 00144 double abspseudorapidity() const { return fabs(eta()); } 00145 /// Get the \f$ |\eta| \f$ directly (alias). 00146 double abseta() const { return fabs(eta()); } 00147 00148 /// Get the spatial part of the 4-vector as a 3-vector. 00149 Vector3 vector3() const { 00150 return Vector3(get(1), get(2), get(3)); 00151 } 00152 00153 00154 public: 00155 00156 /// Contract two 4-vectors, with metric signature (+ - - -). 00157 double contract(const FourVector& v) const { 00158 const double result = t()*v.t() - x()*v.x() - y()*v.y() - z()*v.z(); 00159 return result; 00160 } 00161 00162 /// Contract two 4-vectors, with metric signature (+ - - -). 00163 double dot(const FourVector& v) const { 00164 return contract(v); 00165 } 00166 00167 /// Contract two 4-vectors, with metric signature (+ - - -). 00168 double operator*(const FourVector& v) const { 00169 return contract(v); 00170 } 00171 00172 /// Multiply by a scalar. 00173 FourVector& operator*=(double a) { 00174 _vec = multiply(a, *this)._vec; 00175 return *this; 00176 } 00177 00178 /// Divide by a scalar. 00179 FourVector& operator/=(double a) { 00180 _vec = multiply(1.0/a, *this)._vec; 00181 return *this; 00182 } 00183 00184 /// Add to this 4-vector. 00185 FourVector& operator+=(const FourVector& v) { 00186 _vec = add(*this, v)._vec; 00187 return *this; 00188 } 00189 00190 /// Subtract from this 4-vector. NB time as well as space components are subtracted. 00191 FourVector& operator-=(const FourVector& v) { 00192 _vec = add(*this, -v)._vec; 00193 return *this; 00194 } 00195 00196 /// Multiply all components (space and time) by -1. 00197 FourVector operator-() const { 00198 FourVector result; 00199 result._vec = -_vec; 00200 return result; 00201 } 00202 00203 /// Multiply space components only by -1. 00204 FourVector reverse() const { 00205 FourVector result = -*this; 00206 result.setT(-result.t()); 00207 return result; 00208 } 00209 00210 }; 00211 00212 00213 /// Contract two 4-vectors, with metric signature (+ - - -). 00214 inline double contract(const FourVector& a, const FourVector& b) { 00215 return a.contract(b); 00216 } 00217 00218 /// Contract two 4-vectors, with metric signature (+ - - -). 00219 inline double dot(const FourVector& a, const FourVector& b) { 00220 return contract(a, b); 00221 } 00222 00223 inline FourVector multiply(const double a, const FourVector& v) { 00224 FourVector result; 00225 result._vec = a * v._vec; 00226 return result; 00227 } 00228 00229 inline FourVector multiply(const FourVector& v, const double a) { 00230 return multiply(a, v); 00231 } 00232 00233 inline FourVector operator*(const double a, const FourVector& v) { 00234 return multiply(a, v); 00235 } 00236 00237 inline FourVector operator*(const FourVector& v, const double a) { 00238 return multiply(a, v); 00239 } 00240 00241 inline FourVector operator/(const FourVector& v, const double a) { 00242 return multiply(1.0/a, v); 00243 } 00244 00245 inline FourVector add(const FourVector& a, const FourVector& b) { 00246 FourVector result; 00247 result._vec = a._vec + b._vec; 00248 return result; 00249 } 00250 00251 inline FourVector operator+(const FourVector& a, const FourVector& b) { 00252 return add(a, b); 00253 } 00254 00255 inline FourVector operator-(const FourVector& a, const FourVector& b) { 00256 return add(a, -b); 00257 } 00258 00259 /// Calculate the Lorentz self-invariant of a 4-vector. 00260 /// \f$ v_\mu v^\mu = g_{\mu\nu} x^\mu x^\nu \f$. 00261 inline double invariant(const FourVector& lv) { 00262 return lv.invariant(); 00263 } 00264 00265 /// Angle (in radians) between spatial parts of two Lorentz vectors. 00266 inline double angle(const FourVector& a, const FourVector& b) { 00267 return a.angle(b); 00268 } 00269 00270 /// Angle (in radians) between spatial parts of two Lorentz vectors. 00271 inline double angle(const Vector3& a, const FourVector& b) { 00272 return angle( a, b.vector3() ); 00273 } 00274 00275 /// Angle (in radians) between spatial parts of two Lorentz vectors. 00276 inline double angle(const FourVector& a, const Vector3& b) { 00277 return a.angle(b); 00278 } 00279 00280 00281 //////////////////////////////////////////////// 00282 00283 00284 /// Specialized version of the FourVector with momentum/energy functionality. 00285 class FourMomentum : public FourVector { 00286 friend FourMomentum multiply(const double a, const FourMomentum& v); 00287 friend FourMomentum multiply(const FourMomentum& v, const double a); 00288 friend FourMomentum add(const FourMomentum& a, const FourMomentum& b); 00289 friend FourMomentum transform(const LorentzTransform& lt, const FourMomentum& v4); 00290 00291 public: 00292 FourMomentum() { } 00293 00294 template<typename V4> 00295 FourMomentum(const V4& other) { 00296 this->setE(other.t()); 00297 this->setPx(other.x()); 00298 this->setPy(other.y()); 00299 this->setPz(other.z()); 00300 } 00301 00302 FourMomentum(const Vector<4>& other) 00303 : FourVector(other) { } 00304 00305 FourMomentum(const double E, const double px, const double py, const double pz) { 00306 this->setE(E); 00307 this->setPx(px); 00308 this->setPy(py); 00309 this->setPz(pz); 00310 } 00311 00312 ~FourMomentum() {} 00313 00314 public: 00315 00316 00317 /// @name Coordinate setters 00318 //@{ 00319 00320 /// Set energy \f$ E \f$ (time component of momentum). 00321 FourMomentum& setE(double E) { 00322 setT(E); 00323 return *this; 00324 } 00325 00326 /// Set x-component of momentum \f$ p_x \f$. 00327 FourMomentum& setPx(double px) { 00328 setX(px); 00329 return *this; 00330 } 00331 00332 /// Set y-component of momentum \f$ p_y \f$. 00333 FourMomentum& setPy(double py) { 00334 setY(py); 00335 return *this; 00336 } 00337 00338 /// Set z-component of momentum \f$ p_z \f$. 00339 FourMomentum& setPz(double pz) { 00340 setZ(pz); 00341 return *this; 00342 } 00343 00344 00345 /// Set the p coordinates and energy simultaneously 00346 FourMomentum& setPE(double px, double py, double pz, double E) { 00347 if (E < 0) 00348 throw std::invalid_argument("Negative energy given as argument: " + to_str(E)); 00349 setPx(px); setPy(py); setPz(pz); setE(E); 00350 return *this; 00351 } 00352 /// Alias for setPE 00353 FourMomentum& setXYZE(double px, double py, double pz, double E) { 00354 return setPE(px, py, pz, E); 00355 } 00356 // /// Near-alias with switched arg order 00357 // FourMomentum& setEP(double E, double px, double py, double pz) { 00358 // return setPE(px, py, pz, E); 00359 // } 00360 // /// Alias for setEP 00361 // FourMomentum& setEXYZ(double E, double px, double py, double pz) { 00362 // return setEP(E, px, py, pz); 00363 // } 00364 00365 00366 /// Set the p coordinates and mass simultaneously 00367 FourMomentum& setPM(double px, double py, double pz, double mass) { 00368 if (mass < 0) 00369 throw std::invalid_argument("Negative mass given as argument: " + to_str(mass)); 00370 const double E = sqrt( sqr(mass) + sqr(px) + sqr(py) + sqr(pz) ); 00371 // setPx(px); setPy(py); setPz(pz); setE(E); 00372 return setPE(px, py, pz, E); 00373 } 00374 /// Alias for setPM 00375 FourMomentum& setXYZM(double px, double py, double pz, double mass) { 00376 return setPM(px, py, pz, mass); 00377 } 00378 00379 00380 /// Set the vector state from (eta,phi,energy) coordinates and the mass 00381 /// 00382 /// eta = -ln(tan(theta/2)) 00383 /// -> theta = 2 atan(exp(-eta)) 00384 FourMomentum& setEtaPhiME(double eta, double phi, double mass, double E) { 00385 if (mass < 0) 00386 throw std::invalid_argument("Negative mass given as argument"); 00387 if (E < 0) 00388 throw std::invalid_argument("Negative energy given as argument"); 00389 const double theta = 2 * atan(exp(-eta)); 00390 if (theta < 0 || theta > M_PI) 00391 throw std::domain_error("Polar angle outside 0..pi in calculation"); 00392 setThetaPhiME(theta, phi, mass, E); 00393 return *this; 00394 } 00395 00396 /// Set the vector state from (eta,phi,pT) coordinates and the mass 00397 /// 00398 /// eta = -ln(tan(theta/2)) 00399 /// -> theta = 2 atan(exp(-eta)) 00400 FourMomentum& setEtaPhiMPt(double eta, double phi, double mass, double pt) { 00401 if (mass < 0) 00402 throw std::invalid_argument("Negative mass given as argument"); 00403 if (pt < 0) 00404 throw std::invalid_argument("Negative transverse momentum given as argument"); 00405 const double theta = 2 * atan(exp(-eta)); 00406 if (theta < 0 || theta > M_PI) 00407 throw std::domain_error("Polar angle outside 0..pi in calculation"); 00408 const double p = pt / sin(theta); 00409 const double E = sqrt( sqr(p) + sqr(mass) ); 00410 setThetaPhiME(theta, phi, mass, E); 00411 return *this; 00412 } 00413 00414 /// Set the vector state from (y,phi,energy) coordinates and the mass 00415 /// 00416 /// y = 0.5 * ln((E+pz)/(E-pz)) 00417 /// -> (E^2 - pz^2) exp(2y) = (E+pz)^2 00418 /// & (E^2 - pz^2) exp(-2y) = (E-pz)^2 00419 /// -> E = sqrt(pt^2 + m^2) cosh(y) 00420 /// -> pz = sqrt(pt^2 + m^2) sinh(y) 00421 /// -> sqrt(pt^2 + m^2) = E / cosh(y) 00422 FourMomentum& setRapPhiME(double y, double phi, double mass, double E) { 00423 if (mass < 0) 00424 throw std::invalid_argument("Negative mass given as argument"); 00425 if (E < 0) 00426 throw std::invalid_argument("Negative energy given as argument"); 00427 const double sqrt_pt2_m2 = E / cosh(y); 00428 const double pt = sqrt( sqr(sqrt_pt2_m2) - sqr(mass) ); 00429 if (pt < 0) 00430 throw std::domain_error("Negative transverse momentum in calculation"); 00431 const double pz = sqrt_pt2_m2 * sinh(y); 00432 const double px = pt * cos(phi); 00433 const double py = pt * sin(phi); 00434 setPE(px, py, pz, E); 00435 return *this; 00436 } 00437 00438 /// Set the vector state from (y,phi,pT) coordinates and the mass 00439 /// 00440 /// y = 0.5 * ln((E+pz)/(E-pz)) 00441 /// -> E = sqrt(pt^2 + m^2) cosh(y) [see above] 00442 FourMomentum& setRapPhiMPt(double y, double phi, double mass, double pt) { 00443 if (mass < 0) 00444 throw std::invalid_argument("Negative mass given as argument"); 00445 if (pt < 0) 00446 throw std::invalid_argument("Negative transverse mass given as argument"); 00447 const double E = sqrt( sqr(pt) + sqr(mass) ) * cosh(y); 00448 if (E < 0) 00449 throw std::domain_error("Negative energy in calculation"); 00450 setRapPhiME(y, phi, mass, E); 00451 return *this; 00452 } 00453 00454 /// Set the vector state from (theta,phi,energy) coordinates and the mass 00455 /// 00456 /// p = sqrt(E^2 - mass^2) 00457 /// pz = p cos(theta) 00458 /// pt = p sin(theta) 00459 FourMomentum& setThetaPhiME(double theta, double phi, double mass, double E) { 00460 if (theta < 0 || theta > M_PI) 00461 throw std::invalid_argument("Polar angle outside 0..pi given as argument"); 00462 if (mass < 0) 00463 throw std::invalid_argument("Negative mass given as argument"); 00464 if (E < 0) 00465 throw std::invalid_argument("Negative energy given as argument"); 00466 const double p = sqrt( sqr(E) - sqr(mass) ); 00467 const double pz = p * cos(theta); 00468 const double pt = p * sin(theta); 00469 if (pt < 0) 00470 throw std::invalid_argument("Negative transverse momentum in calculation"); 00471 const double px = pt * cos(phi); 00472 const double py = pt * sin(phi); 00473 setPE(px, py, pz, E); 00474 return *this; 00475 } 00476 00477 /// Set the vector state from (theta,phi,pT) coordinates and the mass 00478 /// 00479 /// p = pt / sin(theta) 00480 /// pz = p cos(theta) 00481 /// E = sqrt(p^2 + mass^2) 00482 FourMomentum& setThetaPhiMPt(double theta, double phi, double mass, double pt) { 00483 if (theta < 0 || theta > M_PI) 00484 throw std::invalid_argument("Polar angle outside 0..pi given as argument"); 00485 if (mass < 0) 00486 throw std::invalid_argument("Negative mass given as argument"); 00487 if (pt < 0) 00488 throw std::invalid_argument("Negative transverse momentum given as argument"); 00489 const double p = pt / sin(theta); 00490 const double px = pt * cos(phi); 00491 const double py = pt * sin(phi); 00492 const double pz = p * cos(theta); 00493 const double E = sqrt( sqr(p) + sqr(mass) ); 00494 setPE(px, py, pz, E); 00495 return *this; 00496 } 00497 00498 /// Set the vector state from (pT,phi,energy) coordinates and the mass 00499 /// 00500 /// pz = sqrt(E^2 - mass^2 - pt^2) 00501 FourMomentum& setPtPhiME(double pt, double phi, double mass, double E) { 00502 if (pt < 0) 00503 throw std::invalid_argument("Negative transverse momentum given as argument"); 00504 if (mass < 0) 00505 throw std::invalid_argument("Negative mass given as argument"); 00506 if (E < 0) 00507 throw std::invalid_argument("Negative energy given as argument"); 00508 const double px = pt * cos(phi); 00509 const double py = pt * sin(phi); 00510 const double pz = sqrt(sqr(E) - sqr(mass) - sqr(pt)); 00511 setPE(px, py, pz, E); 00512 return *this; 00513 } 00514 00515 //@} 00516 00517 00518 /// @name Accessors 00519 //@{ 00520 00521 /// Get energy \f$ E \f$ (time component of momentum). 00522 double E() const { return t(); } 00523 /// Get energy-squared \f$ E^2 \f$. 00524 double E2() const { return t2(); } 00525 00526 /// Get x-component of momentum \f$ p_x \f$. 00527 double px() const { return x(); } 00528 /// Get x-squared \f$ p_x^2 \f$. 00529 double px2() const { return x2(); } 00530 00531 /// Get y-component of momentum \f$ p_y \f$. 00532 double py() const { return y(); } 00533 /// Get y-squared \f$ p_y^2 \f$. 00534 double py2() const { return y2(); } 00535 00536 /// Get z-component of momentum \f$ p_z \f$. 00537 double pz() const { return z(); } 00538 /// Get z-squared \f$ p_z^2 \f$. 00539 double pz2() const { return z2(); } 00540 00541 00542 /// @brief Get the mass \f$ m = \sqrt{E^2 - p^2} \f$ (the Lorentz self-invariant). 00543 /// 00544 /// For spacelike momenta, the mass will be -sqrt(|mass2|). 00545 double mass() const { 00546 // assert(Rivet::isZero(mass2()) || mass2() > 0); 00547 // if (Rivet::isZero(mass2())) { 00548 // return 0.0; 00549 // } else { 00550 // return sqrt(mass2()); 00551 // } 00552 return sign(mass2()) * sqrt(fabs(mass2())); 00553 } 00554 00555 /// Get the squared mass \f$ m^2 = E^2 - p^2 \f$ (the Lorentz self-invariant). 00556 double mass2() const { 00557 return invariant(); 00558 } 00559 00560 00561 /// Get 3-momentum part, \f$ p \f$. 00562 Vector3 p3() const { return vector3(); } 00563 00564 /// Get the modulus of the 3-momentum 00565 double p() const { 00566 return p3().mod(); 00567 } 00568 00569 /// Get the modulus-squared of the 3-momentum 00570 double p2() const { 00571 return p3().mod2(); 00572 } 00573 00574 00575 /// Calculate the rapidity. 00576 double rapidity() const { 00577 return 0.5 * std::log( (E() + pz()) / (E() - pz()) ); 00578 } 00579 /// Alias for rapidity. 00580 double rap() const { 00581 return rapidity(); 00582 } 00583 00584 /// Absolute rapidity. 00585 double absrapidity() const { 00586 return fabs(rapidity()); 00587 } 00588 /// Absolute rapidity. 00589 double absrap() const { 00590 return fabs(rap()); 00591 } 00592 00593 /// Calculate the squared transverse momentum \f$ p_T^2 \f$. 00594 double pT2() const { 00595 return vector3().polarRadius2(); 00596 } 00597 /// Calculate the squared transverse momentum \f$ p_T^2 \f$. 00598 double pt2() const { 00599 return vector3().polarRadius2(); 00600 } 00601 00602 /// Calculate the transverse momentum \f$ p_T \f$. 00603 double pT() const { 00604 return sqrt(pT2()); 00605 } 00606 /// Calculate the transverse momentum \f$ p_T \f$. 00607 double pt() const { 00608 return sqrt(pT2()); 00609 } 00610 00611 /// Calculate the transverse energy \f$ E_T^2 = E^2 \sin^2{\theta} \f$. 00612 double Et2() const { 00613 return Et() * Et(); 00614 } 00615 /// Calculate the transverse energy \f$ E_T = E \sin{\theta} \f$. 00616 double Et() const { 00617 return E() * sin(polarAngle()); 00618 } 00619 00620 //@} 00621 00622 00623 /// @name Lorentz boost factors and vectors 00624 //@{ 00625 00626 /// Calculate the boost factor \f$ \gamma \f$. 00627 /// @note \f$ \gamma = E/mc^2 \f$ so we rely on the c=1 convention 00628 double gamma() const { 00629 return sqrt(E2()/mass2()); 00630 } 00631 00632 /// Calculate the boost vector \f$ \vec{\gamma} \f$. 00633 /// @note \f$ \gamma = E/mc^2 \f$ so we rely on the c=1 convention 00634 Vector3 gammaVec() const { 00635 return gamma() * p3().unit(); 00636 } 00637 00638 /// Calculate the boost factor \f$ \beta \f$. 00639 /// @note \f$ \beta = pc/E \f$ so we rely on the c=1 convention 00640 double beta() const { 00641 return p()/E(); 00642 } 00643 00644 /// Calculate the boost vector \f$ \vec{\beta} \f$. 00645 /// @note \f$ \beta = pc/E \f$ so we rely on the c=1 convention 00646 Vector3 betaVec() const { 00647 // return Vector3(px()/E(), py()/E(), pz()/E()); 00648 return p3()/E(); 00649 } 00650 00651 /// @brief Deprecated alias for betaVec 00652 /// @deprecated This will be removed; use betaVec() instead 00653 Vector3 boostVector() const { return betaVec(); } 00654 00655 //@} 00656 00657 00658 //////////////////////////////////////// 00659 00660 00661 /// @name Sorting helpers 00662 //@{ 00663 00664 /// Struct for sorting by increasing energy 00665 struct byEAscending { 00666 bool operator()(const FourMomentum& left, const FourMomentum& right) const{ 00667 const double pt2left = left.E(); 00668 const double pt2right = right.E(); 00669 return pt2left < pt2right; 00670 } 00671 00672 bool operator()(const FourMomentum* left, const FourMomentum* right) const{ 00673 return (*this)(*left, *right); 00674 } 00675 }; 00676 00677 00678 /// Struct for sorting by decreasing energy 00679 struct byEDescending { 00680 bool operator()(const FourMomentum& left, const FourMomentum& right) const{ 00681 return byEAscending()(right, left); 00682 } 00683 00684 bool operator()(const FourMomentum* left, const FourVector* right) const{ 00685 return (*this)(*left, *right); 00686 } 00687 }; 00688 00689 //@} 00690 00691 00692 //////////////////////////////////////// 00693 00694 00695 /// @name Arithmetic operators 00696 //@{ 00697 00698 /// Multiply by a scalar 00699 FourMomentum& operator*=(double a) { 00700 _vec = multiply(a, *this)._vec; 00701 return *this; 00702 } 00703 00704 /// Divide by a scalar 00705 FourMomentum& operator/=(double a) { 00706 _vec = multiply(1.0/a, *this)._vec; 00707 return *this; 00708 } 00709 00710 /// Add to this 4-vector. NB time as well as space components are added. 00711 FourMomentum& operator+=(const FourMomentum& v) { 00712 _vec = add(*this, v)._vec; 00713 return *this; 00714 } 00715 00716 /// Subtract from this 4-vector. NB time as well as space components are subtracted. 00717 FourMomentum& operator-=(const FourMomentum& v) { 00718 _vec = add(*this, -v)._vec; 00719 return *this; 00720 } 00721 00722 /// Multiply all components (time and space) by -1. 00723 FourMomentum operator-() const { 00724 FourMomentum result; 00725 result._vec = -_vec; 00726 return result; 00727 } 00728 00729 /// Multiply space components only by -1. 00730 FourMomentum reverse() const { 00731 FourMomentum result = -*this; 00732 result.setE(-result.E()); 00733 return result; 00734 } 00735 00736 //@} 00737 00738 00739 //////////////////////////////////////// 00740 00741 00742 /// @name Factory functions 00743 //@{ 00744 00745 /// Make a vector from (px,py,pz,E) coordinates 00746 static FourMomentum mkXYZE(double px, double py, double pz, double E) { 00747 return FourMomentum().setPE(px, py, pz, E); 00748 } 00749 00750 /// Make a vector from (px,py,pz) coordinates and the mass 00751 static FourMomentum mkXYZM(double px, double py, double pz, double mass) { 00752 return FourMomentum().setPM(px, py, pz, mass); 00753 } 00754 00755 /// Make a vector from (eta,phi,energy) coordinates and the mass 00756 static FourMomentum mkEtaPhiME(double eta, double phi, double mass, double E) { 00757 return FourMomentum().setEtaPhiME(eta, phi, mass, E); 00758 } 00759 00760 /// Make a vector from (eta,phi,pT) coordinates and the mass 00761 static FourMomentum mkEtaPhiMPt(double eta, double phi, double mass, double pt) { 00762 return FourMomentum().setEtaPhiMPt(eta, phi, mass, pt); 00763 } 00764 00765 /// Make a vector from (y,phi,energy) coordinates and the mass 00766 static FourMomentum mkRapPhiME(double y, double phi, double mass, double E) { 00767 return FourMomentum().setRapPhiME(y, phi, mass, E); 00768 } 00769 00770 /// Make a vector from (y,phi,pT) coordinates and the mass 00771 static FourMomentum mkRapPhiMPt(double y, double phi, double mass, double pt) { 00772 return FourMomentum().setRapPhiMPt(y, phi, mass, pt); 00773 } 00774 00775 /// Make a vector from (theta,phi,energy) coordinates and the mass 00776 static FourMomentum mkThetaPhiME(double theta, double phi, double mass, double E) { 00777 return FourMomentum().setThetaPhiME(theta, phi, mass, E); 00778 } 00779 00780 /// Make a vector from (theta,phi,pT) coordinates and the mass 00781 static FourMomentum mkThetaPhiMPt(double theta, double phi, double mass, double pt) { 00782 return FourMomentum().setThetaPhiMPt(theta, phi, mass, pt); 00783 } 00784 00785 /// Make a vector from (pT,phi,energy) coordinates and the mass 00786 static FourMomentum mkPtPhiME(double pt, double phi, double mass, double E) { 00787 return FourMomentum().setPtPhiME(pt, phi, mass, E); 00788 } 00789 00790 //@} 00791 00792 00793 }; 00794 00795 00796 00797 inline FourMomentum multiply(const double a, const FourMomentum& v) { 00798 FourMomentum result; 00799 result._vec = a * v._vec; 00800 return result; 00801 } 00802 00803 inline FourMomentum multiply(const FourMomentum& v, const double a) { 00804 return multiply(a, v); 00805 } 00806 00807 inline FourMomentum operator*(const double a, const FourMomentum& v) { 00808 return multiply(a, v); 00809 } 00810 00811 inline FourMomentum operator*(const FourMomentum& v, const double a) { 00812 return multiply(a, v); 00813 } 00814 00815 inline FourMomentum operator/(const FourMomentum& v, const double a) { 00816 return multiply(1.0/a, v); 00817 } 00818 00819 inline FourMomentum add(const FourMomentum& a, const FourMomentum& b) { 00820 FourMomentum result; 00821 result._vec = a._vec + b._vec; 00822 return result; 00823 } 00824 00825 inline FourMomentum operator+(const FourMomentum& a, const FourMomentum& b) { 00826 return add(a, b); 00827 } 00828 00829 inline FourMomentum operator-(const FourMomentum& a, const FourMomentum& b) { 00830 return add(a, -b); 00831 } 00832 00833 00834 ////////////////////////////////////////////////////// 00835 00836 00837 /// @name \f$ \Delta R \f$ calculations from 4-vectors 00838 //@{ 00839 00840 /// @brief Calculate the 2D rapidity-azimuthal ("eta-phi") distance between two four-vectors. 00841 /// There is a scheme ambiguity for momentum-type four vectors as to whether 00842 /// the pseudorapidity (a purely geometric concept) or the rapidity (a 00843 /// relativistic energy-momentum quantity) is to be used: this can be chosen 00844 /// via the optional scheme parameter. Use of this scheme option is 00845 /// discouraged in this case since @c RAPIDITY is only a valid option for 00846 /// vectors whose type is really the FourMomentum derived class. 00847 inline double deltaR(const FourVector& a, const FourVector& b, 00848 RapScheme scheme = PSEUDORAPIDITY) { 00849 switch (scheme) { 00850 case PSEUDORAPIDITY : 00851 return deltaR(a.vector3(), b.vector3()); 00852 case RAPIDITY: 00853 { 00854 const FourMomentum* ma = dynamic_cast<const FourMomentum*>(&a); 00855 const FourMomentum* mb = dynamic_cast<const FourMomentum*>(&b); 00856 if (!ma || !mb) { 00857 string err = "deltaR with scheme RAPIDITY can only be called with FourMomentum objects, not FourVectors"; 00858 throw std::runtime_error(err); 00859 } 00860 return deltaR(*ma, *mb, scheme); 00861 } 00862 default: 00863 throw std::runtime_error("The specified deltaR scheme is not yet implemented"); 00864 } 00865 } 00866 00867 00868 /// @brief Calculate the 2D rapidity-azimuthal ("eta-phi") distance between two four-vectors. 00869 /// There is a scheme ambiguity for momentum-type four vectors 00870 /// as to whether the pseudorapidity (a purely geometric concept) or the 00871 /// rapidity (a relativistic energy-momentum quantity) is to be used: this can 00872 /// be chosen via the optional scheme parameter. 00873 inline double deltaR(const FourVector& v, 00874 double eta2, double phi2, 00875 RapScheme scheme = PSEUDORAPIDITY) { 00876 switch (scheme) { 00877 case PSEUDORAPIDITY : 00878 return deltaR(v.vector3(), eta2, phi2); 00879 case RAPIDITY: 00880 { 00881 const FourMomentum* mv = dynamic_cast<const FourMomentum*>(&v); 00882 if (!mv) { 00883 string err = "deltaR with scheme RAPIDITY can only be called with FourMomentum objects, not FourVectors"; 00884 throw std::runtime_error(err); 00885 } 00886 return deltaR(*mv, eta2, phi2, scheme); 00887 } 00888 default: 00889 throw std::runtime_error("The specified deltaR scheme is not yet implemented"); 00890 } 00891 } 00892 00893 00894 /// @brief Calculate the 2D rapidity-azimuthal ("eta-phi") distance between two four-vectors. 00895 /// There is a scheme ambiguity for momentum-type four vectors 00896 /// as to whether the pseudorapidity (a purely geometric concept) or the 00897 /// rapidity (a relativistic energy-momentum quantity) is to be used: this can 00898 /// be chosen via the optional scheme parameter. 00899 inline double deltaR(double eta1, double phi1, 00900 const FourVector& v, 00901 RapScheme scheme = PSEUDORAPIDITY) { 00902 switch (scheme) { 00903 case PSEUDORAPIDITY : 00904 return deltaR(eta1, phi1, v.vector3()); 00905 case RAPIDITY: 00906 { 00907 const FourMomentum* mv = dynamic_cast<const FourMomentum*>(&v); 00908 if (!mv) { 00909 string err = "deltaR with scheme RAPIDITY can only be called with FourMomentum objects, not FourVectors"; 00910 throw std::runtime_error(err); 00911 } 00912 return deltaR(eta1, phi1, *mv, scheme); 00913 } 00914 default: 00915 throw std::runtime_error("The specified deltaR scheme is not yet implemented"); 00916 } 00917 } 00918 00919 00920 /// @brief Calculate the 2D rapidity-azimuthal ("eta-phi") distance between two four-vectors. 00921 /// There is a scheme ambiguity for momentum-type four vectors 00922 /// as to whether the pseudorapidity (a purely geometric concept) or the 00923 /// rapidity (a relativistic energy-momentum quantity) is to be used: this can 00924 /// be chosen via the optional scheme parameter. 00925 inline double deltaR(const FourMomentum& a, const FourMomentum& b, 00926 RapScheme scheme = PSEUDORAPIDITY) { 00927 switch (scheme) { 00928 case PSEUDORAPIDITY: 00929 return deltaR(a.vector3(), b.vector3()); 00930 case RAPIDITY: 00931 return deltaR(a.rapidity(), a.azimuthalAngle(), b.rapidity(), b.azimuthalAngle()); 00932 default: 00933 throw std::runtime_error("The specified deltaR scheme is not yet implemented"); 00934 } 00935 } 00936 00937 /// @brief Calculate the 2D rapidity-azimuthal ("eta-phi") distance between two four-vectors. 00938 /// There is a scheme ambiguity for momentum-type four vectors 00939 /// as to whether the pseudorapidity (a purely geometric concept) or the 00940 /// rapidity (a relativistic energy-momentum quantity) is to be used: this can 00941 /// be chosen via the optional scheme parameter. 00942 inline double deltaR(const FourMomentum& v, 00943 double eta2, double phi2, 00944 RapScheme scheme = PSEUDORAPIDITY) { 00945 switch (scheme) { 00946 case PSEUDORAPIDITY: 00947 return deltaR(v.vector3(), eta2, phi2); 00948 case RAPIDITY: 00949 return deltaR(v.rapidity(), v.azimuthalAngle(), eta2, phi2); 00950 default: 00951 throw std::runtime_error("The specified deltaR scheme is not yet implemented"); 00952 } 00953 } 00954 00955 00956 /// @brief Calculate the 2D rapidity-azimuthal ("eta-phi") distance between two four-vectors. 00957 /// There is a scheme ambiguity for momentum-type four vectors 00958 /// as to whether the pseudorapidity (a purely geometric concept) or the 00959 /// rapidity (a relativistic energy-momentum quantity) is to be used: this can 00960 /// be chosen via the optional scheme parameter. 00961 inline double deltaR(double eta1, double phi1, 00962 const FourMomentum& v, 00963 RapScheme scheme = PSEUDORAPIDITY) { 00964 switch (scheme) { 00965 case PSEUDORAPIDITY: 00966 return deltaR(eta1, phi1, v.vector3()); 00967 case RAPIDITY: 00968 return deltaR(eta1, phi1, v.rapidity(), v.azimuthalAngle()); 00969 default: 00970 throw std::runtime_error("The specified deltaR scheme is not yet implemented"); 00971 } 00972 } 00973 00974 /// @brief Calculate the 2D rapidity-azimuthal ("eta-phi") distance between two four-vectors. 00975 /// There is a scheme ambiguity for momentum-type four vectors 00976 /// as to whether the pseudorapidity (a purely geometric concept) or the 00977 /// rapidity (a relativistic energy-momentum quantity) is to be used: this can 00978 /// be chosen via the optional scheme parameter. 00979 inline double deltaR(const FourMomentum& a, const FourVector& b, 00980 RapScheme scheme = PSEUDORAPIDITY) { 00981 switch (scheme) { 00982 case PSEUDORAPIDITY: 00983 return deltaR(a.vector3(), b.vector3()); 00984 case RAPIDITY: 00985 return deltaR(a.rapidity(), a.azimuthalAngle(), FourMomentum(b).rapidity(), b.azimuthalAngle()); 00986 default: 00987 throw std::runtime_error("The specified deltaR scheme is not yet implemented"); 00988 } 00989 } 00990 00991 /// @brief Calculate the 2D rapidity-azimuthal ("eta-phi") distance between two four-vectors. 00992 /// There is a scheme ambiguity for momentum-type four vectors 00993 /// as to whether the pseudorapidity (a purely geometric concept) or the 00994 /// rapidity (a relativistic energy-momentum quantity) is to be used: this can 00995 /// be chosen via the optional scheme parameter. 00996 inline double deltaR(const FourVector& a, const FourMomentum& b, 00997 RapScheme scheme = PSEUDORAPIDITY) { 00998 return deltaR(b, a, scheme); 00999 } 01000 01001 /// @brief Calculate the 2D rapidity-azimuthal ("eta-phi") distance between a 01002 /// three-vector and a four-vector. 01003 inline double deltaR(const FourMomentum& a, const Vector3& b) { 01004 return deltaR(a.vector3(), b); 01005 } 01006 01007 /// @brief Calculate the 2D rapidity-azimuthal ("eta-phi") distance between a 01008 /// three-vector and a four-vector. 01009 inline double deltaR(const Vector3& a, const FourMomentum& b) { 01010 return deltaR(a, b.vector3()); 01011 } 01012 01013 /// @brief Calculate the 2D rapidity-azimuthal ("eta-phi") distance between a 01014 /// three-vector and a four-vector. 01015 inline double deltaR(const FourVector& a, const Vector3& b) { 01016 return deltaR(a.vector3(), b); 01017 } 01018 01019 /// @brief Calculate the 2D rapidity-azimuthal ("eta-phi") distance between a 01020 /// three-vector and a four-vector. 01021 inline double deltaR(const Vector3& a, const FourVector& b) { 01022 return deltaR(a, b.vector3()); 01023 } 01024 01025 //@} 01026 01027 01028 ////////////////////////////////////////////////////// 01029 01030 01031 /// @name \f$ \Delta phi \f$ calculations from 4-vectors 01032 //@{ 01033 01034 /// Calculate the difference in azimuthal angle between two vectors. 01035 inline double deltaPhi(const FourMomentum& a, const FourMomentum& b) { 01036 return deltaPhi(a.vector3(), b.vector3()); 01037 } 01038 01039 /// Calculate the difference in azimuthal angle between two vectors. 01040 inline double deltaPhi(const FourMomentum& v, double phi2) { 01041 return deltaPhi(v.vector3(), phi2); 01042 } 01043 01044 /// Calculate the difference in azimuthal angle between two vectors. 01045 inline double deltaPhi(double phi1, const FourMomentum& v) { 01046 return deltaPhi(phi1, v.vector3()); 01047 } 01048 01049 /// Calculate the difference in azimuthal angle between two vectors. 01050 inline double deltaPhi(const FourVector& a, const FourVector& b) { 01051 return deltaPhi(a.vector3(), b.vector3()); 01052 } 01053 01054 /// Calculate the difference in azimuthal angle between two vectors. 01055 inline double deltaPhi(const FourVector& v, double phi2) { 01056 return deltaPhi(v.vector3(), phi2); 01057 } 01058 01059 /// Calculate the difference in azimuthal angle between two vectors. 01060 inline double deltaPhi(double phi1, const FourVector& v) { 01061 return deltaPhi(phi1, v.vector3()); 01062 } 01063 01064 /// Calculate the difference in azimuthal angle between two vectors. 01065 inline double deltaPhi(const FourVector& a, const FourMomentum& b) { 01066 return deltaPhi(a.vector3(), b.vector3()); 01067 } 01068 01069 /// Calculate the difference in azimuthal angle between two vectors. 01070 inline double deltaPhi(const FourMomentum& a, const FourVector& b) { 01071 return deltaPhi(a.vector3(), b.vector3()); 01072 } 01073 01074 /// Calculate the difference in azimuthal angle between two vectors. 01075 inline double deltaPhi(const FourVector& a, const Vector3& b) { 01076 return deltaPhi(a.vector3(), b); 01077 } 01078 01079 /// Calculate the difference in azimuthal angle between two vectors. 01080 inline double deltaPhi(const Vector3& a, const FourVector& b) { 01081 return deltaPhi(a, b.vector3()); 01082 } 01083 01084 /// Calculate the difference in azimuthal angle between two vectors. 01085 inline double deltaPhi(const FourMomentum& a, const Vector3& b) { 01086 return deltaPhi(a.vector3(), b); 01087 } 01088 01089 /// Calculate the difference in azimuthal angle between two vectors. 01090 inline double deltaPhi(const Vector3& a, const FourMomentum& b) { 01091 return deltaPhi(a, b.vector3()); 01092 } 01093 01094 //@} 01095 01096 01097 ////////////////////////////////////////////////////// 01098 01099 01100 /// @name \f$ |\Delta eta| \f$ calculations from 4-vectors 01101 //@{ 01102 01103 /// Calculate the difference in pseudorapidity between two vectors. 01104 inline double deltaEta(const FourMomentum& a, const FourMomentum& b) { 01105 return deltaEta(a.vector3(), b.vector3()); 01106 } 01107 01108 /// Calculate the difference in pseudorapidity between two vectors. 01109 inline double deltaEta(const FourMomentum& v, double eta2) { 01110 return deltaEta(v.vector3(), eta2); 01111 } 01112 01113 /// Calculate the difference in pseudorapidity between two vectors. 01114 inline double deltaEta(double eta1, const FourMomentum& v) { 01115 return deltaEta(eta1, v.vector3()); 01116 } 01117 01118 /// Calculate the difference in pseudorapidity between two vectors. 01119 inline double deltaEta(const FourVector& a, const FourVector& b) { 01120 return deltaEta(a.vector3(), b.vector3()); 01121 } 01122 01123 /// Calculate the difference in pseudorapidity between two vectors. 01124 inline double deltaEta(const FourVector& v, double eta2) { 01125 return deltaEta(v.vector3(), eta2); 01126 } 01127 01128 /// Calculate the difference in pseudorapidity between two vectors. 01129 inline double deltaEta(double eta1, const FourVector& v) { 01130 return deltaEta(eta1, v.vector3()); 01131 } 01132 01133 /// Calculate the difference in pseudorapidity between two vectors. 01134 inline double deltaEta(const FourVector& a, const FourMomentum& b) { 01135 return deltaEta(a.vector3(), b.vector3()); 01136 } 01137 01138 /// Calculate the difference in pseudorapidity between two vectors. 01139 inline double deltaEta(const FourMomentum& a, const FourVector& b) { 01140 return deltaEta(a.vector3(), b.vector3()); 01141 } 01142 01143 /// Calculate the difference in pseudorapidity between two vectors. 01144 inline double deltaEta(const FourVector& a, const Vector3& b) { 01145 return deltaEta(a.vector3(), b); 01146 } 01147 01148 /// Calculate the difference in pseudorapidity between two vectors. 01149 inline double deltaEta(const Vector3& a, const FourVector& b) { 01150 return deltaEta(a, b.vector3()); 01151 } 01152 01153 /// Calculate the difference in pseudorapidity between two vectors. 01154 inline double deltaEta(const FourMomentum& a, const Vector3& b) { 01155 return deltaEta(a.vector3(), b); 01156 } 01157 01158 /// Calculate the difference in pseudorapidity between two vectors. 01159 inline double deltaEta(const Vector3& a, const FourMomentum& b) { 01160 return deltaEta(a, b.vector3()); 01161 } 01162 01163 //@} 01164 01165 01166 /// @name \f$ |\Delta y| \f$ calculations from 4-momentum vectors 01167 //@{ 01168 01169 /// Calculate the difference in rapidity between two 4-momentum vectors. 01170 inline double deltaRap(const FourMomentum& a, const FourMomentum& b) { 01171 return deltaRap(a.rapidity(), b.rapidity()); 01172 } 01173 01174 /// Calculate the difference in rapidity between two 4-momentum vectors. 01175 inline double deltaRap(const FourMomentum& v, double y2) { 01176 return deltaRap(v.rapidity(), y2); 01177 } 01178 01179 /// Calculate the difference in rapidity between two 4-momentum vectors. 01180 inline double deltaRap(double y1, const FourMomentum& v) { 01181 return deltaRap(y1, v.rapidity()); 01182 } 01183 01184 //@} 01185 01186 01187 ////////////////////////////////////////////////////// 01188 01189 01190 /// @name 4-vector comparison functions (for sorting) 01191 //@{ 01192 01193 /// Comparison to give a sorting by decreasing pT 01194 inline bool cmpMomByPt(const FourMomentum& a, const FourMomentum& b) { 01195 return a.pt() > b.pt(); 01196 } 01197 /// Comparison to give a sorting by increasing pT 01198 inline bool cmpMomByAscPt(const FourMomentum& a, const FourMomentum& b) { 01199 return a.pt() < b.pt(); 01200 } 01201 01202 /// Comparison to give a sorting by decreasing 3-momentum magnitude |p| 01203 inline bool cmpMomByP(const FourMomentum& a, const FourMomentum& b) { 01204 return a.vector3().mod() > b.vector3().mod(); 01205 } 01206 /// Comparison to give a sorting by increasing 3-momentum magnitude |p| 01207 inline bool cmpMomByAscP(const FourMomentum& a, const FourMomentum& b) { 01208 return a.vector3().mod() < b.vector3().mod(); 01209 } 01210 01211 /// Comparison to give a sorting by decreasing transverse energy 01212 inline bool cmpMomByEt(const FourMomentum& a, const FourMomentum& b) { 01213 return a.Et() > b.Et(); 01214 } 01215 /// Comparison to give a sorting by increasing transverse energy 01216 inline bool cmpMomByAscEt(const FourMomentum& a, const FourMomentum& b) { 01217 return a.Et() < b.Et(); 01218 } 01219 01220 /// Comparison to give a sorting by decreasing energy 01221 inline bool cmpMomByE(const FourMomentum& a, const FourMomentum& b) { 01222 return a.E() > b.E(); 01223 } 01224 /// Comparison to give a sorting by increasing energy 01225 inline bool cmpMomByAscE(const FourMomentum& a, const FourMomentum& b) { 01226 return a.E() < b.E(); 01227 } 01228 01229 /// Comparison to give a sorting by decreasing mass 01230 inline bool cmpMomByMass(const FourMomentum& a, const FourMomentum& b) { 01231 return a.mass() > b.mass(); 01232 } 01233 /// Comparison to give a sorting by increasing mass 01234 inline bool cmpMomByAscMass(const FourMomentum& a, const FourMomentum& b) { 01235 return a.mass() < b.mass(); 01236 } 01237 01238 /// Comparison to give a sorting by increasing eta (pseudorapidity) 01239 inline bool cmpMomByEta(const FourMomentum& a, const FourMomentum& b) { 01240 return a.eta() < b.eta(); 01241 } 01242 /// Comparison to give a sorting by increasing eta (pseudorapidity) 01243 /// @deprecated Use cmpMomByEta 01244 DEPRECATED("Use cmpMomByEta") 01245 inline bool cmpMomByAscPseudorapidity(const FourMomentum& a, const FourMomentum& b) { 01246 return cmpMomByEta(a,b); 01247 } 01248 01249 /// Comparison to give a sorting by decreasing eta (pseudorapidity) 01250 inline bool cmpMomByDescEta(const FourMomentum& a, const FourMomentum& b) { 01251 return a.pseudorapidity() > b.pseudorapidity(); 01252 } 01253 /// Comparison to give a sorting by decreasing eta (pseudorapidity) 01254 /// @deprecated Use cmpMomByDescEta 01255 DEPRECATED("Use cmpMomByDescEta") 01256 inline bool cmpMomByDescPseudorapidity(const FourMomentum& a, const FourMomentum& b) { 01257 return cmpMomByDescEta(a,b); 01258 } 01259 01260 /// Comparison to give a sorting by increasing absolute eta (pseudorapidity) 01261 inline bool cmpMomByAbsEta(const FourMomentum& a, const FourMomentum& b) { 01262 return fabs(a.eta()) < fabs(b.eta()); 01263 } 01264 /// Comparison to give a sorting by increasing absolute eta (pseudorapidity) 01265 /// @deprecated Use cmpMomByAbsEta 01266 DEPRECATED("Use cmpMomByAbsEta") 01267 inline bool cmpMomByAscAbsPseudorapidity(const FourMomentum& a, const FourMomentum& b) { 01268 return cmpMomByAbsEta(a,b); 01269 } 01270 01271 /// Comparison to give a sorting by increasing absolute eta (pseudorapidity) 01272 inline bool cmpMomByDescAbsEta(const FourMomentum& a, const FourMomentum& b) { 01273 return fabs(a.eta()) > fabs(b.eta()); 01274 } 01275 /// Comparison to give a sorting by increasing absolute eta (pseudorapidity) 01276 /// @deprecated Use cmpMomByDescAbsEta 01277 DEPRECATED("Use cmpMomByDescAbsEta") 01278 inline bool cmpMomByDescAbsPseudorapidity(const FourMomentum& a, const FourMomentum& b) { 01279 return cmpMomByDescAbsEta(a,b); 01280 } 01281 01282 /// Comparison to give a sorting by increasing rapidity 01283 inline bool cmpMomByRap(const FourMomentum& a, const FourMomentum& b) { 01284 return a.rapidity() < b.rapidity(); 01285 } 01286 /// Comparison to give a sorting by increasing rapidity 01287 /// @deprecated Use cmpMomByRap 01288 DEPRECATED("Use cmpMomByRap") 01289 inline bool cmpMomByAscRapidity(const FourMomentum& a, const FourMomentum& b) { 01290 return cmpMomByRap(a,b); 01291 } 01292 01293 /// Comparison to give a sorting by decreasing rapidity 01294 inline bool cmpMomByDescRap(const FourMomentum& a, const FourMomentum& b) { 01295 return a.rapidity() > b.rapidity(); 01296 } 01297 /// Comparison to give a sorting by decreasing rapidity 01298 /// @deprecated Use cmpMomByDescRap 01299 DEPRECATED("Use cmpMomByDescRap") 01300 inline bool cmpMomByDescRapidity(const FourMomentum& a, const FourMomentum& b) { 01301 return cmpMomByDescRap(a,b); 01302 } 01303 01304 /// Comparison to give a sorting by increasing absolute rapidity 01305 inline bool cmpMomByAbsRap(const FourMomentum& a, const FourMomentum& b) { 01306 return fabs(a.rapidity()) < fabs(b.rapidity()); 01307 } 01308 /// Comparison to give a sorting by increasing absolute rapidity 01309 /// @deprecated Use cmpMomByAbsRap 01310 DEPRECATED("Use cmpMomByAbsRap") 01311 inline bool cmpMomByAscAbsRapidity(const FourMomentum& a, const FourMomentum& b) { 01312 return cmpMomByAbsRap(a,b); 01313 } 01314 01315 /// Comparison to give a sorting by decreasing absolute rapidity 01316 inline bool cmpMomByDescAbsRap(const FourMomentum& a, const FourMomentum& b) { 01317 return fabs(a.rapidity()) > fabs(b.rapidity()); 01318 } 01319 /// Comparison to give a sorting by decreasing absolute rapidity 01320 /// @deprecated Use cmpMomByDescAbsRap 01321 DEPRECATED("Use cmpMomByDescAbsRap") 01322 inline bool cmpMomByDescAbsRapidity(const FourMomentum& a, const FourMomentum& b) { 01323 return cmpMomByDescAbsRap(a,b); 01324 } 01325 01326 /// @todo Add sorting by phi [0..2PI] 01327 01328 01329 /// Sort a container of momenta by cmp and return by reference for non-const inputs 01330 template<typename MOMS, typename CMP> 01331 inline MOMS& sortBy(MOMS& pbs, const CMP& cmp) { 01332 std::sort(pbs.begin(), pbs.end(), cmp); 01333 return pbs; 01334 } 01335 /// Sort a container of momenta by cmp and return by value for const inputs 01336 template<typename MOMS, typename CMP> 01337 inline MOMS sortBy(const MOMS& pbs, const CMP& cmp) { 01338 MOMS rtn = pbs; 01339 std::sort(rtn.begin(), rtn.end(), cmp); 01340 return rtn; 01341 } 01342 01343 /// Sort a container of momenta by pT (decreasing) and return by reference for non-const inputs 01344 template<typename MOMS> 01345 inline MOMS& sortByPt(MOMS& pbs) { 01346 return sortBy(pbs, cmpMomByPt); 01347 } 01348 /// Sort a container of momenta by pT (decreasing) and return by value for const inputs 01349 template<typename MOMS> 01350 inline MOMS sortByPt(const MOMS& pbs) { 01351 return sortBy(pbs, cmpMomByPt); 01352 } 01353 01354 /// Sort a container of momenta by E (decreasing) and return by reference for non-const inputs 01355 template<typename MOMS> 01356 inline MOMS& sortByE(MOMS& pbs) { 01357 return sortBy(pbs, cmpMomByE); 01358 } 01359 /// Sort a container of momenta by E (decreasing) and return by value for const inputs 01360 template<typename MOMS> 01361 inline MOMS sortByE(const MOMS& pbs) { 01362 return sortBy(pbs, cmpMomByE); 01363 } 01364 01365 /// Sort a container of momenta by Et (decreasing) and return by reference for non-const inputs 01366 template<typename MOMS> 01367 inline MOMS& sortByEt(MOMS& pbs) { 01368 return sortBy(pbs, cmpMomByEt); 01369 } 01370 /// Sort a container of momenta by Et (decreasing) and return by value for const inputs 01371 template<typename MOMS> 01372 inline MOMS sortByEt(const MOMS& pbs) { 01373 return sortBy(pbs, cmpMomByEt); 01374 } 01375 01376 //@} 01377 01378 01379 ////////////////////////////////////////////////////// 01380 01381 01382 /// @name 4-vector string representations 01383 //@{ 01384 01385 /// Render a 4-vector as a string. 01386 inline std::string toString(const FourVector& lv) { 01387 ostringstream out; 01388 out << "(" << (fabs(lv.t()) < 1E-30 ? 0.0 : lv.t()) 01389 << "; " << (fabs(lv.x()) < 1E-30 ? 0.0 : lv.x()) 01390 << ", " << (fabs(lv.y()) < 1E-30 ? 0.0 : lv.y()) 01391 << ", " << (fabs(lv.z()) < 1E-30 ? 0.0 : lv.z()) 01392 << ")"; 01393 return out.str(); 01394 } 01395 01396 /// Write a 4-vector to an ostream. 01397 inline std::ostream& operator<<(std::ostream& out, const FourVector& lv) { 01398 out << toString(lv); 01399 return out; 01400 } 01401 01402 //@} 01403 01404 01405 /// @name Typedefs of vector types to short names 01406 /// @todo Switch canonical and alias names 01407 //@{ 01408 //typedef FourVector V4; //< generic 01409 typedef FourVector X4; //< spatial 01410 typedef FourMomentum P4; //< momentum 01411 //@} 01412 01413 01414 } 01415 01416 #endif Generated on Tue Dec 13 2016 16:32:41 for The Rivet MC analysis system by ![]() |