Repository: pydap/pydap
Pull request #446 (2025-03-13 00:18:52)

adds .grids() to identify all grid objects within dataset
<!-- Thank you very much for your hard work and contribution! -->

The following Pull Request:

- [x] Closes issue #445  for fixing a bug, requesting a new feature, etc.
- [x] Tests are added to demonstrate the new or fixed behavior, and all tests pass
on a local environment.

## new behavior
```python
url = "http://test.opendap.org/opendap/data/nc/coads_climatology.nc"
pyds = open_url(url, protocol="dap2")
pyds.tree()
.coads_climatology.nc
├──COADSX
├──COADSY
├──TIME
├──SST
│  ├──SST
│  ├──TIME
│  ├──COADSY
│  └──COADSX
├──AIRT
│  ├──AIRT
│  ├──TIME
│  ├──COADSY
│  └──COADSX
├──UWND
│  ├──UWND
│  ├──TIME
│  ├──COADSY
│  └──COADSX
└──VWND
   ├──VWND
   ├──TIME
   ├──COADSY
   └──COADSX


#=========================== this is new
pyds.grids()
>>>{'SST': {'shape': (12, 90, 180), 'maps': ['TIME', 'COADSY', 'COADSX']},
 'AIRT': {'shape': (12, 90, 180), 'maps': ['TIME', 'COADSY', 'COADSX']},
 'UWND': {'shape': (12, 90, 180), 'maps': ['TIME', 'COADSY', 'COADSX']},
 'VWND': {'shape': (12, 90, 180), 'maps': ['TIME', 'COADSY', 'COADSX']}}
#=========================== this is new
```


Mikejmnez: This is a very small feature for dap2 - I will merge.

Patch:
diff --git a/src/pydap/model.py b/src/pydap/model.py
index 4bb868f..5909666 100644
--- a/src/pydap/model.py
+++ b/src/pydap/model.py
@@ -546,6 +546,12 @@ class StructureType(DapType, Mapping):
                 out.update({var.name: [key.name for key in var.children()]})
         return out
 
+    def grids(self):
+        out = {}
+        for var in walk(self, GridType):
+            out.update({var.name: {"shape": var.shape, "maps": list(var.maps)}})
+        return out
+
     def variables(self):
         out = {}
         Bcs = [key for key in self.children() if isinstance(key, BaseType)]


Test patch:
diff --git a/src/pydap/tests/test_model.py b/src/pydap/tests/test_model.py
index c7ede9f..d86afcd 100644
--- a/src/pydap/tests/test_model.py
+++ b/src/pydap/tests/test_model.py
@@ -570,6 +570,30 @@ def test_DatasetType_nbytes(gridtype_example):
     assert dataset.nbytes == Nbytes
 
 
+def test_DatasetType_grids():
+    """test that correctly identifies grid variable
+    and its mappings
+    """
+    # fictitious dataset
+    # grid and groups do not belong to same DAP protocol
+    # but for now, this test accuracy of property
+    pyds = DatasetType("example")
+    pyds.createGroup("Group1")
+    pyds.createSequence("Group1/Seq")
+    pyds.createVariable("Group1/Seq.var")
+    pyds.createVariable("Group1/Seq.foo")
+
+    example = GridType("example")
+    example["a"] = BaseType("a", data=np.arange(30 * 50).reshape(30, 50))
+    example["x"] = BaseType("x", data=np.arange(30))
+    example["y"] = BaseType("y", data=np.arange(50))
+
+    pyds["/example"] = example
+    grids = pyds.grids()
+    assert len(grids) == 1
+    assert grids["example"] == {"shape": (30, 50), "maps": ["x", "y"]}
+
+
 def test_GridType_repr(gridtype_example):
     """Test ``__repr__`` of grids."""
     assert repr(gridtype_example) == "<GridType with array 'a' and maps 'x', 'y'>"