Skip to content

Commit f0e2259

Browse files
authored
Automatic API Documentation (#155)
* Licence years update. * Basic sphinx setup. * Sphinx domains for docstrings. * RTD config file. * RTD Sphinx config location. * sphinxcontrib apidoc * Finished Sphinx domains for docstrings. * RTD mamba. * Single copyright year. * Fix docstring backslash linting. * Revert "Single copyright year." This reverts commit 05e4955. * Rectilinear docstring typo. * CHANGELOG moving and addition. * sphinxcontrib apidoc in setup.cfg. * More accurate docstrings. * README link to docs.
1 parent 1aa8052 commit f0e2259

File tree

16 files changed

+454
-217
lines changed

16 files changed

+454
-217
lines changed

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,10 @@ instance/
7171
.scrapy
7272

7373
# Sphinx documentation
74-
docs/_build/
74+
docs/src/_api_generated/
75+
docs/src/_build/
76+
docs/src/_static/
77+
docs/src/_templates/
7578

7679
# PyBuilder
7780
target/

.readthedocs.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
version: 2
2+
3+
build:
4+
os: ubuntu-20.04
5+
tools:
6+
python: mambaforge-4.10
7+
8+
conda:
9+
environment: requirements/dev.yml
10+
11+
sphinx:
12+
configuration: docs/src/conf.py
13+
fail_on_warning: false
14+
15+
python:
16+
install:
17+
- method: setuptools
18+
path: .
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ This release added the ability to regrid data stored on a UGRID mesh.
2828
[PR#137](https://github.com/SciTools-incubator/iris-esmf-regrid/pull/137)
2929
Added functions for saving of the unstructured regridders.
3030
[@stephenworsley](https://github.com/stephenworsley)
31+
- [PR#155](https://github.com/SciTools-incubator/iris-esmf-regrid/pull/155)
32+
Enabled Sphinx and RTD for automatically rendering the API.
33+
[@trexfeathers](https://github.com/trexfeathers)
3134

3235
## [0.3] - 2021-12-21
3336

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
BSD 3-Clause License
22

3-
Copyright (c) 2020, SciTools-incubator
3+
Copyright (c) 2020 - 2022, SciTools-incubator
44
All rights reserved.
55

66
Redistribution and use in source and binary forms, with or without

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
---
1212

13+
[Click here for the API documentation](https://iris-esmf-regrid.readthedocs.io/en/latest)
14+
1315
## Overview
1416

1517
This project aims to provide a bridge between [Iris](https://github.com/SciTools/iris)

docs/src/Makefile

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Minimal makefile for Sphinx documentation
2+
#
3+
4+
# You can set these variables from the command line, and also
5+
# from the environment for the first two.
6+
SPHINXOPTS ?=
7+
SPHINXBUILD ?= sphinx-build
8+
SOURCEDIR = .
9+
BUILDDIR = _build
10+
11+
# Put it first so that "make" without argument is like "make help".
12+
help:
13+
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
14+
15+
.PHONY: help Makefile
16+
17+
# Catch-all target: route all unknown targets to Sphinx using the new
18+
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
19+
%: Makefile
20+
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

docs/src/conf.py

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
"""
2+
Configuration file for the Sphinx documentation builder.
3+
4+
Created originally using sphinx-quickstart on 2022-02-21.
5+
"""
6+
7+
from datetime import datetime
8+
from pathlib import Path
9+
import sys
10+
11+
# -- Path setup --------------------------------------------------------------
12+
13+
# If extensions (or modules to document with autodoc) are in another directory,
14+
# add these directories to sys.path here - **using absolute paths**.
15+
16+
source_code_root = (Path(__file__).parents[2]).absolute()
17+
sys.path.append(str(source_code_root))
18+
19+
20+
# -- Project information -----------------------------------------------------
21+
22+
from esmf_regrid import __version__ as esmf_r_version
23+
24+
copyright_years = f"2020 - {datetime.now().year}"
25+
26+
project = "iris-esmf-regrid"
27+
copyright = f"{copyright_years}, SciTools-incubator"
28+
author = "iris-esmf-regrid Contributors"
29+
30+
# The full version, including alpha/beta/rc tags
31+
release = esmf_r_version
32+
33+
34+
# -- General configuration ---------------------------------------------------
35+
36+
# Add any Sphinx extension module names here, as strings. They can be
37+
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
38+
# ones.
39+
extensions = [
40+
"sphinx.ext.autodoc",
41+
"sphinx_copybutton",
42+
"sphinx.ext.extlinks",
43+
"sphinx.ext.intersphinx",
44+
"sphinx.ext.napoleon",
45+
"sphinx.ext.todo",
46+
"sphinx.ext.viewcode",
47+
"sphinxcontrib.apidoc",
48+
]
49+
50+
# Add any paths that contain templates here, relative to this directory.
51+
templates_path = ["_templates"]
52+
53+
# List of patterns, relative to source directory, that match files and
54+
# directories to ignore when looking for source files.
55+
# This pattern also affects html_static_path and html_extra_path.
56+
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
57+
58+
59+
# -- Options for HTML output -------------------------------------------------
60+
61+
# The theme to use for HTML and HTML Help pages. See the documentation for
62+
# a list of builtin themes.
63+
#
64+
html_theme = "pydata_sphinx_theme"
65+
66+
html_theme_options = {
67+
"github_url": "https://github.com/SciTools-incubator/iris-esmf-regrid",
68+
"show_prev_next": False,
69+
"icon_links": [
70+
{
71+
"name": "Support",
72+
"url": "https://github.com/SciTools-incubator/iris-esmf-regrid/discussions",
73+
"icon": "fa fa-comments fa-fw",
74+
}
75+
],
76+
}
77+
78+
79+
# Add any paths that contain custom static files (such as style sheets) here,
80+
# relative to this directory. They are copied after the builtin static files,
81+
# so a file named "default.css" will overwrite the builtin "default.css".
82+
html_static_path = ["_static"]
83+
84+
85+
# -- api generation configuration ---------------------------------------------
86+
autoclass_content = "both"
87+
autodoc_typehints = "none"
88+
modindex_common_prefix = ["esmf_regrid"]
89+
90+
91+
# -- copybutton extension -----------------------------------------------------
92+
# See https://sphinx-copybutton.readthedocs.io/en/latest/
93+
copybutton_prompt_text = r">>> |\.\.\. "
94+
copybutton_prompt_is_regexp = True
95+
copybutton_line_continuation_character = "\\"
96+
97+
98+
# -- extlinks extension -------------------------------------------------------
99+
# See https://www.sphinx-doc.org/en/master/usage/extensions/extlinks.html
100+
101+
extlinks = {
102+
"issue": (
103+
"https://github.com/SciTools-incubator/iris-esmf-regrid/issues/%s",
104+
"Issue #",
105+
),
106+
"pull": ("https://github.com/SciTools-incubator/iris-esmf-regrid/pull/%s", "PR #"),
107+
}
108+
109+
110+
# -- intersphinx extension ----------------------------------------------------
111+
# See https://www.sphinx-doc.org/en/master/usage/extensions/intersphinx.html
112+
intersphinx_mapping = {
113+
"iris": ("https://scitools-iris.readthedocs.io/en/latest/", None),
114+
"cartopy": ("https://scitools.org.uk/cartopy/docs/latest/", None),
115+
"numpy": ("https://numpy.org/doc/stable/", None),
116+
"python": ("https://docs.python.org/3/", None),
117+
"scipy": ("https://docs.scipy.org/doc/scipy/", None),
118+
"ESMF": ("https://earthsystemmodeling.org/esmpy_doc/release/latest/html/", None),
119+
}
120+
121+
122+
# -- todo_ extension ----------------------------------------------------------
123+
# See https://www.sphinx-doc.org/en/master/usage/extensions/todo.html
124+
todo_include_todos = True
125+
126+
127+
# -- apidoc extension ---------------------------------------------------------
128+
# See https://github.com/sphinx-contrib/apidoc
129+
module_dir = source_code_root / "esmf_regrid"
130+
131+
apidoc_module_dir = str(module_dir)
132+
apidoc_output_dir = str(Path(__file__).parent / "_api_generated")
133+
apidoc_excluded_paths = [str(module_dir / "tests")]
134+
apidoc_separate_modules = True
135+
apidoc_extra_args = ["-H", "API"]

docs/src/index.rst

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
iris-esmf-regrid
2+
================
3+
4+
A collection of structured and unstructured ESMF_ regridding schemes for Iris_.
5+
6+
This rendered documentation is so far limited to iris-esmf-regrid's API. Some
7+
basic examples and change logs can be found on GitHub_.
8+
9+
:doc:`Click to view the API<_api_generated/modules>`
10+
11+
.. toctree::
12+
:hidden:
13+
14+
_api_generated/modules
15+
16+
.. _Iris: https://github.com/SciTools/iris
17+
.. _ESMF: https://github.com/esmf-org/esmf
18+
.. _GitHub: https://github.com/SciTools-incubator/iris-esmf-regrid

esmf_regrid/_esmf_sdo.py

Lines changed: 28 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,14 @@ class GridInfo(SDO):
7979
This class holds information about lat-lon type grids. That is, grids
8080
defined by lists of latitude and longitude values for points/bounds
8181
(with respect to some coordinate reference system i.e. rotated pole).
82-
It contains methods for translating this information into ESMF objects.
83-
In particular, there are methods for representing as an ESMF Grid and
84-
as an ESMF Field containing that Grid. This ESMF Field is designed to
82+
It contains methods for translating this information into :mod:`ESMF` objects.
83+
In particular, there are methods for representing as a
84+
:class:`ESMF.api.grid.Grid` and
85+
as a :class:`ESMF.api.field.Field` containing that
86+
:class:`~ESMF.api.grid.Grid`. This ESMF :class:`~ESMF.api.field.Field`
87+
is designed to
8588
contain enough information for area weighted regridding and may be
86-
inappropriate for other ESMF regridding schemes.
89+
inappropriate for other :mod:`ESMF` regridding schemes.
8790
8891
"""
8992

@@ -98,31 +101,32 @@ def __init__(
98101
areas=None,
99102
):
100103
"""
101-
Create a GridInfo object describing the grid.
104+
Create a :class:`GridInfo` object describing the grid.
102105
103106
Parameters
104107
----------
105-
lons : array_like
106-
A 1D or 2D numpy array or list describing the longitudes of the
108+
lons : :obj:`~numpy.typing.ArrayLike`
109+
A 1D or 2D array or list describing the longitudes of the
107110
grid points.
108-
lats : array_like
109-
A 1D or 2D numpy array or list describing the latitudes of the
111+
lats : :obj:`~numpy.typing.ArrayLike`
112+
A 1D or 2D array or list describing the latitudes of the
110113
grid points.
111-
lonbounds : array_like
112-
A 1D or 2D numpy array or list describing the longitude bounds of
113-
the grid. Should have length one greater than lons.
114-
latbounds : array_like
115-
A 1D or 2D numpy array or list describing the latitude bounds of
116-
the grid. Should have length one greater than lats.
117-
crs : cartopy projection, optional
118-
None or a cartopy.crs projection describing how to interpret the
119-
above arguments. If None, defaults to Geodetic().
120-
circular : bool, optional
121-
A boolean value describing if the final longitude bounds should
122-
be considered contiguous with the first. Defaults to False.
123-
areas : array_line, optional
124-
either None or a numpy array describing the areas associated with
125-
each face. If None, then ESMF will use its own calculated areas.
114+
lonbounds : :obj:`~numpy.typing.ArrayLike`
115+
A 1D or 2D array or list describing the longitude bounds of
116+
the grid. Should have length one greater than ``lons``.
117+
latbounds : :obj:`~numpy.typing.ArrayLike`
118+
A 1D or 2D array or list describing the latitude bounds of
119+
the grid. Should have length one greater than ``lats``.
120+
crs : :class:`cartopy.crs.CRS`, optional
121+
Describes how to interpret the
122+
above arguments. If ``None``, defaults to :class:`~cartopy.crs.Geodetic`.
123+
circular : bool, default=False
124+
Describes if the final longitude bounds should
125+
be considered contiguous with the first.
126+
areas : :obj:`~numpy.typing.ArrayLike`, optional
127+
Array describing the areas associated with
128+
each face. If ``None``, then :mod:`ESMF` will use its own
129+
calculated areas.
126130
127131
"""
128132
self.lons = lons

esmf_regrid/esmf_regridder.py

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -50,30 +50,31 @@ def _weights_dict_to_sparse_array(weights, shape, index_offsets):
5050

5151

5252
class Regridder:
53-
"""Regridder for directly interfacing with ESMF."""
53+
"""Regridder for directly interfacing with :mod:`ESMF`."""
5454

5555
def __init__(self, src, tgt, precomputed_weights=None):
5656
"""
5757
Create a regridder from descriptions of horizontal grids/meshes.
5858
59-
Weights will be calculated using ESMF and stored as a scipy.sparse
60-
matrix for use in regridding. If precomputed weights are provided,
61-
these will be used instead of calculating via ESMF.
59+
Weights will be calculated using :mod:`ESMF` and stored as a
60+
:class:`scipy.sparse.csr_matrix`
61+
for use in regridding. If precomputed weights are provided,
62+
these will be used instead of calculating via :mod:`ESMF`.
6263
6364
Parameters
6465
----------
65-
src : object
66-
A MeshInfo or GridInfo object describing the source mesh/grid.
67-
Data supplied to this regridder should be in a numpy array
68-
whose shape is compatible with src.
69-
tgt : object
70-
A MeshInfo or GridInfo oject describing the target mesh/grid.
71-
Data output by this regridder will be a numpy array whose
72-
shape is compatible with tgt.
73-
precomputed_weights : sparse-matix object, optional
74-
None or a scipy.sparse matrix. If None, ESMF will be used to
75-
calculate regridding weights. Otherwise, ESMF will be bypassed
76-
and precomputed_weights will be used as the regridding weights.
66+
src : :class:`~esmf_regrid.experimental.unstructured_regrid.MeshInfo` or :class:`GridInfo`
67+
Describes the source mesh/grid.
68+
Data supplied to this regridder should be in a :class:`numpy.ndarray`
69+
whose shape is compatible with ``src``.
70+
tgt : :class:`~esmf_regrid.experimental.unstructured_regrid.MeshInfo` or :class:`GridInfo`
71+
Describes the target mesh/grid.
72+
Data output by this regridder will be a :class:`numpy.ndarray` whose
73+
shape is compatible with ``tgt``.
74+
precomputed_weights : :class:`scipy.sparse.spmatrix`, optional
75+
If ``None``, :mod:`ESMF` will be used to
76+
calculate regridding weights. Otherwise, :mod:`ESMF` will be bypassed
77+
and ``precomputed_weights`` will be used as the regridding weights.
7778
"""
7879
self.src = src
7980
self.tgt = tgt
@@ -111,26 +112,27 @@ def regrid(self, src_array, norm_type="fracarea", mdtol=1):
111112
112113
Parameters
113114
----------
114-
src_array : array_like
115-
A numpy array whose shape is compatible with self.src
116-
norm_type : string
117-
Either "fracarea" or "dstarea", defaults to "fracarea". Determines the
115+
src_array : :obj:`~numpy.typing.ArrayLike`
116+
Array whose shape is compatible with ``self.src``
117+
norm_type : str
118+
Either ``fracarea`` or ``dstarea``, defaults to ``fracarea``. Determines the
118119
type of normalisation applied to the weights. Normalisations correspond
119-
to ESMF constants ESMF.NormType.FRACAREA and ESMF.NormType.DSTAREA.
120-
mdtol : float, optional
120+
to :mod:`ESMF` constants :attr:`~ESMF.api.constants.NormType.FRACAREA` and
121+
:attr:`~ESMF.api.constants.NormType.DSTAREA`.
122+
mdtol : float, default=1
121123
A number between 0 and 1 describing the missing data tolerance.
122-
Depending on the value of `mdtol`, if a cell in the target grid is not
124+
Depending on the value of ``mdtol``, if a cell in the target grid is not
123125
sufficiently covered by unmasked cells of the source grid, then it will
124-
be masked. An `mdtol` of 1 means that only target cells which are not
125-
covered at all will be masked, an `mdtol` of 0 means that all target
126-
cells that are not entirely covered will be masked, and an `mdtol` of
127-
0.5 means that all target cells that are less than half covered will
126+
be masked. ``mdtol=1`` means that only target cells which are not
127+
covered at all will be masked, ``mdtol=0`` means that all target
128+
cells that are not entirely covered will be masked, and ``mdtol=0.5``
129+
means that all target cells that are less than half covered will
128130
be masked.
129131
130132
Returns
131133
-------
132-
array_like
133-
A numpy array whose shape is compatible with self.tgt.
134+
:obj:`~numpy.typing.ArrayLike`
135+
An array whose shape is compatible with ``self.tgt``.
134136
135137
"""
136138
array_shape = src_array.shape

0 commit comments

Comments
 (0)