CLHEP 2.4.6.4
C++ Class Library for High Energy Physics
Loading...
Searching...
No Matches
ThreeVector.cc
Go to the documentation of this file.
1// -*- C++ -*-
2// $Id: ThreeVector.cc,v 1.3 2003/08/13 20:00:14 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 Hep3Vector class.
8//
9// See also ThreeVectorR.cc for implementation of Hep3Vector methods which
10// would couple in all the HepRotation methods.
11//
12
13#include "CLHEP/Vector/defs.h"
14#include "CLHEP/Vector/ThreeVector.h"
15#include "CLHEP/Vector/ZMxpv.h"
16#include "CLHEP/Units/PhysicalConstants.h"
17
18#include <cmath>
19#include <iostream>
20
21namespace CLHEP {
22
23void Hep3Vector::setMag(double ma) {
24 double factor = mag();
25 if (factor == 0) {
26 ZMthrowA ( ZMxpvZeroVector (
27 "Hep3Vector::setMag : zero vector can't be stretched"));
28 }else{
29 factor = ma/factor;
30 setX(x()*factor);
31 setY(y()*factor);
32 setZ(z()*factor);
33 }
34}
35
37 // NewUzVector must be normalized !
38
39 double u1 = NewUzVector.x();
40 double u2 = NewUzVector.y();
41 double u3 = NewUzVector.z();
42 double up = u1*u1 + u2*u2;
43
44 if (up > 0) {
45 up = std::sqrt(up);
46 double px = (u1 * u3 * x() - u2 * y()) / up + u1 * z();
47 double py = (u2 * u3 * x() + u1 * y()) / up + u2 * z();
48 double pz = -up * x() + u3 * z();
49 set(px, py, pz);
50 } else if (u3 < 0.) {
51 setX(-x());
52 setZ(-z());
53 } // phi=0 teta=pi
54
55 return *this;
56}
57
59 double m1 = mag();
60 if ( m1== 0 ) return 0.0;
61 if ( m1== z() ) return 1.0E72;
62 if ( m1== -z() ) return -1.0E72;
63 return 0.5*std::log( (m1+z())/(m1-z()) );
64}
65
66std::ostream & operator<< (std::ostream & os, const Hep3Vector & v) {
67 return os << "(" << v.x() << "," << v.y() << "," << v.z() << ")";
68}
69
70void ZMinput3doubles ( std::istream & is, const char * type,
71 double & x, double & y, double & z );
72
73std::istream & operator>>(std::istream & is, Hep3Vector & v) {
74 double x, y, z;
75 ZMinput3doubles ( is, "Hep3Vector", x, y, z );
76 v.set(x, y, z);
77 return is;
78} // operator>>()
79
80const Hep3Vector HepXHat(1.0, 0.0, 0.0);
81const Hep3Vector HepYHat(0.0, 1.0, 0.0);
82const Hep3Vector HepZHat(0.0, 0.0, 1.0);
83
84//-------------------
85//
86// New methods introduced when ZOOM PhysicsVectors was merged in:
87//
88//-------------------
89
91 double sinphi = std::sin(phi1);
92 double cosphi = std::cos(phi1);
93 double ty = y() * cosphi - z() * sinphi;
94 double tz = z() * cosphi + y() * sinphi;
95 setY(ty);
96 setZ(tz);
97 return *this;
98} /* rotateX */
99
101 double sinphi = std::sin(phi1);
102 double cosphi = std::cos(phi1);
103 double tx = x() * cosphi + z() * sinphi;
104 double tz = z() * cosphi - x() * sinphi;
105 setX(tx);
106 setZ(tz);
107 return *this;
108} /* rotateY */
109
111 double sinphi = std::sin(phi1);
112 double cosphi = std::cos(phi1);
113 double tx = x() * cosphi - y() * sinphi;
114 double ty = y() * cosphi + x() * sinphi;
115 setX(tx);
116 setY(ty);
117 return *this;
118} /* rotateZ */
119
120bool Hep3Vector::isNear(const Hep3Vector & v, double epsilon) const {
121 double limit = dot(v)*epsilon*epsilon;
122 return ( (*this - v).mag2() <= limit );
123} /* isNear() */
124
125double Hep3Vector::howNear(const Hep3Vector & v ) const {
126 // | V1 - V2 | **2 / V1 dot V2, up to 1
127 double d = (*this - v).mag2();
128 double vdv = dot(v);
129 if ( (vdv > 0) && (d < vdv) ) {
130 return std::sqrt (d/vdv);
131 } else if ( (vdv == 0) && (d == 0) ) {
132 return 0;
133 } else {
134 return 1;
135 }
136} /* howNear */
137
138double Hep3Vector::deltaPhi (const Hep3Vector & v2) const {
139 double dphi = v2.getPhi() - getPhi();
140 if ( dphi > CLHEP::pi ) {
141 dphi -= CLHEP::twopi;
142 } else if ( dphi <= -CLHEP::pi ) {
143 dphi += CLHEP::twopi;
144 }
145 return dphi;
146} /* deltaPhi */
147
148double Hep3Vector::deltaR ( const Hep3Vector & v ) const {
149 double a = eta() - v.eta();
150 double b = deltaPhi(v);
151 return std::sqrt ( a*a + b*b );
152} /* deltaR */
153
154double Hep3Vector::cosTheta(const Hep3Vector & q) const {
155 double arg;
156 double ptot2 = mag2()*q.mag2();
157 if(ptot2 <= 0) {
158 arg = 0.0;
159 }else{
160 arg = dot(q)/std::sqrt(ptot2);
161 if(arg > 1.0) arg = 1.0;
162 if(arg < -1.0) arg = -1.0;
163 }
164 return arg;
165}
166
167double Hep3Vector::cos2Theta(const Hep3Vector & q) const {
168 double arg;
169 double ptot2 = mag2();
170 double qtot2 = q.mag2();
171 if ( ptot2 == 0 || qtot2 == 0 ) {
172 arg = 1.0;
173 }else{
174 double pdq = dot(q);
175 arg = (pdq/ptot2) * (pdq/qtot2);
176 // More naive methods overflow on vectors which can be squared
177 // but can't be raised to the 4th power.
178 if(arg > 1.0) arg = 1.0;
179 }
180 return arg;
181}
182
183void Hep3Vector::setEta (double eta1) {
184 double phi1 = 0;
185 double r1;
186 if ( (x() == 0) && (y() == 0) ) {
187 if (z() == 0) {
188 ZMthrowC (ZMxpvZeroVector(
189 "Attempt to set eta of zero vector -- vector is unchanged"));
190 return;
191 }
192 ZMthrowC (ZMxpvZeroVector(
193 "Attempt to set eta of vector along Z axis -- will use phi = 0"));
194 r1 = std::fabs(z());
195 } else {
196 r1 = getR();
197 phi1 = getPhi();
198 }
199 double tanHalfTheta = std::exp ( -eta1 );
200 double cosTheta1 =
201 (1 - tanHalfTheta*tanHalfTheta) / (1 + tanHalfTheta*tanHalfTheta);
202 double rho1 = r1*std::sqrt(1 - cosTheta1*cosTheta1);
203 setZ(r1 * cosTheta1);
204 setY(rho1 * std::sin (phi1));
205 setX(rho1 * std::cos (phi1));
206 return;
207}
208
209void Hep3Vector::setCylTheta (double theta1) {
210
211 // In cylindrical coords, set theta while keeping rho and phi fixed
212
213 if ( (x() == 0) && (y() == 0) ) {
214 if (z() == 0) {
215 ZMthrowC (ZMxpvZeroVector(
216 "Attempt to set cylTheta of zero vector -- vector is unchanged"));
217 return;
218 }
219 if (theta1 == 0) {
220 setZ(std::fabs(z()));
221 return;
222 }
223 if (theta1 == CLHEP::pi) {
224 setZ(-std::fabs(z()));
225 return;
226 }
227 ZMthrowC (ZMxpvZeroVector(
228 "Attempt set cylindrical theta of vector along Z axis "
229 "to a non-trivial value, while keeping rho fixed -- "
230 "will return zero vector"));
231 setZ(0.0);
232 return;
233 }
234 if ( (theta1 < 0) || (theta1 > CLHEP::pi) ) {
235 ZMthrowC (ZMxpvUnusualTheta(
236 "Setting Cyl theta of a vector based on a value not in [0, PI]"));
237 // No special return needed if warning is ignored.
238 }
239 double phi1 (getPhi());
240 double rho1 = getRho();
241 if ( (theta1 == 0) || (theta1 == CLHEP::pi) ) {
242 ZMthrowC (ZMxpvInfiniteVector(
243 "Attempt to set cylindrical theta to 0 or PI "
244 "while keeping rho fixed -- infinite Z will be computed"));
245 setZ((theta1==0) ? 1.0E72 : -1.0E72);
246 return;
247 }
248 setZ(rho1 / std::tan (theta1));
249 setY(rho1 * std::sin (phi1));
250 setX(rho1 * std::cos (phi1));
251
252} /* setCylTheta */
253
254void Hep3Vector::setCylEta (double eta1) {
255
256 // In cylindrical coords, set eta while keeping rho and phi fixed
257
258 double theta1 = 2 * std::atan ( std::exp (-eta1) );
259
260 //-| The remaining code is similar to setCylTheta, The reason for
261 //-| using a copy is so as to be able to change the messages in the
262 //-| ZMthrows to say eta rather than theta. Besides, we assumedly
263 //-| need not check for theta of 0 or PI.
264
265 if ( (x() == 0) && (y() == 0) ) {
266 if (z() == 0) {
267 ZMthrowC (ZMxpvZeroVector(
268 "Attempt to set cylEta of zero vector -- vector is unchanged"));
269 return;
270 }
271 if (theta1 == 0) {
272 setZ(std::fabs(z()));
273 return;
274 }
275 if (theta1 == CLHEP::pi) {
276 setZ(-std::fabs(z()));
277 return;
278 }
279 ZMthrowC (ZMxpvZeroVector(
280 "Attempt set cylindrical eta of vector along Z axis "
281 "to a non-trivial value, while keeping rho fixed -- "
282 "will return zero vector"));
283 setZ(0.0);
284 return;
285 }
286 double phi1 (getPhi());
287 double rho1 = getRho();
288 setZ(rho1 / std::tan (theta1));
289 setY(rho1 * std::sin (phi1));
290 setX(rho1 * std::cos (phi1));
291
292} /* setCylEta */
293
294
295Hep3Vector operator/ ( const Hep3Vector & v1, double c ) {
296 if (c == 0) {
297 ZMthrowA ( ZMxpvInfiniteVector (
298 "Attempt to divide vector by 0 -- "
299 "will produce infinities and/or NANs"));
300 }
301 return v1 * (1.0/c);
302} /* v / c */
303
305 if (c == 0) {
306 ZMthrowA (ZMxpvInfiniteVector(
307 "Attempt to do vector /= 0 -- "
308 "division by zero would produce infinite or NAN components"));
309 }
310 *this *= 1.0/c;
311 return *this;
312}
313
315
316} // namespace CLHEP
317
318
319
#define ZMthrowC(A)
Definition: ZMxpv.h:133
#define ZMthrowA(A)
Definition: ZMxpv.h:128
Hep3Vector & rotateY(double)
Definition: ThreeVector.cc:100
double z() const
void setEta(double p)
Definition: ThreeVector.cc:183
Hep3Vector & rotateX(double)
Definition: ThreeVector.cc:90
double eta() const
double cos2Theta() const
static double tolerance
Definition: ThreeVector.h:394
double x() const
void setY(double)
double mag2() const
double getR() const
Hep3Vector & rotateZ(double)
Definition: ThreeVector.cc:110
static const int ToleranceTicks
Definition: ThreeVector.h:295
Hep3Vector & operator/=(double)
Definition: ThreeVector.cc:304
double y() const
void setCylEta(double p)
Definition: ThreeVector.cc:254
double howNear(const Hep3Vector &v) const
Definition: ThreeVector.cc:125
double dot(const Hep3Vector &) const
void setZ(double)
double mag() const
bool isNear(const Hep3Vector &, double epsilon=tolerance) const
Definition: ThreeVector.cc:120
double pseudoRapidity() const
Definition: ThreeVector.cc:58
double getRho() const
double deltaPhi(const Hep3Vector &v2) const
Definition: ThreeVector.cc:138
void set(double x, double y, double z)
void setMag(double)
Definition: ThreeVector.cc:23
double getPhi() const
double deltaR(const Hep3Vector &v) const
Definition: ThreeVector.cc:148
void setX(double)
Hep3Vector & rotateUz(const Hep3Vector &)
Definition: ThreeVector.cc:36
double cosTheta() const
void setCylTheta(double)
Definition: ThreeVector.cc:209
std::istream & operator>>(std::istream &is, HepRandom &dist)
Definition: Random.cc:225
std::ostream & operator<<(std::ostream &s, const HepDiagMatrix &q)
Definition: DiagMatrix.cc:560
void ZMinput3doubles(std::istream &is, const char *type, double &x, double &y, double &z)
Definition: ZMinput.cc:37
const Hep3Vector HepYHat(0.0, 1.0, 0.0)
Definition: ThreeVector.h:419
const Hep3Vector HepXHat(1.0, 0.0, 0.0)
Definition: ThreeVector.h:419
HepDiagMatrix operator/(const HepDiagMatrix &hm1, double t)
Definition: DiagMatrix.cc:335
const Hep3Vector HepZHat(0.0, 0.0, 1.0)
Definition: ThreeVector.h:419