From b72a99623d156a848c1b0371d2f5d9db7ce3450d Mon Sep 17 00:00:00 2001 From: domfournier Date: Wed, 29 Jul 2026 12:25:57 -0700 Subject: [PATCH 1/5] [GEOPY-3009] Move functions. Refactor test_get_block_model in sub-tests --- tests/conftest.py | 40 +++++++++++ tests/run_tests/block_model_test.py | 86 +++++++++++------------ tests/run_tests/grid_model_merger_test.py | 33 +-------- 3 files changed, 82 insertions(+), 77 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 6147833..9428038 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -6,10 +6,14 @@ # grid-apps is distributed under the terms and conditions of the MIT License ' # (see LICENSE file at the root of this source code package). ' # ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' +from __future__ import annotations import numpy as np import pytest from discretize.utils import mesh_builder_xyz +from geoh5py.objects import BlockModel, Grid2D + +from grid_apps.block_models.driver import Driver as BlockModelDriver @pytest.fixture @@ -62,3 +66,39 @@ def setup_test_octree(diagonal_balance=False): treemesh, params_dict, ) + + +def setup_block_model( + workspace, + *, + top=200, + depth_core=300.0, + pads=(100, 150, 200, 300, 0, 0), + cell_size=(50, 50, 50), + expansion_factor=1.1, +) -> BlockModel: + # padding in the W/E/N/S directions should make create locs at least as + # far as the core hull plus the padding distances + height = 300 + width = 1000 + n = 3 + x_grid, y_grid = np.meshgrid(np.arange(0, width, n), np.arange(0, height, n)) + z_grid = np.around((top / 2) * np.sin(x_grid) + (top / 2), -1) + locs = np.c_[x_grid.ravel(), y_grid.ravel(), z_grid.ravel()] + + mesh = BlockModelDriver.get_block_model( + workspace, locs, cell_size, depth_core, pads, expansion_factor, name="test" + ) + return mesh + + +def setup_grid2d_model(workspace) -> Grid2D: + mesh = Grid2D.create( + workspace, + origin=[0, 0, 0], + u_cell_size=50.0, + v_cell_size=50.0, + u_count=10, + v_count=15, + ) + return mesh diff --git a/tests/run_tests/block_model_test.py b/tests/run_tests/block_model_test.py index 9c53949..e1208e7 100644 --- a/tests/run_tests/block_model_test.py +++ b/tests/run_tests/block_model_test.py @@ -14,77 +14,73 @@ import numpy as np from geoh5py.workspace import Workspace -from grid_apps.block_models.driver import Driver as BlockModelDriver +from tests.conftest import setup_block_model def test_get_block_model(tmp_path: Path): # pylint: disable=too-many-locals # padding in the W/E/N/S directions should make create locs at least as # far as the core hull plus the padding distances - top = 500 - depth_core = 300.0 - height = 300 - width = 1000 - n = 100 - x_grid, y_grid = np.meshgrid(np.arange(0, width, n), np.arange(0, height, n)) - z_grid = np.around((top / 2) * np.sin(x_grid) + (top / 2), -1) - locs = np.c_[x_grid.ravel(), y_grid.ravel(), z_grid.ravel()] pads = [100, 150, 200, 300, 0, 0] - ws = Workspace(tmp_path / "block_model.geoh5") - obj = BlockModelDriver.get_block_model( - ws, locs, [50, 50, 50], depth_core, pads, 1.1, name="test" - ) + top = 500 + with Workspace(tmp_path / f"{__name__}.geoh5") as ws: + obj = setup_block_model( + ws, + top=top, + depth_core=300.0, + pads=pads, + ) assert (obj.origin["z"] + obj.z_cell_delimiters).max() == top assert obj.origin["x"] < -pads[0] assert obj.origin["y"] < -pads[2] - assert obj.u_cell_delimiters.max() >= locs[:, 0].max() + pads[1] + pads[0] # type: ignore - assert obj.v_cell_delimiters.max() >= locs[:, 1].max() + pads[3] + pads[2] # type: ignore + assert obj.u_cell_delimiters.max() >= 1000 + pads[1] + pads[0] + assert obj.v_cell_delimiters.max() >= 300 + pads[3] + pads[2] + +def test_padding(tmp_path: Path): # padding in the down direction should create locs at least as deep as the top # minus the sum of depth_core, h[2], and bottom padding. top = 500 - depth_core = 300.0 - height = 300 - width = 1000 - n = 100 - - x_grid, y_grid = np.meshgrid(np.arange(0, width, n), np.arange(0, height, n)) - z_grid = np.around((top / 2) * np.sin(x_grid) + (top / 2), -1) - locs = np.c_[x_grid.ravel(), y_grid.ravel(), z_grid.ravel()] pads = [0, 0, 0, 0, 100, 0] # padding on the bottom - h = [50, 50, 50] - - obj = BlockModelDriver.get_block_model( - ws, locs, h, depth_core, pads, 1.1, name="test2" - ) + depth_core = 300.0 + cell_size = (50, 50, 50) + with Workspace(tmp_path / f"{__name__}.geoh5") as ws: + obj = obj = setup_block_model( + ws, + top=top, + depth_core=depth_core, + pads=pads, + cell_size=cell_size, + ) - assert top - (depth_core + h[2] + pads[4]) >= np.min( + assert top - (depth_core + obj.z_cells[0] + pads[4]) >= np.min( obj.origin["z"] + obj.z_cell_delimiters ) + +def test_padding_up_to(tmp_path: Path): # padding in the up direction should shift the origin so that the core area # envelopes the locs (adjusted by depth_core). top = 500 + pads = [0, 0, 0, 0, 0, 100] # padding on the bottom depth_core = 300.0 - height = 300 - width = 1000 - n = 100 - expansion_rate = 1.1 - - x_grid, y_grid = np.meshgrid(np.arange(0, width, n), np.arange(0, height, n)) - z_grid = np.around((top / 2) * np.sin(x_grid) + (top / 2), -1) - locs = np.c_[x_grid.ravel(), y_grid.ravel(), z_grid.ravel()] - pads = [0, 0, 0, 0, 0, 100] # padding on the top - h = [50, 50, 50] - - obj = BlockModelDriver.get_block_model( - ws, locs, h, depth_core, pads, expansion_rate, name="test2" - ) + expansion_factor = 1.1 + cell_size = (50, 50, 50) + with Workspace(tmp_path / f"{__name__}.geoh5") as ws: + obj = obj = setup_block_model( + ws, + top=top, + depth_core=depth_core, + pads=pads, + expansion_factor=expansion_factor, + cell_size=cell_size, + ) assert obj.origin["z"] >= top + pads[-1] depth_delimiters = obj.origin["z"] + obj.z_cell_delimiters core_top_ind = np.argwhere(depth_delimiters == 500).flatten()[0] - assert np.abs(np.diff(depth_delimiters))[core_top_ind] == h[2] + assert np.abs(np.diff(depth_delimiters))[core_top_ind] == cell_size[2] assert np.isclose( - np.abs(np.diff(depth_delimiters))[core_top_ind - 1], h[2] * expansion_rate + np.abs(np.diff(depth_delimiters))[core_top_ind - 1], + cell_size[2] * expansion_factor, ) diff --git a/tests/run_tests/grid_model_merger_test.py b/tests/run_tests/grid_model_merger_test.py index 35db3b5..0b86ed6 100644 --- a/tests/run_tests/grid_model_merger_test.py +++ b/tests/run_tests/grid_model_merger_test.py @@ -17,42 +17,11 @@ from geoh5py.workspace import Workspace from pytest import mark -from grid_apps.block_models.driver import Driver as BlockModelDriver from grid_apps.grid_model_merger.driver import Driver from grid_apps.grid_model_merger.options import GridModelMergerOptions from grid_apps.octree_creation.driver import OctreeDriver from grid_apps.octree_creation.options import OctreeOptions - - -def setup_block_model(workspace) -> BlockModel: - # padding in the W/E/N/S directions should make create locs at least as - # far as the core hull plus the padding distances - top = 200 - depth_core = 300.0 - height = 300 - width = 1000 - n = 100 - - x_grid, y_grid = np.meshgrid(np.arange(0, width, n), np.arange(0, height, n)) - z_grid = np.around((top / 2) * np.sin(x_grid) + (top / 2), -1) - locs = np.c_[x_grid.ravel(), y_grid.ravel(), z_grid.ravel()] - pads = [100, 150, 200, 300, 0, 0] - mesh = BlockModelDriver.get_block_model( - workspace, locs, [50, 50, 50], depth_core, pads, 1.1, name="test" - ) - return mesh - - -def setup_grid2d_model(workspace) -> Grid2D: - mesh = Grid2D.create( - workspace, - origin=[0, 0, 0], - u_cell_size=50.0, - v_cell_size=50.0, - u_count=10, - v_count=15, - ) - return mesh +from tests.conftest import setup_block_model, setup_grid2d_model def setup_octree(workspace, locations, refinement, params_dict) -> Octree: From 0d921c2cbf0560d9d0a0f75d1f9238d49b06d6b9 Mon Sep 17 00:00:00 2001 From: domfournier Date: Wed, 29 Jul 2026 12:52:15 -0700 Subject: [PATCH 2/5] [GEOPY-3009] Adjust tests --- tests/conftest.py | 8 ++++---- tests/run_tests/block_model_test.py | 24 +++++++++++------------ tests/run_tests/grid_model_merger_test.py | 4 ++-- 3 files changed, 17 insertions(+), 19 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 9428038..a8dff74 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -11,7 +11,7 @@ import numpy as np import pytest from discretize.utils import mesh_builder_xyz -from geoh5py.objects import BlockModel, Grid2D +from geoh5py.objects import BlockModel, Grid2D, Points from grid_apps.block_models.driver import Driver as BlockModelDriver @@ -81,11 +81,11 @@ def setup_block_model( # far as the core hull plus the padding distances height = 300 width = 1000 - n = 3 - x_grid, y_grid = np.meshgrid(np.arange(0, width, n), np.arange(0, height, n)) + n = 11 + x_grid, y_grid = np.meshgrid(np.linspace(0, width, n), np.linspace(0, height, n)) z_grid = np.around((top / 2) * np.sin(x_grid) + (top / 2), -1) locs = np.c_[x_grid.ravel(), y_grid.ravel(), z_grid.ravel()] - + Points.create(workspace, vertices=locs) mesh = BlockModelDriver.get_block_model( workspace, locs, cell_size, depth_core, pads, expansion_factor, name="test" ) diff --git a/tests/run_tests/block_model_test.py b/tests/run_tests/block_model_test.py index e1208e7..368a0b7 100644 --- a/tests/run_tests/block_model_test.py +++ b/tests/run_tests/block_model_test.py @@ -12,6 +12,7 @@ from pathlib import Path import numpy as np +from geoh5py.objects import Points from geoh5py.workspace import Workspace from tests.conftest import setup_block_model @@ -24,17 +25,16 @@ def test_get_block_model(tmp_path: Path): # pylint: disable=too-many-locals pads = [100, 150, 200, 300, 0, 0] top = 500 with Workspace(tmp_path / f"{__name__}.geoh5") as ws: - obj = setup_block_model( + grid = setup_block_model( ws, top=top, depth_core=300.0, pads=pads, ) - assert (obj.origin["z"] + obj.z_cell_delimiters).max() == top - assert obj.origin["x"] < -pads[0] - assert obj.origin["y"] < -pads[2] - assert obj.u_cell_delimiters.max() >= 1000 + pads[1] + pads[0] - assert obj.v_cell_delimiters.max() >= 300 + pads[3] + pads[2] + points: Points = ws.get_entity("Points")[0] + np.testing.assert_allclose(grid.origin["z"], points.vertices[:, 2].max()) + assert grid.origin["x"] < points.vertices[:, 0].min() + assert grid.origin["y"] < points.vertices[:, 1].min() def test_padding(tmp_path: Path): @@ -45,7 +45,7 @@ def test_padding(tmp_path: Path): depth_core = 300.0 cell_size = (50, 50, 50) with Workspace(tmp_path / f"{__name__}.geoh5") as ws: - obj = obj = setup_block_model( + grid = setup_block_model( ws, top=top, depth_core=depth_core, @@ -53,9 +53,7 @@ def test_padding(tmp_path: Path): cell_size=cell_size, ) - assert top - (depth_core + obj.z_cells[0] + pads[4]) >= np.min( - obj.origin["z"] + obj.z_cell_delimiters - ) + assert np.abs(np.sum(grid.z_cells)) >= (depth_core + pads[4]) def test_padding_up_to(tmp_path: Path): @@ -67,7 +65,7 @@ def test_padding_up_to(tmp_path: Path): expansion_factor = 1.1 cell_size = (50, 50, 50) with Workspace(tmp_path / f"{__name__}.geoh5") as ws: - obj = obj = setup_block_model( + grid = setup_block_model( ws, top=top, depth_core=depth_core, @@ -76,8 +74,8 @@ def test_padding_up_to(tmp_path: Path): cell_size=cell_size, ) - assert obj.origin["z"] >= top + pads[-1] - depth_delimiters = obj.origin["z"] + obj.z_cell_delimiters + assert grid.origin["z"] >= top + pads[-1] + depth_delimiters = grid.origin["z"] + grid.z_cell_delimiters core_top_ind = np.argwhere(depth_delimiters == 500).flatten()[0] assert np.abs(np.diff(depth_delimiters))[core_top_ind] == cell_size[2] assert np.isclose( diff --git a/tests/run_tests/grid_model_merger_test.py b/tests/run_tests/grid_model_merger_test.py index 0b86ed6..92b66fd 100644 --- a/tests/run_tests/grid_model_merger_test.py +++ b/tests/run_tests/grid_model_merger_test.py @@ -70,7 +70,7 @@ def test_merge_block_model(tmp_path: Path): # pylint: disable=too-many-locals out_grid = driver.run() merged_model = out_grid.children[0] - np.testing.assert_almost_equal(merged_model.values[3406], 1.5, decimal=1) + np.testing.assert_almost_equal(merged_model.values[3937], 1.5, decimal=1) # Repeat with a hole in the first model values = model_a.values @@ -79,7 +79,7 @@ def test_merge_block_model(tmp_path: Path): # pylint: disable=too-many-locals out_grid = driver.run() merged_model = out_grid.children[0] - np.testing.assert_almost_equal(merged_model.values[3406], 2.0, decimal=1) + np.testing.assert_almost_equal(merged_model.values[3937], 2.0, decimal=1) def test_merge_all_nan(tmp_path: Path, caplog): # pylint: disable=too-many-locals From fdba6299ecb9f15446f204d21a49afee9a2362aa Mon Sep 17 00:00:00 2001 From: domfournier Date: Wed, 29 Jul 2026 13:26:56 -0700 Subject: [PATCH 3/5] Apply suggestions from code review Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- tests/conftest.py | 2 +- tests/run_tests/block_model_test.py | 12 ++++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index a8dff74..5659398 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -77,7 +77,7 @@ def setup_block_model( cell_size=(50, 50, 50), expansion_factor=1.1, ) -> BlockModel: - # padding in the W/E/N/S directions should make create locs at least as + # padding in the W/E/N/S directions should create locations at least as # far as the core hull plus the padding distances height = 300 width = 1000 diff --git a/tests/run_tests/block_model_test.py b/tests/run_tests/block_model_test.py index 368a0b7..581e246 100644 --- a/tests/run_tests/block_model_test.py +++ b/tests/run_tests/block_model_test.py @@ -32,9 +32,12 @@ def test_get_block_model(tmp_path: Path): # pylint: disable=too-many-locals pads=pads, ) points: Points = ws.get_entity("Points")[0] - np.testing.assert_allclose(grid.origin["z"], points.vertices[:, 2].max()) - assert grid.origin["x"] < points.vertices[:, 0].min() - assert grid.origin["y"] < points.vertices[:, 1].min() + + assert (grid.origin["z"] + grid.z_cell_delimiters).max() == top + assert grid.origin["x"] <= points.vertices[:, 0].min() - pads[0] + assert grid.origin["y"] <= points.vertices[:, 1].min() - pads[2] + assert grid.u_cell_delimiters.max() >= points.vertices[:, 0].max() + pads[0] + pads[1] # type: ignore + assert grid.v_cell_delimiters.max() >= points.vertices[:, 1].max() + pads[2] + pads[3] # type: ignore def test_padding(tmp_path: Path): @@ -53,7 +56,8 @@ def test_padding(tmp_path: Path): cell_size=cell_size, ) - assert np.abs(np.sum(grid.z_cells)) >= (depth_core + pads[4]) + depth_delimiters = grid.origin["z"] + grid.z_cell_delimiters + assert top - (depth_core + cell_size[2] + pads[4]) >= np.min(depth_delimiters) def test_padding_up_to(tmp_path: Path): From 75a8b638d205653f5964ec31188e2c67c5523ad4 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 29 Jul 2026 20:27:12 +0000 Subject: [PATCH 4/5] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- tests/run_tests/block_model_test.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tests/run_tests/block_model_test.py b/tests/run_tests/block_model_test.py index 581e246..309ba5f 100644 --- a/tests/run_tests/block_model_test.py +++ b/tests/run_tests/block_model_test.py @@ -36,8 +36,14 @@ def test_get_block_model(tmp_path: Path): # pylint: disable=too-many-locals assert (grid.origin["z"] + grid.z_cell_delimiters).max() == top assert grid.origin["x"] <= points.vertices[:, 0].min() - pads[0] assert grid.origin["y"] <= points.vertices[:, 1].min() - pads[2] - assert grid.u_cell_delimiters.max() >= points.vertices[:, 0].max() + pads[0] + pads[1] # type: ignore - assert grid.v_cell_delimiters.max() >= points.vertices[:, 1].max() + pads[2] + pads[3] # type: ignore + assert ( + grid.u_cell_delimiters.max() + >= points.vertices[:, 0].max() + pads[0] + pads[1] + ) # type: ignore + assert ( + grid.v_cell_delimiters.max() + >= points.vertices[:, 1].max() + pads[2] + pads[3] + ) # type: ignore def test_padding(tmp_path: Path): From c2e13f1a0a3cb3a56fae2f3eff0c7fb006bbe24f Mon Sep 17 00:00:00 2001 From: domfournier Date: Wed, 29 Jul 2026 13:28:19 -0700 Subject: [PATCH 5/5] [GEOPY-3009] Shift more under context --- tests/run_tests/block_model_test.py | 30 +++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/tests/run_tests/block_model_test.py b/tests/run_tests/block_model_test.py index 581e246..858da0b 100644 --- a/tests/run_tests/block_model_test.py +++ b/tests/run_tests/block_model_test.py @@ -36,8 +36,14 @@ def test_get_block_model(tmp_path: Path): # pylint: disable=too-many-locals assert (grid.origin["z"] + grid.z_cell_delimiters).max() == top assert grid.origin["x"] <= points.vertices[:, 0].min() - pads[0] assert grid.origin["y"] <= points.vertices[:, 1].min() - pads[2] - assert grid.u_cell_delimiters.max() >= points.vertices[:, 0].max() + pads[0] + pads[1] # type: ignore - assert grid.v_cell_delimiters.max() >= points.vertices[:, 1].max() + pads[2] + pads[3] # type: ignore + assert ( + grid.u_cell_delimiters.max() + >= points.vertices[:, 0].max() + pads[0] + pads[1] + ) # type: ignore + assert ( + grid.v_cell_delimiters.max() + >= points.vertices[:, 1].max() + pads[2] + pads[3] + ) # type: ignore def test_padding(tmp_path: Path): @@ -56,8 +62,8 @@ def test_padding(tmp_path: Path): cell_size=cell_size, ) - depth_delimiters = grid.origin["z"] + grid.z_cell_delimiters - assert top - (depth_core + cell_size[2] + pads[4]) >= np.min(depth_delimiters) + depth_delimiters = grid.origin["z"] + grid.z_cell_delimiters + assert top - (depth_core + cell_size[2] + pads[4]) >= np.min(depth_delimiters) def test_padding_up_to(tmp_path: Path): @@ -78,11 +84,11 @@ def test_padding_up_to(tmp_path: Path): cell_size=cell_size, ) - assert grid.origin["z"] >= top + pads[-1] - depth_delimiters = grid.origin["z"] + grid.z_cell_delimiters - core_top_ind = np.argwhere(depth_delimiters == 500).flatten()[0] - assert np.abs(np.diff(depth_delimiters))[core_top_ind] == cell_size[2] - assert np.isclose( - np.abs(np.diff(depth_delimiters))[core_top_ind - 1], - cell_size[2] * expansion_factor, - ) + assert grid.origin["z"] >= top + pads[-1] + depth_delimiters = grid.origin["z"] + grid.z_cell_delimiters + core_top_ind = np.argwhere(depth_delimiters == 500).flatten()[0] + assert np.abs(np.diff(depth_delimiters))[core_top_ind] == cell_size[2] + assert np.isclose( + np.abs(np.diff(depth_delimiters))[core_top_ind - 1], + cell_size[2] * expansion_factor, + )