Repository: csiro-coasts/emsarray

Issue:
Shoc datasets without depth coordinate throw errors
SHOC datasets that do not have a depth coordinate throw an error in `Convention.get_depth_name()` which is correct, but this error bubbles up to `Convention.get_all_depth_names()` which is incorrect. This means that Shoc datasets that have been passed through `Convention.ocean_floor()` will not support `Convention.select_variables()`, for a specific failure case.

`/ShocStandard/ShocSimple.get_all_depth_names()` should not throw an error if there is no depth coordinate.

Discussion:

Patch:
diff --git a/docs/releases/development.rst b/docs/releases/development.rst
index 416ffd0..7175a6f 100644
--- a/docs/releases/development.rst
+++ b/docs/releases/development.rst
@@ -11,3 +11,6 @@ Next release (in development)
 * Drop dependency on importlib_metadata.
   This was only required to support Python 3.8, which was dropped in a previous release
   (:issue:`122`, :pr:`125`).
+* Fix an error with `ShocSimple.get_all_depth_names()`
+  when the dataset had no depth coordinates
+  (:issue:`123`, :pr:`126`).
diff --git a/src/emsarray/conventions/shoc.py b/src/emsarray/conventions/shoc.py
index 8ef5640..69c9e15 100644
--- a/src/emsarray/conventions/shoc.py
+++ b/src/emsarray/conventions/shoc.py
@@ -57,7 +57,9 @@ class ShocStandard(ArakawaC):
         return name
 
     def get_all_depth_names(self) -> List[Hashable]:
-        return ['z_centre', 'z_grid']
+        return [
+            name for name in ['z_centre', 'z_grid']
+            if name in self.dataset.variables]
 
     def get_time_name(self) -> Hashable:
         name = 't'
@@ -123,4 +125,8 @@ class ShocSimple(CFGrid2D):
         return name
 
     def get_all_depth_names(self) -> List[Hashable]:
-        return [self.get_depth_name()]
+        name = 'zc'
+        if name in self.dataset.variables:
+            return [name]
+        else:
+            return []


Test patch:
diff --git a/tests/conventions/test_cfgrid2d.py b/tests/conventions/test_cfgrid2d.py
index b73c99b..5c81c38 100644
--- a/tests/conventions/test_cfgrid2d.py
+++ b/tests/conventions/test_cfgrid2d.py
@@ -24,6 +24,7 @@ from shapely.testing import assert_geometries_equal
 from emsarray.conventions import get_dataset_convention
 from emsarray.conventions.grid import CFGrid2DTopology, CFGridKind
 from emsarray.conventions.shoc import ShocSimple
+from emsarray.exceptions import NoSuchCoordinateError
 from emsarray.operations import geometry
 from tests.utils import (
     DiagonalShocGrid, ShocGridGenerator, ShocLayerGenerator,
@@ -175,6 +176,16 @@ def test_varnames():
     assert dataset.ems.get_time_name() == 'time'
 
 
+def test_no_depth_coordinate():
+    dataset = make_dataset(j_size=10, i_size=10)
+    dataset = dataset.isel({'k': -1}, drop=True)
+    print(dataset)
+
+    assert dataset.ems.get_all_depth_names() == []
+    with pytest.raises(NoSuchCoordinateError):
+        dataset.ems.get_depth_name()
+
+
 @pytest.mark.parametrize(
     ['name', 'attrs'],
     [
diff --git a/tests/conventions/test_shoc_standard.py b/tests/conventions/test_shoc_standard.py
index e66dbee..ac63da7 100644
--- a/tests/conventions/test_shoc_standard.py
+++ b/tests/conventions/test_shoc_standard.py
@@ -32,7 +32,7 @@ def make_dataset(
     corner_size: int = 0,
 ) -> xarray.Dataset:
     """
-    Make a dummy SHOC simple dataset of a particular size.
+    Make a dummy SHOC standard dataset of a particular size.
     It will have a sheared grid of points located near (0, 0),
     with increasing j moving north east, and increasing i moving south east.
 
@@ -187,7 +187,7 @@ def make_dataset(
 def test_make_dataset():
     dataset = make_dataset(j_size=5, i_size=9, corner_size=2)
 
-    # Check that this is recognised as a ShocSimple dataset
+    # Check that this is recognised as a ShocStandard dataset
     assert get_dataset_convention(dataset) is ShocStandard
 
     # Check that the correct convention is used