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