8#include <framework/utilities/TestHelpers.h>
9#include <framework/geometry/B2Vector3.h>
13#include <gtest/gtest.h>
20 struct PointRThetaPhi {
double r;
double theta;
double phi; };
21 struct PointXYZ {
double X;
double Y;
double Z; };
22 std::vector<PointRThetaPhi> test_vectors(
const std::vector<double>& R = {1},
int nTheta = 3,
int nPhi = 4,
bool prune =
true)
24 std::vector<PointRThetaPhi> result;
25 auto get_theta = [nTheta](
int i) ->
double {
26 if (nTheta < 2)
return 0.;
27 return M_PI / (nTheta - 1) * i;
29 auto get_phi = [nPhi](
int i) ->
double {
30 if (nPhi < 2)
return 0.;
31 return 2 * M_PI / nPhi * i;
35 for (
int i = 0; i < nTheta || (nTheta < 2 && i == 0); ++i) {
36 double theta = get_theta(i);
37 for (
int j = 0; j < nPhi || (nPhi < 2 && j == 0); ++j) {
38 double phi = get_phi(j);
39 result.push_back(PointRThetaPhi{r, theta, phi});
41 if (prune && (theta == 0 || theta == M_PI))
break;
44 if (prune && r == 0)
break;
52 gErrorIgnoreLevel = kError;
55 for (
auto& rtp : test_vectors({0, 1, 1e20}, 64, 64)) {
58 EXPECT_EQ(bvec, tvec);
61 EXPECT_EQ(bvec2, bvec);
62 TVector3 tvec2 = bvec;
63 EXPECT_EQ(tvec2, tvec);
76 EXPECT_DOUBLE_EQ(bvec.
X(), tvec.X()) << bvec.
PrintString();
77 EXPECT_DOUBLE_EQ(bvec.
Y(), tvec.Y()) << bvec.
PrintString();
78 EXPECT_DOUBLE_EQ(bvec.
Z(), tvec.Z()) << bvec.
PrintString();
79 EXPECT_DOUBLE_EQ(bvec.
X(), tvec.X()) << bvec.
PrintString();
80 EXPECT_DOUBLE_EQ(bvec.
Y(), tvec.Y()) << bvec.
PrintString();
81 EXPECT_DOUBLE_EQ(bvec.
Z(), tvec.Z()) << bvec.
PrintString();
92 gErrorIgnoreLevel = kError;
95 for (
auto& rtp : test_vectors({0, 1, 1e20}, 16, 16)) {
101 for (
auto& rtp2 : test_vectors({0, 1, 1e20}, 16, 16)) {
120 gErrorIgnoreLevel = kError;
126 tvec.SetXYZ(1., 0., 0.);
128 tvec.Rotate(M_PI_2, TVector3(0., 0., 1.));
133 EXPECT_NEAR(bvec.
X(), tvec.X(), 1e-14) << bvec.
PrintString();
134 EXPECT_NEAR(bvec.
Y(), tvec.Y(), 1e-14) << bvec.
PrintString();
135 EXPECT_NEAR(bvec.
Z(), tvec.Z(), 1e-14) << bvec.
PrintString();
139 tvec.SetXYZ(1., 0., 0.);
141 tvec.Rotate(M_PI, TVector3(0., 0., 1.));
142 EXPECT_NEAR(bvec.
X(), -1., 1e-14) << bvec.
PrintString();
146 EXPECT_NEAR(bvec.
X(), tvec.X(), 1e-14) << bvec.
PrintString();
147 EXPECT_NEAR(bvec.
Y(), tvec.Y(), 1e-14) << bvec.
PrintString();
148 EXPECT_NEAR(bvec.
Z(), tvec.Z(), 1e-14) << bvec.
PrintString();
152 tvec.SetXYZ(4., 3., 2.);
154 tvec.Rotate(M_PI / 2.5, TVector3(1., 2., 3.));
161 EXPECT_NEAR(bvec.
X(), tvec.X(), 1e-14) << bvec.
PrintString();
162 EXPECT_NEAR(bvec.
Y(), tvec.Y(), 1e-14) << bvec.
PrintString();
163 EXPECT_NEAR(bvec.
Z(), tvec.Z(), 1e-14) << bvec.
PrintString();
167 const TVector3 taxis(4., 3., -2.);
169 for (
auto& rtp : test_vectors({0, 1, 1e20}, 64, 64)) {
171 double epsilon = (rtp.r < 1e10 ? 1e-10 : rtp.r * 1e-10);
174 for (
int i = 0; i < 28; i++) {
175 double angle = 2.*M_PI / 28 * i;
176 tvec.SetMagThetaPhi(rtp.r, rtp.theta, rtp.phi);
178 bvec.
Rotate(angle, baxis);
179 tvec.Rotate(angle, taxis);
183 if (fabs(fabs(bvec.
Phi() - tvec.Phi()) - 2.*M_PI) < 1e-14) {
195 EXPECT_NEAR(bvec.
X(), tvec.X(), epsilon) << bvec.
PrintString();
196 EXPECT_NEAR(bvec.
Y(), tvec.Y(), epsilon) << bvec.
PrintString();
197 EXPECT_NEAR(bvec.
Z(), tvec.Z(), epsilon) << bvec.
PrintString();
A fast and root compatible alternative to TVector3.
DataType Phi() const
The azimuth angle.
DataType Pz() const
access variable Z (= .at(2) without boundary check)
DataType Z() const
access variable Z (= .at(2) without boundary check)
DataType Perp2() const
The transverse component squared (R^2 in cylindrical coordinate system).
DataType Theta() const
The polar angle.
DataType CosTheta() const
Cosine of the polar angle.
void SetMagThetaPhi(DataType mag, DataType theta, DataType phi)
setter with mag, theta, phi
DataType X() const
access variable X (= .at(0) without boundary check)
DataType Eta() const
Returns the pseudo-rapidity.
DataType DeltaPhi(const B2Vector3< DataType > &v) const
returns phi in the interval [-PI,PI)
DataType Y() const
access variable Y (= .at(1) without boundary check)
std::string PrintString(unsigned precision=4) const
create a string containing vector in cartesian and spherical coordinates
DataType Mag() const
The magnitude (rho in spherical coordinate system).
DataType DeltaR(const B2Vector3< DataType > &v) const
return deltaR with respect to input-vector
DataType Mag2() const
The magnitude squared (rho^2 in spherical coordinate system).
DataType Dot(const B2Vector3< DataType > &p) const
Scalar product.
DataType PseudoRapidity() const
Returns the pseudo-rapidity, i.e.
DataType DrEtaPhi(const B2Vector3< DataType > &v) const
return DrEtaPhi with respect to input-vector
DataType Perp() const
The transverse component (R in cylindrical coordinate system).
DataType Py() const
access variable Y (= .at(1) without boundary check)
DataType Pt() const
The transverse component (R in cylindrical coordinate system).
DataType Px() const
access variable X (= .at(0) without boundary check)
void SetXYZ(DataType x, DataType y, DataType z)
set all coordinates using data type
DataType Angle(const B2Vector3< DataType > &q) const
The angle w.r.t.
void Rotate(DataType alpha, const B2Vector3< DataType > &v)
Rotation around an arbitrary axis v with angle alpha.
void SetPhi(DataType phi)
Set phi keeping mag and theta constant.
B2Vector3< double > B2Vector3D
typedef for common usage with double
Abstract base class for different kinds of events.