From 2af70079d86f9218462139feb5f96204414588d4 Mon Sep 17 00:00:00 2001 From: Irfan Alibay Date: Wed, 5 Feb 2025 23:36:37 +0000 Subject: [PATCH] Add docs (#37) * Add docs --- .readthedocs.yaml | 19 +++ docs/Makefile | 20 +++ docs/_ext/sass.py | 88 +++++++++++++ docs/_static/API.svg | 1 + docs/_static/CLI.svg | 1 + docs/_static/Cookbook.svg | 1 + docs/_static/Download.svg | 1 + docs/_static/Rocket.svg | 1 + docs/_static/Showcase.svg | 75 ++++++++++++ docs/_static/Squaredcircle.svg | 21 ++++ docs/_static/Tutorial.svg | 1 + docs/_static/UserGuide.svg | 1 + docs/_templates/README.md | 14 +++ docs/api.rst | 9 ++ docs/api/protocols/asfe_protocol.rst | 40 ++++++ docs/api/protocols/index.rst | 10 ++ docs/conf.py | 177 +++++++++++++++++++++++++++ docs/environment.yaml | 28 +++++ docs/getting_started.rst | 19 +++ docs/index.rst | 23 ++++ docs/make.bat | 36 ++++++ 21 files changed, 586 insertions(+) create mode 100644 .readthedocs.yaml create mode 100644 docs/Makefile create mode 100644 docs/_ext/sass.py create mode 100644 docs/_static/API.svg create mode 100644 docs/_static/CLI.svg create mode 100644 docs/_static/Cookbook.svg create mode 100644 docs/_static/Download.svg create mode 100644 docs/_static/Rocket.svg create mode 100644 docs/_static/Showcase.svg create mode 100644 docs/_static/Squaredcircle.svg create mode 100644 docs/_static/Tutorial.svg create mode 100644 docs/_static/UserGuide.svg create mode 100644 docs/_templates/README.md create mode 100644 docs/api.rst create mode 100644 docs/api/protocols/asfe_protocol.rst create mode 100644 docs/api/protocols/index.rst create mode 100644 docs/conf.py create mode 100644 docs/environment.yaml create mode 100644 docs/getting_started.rst create mode 100644 docs/index.rst create mode 100644 docs/make.bat diff --git a/.readthedocs.yaml b/.readthedocs.yaml new file mode 100644 index 0000000..4f34320 --- /dev/null +++ b/.readthedocs.yaml @@ -0,0 +1,19 @@ +version: 2 + +build: + os: "ubuntu-24.04" + tools: + python: "mambaforge-4.10" + +sphinx: + configuration: docs/conf.py + fail_on_warning: true + +conda: + environment: docs/environment.yaml + +python: + # Install our python package before building the docs + install: + - method: pip + path: . diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..3d51b09 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +SPHINXPROJ = pontibus +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) diff --git a/docs/_ext/sass.py b/docs/_ext/sass.py new file mode 100644 index 0000000..43888aa --- /dev/null +++ b/docs/_ext/sass.py @@ -0,0 +1,88 @@ +""" +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, + } diff --git a/docs/_static/API.svg b/docs/_static/API.svg new file mode 100644 index 0000000..9c2cb31 --- /dev/null +++ b/docs/_static/API.svg @@ -0,0 +1 @@ + diff --git a/docs/_static/CLI.svg b/docs/_static/CLI.svg new file mode 100644 index 0000000..3d170a9 --- /dev/null +++ b/docs/_static/CLI.svg @@ -0,0 +1 @@ + diff --git a/docs/_static/Cookbook.svg b/docs/_static/Cookbook.svg new file mode 100644 index 0000000..d2f72b4 --- /dev/null +++ b/docs/_static/Cookbook.svg @@ -0,0 +1 @@ + diff --git a/docs/_static/Download.svg b/docs/_static/Download.svg new file mode 100644 index 0000000..3e425ca --- /dev/null +++ b/docs/_static/Download.svg @@ -0,0 +1 @@ + diff --git a/docs/_static/Rocket.svg b/docs/_static/Rocket.svg new file mode 100644 index 0000000..ae1ed81 --- /dev/null +++ b/docs/_static/Rocket.svg @@ -0,0 +1 @@ + diff --git a/docs/_static/Showcase.svg b/docs/_static/Showcase.svg new file mode 100644 index 0000000..953eb0d --- /dev/null +++ b/docs/_static/Showcase.svg @@ -0,0 +1,75 @@ + + + + diff --git a/docs/_static/Squaredcircle.svg b/docs/_static/Squaredcircle.svg new file mode 100644 index 0000000..0c622a5 --- /dev/null +++ b/docs/_static/Squaredcircle.svg @@ -0,0 +1,21 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/docs/_static/Tutorial.svg b/docs/_static/Tutorial.svg new file mode 100644 index 0000000..a42592d --- /dev/null +++ b/docs/_static/Tutorial.svg @@ -0,0 +1 @@ + diff --git a/docs/_static/UserGuide.svg b/docs/_static/UserGuide.svg new file mode 100644 index 0000000..e8cf53a --- /dev/null +++ b/docs/_static/UserGuide.svg @@ -0,0 +1 @@ + diff --git a/docs/_templates/README.md b/docs/_templates/README.md new file mode 100644 index 0000000..485f82a --- /dev/null +++ b/docs/_templates/README.md @@ -0,0 +1,14 @@ +# Templates Doc Directory + +Add any paths that contain templates here, relative to +the `conf.py` file's directory. +They are copied after the builtin template files, +so a file named "page.html" will overwrite the builtin "page.html". + +The path to this folder is set in the Sphinx `conf.py` file in the line: +```python +html_static_path = ['_templates'] +``` + +## Examples of file to add to this directory +* HTML extensions of stock pages like `page.html` or `layout.html` diff --git a/docs/api.rst b/docs/api.rst new file mode 100644 index 0000000..236565d --- /dev/null +++ b/docs/api.rst @@ -0,0 +1,9 @@ +API Documentation +================= + + +.. toctree:: + :maxdepth: 4 + :caption: API Contents: + + api/protocols/index diff --git a/docs/api/protocols/asfe_protocol.rst b/docs/api/protocols/asfe_protocol.rst new file mode 100644 index 0000000..d4dbf9b --- /dev/null +++ b/docs/api/protocols/asfe_protocol.rst @@ -0,0 +1,40 @@ +Absolute Solvation Free Energy (ASFE) Protocol +============================================== + +.. _asfe protocol api: + +A Protocol for running arbitrary solvent solvation free energy calculations. + + +Protocol API Specification +-------------------------- + +.. module:: pontibus.protocols.solvation + +.. autosummary:: + :nosignatures: + :toctree: generated/ + + ASFEProtocol + ASFEProtocolResult + ASFESettings + ASFESolventUnit + ASFEVacuumUnit + + +Protocol Settings +----------------- + +.. module:: pontibus.protocols.solvation.settings + +.. autopydantic_model:: ASFESettings + :model-show-json: False + :model-show-field-summary: False + :model-show-config-member: False + :model-show-config-summary: False + :model-show-validator-members: False + :model-show-validator-summary: False + :field-list-validators: False + :inherited-members: SettingsBaseModel + :exclude-members: get_defaults + :member-order: bysource diff --git a/docs/api/protocols/index.rst b/docs/api/protocols/index.rst new file mode 100644 index 0000000..c82b7db --- /dev/null +++ b/docs/api/protocols/index.rst @@ -0,0 +1,10 @@ +.. _api: + + +Pontibus Protocols API Reference +================================ + +.. toctree:: + :maxdepth: 2 + + asfe_protocol diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..b94b4cc --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,177 @@ +# +# Configuration file for the Sphinx documentation builder. +# +# This file does only contain a selection of the most common options. For a +# full list see the documentation: +# http://www.sphinx-doc.org/en/stable/config + +# -- 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. + +# Incase the project was not installed +import os +from pathlib import Path +import shutil +import sys +sys.path.insert(0, os.path.abspath('..')) + +import pontibus + + +# -- Project information ----------------------------------------------------- + +project = 'pontibus' +copyright = ("2024, Open Free Energy.") +author = 'The OpenFE Development Team' + +# The short X.Y version +version = '' +# The full version, including alpha/beta/rc tags +release = '' + + +# -- General configuration --------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +# +# needs_sphinx = '1.0' + +# 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", +] + + +intersphinx_mapping = { + "python": ("https://docs.python.org/3.10", None), + "numpy": ("https://numpy.org/doc/stable", None), + "scipy": ("https://docs.scipy.org/doc/scipy", None), + "scikit.learn": ("https://scikit-learn.org/stable", None), + "openmm": ("http://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.readthedocs.io/en/latest/", None), + "openfe": ("https://openfe.readthedocs.io/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", + "**/README.md", + "ExampleNotebooks", +] + +autodoc_mock_imports = [ + "matplotlib", + "mdtraj", + "openmmforcefields", + "openmmtools", + "pymbar", +] + +# 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 GROMACS Protocols"}, + "icon_links": [ + { + "name": "GitHub", + "url": "https://github.com/OpenFreeEnergy/pontibus", + "icon": "fa-brands fa-square-github", + "type": "fontawesome", + } + ], + "accent_color": "DarkGoldenYellow", + "navigation_with_keys": False, +} +html_logo = "_static/Squaredcircle.svg" + +# 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"] + +## Add below when we have notebooks +#example_notebooks_path = Path("ExampleNotebooks") +# +#try: +# if example_notebooks_path.exists(): +# pass +# else: +# source = Path("../examples") +# shutil.copytree(source, example_notebooks_path) +#except Exception as e: +# raise OSError("Could not copy over example notebooks") diff --git a/docs/environment.yaml b/docs/environment.yaml new file mode 100644 index 0000000..6ff3691 --- /dev/null +++ b/docs/environment.yaml @@ -0,0 +1,28 @@ +name: docs +channels: +- conda-forge +dependencies: +- autodoc-pydantic<2.0 +- openfe>=1.1.0 +- packaging +- plugcli +- python=3.10 +- sphinx<7 +- sphinx-click +- gitpython +- libsass +- nbsphinx +- nbsphinx-link +- myst-parser +- pip: + - sphinx-design + - sphinx-toolbox + - sphinx<7 + - git+https://github.com/OpenFreeEnergy/ofe-sphinx-theme@main + +# These are added automatically by RTD, so we include them here +# for a consistent environment. +- mock +- pillow +- sphinx +- sphinx_rtd_theme diff --git a/docs/getting_started.rst b/docs/getting_started.rst new file mode 100644 index 0000000..96fa815 --- /dev/null +++ b/docs/getting_started.rst @@ -0,0 +1,19 @@ +Getting Started +=============== + +This page details how to get started with pontibus. + + +Developer Install +***************** + +To install the development version of the pontibus, you should do a source +installation in the following manner:: + + git clone https://github.com/OpenFreeEnergy/pontibus.git + + cd pontibus + mamba env create -f environment.yml + + mamba activate pontibus + python -m pip install -e . diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..459416c --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,23 @@ +.. pontibus documentation index + +Welcome to pontibus' documentation! +=================================== + +Pontibus is a set of experimental OpenFE Free Energy Protocols +aimed specifically at facilitating the validation of OpenFF Force Fields. + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + getting_started + api + + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 0000000..d3954ea --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,36 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=. +set BUILDDIR=_build +set SPHINXPROJ=pontibus + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% + +:end +popd