CLHEP 2.0.4.7 Reference Documentation
CLHEP Home Page CLHEP Documentation CLHEP Bug Reports |
00001 // -*- C++ -*- 00002 // --------------------------------------------------------------------------- 00003 // 00004 // This file is a part of the CLHEP - a Class Library for High Energy Physics. 00005 // 00006 // This is part of the implementation of the HepLorentzVector class: 00007 // Those methods which originated from ZOOM and which deal with relativistic 00008 // kinematic properties. 00009 // 00010 00011 #ifdef GNUPRAGMA 00012 #pragma implementation 00013 #endif 00014 00015 #include "CLHEP/Vector/defs.h" 00016 #include "CLHEP/Vector/LorentzVector.h" 00017 #include "CLHEP/Vector/ZMxpv.h" 00018 00019 #include <cmath> 00020 00021 namespace CLHEP { 00022 00023 //-****************** 00024 // Metric flexibility 00025 //-****************** 00026 00027 ZMpvMetric_t HepLorentzVector::setMetric( ZMpvMetric_t m ) { 00028 ZMpvMetric_t oldMetric = (metric > 0) ? TimePositive : TimeNegative; 00029 if ( m == TimeNegative ) { 00030 metric = -1.0; 00031 } else { 00032 metric = 1.0; 00033 } 00034 return oldMetric; 00035 } 00036 00037 ZMpvMetric_t HepLorentzVector::getMetric() { 00038 return ( (metric > 0) ? TimePositive : TimeNegative ); 00039 } 00040 00041 //-******** 00042 // plus 00043 // minus 00044 //-******** 00045 00046 double HepLorentzVector::plus (const Hep3Vector & ref) const { 00047 double r = ref.mag(); 00048 if (r == 0) { 00049 ZMthrowA (ZMxpvZeroVector( 00050 "A zero vector used as reference to LorentzVector plus-part")); 00051 return ee; 00052 } 00053 return ee + pp.dot(ref)/r; 00054 } /* plus */ 00055 00056 double HepLorentzVector::minus (const Hep3Vector & ref) const { 00057 double r = ref.mag(); 00058 if (r == 0) { 00059 ZMthrowA (ZMxpvZeroVector( 00060 "A zero vector used as reference to LorentzVector minus-part")); 00061 return ee; 00062 } 00063 return ee - pp.dot(ref)/r; 00064 } /* plus */ 00065 00066 HepLorentzVector HepLorentzVector::rest4Vector() const { 00067 return HepLorentzVector (0, 0, 0, (t() < 0.0 ? -m() : m())); 00068 } 00069 00070 //-******** 00071 // beta 00072 // gamma 00073 //-******** 00074 00075 double HepLorentzVector::beta() const { 00076 if (ee == 0) { 00077 if (pp.mag2() == 0) { 00078 return 0; 00079 } else { 00080 ZMthrowA (ZMxpvInfiniteVector( 00081 "beta computed for HepLorentzVector with t=0 -- infinite result")); 00082 return 1./ee; 00083 } 00084 } 00085 if (restMass2() <= 0) { 00086 ZMthrowC (ZMxpvTachyonic( 00087 "beta computed for a non-timelike HepLorentzVector")); 00088 // result will make analytic sense but is physically meaningless 00089 } 00090 return sqrt (pp.mag2() / (ee*ee)) ; 00091 } /* beta */ 00092 00093 double HepLorentzVector::gamma() const { 00094 double v2 = pp.mag2(); 00095 double t2 = ee*ee; 00096 if (ee == 0) { 00097 if (pp.mag2() == 0) { 00098 return 1; 00099 } else { 00100 ZMthrowC (ZMxpvInfiniteVector( 00101 "gamma computed for HepLorentzVector with t=0 -- zero result")); 00102 return 0; 00103 } 00104 } 00105 if (t2 < v2) { 00106 ZMthrowA (ZMxpvSpacelike( 00107 "gamma computed for a spacelike HepLorentzVector -- imaginary result")); 00108 // analytic result would be imaginary. 00109 return 0; 00110 } else if ( t2 == v2 ) { 00111 ZMthrowA (ZMxpvInfinity( 00112 "gamma computed for a lightlike HepLorentzVector -- infinite result")); 00113 } 00114 return 1./sqrt(1. - v2/t2 ); 00115 } /* gamma */ 00116 00117 00118 //-*************** 00119 // rapidity 00120 // pseudorapidity 00121 // eta 00122 //-*************** 00123 00124 double HepLorentzVector::rapidity() const { 00125 register double z = pp.getZ(); 00126 if (fabs(ee) == fabs(z)) { 00127 ZMthrowA (ZMxpvInfinity( 00128 "rapidity for 4-vector with |E| = |Pz| -- infinite result")); 00129 } 00130 if (fabs(ee) < fabs(z)) { 00131 ZMthrowA (ZMxpvSpacelike( 00132 "rapidity for spacelike 4-vector with |E| < |Pz| -- undefined")); 00133 return 0; 00134 } 00135 double q = (ee + z) / (ee - z); 00136 //-| This cannot be negative now, since both numerator 00137 //-| and denominator have the same sign as ee. 00138 return .5 * log(q); 00139 } /* rapidity */ 00140 00141 double HepLorentzVector::rapidity(const Hep3Vector & ref) const { 00142 register double r = ref.mag2(); 00143 if (r == 0) { 00144 ZMthrowA (ZMxpvZeroVector( 00145 "A zero vector used as reference to LorentzVector rapidity")); 00146 return 0; 00147 } 00148 register double vdotu = pp.dot(ref)/sqrt(r); 00149 if (fabs(ee) == fabs(vdotu)) { 00150 ZMthrowA (ZMxpvInfinity( 00151 "rapidity for 4-vector with |E| = |Pu| -- infinite result")); 00152 } 00153 if (fabs(ee) < fabs(vdotu)) { 00154 ZMthrowA (ZMxpvSpacelike( 00155 "rapidity for spacelike 4-vector with |E| < |P*ref| -- undefined ")); 00156 return 0; 00157 } 00158 double q = (ee + vdotu) / (ee - vdotu); 00159 return .5 * log(q); 00160 } /* rapidity(ref) */ 00161 00162 double HepLorentzVector::coLinearRapidity() const { 00163 register double v = pp.mag(); 00164 if (fabs(ee) == fabs(v)) { 00165 ZMthrowA (ZMxpvInfinity( 00166 "co-Linear rapidity for 4-vector with |E| = |P| -- infinite result")); 00167 } 00168 if (fabs(ee) < fabs(v)) { 00169 ZMthrowA (ZMxpvSpacelike( 00170 "co-linear rapidity for spacelike 4-vector -- undefined")); 00171 return 0; 00172 } 00173 double q = (ee + v) / (ee - v); 00174 return .5 * log(q); 00175 } /* rapidity */ 00176 00177 //-************* 00178 // invariantMass 00179 //-************* 00180 00181 double HepLorentzVector::invariantMass(const HepLorentzVector & w) const { 00182 double m2 = invariantMass2(w); 00183 if (m2 < 0) { 00184 // We should find out why: 00185 if ( ee * w.ee < 0 ) { 00186 ZMthrowA (ZMxpvNegativeMass( 00187 "invariant mass meaningless: \n" 00188 "a negative-mass input led to spacelike 4-vector sum" )); 00189 return 0; 00190 } else if ( (isSpacelike() && !isLightlike()) || 00191 (w.isSpacelike() && !w.isLightlike()) ) { 00192 ZMthrowA (ZMxpvSpacelike( 00193 "invariant mass meaningless because of spacelike input")); 00194 return 0; 00195 } else { 00196 // Invariant mass squared for a pair of timelike or lightlike vectors 00197 // mathematically cannot be negative. If the vectors are within the 00198 // tolerance of being lightlike or timelike, we can assume that prior 00199 // or current roundoffs have caused the negative result, and return 0 00200 // without comment. 00201 return 0; 00202 } 00203 } 00204 return (ee+w.ee >=0 ) ? sqrt(m2) : - sqrt(m2); 00205 } /* invariantMass */ 00206 00207 //-*************** 00208 // findBoostToCM 00209 //-*************** 00210 00211 Hep3Vector HepLorentzVector::findBoostToCM() const { 00212 return -boostVector(); 00213 } /* boostToCM() */ 00214 00215 Hep3Vector HepLorentzVector::findBoostToCM (const HepLorentzVector & w) const { 00216 double t = ee + w.ee; 00217 Hep3Vector v = pp + w.pp; 00218 if (t == 0) { 00219 if (v.mag2() == 0) { 00220 return Hep3Vector(0,0,0); 00221 } else { 00222 ZMthrowA (ZMxpvInfiniteVector( 00223 "boostToCM computed for two 4-vectors with combined t=0 -- " 00224 "infinite result")); 00225 return Hep3Vector(v*(1./t)); // Yup, 1/0 -- that is how we return infinity 00226 } 00227 } 00228 if (t*t - v.mag2() <= 0) { 00229 ZMthrowC (ZMxpvTachyonic( 00230 "boostToCM computed for pair of HepLorentzVectors with non-timelike sum")); 00231 // result will make analytic sense but is physically meaningless 00232 } 00233 return Hep3Vector(v * (-1./t)); 00234 } /* boostToCM(w) */ 00235 00236 } // namespace CLHEP 00237