Skip to content

Commit 6be6aa5

Browse files
committed
Merge remote-tracking branch 'origin/GEOPY-1571' into develop
2 parents 3e8a343 + 9b0b5c6 commit 6be6aa5

File tree

3 files changed

+68
-31
lines changed

3 files changed

+68
-31
lines changed

surface_apps/driver.py

Lines changed: 10 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -13,30 +13,28 @@
1313
import sys
1414
import tempfile
1515
from abc import abstractmethod
16-
from json import load
1716
from pathlib import Path
1817

19-
from geoapps_utils.driver.data import BaseData
20-
from geoapps_utils.driver.driver import BaseDriver
18+
from geoapps_utils.base import Driver, Options
2119
from geoh5py.groups import UIJsonGroup
2220
from geoh5py.objects import ObjectBase
23-
from geoh5py.shared.utils import fetch_active_workspace
21+
from geoh5py.shared.utils import fetch_active_workspace, stringify
2422
from geoh5py.ui_json import InputFile
2523

2624

2725
logger = logging.getLogger(__name__)
2826

2927

30-
class BaseSurfaceDriver(BaseDriver):
28+
class BaseSurfaceDriver(Driver):
3129
"""
3230
Driver for the surface application.
3331
3432
:param parameters: Application parameters.
3533
"""
3634

37-
_parameter_class: type[BaseData]
35+
_parameter_class: type[Options]
3836

39-
def __init__(self, parameters: BaseData | InputFile):
37+
def __init__(self, parameters: Options | InputFile):
4038
self._out_group: UIJsonGroup | None = None
4139

4240
if isinstance(parameters, InputFile):
@@ -59,9 +57,7 @@ def out_group(self) -> UIJsonGroup | None:
5957
workspace=workspace,
6058
name=self.params.title,
6159
)
62-
self._out_group.options = InputFile.stringify( # type: ignore
63-
InputFile.demote(self.params.input_file.ui_json)
64-
)
60+
self._out_group.options = stringify(self.params.input_file.ui_json)
6561

6662
return self._out_group
6763

@@ -91,27 +87,16 @@ def run(self):
9187
self.store()
9288

9389
@property
94-
def params(self) -> BaseData:
90+
def params(self) -> Options:
9591
"""Application parameters."""
9692
return self._params
9793

9894
@params.setter
99-
def params(self, val: BaseData):
100-
if not isinstance(val, BaseData):
101-
raise TypeError("Parameters must be a BaseData subclass.")
95+
def params(self, val: Options):
96+
if not isinstance(val, Options):
97+
raise TypeError("Parameters must be an Options subclass.")
10298
self._params = val
10399

104-
@classmethod
105-
def start(cls, filepath: str | Path, driver_class=None, **kwargs):
106-
with open(filepath, encoding="utf-8") as jsonfile:
107-
uijson = load(jsonfile)
108-
109-
if driver_class is None:
110-
module = __import__(uijson["run_command"], fromlist=["Driver"])
111-
driver_class = module.Driver
112-
113-
super().start(filepath, driver_class=driver_class, **kwargs)
114-
115100
def add_ui_json(self, entity: ObjectBase | UIJsonGroup) -> None:
116101
"""
117102
Add ui.json file to entity.

surface_apps/iso_surfaces/params.py

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,19 @@
1313
from typing import ClassVar
1414

1515
import numpy as np
16-
from geoapps_utils.driver.data import BaseData
16+
from geoapps_utils.base import Options
1717
from geoh5py.data import Data
1818
from geoh5py.groups import UIJsonGroup
19-
from geoh5py.objects import Points, Surface
19+
from geoh5py.objects import BlockModel, Points, Surface
2020
from geoh5py.objects.cell_object import CellObject
2121
from geoh5py.objects.grid_object import GridObject
2222
from geoh5py.ui_json.utils import str2list
23-
from pydantic import ConfigDict, field_validator
23+
from pydantic import BaseModel, ConfigDict, field_validator
2424

2525
from surface_apps import assets_path
2626

2727

28-
class IsoSurfaceSourceParameters(BaseData):
28+
class IsoSurfaceSourceParameters(BaseModel):
2929
"""
3030
Source parameters providing input data to the driver.
3131
@@ -41,8 +41,22 @@ class IsoSurfaceSourceParameters(BaseData):
4141
data: Data
4242
horizon: Surface | None = None
4343

44+
@field_validator("objects", mode="before")
45+
@classmethod
46+
def no_single_layer_grids(cls, value):
47+
"""Ensure a grid has more than a single layer in any dimension."""
48+
49+
if isinstance(value, BlockModel):
50+
n_cells = [len(getattr(value, f"{k}_cell_delimiters")) - 1 for k in "uvz"]
51+
if any(n == 1 for n in n_cells):
52+
raise ValueError(
53+
"Grid source cannot be a single layer in any dimension."
54+
)
55+
56+
return value
57+
4458

45-
class IsoSurfaceDetectionParameters(BaseData):
59+
class IsoSurfaceDetectionParameters(BaseModel):
4660
"""
4761
Contour specification parameters.
4862
@@ -123,7 +137,7 @@ def contours(self) -> list[float]:
123137
return contours
124138

125139

126-
class IsoSurfaceParameters(BaseData):
140+
class IsoSurfaceParameters(Options):
127141
"""
128142
Contour parameters for use with `contours.driver`.
129143

tests/run_tests/iso_surfaces_test.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,13 @@
1212
from pathlib import Path
1313

1414
import numpy as np
15+
import pytest
16+
from geoapps_utils.utils.importing import GeoAppsError
1517
from geoh5py.objects import BlockModel, Points, Surface
1618
from geoh5py.workspace import Workspace
1719

1820
from surface_apps.iso_surfaces.driver import Driver as IsoSurfacesDriver
21+
from surface_apps.iso_surfaces.params import IsoSurfaceParameters
1922

2023

2124
# pylint: disable=too-many-locals
@@ -215,3 +218,38 @@ def test_clipping_horizon(tmp_path: Path):
215218
)
216219

217220
assert np.all(surface.vertices[:, -1] <= 30)
221+
222+
223+
def test_single_layer_grid(tmp_path):
224+
with Workspace(tmp_path / "iso_test.geoh5") as ws:
225+
grid = BlockModel.create(
226+
ws,
227+
name="single_layer_grid",
228+
u_cell_delimiters=np.linspace(0, 10, 11),
229+
v_cell_delimiters=np.linspace(0, 10, 11),
230+
z_cell_delimiters=np.array([0.0, 1.0]),
231+
origin=[0, 0, 0],
232+
)
233+
data = grid.add_data(
234+
{
235+
"elevation": {
236+
"values": np.random.rand(grid.n_cells) * 100,
237+
"data_type": "Float",
238+
"association": "Cell",
239+
}
240+
}
241+
)
242+
243+
with pytest.raises(GeoAppsError, match="cannot be a single layer"):
244+
IsoSurfaceParameters.build(
245+
{
246+
"geoh5": ws,
247+
"objects": grid,
248+
"data": data,
249+
"interval_min": 0.0,
250+
"interval_max": 100.0,
251+
"interval_spacing": 20.0,
252+
"max_distance": 50.0,
253+
"resolution": 5.0,
254+
}
255+
)

0 commit comments

Comments
 (0)