From c0c996a0dac53d8fd8aa6f2a7ea222e74c20a63e Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Tue, 22 Oct 2024 16:16:28 +0200 Subject: [PATCH 01/27] configure the api documentation --- .gitignore | 1 + docs/api.rst | 40 ++++++++++++++++++++++++++++++++++++++++ docs/conf.py | 10 +++++++++- docs/index.md | 4 ++++ 4 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 docs/api.rst diff --git a/.gitignore b/.gitignore index ee5aa2d..e13a096 100644 --- a/.gitignore +++ b/.gitignore @@ -70,6 +70,7 @@ instance/ # Sphinx documentation docs/_build/ +docs/generated/ # PyBuilder .pybuilder/ diff --git a/docs/api.rst b/docs/api.rst new file mode 100644 index 0000000..e7e87d6 --- /dev/null +++ b/docs/api.rst @@ -0,0 +1,40 @@ +.. _api: + +############# +API reference +############# + +Top-level functions +=================== + +.. currentmodule:: xdggs + +.. autosummary:: + :toctree: generated/ + + decode + + +.. currentmodule:: xarray + +Parameters +========== +.. autosummary:: + :toctree: generated/ + :template: autosummary/accessor_attribute.rst + + DataArray.dggs.grid_info + Dataset.dggs.grid_info + + +Data inference +============== + +.. autosummary:: + :toctree: generated/ + :template: autosummary/accessor_method.rst + + DataArray.dggs.cell_centers + DataArray.dggs.cell_boundaries + Dataset.dggs.cell_centers + Dataset.dggs.cell_boundaries diff --git a/docs/conf.py b/docs/conf.py index 06c2702..8bc4f35 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,6 +1,10 @@ # -- Project information ----------------------------------------------------- import datetime as dt +import sphinx_autosummary_accessors + +import xdggs # noqa: F401 + project = "xdggs" author = f"{project} developers" initial_year = "2023" @@ -18,9 +22,13 @@ extensions = [ "sphinx.ext.extlinks", "sphinx.ext.intersphinx", + "sphinx.ext.autodoc", + "sphinx.ext.autosummary", + "sphinx.ext.napoleon", "IPython.sphinxext.ipython_directive", "IPython.sphinxext.ipython_console_highlighting", "myst_parser", + "sphinx_autosummary_accessors", ] extlinks = { @@ -29,7 +37,7 @@ } # Add any paths that contain templates here, relative to this directory. -templates_path = ["_templates"] +templates_path = ["_templates", sphinx_autosummary_accessors.templates_path] # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. diff --git a/docs/index.md b/docs/index.md index e456944..964c250 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1 +1,5 @@ # welcome to the documentation of `xdggs` + +```{toctree} +api.rst +``` From 1ff278f677fa157239933b4e4edaedd271cb8292 Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Wed, 23 Oct 2024 12:15:19 +0200 Subject: [PATCH 02/27] document grid info objects --- docs/api.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/api.rst b/docs/api.rst index e7e87d6..283d0cf 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -14,6 +14,14 @@ Top-level functions decode +Grid parameter objects +====================== + +.. autosummary:: + :toctree: generated + + HealpixInfo + H3Info .. currentmodule:: xarray From 629a248d27b6be52847c6a752f6a54ee6a19ca3a Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Wed, 23 Oct 2024 12:16:55 +0200 Subject: [PATCH 03/27] expose the dggs info classes --- xdggs/__init__.py | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/xdggs/__init__.py b/xdggs/__init__.py index 7c8ce81..9818cae 100644 --- a/xdggs/__init__.py +++ b/xdggs/__init__.py @@ -1,8 +1,9 @@ from importlib.metadata import PackageNotFoundError, version from xdggs.accessor import DGGSAccessor # noqa: F401 -from xdggs.h3 import H3Index -from xdggs.healpix import HealpixIndex +from xdggs.grid import DGGSInfo +from xdggs.h3 import H3Index, H3Info +from xdggs.healpix import HealpixIndex, HealpixInfo from xdggs.index import DGGSIndex, decode try: @@ -11,4 +12,13 @@ # package is not installed __version__ = "9999" -__all__ = ["__version__", "DGGSIndex", "H3Index", "HealpixIndex", "decode"] +__all__ = [ + "__version__", + "DGGSInfo", + "H3Info", + "HealpixInfo", + "DGGSIndex", + "H3Index", + "HealpixIndex", + "decode", +] From 34afaf2e4766401950db6e85c2e86cd5745a3f6b Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Wed, 23 Oct 2024 12:20:39 +0200 Subject: [PATCH 04/27] generate entries for the grid info objects --- docs/api-hidden.rst | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 docs/api-hidden.rst diff --git a/docs/api-hidden.rst b/docs/api-hidden.rst new file mode 100644 index 0000000..3a9ab9b --- /dev/null +++ b/docs/api-hidden.rst @@ -0,0 +1,18 @@ +:orphan: + +.. currentmodule:: xdggs + +.. autosummary:: + :toctree: generated + + HealpixInfo.from_dict + HealpixInfo.to_dict + HealpixInfo.cell_boundaries + HealpixInfo.cell_ids2geographic + HealpixInfo.geographic2cell_ids + + H3Info.from_dict + H3Info.to_dict + H3Info.cell_boundaries + H3Info.cell_ids2geographic + H3Info.geographic2cell_ids From f368584e58c397190823cd6aa07e0058358964af Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Wed, 23 Oct 2024 12:23:15 +0200 Subject: [PATCH 05/27] add `xarray`, `numpy` and `pandas` intersphinx entries --- docs/conf.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/conf.py b/docs/conf.py index 8bc4f35..582e8a1 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -62,4 +62,7 @@ intersphinx_mapping = { "python": ("https://docs.python.org/3/", None), "sphinx": ("https://www.sphinx-doc.org/en/stable/", None), + "numpy": ("https://numpy.org/doc/stable", None), + "xarray": ("https://docs.xarray.dev/en/latest/", None), + "pandas": ("https://pandas.pydata.org/pandas-docs/stable", None), } From b918fe44dd8a6d86219d9f11bdec87ae2764c6de Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Wed, 23 Oct 2024 12:26:47 +0200 Subject: [PATCH 06/27] install the project --- ci/docs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/ci/docs.yml b/ci/docs.yml index bd1c5f6..81d43cc 100644 --- a/ci/docs.yml +++ b/ci/docs.yml @@ -27,3 +27,4 @@ dependencies: - pip - pip: - h3ronpy + - -e .. From 0c064fdd0446167a57ba5554169892e98bc7d423 Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Wed, 23 Oct 2024 13:23:58 +0200 Subject: [PATCH 07/27] expose the plotting mechanism --- docs/api.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/api.rst b/docs/api.rst index 283d0cf..9792704 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -46,3 +46,12 @@ Data inference DataArray.dggs.cell_boundaries Dataset.dggs.cell_centers Dataset.dggs.cell_boundaries + +Plotting +======== +.. autosummary:: + :toctree: generated/ + :template: autosummary/accessor_method.rst + + DataArray.dggs.explore + Dataset.dggs.explore From ac10a8de5aeac2ac22a5231a962a592595f29f93 Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Wed, 23 Oct 2024 15:40:34 +0200 Subject: [PATCH 08/27] get the documentation to pass without warnings --- docs/api-hidden.rst | 9 +++++++++ docs/conf.py | 12 ++++++++++++ 2 files changed, 21 insertions(+) diff --git a/docs/api-hidden.rst b/docs/api-hidden.rst index 3a9ab9b..19fe952 100644 --- a/docs/api-hidden.rst +++ b/docs/api-hidden.rst @@ -5,12 +5,21 @@ .. autosummary:: :toctree: generated + HealpixInfo.resolution + HealpixInfo.indexing_scheme + HealpixInfo.valid_parameters + HealpixInfo.nside + HealpixInfo.nest + HealpixInfo.from_dict HealpixInfo.to_dict HealpixInfo.cell_boundaries HealpixInfo.cell_ids2geographic HealpixInfo.geographic2cell_ids + H3Info.resolution + H3Info.valid_parameters + H3Info.from_dict H3Info.to_dict H3Info.cell_boundaries diff --git a/docs/conf.py b/docs/conf.py index 582e8a1..6471e65 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -44,6 +44,17 @@ # This pattern also affects html_static_path and html_extra_path. exclude_patterns = ["_build", "directory"] +# -- autosummary / autodoc --------------------------------------------------- + +autosummary_generate = True +autodoc_typehints = "none" + +# -- napoleon ---------------------------------------------------------------- + +napoleon_numpy_docstring = True +napoleon_use_param = False +napoleon_use_rtype = False +napoleon_preprocess_types = True # -- Options for HTML output ------------------------------------------------- @@ -65,4 +76,5 @@ "numpy": ("https://numpy.org/doc/stable", None), "xarray": ("https://docs.xarray.dev/en/latest/", None), "pandas": ("https://pandas.pydata.org/pandas-docs/stable", None), + "lonboard": ("https://developmentseed.org/lonboard/latest", None), } From c39ff12788ea7cb008e77f3b9083cc97c060782b Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Wed, 23 Oct 2024 15:40:54 +0200 Subject: [PATCH 09/27] minimal docstring for `HealpixInfo.nside` --- xdggs/healpix.py | 1 + 1 file changed, 1 insertion(+) diff --git a/xdggs/healpix.py b/xdggs/healpix.py index db47955..b1dc8c3 100644 --- a/xdggs/healpix.py +++ b/xdggs/healpix.py @@ -115,6 +115,7 @@ def __post_init__(self): @property def nside(self: Self) -> int: + """resolution as the healpy-compatible nside parameter""" return 2**self.resolution @property From 26d905c394f01849a201f109977c6a742d193437 Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Wed, 23 Oct 2024 15:41:46 +0200 Subject: [PATCH 10/27] minimal docstring for `HealpixInfo.nest` --- xdggs/healpix.py | 1 + 1 file changed, 1 insertion(+) diff --git a/xdggs/healpix.py b/xdggs/healpix.py index b1dc8c3..c267fd4 100644 --- a/xdggs/healpix.py +++ b/xdggs/healpix.py @@ -120,6 +120,7 @@ def nside(self: Self) -> int: @property def nest(self: Self) -> bool: + """indexing_scheme as the healpy-compatible nest parameter""" if self.indexing_scheme not in {"nested", "ring"}: raise ValueError( f"cannot convert indexing scheme {self.indexing_scheme} to `nest`" From f986bd2d8ad3deec3f53299f3bb5b59b3b719893 Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Wed, 23 Oct 2024 15:58:15 +0200 Subject: [PATCH 11/27] remove `Dataset.dggs.explore`, which errors currently --- docs/api.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/api.rst b/docs/api.rst index 9792704..3e2c516 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -54,4 +54,3 @@ Plotting :template: autosummary/accessor_method.rst DataArray.dggs.explore - Dataset.dggs.explore From ad2468cbe0f7c401f969d11fb301e49c5bb71b62 Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Wed, 23 Oct 2024 16:06:18 +0200 Subject: [PATCH 12/27] docstrings for `cell_centers` and `cell_boundaries` --- xdggs/accessor.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/xdggs/accessor.py b/xdggs/accessor.py index df6e186..10f33dd 100644 --- a/xdggs/accessor.py +++ b/xdggs/accessor.py @@ -101,6 +101,13 @@ def cell_ids(self): return self._obj[self._name] def cell_centers(self): + """derive geographic cell center coordinates + + Returns + ------- + coords : xarray.Dataset + Dataset containing the cell centers in geographic coordinates. + """ lon_data, lat_data = self.index.cell_centers() return xr.Dataset( @@ -111,6 +118,13 @@ def cell_centers(self): ) def cell_boundaries(self): + """derive cell boundary polygons + + Returns + ------- + boundaries : xarray.DataArray + The cell boundaries as shapely objects. + """ boundaries = self.index.cell_boundaries() return xr.DataArray( From 8a27cea6e5f8fccb83a7933bb0dc2c2709cbb82f Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Wed, 23 Oct 2024 16:11:31 +0200 Subject: [PATCH 13/27] document `*.dggs.grid_info` --- docs/api-hidden.rst | 8 ++++++++ docs/api.rst | 2 ++ xdggs/accessor.py | 6 ++++++ 3 files changed, 16 insertions(+) diff --git a/docs/api-hidden.rst b/docs/api-hidden.rst index 19fe952..0dc483b 100644 --- a/docs/api-hidden.rst +++ b/docs/api-hidden.rst @@ -5,6 +5,14 @@ .. autosummary:: :toctree: generated + DGGSInfo.resolution + + DGGSInfo.from_dict + DGGSInfo.to_dict + DGGSInfo.cell_boundaries + DGGSInfo.cell_ids2geographic + DGGSInfo.geographic2cell_ids + HealpixInfo.resolution HealpixInfo.indexing_scheme HealpixInfo.valid_parameters diff --git a/docs/api.rst b/docs/api.rst index 3e2c516..554952e 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -20,6 +20,8 @@ Grid parameter objects .. autosummary:: :toctree: generated + DGGSInfo + HealpixInfo H3Info diff --git a/xdggs/accessor.py b/xdggs/accessor.py index 10f33dd..169a482 100644 --- a/xdggs/accessor.py +++ b/xdggs/accessor.py @@ -59,6 +59,12 @@ def params(self) -> dict: @property def grid_info(self) -> DGGSInfo: + """The grid info object containing the DGGS type and its parameters. + + Returns + ------- + xdggs.DGGSInfo + """ return self.index.grid_info def sel_latlon( From 082ee65cbca464b5dfe4970454937fccade25e25 Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Thu, 24 Oct 2024 11:32:07 +0200 Subject: [PATCH 14/27] docstring for `from_dict` --- xdggs/h3.py | 13 +++++++++++++ xdggs/healpix.py | 13 +++++++++++++ 2 files changed, 26 insertions(+) diff --git a/xdggs/h3.py b/xdggs/h3.py index 40bf289..e141ea9 100644 --- a/xdggs/h3.py +++ b/xdggs/h3.py @@ -70,6 +70,19 @@ def __post_init__(self): @classmethod def from_dict(cls: type[Self], mapping: dict[str, Any]) -> Self: + """construct a `H3Info` object from a mapping of attributes + + Parameters + ---------- + mapping: mapping of str to any + The attributes. + + Returns + ------- + grid_info : H3Info + The constructed grid info object. + """ + params = {k: v for k, v in mapping.items() if k != "grid_name"} return cls(**params) diff --git a/xdggs/healpix.py b/xdggs/healpix.py index c267fd4..9d8cf3c 100644 --- a/xdggs/healpix.py +++ b/xdggs/healpix.py @@ -130,6 +130,19 @@ def nest(self: Self) -> bool: @classmethod def from_dict(cls: type[T], mapping: dict[str, Any]) -> T: + """construct a `HealpixInfo` object from a mapping of attributes + + Parameters + ---------- + mapping: mapping of str to any + The attributes. + + Returns + ------- + grid_info : HealpixInfo + The constructed grid info object. + """ + def translate_nside(nside): log = np.log2(nside) potential_resolution = int(log) From fcb5e4b0bbd6675c7c19947440649def8d6348c3 Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Fri, 25 Oct 2024 16:03:11 +0200 Subject: [PATCH 15/27] remove the trailing slash from the toctree dir --- docs/api.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/api.rst b/docs/api.rst index 554952e..8524a44 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -10,7 +10,7 @@ Top-level functions .. currentmodule:: xdggs .. autosummary:: - :toctree: generated/ + :toctree: generated decode @@ -30,7 +30,7 @@ Grid parameter objects Parameters ========== .. autosummary:: - :toctree: generated/ + :toctree: generated :template: autosummary/accessor_attribute.rst DataArray.dggs.grid_info @@ -41,7 +41,7 @@ Data inference ============== .. autosummary:: - :toctree: generated/ + :toctree: generated :template: autosummary/accessor_method.rst DataArray.dggs.cell_centers @@ -52,7 +52,7 @@ Data inference Plotting ======== .. autosummary:: - :toctree: generated/ + :toctree: generated :template: autosummary/accessor_method.rst DataArray.dggs.explore From b65f8abc4f16ccad7b3de7e8ca9d52c28c60df0d Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Fri, 25 Oct 2024 16:05:27 +0200 Subject: [PATCH 16/27] document `tutorial.open_dataset` --- docs/api.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/api.rst b/docs/api.rst index 8524a44..6574497 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -56,3 +56,13 @@ Plotting :template: autosummary/accessor_method.rst DataArray.dggs.explore + +Tutorial +======== + +.. currentmodule:: xdggs + +.. autosummary:: + :toctree: generated + + tutorial.open_dataset From b3f1128c10e0c06d775e938115383309ef7f1d4e Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Fri, 25 Oct 2024 16:09:58 +0200 Subject: [PATCH 17/27] clarify the role of the grid names --- xdggs/tutorial.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xdggs/tutorial.py b/xdggs/tutorial.py index ad6fffd..7405f64 100644 --- a/xdggs/tutorial.py +++ b/xdggs/tutorial.py @@ -69,9 +69,9 @@ def open_dataset( If a local copy is found then always use that to avoid network traffic. - Available datasets: + Available datasets (available grid names in parentheses): - * ``"air_temperature"`` (H3, healpix): NCEP reanalysis subset. + * ``"air_temperature"`` (``h3``, ``healpix``): NCEP reanalysis subset. Parameters ---------- From 24c500f51194b482683ab65545d814c49872cab9 Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Fri, 25 Oct 2024 16:10:11 +0200 Subject: [PATCH 18/27] set some generic aliases --- docs/conf.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/conf.py b/docs/conf.py index 6471e65..3acd3bc 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -55,6 +55,18 @@ napoleon_use_param = False napoleon_use_rtype = False napoleon_preprocess_types = True +napoleon_type_aliases = { + # general terms + "sequence": ":term:`sequence`", + "iterable": ":term:`iterable`", + "callable": ":py:func:`callable`", + "dict_like": ":term:`dict-like `", + "dict-like": ":term:`dict-like `", + "path-like": ":term:`path-like `", + "mapping": ":term:`mapping`", + "file-like": ":term:`file-like `", + "any": ":py:class:`any `", +} # -- Options for HTML output ------------------------------------------------- From 599e868ddca420939ad875832c575c2d69d901bd Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Fri, 25 Oct 2024 16:24:31 +0200 Subject: [PATCH 19/27] improve the docstrings of `index` and `coord` --- xdggs/accessor.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/xdggs/accessor.py b/xdggs/accessor.py index 169a482..f817b9e 100644 --- a/xdggs/accessor.py +++ b/xdggs/accessor.py @@ -31,9 +31,12 @@ def __init__(self, obj: xr.Dataset | xr.DataArray): @property def index(self) -> DGGSIndex: - """Returns the DGGSIndex instance for this Dataset or DataArray. + """The DGGSIndex instance for this Dataset or DataArray. - Raise a ``ValueError`` if no such index is found. + Raises + ------ + ValueError + if no DGGSIndex can be found """ if self._index is None: raise ValueError("no DGGSIndex found on this Dataset or DataArray") @@ -41,10 +44,12 @@ def index(self) -> DGGSIndex: @property def coord(self) -> xr.DataArray: - """Returns the indexed DGGS (cell ids) coordinate as a DataArray. - - Raise a ``ValueError`` if no such coordinate is found on this Dataset or DataArray. + """The indexed DGGS (cell ids) coordinate as a DataArray. + Raises + ------ + ValueError + if no such coordinate is found on the Dataset / DataArray """ if not self._name: raise ValueError( @@ -84,7 +89,6 @@ def sel_latlon( subset A new :py:class:`xarray.Dataset` or :py:class:`xarray.DataArray` with all cells that contain the input latitude/longitude data points. - """ cell_indexers = { self._name: self.grid_info.geographic2cell_ids(latitude, longitude) From 38e931fe4acd8314579fbe466fdb55d965ff37b9 Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Fri, 25 Oct 2024 16:24:44 +0200 Subject: [PATCH 20/27] make `cell_ids` an alias of `coord` --- xdggs/accessor.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/xdggs/accessor.py b/xdggs/accessor.py index f817b9e..72792a1 100644 --- a/xdggs/accessor.py +++ b/xdggs/accessor.py @@ -108,7 +108,16 @@ def assign_latlon_coords(self) -> xr.Dataset | xr.DataArray: @property def cell_ids(self): - return self._obj[self._name] + """The indexed DGGS (cell ids) coordinate as a DataArray. + + Alias of ``coord``. + + Raises + ------ + ValueError + if no such coordinate is found on the Dataset / DataArray + """ + return self.coord def cell_centers(self): """derive geographic cell center coordinates From 930ef7dc797c41cf68020840a85ff3192545dfdb Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Fri, 25 Oct 2024 16:59:49 +0200 Subject: [PATCH 21/27] restructure the api docs --- docs/api.rst | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/docs/api.rst b/docs/api.rst index 6574497..0fea7c3 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -27,30 +27,54 @@ Grid parameter objects .. currentmodule:: xarray +Dataset +======= + Parameters -========== +---------- .. autosummary:: :toctree: generated :template: autosummary/accessor_attribute.rst - DataArray.dggs.grid_info Dataset.dggs.grid_info + Dataset.dggs.params Data inference -============== +-------------- .. autosummary:: :toctree: generated :template: autosummary/accessor_method.rst - DataArray.dggs.cell_centers - DataArray.dggs.cell_boundaries Dataset.dggs.cell_centers Dataset.dggs.cell_boundaries +DataArray +========= + +Parameters +---------- +.. autosummary:: + :toctree: generated + :template: autosummary/accessor_attribute.rst + + DataArray.dggs.grid_info + DataArray.dggs.params + + +Data inference +-------------- + +.. autosummary:: + :toctree: generated + :template: autosummary/accessor_method.rst + + DataArray.dggs.cell_centers + DataArray.dggs.cell_boundaries + Plotting -======== +-------- .. autosummary:: :toctree: generated :template: autosummary/accessor_method.rst From 6950d6ebe536f4964c7467f29d552840d8705b03 Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Fri, 25 Oct 2024 17:00:31 +0200 Subject: [PATCH 22/27] document the healpix grid info object --- docs/conf.py | 8 +++++ xdggs/healpix.py | 80 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) diff --git a/docs/conf.py b/docs/conf.py index 3acd3bc..7a378f3 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -66,6 +66,12 @@ "mapping": ":term:`mapping`", "file-like": ":term:`file-like `", "any": ":py:class:`any `", + # numpy terms + "array_like": ":term:`array_like`", + "array-like": ":term:`array-like `", + "scalar": ":term:`scalar`", + "array": ":term:`array`", + "hashable": ":term:`hashable `", } # -- Options for HTML output ------------------------------------------------- @@ -89,4 +95,6 @@ "xarray": ("https://docs.xarray.dev/en/latest/", None), "pandas": ("https://pandas.pydata.org/pandas-docs/stable", None), "lonboard": ("https://developmentseed.org/lonboard/latest", None), + "healpy": ("https://healpy.readthedocs.io/en/latest", None), + "shapely": ("https://shapely.readthedocs.io/en/stable", None), } diff --git a/xdggs/healpix.py b/xdggs/healpix.py index 9d8cf3c..21440f2 100644 --- a/xdggs/healpix.py +++ b/xdggs/healpix.py @@ -95,14 +95,32 @@ def center_around_prime_meridian(lon, lat): @dataclass(frozen=True) class HealpixInfo(DGGSInfo): + """ + Grid information container for healpix grids. + + Parameters + ---------- + resolution : int + The resolution of the grid + indexing_scheme : {"nested", "ring", "unique"}, default: "nested" + The indexing scheme of the healpix grid. + + .. warning:: + Note that ``"unique"`` is currently not supported as the underlying library + (:doc:`healpy `) does not support it. + """ + resolution: int + """int : The resolution of the grid""" indexing_scheme: Literal["nested", "ring", "unique"] = "nested" + """int : The indexing scheme of the grid""" valid_parameters: ClassVar[dict[str, Any]] = { "resolution": range(0, 29 + 1), "indexing_scheme": ["nested", "ring", "unique"], } + """mapping of str to any : Valid values for the parameters.""" def __post_init__(self): if self.resolution not in self.valid_parameters["resolution"]: @@ -112,6 +130,8 @@ def __post_init__(self): raise ValueError( f"indexing scheme must be one of {self.valid_parameters['indexing_scheme']}" ) + elif self.indexing_scheme == "unique": + raise ValueError("the indexing scheme `unique` is currently not supported") @property def nside(self: Self) -> int: @@ -191,6 +211,14 @@ def translate(name, value): return cls(**params) def to_dict(self: Self) -> dict[str, Any]: + """ + Dump the normalized grid parameters. + + Returns + ------- + mapping : dict of str to any + The normalized grid parameters. + """ return { "grid_name": "healpix", "resolution": self.resolution, @@ -198,14 +226,66 @@ def to_dict(self: Self) -> dict[str, Any]: } def cell_ids2geographic(self, cell_ids): + """ + Convert cell ids to geographic coordinates + + Parameters + ---------- + cell_ids : array-like + Array-like containing the cell ids. + + Returns + ------- + lon : array-like + The longitude coordinate values of the grid cells in degree + lat : array-like + The latitude coordinate values of the grid cells in degree + """ lon, lat = healpy.pix2ang(self.nside, cell_ids, nest=self.nest, lonlat=True) return lon, lat def geographic2cell_ids(self, lon, lat): + """ + Convert cell ids to geographic coordinates + + This will perform a binning operation: any point within a grid cell will be assign + that cell's ID. + + Parameters + ---------- + lon : array-like + The longitude coordinate values in degree + lat : array-like + The latitude coordinate values in degree + + Returns + ------- + cell_ids : array-like + Array-like containing the cell ids. + """ return healpy.ang2pix(self.nside, lon, lat, lonlat=True, nest=self.nest) def cell_boundaries(self, cell_ids: Any, backend="shapely") -> np.ndarray: + """ + Derive cell boundary polygons from cell ids + + Parameters + ---------- + cell_ids : array-like + The cell ids. + backend : {"shapely", "geoarrow"}, default: "shapely" + The backend to convert to. + + Returns + ------- + polygons : array-like + The derived cell boundary polygons. The format differs based on the passed + backend: + + - ``"shapely"``: return a array of :py:class:`shapely.Polygon` objects + - ``"geoarrow"``: return a ``geoarrow`` array + """ boundary_vectors = healpy.boundaries( self.nside, cell_ids, step=1, nest=self.nest ) From ed64b34f8320bebfc83ee39cb224c2629aa5a967 Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Fri, 25 Oct 2024 17:08:52 +0200 Subject: [PATCH 23/27] document the h3 grid info class --- xdggs/h3.py | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/xdggs/h3.py b/xdggs/h3.py index e141ea9..a38592b 100644 --- a/xdggs/h3.py +++ b/xdggs/h3.py @@ -60,7 +60,17 @@ def polygons_geoarrow(wkb): @dataclass(frozen=True) class H3Info(DGGSInfo): + """ + Grid information container for h3 grids. + + Parameters + ---------- + resolution : int + The resolution of the grid + """ + resolution: int + """int : The resolution of the grid""" valid_parameters: ClassVar[dict[str, Any]] = {"resolution": range(16)} @@ -87,19 +97,79 @@ def from_dict(cls: type[Self], mapping: dict[str, Any]) -> Self: return cls(**params) def to_dict(self: Self) -> dict[str, Any]: + """ + Dump the normalized grid parameters. + + Returns + ------- + mapping : dict of str to any + The normalized grid parameters. + """ return {"grid_name": "h3", "resolution": self.resolution} def cell_ids2geographic( self, cell_ids: np.ndarray ) -> tuple[np.ndarray, np.ndarray]: + """ + Convert cell ids to geographic coordinates + + Parameters + ---------- + cell_ids : array-like + Array-like containing the cell ids. + + Returns + ------- + lon : array-like + The longitude coordinate values of the grid cells in degree + lat : array-like + The latitude coordinate values of the grid cells in degree + """ lat, lon = cells_to_coordinates(cell_ids, radians=False) return lon, lat def geographic2cell_ids(self, lon, lat): + """ + Convert cell ids to geographic coordinates + + This will perform a binning operation: any point within a grid cell will be assign + that cell's ID. + + Parameters + ---------- + lon : array-like + The longitude coordinate values in degree + lat : array-like + The latitude coordinate values in degree + + Returns + ------- + cell_ids : array-like + Array-like containing the cell ids. + """ return coordinates_to_cells(lat, lon, self.resolution, radians=False) def cell_boundaries(self, cell_ids, backend="shapely"): + """ + Derive cell boundary polygons from cell ids + + Parameters + ---------- + cell_ids : array-like + The cell ids. + backend : {"shapely", "geoarrow"}, default: "shapely" + The backend to convert to. + + Returns + ------- + polygons : array-like + The derived cell boundary polygons. The format differs based on the passed + backend: + + - ``"shapely"``: return a array of :py:class:`shapely.Polygon` objects + - ``"geoarrow"``: return a ``geoarrow`` array + """ # TODO: convert cell ids directly to geoarrow once h3ronpy supports it wkb = cells_to_wkb_polygons(cell_ids, radians=False, link_cells=False) From 9e7f378c1450f977bcd91efc78d72fa777b6c35f Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Fri, 25 Oct 2024 17:09:52 +0200 Subject: [PATCH 24/27] don't document the `valid_parameters` class attribute --- xdggs/healpix.py | 1 - 1 file changed, 1 deletion(-) diff --git a/xdggs/healpix.py b/xdggs/healpix.py index 21440f2..6db12db 100644 --- a/xdggs/healpix.py +++ b/xdggs/healpix.py @@ -120,7 +120,6 @@ class HealpixInfo(DGGSInfo): "resolution": range(0, 29 + 1), "indexing_scheme": ["nested", "ring", "unique"], } - """mapping of str to any : Valid values for the parameters.""" def __post_init__(self): if self.resolution not in self.valid_parameters["resolution"]: From c9638a911dce8b969d6d798a84b4bd3a65351273 Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Fri, 25 Oct 2024 17:15:29 +0200 Subject: [PATCH 25/27] don't count `unique` as a valid indexing scheme --- xdggs/tests/test_healpix.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/xdggs/tests/test_healpix.py b/xdggs/tests/test_healpix.py index d823f36..5de2f7f 100644 --- a/xdggs/tests/test_healpix.py +++ b/xdggs/tests/test_healpix.py @@ -24,10 +24,9 @@ class strategies: invalid_resolutions = st.integers(max_value=-1) | st.integers(min_value=30) resolutions = st.integers(min_value=0, max_value=29) - indexing_schemes = st.sampled_from(["nested", "ring", "unique"]) - invalid_indexing_schemes = st.text().filter( - lambda x: x not in ["nested", "ring", "unique"] - ) + # TODO: add back `"unique"` once that is supported + indexing_schemes = st.sampled_from(["nested", "ring"]) + invalid_indexing_schemes = st.text().filter(lambda x: x not in ["nested", "ring"]) dims = xrst.names() From 278f0a27eef1c281a5238ed5227c11ca12b0284e Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Fri, 25 Oct 2024 17:23:35 +0200 Subject: [PATCH 26/27] document `xdggs.decode` --- xdggs/index.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/xdggs/index.py b/xdggs/index.py index 36eb613..13149d9 100644 --- a/xdggs/index.py +++ b/xdggs/index.py @@ -10,6 +10,21 @@ def decode(ds): + """ + decode grid parameters and create a DGGS index + + Parameters + ---------- + ds : xarray.Dataset + The input dataset. Must contain a `"cell_ids"` coordinate with at least + the attributes `grid_name` and `resolution`. + + Returns + ------- + decoded : xarray.Dataset + The input dataset with a DGGS index on the ``"cell_ids"`` coordinate. + """ + variable_name = "cell_ids" return ds.drop_indexes(variable_name, errors="ignore").set_xindex( From c26f4d386e4ce5712070d86ac2be1b0b41330965 Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Fri, 25 Oct 2024 17:28:56 +0200 Subject: [PATCH 27/27] link to the documentation in the package metadata --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index ee788a7..c5ca828 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -46,7 +46,7 @@ dependencies = [ ] [project.urls] -# Home = "https://xdggs.readthedocs.io" +Documentation = "https://xdggs.readthedocs.io" Repository = "https://github.com/xarray-contrib/xdggs" [tool.ruff]