diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 17d0e465..f30a2aa6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -75,11 +75,11 @@ jobs: # steps: # - uses: actions/checkout@v2 - # - name: Get Conda - # uses: conda-incubator/setup-miniconda@v2 - # with: - # environment-file: environment.yml - # activate-environment: vector + - name: Get Conda + uses: conda-incubator/setup-miniconda@v2 + with: + environment-file: environment.yml + activate-environment: vector # - name: Run tests # shell: "bash -l {0}" diff --git a/src/vector/_compute/spatial/dot.py b/src/vector/_compute/spatial/dot.py index 16afbf0a..37ea0c7d 100644 --- a/src/vector/_compute/spatial/dot.py +++ b/src/vector/_compute/spatial/dot.py @@ -32,7 +32,7 @@ # specialized def xy_z_xy_z(lib, x1, y1, z1, x2, y2, z2): - return x1 * x2 + y1 * y2 + z1 * z2 + return lib.nan_to_num(x1 * x2 + y1 * y2 + z1 * z2, nan=0.0) def xy_z_xy_theta(lib, x1, y1, z1, x2, y2, theta2): @@ -277,7 +277,7 @@ def rhophi_z_xy_eta(lib, rho1, phi1, z1, x2, y2, eta2): # specialized def rhophi_z_rhophi_z(lib, rho1, phi1, z1, rho2, phi2, z2): - return rho1 * rho2 * lib.cos(phi1 - phi2) + z1 * z2 + return lib.nan_to_num(rho1 * rho2 * lib.cos(phi1 - phi2) + z1 * z2, nan=0.0) def rhophi_z_rhophi_theta(lib, rho1, phi1, z1, rho2, phi2, theta2): @@ -336,8 +336,9 @@ def rhophi_theta_rhophi_z(lib, rho1, phi1, theta1, rho2, phi2, z2): # specialized def rhophi_theta_rhophi_theta(lib, rho1, phi1, theta1, rho2, phi2, theta2): - return ( - rho1 * rho2 * (lib.cos(phi1 - phi2) + 1 / (lib.tan(theta1) * lib.tan(theta2))) + return lib.nan_to_num( + rho1 * rho2 * (lib.cos(phi1 - phi2) + 1 / (lib.tan(theta1) * lib.tan(theta2))), + nan=0, ) @@ -407,7 +408,9 @@ def rhophi_eta_rhophi_eta(lib, rho1, phi1, eta1, rho2, phi2, eta2): expmeta2 = lib.exp(-eta2) invtantheta1 = 0.5 * (1 - expmeta1 ** 2) / expmeta1 invtantheta2 = 0.5 * (1 - expmeta2 ** 2) / expmeta2 - return rho1 * rho2 * (lib.cos(phi1 - phi2) + invtantheta1 * invtantheta2) + return lib.nan_to_num( + rho1 * rho2 * (lib.cos(phi1 - phi2) + invtantheta1 * invtantheta2), nan=0.0 + ) dispatch_map = { diff --git a/src/vector/_compute/spatial/eta.py b/src/vector/_compute/spatial/eta.py index 12178a5e..a6b0e976 100644 --- a/src/vector/_compute/spatial/eta.py +++ b/src/vector/_compute/spatial/eta.py @@ -48,7 +48,7 @@ def rhophi_z(lib, rho, phi, z): def rhophi_theta(lib, rho, phi, theta): - return -lib.log(lib.tan(0.5 * theta)) + return lib.nan_to_num(-lib.log(lib.tan(0.5 * theta)), nan=0.0) def rhophi_eta(lib, rho, phi, eta): diff --git a/tests/root/test_EulerAngles.py b/tests/root/test_EulerAngles.py new file mode 100644 index 00000000..81afd761 --- /dev/null +++ b/tests/root/test_EulerAngles.py @@ -0,0 +1,81 @@ +# Copyright (c) 2019-2021, Jonas Eschle, Jim Pivarski, Eduardo Rodrigues, and Henry Schreiner. +# +# Distributed under the 3-clause BSD license, see accompanying file LICENSE +# or https://github.com/scikit-hep/vector for details. + +import pytest + +# If ROOT is not available, skip these tests. +ROOT = pytest.importorskip("ROOT") + +# 4D constructor arguments to get all the weird cases. +constructor = [ + (0, 0, 0, 0), + (0, 0, 1, 0), # theta == 0.0 + (0, 0, -1, 0), + (0, 0, 1, 0), + (0, 0, 0, 4294967296), + (0, 4294967296, 0, 0), + (0, 0, 0, 10), + (0, 0, 0, -10), + (1, 2, 3, 0), + (1, 2, 3, 10), + (1, 2, 3, -10), + (1.0, 2.0, 3.0, 2.5), + (1, 2, 3, 2.5), + (1, 2, 3, -2.5), +] + +# Coordinate conversion methods to apply to the VectorObject4D. +coordinate_list = [ + "to_xyzt", + "to_xythetat", # may fail for constructor2 + "to_xyetat", + "to_rhophizt", + "to_rhophithetat", + "to_rhophietat", + "to_xyztau", + "to_xythetatau", + "to_xyetatau", + "to_rhophiztau", + "to_rhophithetatau", + "to_rhophietatau", +] + + +@pytest.fixture(scope="module", params=coordinate_list) +def coordinates(request): + return request.param + + +angle_list = [ + 0, + 0.0, + 0.7853981633974483, + -0.7853981633974483, + 1.5707963267948966, + -1.5707963267948966, + 3.141592653589793, + -3.141592653589793, + 6.283185307179586, + -6.283185307179586, +] + + +@pytest.fixture(scope="module", params=angle_list) +def angle(request): + return request.param + + +scalar_list = [ + 0, + -1, + 1.0, + 100000.0000, + -100000.0000, +] + + +@pytest.fixture(scope="module", params=scalar_list) +def scalar(request): + return request.param diff --git a/tests/root/test_Polar2DVector.py b/tests/root/test_Polar2DVector.py new file mode 100644 index 00000000..8e75b1d0 --- /dev/null +++ b/tests/root/test_Polar2DVector.py @@ -0,0 +1,246 @@ +# Copyright (c) 2019-2021, Jonas Eschle, Jim Pivarski, Eduardo Rodrigues, and Henry Schreiner. +# +# Distributed under the 3-clause BSD license, see accompanying file LICENSE +# or https://github.com/scikit-hep/vector for details. + +import numpy as np +import pytest + +import vector + +# If ROOT is not available, skip these tests. +ROOT = pytest.importorskip("ROOT") + +# ROOT.Math.Polar2DVector constructor arguments to get all the weird cases. +# r > 0 and phi from 0 to 360 deg? +constructor = [ + (0, 0), + (0, 10), + (1, 0), + (10, 0), + (1, 10), + (10.0, 10), + (1.0, 2.5), + (1, 2.5), + (1, 6.283185307179586), +] + +# Coordinate conversion methods to apply to the VectorObject2D. +coordinate_list = [ + "to_xy", + "to_rhophi", +] + + +@pytest.fixture(scope="module", params=coordinate_list) +def coordinates(request): + return request.param + + +angle_list = [ + 0, + 0.0, + 0.25 * np.pi, + -0.25 * np.pi, + 0.5 * np.pi, + -0.5 * np.pi, + np.pi, + -np.pi, + 2 * np.pi, + -2 * np.pi, +] + + +@pytest.fixture(scope="module", params=angle_list) +def angle(request): + return request.param + + +scalar_list = [ + 0, + -1, + 1.0, + 100000.0000, + -100000.0000, +] + + +@pytest.fixture(scope="module", params=scalar_list) +def scalar(request): + return request.param + + +# Run a test that compares ROOT's 'Dot()' with vector's 'dot' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Dot(constructor, coordinates): + assert ROOT.Math.Polar2DVector(*constructor).Dot( + ROOT.Math.Polar2DVector(*constructor) + ) == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "phi"], constructor))), coordinates + )().dot( + getattr(vector.obj(**dict(zip(["rho", "phi"], constructor))), coordinates)() + ), + 1.0e-6, + 1.0e-6, + ) + + +# Run a test that compares ROOT's 'Mag2()' with vector's 'rho2' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Mag2(constructor, coordinates): + assert ROOT.Math.Polar2DVector(*constructor).Mag2() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "phi"], constructor))), coordinates + )().rho2 + ) + + +# Run a test that compares ROOT's 'R()' with vector's 'rho' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Mag(constructor, coordinates): + assert ROOT.Math.sqrt( + ROOT.Math.Polar2DVector(*constructor).Mag2() + ) == pytest.approx( + getattr(vector.obj(**dict(zip(["rho", "phi"], constructor))), coordinates)().rho + ) + + +# Run a test that compares ROOT's 'Phi()' with vector's 'rho' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Phi(constructor, coordinates): + assert ROOT.Math.Polar2DVector(*constructor).Phi() == pytest.approx( + getattr(vector.obj(**dict(zip(["rho", "phi"], constructor))), coordinates)().phi + ) + + +# Run a test that compares ROOT's 'Rotate()' with vector's 'rotateZ' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Rotate(constructor, angle, coordinates): + ref_vec = ROOT.Math.Polar2DVector(*constructor) + ref_vec.Rotate(angle) + vec = getattr( + vector.obj(**dict(zip(["rho", "phi"], constructor))), coordinates + )().rotateZ(angle) + res_vec = vec.rotateZ(angle) + assert ref_vec.R() == pytest.approx( + res_vec.rho, + 1.0e-6, + 1.0e-6, + ) + assert ref_vec.Phi() == pytest.approx( + res_vec.phi, + 1.0e-6, + 1.0e-6, + ) + + +# Run a test that compares ROOT's 'Unit()' with vector's 'unit' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Unit(constructor, coordinates): + ref_vec = ROOT.Math.Polar2DVector(*constructor).Unit() + vec = getattr(vector.obj(**dict(zip(["rho", "phi"], constructor))), coordinates)() + res_vec = vec.unit + assert ref_vec.R() == pytest.approx(res_vec().rho) + assert ref_vec.Phi() == pytest.approx(res_vec().phi) + + +# Run a test that compares ROOT's 'X()' and 'Y()' with vector's 'x' and 'y' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_X_and_Y(constructor, coordinates): + ref_vec = ROOT.Math.Polar2DVector(*constructor) + vec = getattr(vector.obj(**dict(zip(["rho", "phi"], constructor))), coordinates)() + assert ref_vec.X() == pytest.approx(vec.x) and ref_vec.Y() == pytest.approx(vec.y) + + +# Run a test that compares ROOT's '__add__' with vector's 'add' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_add(constructor, coordinates): + ref_vec = ROOT.Math.Polar2DVector(*constructor).__add__( + ROOT.Math.Polar2DVector(*constructor) + ) + vec = getattr( + vector.obj(**dict(zip(["rho", "phi"], constructor))), coordinates + )().add( + getattr(vector.obj(**dict(zip(["rho", "phi"], constructor))), coordinates)() + ) + assert ref_vec.R() == pytest.approx( + vec.rho, + 1.0e-6, + 1.0e-6, + ) + assert ref_vec.Phi() == pytest.approx( + vec.phi, + 1.0e-6, + 1.0e-6, + ) + + +# Run a test that compares ROOT's '__sub__' with vector's 'subtract' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_sub(constructor, coordinates): + ref_vec = ROOT.Math.Polar2DVector(*constructor).__sub__( + ROOT.Math.Polar2DVector(*constructor) + ) + vec1 = getattr(vector.obj(**dict(zip(["rho", "phi"], constructor))), coordinates)() + vec2 = getattr(vector.obj(**dict(zip(["rho", "phi"], constructor))), coordinates)() + res_vec = vec1.subtract(vec2) + assert ref_vec.R() == pytest.approx( + res_vec.rho, + 1.0e-6, + 1.0e-6, + ) + assert ref_vec.Phi() == pytest.approx( + res_vec.phi, + 1.0e-6, + 1.0e-6, + ) + + +# Run a test that compares ROOT's '__neg__' with vector's '__neg__' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_neg(constructor, coordinates): + ref_vec = ROOT.Math.Polar2DVector(*constructor).__neg__() + vec = getattr( + vector.obj(**dict(zip(["rho", "phi"], constructor))), coordinates + )().__neg__ + assert ref_vec.R() == pytest.approx(vec().rho) + assert ref_vec.Phi() == pytest.approx(vec().phi) + + +# Run a test that compares ROOT's '__mul__' with vector's 'mul' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_mul(constructor, scalar, coordinates): + ref_vec = ROOT.Math.Polar2DVector(*constructor).__mul__(scalar) + vec = getattr( + vector.obj(**dict(zip(["rho", "phi"], constructor))), coordinates + )().__mul__(scalar) + assert ref_vec.R() == pytest.approx(vec.rho) + assert ref_vec.Phi() == pytest.approx(vec.phi) + + +# Run a test that compares ROOT's '__truediv__' with vector's '__truediv__' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_truediv(constructor, scalar, coordinates): + # FIXME: + if scalar != 0: + ref_vec = ROOT.Math.Polar2DVector(*constructor).__truediv__(scalar) + vec = getattr( + vector.obj(**dict(zip(["rho", "phi"], constructor))), coordinates + )().__truediv__(scalar) + assert ref_vec.R() == pytest.approx(vec.rho) + assert ref_vec.Phi() == pytest.approx(vec.phi) + + +# Run a test that compares ROOT's '__eq__' with vector's 'isclose' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_eq(constructor, coordinates): + ref_vec = ROOT.Math.Polar2DVector(*constructor).__eq__( + ROOT.Math.Polar2DVector(*constructor) + ) + vec = getattr( + vector.obj(**dict(zip(["rho", "phi"], constructor))), coordinates + )().isclose( + getattr(vector.obj(**dict(zip(["rho", "phi"], constructor))), coordinates)() + ) + assert ref_vec == vec diff --git a/tests/root/test_Polar3DVector.py b/tests/root/test_Polar3DVector.py new file mode 100644 index 00000000..55164461 --- /dev/null +++ b/tests/root/test_Polar3DVector.py @@ -0,0 +1,403 @@ +# Copyright (c) 2019-2021, Jonas Eschle, Jim Pivarski, Eduardo Rodrigues, and Henry Schreiner. +# +# Distributed under the 3-clause BSD license, see accompanying file LICENSE +# or https://github.com/scikit-hep/vector for details. + +import pytest + +import vector + +# If ROOT is not available, skip these tests. +ROOT = pytest.importorskip("ROOT") + +# ROOT.Math.Polar3DVector constructor arguments to get all the weird cases. +# "rho", "theta", "phi" +# Phi is restricted to be in the range [-PI,PI) +constructor = [ + (0.0, 0.0, 0.0), + # (0.0, 10.0, 0.0), + # (0.0, -10.0, 0.0), + (1.0, 0.0, 0.0), + # (1.0, 10.0, 0.0), + # (1.0, -10.0, 0.0), + # (1.0, 2.5, 2.0), + # (1.0, 2.5, 2.0), + # (1.0, -2.5, 2.0), +] + +# Coordinate conversion methods to apply to the VectorObject2D. +coordinate_list = [ + "to_xyz", + "to_rhophieta", + "to_rhophitheta", + "to_rhophiz", + "to_xyeta", + "to_xytheta", +] + + +@pytest.fixture(scope="module", params=coordinate_list) +def coordinates(request): + return request.param + + +angle_list = [ + 0, + 0.0, + 0.7853981633974483, + -0.7853981633974483, + 1.5707963267948966, + -1.5707963267948966, + 3.141592653589793, + -3.141592653589793, + 6.283185307179586, + -6.283185307179586, +] + + +@pytest.fixture(scope="module", params=angle_list) +def angle(request): + return request.param + + +scalar_list = [ + 0, + -1, + 1.0, + 100000.0000, + -100000.0000, +] + + +@pytest.fixture(scope="module", params=scalar_list) +def scalar(request): + return request.param + + +# Run a test that compares ROOT's 'Dot()' with vector's 'dot' for all cases. +# rho = r*sin(theta) +@pytest.mark.parametrize("constructor", constructor) +def test_Dot(constructor, coordinates): + assert ROOT.Math.Polar3DVector(*constructor).Dot( + ROOT.Math.Polar3DVector(*constructor) + ) == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "theta", "phi"], constructor))), coordinates + )().dot( + getattr( + vector.obj(**dict(zip(["rho", "theta", "phi"], constructor))), + coordinates, + )() + ) + ) + + +# Run a test that compares ROOT's 'Cross()' with vector's 'cross' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Cross(constructor, coordinates): + ref_vec = ROOT.Math.Polar3DVector(*constructor).Cross( + ROOT.Math.Polar3DVector(*constructor) + ) + vec = getattr( + vector.obj(**dict(zip(["rho", "theta", "phi"], constructor))), coordinates + )().cross( + getattr( + vector.obj(**dict(zip(["rho", "theta", "phi"], constructor))), coordinates + )() + ) + assert ( + ref_vec.X() + == pytest.approx( + vec.x, + 1.0e-6, + 1.0e-6, + ) + and ref_vec.Y() + == pytest.approx( + vec.y, + 1.0e-6, + 1.0e-6, + ) + and ref_vec.Z() + == pytest.approx( + vec.z, + 1.0e-6, + 1.0e-6, + ) + ) + + +# Run a test that compares ROOT's 'Mag2()' with vector's 'rho2' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Mag2(constructor, coordinates): + assert ROOT.Math.Polar3DVector(*constructor).Mag2() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "theta", "phi"], constructor))), coordinates + )().mag2 + ) + + +# Run a test that compares ROOT's 'Mag()' with vector's 'mag' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_R(constructor, coordinates): + assert ROOT.Math.Polar3DVector(*constructor).R() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "theta", "phi"], constructor))), + coordinates, + )().mag + ) + + +# Run a test that compares ROOT's 'Perp2()' with vector's 'rho2' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Perp2(constructor, coordinates): + assert ROOT.Math.Polar3DVector(*constructor).Perp2() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "theta", "phi"], constructor))), coordinates + )().rho2 + ) + + +# Run a test that compares ROOT's 'Rho()' with vector's 'rho' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Rho(constructor, coordinates): + assert ROOT.Math.Polar3DVector(*constructor).Rho() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "theta", "phi"], constructor))), + coordinates, + )().rho + ) + + +# Run a test that compares ROOT's 'Phi()' with vector's 'phi' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Phi(constructor, coordinates): + assert ROOT.Math.Polar3DVector(*constructor).Phi() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "theta", "phi"], constructor))), coordinates + )().phi + ) + + +# Run a test that compares ROOT's 'Eta()' with vector's 'eta' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def Eta(constructor, coordinates): + assert ROOT.Math.Polar3DVector(*constructor).Eta() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "theta", "phi"], constructor))), coordinates + )().eta + ) + + +# Run a test that compares ROOT's 'Theta()' with vector's 'theta' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Theta(constructor, coordinates): + assert ROOT.Math.Polar3DVector(*constructor).Theta() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "theta", "phi"], constructor))), coordinates + )().theta + ) + + +# Run a test that compares ROOT's 'RotateX()' with vector's 'rotateX' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_RotateX(constructor, angle, coordinates): + ref_vec = ROOT.Math.RotationX(angle) * ROOT.Math.Polar3DVector(*constructor) + vec = getattr( + vector.obj(**dict(zip(["rho", "theta", "phi"], constructor))), coordinates + )() + res_vec = vec.rotateX(angle) + assert ref_vec.X() == pytest.approx(res_vec.x) + assert ref_vec.Y() == pytest.approx(res_vec.y) + assert ref_vec.Z() == pytest.approx(res_vec.z) + + +# Run a test that compares ROOT's 'RotateY()' with vector's 'rotateY' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_RotateY(constructor, angle, coordinates): + ref_vec = ROOT.Math.RotationY(angle) * ROOT.Math.Polar3DVector(*constructor) + vec = getattr( + vector.obj(**dict(zip(["rho", "theta", "phi"], constructor))), coordinates + )() + res_vec = vec.rotateY(angle) + assert ref_vec.X() == pytest.approx(res_vec.x) + assert ref_vec.Y() == pytest.approx(res_vec.y) + assert ref_vec.Z() == pytest.approx(res_vec.z) + + +# Run a test that compares ROOT's 'RotateZ()' with vector's 'rotateZ' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_RotateZ(constructor, angle, coordinates): + ref_vec = ROOT.Math.RotationZ(angle) * ROOT.Math.Polar3DVector(*constructor) + vec = getattr( + vector.obj(**dict(zip(["rho", "theta", "phi"], constructor))), coordinates + )() + res_vec = vec.rotateZ(angle) + assert ( + ref_vec.R() + == pytest.approx( + vec.rho, + 1.0e-6, + 1.0e-6, + ) + and ref_vec.Theta() + == pytest.approx( + vec.theta, + 1.0e-6, + 1.0e-6, + ) + and ref_vec.Phi() + == pytest.approx( + vec.phi, + 1.0e-6, + 1.0e-6, + ) + ) + assert ref_vec.X() == pytest.approx(res_vec.x) + assert ref_vec.Y() == pytest.approx(res_vec.y) + assert ref_vec.Z() == pytest.approx(res_vec.z) + + +# Run a test that compares ROOT's 'RotateAxes' with vector's 'rotate_axes' for all cases. +def test_RotateAxes(constructor, angle, coordinates): + ref_vec = ROOT.Math.Polar3DVector(*constructor) + vec = getattr( + vector.obj(**dict(zip(["rho", "theta", "phi"], constructor))), coordinates + )() + # FIXME: rotate_axis + assert ( + ref_vec.R() + == pytest.approx( + vec.rho, + 1.0e-6, + 1.0e-6, + ) + and ref_vec.Theta() + == pytest.approx( + vec.theta, + 1.0e-6, + 1.0e-6, + ) + and ref_vec.Phi() + == pytest.approx( + vec.phi, + 1.0e-6, + 1.0e-6, + ) + ) + + +# Run a test that compares ROOT's 'Unit()' with vector's 'unit' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Unit(constructor, coordinates): + ref_vec = ROOT.Math.Polar3DVector(*constructor).Unit() + vec = getattr( + vector.obj(**dict(zip(["rho", "theta", "phi"], constructor))), coordinates + )() + res_vec = vec.unit + assert ref_vec.X() == pytest.approx(res_vec().x) + assert ref_vec.Y() == pytest.approx(res_vec().y) + assert ref_vec.Z() == pytest.approx(res_vec().z) + + +# Run a test that compares ROOT's 'X()' and 'Y()' with vector's 'x' and 'y' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_X_Y_Z(constructor, coordinates): + vec = getattr( + vector.obj(**dict(zip(["rho", "theta", "phi"], constructor))), coordinates + )() + assert ( + ROOT.Math.Polar3DVector(*constructor).X() == pytest.approx(vec.x) + and ROOT.Math.Polar3DVector(*constructor).Y() == pytest.approx(vec.y) + and ROOT.Math.Polar3DVector(*constructor).Z() == pytest.approx(vec.z) + ) + + +# Run a test that compares ROOT's '__add__' with vector's 'add' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_add(constructor, coordinates): + ref_vec = ROOT.Math.Polar3DVector(*constructor).__add__( + ROOT.Math.Polar3DVector(*constructor) + ) + vec = getattr( + vector.obj(**dict(zip(["rho", "theta", "phi"], constructor))), coordinates + )().add( + getattr( + vector.obj(**dict(zip(["rho", "theta", "phi"], constructor))), coordinates + )() + ) + assert ref_vec.X() == pytest.approx(vec.x) + assert ref_vec.Y() == pytest.approx(vec.y) + assert ref_vec.Z() == pytest.approx(vec.z) + + +# Run a test that compares ROOT's '__sub__' with vector's 'subtract' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_sub(constructor, coordinates): + ref_vec = ROOT.Math.Polar3DVector(*constructor).__sub__( + ROOT.Math.Polar3DVector(*constructor) + ) + vec1 = getattr( + vector.obj(**dict(zip(["rho", "theta", "phi"], constructor))), coordinates + )() + vec2 = getattr( + vector.obj(**dict(zip(["rho", "theta", "phi"], constructor))), coordinates + )() + res_vec = vec1.subtract(vec2) + assert ref_vec.X() == pytest.approx(res_vec.x) + assert ref_vec.Y() == pytest.approx(res_vec.y) + assert ref_vec.Z() == pytest.approx(res_vec.z) + + +# Run a test that compares ROOT's '__neg__' with vector's '__neg__' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_neg(constructor, coordinates): + ref_vec = ROOT.Math.Polar3DVector(*constructor).__neg__() + vec = getattr( + vector.obj(**dict(zip(["rho", "theta", "phi"], constructor))), coordinates + )().__neg__ + assert ref_vec.X() == pytest.approx(vec().x) + assert ref_vec.Y() == pytest.approx(vec().y) + assert ref_vec.Z() == pytest.approx(vec().z) + + +# Run a test that compares ROOT's '__mul__' with vector's 'mul' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_mul(constructor, scalar, coordinates): + ref_vec = ROOT.Math.Polar3DVector(*constructor).__mul__(scalar) + vec = getattr( + vector.obj(**dict(zip(["rho", "theta", "phi"], constructor))), coordinates + )().__mul__(scalar) + assert ref_vec.X() == pytest.approx(vec.x) + assert ref_vec.Y() == pytest.approx(vec.y) + assert ref_vec.Z() == pytest.approx(vec.z) + + +# Run a test that compares ROOT's '__truediv__' with vector's '__truediv__' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_truediv(constructor, scalar, coordinates): + # FIXME + if scalar != 0: + ref_vec = ROOT.Math.Polar3DVector(*constructor).__truediv__(scalar) + vec = getattr( + vector.obj(**dict(zip(["rho", "theta", "phi"], constructor))), coordinates + )().__truediv__(scalar) + assert ref_vec.X() == pytest.approx(vec.x) + assert ref_vec.Y() == pytest.approx(vec.y) + assert ref_vec.Z() == pytest.approx(vec.z) + + +# Run a test that compares ROOT's '__eq__' with vector's 'isclose' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_eq(constructor, coordinates): + ref_vec = ROOT.Math.Polar3DVector(*constructor).__eq__( + ROOT.Math.Polar3DVector(*constructor) + ) + vec = getattr( + vector.obj(**dict(zip(["rho", "theta", "phi"], constructor))), coordinates + )().isclose( + getattr( + vector.obj(**dict(zip(["rho", "theta", "phi"], constructor))), coordinates + )() + ) + assert ref_vec == vec diff --git a/tests/root/test_PtEtaPhiEVector.py b/tests/root/test_PtEtaPhiEVector.py new file mode 100644 index 00000000..2ab6fc34 --- /dev/null +++ b/tests/root/test_PtEtaPhiEVector.py @@ -0,0 +1,472 @@ +# Copyright (c) 2019-2021, Jonas Eschle, Jim Pivarski, Eduardo Rodrigues, and Henry Schreiner. +# +# Distributed under the 3-clause BSD license, see accompanying file LICENSE +# or https://github.com/scikit-hep/vector for details. + +import pytest + +import vector + +# If ROOT is not available, skip these tests. +ROOT = pytest.importorskip("ROOT") + +# ROOT.Math.PtEtaPhiEVector constructor arguments to get all the weird cases. +constructor = [ + (0, 0, 0, 0), + (0, 0, 1, 0), # theta == 0.0 + (0, 0, -1, 0), + (0, 0, 1, 0), + (0, 0, 0, 4294967296), + (0, 4294967296, 0, 0), + (0, 0, 0, 10), + (0, 0, 0, -10), + (1, 2, 3, 0), + (1, 2, 3, 10), + (1, 2, 3, -10), + (1.0, 2.0, 3.0, 2.5), + (1, 2, 3, 2.5), + (1, 2, 3, -2.5), +] + +# Coordinate conversion methods to apply to the VectorObject4D. +coordinate_list = [ + "to_xyzt", + "to_xythetat", # may fail for constructor2 + "to_xyetat", + "to_rhophizt", + "to_rhophithetat", + "to_rhophietat", + "to_xyztau", + "to_xythetatau", + "to_xyetatau", + "to_rhophiztau", + "to_rhophithetatau", + "to_rhophietatau", +] + + +@pytest.fixture(scope="module", params=coordinate_list) +def coordinates(request): + return request.param + + +angle_list = [ + 0, + 0.0, + 0.7853981633974483, + -0.7853981633974483, + 1.5707963267948966, + -1.5707963267948966, + 3.141592653589793, + -3.141592653589793, + 6.283185307179586, + -6.283185307179586, +] + + +@pytest.fixture(scope="module", params=angle_list) +def angle(request): + return request.param + + +scalar_list = [ + 0, + -1, + 1.0, + 100000.0000, + -100000.0000, +] + + +@pytest.fixture(scope="module", params=scalar_list) +def scalar(request): + return request.param + + +# Run a test that compares ROOT's 'Dot()' with vector's 'dot' for all cases. +# Dot +@pytest.mark.parametrize("constructor", constructor) +def test_Dot(constructor, coordinates): + v1 = getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "t"], constructor))), coordinates + )() + v2 = getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "t"], constructor))), coordinates + )() + assert ROOT.Math.PtEtaPhiEVector(*constructor).Dot( + ROOT.Math.PtEtaPhiEVector(*constructor) + ) == pytest.approx(v1.dot(v2)) + + +# Run a test that compares ROOT's 'M2()' with vector's 'tau2' for all cases. +# Mass2 is our tau2 (or mass2 if it's a momentum vector and has kinematic synonyms) +@pytest.mark.parametrize("constructor", constructor) +def test_M2(constructor, coordinates): + assert ROOT.Math.PtEtaPhiEVector(*constructor).M2() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "t"], constructor))), + coordinates, + )().tau2 + ) + + +# Run a test that compares ROOT's 'M()' with vector's 'tau' for all cases. +# Mass is tau (or mass) +@pytest.mark.parametrize("constructor", constructor) +def test_M(constructor, coordinates): + assert ROOT.Math.PtEtaPhiEVector(*constructor).M() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "t"], constructor))), + coordinates, + )().tau + ) + + +# Run a test that compares ROOT's 'Mt2()' with vector's 'mt2' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Mt2(constructor, coordinates): + v = getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "t"], constructor))), coordinates + )() + assert ROOT.Math.PtEtaPhiEVector(*constructor).Mt2() == pytest.approx( + v.t * v.t - v.z * v.z + ) + + +# Run a test that compares ROOT's 'Mt()' with vector's 'mt' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Mt(constructor, coordinates): + v = getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "t"], constructor))), coordinates + )() + assert ROOT.Math.PtEtaPhiEVector(*constructor).mt() == pytest.approx( + v.lib.sqrt(v.t * v.t - v.z * v.z) + ) + + +# Run a test that compares ROOT's 'P2()' with vector's 'mag2' for all cases. +# P2 is our mag2 (ROOT's 4D mag2 is the dot product with itself, what we call tau or mass) +@pytest.mark.parametrize("constructor", constructor) +def test_P2(constructor, coordinates): + assert ROOT.Math.PtEtaPhiEVector(*constructor).P2() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "t"], constructor))), + coordinates, + )().mag2 + ) + + +# Run a test that compares ROOT's 'P()' with vector's 'mag' for all cases. +# P is our mag (same deal) +@pytest.mark.parametrize("constructor", constructor) +def test_P(constructor, coordinates): + assert ROOT.Math.PtEtaPhiEVector(*constructor).P() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "t"], constructor))), + coordinates, + )().mag + ) + + +# Run a test that compares ROOT's 'Perp2()' with vector's 'rho2' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Perp2(constructor, coordinates): + assert ROOT.Math.PtEtaPhiEVector(*constructor).Perp2() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "t"], constructor))), + coordinates, + )().rho2 + ) + + +# Run a test that compares ROOT's 'Perp()' with vector's 'rho' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Perp(constructor, coordinates): + assert ROOT.Math.sqrt( + ROOT.Math.PtEtaPhiEVector(*constructor).Perp2() + ) == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "t"], constructor))), + coordinates, + )().rho + ) + + +# Run a test that compares ROOT's 'Phi()' with vector's 'phi' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Phi(constructor, coordinates): + assert ROOT.Math.PtEtaPhiEVector(*constructor).Phi() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "t"], constructor))), + coordinates, + )().phi + ) + + +# Run a test that compares ROOT's 'Rapidity()' with vector's 'rapidity' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Rapidity(constructor, coordinates): + assert ROOT.Math.PtEtaPhiEVector(*constructor).Rapidity() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "t"], constructor))), + coordinates, + )().rapidity + ) + + +# Run a test that compares ROOT's 'Beta()' with vector's 'beta' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Beta(constructor, coordinates): + assert ROOT.Math.PtEtaPhiEVector(*constructor).Beta() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "t"], constructor))), + coordinates, + )().beta + ) + + +# Run a test that compares ROOT's 'Eta()' with vector's 'eta' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Eta(constructor, coordinates): + assert ROOT.Math.PtEtaPhiEVector(*constructor).Eta() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "t"], constructor))), + coordinates, + )().eta + ) + + +# Run a test that compares ROOT's 'Gamma()' with vector's 'gamma' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Gamma(constructor, coordinates): + assert ROOT.Math.PtEtaPhiEVector(*constructor).Gamma() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "t"], constructor))), + coordinates, + )().gamma + ) + + +# Run a test that compares ROOT's 'isLightlike()' with vector's 'is_lightlike' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_isLightlike(constructor, coordinates): + assert ROOT.Math.PtEtaPhiEVector(*constructor).isLightlike() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "t"], constructor))), + coordinates, + )().is_lightlike() + ) + + +# Run a test that compares ROOT's 'isSpacelike()' with vector's 'is_spacelike' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_isSpacelike(constructor, coordinates): + assert ROOT.Math.PtEtaPhiEVector(*constructor).isSpacelike() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "t"], constructor))), + coordinates, + )().is_spacelike() + ) + + +# Run a test that compares ROOT's 'isTimelike()' with vector's 'is_timelike' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_isTimelike(constructor, coordinates): + assert ROOT.Math.PtEtaPhiEVector(*constructor).isTimelike() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "t"], constructor))), + coordinates, + )().is_timelike() + ) + + +# Run a test that compares ROOT's 'Theta()' with vector's 'theta' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Theta(constructor, coordinates): + assert ROOT.Math.PtEtaPhiEVector(*constructor).Theta() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "t"], constructor))), + coordinates, + )().theta + ) + + +# Run a test that compares ROOT's 'X()' with vector's 'x' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_X(constructor, coordinates): + assert ROOT.Math.PtEtaPhiEVector(*constructor).X() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "t"], constructor))), + coordinates, + )().x + ) + + +# Run a test that compares ROOT's 'Y()' with vector's 'y' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Y(constructor, coordinates): + assert ROOT.Math.PtEtaPhiEVector(*constructor).Y() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "t"], constructor))), + coordinates, + )().y + ) + + +# Run a test that compares ROOT's 'Z()' with vector's 'z' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Z(constructor, coordinates): + assert ROOT.Math.PtEtaPhiEVector(*constructor).Z() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "t"], constructor))), + coordinates, + )().z + ) + + +# Run a test that compares ROOT's 'T()' with vector's 't' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_T(constructor, coordinates): + assert ROOT.Math.PtEtaPhiEVector(*constructor).T() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "t"], constructor))), + coordinates, + )().t + ) + + +# Run a test that compares ROOT's '__add__' with vector's 'add' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_add(constructor, coordinates): + ref_vec = ROOT.Math.PtEtaPhiEVector(*constructor).__add__( + ROOT.Math.PtEtaPhiEVector(*constructor) + ) + vec = getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "t"], constructor))), coordinates + )().add( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "t"], constructor))), + coordinates, + )() + ) + assert ref_vec.X() == pytest.approx(vec.x) + assert ref_vec.Y() == pytest.approx(vec.y) + assert ref_vec.Z() == pytest.approx(vec.z) + assert ref_vec.T() == pytest.approx(vec.t) + + +# Run a test that compares ROOT's '__sub__' with vector's 'subtract' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_sub(constructor, coordinates): + ref_vec = ROOT.Math.PtEtaPhiEVector(*constructor).__sub__( + ROOT.Math.PtEtaPhiEVector(*constructor) + ) + vec1 = getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "t"], constructor))), coordinates + )() + vec2 = getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "t"], constructor))), coordinates + )() + res_vec = vec1.subtract(vec2) + assert ref_vec.X() == pytest.approx(res_vec.x) + assert ref_vec.Y() == pytest.approx(res_vec.y) + assert ref_vec.Z() == pytest.approx(res_vec.z) + assert ref_vec.T() == pytest.approx(res_vec.t) + + +# Run a test that compares ROOT's '__neg__' with vector's '__neg__' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_neg(constructor, coordinates): + ref_vec = ROOT.Math.PtEtaPhiEVector(*constructor).__neg__() + vec = getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "t"], constructor))), coordinates + )().__neg__ + assert ref_vec.X() == pytest.approx(vec().x) + assert ref_vec.Y() == pytest.approx(vec().y) + assert ref_vec.Z() == pytest.approx(vec().z) + assert ref_vec.T() == pytest.approx(vec().t) + + +# Run a test that compares ROOT's '__mul__' with vector's 'mul' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_mul(constructor, scalar, coordinates): + ref_vec = ROOT.Math.PtEtaPhiEVector(*constructor).__mul__(scalar) + vec = getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "t"], constructor))), coordinates + )().__mul__(scalar) + assert ref_vec.X() == pytest.approx(vec.x) + assert ref_vec.Y() == pytest.approx(vec.y) + assert ref_vec.Z() == pytest.approx(vec.z) + assert ref_vec.T() == pytest.approx(vec.t) + + +# Run a test that compares ROOT's '__truediv__' with vector's '__truediv__' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_truediv(constructor, scalar, coordinates): + ref_vec = ROOT.Math.PtEtaPhiEVector(*constructor).__truediv__(scalar) + vec = getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "t"], constructor))), coordinates + )().__truediv__(scalar) + assert ref_vec.X() == pytest.approx(vec.x) + assert ref_vec.Y() == pytest.approx(vec.y) + assert ref_vec.Z() == pytest.approx(vec.z) + assert ref_vec.T() == pytest.approx(vec.t) + + +# Run a test that compares ROOT's '__eq__' with vector's 'isclose' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_eq(constructor, coordinates): + ref_vec = ROOT.Math.PtEtaPhiEVector(*constructor).__eq__( + ROOT.Math.PtEtaPhiEVector(*constructor) + ) + vec = getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "t"], constructor))), coordinates + )().isclose( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "t"], constructor))), + coordinates, + )() + ) + assert ref_vec == vec + + +# Run a test that compares ROOT's 'RotateX()' with vector's 'rotateX' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_RotateX(constructor, angle, coordinates): + ref_vec = ROOT.Math.RotationX(angle) * ROOT.Math.PtEtaPhiEVector(*constructor) + vec = getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "t"], constructor))), coordinates + )() + res_vec = vec.rotateX(angle) + assert ref_vec.X() == pytest.approx(res_vec.x) + assert ref_vec.Y() == pytest.approx(res_vec.y) + assert ref_vec.Z() == pytest.approx(res_vec.z) + assert ref_vec.T() == pytest.approx(res_vec.t) + + +# Run a test that compares ROOT's 'RotateY()' with vector's 'rotateY' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_RotateY(constructor, angle, coordinates): + ref_vec = ROOT.Math.RotationY(angle) * ROOT.Math.PtEtaPhiEVector(*constructor) + vec = getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "t"], constructor))), coordinates + )() + res_vec = vec.rotateY(angle) + assert ref_vec.X() == pytest.approx(res_vec.x) + assert ref_vec.Y() == pytest.approx(res_vec.y) + assert ref_vec.Z() == pytest.approx(res_vec.z) + assert ref_vec.T() == pytest.approx(res_vec.t) + + +# Run a test that compares ROOT's 'RotateZ()' with vector's 'rotateZ' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_RotateZ(constructor, angle, coordinates): + ref_vec = ROOT.Math.RotationZ(angle) * ROOT.Math.PtEtaPhiEVector(*constructor) + vec = getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "t"], constructor))), coordinates + )() + res_vec = vec.rotateZ(angle) + assert ref_vec.X() == pytest.approx(res_vec.x) + assert ref_vec.Y() == pytest.approx(res_vec.y) + assert ref_vec.Z() == pytest.approx(res_vec.z) + assert ref_vec.T() == pytest.approx(res_vec.t) diff --git a/tests/root/test_PtEtaPhiMVector.py b/tests/root/test_PtEtaPhiMVector.py new file mode 100644 index 00000000..7468a3b9 --- /dev/null +++ b/tests/root/test_PtEtaPhiMVector.py @@ -0,0 +1,472 @@ +# Copyright (c) 2019-2021, Jonas Eschle, Jim Pivarski, Eduardo Rodrigues, and Henry Schreiner. +# +# Distributed under the 3-clause BSD license, see accompanying file LICENSE +# or https://github.com/scikit-hep/vector for details. + +import pytest + +import vector + +# If ROOT is not available, skip these tests. +ROOT = pytest.importorskip("ROOT") + +# ROOT.Math.PtEtaPhiMVector constructor arguments to get all the weird cases. +constructor = [ + (0, 0, 0, 0), + (0, 0, 1, 0), # theta == 0.0 + (0, 0, -1, 0), + (0, 0, 1, 0), + (0, 0, 0, 4294967296), + (0, 4294967296, 0, 0), + (0, 0, 0, 10), + (0, 0, 0, -10), + (1, 2, 3, 0), + (1, 2, 3, 10), + (1, 2, 3, -10), + (1.0, 2.0, 3.0, 2.5), + (1, 2, 3, 2.5), + (1, 2, 3, -2.5), +] + +# Coordinate conversion methods to apply to the VectorObject4D. +coordinate_list = [ + "to_xyzt", + "to_xythetat", # may fail for constructor2 + "to_xyetat", + "to_rhophizt", + "to_rhophithetat", + "to_rhophietat", + "to_xyztau", + "to_xythetatau", + "to_xyetatau", + "to_rhophiztau", + "to_rhophithetatau", + "to_rhophietatau", +] + + +@pytest.fixture(scope="module", params=coordinate_list) +def coordinates(request): + return request.param + + +angle_list = [ + 0, + 0.0, + 0.7853981633974483, + -0.7853981633974483, + 1.5707963267948966, + -1.5707963267948966, + 3.141592653589793, + -3.141592653589793, + 6.283185307179586, + -6.283185307179586, +] + + +@pytest.fixture(scope="module", params=angle_list) +def angle(request): + return request.param + + +scalar_list = [ + 0, + -1, + 1.0, + 100000.0000, + -100000.0000, +] + + +@pytest.fixture(scope="module", params=scalar_list) +def scalar(request): + return request.param + + +# Run a test that compares ROOT's 'Dot()' with vector's 'dot' for all cases. +# Dot +@pytest.mark.parametrize("constructor", constructor) +def test_Dot(constructor, coordinates): + v1 = getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "tau"], constructor))), coordinates + )() + v2 = getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "tau"], constructor))), coordinates + )() + assert ROOT.Math.PtEtaPhiMVector(*constructor).Dot( + ROOT.Math.PtEtaPhiMVector(*constructor) + ) == pytest.approx(v1.dot(v2)) + + +# Run a test that compares ROOT's 'M2()' with vector's 'tau2' for all cases. +# Mass2 is our tau2 (or mass2 if it's a momentum vector and has kinematic synonyms) +@pytest.mark.parametrize("constructor", constructor) +def test_M2(constructor, coordinates): + assert ROOT.Math.PtEtaPhiMVector(*constructor).M2() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "tau"], constructor))), + coordinates, + )().tau2 + ) + + +# Run a test that compares ROOT's 'M()' with vector's 'tau' for all cases. +# Mass is tau (or mass) +@pytest.mark.parametrize("constructor", constructor) +def test_M(constructor, coordinates): + assert ROOT.Math.PtEtaPhiMVector(*constructor).M() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "tau"], constructor))), + coordinates, + )().tau + ) + + +# Run a test that compares ROOT's 'Mt2()' with vector's 'mt2' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Mt2(constructor, coordinates): + v = getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "tau"], constructor))), coordinates + )() + assert ROOT.Math.PtEtaPhiMVector(*constructor).Mt2() == pytest.approx( + v.t * v.t - v.z * v.z + ) + + +# Run a test that compares ROOT's 'Mt()' with vector's 'mt' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Mt(constructor, coordinates): + v = getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "tau"], constructor))), coordinates + )() + assert ROOT.Math.PtEtaPhiMVector(*constructor).mt() == pytest.approx( + v.lib.sqrt(v.t * v.t - v.z * v.z) + ) + + +# Run a test that compares ROOT's 'P2()' with vector's 'mag2' for all cases. +# P2 is our mag2 (ROOT's 4D mag2 is the dot product with itself, what we call tau or mass) +@pytest.mark.parametrize("constructor", constructor) +def test_P2(constructor, coordinates): + assert ROOT.Math.PtEtaPhiMVector(*constructor).P2() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "tau"], constructor))), + coordinates, + )().mag2 + ) + + +# Run a test that compares ROOT's 'P()' with vector's 'mag' for all cases. +# P is our mag (same deal) +@pytest.mark.parametrize("constructor", constructor) +def test_P(constructor, coordinates): + assert ROOT.Math.PtEtaPhiMVector(*constructor).P() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "tau"], constructor))), + coordinates, + )().mag + ) + + +# Run a test that compares ROOT's 'Perp2()' with vector's 'rho2' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Perp2(constructor, coordinates): + assert ROOT.Math.PtEtaPhiMVector(*constructor).Perp2() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "tau"], constructor))), + coordinates, + )().rho2 + ) + + +# Run a test that compares ROOT's 'Perp()' with vector's 'rho' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Perp(constructor, coordinates): + assert ROOT.Math.sqrt( + ROOT.Math.PtEtaPhiMVector(*constructor).Perp2() + ) == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "tau"], constructor))), + coordinates, + )().rho + ) + + +# Run a test that compares ROOT's 'Phi()' with vector's 'phi' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Phi(constructor, coordinates): + assert ROOT.Math.PtEtaPhiMVector(*constructor).Phi() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "tau"], constructor))), + coordinates, + )().phi + ) + + +# Run a test that compares ROOT's 'Rapidity()' with vector's 'rapidity' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Rapidity(constructor, coordinates): + assert ROOT.Math.PtEtaPhiMVector(*constructor).Rapidity() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "tau"], constructor))), + coordinates, + )().rapidity + ) + + +# Run a test that compares ROOT's 'Beta()' with vector's 'beta' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Beta(constructor, coordinates): + assert ROOT.Math.PtEtaPhiMVector(*constructor).Beta() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "tau"], constructor))), + coordinates, + )().beta + ) + + +# Run a test that compares ROOT's 'Eta()' with vector's 'eta' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Eta(constructor, coordinates): + assert ROOT.Math.PtEtaPhiMVector(*constructor).Eta() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "tau"], constructor))), + coordinates, + )().eta + ) + + +# Run a test that compares ROOT's 'Gamma()' with vector's 'gamma' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Gamma(constructor, coordinates): + assert ROOT.Math.PtEtaPhiMVector(*constructor).Gamma() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "tau"], constructor))), + coordinates, + )().gamma + ) + + +# Run a test that compares ROOT's 'isLightlike()' with vector's 'is_lightlike' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_isLightlike(constructor, coordinates): + assert ROOT.Math.PtEtaPhiMVector(*constructor).isLightlike() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "tau"], constructor))), + coordinates, + )().is_lightlike() + ) + + +# Run a test that compares ROOT's 'isSpacelike()' with vector's 'is_spacelike' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_isSpacelike(constructor, coordinates): + assert ROOT.Math.PtEtaPhiMVector(*constructor).isSpacelike() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "tau"], constructor))), + coordinates, + )().is_spacelike() + ) + + +# Run a test that compares ROOT's 'isTimelike()' with vector's 'is_timelike' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_isTimelike(constructor, coordinates): + assert ROOT.Math.PtEtaPhiMVector(*constructor).isTimelike() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "tau"], constructor))), + coordinates, + )().is_timelike() + ) + + +# Run a test that compares ROOT's 'Theta()' with vector's 'theta' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Theta(constructor, coordinates): + assert ROOT.Math.PtEtaPhiMVector(*constructor).Theta() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "tau"], constructor))), + coordinates, + )().theta + ) + + +# Run a test that compares ROOT's 'X()' with vector's 'x' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_X(constructor, coordinates): + assert ROOT.Math.PtEtaPhiMVector(*constructor).X() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "tau"], constructor))), + coordinates, + )().x + ) + + +# Run a test that compares ROOT's 'Y()' with vector's 'y' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Y(constructor, coordinates): + assert ROOT.Math.PtEtaPhiMVector(*constructor).Y() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "tau"], constructor))), + coordinates, + )().y + ) + + +# Run a test that compares ROOT's 'Z()' with vector's 'z' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Z(constructor, coordinates): + assert ROOT.Math.PtEtaPhiMVector(*constructor).Z() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "tau"], constructor))), + coordinates, + )().z + ) + + +# Run a test that compares ROOT's 'T()' with vector's 't' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_T(constructor, coordinates): + assert ROOT.Math.PtEtaPhiMVector(*constructor).T() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "tau"], constructor))), + coordinates, + )().t + ) + + +# Run a test that compares ROOT's '__add__' with vector's 'add' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_add(constructor, coordinates): + ref_vec = ROOT.Math.PtEtaPhiMVector(*constructor).__add__( + ROOT.Math.PtEtaPhiMVector(*constructor) + ) + vec = getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "tau"], constructor))), coordinates + )().add( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "tau"], constructor))), + coordinates, + )() + ) + assert ref_vec.X() == pytest.approx(vec.x) + assert ref_vec.Y() == pytest.approx(vec.y) + assert ref_vec.Z() == pytest.approx(vec.z) + assert ref_vec.T() == pytest.approx(vec.t) + + +# Run a test that compares ROOT's '__sub__' with vector's 'subtract' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_sub(constructor, coordinates): + ref_vec = ROOT.Math.PtEtaPhiMVector(*constructor).__sub__( + ROOT.Math.PtEtaPhiMVector(*constructor) + ) + vec1 = getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "tau"], constructor))), coordinates + )() + vec2 = getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "tau"], constructor))), coordinates + )() + res_vec = vec1.subtract(vec2) + assert ref_vec.X() == pytest.approx(res_vec.x) + assert ref_vec.Y() == pytest.approx(res_vec.y) + assert ref_vec.Z() == pytest.approx(res_vec.z) + assert ref_vec.T() == pytest.approx(res_vec.t) + + +# Run a test that compares ROOT's '__neg__' with vector's '__neg__' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_neg(constructor, coordinates): + ref_vec = ROOT.Math.PtEtaPhiMVector(*constructor).__neg__() + vec = getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "tau"], constructor))), coordinates + )().__neg__ + assert ref_vec.X() == pytest.approx(vec().x) + assert ref_vec.Y() == pytest.approx(vec().y) + assert ref_vec.Z() == pytest.approx(vec().z) + assert ref_vec.T() == pytest.approx(vec().t) + + +# Run a test that compares ROOT's '__mul__' with vector's 'mul' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_mul(constructor, scalar, coordinates): + ref_vec = ROOT.Math.PtEtaPhiMVector(*constructor).__mul__(scalar) + vec = getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "tau"], constructor))), coordinates + )().__mul__(scalar) + assert ref_vec.X() == pytest.approx(vec.x) + assert ref_vec.Y() == pytest.approx(vec.y) + assert ref_vec.Z() == pytest.approx(vec.z) + assert ref_vec.T() == pytest.approx(vec.t) + + +# Run a test that compares ROOT's '__truediv__' with vector's '__truediv__' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_truediv(constructor, scalar, coordinates): + ref_vec = ROOT.Math.PtEtaPhiMVector(*constructor).__truediv__(scalar) + vec = getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "tau"], constructor))), coordinates + )().__truediv__(scalar) + assert ref_vec.X() == pytest.approx(vec.x) + assert ref_vec.Y() == pytest.approx(vec.y) + assert ref_vec.Z() == pytest.approx(vec.z) + assert ref_vec.T() == pytest.approx(vec.t) + + +# Run a test that compares ROOT's '__eq__' with vector's 'isclose' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_eq(constructor, coordinates): + ref_vec = ROOT.Math.PtEtaPhiMVector(*constructor).__eq__( + ROOT.Math.PtEtaPhiMVector(*constructor) + ) + vec = getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "tau"], constructor))), coordinates + )().isclose( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "tau"], constructor))), + coordinates, + )() + ) + assert ref_vec == vec + + +# Run a test that compares ROOT's 'RotateX()' with vector's 'rotateX' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_RotateX(constructor, angle, coordinates): + ref_vec = ROOT.Math.RotationX(angle) * ROOT.Math.PtEtaPhiMVector(*constructor) + vec = getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "tau"], constructor))), coordinates + )() + res_vec = vec.rotateX(angle) + assert ref_vec.X() == pytest.approx(res_vec.x) + assert ref_vec.Y() == pytest.approx(res_vec.y) + assert ref_vec.Z() == pytest.approx(res_vec.z) + assert ref_vec.T() == pytest.approx(res_vec.t) + + +# Run a test that compares ROOT's 'RotateY()' with vector's 'rotateY' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_RotateY(constructor, angle, coordinates): + ref_vec = ROOT.Math.RotationY(angle) * ROOT.Math.PtEtaPhiMVector(*constructor) + vec = getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "tau"], constructor))), coordinates + )() + res_vec = vec.rotateY(angle) + assert ref_vec.X() == pytest.approx(res_vec.x) + assert ref_vec.Y() == pytest.approx(res_vec.y) + assert ref_vec.Z() == pytest.approx(res_vec.z) + assert ref_vec.T() == pytest.approx(res_vec.t) + + +# Run a test that compares ROOT's 'RotateZ()' with vector's 'rotateZ' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_RotateZ(constructor, angle, coordinates): + ref_vec = ROOT.Math.RotationZ(angle) * ROOT.Math.PtEtaPhiMVector(*constructor) + vec = getattr( + vector.obj(**dict(zip(["rho", "eta", "phi", "tau"], constructor))), coordinates + )() + res_vec = vec.rotateZ(angle) + assert ref_vec.X() == pytest.approx(res_vec.x) + assert ref_vec.Y() == pytest.approx(res_vec.y) + assert ref_vec.Z() == pytest.approx(res_vec.z) + assert ref_vec.T() == pytest.approx(res_vec.t) diff --git a/tests/root/test_PxPyPzEVector.py b/tests/root/test_PxPyPzEVector.py new file mode 100644 index 00000000..77cf7a08 --- /dev/null +++ b/tests/root/test_PxPyPzEVector.py @@ -0,0 +1,451 @@ +# Copyright (c) 2019-2021, Jonas Eschle, Jim Pivarski, Eduardo Rodrigues, and Henry Schreiner. +# +# Distributed under the 3-clause BSD license, see accompanying file LICENSE +# or https://github.com/scikit-hep/vector for details. + +import pytest + +import vector + +# If ROOT is not available, skip these tests. +ROOT = pytest.importorskip("ROOT") + +# ROOT.Math.PxPyPzEVector constructor arguments to get all the weird cases. +constructor = [ + (0, 0, 0, 0), + (0, 0, 1, 0), # theta == 0.0 + (0, 0, -1, 0), + (0, 0, 1, 0), + (0, 0, 0, 4294967296), + (0, 4294967296, 0, 0), + (0, 0, 0, 10), + (0, 0, 0, -10), + (1, 2, 3, 0), + (1, 2, 3, 10), + (1, 2, 3, -10), + (1.0, 2.0, 3.0, 2.5), + (1, 2, 3, 2.5), + (1, 2, 3, -2.5), +] + +# Coordinate conversion methods to apply to the VectorObject4D. +coordinate_list = [ + "to_xyzt", + "to_xythetat", # may fail for constructor2 + "to_xyetat", + "to_rhophizt", + "to_rhophithetat", + "to_rhophietat", + "to_xyztau", + "to_xythetatau", + "to_xyetatau", + "to_rhophiztau", + "to_rhophithetatau", + "to_rhophietatau", +] + + +@pytest.fixture(scope="module", params=coordinate_list) +def coordinates(request): + return request.param + + +angle_list = [ + 0, + 0.0, + 0.7853981633974483, + -0.7853981633974483, + 1.5707963267948966, + -1.5707963267948966, + 3.141592653589793, + -3.141592653589793, + 6.283185307179586, + -6.283185307179586, +] + + +@pytest.fixture(scope="module", params=angle_list) +def angle(request): + return request.param + + +scalar_list = [ + 0, + -1, + 1.0, + 100000.0000, + -100000.0000, +] + + +@pytest.fixture(scope="module", params=scalar_list) +def scalar(request): + return request.param + + +# Run a test that compares ROOT's 'Dot()' with vector's 'dot' for all cases. +# Dot +@pytest.mark.parametrize("constructor", constructor) +def test_Dot(constructor, coordinates): + v1 = getattr( + vector.obj(**dict(zip(["x", "y", "z", "t"], constructor))), coordinates + )() + v2 = getattr( + vector.obj(**dict(zip(["x", "y", "z", "t"], constructor))), coordinates + )() + assert ROOT.Math.PxPyPzEVector(*constructor).Dot( + ROOT.Math.PxPyPzEVector(*constructor) + ) == pytest.approx(v1.dot(v2)) + + +# Run a test that compares ROOT's 'M2()' with vector's 'tau2' for all cases. +# Mass2 is our tau2 (or mass2 if it's a momentum vector and has kinematic synonyms) +@pytest.mark.parametrize("constructor", constructor) +def test_M2(constructor, coordinates): + assert ROOT.Math.PxPyPzEVector(*constructor).M2() == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z", "t"], constructor))), coordinates + )().tau2 + ) + + +# Run a test that compares ROOT's 'M()' with vector's 'tau' for all cases. +# Mass is tau (or mass) +@pytest.mark.parametrize("constructor", constructor) +def test_M(constructor, coordinates): + assert ROOT.Math.PxPyPzEVector(*constructor).M() == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z", "t"], constructor))), coordinates + )().tau + ) + + +# Run a test that compares ROOT's 'Mt2()' with vector's 'mt2' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Mt2(constructor, coordinates): + v = getattr( + vector.obj(**dict(zip(["x", "y", "z", "t"], constructor))), coordinates + )() + assert ROOT.Math.PxPyPzEVector(*constructor).Mt2() == pytest.approx( + v.t * v.t - v.z * v.z + ) + + +# Run a test that compares ROOT's 'Mt()' with vector's 'mt' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Mt(constructor, coordinates): + v = getattr( + vector.obj(**dict(zip(["x", "y", "z", "t"], constructor))), coordinates + )() + assert ROOT.Math.PxPyPzEVector(*constructor).mt() == pytest.approx( + v.lib.sqrt(v.t * v.t - v.z * v.z) + ) + + +# Run a test that compares ROOT's 'P2()' with vector's 'mag2' for all cases. +# P2 is our mag2 (ROOT's 4D mag2 is the dot product with itself, what we call tau or mass) +@pytest.mark.parametrize("constructor", constructor) +def test_P2(constructor, coordinates): + assert ROOT.Math.PxPyPzEVector(*constructor).P2() == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z", "t"], constructor))), coordinates + )().mag2 + ) + + +# Run a test that compares ROOT's 'P()' with vector's 'mag' for all cases. +# P is our mag (same deal) +@pytest.mark.parametrize("constructor", constructor) +def test_P(constructor, coordinates): + assert ROOT.Math.PxPyPzEVector(*constructor).P() == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z", "t"], constructor))), coordinates + )().mag + ) + + +# Run a test that compares ROOT's 'Perp2()' with vector's 'rho2' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Perp2(constructor, coordinates): + assert ROOT.Math.PxPyPzEVector(*constructor).Perp2() == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z", "t"], constructor))), coordinates + )().rho2 + ) + + +# Run a test that compares ROOT's 'Perp()' with vector's 'rho' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Perp(constructor, coordinates): + assert ROOT.Math.sqrt( + ROOT.Math.PxPyPzEVector(*constructor).Perp2() + ) == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z", "t"], constructor))), coordinates + )().rho + ) + + +# Run a test that compares ROOT's 'Phi()' with vector's 'phi' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Phi(constructor, coordinates): + assert ROOT.Math.PxPyPzEVector(*constructor).Phi() == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z", "t"], constructor))), coordinates + )().phi + ) + + +# Run a test that compares ROOT's 'Rapidity()' with vector's 'rapidity' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Rapidity(constructor, coordinates): + assert ROOT.Math.PxPyPzEVector(*constructor).Rapidity() == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z", "t"], constructor))), coordinates + )().rapidity + ) + + +# Run a test that compares ROOT's 'Beta()' with vector's 'beta' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Beta(constructor, coordinates): + assert ROOT.Math.PxPyPzEVector(*constructor).Beta() == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z", "t"], constructor))), coordinates + )().beta + ) + + +# Run a test that compares ROOT's 'Eta()' with vector's 'eta' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Eta(constructor, coordinates): + assert ROOT.Math.PxPyPzEVector(*constructor).Eta() == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z", "t"], constructor))), coordinates + )().eta + ) + + +# Run a test that compares ROOT's 'Gamma()' with vector's 'gamma' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Gamma(constructor, coordinates): + assert ROOT.Math.PxPyPzEVector(*constructor).Gamma() == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z", "t"], constructor))), coordinates + )().gamma + ) + + +# Run a test that compares ROOT's 'isLightlike()' with vector's 'is_lightlike' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_isLightlike(constructor, coordinates): + assert ROOT.Math.PxPyPzEVector(*constructor).isLightlike() == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z", "t"], constructor))), coordinates + )().is_lightlike() + ) + + +# Run a test that compares ROOT's 'isSpacelike()' with vector's 'is_spacelike' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_isSpacelike(constructor, coordinates): + assert ROOT.Math.PxPyPzEVector(*constructor).isSpacelike() == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z", "t"], constructor))), coordinates + )().is_spacelike() + ) + + +# Run a test that compares ROOT's 'isTimelike()' with vector's 'is_timelike' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_isTimelike(constructor, coordinates): + assert ROOT.Math.PxPyPzEVector(*constructor).isTimelike() == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z", "t"], constructor))), coordinates + )().is_timelike() + ) + + +# Run a test that compares ROOT's 'Theta()' with vector's 'theta' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Theta(constructor, coordinates): + assert ROOT.Math.PxPyPzEVector(*constructor).Theta() == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z", "t"], constructor))), coordinates + )().theta + ) + + +# Run a test that compares ROOT's 'X()' with vector's 'x' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_X(constructor, coordinates): + assert ROOT.Math.PxPyPzEVector(*constructor).X() == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z", "t"], constructor))), coordinates + )().x + ) + + +# Run a test that compares ROOT's 'Y()' with vector's 'y' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Y(constructor, coordinates): + assert ROOT.Math.PxPyPzEVector(*constructor).Y() == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z", "t"], constructor))), coordinates + )().y + ) + + +# Run a test that compares ROOT's 'Z()' with vector's 'z' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Z(constructor, coordinates): + assert ROOT.Math.PxPyPzEVector(*constructor).Z() == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z", "t"], constructor))), coordinates + )().z + ) + + +# Run a test that compares ROOT's 'T()' with vector's 't' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_T(constructor, coordinates): + assert ROOT.Math.PxPyPzEVector(*constructor).T() == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z", "t"], constructor))), coordinates + )().t + ) + + +# Run a test that compares ROOT's '__add__' with vector's 'add' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_add(constructor, coordinates): + ref_vec = ROOT.Math.PxPyPzEVector(*constructor).__add__( + ROOT.Math.PxPyPzEVector(*constructor) + ) + vec = getattr( + vector.obj(**dict(zip(["x", "y", "z", "t"], constructor))), coordinates + )().add( + getattr( + vector.obj(**dict(zip(["x", "y", "z", "t"], constructor))), coordinates + )() + ) + assert ref_vec.X() == pytest.approx(vec.x) + assert ref_vec.Y() == pytest.approx(vec.y) + assert ref_vec.Z() == pytest.approx(vec.z) + assert ref_vec.T() == pytest.approx(vec.t) + + +# Run a test that compares ROOT's '__sub__' with vector's 'subtract' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_sub(constructor, coordinates): + ref_vec = ROOT.Math.PxPyPzEVector(*constructor).__sub__( + ROOT.Math.PxPyPzEVector(*constructor) + ) + vec1 = getattr( + vector.obj(**dict(zip(["x", "y", "z", "t"], constructor))), coordinates + )() + vec2 = getattr( + vector.obj(**dict(zip(["x", "y", "z", "t"], constructor))), coordinates + )() + res_vec = vec1.subtract(vec2) + assert ref_vec.X() == pytest.approx(res_vec.x) + assert ref_vec.Y() == pytest.approx(res_vec.y) + assert ref_vec.Z() == pytest.approx(res_vec.z) + assert ref_vec.T() == pytest.approx(res_vec.t) + + +# Run a test that compares ROOT's '__neg__' with vector's '__neg__' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_neg(constructor, coordinates): + ref_vec = ROOT.Math.PxPyPzEVector(*constructor).__neg__() + vec = getattr( + vector.obj(**dict(zip(["x", "y", "z", "t"], constructor))), coordinates + )().__neg__ + assert ref_vec.X() == pytest.approx(vec().x) + assert ref_vec.Y() == pytest.approx(vec().y) + assert ref_vec.Z() == pytest.approx(vec().z) + assert ref_vec.T() == pytest.approx(vec().t) + + +# Run a test that compares ROOT's '__mul__' with vector's 'mul' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_mul(constructor, scalar, coordinates): + ref_vec = ROOT.Math.PxPyPzEVector(*constructor).__mul__(scalar) + vec = getattr( + vector.obj(**dict(zip(["x", "y", "z", "t"], constructor))), coordinates + )().__mul__(scalar) + assert ref_vec.X() == pytest.approx(vec.x) + assert ref_vec.Y() == pytest.approx(vec.y) + assert ref_vec.Z() == pytest.approx(vec.z) + assert ref_vec.T() == pytest.approx(vec.t) + + +# Run a test that compares ROOT's '__truediv__' with vector's '__truediv__' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_truediv(constructor, scalar, coordinates): + ref_vec = ROOT.Math.PxPyPzEVector(*constructor).__truediv__(scalar) + vec = getattr( + vector.obj(**dict(zip(["x", "y", "z", "t"], constructor))), coordinates + )().__truediv__(scalar) + assert ref_vec.X() == pytest.approx(vec.x) + assert ref_vec.Y() == pytest.approx(vec.y) + assert ref_vec.Z() == pytest.approx(vec.z) + assert ref_vec.T() == pytest.approx(vec.t) + + +# Run a test that compares ROOT's '__eq__' with vector's 'isclose' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_eq(constructor, coordinates): + ref_vec = ROOT.Math.PxPyPzEVector(*constructor).__eq__( + ROOT.Math.PxPyPzEVector(*constructor) + ) + vec = getattr( + vector.obj(**dict(zip(["x", "y", "z", "t"], constructor))), coordinates + )().isclose( + getattr( + vector.obj(**dict(zip(["x", "y", "z", "t"], constructor))), coordinates + )() + ) + assert ref_vec == vec + + +# Run a test that compares ROOT's 'RotateX()' with vector's 'rotateX' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_RotateX(constructor, angle, coordinates): + ref_vec = ROOT.Math.RotationX(angle) * ROOT.Math.PxPyPzEVector(*constructor) + vec = getattr( + vector.obj(**dict(zip(["x", "y", "z", "t"], constructor))), coordinates + )() + res_vec = vec.rotateX(angle) + assert ref_vec.X() == pytest.approx(res_vec.x) + assert ref_vec.Y() == pytest.approx(res_vec.y) + assert ref_vec.Z() == pytest.approx(res_vec.z) + assert ref_vec.T() == pytest.approx(res_vec.t) + + +# Run a test that compares ROOT's 'RotateY()' with vector's 'rotateY' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_RotateY(constructor, angle, coordinates): + ref_vec = ROOT.Math.RotationY(angle) * ROOT.Math.PxPyPzEVector(*constructor) + vec = getattr( + vector.obj(**dict(zip(["x", "y", "z", "t"], constructor))), coordinates + )() + res_vec = vec.rotateY(angle) + assert ref_vec.X() == pytest.approx(res_vec.x) + assert ref_vec.Y() == pytest.approx(res_vec.y) + assert ref_vec.Z() == pytest.approx(res_vec.z) + assert ref_vec.T() == pytest.approx(res_vec.t) + + +# Run a test that compares ROOT's 'RotateZ()' with vector's 'rotateZ' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_RotateZ(constructor, angle, coordinates): + ref_vec = ROOT.Math.RotationZ(angle) * ROOT.Math.PxPyPzEVector(*constructor) + vec = getattr( + vector.obj(**dict(zip(["x", "y", "z", "t"], constructor))), coordinates + )() + res_vec = vec.rotateZ(angle) + assert ref_vec.X() == pytest.approx(res_vec.x) + assert ref_vec.Y() == pytest.approx(res_vec.y) + assert ref_vec.Z() == pytest.approx(res_vec.z) + assert ref_vec.T() == pytest.approx(res_vec.t) diff --git a/tests/root/test_PxPyPzMVector.py b/tests/root/test_PxPyPzMVector.py new file mode 100644 index 00000000..e0fd3dbc --- /dev/null +++ b/tests/root/test_PxPyPzMVector.py @@ -0,0 +1,451 @@ +# Copyright (c) 2019-2021, Jonas Eschle, Jim Pivarski, Eduardo Rodrigues, and Henry Schreiner. +# +# Distributed under the 3-clause BSD license, see accompanying file LICENSE +# or https://github.com/scikit-hep/vector for details. + +import pytest + +import vector + +# If ROOT is not available, skip these tests. +ROOT = pytest.importorskip("ROOT") + +# ROOT.Math.PxPyPzMVector constructor arguments to get all the weird cases. +constructor = [ + (0, 0, 0, 0), + (0, 0, 1, 0), # theta == 0.0 + (0, 0, -1, 0), + (0, 0, 1, 0), + (0, 0, 0, 4294967296), + (0, 4294967296, 0, 0), + (0, 0, 0, 10), + (0, 0, 0, -10), + (1, 2, 3, 0), + (1, 2, 3, 10), + (1, 2, 3, -10), + (1.0, 2.0, 3.0, 2.5), + (1, 2, 3, 2.5), + (1, 2, 3, -2.5), +] + +# Coordinate conversion methods to apply to the VectorObject4D. +coordinate_list = [ + "to_xyzt", + "to_xythetat", # may fail for constructor2 + "to_xyetat", + "to_rhophizt", + "to_rhophithetat", + "to_rhophietat", + "to_xyztau", + "to_xythetatau", + "to_xyetatau", + "to_rhophiztau", + "to_rhophithetatau", + "to_rhophietatau", +] + + +@pytest.fixture(scope="module", params=coordinate_list) +def coordinates(request): + return request.param + + +angle_list = [ + 0, + 0.0, + 0.7853981633974483, + -0.7853981633974483, + 1.5707963267948966, + -1.5707963267948966, + 3.141592653589793, + -3.141592653589793, + 6.283185307179586, + -6.283185307179586, +] + + +@pytest.fixture(scope="module", params=angle_list) +def angle(request): + return request.param + + +scalar_list = [ + 0, + -1, + 1.0, + 100000.0000, + -100000.0000, +] + + +@pytest.fixture(scope="module", params=scalar_list) +def scalar(request): + return request.param + + +# Run a test that compares ROOT's 'Dot()' with vector's 'dot' for all cases. +# Dot +@pytest.mark.parametrize("constructor", constructor) +def test_Dot(constructor, coordinates): + v1 = getattr( + vector.obj(**dict(zip(["x", "y", "z", "tau"], constructor))), coordinates + )() + v2 = getattr( + vector.obj(**dict(zip(["x", "y", "z", "tau"], constructor))), coordinates + )() + assert ROOT.Math.PxPyPzMVector(*constructor).Dot( + ROOT.Math.PxPyPzMVector(*constructor) + ) == pytest.approx(v1.dot(v2)) + + +# Run a test that compares ROOT's 'M2()' with vector's 'tau2' for all cases. +# Mass2 is our tau2 (or mass2 if it's a momentum vector and has kinematic synonyms) +@pytest.mark.parametrize("constructor", constructor) +def test_M2(constructor, coordinates): + assert ROOT.Math.PxPyPzMVector(*constructor).M2() == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z", "tau"], constructor))), coordinates + )().tau2 + ) + + +# Run a test that compares ROOT's 'M()' with vector's 'tau' for all cases. +# Mass is tau (or mass) +@pytest.mark.parametrize("constructor", constructor) +def test_M(constructor, coordinates): + assert ROOT.Math.PxPyPzMVector(*constructor).M() == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z", "tau"], constructor))), coordinates + )().tau + ) + + +# Run a test that compares ROOT's 'Mt2()' with vector's 'mt2' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Mt2(constructor, coordinates): + v = getattr( + vector.obj(**dict(zip(["x", "y", "z", "tau"], constructor))), coordinates + )() + assert ROOT.Math.PxPyPzMVector(*constructor).Mt2() == pytest.approx( + v.t * v.t - v.z * v.z + ) + + +# Run a test that compares ROOT's 'Mt()' with vector's 'mt' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Mt(constructor, coordinates): + v = getattr( + vector.obj(**dict(zip(["x", "y", "z", "tau"], constructor))), coordinates + )() + assert ROOT.Math.PxPyPzMVector(*constructor).mt() == pytest.approx( + v.lib.sqrt(v.t * v.t - v.z * v.z) + ) + + +# Run a test that compares ROOT's 'P2()' with vector's 'mag2' for all cases. +# P2 is our mag2 (ROOT's 4D mag2 is the dot product with itself, what we call tau or mass) +@pytest.mark.parametrize("constructor", constructor) +def test_P2(constructor, coordinates): + assert ROOT.Math.PxPyPzMVector(*constructor).P2() == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z", "tau"], constructor))), coordinates + )().mag2 + ) + + +# Run a test that compares ROOT's 'P()' with vector's 'mag' for all cases. +# P is our mag (same deal) +@pytest.mark.parametrize("constructor", constructor) +def test_P(constructor, coordinates): + assert ROOT.Math.PxPyPzMVector(*constructor).P() == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z", "tau"], constructor))), coordinates + )().mag + ) + + +# Run a test that compares ROOT's 'Perp2()' with vector's 'rho2' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Perp2(constructor, coordinates): + assert ROOT.Math.PxPyPzMVector(*constructor).Perp2() == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z", "tau"], constructor))), coordinates + )().rho2 + ) + + +# Run a test that compares ROOT's 'Perp()' with vector's 'rho' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Perp(constructor, coordinates): + assert ROOT.Math.sqrt( + ROOT.Math.PxPyPzMVector(*constructor).Perp2() + ) == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z", "tau"], constructor))), coordinates + )().rho + ) + + +# Run a test that compares ROOT's 'Phi()' with vector's 'phi' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Phi(constructor, coordinates): + assert ROOT.Math.PxPyPzMVector(*constructor).Phi() == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z", "tau"], constructor))), coordinates + )().phi + ) + + +# Run a test that compares ROOT's 'Rapidity()' with vector's 'rapidity' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Rapidity(constructor, coordinates): + assert ROOT.Math.PxPyPzMVector(*constructor).Rapidity() == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z", "tau"], constructor))), coordinates + )().rapidity + ) + + +# Run a test that compares ROOT's 'Beta()' with vector's 'beta' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Beta(constructor, coordinates): + assert ROOT.Math.PxPyPzMVector(*constructor).Beta() == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z", "tau"], constructor))), coordinates + )().beta + ) + + +# Run a test that compares ROOT's 'Eta()' with vector's 'eta' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Eta(constructor, coordinates): + assert ROOT.Math.PxPyPzMVector(*constructor).Eta() == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z", "tau"], constructor))), coordinates + )().eta + ) + + +# Run a test that compares ROOT's 'Gamma()' with vector's 'gamma' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Gamma(constructor, coordinates): + assert ROOT.Math.PxPyPzMVector(*constructor).Gamma() == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z", "tau"], constructor))), coordinates + )().gamma + ) + + +# Run a test that compares ROOT's 'isLightlike()' with vector's 'is_lightlike' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_isLightlike(constructor, coordinates): + assert ROOT.Math.PxPyPzMVector(*constructor).isLightlike() == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z", "tau"], constructor))), coordinates + )().is_lightlike() + ) + + +# Run a test that compares ROOT's 'isSpacelike()' with vector's 'is_spacelike' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_isSpacelike(constructor, coordinates): + assert ROOT.Math.PxPyPzMVector(*constructor).isSpacelike() == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z", "tau"], constructor))), coordinates + )().is_spacelike() + ) + + +# Run a test that compares ROOT's 'isTimelike()' with vector's 'is_timelike' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_isTimelike(constructor, coordinates): + assert ROOT.Math.PxPyPzMVector(*constructor).isTimelike() == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z", "tau"], constructor))), coordinates + )().is_timelike() + ) + + +# Run a test that compares ROOT's 'Theta()' with vector's 'theta' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Theta(constructor, coordinates): + assert ROOT.Math.PxPyPzMVector(*constructor).Theta() == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z", "tau"], constructor))), coordinates + )().theta + ) + + +# Run a test that compares ROOT's 'X()' with vector's 'x' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_X(constructor, coordinates): + assert ROOT.Math.PxPyPzMVector(*constructor).X() == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z", "tau"], constructor))), coordinates + )().x + ) + + +# Run a test that compares ROOT's 'Y()' with vector's 'y' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Y(constructor, coordinates): + assert ROOT.Math.PxPyPzMVector(*constructor).Y() == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z", "tau"], constructor))), coordinates + )().y + ) + + +# Run a test that compares ROOT's 'Z()' with vector's 'z' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Z(constructor, coordinates): + assert ROOT.Math.PxPyPzMVector(*constructor).Z() == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z", "tau"], constructor))), coordinates + )().z + ) + + +# Run a test that compares ROOT's 'T()' with vector's 't' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_T(constructor, coordinates): + assert ROOT.Math.PxPyPzMVector(*constructor).T() == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z", "tau"], constructor))), coordinates + )().t + ) + + +# Run a test that compares ROOT's '__add__' with vector's 'add' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_add(constructor, coordinates): + ref_vec = ROOT.Math.PxPyPzMVector(*constructor).__add__( + ROOT.Math.PxPyPzMVector(*constructor) + ) + vec = getattr( + vector.obj(**dict(zip(["x", "y", "z", "tau"], constructor))), coordinates + )().add( + getattr( + vector.obj(**dict(zip(["x", "y", "z", "tau"], constructor))), coordinates + )() + ) + assert ref_vec.X() == pytest.approx(vec.x) + assert ref_vec.Y() == pytest.approx(vec.y) + assert ref_vec.Z() == pytest.approx(vec.z) + assert ref_vec.T() == pytest.approx(vec.t) + + +# Run a test that compares ROOT's '__sub__' with vector's 'subtract' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_sub(constructor, coordinates): + ref_vec = ROOT.Math.PxPyPzMVector(*constructor).__sub__( + ROOT.Math.PxPyPzMVector(*constructor) + ) + vec1 = getattr( + vector.obj(**dict(zip(["x", "y", "z", "tau"], constructor))), coordinates + )() + vec2 = getattr( + vector.obj(**dict(zip(["x", "y", "z", "tau"], constructor))), coordinates + )() + res_vec = vec1.subtract(vec2) + assert ref_vec.X() == pytest.approx(res_vec.x) + assert ref_vec.Y() == pytest.approx(res_vec.y) + assert ref_vec.Z() == pytest.approx(res_vec.z) + assert ref_vec.T() == pytest.approx(res_vec.t) + + +# Run a test that compares ROOT's '__neg__' with vector's '__neg__' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_neg(constructor, coordinates): + ref_vec = ROOT.Math.PxPyPzMVector(*constructor).__neg__() + vec = getattr( + vector.obj(**dict(zip(["x", "y", "z", "tau"], constructor))), coordinates + )().__neg__ + assert ref_vec.X() == pytest.approx(vec().x) + assert ref_vec.Y() == pytest.approx(vec().y) + assert ref_vec.Z() == pytest.approx(vec().z) + assert ref_vec.T() == pytest.approx(vec().t) + + +# Run a test that compares ROOT's '__mul__' with vector's 'mul' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_mul(constructor, scalar, coordinates): + ref_vec = ROOT.Math.PxPyPzMVector(*constructor).__mul__(scalar) + vec = getattr( + vector.obj(**dict(zip(["x", "y", "z", "tau"], constructor))), coordinates + )().__mul__(scalar) + assert ref_vec.X() == pytest.approx(vec.x) + assert ref_vec.Y() == pytest.approx(vec.y) + assert ref_vec.Z() == pytest.approx(vec.z) + assert ref_vec.T() == pytest.approx(vec.t) + + +# Run a test that compares ROOT's '__truediv__' with vector's '__truediv__' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_truediv(constructor, scalar, coordinates): + ref_vec = ROOT.Math.PxPyPzMVector(*constructor).__truediv__(scalar) + vec = getattr( + vector.obj(**dict(zip(["x", "y", "z", "tau"], constructor))), coordinates + )().__truediv__(scalar) + assert ref_vec.X() == pytest.approx(vec.x) + assert ref_vec.Y() == pytest.approx(vec.y) + assert ref_vec.Z() == pytest.approx(vec.z) + assert ref_vec.T() == pytest.approx(vec.t) + + +# Run a test that compares ROOT's '__eq__' with vector's 'isclose' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_eq(constructor, coordinates): + ref_vec = ROOT.Math.PxPyPzMVector(*constructor).__eq__( + ROOT.Math.PxPyPzMVector(*constructor) + ) + vec = getattr( + vector.obj(**dict(zip(["x", "y", "z", "tau"], constructor))), coordinates + )().isclose( + getattr( + vector.obj(**dict(zip(["x", "y", "z", "tau"], constructor))), coordinates + )() + ) + assert ref_vec == vec + + +# Run a test that compares ROOT's 'RotateX()' with vector's 'rotateX' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_RotateX(constructor, angle, coordinates): + ref_vec = ROOT.Math.RotationX(angle) * ROOT.Math.PxPyPzMVector(*constructor) + vec = getattr( + vector.obj(**dict(zip(["x", "y", "z", "tau"], constructor))), coordinates + )() + res_vec = vec.rotateX(angle) + assert ref_vec.X() == pytest.approx(res_vec.x) + assert ref_vec.Y() == pytest.approx(res_vec.y) + assert ref_vec.Z() == pytest.approx(res_vec.z) + assert ref_vec.T() == pytest.approx(res_vec.t) + + +# Run a test that compares ROOT's 'RotateY()' with vector's 'rotateY' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_RotateY(constructor, angle, coordinates): + ref_vec = ROOT.Math.RotationY(angle) * ROOT.Math.PxPyPzMVector(*constructor) + vec = getattr( + vector.obj(**dict(zip(["x", "y", "z", "tau"], constructor))), coordinates + )() + res_vec = vec.rotateY(angle) + assert ref_vec.X() == pytest.approx(res_vec.x) + assert ref_vec.Y() == pytest.approx(res_vec.y) + assert ref_vec.Z() == pytest.approx(res_vec.z) + assert ref_vec.T() == pytest.approx(res_vec.t) + + +# Run a test that compares ROOT's 'RotateZ()' with vector's 'rotateZ' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_RotateZ(constructor, angle, coordinates): + ref_vec = ROOT.Math.RotationZ(angle) * ROOT.Math.PxPyPzMVector(*constructor) + vec = getattr( + vector.obj(**dict(zip(["x", "y", "z", "tau"], constructor))), coordinates + )() + res_vec = vec.rotateZ(angle) + assert ref_vec.X() == pytest.approx(res_vec.x) + assert ref_vec.Y() == pytest.approx(res_vec.y) + assert ref_vec.Z() == pytest.approx(res_vec.z) + assert ref_vec.T() == pytest.approx(res_vec.t) diff --git a/tests/root/test_Quaternion.py b/tests/root/test_Quaternion.py new file mode 100644 index 00000000..721826d4 --- /dev/null +++ b/tests/root/test_Quaternion.py @@ -0,0 +1,81 @@ +# Copyright (c) 2019-2021, Jonas Eschle, Jim Pivarski, Eduardo Rodrigues, and Henry Schreiner. +# +# Distributed under the 3-clause BSD license, see accompanying file LICENSE +# or https://github.com/scikit-hep/vector for details. + +import pytest + +# If ROOT is not available, skip these tests. +ROOT = pytest.importorskip("ROOT") + +# ROOT.Math.XYVector constructor arguments to get all the weird cases. +constructor = [ + (0, 0, 0, 0), + (0, 0, 1, 0), # theta == 0.0 + (0, 0, -1, 0), + (0, 0, 1, 0), + (0, 0, 0, 4294967296), + (0, 4294967296, 0, 0), + (0, 0, 0, 10), + (0, 0, 0, -10), + (1, 2, 3, 0), + (1, 2, 3, 10), + (1, 2, 3, -10), + (1.0, 2.0, 3.0, 2.5), + (1, 2, 3, 2.5), + (1, 2, 3, -2.5), +] + +# Coordinate conversion methods to apply to the VectorObject4D. +coordinate_list = [ + "to_xyzt", + "to_xythetat", # may fail for constructor2 + "to_xyetat", + "to_rhophizt", + "to_rhophithetat", + "to_rhophietat", + "to_xyztau", + "to_xythetatau", + "to_xyetatau", + "to_rhophiztau", + "to_rhophithetatau", + "to_rhophietatau", +] + + +@pytest.fixture(scope="module", params=coordinate_list) +def coordinates(request): + return request.param + + +angle_list = [ + 0, + 0.0, + 0.7853981633974483, + -0.7853981633974483, + 1.5707963267948966, + -1.5707963267948966, + 3.141592653589793, + -3.141592653589793, + 6.283185307179586, + -6.283185307179586, +] + + +@pytest.fixture(scope="module", params=angle_list) +def angle(request): + return request.param + + +scalar_list = [ + 0, + -1, + 1.0, + 100000.0000, + -100000.0000, +] + + +@pytest.fixture(scope="module", params=scalar_list) +def scalar(request): + return request.param diff --git a/tests/root/test_RhoEtaPhiVector.py b/tests/root/test_RhoEtaPhiVector.py new file mode 100644 index 00000000..0db4c971 --- /dev/null +++ b/tests/root/test_RhoEtaPhiVector.py @@ -0,0 +1,272 @@ +# Copyright (c) 2019-2021, Jonas Eschle, Jim Pivarski, Eduardo Rodrigues, and Henry Schreiner. +# +# Distributed under the 3-clause BSD license, see accompanying file LICENSE +# or https://github.com/scikit-hep/vector for details. + +import numpy as np +import pytest + +import vector + +# If ROOT is not available, skip these tests. +ROOT = pytest.importorskip("ROOT") + +# ROOT.Math.RhoEtaPhiVector constructor arguments to get all the weird cases. +constructor = [ + (0, 0, 0), + (0, 10, 0), + (0, -10, 0), + (1, 0, 0), + (1, 10, 0), + (1, -10, 0), + (1.0, 2.5, 2.0), + (1, 2.5, 2.0), + (1, -2.5, 2.0), +] + +# Coordinate conversion methods to apply to the VectorObject2D. +coordinate_list = [ + "to_xyz", + "to_rhophieta", + "to_rhophitheta", + "to_rhophiz", + "to_xyeta", + "to_xytheta", +] + + +@pytest.fixture(scope="module", params=coordinate_list) +def coordinates(request): + return request.param + + +angle_list = [ + 0, + 0.0, + 0.7853981633974483, + -0.7853981633974483, + 1.5707963267948966, + -1.5707963267948966, + 3.141592653589793, + -3.141592653589793, + 6.283185307179586, + -6.283185307179586, +] + + +@pytest.fixture(scope="module", params=angle_list) +def angle(request): + return request.param + + +scalar_list = [ + 0, + -1, + 1.0, + 100000.0000, + -100000.0000, +] + + +@pytest.fixture(scope="module", params=scalar_list) +def scalar(request): + return request.param + + +# Run a test that compares ROOT's 'Dot()' with vector's 'dot' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Dot(constructor, coordinates): + assert ROOT.Math.RhoEtaPhiVector(*constructor).Dot( + ROOT.Math.RhoEtaPhiVector(*constructor) + ) == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi"], constructor))), coordinates + )().dot( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi"], constructor))), coordinates + )() + ) + ) + + +# Run a test that compares ROOT's 'Mag2()' with vector's 'rho2' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Mag2(constructor, coordinates): + assert ROOT.Math.RhoEtaPhiVector(*constructor).Mag2() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi"], constructor))), coordinates + )().rho2 + ) + + +# Run a test that compares ROOT's 'R()' with vector's 'rho' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_R(constructor, coordinates): + assert ROOT.Math.RhoEtaPhiVector(*constructor).R() == pytest.approx( + np.sqrt( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi"], constructor))), coordinates + )().rho2 + ) + ) + + +# Run a test that compares ROOT's 'Phi()' with vector's 'rho' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Phi(constructor, coordinates): + assert ROOT.Math.RhoEtaPhiVector(*constructor).Phi() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi"], constructor))), coordinates + )().phi + ) + + +# Run a test that compares ROOT's 'RotateX()' with vector's 'rotateX' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_RotateX(constructor, angle, coordinates): + ref_vec = ROOT.Math.RotationX(angle) * ROOT.Math.RhoEtaPhiVector(*constructor) + vec = getattr( + vector.obj(**dict(zip(["rho", "eta", "phi"], constructor))), coordinates + )() + res_vec = vec.rotateX(angle) + assert ref_vec.X() == pytest.approx(res_vec.x) + assert ref_vec.Y() == pytest.approx(res_vec.y) + assert ref_vec.Z() == pytest.approx(res_vec.z) + + +# Run a test that compares ROOT's 'RotateY()' with vector's 'rotateY' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_RotateY(constructor, angle, coordinates): + ref_vec = ROOT.Math.RotationY(angle) * ROOT.Math.RhoEtaPhiVector(*constructor) + vec = getattr( + vector.obj(**dict(zip(["rho", "eta", "phi"], constructor))), coordinates + )() + res_vec = vec.rotateY(angle) + assert ref_vec.X() == pytest.approx(res_vec.x) + assert ref_vec.Y() == pytest.approx(res_vec.y) + assert ref_vec.Z() == pytest.approx(res_vec.z) + + +# Run a test that compares ROOT's 'RotateZ()' with vector's 'rotateZ' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_RotateZ(constructor, angle, coordinates): + ref_vec = ROOT.Math.RotationZ(angle) * ROOT.Math.RhoEtaPhiVector(*constructor) + vec = getattr( + vector.obj(**dict(zip(["rho", "eta", "phi"], constructor))), coordinates + )() + res_vec = vec.rotateZ(angle) + assert ref_vec.X() == pytest.approx(res_vec.x) + assert ref_vec.Y() == pytest.approx(res_vec.y) + assert ref_vec.Z() == pytest.approx(res_vec.z) + + +# Run a test that compares ROOT's 'Unit()' with vector's 'unit' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Unit(constructor, coordinates): + ref_vec = ROOT.Math.RhoEtaPhiVector(*constructor).Unit() + vec = getattr( + vector.obj(**dict(zip(["rho", "eta", "phi"], constructor))), coordinates + )() + res_vec = vec.unit + assert ref_vec.X() == pytest.approx(res_vec().x) + assert ref_vec.Y() == pytest.approx(res_vec().y) + assert ref_vec.Z() == pytest.approx(res_vec().z) + + +# Run a test that compares ROOT's 'X()' and 'Y()' with vector's 'x' and 'y' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_X_and_Y(constructor, coordinates): + vec = getattr( + vector.obj(**dict(zip(["rho", "eta", "phi"], constructor))), coordinates + )() + assert ROOT.Math.RhoEtaPhiVector(*constructor).X() == pytest.approx( + vec.x + ) and ROOT.Math.RhoEtaPhiVector(*constructor).Y() == pytest.approx(vec.y) + + +# Run a test that compares ROOT's '__add__' with vector's 'add' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_add(constructor, coordinates): + ref_vec = ROOT.Math.RhoEtaPhiVector(*constructor).__add__( + ROOT.Math.RhoEtaPhiVector(*constructor) + ) + vec = getattr( + vector.obj(**dict(zip(["rho", "eta", "phi"], constructor))), coordinates + )().add( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi"], constructor))), coordinates + )() + ) + assert ref_vec.X() == pytest.approx(vec.x) + assert ref_vec.Y() == pytest.approx(vec.y) + assert ref_vec.Z() == pytest.approx(vec.z) + + +# Run a test that compares ROOT's '__sub__' with vector's 'subtract' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_sub(constructor, coordinates): + ref_vec = ROOT.Math.RhoEtaPhiVector(*constructor).__sub__( + ROOT.Math.RhoEtaPhiVector(*constructor) + ) + vec1 = getattr( + vector.obj(**dict(zip(["rho", "eta", "phi"], constructor))), coordinates + )() + vec2 = getattr( + vector.obj(**dict(zip(["rho", "eta", "phi"], constructor))), coordinates + )() + res_vec = vec1.subtract(vec2) + assert ref_vec.X() == pytest.approx(res_vec.x) + assert ref_vec.Y() == pytest.approx(res_vec.y) + assert ref_vec.Z() == pytest.approx(res_vec.z) + + +# Run a test that compares ROOT's '__neg__' with vector's '__neg__' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_neg(constructor, coordinates): + ref_vec = ROOT.Math.RhoEtaPhiVector(*constructor).__neg__() + vec = getattr( + vector.obj(**dict(zip(["rho", "eta", "phi"], constructor))), coordinates + )().__neg__ + assert ref_vec.X() == pytest.approx(vec().x) + assert ref_vec.Y() == pytest.approx(vec().y) + assert ref_vec.Z() == pytest.approx(vec().z) + + +# Run a test that compares ROOT's '__mul__' with vector's 'mul' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_mul(constructor, scalar, coordinates): + ref_vec = ROOT.Math.RhoEtaPhiVector(*constructor).__mul__(scalar) + vec = getattr( + vector.obj(**dict(zip(["rho", "eta", "phi"], constructor))), coordinates + )().__mul__(scalar) + assert ref_vec.X() == pytest.approx(vec.x) + assert ref_vec.Y() == pytest.approx(vec.y) + assert ref_vec.Z() == pytest.approx(vec.z) + + +# Run a test that compares ROOT's '__truediv__' with vector's '__truediv__' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_truediv(constructor, scalar, coordinates): + ref_vec = ROOT.Math.RhoEtaPhiVector(*constructor).__truediv__(scalar) + vec = getattr( + vector.obj(**dict(zip(["rho", "eta", "phi"], constructor))), coordinates + )().__truediv__(scalar) + assert ref_vec.X() == pytest.approx(vec.x) + assert ref_vec.Y() == pytest.approx(vec.y) + assert ref_vec.Z() == pytest.approx(vec.z) + + +# Run a test that compares ROOT's '__eq__' with vector's 'isclose' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_eq(constructor, coordinates): + ref_vec = ROOT.Math.RhoEtaPhiVector(*constructor).__eq__( + ROOT.Math.RhoEtaPhiVector(*constructor) + ) + vec = getattr( + vector.obj(**dict(zip(["rho", "eta", "phi"], constructor))), coordinates + )().isclose( + getattr( + vector.obj(**dict(zip(["rho", "eta", "phi"], constructor))), coordinates + )() + ) + assert ref_vec == vec diff --git a/tests/root/test_RhoZPhiVector.py b/tests/root/test_RhoZPhiVector.py new file mode 100644 index 00000000..39241e64 --- /dev/null +++ b/tests/root/test_RhoZPhiVector.py @@ -0,0 +1,272 @@ +# Copyright (c) 2019-2021, Jonas Eschle, Jim Pivarski, Eduardo Rodrigues, and Henry Schreiner. +# +# Distributed under the 3-clause BSD license, see accompanying file LICENSE +# or https://github.com/scikit-hep/vector for details. + +import numpy as np +import pytest + +import vector + +# If ROOT is not available, skip these tests. +ROOT = pytest.importorskip("ROOT") + +# ROOT.Math.RhoZPhiVector constructor arguments to get all the weird cases. +constructor = [ + (0, 0, 0), + (0, 10, 0), + (0, -10, 0), + (1, 0, 0), + (1, 10, 0), + (1, -10, 0), + (1.0, 2.5, 2.0), + (1, 2.5, 2.0), + (1, -2.5, 2.0), +] + +# Coordinate conversion methods to apply to the VectorObject2D. +coordinate_list = [ + "to_xyz", + "to_rhophieta", + "to_rhophitheta", + "to_rhophiz", + "to_xyeta", + "to_xytheta", +] + + +@pytest.fixture(scope="module", params=coordinate_list) +def coordinates(request): + return request.param + + +angle_list = [ + 0, + 0.0, + 0.7853981633974483, + -0.7853981633974483, + 1.5707963267948966, + -1.5707963267948966, + 3.141592653589793, + -3.141592653589793, + 6.283185307179586, + -6.283185307179586, +] + + +@pytest.fixture(scope="module", params=angle_list) +def angle(request): + return request.param + + +scalar_list = [ + 0, + -1, + 1.0, + 100000.0000, + -100000.0000, +] + + +@pytest.fixture(scope="module", params=scalar_list) +def scalar(request): + return request.param + + +# Run a test that compares ROOT's 'Dot()' with vector's 'dot' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Dot(constructor, coordinates): + assert ROOT.Math.RhoZPhiVector(*constructor).Dot( + ROOT.Math.RhoZPhiVector(*constructor) + ) == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "z", "phi"], constructor))), coordinates + )().dot( + getattr( + vector.obj(**dict(zip(["rho", "z", "phi"], constructor))), coordinates + )() + ) + ) + + +# Run a test that compares ROOT's 'Mag2()' with vector's 'rho2' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Mag2(constructor, coordinates): + assert ROOT.Math.RhoZPhiVector(*constructor).Mag2() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "z", "phi"], constructor))), coordinates + )().rho2 + ) + + +# Run a test that compares ROOT's 'R()' with vector's 'rho' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_R(constructor, coordinates): + assert ROOT.Math.RhoZPhiVector(*constructor).R() == pytest.approx( + np.sqrt( + getattr( + vector.obj(**dict(zip(["rho", "z", "phi"], constructor))), coordinates + )().rho2 + ) + ) + + +# Run a test that compares ROOT's 'Phi()' with vector's 'rho' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Phi(constructor, coordinates): + assert ROOT.Math.RhoZPhiVector(*constructor).Phi() == pytest.approx( + getattr( + vector.obj(**dict(zip(["rho", "z", "phi"], constructor))), coordinates + )().phi + ) + + +# Run a test that compares ROOT's 'RotateX()' with vector's 'rotateX' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_RotateX(constructor, angle, coordinates): + ref_vec = ROOT.Math.RotationX(angle) * ROOT.Math.RhoZPhiVector(*constructor) + vec = getattr( + vector.obj(**dict(zip(["rho", "z", "phi"], constructor))), coordinates + )() + res_vec = vec.rotateX(angle) + assert ref_vec.X() == pytest.approx(res_vec.x) + assert ref_vec.Y() == pytest.approx(res_vec.y) + assert ref_vec.Z() == pytest.approx(res_vec.z) + + +# Run a test that compares ROOT's 'RotateY()' with vector's 'rotateY' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_RotateY(constructor, angle, coordinates): + ref_vec = ROOT.Math.RotationY(angle) * ROOT.Math.RhoZPhiVector(*constructor) + vec = getattr( + vector.obj(**dict(zip(["rho", "z", "phi"], constructor))), coordinates + )() + res_vec = vec.rotateY(angle) + assert ref_vec.X() == pytest.approx(res_vec.x) + assert ref_vec.Y() == pytest.approx(res_vec.y) + assert ref_vec.Z() == pytest.approx(res_vec.z) + + +# Run a test that compares ROOT's 'RotateZ()' with vector's 'rotateZ' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_RotateZ(constructor, angle, coordinates): + ref_vec = ROOT.Math.RotationZ(angle) * ROOT.Math.RhoZPhiVector(*constructor) + vec = getattr( + vector.obj(**dict(zip(["rho", "z", "phi"], constructor))), coordinates + )() + res_vec = vec.rotateZ(angle) + assert ref_vec.X() == pytest.approx(res_vec.x) + assert ref_vec.Y() == pytest.approx(res_vec.y) + assert ref_vec.Z() == pytest.approx(res_vec.z) + + +# Run a test that compares ROOT's 'Unit()' with vector's 'unit' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Unit(constructor, coordinates): + ref_vec = ROOT.Math.RhoZPhiVector(*constructor).Unit() + vec = getattr( + vector.obj(**dict(zip(["rho", "z", "phi"], constructor))), coordinates + )() + res_vec = vec.unit + assert ref_vec.X() == pytest.approx(res_vec().x) + assert ref_vec.Y() == pytest.approx(res_vec().y) + assert ref_vec.Z() == pytest.approx(res_vec().z) + + +# Run a test that compares ROOT's 'X()' and 'Y()' with vector's 'x' and 'y' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_X_and_Y(constructor, coordinates): + vec = getattr( + vector.obj(**dict(zip(["rho", "z", "phi"], constructor))), coordinates + )() + assert ROOT.Math.RhoZPhiVector(*constructor).X() == pytest.approx( + vec.x + ) and ROOT.Math.RhoZPhiVector(*constructor).Y() == pytest.approx(vec.y) + + +# Run a test that compares ROOT's '__add__' with vector's 'add' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_add(constructor, coordinates): + ref_vec = ROOT.Math.RhoZPhiVector(*constructor).__add__( + ROOT.Math.RhoZPhiVector(*constructor) + ) + vec = getattr( + vector.obj(**dict(zip(["rho", "z", "phi"], constructor))), coordinates + )().add( + getattr( + vector.obj(**dict(zip(["rho", "z", "phi"], constructor))), coordinates + )() + ) + assert ref_vec.X() == pytest.approx(vec.x) + assert ref_vec.Y() == pytest.approx(vec.y) + assert ref_vec.Z() == pytest.approx(vec.z) + + +# Run a test that compares ROOT's '__sub__' with vector's 'subtract' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_sub(constructor, coordinates): + ref_vec = ROOT.Math.RhoZPhiVector(*constructor).__sub__( + ROOT.Math.RhoZPhiVector(*constructor) + ) + vec1 = getattr( + vector.obj(**dict(zip(["rho", "z", "phi"], constructor))), coordinates + )() + vec2 = getattr( + vector.obj(**dict(zip(["rho", "z", "phi"], constructor))), coordinates + )() + res_vec = vec1.subtract(vec2) + assert ref_vec.X() == pytest.approx(res_vec.x) + assert ref_vec.Y() == pytest.approx(res_vec.y) + assert ref_vec.Z() == pytest.approx(res_vec.z) + + +# Run a test that compares ROOT's '__neg__' with vector's '__neg__' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_neg(constructor, coordinates): + ref_vec = ROOT.Math.RhoZPhiVector(*constructor).__neg__() + vec = getattr( + vector.obj(**dict(zip(["rho", "z", "phi"], constructor))), coordinates + )().__neg__ + assert ref_vec.X() == pytest.approx(vec().x) + assert ref_vec.Y() == pytest.approx(vec().y) + assert ref_vec.Z() == pytest.approx(vec().z) + + +# Run a test that compares ROOT's '__mul__' with vector's 'mul' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_mul(constructor, scalar, coordinates): + ref_vec = ROOT.Math.RhoZPhiVector(*constructor).__mul__(scalar) + vec = getattr( + vector.obj(**dict(zip(["rho", "z", "phi"], constructor))), coordinates + )().__mul__(scalar) + assert ref_vec.X() == pytest.approx(vec.x) + assert ref_vec.Y() == pytest.approx(vec.y) + assert ref_vec.Z() == pytest.approx(vec.z) + + +# Run a test that compares ROOT's '__truediv__' with vector's '__truediv__' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_truediv(constructor, scalar, coordinates): + ref_vec = ROOT.Math.RhoZPhiVector(*constructor).__truediv__(scalar) + vec = getattr( + vector.obj(**dict(zip(["rho", "z", "phi"], constructor))), coordinates + )().__truediv__(scalar) + assert ref_vec.X() == pytest.approx(vec.x) + assert ref_vec.Y() == pytest.approx(vec.y) + assert ref_vec.Z() == pytest.approx(vec.z) + + +# Run a test that compares ROOT's '__eq__' with vector's 'isclose' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_eq(constructor, coordinates): + ref_vec = ROOT.Math.RhoZPhiVector(*constructor).__eq__( + ROOT.Math.RhoZPhiVector(*constructor) + ) + vec = getattr( + vector.obj(**dict(zip(["rho", "z", "phi"], constructor))), coordinates + )().isclose( + getattr( + vector.obj(**dict(zip(["rho", "z", "phi"], constructor))), coordinates + )() + ) + assert ref_vec == vec diff --git a/tests/root/test_XYVector.py b/tests/root/test_XYVector.py new file mode 100644 index 00000000..4a75f3cb --- /dev/null +++ b/tests/root/test_XYVector.py @@ -0,0 +1,213 @@ +# Copyright (c) 2019-2021, Jonas Eschle, Jim Pivarski, Eduardo Rodrigues, and Henry Schreiner. +# +# Distributed under the 3-clause BSD license, see accompanying file LICENSE +# or https://github.com/scikit-hep/vector for details. + +import numpy as np +import pytest + +import vector + +# If ROOT is not available, skip these tests. +ROOT = pytest.importorskip("ROOT") + +# ROOT.Math.XYVector constructor arguments to get all the weird cases. +constructor = [ + (0, 0), + (0, 10), + (0, -10), + (1, 0), + (1, 10), + (1, -10), + (1.0, 2.5), + (1, 2.5), + (1, -2.5), +] + +# Coordinate conversion methods to apply to the VectorObject2D. +coordinate_list = [ + "to_xy", + "to_rhophi", +] + + +@pytest.fixture(scope="module", params=coordinate_list) +def coordinates(request): + return request.param + + +angle_list = [ + 0, + 0.0, + 0.7853981633974483, + -0.7853981633974483, + 1.5707963267948966, + -1.5707963267948966, + 3.141592653589793, + -3.141592653589793, + 6.283185307179586, + -6.283185307179586, +] + + +@pytest.fixture(scope="module", params=angle_list) +def angle(request): + return request.param + + +scalar_list = [ + 0, + -1, + 1.0, + 100000.0000, + -100000.0000, +] + + +@pytest.fixture(scope="module", params=scalar_list) +def scalar(request): + return request.param + + +# Run a test that compares ROOT's 'Dot()' with vector's 'dot' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Dot(constructor, coordinates): + assert ROOT.Math.XYVector(*constructor).Dot( + ROOT.Math.XYVector(*constructor) + ) == pytest.approx( + getattr(vector.obj(**dict(zip(["x", "y"], constructor))), coordinates)().dot( + getattr(vector.obj(**dict(zip(["x", "y"], constructor))), coordinates)() + ), + 1.0e-6, + 1.0e-6, + ) + + +# Run a test that compares ROOT's 'Mag2()' with vector's 'rho2' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Mag2(constructor, coordinates): + assert ROOT.Math.XYVector(*constructor).Mag2() == pytest.approx( + getattr(vector.obj(**dict(zip(["x", "y"], constructor))), coordinates)().rho2 + ) + + +# Run a test that compares ROOT's 'R()' with vector's 'rho' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_R(constructor, coordinates): + assert ROOT.Math.XYVector(*constructor).R() == pytest.approx( + np.sqrt( + getattr( + vector.obj(**dict(zip(["x", "y"], constructor))), coordinates + )().rho2 + ) + ) + + +# Run a test that compares ROOT's 'Phi()' with vector's 'rho' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Phi(constructor, coordinates): + assert ROOT.Math.XYVector(*constructor).Phi() == pytest.approx( + getattr(vector.obj(**dict(zip(["x", "y"], constructor))), coordinates)().phi + ) + + +# Run a test that compares ROOT's 'Rotate()' with vector's 'rotateZ' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Rotate(constructor, angle, coordinates): + ref_vec = ROOT.Math.XYVector(*constructor) + ref_vec.Rotate(angle) + vec = getattr(vector.obj(**dict(zip(["x", "y"], constructor))), coordinates)() + res_vec = vec.rotateZ(angle) + assert ref_vec.X() == pytest.approx(res_vec.x) + assert ref_vec.Y() == pytest.approx(res_vec.y) + + +# Run a test that compares ROOT's 'Unit()' with vector's 'unit' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Unit(constructor, coordinates): + # FIXME: if x == 0 and y == 0 + # assert 0.0 == 1.0 ± 1.0e-06 + if constructor[0] != 0 and constructor[1] != 0: + ref_vec = ROOT.Math.XYVector(*constructor).Unit() + vec = getattr(vector.obj(**dict(zip(["x", "y"], constructor))), coordinates)() + res_vec = vec.unit + assert ref_vec.X() == pytest.approx(res_vec().x) + assert ref_vec.Y() == pytest.approx(res_vec().y) + + +# Run a test that compares ROOT's 'X()' and 'Y()' with vector's 'x' and 'y' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_X_and_Y(constructor, coordinates): + vec = getattr(vector.obj(**dict(zip(["x", "y"], constructor))), coordinates)() + assert ROOT.Math.XYVector(*constructor).X() == pytest.approx( + vec.x + ) and ROOT.Math.XYVector(*constructor).Y() == pytest.approx(vec.y) + + +# Run a test that compares ROOT's '__add__' with vector's 'add' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_add(constructor, coordinates): + ref_vec = ROOT.Math.XYVector(*constructor).__add__(ROOT.Math.XYVector(*constructor)) + vec = getattr(vector.obj(**dict(zip(["x", "y"], constructor))), coordinates)().add( + getattr(vector.obj(**dict(zip(["x", "y"], constructor))), coordinates)() + ) + assert ref_vec.X() == pytest.approx(vec.x) + assert ref_vec.Y() == pytest.approx(vec.y) + + +# Run a test that compares ROOT's '__sub__' with vector's 'subtract' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_sub(constructor, coordinates): + ref_vec = ROOT.Math.XYVector(*constructor).__sub__(ROOT.Math.XYVector(*constructor)) + vec1 = getattr(vector.obj(**dict(zip(["x", "y"], constructor))), coordinates)() + vec2 = getattr(vector.obj(**dict(zip(["x", "y"], constructor))), coordinates)() + res_vec = vec1.subtract(vec2) + assert ref_vec.X() == pytest.approx(res_vec.x) + assert ref_vec.Y() == pytest.approx(res_vec.y) + + +# Run a test that compares ROOT's '__neg__' with vector's '__neg__' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_neg(constructor, coordinates): + ref_vec = ROOT.Math.XYVector(*constructor).__neg__() + vec = getattr( + vector.obj(**dict(zip(["x", "y"], constructor))), coordinates + )().__neg__ + assert ref_vec.X() == pytest.approx(vec().x) + assert ref_vec.Y() == pytest.approx(vec().y) + + +# Run a test that compares ROOT's '__mul__' with vector's 'mul' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_mul(constructor, scalar, coordinates): + ref_vec = ROOT.Math.XYVector(*constructor).__mul__(scalar) + vec = getattr( + vector.obj(**dict(zip(["x", "y"], constructor))), coordinates + )().__mul__(scalar) + assert ref_vec.X() == pytest.approx( + vec.x, 1.0e-6, 1.0e-6 + ) and ref_vec.Y() == pytest.approx(vec.y, 1.0e-6, 1.0e-6) + + +# Run a test that compares ROOT's '__truediv__' with vector's '__truediv__' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_truediv(constructor, scalar, coordinates): + if scalar != 0: + ref_vec = ROOT.Math.XYVector(*constructor).__truediv__(scalar) + vec = getattr( + vector.obj(**dict(zip(["x", "y"], constructor))), coordinates + )().__truediv__(scalar) + assert ref_vec.X() == pytest.approx(vec.x) + assert ref_vec.Y() == pytest.approx(vec.y) + + +# Run a test that compares ROOT's '__eq__' with vector's 'isclose' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_eq(constructor, coordinates): + ref_vec = ROOT.Math.XYVector(*constructor).__eq__(ROOT.Math.XYVector(*constructor)) + vec = getattr( + vector.obj(**dict(zip(["x", "y"], constructor))), coordinates + )().isclose( + getattr(vector.obj(**dict(zip(["x", "y"], constructor))), coordinates)() + ) + assert ref_vec == vec diff --git a/tests/root/test_XYZVector.py b/tests/root/test_XYZVector.py new file mode 100644 index 00000000..44750dff --- /dev/null +++ b/tests/root/test_XYZVector.py @@ -0,0 +1,338 @@ +# Copyright (c) 2019-2021, Jonas Eschle, Jim Pivarski, Eduardo Rodrigues, and Henry Schreiner. +# +# Distributed under the 3-clause BSD license, see accompanying file LICENSE +# or https://github.com/scikit-hep/vector for details. + +import pytest + +import vector + +# If ROOT is not available, skip these tests. +ROOT = pytest.importorskip("ROOT") + +# ROOT.Math.XYZVector constructor arguments to get all the weird cases. +constructor = [ + (0, 0, 0), + (0, 10, 0), + (0, -10, 0), + (1, 0, 0), + (1, 10, 0), + (1, -10, 0), + (1.0, 2.5, 2.0), + (1, 2.5, 2.0), + (1, -2.5, 2.0), +] + +# Coordinate conversion methods to apply to the VectorObject2D. +coordinate_list = [ + "to_xyz", + "to_rhophieta", + "to_rhophitheta", + "to_rhophiz", + "to_xyeta", + "to_xytheta", +] + + +@pytest.fixture(scope="module", params=coordinate_list) +def coordinates(request): + return request.param + + +angle_list = [ + 0, + 0.0, + 0.7853981633974483, + -0.7853981633974483, + 1.5707963267948966, + -1.5707963267948966, + 3.141592653589793, + -3.141592653589793, + 6.283185307179586, + -6.283185307179586, +] + + +@pytest.fixture(scope="module", params=angle_list) +def angle(request): + return request.param + + +scalar_list = [ + 0, + -1, + 1.0, + 100000.0000, + -100000.0000, +] + + +@pytest.fixture(scope="module", params=scalar_list) +def scalar(request): + return request.param + + +# Run a test that compares ROOT's 'Dot()' with vector's 'dot' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Dot(constructor, coordinates): + assert ROOT.Math.XYZVector(*constructor).Dot( + ROOT.Math.XYZVector(*constructor) + ) == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z"], constructor))), coordinates + )().dot( + getattr( + vector.obj(**dict(zip(["x", "y", "z"], constructor))), coordinates + )() + ) + ) + + +# Run a test that compares ROOT's 'Cross()' with vector's 'cross' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Cross(constructor, coordinates): + ref_vec = ROOT.Math.XYZVector(*constructor).Cross(ROOT.Math.XYZVector(*constructor)) + vec = getattr( + vector.obj(**dict(zip(["x", "y", "z"], constructor))), coordinates + )().cross( + getattr(vector.obj(**dict(zip(["x", "y", "z"], constructor))), coordinates)() + ) + assert ( + ref_vec.X() + == pytest.approx( + vec.x, + 1.0e-6, + 1.0e-6, + ) + and ref_vec.Y() + == pytest.approx( + vec.y, + 1.0e-6, + 1.0e-6, + ) + and ref_vec.Z() + == pytest.approx( + vec.z, + 1.0e-6, + 1.0e-6, + ) + ) + + +# Run a test that compares ROOT's 'Mag2()' with vector's 'mag2' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Mag2(constructor, coordinates): + ref_vec = ROOT.Math.XYZVector(*constructor) + vec = getattr(vector.obj(**dict(zip(["x", "y", "z"], constructor))), coordinates)() + assert ( + pytest.approx(vec.x) == ref_vec.X() + and pytest.approx(vec.y) == ref_vec.Y() + and pytest.approx(vec.z) == ref_vec.Z() + ) + + assert ref_vec.Mag2() == pytest.approx(vec.mag2, 1.0e-6, 1.0e-6) + + +# Run a test that compares ROOT's 'Mag()' with vector's 'mag' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Mag(constructor, coordinates): + assert ROOT.Math.XYZVector(*constructor).R() == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z"], constructor))), coordinates + )().mag, + 1.0e-6, + 1.0e-6, + ) + + +# Run a test that compares ROOT's 'Perp2()' with vector's 'rho2' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Perp2(constructor, coordinates): + assert ROOT.Math.XYZVector(*constructor).Perp2() == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z"], constructor))), coordinates + )().rho2, + 1.0e-6, + 1.0e-6, + ) + + +# Run a test that compares ROOT's 'Perp()' with vector's 'rho' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Perp(constructor, coordinates): + assert ROOT.Math.sqrt(ROOT.Math.XYZVector(*constructor).Perp2()) == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z"], constructor))), coordinates + )().rho, + 1.0e-6, + 1.0e-6, + ) + + +# Run a test that compares ROOT's 'Phi()' with vector's 'rho' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Phi(constructor, coordinates): + assert ROOT.Math.XYZVector(*constructor).Phi() == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z"], constructor))), coordinates + )().phi + ) + + +# Run a test that compares ROOT's 'Eta()' with vector's 'eta' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Eta(constructor, coordinates): + assert ROOT.Math.XYZVector(*constructor).Eta() == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z"], constructor))), coordinates + )().eta, + 1.0e-6, + 1.0e-6, + ) + + +# Run a test that compares ROOT's 'Theta()' with vector's 'theta' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Theta(constructor, coordinates): + assert ROOT.Math.XYZVector(*constructor).Theta() == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z"], constructor))), coordinates + )().theta + ) + + +# Run a test that compares ROOT's 'RotateX()' with vector's 'rotateX' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_RotateX(constructor, angle, coordinates): + ref_vec = ROOT.Math.RotationX(angle) * ROOT.Math.XYZVector(*constructor) + vec = getattr(vector.obj(**dict(zip(["x", "y", "z"], constructor))), coordinates)() + res_vec = vec.rotateX(angle) + assert ref_vec.X() == pytest.approx(res_vec.x) + assert ref_vec.Y() == pytest.approx(res_vec.y) + assert ref_vec.Z() == pytest.approx(res_vec.z) + + +# Run a test that compares ROOT's 'RotateY()' with vector's 'rotateY' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_RotateY(constructor, angle, coordinates): + ref_vec = ROOT.Math.RotationY(angle) * ROOT.Math.XYZVector(*constructor) + vec = getattr(vector.obj(**dict(zip(["x", "y", "z"], constructor))), coordinates)() + res_vec = vec.rotateY(angle) + assert ref_vec.X() == pytest.approx(res_vec.x) + assert ref_vec.Y() == pytest.approx(res_vec.y) + assert ref_vec.Z() == pytest.approx(res_vec.z) + + +# Run a test that compares ROOT's 'RotateZ()' with vector's 'rotateZ' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_RotateZ(constructor, angle, coordinates): + ref_vec = ROOT.Math.RotationZ(angle) * ROOT.Math.XYZVector(*constructor) + vec = getattr(vector.obj(**dict(zip(["x", "y", "z"], constructor))), coordinates)() + res_vec = vec.rotateZ(angle) + assert ref_vec.X() == pytest.approx(res_vec.x) + assert ref_vec.Y() == pytest.approx(res_vec.y) + assert ref_vec.Z() == pytest.approx(res_vec.z) + + +# Run a test that compares ROOT's 'Unit()' with vector's 'unit' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_Unit(constructor, coordinates): + ref_vec = ROOT.Math.XYZVector(*constructor).Unit() + vec = getattr(vector.obj(**dict(zip(["x", "y", "z"], constructor))), coordinates)() + res_vec = vec.unit + assert ref_vec.X() == pytest.approx(res_vec().x) + assert ref_vec.Y() == pytest.approx(res_vec().y) + assert ref_vec.Z() == pytest.approx(res_vec().z) + + +# Run a test that compares ROOT's 'X()' and 'Y()' with vector's 'x' and 'y' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_X_Y_Z(constructor, coordinates): + vec = getattr(vector.obj(**dict(zip(["x", "y", "z"], constructor))), coordinates)() + assert ( + ROOT.Math.XYZVector(*constructor).X() == pytest.approx(vec.x) + and ROOT.Math.XYZVector(*constructor).Y() == pytest.approx(vec.y) + and ROOT.Math.XYZVector(*constructor).Z() == pytest.approx(vec.z) + ) + + +# Run a test that compares ROOT's '__add__' with vector's 'add' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_add(constructor, coordinates): + ref_vec = ROOT.Math.XYZVector(*constructor).__add__( + ROOT.Math.XYZVector(*constructor) + ) + vec = getattr( + vector.obj(**dict(zip(["x", "y", "z"], constructor))), coordinates + )().add( + getattr(vector.obj(**dict(zip(["x", "y", "z"], constructor))), coordinates)() + ) + assert ref_vec.X() == pytest.approx(vec.x) + assert ref_vec.Y() == pytest.approx(vec.y) + assert ref_vec.Z() == pytest.approx(vec.z) + + +# Run a test that compares ROOT's '__sub__' with vector's 'subtract' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_sub(constructor, coordinates): + ref_vec = ROOT.Math.XYZVector(*constructor).__sub__( + ROOT.Math.XYZVector(*constructor) + ) + vec1 = getattr(vector.obj(**dict(zip(["x", "y", "z"], constructor))), coordinates)() + vec2 = getattr(vector.obj(**dict(zip(["x", "y", "z"], constructor))), coordinates)() + res_vec = vec1.subtract(vec2) + assert ref_vec.X() == pytest.approx(res_vec.x) + assert ref_vec.Y() == pytest.approx(res_vec.y) + assert ref_vec.Z() == pytest.approx(res_vec.z) + + +# Run a test that compares ROOT's '__neg__' with vector's '__neg__' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_neg(constructor, coordinates): + ref_vec = ROOT.Math.XYZVector(*constructor).__neg__() + vec = getattr( + vector.obj(**dict(zip(["x", "y", "z"], constructor))), coordinates + )().__neg__ + assert ref_vec.X() == pytest.approx(vec().x) + assert ref_vec.Y() == pytest.approx(vec().y) + assert ref_vec.Z() == pytest.approx(vec().z) + + +# Run a test that compares ROOT's '__mul__' with vector's 'mul' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_mul(constructor, scalar, coordinates): + ref_vec = ROOT.Math.XYZVector(*constructor).__mul__(scalar) + vec = getattr( + vector.obj(**dict(zip(["x", "y", "z"], constructor))), coordinates + )().__mul__(scalar) + assert ref_vec.X() == pytest.approx(vec.x, 1.0e-6, 1.0e-6) + assert ref_vec.Y() == pytest.approx(vec.y, 1.0e-6, 1.0e-6) + assert ref_vec.Z() == pytest.approx(vec.z, 1.0e-6, 1.0e-6) + + +# Run a test that compares ROOT's '__truediv__' with vector's '__truediv__' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_truediv(constructor, scalar, coordinates): + # FIXME + if scalar != 0: + ref_vec = ROOT.Math.XYZVector(*constructor).__truediv__(scalar) + vec = getattr( + vector.obj(**dict(zip(["x", "y", "z"], constructor))), coordinates + )().__truediv__(scalar) + assert ref_vec.X() == pytest.approx(vec.x) + assert ref_vec.Y() == pytest.approx(vec.y) + assert ref_vec.Z() == pytest.approx(vec.z) + + +# Run a test that compares ROOT's '__eq__' with vector's 'isclose' for all cases. +@pytest.mark.parametrize("constructor", constructor) +def test_eq(constructor, coordinates): + ref_vec = ROOT.Math.XYZVector(*constructor).__eq__( + ROOT.Math.XYZVector(*constructor) + ) + vec = getattr( + vector.obj(**dict(zip(["x", "y", "z"], constructor))), coordinates + )().isclose( + getattr(vector.obj(**dict(zip(["x", "y", "z"], constructor))), coordinates)() + ) + assert ref_vec == vec diff --git a/tests/root/test_vector.py b/tests/root/test_vector.py new file mode 100644 index 00000000..86d8bc9b --- /dev/null +++ b/tests/root/test_vector.py @@ -0,0 +1,111 @@ +# This test code was written by the `hypothesis.extra.ghostwriter` module +# and is provided under the Creative Commons Zero public domain dedication. + +import pytest + +import vector + +# If ROOT is not available, skip these tests. +ROOT = pytest.importorskip("ROOT") + +# Coordinate conversion methods to apply to the VectorObject4D. +coordinate_list = [ + "to_xyzt", + "to_xythetat", + "to_xyetat", + "to_rhophizt", + "to_rhophithetat", + "to_rhophietat", + "to_xyztau", + "to_xythetatau", + "to_xyetatau", + "to_rhophiztau", + "to_rhophithetatau", + "to_rhophietatau", +] + + +@pytest.fixture(scope="module", params=coordinate_list) +def coordinates(request): + return request.param + + +constructor = [ + (0, 0, 0, 0), + (0, 0, 0, 10), + (0, 0, 0, -10), + (1, 2, 3, 0), + (1, 2, 3, 10), + (1, 2, 3, -10), + (1, 2, 3, 2.5), + (1, 2, 3, -2.5), +] + + +@pytest.mark.parametrize("constructor", constructor) +def test_M2(constructor, coordinates): + assert ROOT.Math.PxPyPzEVector(*constructor).M2() == pytest.approx( + getattr( + vector.obj(**dict(zip(["x", "y", "z", "t"], constructor))), coordinates + )().tau2 + ) + + +# @given( +# azimuthal=st.tuples(st.floats(), st.floats()) +# | st.tuples(st.integers(), st.integers()) +# ) +# def test_fuzz_MomentumObject2D(azimuthal): +# vector.MomentumObject2D(azimuthal=azimuthal) +# +# +# @given( +# azimuthal=st.tuples(st.floats(), st.floats()) +# | st.tuples(st.integers(), st.integers()), +# longitudinal=st.floats() | st.integers(), +# ) +# def test_fuzz_MomentumObject3D(azimuthal, longitudinal): +# vector.MomentumObject3D(azimuthal=azimuthal, longitudinal=longitudinal) +# +# +# @given( +# azimuthal=st.tuples(st.floats(), st.floats()) +# | st.tuples(st.integers(), st.integers()), +# longitudinal=st.floats() | st.integers(), +# temporal=st.floats() | st.integers(), +# ) +# def test_fuzz_MomentumObject4D(azimuthal, longitudinal, temporal): +# vector.MomentumObject4D( +# azimuthal=azimuthal, longitudinal=longitudinal, temporal=temporal +# ) +# +# +# @given( +# azimuthal=st.tuples(st.floats(), st.floats()) +# | st.tuples(st.integers(), st.integers()) +# ) +# def test_fuzz_VectorObject2D(azimuthal): +# vector.VectorObject2D(azimuthal=azimuthal) +# +# +# @given( +# azimuthal=st.tuples(st.floats(), st.floats()) +# | st.tuples(st.integers(), st.integers()), +# longitudinal=st.floats() | st.integers(), +# ) +# def test_fuzz_VectorObject3D(azimuthal, longitudinal): +# vector.VectorObject3D(azimuthal=azimuthal, longitudinal=longitudinal) +# +# +# @given( +# azimuthal=st.tuples(st.floats(), st.floats()) +# | st.tuples(st.integers(), st.integers()), +# longitudinal=st.floats() | st.integers(), +# temporal=st.floats() | st.integers(), +# ) +# def test_fuzz_VectorObject4D(azimuthal, longitudinal, temporal): +# vector.VectorObject4D( +# azimuthal=azimuthal, longitudinal=longitudinal, temporal=temporal +# ) +# assert (vector.obj(**dict(zip(["x", "y", "z", "t"], azimuthal[0], azimuthal[1], longitudinal, temporal)))).tau == 0 +# pytest.approx(ROOT.Math.PxPyPzEVector(azimuthal[0], azimuthal[1], longitudinal, temporal).M())