Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
LorentzVectorC.cc
Go to the documentation of this file.
1// -*- C++ -*-
2// ---------------------------------------------------------------------------
3//
4// This file is a part of the CLHEP - a Class Library for High Energy Physics.
5//
6// This is the implementation of the HepLorentzVector class:
7// Those methods originating with ZOOM dealing with comparison (other than
8// isSpaceLike, isLightlike, isTimelike, which are in the main part.)
9//
10// 11/29/05 mf in deltaR, replaced the direct subtraction
11// pp.phi() - w.getV().phi() with pp.deltaRPhi(w.getV()) which behaves
12// correctly across the 2pi boundary.
13
15
16#include <cmath>
17#include <iostream>
18
19namespace CLHEP {
20
21//-***********
22// Comparisons
23//-***********
24
26 if ( ee > w.ee ) {
27 return 1;
28 } else if ( ee < w.ee ) {
29 return -1;
30 } else {
31 return ( pp.compare(w.pp) );
32 }
33} /* Compare */
34
36 return (compare(w) > 0);
37}
39 return (compare(w) < 0);
40}
42 return (compare(w) >= 0);
43}
45 return (compare(w) <= 0);
46}
47
48//-********
49// isNear
50// howNear
51//-********
52
54 double epsilon) const {
55 double limit = std::fabs(pp.dot(w.pp));
56 limit += .25*((ee+w.ee)*(ee+w.ee));
57 limit *= epsilon*epsilon;
58 double delta = (pp - w.pp).mag2();
59 delta += (ee-w.ee)*(ee-w.ee);
60 return (delta <= limit );
61} /* isNear() */
62
64 double wdw = std::fabs(pp.dot(w.pp)) + .25*((ee+w.ee)*(ee+w.ee));
65 double delta = (pp - w.pp).mag2() + (ee-w.ee)*(ee-w.ee);
66 if ( (wdw > 0) && (delta < wdw) ) {
67 return std::sqrt (delta/wdw);
68 } else if ( (wdw == 0) && (delta == 0) ) {
69 return 0;
70 } else {
71 return 1;
72 }
73} /* howNear() */
74
75//-*********
76// isNearCM
77// howNearCM
78//-*********
79
81 (const HepLorentzVector & w, double epsilon) const {
82
83 double tTotal = (ee + w.ee);
84 Hep3Vector vTotal (pp + w.pp);
85 double vTotal2 = vTotal.mag2();
86
87 if ( vTotal2 >= tTotal*tTotal ) {
88 // Either one or both vectors are spacelike, or the dominant T components
89 // are in opposite directions. So boosting and testing makes no sense;
90 // but we do consider two exactly equal vectors to be equal in any frame,
91 // even if they are spacelike and can't be boosted to a CM frame.
92 return (*this == w);
93 }
94
95 if ( vTotal2 == 0 ) { // no boost needed!
96 return (isNear(w, epsilon));
97 }
98
99 // Find the boost to the CM frame. We know that the total vector is timelike.
100
101 double tRecip = 1./tTotal;
102 Hep3Vector bboost ( vTotal * (-tRecip) );
103
104 //-| Note that you could do pp/t and not be terribly inefficient since
105 //-| SpaceVector/t itself takes 1/t and multiplies. The code here saves
106 //-| a redundant check for t=0.
107
108 // Boost both vectors. Since we have the same boost, there is no need
109 // to repeat the beta and gamma calculation; and there is no question
110 // about beta >= 1. That is why we don't just call w.boosted().
111
112 double b2 = vTotal2*tRecip*tRecip;
113
114 double ggamma = std::sqrt(1./(1.-b2));
115 double boostDotV1 = bboost.dot(pp);
116 double gm1_b2 = (ggamma-1)/b2;
117
118 HepLorentzVector w1 ( pp + ((gm1_b2)*boostDotV1+ggamma*ee) * bboost,
119 ggamma * (ee + boostDotV1) );
120
121 double boostDotV2 = bboost.dot(w.pp);
122 HepLorentzVector w2 ( w.pp + ((gm1_b2)*boostDotV2+ggamma*w.ee) * bboost,
123 ggamma * (w.ee + boostDotV2) );
124
125 return (w1.isNear(w2, epsilon));
126
127} /* isNearCM() */
128
130
131 double tTotal = (ee + w.ee);
132 Hep3Vector vTotal (pp + w.pp);
133 double vTotal2 = vTotal.mag2();
134
135 if ( vTotal2 >= tTotal*tTotal ) {
136 // Either one or both vectors are spacelike, or the dominant T components
137 // are in opposite directions. So boosting and testing makes no sense;
138 // but we do consider two exactly equal vectors to be equal in any frame,
139 // even if they are spacelike and can't be boosted to a CM frame.
140 if (*this == w) {
141 return 0;
142 } else {
143 return 1;
144 }
145 }
146
147 if ( vTotal2 == 0 ) { // no boost needed!
148 return (howNear(w));
149 }
150
151 // Find the boost to the CM frame. We know that the total vector is timelike.
152
153 double tRecip = 1./tTotal;
154 Hep3Vector bboost ( vTotal * (-tRecip) );
155
156 //-| Note that you could do pp/t and not be terribly inefficient since
157 //-| SpaceVector/t itself takes 1/t and multiplies. The code here saves
158 //-| a redundant check for t=0.
159
160 // Boost both vectors. Since we have the same boost, there is no need
161 // to repeat the beta and gamma calculation; and there is no question
162 // about beta >= 1. That is why we don't just call w.boosted().
163
164 double b2 = vTotal2*tRecip*tRecip;
165// if ( b2 >= 1 ) { // NaN-proofing
166// std::cerr << "HepLorentzVector::howNearCM() - "
167// << "boost vector in howNearCM appears to be tachyonic" << std::endl;
168// }
169 double ggamma = std::sqrt(1./(1.-b2));
170 double boostDotV1 = bboost.dot(pp);
171 double gm1_b2 = (ggamma-1)/b2;
172
173 HepLorentzVector w1 ( pp + ((gm1_b2)*boostDotV1+ggamma*ee) * bboost,
174 ggamma * (ee + boostDotV1) );
175
176 double boostDotV2 = bboost.dot(w.pp);
177 HepLorentzVector w2 ( w.pp + ((gm1_b2)*boostDotV2+ggamma*w.ee) * bboost,
178 ggamma * (w.ee + boostDotV2) );
179
180 return (w1.howNear(w2));
181
182} /* howNearCM() */
183
184//-************
185// deltaR
186// isParallel
187// howParallel
188// howLightlike
189//-************
190
191double HepLorentzVector::deltaR ( const HepLorentzVector & w ) const {
192
193 double a = eta() - w.eta();
194 double b = pp.deltaPhi(w.getV());
195
196 return std::sqrt ( a*a + b*b );
197
198} /* deltaR */
199
200// If the difference (in the Euclidean norm) of the normalized (in Euclidean
201// norm) 4-vectors is small, then those 4-vectors are considered nearly
202// parallel.
203
205 double norm = euclideanNorm();
206 double wnorm = w.euclideanNorm();
207 if ( norm == 0 ) {
208 if ( wnorm == 0 ) {
209 return true;
210 } else {
211 return false;
212 }
213 }
214 if ( wnorm == 0 ) {
215 return false;
216 }
217 HepLorentzVector w1 = *this / norm;
218 HepLorentzVector w2 = w / wnorm;
219 return ( (w1-w2).euclideanNorm2() <= epsilon*epsilon );
220} /* isParallel */
221
222
224
225 double norm = euclideanNorm();
226 double wnorm = w.euclideanNorm();
227 if ( norm == 0 ) {
228 if ( wnorm == 0 ) {
229 return 0;
230 } else {
231 return 1;
232 }
233 }
234 if ( wnorm == 0 ) {
235 return 1;
236 }
237
238 HepLorentzVector w1 = *this / norm;
239 HepLorentzVector w2 = w / wnorm;
240 double x1 = (w1-w2).euclideanNorm();
241 return (x1 < 1) ? x1 : 1;
242
243} /* howParallel */
244
246 double m1 = std::fabs(restMass2());
247 double twoT2 = 2*ee*ee;
248 if (m1 < twoT2) {
249 return m1/twoT2;
250 } else {
251 return 1;
252 }
253} /* HowLightlike */
254
255} // namespace CLHEP
G4double epsilon(G4double density, G4double temperature)
double mag2() const
double dot(const Hep3Vector &) const
double deltaPhi(const Hep3Vector &v2) const
Definition: ThreeVector.cc:135
int compare(const Hep3Vector &v) const
Definition: SpaceVector.cc:118
bool isParallel(const HepLorentzVector &w, double epsilon=tolerance) const
bool isNearCM(const HepLorentzVector &w, double epsilon=tolerance) const
Hep3Vector getV() const
int compare(const HepLorentzVector &w) const
double howParallel(const HepLorentzVector &w) const
bool operator<=(const HepLorentzVector &w) const
double restMass2() const
double deltaR(const HepLorentzVector &v) const
double euclideanNorm() const
double howNear(const HepLorentzVector &w) const
double howLightlike() const
double howNearCM(const HepLorentzVector &w) const
bool operator<(const HepLorentzVector &w) const
double euclideanNorm2() const
bool isNear(const HepLorentzVector &w, double epsilon=tolerance) const
bool operator>(const HepLorentzVector &w) const
bool operator>=(const HepLorentzVector &w) const
Definition: DoubConv.h:17