diff --git a/src/xtgeo/surface/regular_surface.py b/src/xtgeo/surface/regular_surface.py index e759392a3..300a1f833 100644 --- a/src/xtgeo/surface/regular_surface.py +++ b/src/xtgeo/surface/regular_surface.py @@ -1097,6 +1097,7 @@ def to_file( fformat: Optional[str] = "irap_binary", pmd_dataunits: Optional[Tuple[int, int]] = (15, 10), engine: Optional[str] = "cxtgeo", + error_if_near_empty: bool = False, ): """Export a surface (map) to file. @@ -1117,6 +1118,9 @@ def to_file( but may be safer when reading memory streams and/or threading. Engine is relevant for Irap binary, Irap ascii and zmap. This is mainly a developer setting. + error_if_near_empty: Default is False. If True, raise a RuntimeError if + number of map nodes is less than 4. Otherwise, if False and number of + nodes are less than 4, a UserWarning will be given. Returns: ofile (pathlib.Path): The actual file instance, or None if io.Bytestream @@ -1145,8 +1149,20 @@ def to_file( .. versionchanged:: 2.5 Added support for BytesIO .. versionchanged:: 2.13 Improved support for BytesIO .. versionchanged:: 2.14 Support for alias file name and return value + .. versionchanged:: 3.8 Add key ``error_if_near_empty`` """ logger.info("Export RegularSurface to file or memstream...") + if self.nactive is None or self.nactive < 4: + msg = ( + f"Number of maps nodes are {self.nactive}. Exporting regular " + "surfaces with fewer than 4 nodes will not provide any " + "usable result. The map may also be not loaded if nodes are None." + ) + + if error_if_near_empty: + raise RuntimeError(msg) + warnings.warn(msg, UserWarning) + mfile = FileWrapper(mfile, mode="wb", obj=self) if not mfile.memstream: diff --git a/tests/test_surface/test_file_io.py b/tests/test_surface/test_file_io.py index 16b6c8607..26d9e7678 100644 --- a/tests/test_surface/test_file_io.py +++ b/tests/test_surface/test_file_io.py @@ -174,3 +174,21 @@ def test_read_cube(data): # Make sure it is properly constructed: result = {key: getattr(surf_from_cube, key) for key in cube_input} assert result == cube_input + + +def test_surf_io_few_nodes(tmp_path, larger_surface): + """Test to_file() with to few active nodes shall warn or raise error.""" + + surf = RegularSurface(**larger_surface) + + assert surf.nactive == 38 + + surf.values = np.ma.masked_where(surf.values > 0, surf.values) + + assert surf.nactive == 3 + + with pytest.warns(UserWarning, match="surfaces with fewer than 4 nodes will not"): + surf.to_file(tmp_path / "anyfile1.gri") + + with pytest.raises(RuntimeError, match="surfaces with fewer than 4 nodes will not"): + surf.to_file(tmp_path / "anyfile2.gri", error_if_near_empty=True)