Skip to content

Commit b9b45ee

Browse files
hdrakehfdrake
andauthored
Add docs (#23)
* Make license info in pyproject.toml consistent with MIT License * Add conda recipe and disable default conda channel * Add installation page * Add example notebook to RTD * Update Docs landing page. * Add badges to README.md * Switch to conda install --------- Co-authored-by: hfdrake <hfdrake@mac.lan>
1 parent fa73b03 commit b9b45ee

11 files changed

Lines changed: 280 additions & 7 deletions

File tree

.readthedocs.yaml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Read the Docs configuration file
2+
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
3+
4+
# Required
5+
version: 2
6+
7+
# Set the OS, Python version, and other tools you might need
8+
build:
9+
os: ubuntu-24.04
10+
tools:
11+
python: "miniforge3-latest"
12+
13+
# Build documentation in the "docs/" directory with Sphinx
14+
sphinx:
15+
builder: html
16+
configuration: docs/source/conf.py
17+
fail_on_warning: true
18+
19+
# Don't build any extra output files
20+
formats: []
21+
22+
python:
23+
install:
24+
- method: pip
25+
path: .
26+
27+
conda:
28+
environment: docs/environment.yml

README.md

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1-
# xbudget
2-
Helper functions and meta-data conventions for wrangling finite-volume ocean model budgets.
1+
xbudget: easy handling of budgets diagnosed from General Circulation Models with xarray
2+
=========================
33

4-
Quick Start Guide
5-
-----------------
4+
[![PyPI](https://badge.fury.io/py/xbudget.svg)](https://badge.fury.io/py/xbudget)
5+
[![Conda Version](https://img.shields.io/conda/vn/conda-forge/xbudget)](https://anaconda.org/conda-forge/xbudget)
6+
[![Docs](https://readthedocs.org/projects/xbudget/badge/?version=latest)](https://xbudget.readthedocs.io/en/latest/)
7+
[![License](https://img.shields.io/github/license/hdrake/xbudget)](https://github.com/hdrake/xbudget)
68

9+
## Quick Start Guide
710
**For users: minimal installation within an existing environment**
811
```bash
9-
pip install xbudget
12+
conda install xbudget
1013
```
1114

1215
**For developers: installing from scratch using `conda`**
@@ -18,4 +21,4 @@ conda activate docs_env_xbudget
1821
pip install -e .
1922
python -m ipykernel install --user --name docs_env_xbudget --display-name "docs_env_xbudget"
2023
jupyter-lab
21-
```
24+
```

docs/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 = source
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/environment.yml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@ name: docs_env_xbudget
22
channels:
33
- conda-forge
44
dependencies:
5-
- python==3.12
5+
- python=3.12
66
- cftime
77
- ipython
88
- jupyterlab
99
- matplotlib
1010
- netcdf4
1111
- pydap
1212
- pytest
13+
- sphinx
14+
- nbsphinx
15+
- ipykernel
1316
- pip

docs/make.bat

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
@ECHO OFF
2+
3+
pushd %~dp0
4+
5+
REM Command file for Sphinx documentation
6+
7+
if "%SPHINXBUILD%" == "" (
8+
set SPHINXBUILD=sphinx-build
9+
)
10+
set SOURCEDIR=source
11+
set BUILDDIR=build
12+
13+
%SPHINXBUILD% >NUL 2>NUL
14+
if errorlevel 9009 (
15+
echo.
16+
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
17+
echo.installed, then set the SPHINXBUILD environment variable to point
18+
echo.to the full path of the 'sphinx-build' executable. Alternatively you
19+
echo.may add the Sphinx directory to PATH.
20+
echo.
21+
echo.If you don't have Sphinx installed, grab it from
22+
echo.https://www.sphinx-doc.org/
23+
exit /b 1
24+
)
25+
26+
if "%1" == "" goto help
27+
28+
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
29+
goto end
30+
31+
:help
32+
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
33+
34+
:end
35+
popd

docs/source/_static/.gitkeep

Whitespace-only changes.

docs/source/_static/custom.css

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/* Responsive layout widening for Alabaster
2+
- On small screens: use full width (with padding)
3+
- On typical laptops: ~1100–1250px content area
4+
- On big screens: cap so lines don't get absurdly long
5+
*/
6+
7+
div.document {
8+
/* Total doc block width (sidebar + content) */
9+
width: min(96vw, 1400px);
10+
margin: 0 auto;
11+
}
12+
13+
/* Keep the main content comfortable: cap line length */
14+
div.body {
15+
/* body width within the document area */
16+
max-width: 900px;
17+
}
18+
19+
/* Give the sidebar a stable width; let it wrap below on small screens */
20+
div.sphinxsidebar {
21+
width: 270px;
22+
}
23+
24+
/* On narrower screens, don't force sidebar + body side-by-side */
25+
@media (max-width: 900px) {
26+
div.document {
27+
width: 96vw;
28+
}
29+
div.sphinxsidebar {
30+
float: none;
31+
width: auto;
32+
}
33+
div.bodywrapper {
34+
margin: 0;
35+
}
36+
div.body {
37+
max-width: none;
38+
}
39+
}

docs/source/_templates/.gitkeep

Whitespace-only changes.

docs/source/conf.py

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# Configuration file for the Sphinx documentation builder.
2+
#
3+
# For the full list of built-in configuration values, see the documentation:
4+
# https://www.sphinx-doc.org/en/master/usage/configuration.html
5+
6+
from importlib.metadata import version as get_version
7+
from pathlib import Path
8+
import shutil
9+
10+
# The master toctree document.
11+
master_doc = "index"
12+
13+
# -- Project information -----------------------------------------------------
14+
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
15+
16+
17+
project = 'xbudget'
18+
copyright = '2026, Henri Drake'
19+
author = 'Henri Drake'
20+
21+
release = get_version(project)
22+
version = ".".join(release.split(".")[:2])
23+
24+
# -- General configuration ---------------------------------------------------
25+
# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
26+
27+
extensions = [
28+
"nbsphinx"
29+
]
30+
31+
templates_path = ['_templates']
32+
exclude_patterns = []
33+
34+
# Don't execute notebooks on RTD unless you want that
35+
nbsphinx_execute = "never"
36+
37+
# -- Copy notebooks from repo root/examples into docs/source/examples --------
38+
39+
HERE = Path(__file__).resolve()
40+
DOCS_SOURCE = HERE.parent # docs/source
41+
REPO_ROOT = HERE.parents[2] # up two levels from conf.py
42+
EXAMPLES_SRC = REPO_ROOT / "examples"
43+
EXAMPLES_DST = DOCS_SOURCE / "examples"
44+
45+
def _sync_examples():
46+
if not EXAMPLES_SRC.exists():
47+
return
48+
49+
# fresh copy so removed notebooks don't linger
50+
if EXAMPLES_DST.exists():
51+
shutil.rmtree(EXAMPLES_DST)
52+
EXAMPLES_DST.mkdir(parents=True, exist_ok=True)
53+
54+
for nb in EXAMPLES_SRC.rglob("*.ipynb"):
55+
rel = nb.relative_to(EXAMPLES_SRC)
56+
out = EXAMPLES_DST / rel
57+
out.parent.mkdir(parents=True, exist_ok=True)
58+
shutil.copy2(nb, out)
59+
60+
_sync_examples()
61+
62+
# -- Options for HTML output -------------------------------------------------
63+
# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
64+
65+
html_title = f"{project} v{version} documentation"
66+
67+
html_theme = "alabaster"
68+
69+
html_theme_options = {
70+
"sidebar_width": "270px",
71+
}
72+
73+
html_static_path = ["_static"]
74+
html_css_files = ["custom.css"]
75+
76+
latex_documents = [
77+
("index")
78+
]

docs/source/index.rst

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
2+
xbudget: easy handling of budgets diagnosed from General Circulation Models with xarray
3+
========================================================================================
4+
5+
**xbudget** is a python package that facilitates the handling of budget diagnostics for finite-volume General Circulation Models (currently only supporting structured grids).
6+
7+
xbudget expects budgets which have a Left-Hand Side (LHS) equal to a Right-Hand Side (RHS), typically in one of the following two forms:
8+
9+
.. math::
10+
\frac{\partial}{\partial t} \int \rho \lambda \, dV = \int \left[ - \nabla \cdot \left( \mathbf{F}_{\lambda} + \rho \lambda \mathbf{u} \right) \right] \, dV
11+
12+
where :math:`\lambda` is the property density (or tracer concentration), :math:`\mathbf{u}` is the flow velocity, and :math:`\mathbf{F}_{\lambda}` is the sum of all non-advective fluxes of :math:`\lambda`.
13+
14+
xbudget ingests an `xgcm.Grid` object containing the budget diagnostics and uses structured metadata, in the form of a nested dictionary (or `.yaml` file), to close such budgets. While this may seem trivial for use cases in which there is a single flux to keep track of, total non-advective fluxes in general circulation models can be composed of dozens of contributing processes. Since budget diagnostics are often not output as volume-integrated tendencies, xbudget allows for terms to be derived as sums, products, or differences (or some combination of these). For example, ocean heat tendency due to air-sea heat fluxes might be derived from the difference between vertical heat fluxes across depth interfaces, summed over longwave, shortwave, sensible, and latent components of the flux, and multiplied by the ocean cell area.
15+
16+
While drafting a `.yaml` file from scratch for a new model can be daunting, it only needs to be done once -- then closing budgets is a breeze!
17+
18+
.. toctree::
19+
:maxdepth: 2
20+
:caption: Contents:
21+
22+
installation
23+
examples/MOM6_budget_examples_mass_heat_salt

0 commit comments

Comments
 (0)