Skip to content

Commit

Permalink
Automatic API Documentation (#155)
Browse files Browse the repository at this point in the history
* 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.
  • Loading branch information
trexfeathers committed Feb 23, 2022
1 parent 1aa8052 commit f0e2259
Show file tree
Hide file tree
Showing 16 changed files with 454 additions and 217 deletions.
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,10 @@ instance/
.scrapy

# Sphinx documentation
docs/_build/
docs/src/_api_generated/
docs/src/_build/
docs/src/_static/
docs/src/_templates/

# PyBuilder
target/
Expand Down
18 changes: 18 additions & 0 deletions .readthedocs.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
version: 2

build:
os: ubuntu-20.04
tools:
python: mambaforge-4.10

conda:
environment: requirements/dev.yml

sphinx:
configuration: docs/src/conf.py
fail_on_warning: false

python:
install:
- method: setuptools
path: .
3 changes: 3 additions & 0 deletions docs/src/CHANGELOG.md → CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ This release added the ability to regrid data stored on a UGRID mesh.
[PR#137](https://github.com/SciTools-incubator/iris-esmf-regrid/pull/137)
Added functions for saving of the unstructured regridders.
[@stephenworsley](https://github.com/stephenworsley)
- [PR#155](https://github.com/SciTools-incubator/iris-esmf-regrid/pull/155)
Enabled Sphinx and RTD for automatically rendering the API.
[@trexfeathers](https://github.com/trexfeathers)

## [0.3] - 2021-12-21

Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
BSD 3-Clause License

Copyright (c) 2020, SciTools-incubator
Copyright (c) 2020 - 2022, SciTools-incubator
All rights reserved.

Redistribution and use in source and binary forms, with or without
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

---

[Click here for the API documentation](https://iris-esmf-regrid.readthedocs.io/en/latest)

## Overview

This project aims to provide a bridge between [Iris](https://github.com/SciTools/iris)
Expand Down
20 changes: 20 additions & 0 deletions docs/src/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Minimal makefile for Sphinx documentation
#

# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?=
SPHINXBUILD ?= sphinx-build
SOURCEDIR = .
BUILDDIR = _build

# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

.PHONY: help Makefile

# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
135 changes: 135 additions & 0 deletions docs/src/conf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
"""
Configuration file for the Sphinx documentation builder.
Created originally using sphinx-quickstart on 2022-02-21.
"""

from datetime import datetime
from pathlib import Path
import sys

# -- Path setup --------------------------------------------------------------

# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here - **using absolute paths**.

source_code_root = (Path(__file__).parents[2]).absolute()
sys.path.append(str(source_code_root))


# -- Project information -----------------------------------------------------

from esmf_regrid import __version__ as esmf_r_version

copyright_years = f"2020 - {datetime.now().year}"

project = "iris-esmf-regrid"
copyright = f"{copyright_years}, SciTools-incubator"
author = "iris-esmf-regrid Contributors"

# The full version, including alpha/beta/rc tags
release = esmf_r_version


# -- General configuration ---------------------------------------------------

# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
"sphinx.ext.autodoc",
"sphinx_copybutton",
"sphinx.ext.extlinks",
"sphinx.ext.intersphinx",
"sphinx.ext.napoleon",
"sphinx.ext.todo",
"sphinx.ext.viewcode",
"sphinxcontrib.apidoc",
]

# Add any paths that contain templates here, relative to this directory.
templates_path = ["_templates"]

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]


# -- Options for HTML output -------------------------------------------------

# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = "pydata_sphinx_theme"

html_theme_options = {
"github_url": "https://github.com/SciTools-incubator/iris-esmf-regrid",
"show_prev_next": False,
"icon_links": [
{
"name": "Support",
"url": "https://github.com/SciTools-incubator/iris-esmf-regrid/discussions",
"icon": "fa fa-comments fa-fw",
}
],
}


# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ["_static"]


# -- api generation configuration ---------------------------------------------
autoclass_content = "both"
autodoc_typehints = "none"
modindex_common_prefix = ["esmf_regrid"]


# -- copybutton extension -----------------------------------------------------
# See https://sphinx-copybutton.readthedocs.io/en/latest/
copybutton_prompt_text = r">>> |\.\.\. "
copybutton_prompt_is_regexp = True
copybutton_line_continuation_character = "\\"


# -- extlinks extension -------------------------------------------------------
# See https://www.sphinx-doc.org/en/master/usage/extensions/extlinks.html

extlinks = {
"issue": (
"https://github.com/SciTools-incubator/iris-esmf-regrid/issues/%s",
"Issue #",
),
"pull": ("https://github.com/SciTools-incubator/iris-esmf-regrid/pull/%s", "PR #"),
}


# -- intersphinx extension ----------------------------------------------------
# See https://www.sphinx-doc.org/en/master/usage/extensions/intersphinx.html
intersphinx_mapping = {
"iris": ("https://scitools-iris.readthedocs.io/en/latest/", None),
"cartopy": ("https://scitools.org.uk/cartopy/docs/latest/", None),
"numpy": ("https://numpy.org/doc/stable/", None),
"python": ("https://docs.python.org/3/", None),
"scipy": ("https://docs.scipy.org/doc/scipy/", None),
"ESMF": ("https://earthsystemmodeling.org/esmpy_doc/release/latest/html/", None),
}


# -- todo_ extension ----------------------------------------------------------
# See https://www.sphinx-doc.org/en/master/usage/extensions/todo.html
todo_include_todos = True


# -- apidoc extension ---------------------------------------------------------
# See https://github.com/sphinx-contrib/apidoc
module_dir = source_code_root / "esmf_regrid"

apidoc_module_dir = str(module_dir)
apidoc_output_dir = str(Path(__file__).parent / "_api_generated")
apidoc_excluded_paths = [str(module_dir / "tests")]
apidoc_separate_modules = True
apidoc_extra_args = ["-H", "API"]
18 changes: 18 additions & 0 deletions docs/src/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
iris-esmf-regrid
================

A collection of structured and unstructured ESMF_ regridding schemes for Iris_.

This rendered documentation is so far limited to iris-esmf-regrid's API. Some
basic examples and change logs can be found on GitHub_.

:doc:`Click to view the API<_api_generated/modules>`

.. toctree::
:hidden:

_api_generated/modules

.. _Iris: https://github.com/SciTools/iris
.. _ESMF: https://github.com/esmf-org/esmf
.. _GitHub: https://github.com/SciTools-incubator/iris-esmf-regrid
52 changes: 28 additions & 24 deletions esmf_regrid/_esmf_sdo.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,14 @@ class GridInfo(SDO):
This class holds information about lat-lon type grids. That is, grids
defined by lists of latitude and longitude values for points/bounds
(with respect to some coordinate reference system i.e. rotated pole).
It contains methods for translating this information into ESMF objects.
In particular, there are methods for representing as an ESMF Grid and
as an ESMF Field containing that Grid. This ESMF Field is designed to
It contains methods for translating this information into :mod:`ESMF` objects.
In particular, there are methods for representing as a
:class:`ESMF.api.grid.Grid` and
as a :class:`ESMF.api.field.Field` containing that
:class:`~ESMF.api.grid.Grid`. This ESMF :class:`~ESMF.api.field.Field`
is designed to
contain enough information for area weighted regridding and may be
inappropriate for other ESMF regridding schemes.
inappropriate for other :mod:`ESMF` regridding schemes.
"""

Expand All @@ -98,31 +101,32 @@ def __init__(
areas=None,
):
"""
Create a GridInfo object describing the grid.
Create a :class:`GridInfo` object describing the grid.
Parameters
----------
lons : array_like
A 1D or 2D numpy array or list describing the longitudes of the
lons : :obj:`~numpy.typing.ArrayLike`
A 1D or 2D array or list describing the longitudes of the
grid points.
lats : array_like
A 1D or 2D numpy array or list describing the latitudes of the
lats : :obj:`~numpy.typing.ArrayLike`
A 1D or 2D array or list describing the latitudes of the
grid points.
lonbounds : array_like
A 1D or 2D numpy array or list describing the longitude bounds of
the grid. Should have length one greater than lons.
latbounds : array_like
A 1D or 2D numpy array or list describing the latitude bounds of
the grid. Should have length one greater than lats.
crs : cartopy projection, optional
None or a cartopy.crs projection describing how to interpret the
above arguments. If None, defaults to Geodetic().
circular : bool, optional
A boolean value describing if the final longitude bounds should
be considered contiguous with the first. Defaults to False.
areas : array_line, optional
either None or a numpy array describing the areas associated with
each face. If None, then ESMF will use its own calculated areas.
lonbounds : :obj:`~numpy.typing.ArrayLike`
A 1D or 2D array or list describing the longitude bounds of
the grid. Should have length one greater than ``lons``.
latbounds : :obj:`~numpy.typing.ArrayLike`
A 1D or 2D array or list describing the latitude bounds of
the grid. Should have length one greater than ``lats``.
crs : :class:`cartopy.crs.CRS`, optional
Describes how to interpret the
above arguments. If ``None``, defaults to :class:`~cartopy.crs.Geodetic`.
circular : bool, default=False
Describes if the final longitude bounds should
be considered contiguous with the first.
areas : :obj:`~numpy.typing.ArrayLike`, optional
Array describing the areas associated with
each face. If ``None``, then :mod:`ESMF` will use its own
calculated areas.
"""
self.lons = lons
Expand Down
60 changes: 31 additions & 29 deletions esmf_regrid/esmf_regridder.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,30 +50,31 @@ def _weights_dict_to_sparse_array(weights, shape, index_offsets):


class Regridder:
"""Regridder for directly interfacing with ESMF."""
"""Regridder for directly interfacing with :mod:`ESMF`."""

def __init__(self, src, tgt, precomputed_weights=None):
"""
Create a regridder from descriptions of horizontal grids/meshes.
Weights will be calculated using ESMF and stored as a scipy.sparse
matrix for use in regridding. If precomputed weights are provided,
these will be used instead of calculating via ESMF.
Weights will be calculated using :mod:`ESMF` and stored as a
:class:`scipy.sparse.csr_matrix`
for use in regridding. If precomputed weights are provided,
these will be used instead of calculating via :mod:`ESMF`.
Parameters
----------
src : object
A MeshInfo or GridInfo object describing the source mesh/grid.
Data supplied to this regridder should be in a numpy array
whose shape is compatible with src.
tgt : object
A MeshInfo or GridInfo oject describing the target mesh/grid.
Data output by this regridder will be a numpy array whose
shape is compatible with tgt.
precomputed_weights : sparse-matix object, optional
None or a scipy.sparse matrix. If None, ESMF will be used to
calculate regridding weights. Otherwise, ESMF will be bypassed
and precomputed_weights will be used as the regridding weights.
src : :class:`~esmf_regrid.experimental.unstructured_regrid.MeshInfo` or :class:`GridInfo`
Describes the source mesh/grid.
Data supplied to this regridder should be in a :class:`numpy.ndarray`
whose shape is compatible with ``src``.
tgt : :class:`~esmf_regrid.experimental.unstructured_regrid.MeshInfo` or :class:`GridInfo`
Describes the target mesh/grid.
Data output by this regridder will be a :class:`numpy.ndarray` whose
shape is compatible with ``tgt``.
precomputed_weights : :class:`scipy.sparse.spmatrix`, optional
If ``None``, :mod:`ESMF` will be used to
calculate regridding weights. Otherwise, :mod:`ESMF` will be bypassed
and ``precomputed_weights`` will be used as the regridding weights.
"""
self.src = src
self.tgt = tgt
Expand Down Expand Up @@ -111,26 +112,27 @@ def regrid(self, src_array, norm_type="fracarea", mdtol=1):
Parameters
----------
src_array : array_like
A numpy array whose shape is compatible with self.src
norm_type : string
Either "fracarea" or "dstarea", defaults to "fracarea". Determines the
src_array : :obj:`~numpy.typing.ArrayLike`
Array whose shape is compatible with ``self.src``
norm_type : str
Either ``fracarea`` or ``dstarea``, defaults to ``fracarea``. Determines the
type of normalisation applied to the weights. Normalisations correspond
to ESMF constants ESMF.NormType.FRACAREA and ESMF.NormType.DSTAREA.
mdtol : float, optional
to :mod:`ESMF` constants :attr:`~ESMF.api.constants.NormType.FRACAREA` and
:attr:`~ESMF.api.constants.NormType.DSTAREA`.
mdtol : float, default=1
A number between 0 and 1 describing the missing data tolerance.
Depending on the value of `mdtol`, if a cell in the target grid is not
Depending on the value of ``mdtol``, if a cell in the target grid is not
sufficiently covered by unmasked cells of the source grid, then it will
be masked. An `mdtol` of 1 means that only target cells which are not
covered at all will be masked, an `mdtol` of 0 means that all target
cells that are not entirely covered will be masked, and an `mdtol` of
0.5 means that all target cells that are less than half covered will
be masked. ``mdtol=1`` means that only target cells which are not
covered at all will be masked, ``mdtol=0`` means that all target
cells that are not entirely covered will be masked, and ``mdtol=0.5``
means that all target cells that are less than half covered will
be masked.
Returns
-------
array_like
A numpy array whose shape is compatible with self.tgt.
:obj:`~numpy.typing.ArrayLike`
An array whose shape is compatible with ``self.tgt``.
"""
array_shape = src_array.shape
Expand Down

0 comments on commit f0e2259

Please sign in to comment.