|
10 | 10 |
|
11 | 11 | import itertools |
12 | 12 | import re |
| 13 | +from unittest.mock import patch |
13 | 14 |
|
14 | 15 | import numpy as np |
15 | 16 | import pytest |
|
22 | 23 | create_ellipsoid, |
23 | 24 | ) |
24 | 25 |
|
| 26 | +try: |
| 27 | + import pyvista |
| 28 | +except ImportError: |
| 29 | + pyvista = None |
| 30 | + |
25 | 31 |
|
26 | 32 | class TestProlateEllipsoid: |
27 | 33 | """Test the ProlateEllipsoid class.""" |
@@ -544,3 +550,48 @@ def test_physical_properties(self, a, b, c, physical_property): |
544 | 550 | center = (1.0, 2.0, 3.0) |
545 | 551 | ellipsoid = create_ellipsoid(a, b, c, center=center, **kwargs) |
546 | 552 | np.testing.assert_allclose(getattr(ellipsoid, physical_property), value) |
| 553 | + |
| 554 | + |
| 555 | +@pytest.mark.skipif(pyvista is None, reason="requires pyvista") |
| 556 | +class TestToPyvista: |
| 557 | + """Test exporting ellipsoids to PyVista objects.""" |
| 558 | + |
| 559 | + @pytest.fixture(params=["oblate", "prolate", "triaxial", "sphere"]) |
| 560 | + def ellipsoid(self, request): |
| 561 | + a, b, c = 3.0, 2.0, 1.0 |
| 562 | + yaw, pitch, roll = 73.0, 14.0, -35.0 |
| 563 | + center = (43.0, -72.0, 105) |
| 564 | + match request.param: |
| 565 | + case "oblate": |
| 566 | + ellipsoid = OblateEllipsoid(b, a, yaw, pitch, center=center) |
| 567 | + case "prolate": |
| 568 | + ellipsoid = ProlateEllipsoid(a, b, yaw, pitch, center=center) |
| 569 | + case "triaxial": |
| 570 | + ellipsoid = TriaxialEllipsoid(a, b, c, yaw, pitch, roll, center=center) |
| 571 | + case "sphere": |
| 572 | + ellipsoid = Sphere(a, center=center) |
| 573 | + case _: |
| 574 | + raise ValueError() |
| 575 | + return ellipsoid |
| 576 | + |
| 577 | + @patch("harmonica._forward.ellipsoids.ellipsoids.pyvista", None) |
| 578 | + def test_pyvista_missing_error(self, ellipsoid): |
| 579 | + """ |
| 580 | + Check if error is raised when pyvista is not installed. |
| 581 | + """ |
| 582 | + with pytest.raises(ImportError): |
| 583 | + ellipsoid.to_pyvista() |
| 584 | + |
| 585 | + def test_pyvista_object(self, ellipsoid): |
| 586 | + """ |
| 587 | + Check if method works as expected. |
| 588 | + """ |
| 589 | + ellipsoid_pv = ellipsoid.to_pyvista() |
| 590 | + assert isinstance(ellipsoid_pv, pyvista.PolyData) |
| 591 | + # rtol needed since the parametric ellipsoid is not the exact surface. |
| 592 | + np.testing.assert_allclose(ellipsoid_pv.center, ellipsoid.center, rtol=1e-4) |
| 593 | + np.testing.assert_allclose( |
| 594 | + ellipsoid_pv.volume, |
| 595 | + 4 / 3 * np.pi * ellipsoid.a * ellipsoid.b * ellipsoid.c, |
| 596 | + rtol=1e-3, |
| 597 | + ) |
0 commit comments