8#include <framework/geometry/B2Vector3.h> 
   12#include <gtest/gtest.h> 
   19  struct PointRThetaPhi { 
double r; 
double theta; 
double phi; };
 
   20  struct PointXYZ { 
double X; 
double Y; 
double Z; };
 
   21  std::vector<PointRThetaPhi> test_vectors(
const std::vector<double>& R = {1}, 
int nTheta = 3, 
int nPhi = 4, 
bool prune = 
true)
 
   23    std::vector<PointRThetaPhi> result;
 
   24    auto get_theta = [nTheta](
int i) -> 
double {
 
   25      if (nTheta < 2) 
return 0.;
 
   26      return M_PI / (nTheta - 1) * i;
 
   28    auto get_phi = [nPhi](
int i) -> 
double {
 
   29      if (nPhi < 2) 
return 0.;
 
   30      return 2 * M_PI / nPhi * i;
 
   34      for (
int i = 0; i < nTheta || (nTheta < 2 && i == 0); ++i) {
 
   35        double theta = get_theta(i);
 
   36        for (
int j = 0; j < nPhi || (nPhi < 2 && j == 0); ++j) {
 
   37          double phi = get_phi(j);
 
   38          result.push_back(PointRThetaPhi{r, theta, phi});
 
   40          if (prune && (theta == 0 || theta == M_PI)) 
break;
 
   43        if (prune && r == 0) 
break;
 
   51    gErrorIgnoreLevel = kError;
 
   54    for (
auto& rtp : test_vectors({0, 1, 1e20}, 64, 64)) {
 
   55      tvec.SetMagThetaPhi(rtp.r, rtp.theta, rtp.phi);
 
   57      EXPECT_EQ(bvec, tvec);
 
   60      EXPECT_EQ(bvec2, bvec);
 
   61      TVector3 tvec2 = bvec;
 
   62      EXPECT_EQ(tvec2, tvec);
 
   75      EXPECT_DOUBLE_EQ(bvec.
X(), tvec.X()) << bvec.
PrintString();
 
   76      EXPECT_DOUBLE_EQ(bvec.
Y(), tvec.Y()) << bvec.
PrintString();
 
   77      EXPECT_DOUBLE_EQ(bvec.
Z(), tvec.Z()) << bvec.
PrintString();
 
   78      EXPECT_DOUBLE_EQ(bvec.
X(), tvec.X()) << bvec.
PrintString();
 
   79      EXPECT_DOUBLE_EQ(bvec.
Y(), tvec.Y()) << bvec.
PrintString();
 
   80      EXPECT_DOUBLE_EQ(bvec.
Z(), tvec.Z()) << bvec.
PrintString();
 
   91    gErrorIgnoreLevel = kError;
 
   94    for (
auto& rtp : test_vectors({0, 1, 1e20}, 16, 16)) {
 
   95      tvec.SetMagThetaPhi(rtp.r, rtp.theta, rtp.phi);
 
  100      for (
auto& rtp2 : test_vectors({0, 1, 1e20}, 16, 16)) {
 
  101        tvec2.SetMagThetaPhi(rtp2.r, rtp2.theta, rtp2.phi);
 
  119    gErrorIgnoreLevel = kError;
 
  125    tvec.SetXYZ(1., 0., 0.);
 
  127    tvec.Rotate(M_PI_2, TVector3(0., 0., 1.));
 
  132    EXPECT_NEAR(bvec.
X(), tvec.X(), 1e-14) << bvec.
PrintString();
 
  133    EXPECT_NEAR(bvec.
Y(), tvec.Y(), 1e-14) << bvec.
PrintString();
 
  134    EXPECT_NEAR(bvec.
Z(), tvec.Z(), 1e-14) << bvec.
PrintString();
 
  138    tvec.SetXYZ(1., 0., 0.);
 
  140    tvec.Rotate(M_PI, TVector3(0., 0., 1.));
 
  141    EXPECT_NEAR(bvec.
X(), -1., 1e-14) << bvec.
PrintString();
 
  145    EXPECT_NEAR(bvec.
X(), tvec.X(), 1e-14) << bvec.
PrintString();
 
  146    EXPECT_NEAR(bvec.
Y(), tvec.Y(), 1e-14) << bvec.
PrintString();
 
  147    EXPECT_NEAR(bvec.
Z(), tvec.Z(), 1e-14) << bvec.
PrintString();
 
  151    tvec.SetXYZ(4., 3., 2.);
 
  153    tvec.Rotate(M_PI / 2.5, TVector3(1., 2., 3.));
 
  160    EXPECT_NEAR(bvec.
X(), tvec.X(), 1e-14) << bvec.
PrintString();
 
  161    EXPECT_NEAR(bvec.
Y(), tvec.Y(), 1e-14) << bvec.
PrintString();
 
  162    EXPECT_NEAR(bvec.
Z(), tvec.Z(), 1e-14) << bvec.
PrintString();
 
  166    const TVector3   taxis(4., 3., -2.);
 
  168    for (
auto& rtp : test_vectors({0, 1, 1e20}, 64, 64)) {
 
  170      double epsilon = (rtp.r < 1e10 ? 1e-10 : rtp.r * 1e-10);
 
  173      for (
int i = 0; i < 28; i++) {
 
  174        double angle = 2.*M_PI / 28 * i;
 
  175        tvec.SetMagThetaPhi(rtp.r, rtp.theta, rtp.phi);
 
  177        bvec.
Rotate(angle, baxis);
 
  178        tvec.Rotate(angle, taxis);
 
  182        if (fabs(fabs(bvec.
Phi() - tvec.Phi()) - 2.*M_PI) < 1e-14) {
 
  194        EXPECT_NEAR(bvec.
X(), tvec.X(), epsilon) << bvec.
PrintString();
 
  195        EXPECT_NEAR(bvec.
Y(), tvec.Y(), epsilon) << bvec.
PrintString();
 
  196        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.