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