Skip to content

Commit bbb6f30

Browse files
authored
is_hollow method xarray-contrib/datatree#272
* tests * implementation * API docs * narrative docs * whatsnew
1 parent 490002c commit bbb6f30

File tree

5 files changed

+37
-0
lines changed

5 files changed

+37
-0
lines changed

datatree/datatree.py

+5
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,11 @@ def is_empty(self) -> bool:
505505
"""False if node contains any data or attrs. Does not look at children."""
506506
return not (self.has_data or self.has_attrs)
507507

508+
@property
509+
def is_hollow(self) -> bool:
510+
"""True if only leaf nodes contain data."""
511+
return not any(node.has_data for node in self.subtree if not node.is_leaf)
512+
508513
@property
509514
def variables(self) -> Mapping[Hashable, Variable]:
510515
"""Low level interface to node contents as dict of Variable objects.

datatree/tests/test_datatree.py

+10
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,16 @@ def test_has_data(self):
136136
john = DataTree(name="john", data=None)
137137
assert not john.has_data
138138

139+
def test_is_hollow(self):
140+
john = DataTree(data=xr.Dataset({"a": 0}))
141+
assert john.is_hollow
142+
143+
eve = DataTree(children={"john": john})
144+
assert eve.is_hollow
145+
146+
eve.ds = xr.Dataset({"a": 1})
147+
assert not eve.is_hollow
148+
139149

140150
class TestVariablesChildrenNameCollisions:
141151
def test_parent_already_has_variable_with_childs_name(self):

docs/source/api.rst

+1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ This interface echoes that of ``xarray.Dataset``.
6464
DataTree.has_data
6565
DataTree.has_attrs
6666
DataTree.is_empty
67+
DataTree.is_hollow
6768

6869
..
6970

docs/source/hierarchical-data.rst

+19
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,25 @@ You can see this tree is similar to the ``dt`` object above, except that it is m
369369

370370
(If you want to keep the name of the root node, you will need to add the ``name`` kwarg to :py:class:`from_dict`, i.e. ``DataTree.from_dict(non_empty_nodes, name=dt.root.name)``.)
371371

372+
.. _Tree Contents:
373+
374+
Tree Contents
375+
-------------
376+
377+
Hollow Trees
378+
~~~~~~~~~~~~
379+
380+
A concept that can sometimes be useful is that of a "Hollow Tree", which means a tree with data stored only at the leaf nodes.
381+
This is useful because certain useful tree manipulation operations only make sense for hollow trees.
382+
383+
You can check if a tree is a hollow tree by using the :py:meth:`~DataTree.is_hollow` property.
384+
We can see that the Simpson's family is not hollow because the data variable ``"age"`` is present at some nodes which
385+
have children (i.e. Abe and Homer).
386+
387+
.. ipython:: python
388+
389+
simpsons.is_hollow
390+
372391
.. _manipulating trees:
373392

374393
Manipulating Trees

docs/source/whats-new.rst

+2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ New Features
2525

2626
- New :py:meth:`DataTree.match` method for glob-like pattern matching of node paths. (:pull:`267`)
2727
By `Tom Nicholas <https://github.com/TomNicholas>`_.
28+
- New :py:meth:`DataTree.is_hollow` property for checking if data is only contained at the leaf nodes. (:pull:`272`)
29+
By `Tom Nicholas <https://github.com/TomNicholas>`_.
2830
- Indicate which node caused the problem if error encountered while applying user function using :py:func:`map_over_subtree`
2931
(:issue:`190`, :pull:`264`). Only works when using python 3.11 or later.
3032
By `Tom Nicholas <https://github.com/TomNicholas>`_.

0 commit comments

Comments
 (0)