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