Skip to content

WritingDocumentation

Oliver Beckstein edited this page Jul 8, 2020 · 22 revisions

See also

Table of Contents

MDAnalysis has a lot of documentation in the Python doc strings. In the Python interpreter one can simply say

  import MDAnalysis
  help(MDAnalysis)
  help(MDAnalysis.Universe)

In ipython one can use the question mark operator

  MDAnalysis.Universe?

Interactive use is not always convenient, though, and hence Issue 26 called for proper documentation. As of Jan 2011, the Online Documentation is available, too. This page should help developers write good documentation that can be easily processed into online docs.

Guidelines

When writing Python code, you should always add a doc string to each public (user-visible):

  • module
  • function
  • class
  • method

We use the numpy-style doc strings for classes, methods and functions. They are nice to read as normal text and are converted by sphinx to normal ReST through napoleon. When you add a new module you should include a docstring with a short sentence describing what the module does or a long document including examples and references. A typical function doc string looks like the following.

def func(arg1, arg2):
    """Summary line.

    Extended description of function.

    Parameters
    ----------
    arg1 : int
        Description of `arg1`
    arg2 : str
        Description of `arg2`

    Returns
    -------
    bool
        Description of return value

    """
    return True

For the detailed NumPy syntax please look at the example files

Notes on writing doc strings

  • If you include any maths, make the string a raw string by prefixing with r, e.g.,
    r"""some :math:`\nu^2 / \rho` with backslashes"""
    Otherwise the \n and \r will be rendered as ASCII escape sequences that break lines without you noticing it and you will get either of the following two errors that won't make any sense:
  • When writing reST markup such as
    some more docs bla bla
    
    Notes
    -----
    THE NEXT TWO BLANK LINES ARE IMPORTANT.
    
    
    .. versionaddedd:: 0.16.0
    then make sure that there are at least two blank lines above the reST after a numpy heading; otherwise the sphinx/napoleon parser does not render correctly.
  • Do not use "Example" or "Examples" as a normal section heading (e.g. in module level docs): only use it as a NumPy doc Section. It will never be rendered as a normal section and will mess up sectioning.

Documenting changes

We use reST constructs to annotate additions, changes, deprecations to the code so that users can quickly learn from the documentation in which version of MDAnalysis the feature is available.

A newly added module/class/method/attribute/function gets a versionadded directive

.. versionadded:: X.Y.Z

entry in its primary doc section. For parameters and attributes, we typically mention the new entity in a .. versionchanged:: section of the function or class (although a versionadded would also be acceptable).

Changes are indicated with a versionchanged directive

.. versionchanged:: X.Y.Z
   Description of the change. Can contain multiple descriptions.
   Don't assume that you get nice line breaks or formatting, write your text in
   full sentences that can be read as a paragraph.

Deprecations (features that are not any longer recommended for use and that will be removed in future releases) are indicated by the deprecated directive

.. deprecated:: X.Y.Z
   Describe (1) alternatives (what should users rather use) and 
   (2) in which future release the feature will be removed.

When a feature is removed, we remove the deprecation notice and add a versionchanged to the docs of the enclosing scope. E.g., when a parameter of a function is removed, we update the docs of the function. Function/class removal are indicated in the module docs. When we remove a whole module, we typically indicate it in the top-level reST docs that contain the TOC tree that included the module.

Writing docs for abstract Base Classes

MDAnalysis contains a number of abstract base classes like analysis.base.AnalysisBase. The API of a base class is only indented for developers should follow these rules. Background see Issue #919

Document Base class APIs in the class doc string.

  • The class doc-string needs to contain a list of methods that can be overwritten by inheritance from the base class. Distinguish and document methods as required or optional.
  • The class doc-string should contain a minimal example for how to derive this class. (This demonstrates best practices, documents ideas and intentions behind the specific choices in the API, helps to promote a unified code base and is useful for developers as a concise summary of the API).
  • A more detailed description of methods should come in the method doc-string with a note specifying if the method is required or optional to overwrite.

As an example see analysis.base.AnalysisBase

Location of documentation

Format: sphinx reStructuredText

Sphinx basics

We are using reStructuredText ("rst" or "reST") in the Python code and in the Online Documentation. The reST is processed with sphinx to generate HTML or PDF. Thus, the docs should use reST with the sphinx autodoc extensions:

Note that each page of the Online Documentation has a link to the Source of the page. You can look at it in order to find out how a particular page has been written in reST and copy the approach for your own documentation.

NumPy style

As outlined in the Style Guide, we use NumPy-style format for the reST strings.

Numpy Style Gotchas

  • After every numpy heading leave 2 empty lines before starting other sphinx paragraphs like .. deprecated:

  • When writing multiple common names in one line it can happen that sphinx tries to reference the first name. In that case you have to split the names across multiple lines. See below for an example

    Parameters
    ----------
    n_atoms, n_residues : int
        numbers of atoms/residues

Mathematics

We are using MathJax with sphinx so you can write LaTeX code in math tags, e.g.

#<SPACE if there is text above equation>
.. math::
   e^{i\pi} = -1

or inline

We make use of the identity :math:`e^{i\pi} = -1` to show...

Note that you should always make doc strings with math code raw python strings by prefixing them with the letter "r":

def rotate(self, R):
    r"""Apply a rotation matrix *R* to the selection's coordinates.

    :math:`\mathsf{R}` is a 3x3 orthogonal matrix that transforms a vector
    :math:`\mathbf{x} \rightarrow \mathbf{x}'`:

    .. math::

       \mathbf{x}' = \mathsf{R}\mathbf{x}
    """

or else you will get problems with backslashes in unexpected places (see Stackoverflow: Mathjax expression in sphinx python not rendering correctly).

Generating the docs

The documentation in HTML format lives in package/doc/html. HTML is the primary format in which we provide the docs. Documentation for releases is accessible at https://docs.mdanalysis.org (and is stored in the repository MDAnalysis/docs). The documentation for the development branch is hosted as GitHub pages in the gh-pages branch and is available at http://devdocs.mdanalysis.org.

  • release docs are built by a maintainer and uploaded to PyPi
  • development docs are built automatically by Travis CI (see issue #386 for details)

In order to generate the documentation, one has to have sphinx installed. The current version of MDAnalysis must be installed and MDAnalysis must be importable. A 'develop' installation (python setup.py develop) is generally useful for quick turn-around.

Running sphinx

Then one generates the html docs with

python setup.py build_sphinx -E

This generates and updates the files in doc/html. If the above command fails with an ImportError, run

python setup.py build_ext --inplace

and retry.

Checking

You should point your browser to the file doc/html/html/index.html and look through the docs, in particular any pages that you tinkered with. It is typical to go through multiple cycles of fix, rebuild the docs, check and fix again.

If any fixes in the restructured text are needed, put them in their own commit (and do not include any generated files under docs/html) — git add FILE and git commit --amend is your friend when piling more and more small reST fixes onto a single "fixed reST" commit.

Distribute docs for releases

Run the maintainer/deploy_master_docs.sh script from the top level. This should build the docs and push them to the repository MDAnalysis/docs. They are served as GitHub pages (from the master branch of this repo) and they appear as https://www.mdanalysis.org/docs.

Clone this wiki locally