Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 4 additions & 9 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
@@ -1,24 +1,19 @@
# .readthedocs.yaml
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details

# Required
version: 2

build:
os: ubuntu-20.04
os: "ubuntu-24.04"
tools:
python: "mambaforge-4.10"
python: "miniconda3-3.12-24.9"

sphinx:
configuration: docs/conf.py
fail_on_warning: true

conda:
environment: environment.yml
environment: docs/environment.yaml

python:
# Install our python package before building the docs so setuptools-scm generates the version for RTD to find.
# Install our python package before building the docs
install:
- method: pip
path: .
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
[![Logo](https://img.shields.io/badge/OSMF-OpenFreeEnergy-%23002f4a)](https://openfree.energy/)
[![CI](https://github.com/OpenFreeEnergy/openfe_analysis/actions/workflows/ci.yaml/badge.svg)](https://github.com/OpenFreeEnergy/openfe_analysis/actions/workflows/ci.yaml)
[![Coverage](https://codecov.io/gh/OpenFreeEnergy/openfe_analysis/graph/badge.svg?token=krb231ftki)](https://codecov.io/gh/OpenFreeEnergy/openfe_analysis)
[![documentation](https://readthedocs.org/projects/openfe_analysis/badge/?version=stable)](https://openfe_analysis.openfree.energy/en/stable/?badge=stable)
[![Powered by MDAnalysis](https://img.shields.io/badge/powered%20by-MDAnalysis-orange.svg?logoWidth=16&logo=data:image/x-icon;base64,AAABAAEAEBAAAAEAIAAoBAAAFgAAACgAAAAQAAAAIAAAAAEAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJD+XwCY/fEAkf3uAJf97wGT/a+HfHaoiIWE7n9/f+6Hh4fvgICAjwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACT/yYAlP//AJ///wCg//8JjvOchXly1oaGhv+Ghob/j4+P/39/f3IAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAJH8aQCY/8wAkv2kfY+elJ6al/yVlZX7iIiI8H9/f7h/f38UAAAAAAAAAAAAAAAAAAAAAAAAAAB/f38egYF/noqAebF8gYaagnx3oFpUUtZpaWr/WFhY8zo6OmT///8BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgICAn46Ojv+Hh4b/jouJ/4iGhfcAAADnAAAA/wAAAP8AAADIAAAAAwCj/zIAnf2VAJD/PAAAAAAAAAAAAAAAAICAgNGHh4f/gICA/4SEhP+Xl5f/AwMD/wAAAP8AAAD/AAAA/wAAAB8Aov9/ALr//wCS/Z0AAAAAAAAAAAAAAACBgYGOjo6O/4mJif+Pj4//iYmJ/wAAAOAAAAD+AAAA/wAAAP8AAABhAP7+FgCi/38Axf4fAAAAAAAAAAAAAAAAiIiID4GBgYKCgoKogoB+fYSEgZhgYGDZXl5e/m9vb/9ISEjpEBAQxw8AAFQAAAAAAAAANQAAADcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAjo6Mb5iYmP+cnJz/jY2N95CQkO4pKSn/AAAA7gAAAP0AAAD7AAAAhgAAAAEAAAAAAAAAAACL/gsAkv2uAJX/QQAAAAB9fX3egoKC/4CAgP+NjY3/c3Nz+wAAAP8AAAD/AAAA/wAAAPUAAAAcAAAAAAAAAAAAnP4NAJL9rgCR/0YAAAAAfX19w4ODg/98fHz/i4uL/4qKivwAAAD/AAAA/wAAAP8AAAD1AAAAGwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALGxsVyqqqr/mpqa/6mpqf9KSUn/AAAA5QAAAPkAAAD5AAAAhQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADkUFBSuZ2dn/3V1df8uLi7bAAAATgBGfyQAAAA2AAAAMwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB0AAADoAAAA/wAAAP8AAAD/AAAAWgC3/2AAnv3eAJ/+dgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA9AAAA/wAAAP8AAAD/AAAA/wAKDzEAnP3WAKn//wCS/OgAf/8MAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIQAAANwAAADtAAAA7QAAAMAAABUMAJn9gwCe/e0Aj/2LAP//AQAAAAAAAAAA)](https://www.mdanalysis.org)

## Quickstart
Expand Down
1 change: 1 addition & 0 deletions docs/ExampleNotebooks
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove?

Submodule ExampleNotebooks added at cef045
20 changes: 20 additions & 0 deletions docs/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 ?= -v -W --keep-going
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)
86 changes: 86 additions & 0 deletions docs/_ext/sass.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
"""
sphinxcontrib-sass
https://github.com/attakei-lab/sphinxcontrib-sass
Kayuza Takei
Apache 2.0

Modified to:
- Write directly to Sphinx output directory
- Infer targets if not given
- Ensure ``target: Path`` in ``configure_path()``
- Return version number and thread safety from ``setup()``
- Use compressed style by default
- More complete type checking
"""

from os import PathLike
from pathlib import Path
from typing import Optional, Union

import sass
from sphinx.application import Sphinx
from sphinx.environment import BuildEnvironment
from sphinx.util import logging

logger = logging.getLogger(__name__)


def configure_path(conf_dir: str, src: Optional[Union[PathLike, Path]]) -> Path:
if src is None:
target = Path(conf_dir)
else:
target = Path(src)
if not target.is_absolute():
target = Path(conf_dir) / target
return target


def get_targets(app: Sphinx) -> dict[Path, Path]:
src_dir = configure_path(app.confdir, app.config.sass_src_dir)
dst_dir = configure_path(app.outdir, app.config.sass_out_dir)

if isinstance(app.config.sass_targets, dict):
targets = app.config.sass_targets
else:
targets = {
path: path.relative_to(src_dir).with_suffix(".css")
for path in src_dir.glob("**/[!_]*.s[ca]ss")
}

return {src_dir / src: dst_dir / dst for src, dst in targets.items()}


def build_sass_sources(app: Sphinx, env: BuildEnvironment):
logger.debug("Building stylesheet files")
include_paths = [str(p) for p in app.config.sass_include_paths]
targets = get_targets(app)
output_style = app.config.sass_output_style
# Build css files
for src, dst in targets.items():
content = src.read_text()
css = sass.compile(
string=content,
output_style=output_style,
include_paths=[str(src.parent)] + include_paths,
)
dst.parent.mkdir(exist_ok=True, parents=True)
dst.write_text(css)


def setup(app: Sphinx):
"""
Setup function for this extension.
"""
logger.debug(f"Using {__name__}")
app.add_config_value("sass_include_paths", [], "html")
app.add_config_value("sass_src_dir", None, "html")
app.add_config_value("sass_out_dir", None, "html")
app.add_config_value("sass_targets", None, "html")
app.add_config_value("sass_output_style", "compressed", "html")
app.connect("env-updated", build_sass_sources)

return {
"version": "0.3.4ofe",
"parallel_read_safe": True,
"parallel_write_safe": True,
}
167 changes: 167 additions & 0 deletions docs/conf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html

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

# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
import os
import sys
from importlib.metadata import version
from inspect import cleandoc
from pathlib import Path

import git
import nbformat
import nbsphinx
from packaging.version import parse

sys.path.insert(0, os.path.abspath("../"))


os.environ["SPHINX"] = "True"

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

project = "OpenFE Analysis"
copyright = "2026, The OpenFE Development Team"
author = "The OpenFE Development Team"
version = f"{parse(version('openfe_analysis')).major}.{parse(version('openfe_analysis')).minor}"

# -- 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.ext.napoleon",
"sphinx_click.ext",
"sphinxcontrib.autodoc_pydantic",
"sphinx_toolbox.collapse",
"sphinx.ext.autosectionlabel",
"sphinx_design",
"sphinx.ext.intersphinx",
"sphinx.ext.autosummary",
"docs._ext.sass",
"myst_parser",
"nbsphinx",
"nbsphinx_link",
"sphinx.ext.mathjax",
]
suppress_warnings = ["config.cache"] # https://github.com/sphinx-doc/sphinx/issues/12300

intersphinx_mapping = {
"python": ("https://docs.python.org/3.9", None),
"numpy": ("https://numpy.org/doc/stable", None),
"scikit.learn": ("https://scikit-learn.org/stable", None),
"openmm": ("https://docs.openmm.org/latest/api-python/", None),
"rdkit": ("https://www.rdkit.org/docs", None),
"openeye": ("https://docs.eyesopen.com/toolkits/python/", None),
"mdtraj": ("https://www.mdtraj.org/1.9.5/", None),
"openff.units": ("https://docs.openforcefield.org/projects/units/en/stable", None),
"gufe": ("https://gufe.openfree.energy/en/latest/", None),
}

autoclass_content = "both"
# Make sure labels are unique
# https://www.sphinx-doc.org/en/master/usage/extensions/autosectionlabel.html#confval-autosectionlabel_prefix_document
autosectionlabel_prefix_document = True

autodoc_pydantic_model_show_json = False

autodoc_default_options = {
"members": True,
"member-order": "bysource",
"inherited-members": "GufeTokenizable,BaseModel",
"undoc-members": True,
"special-members": "__call__",
}
toc_object_entries_show_parents = "hide"

# 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",
"_ext",
"_sass",
"**/README.md",
"ExampleNotebooks",
]

autodoc_mock_imports = [
"MDAnalysis",
]

# Extensions for the myst parser
myst_enable_extensions = [
"dollarmath",
"colon_fence",
"smartquotes",
"replacements",
"deflist",
"attrs_inline",
]
myst_heading_anchors = 3

# -- 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 = "ofe_sphinx_theme"
html_theme_options = {
"logo": {"text": "openfe-analysis docs"},
"icon_links": [
{
"name": "GitHub",
"url": "https://github.com/OpenFreeEnergy/openfe_analysis",
"icon": "fa-brands fa-square-github",
"type": "fontawesome",
}
],
"accent_color": "cantina-purple",
"navigation_with_keys": False,
}
html_logo = "_static/OFE-color-icon.svg"
html_favicon = "_static/OFE-color-icon.svg"
# temporary fix, see https://github.com/pydata/pydata-sphinx-theme/issues/1662
html_sidebars = {
"installation": [],
"CHANGELOG": [],
}
# 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']


# replace macros
rst_prolog = """
.. |rdkit.mol| replace:: :class:`rdkit.Chem.rdchem.Mol`
"""

# 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"]
html_css_files = [
"css/custom.css",
"css/custom-api.css",
"css/deflist-flowchart.css",
]

# custom-api.css is compiled from custom-api.scss
sass_src_dir = "_sass"
sass_out_dir = "_static/css"
36 changes: 36 additions & 0 deletions docs/environment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
name: openfe_analysis-docs
channels:
- https://conda.anaconda.org/conda-forge

# explicit pins to speed up build:
dependencies:
- autodoc-pydantic >= 2.1
- docutils == 0.20
- gitpython
- libsass
- myst-parser
- nbsphinx
- nbsphinx-link
- openff-toolkit-base == 0.17.0
- openff-units == 0.3.1
- packaging
- pip
- plugcli >= 0.2.1
- python
- pydantic >=2.0.0, <2.12.0 # https://github.com/openforcefield/openff-interchange/issues/1346
- sphinx ==7.2.6 # TODO: debug "duplicate object" warning with later versions
- sphinx-click
- sphinx-design
- sphinx-toolbox
- threadpoolctl
- tqdm
- pip:
- git+https://github.com/OpenFreeEnergy/ofe-sphinx-theme@v0.3.1
# pip install these so that we can make sure docs build on main while these packages' docs are under development

# These are added automatically by RTD, so we include them here
# for a consistent environment.
- mock
- pillow
# - sphinx
# - sphinx_rtd_theme
16 changes: 16 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
.. template taken from SciPy who took it from Pandas (keep the chain going)

.. module:: openfe_analysis

==========================================
Welcome to OpenFE Analysis' documentation!
==========================================

The **OpenFE Analysis** toolkit provides a free and open-source framework for analyzing alchemical free energy calculations.


.. toctree::
:maxdepth: 2
:hidden:

api
Loading
Loading