[med-svn] [python-multipletau] 02/10: Imported Upstream version 0.1.5+ds
Alex Mestiashvili
malex-guest at moszumanska.debian.org
Tue Dec 15 17:11:45 UTC 2015
This is an automated email from the git hooks/post-receive script.
malex-guest pushed a commit to branch master
in repository python-multipletau.
commit 566e0a164b6b2c40238b5e522a49631e40ca5870
Author: Alexandre Mestiashvili <alex at biotec.tu-dresden.de>
Date: Tue Dec 15 15:56:02 2015 +0100
Imported Upstream version 0.1.5+ds
---
.gitignore | 11 +-
.travis.yml | 24 +
CHANGELOG.md | 4 +-
MANIFEST.in | 8 +-
README.md | 28 +-
README.txt | 2 +-
doc/Makefile | 177 -----
doc/README.md | 28 +-
doc/_extensions/apigen.py | 427 ------------
doc/_extensions/copybutton.js | 51 --
doc/_extensions/docscrape.py | 497 --------------
doc/_extensions/docscrape_sphinx.py | 136 ----
doc/_extensions/github.py | 714 ---------------------
doc/_extensions/hidden_code_block.py | 128 ----
doc/_extensions/inheritance_diagram.py | 407 ------------
doc/_extensions/ipython_console_highlighting.py | 114 ----
doc/_extensions/ipython_directive.py | 0
doc/_extensions/numpydoc.py | 116 ----
doc/conf.py | 59 +-
doc/deploy_ghpages.py | 83 +++
doc/extensions/myviewcode.py | 240 +++++++
doc/index.rst | 35 +-
doc/make.bat | 242 -------
doc/make.py | 14 -
doc/testing_multipletau.png | Bin 77102 -> 0 bytes
examples/compare_correlation_methods.png | Bin 0 -> 80520 bytes
.../compare_correlation_methods.py | 48 +-
test/__init__.py => examples/noise_generator.py | 20 +-
multipletau/__init__.py | 99 ++-
multipletau/_multipletau.py | 300 ++++-----
multipletau/_version.py | 2 +
setup.py | 97 ++-
tests/README.md | 16 +
tests/test_basic.py | 37 ++
34 files changed, 872 insertions(+), 3292 deletions(-)
diff --git a/.gitignore b/.gitignore
index b00b084..9110534 100644
--- a/.gitignore
+++ b/.gitignore
@@ -36,4 +36,13 @@ nosetests.xml
.settings*
# doc build
-doc/_build/**
\ No newline at end of file
+doc/_build/**
+
+
+# other stuff
+*.yml~
+*.py~
+*.md~
+*.in~
+*.txt~
+*.txt~
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..96bb5bd
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,24 @@
+language: python
+python:
+- '2.7'
+- '3.4'
+- '3.5'
+env:
+ global:
+ - GH_REF: github.com/FCS-analysis/multipletau.git
+ - secure: IVoAJNYKGjWbHUGPpe8oOTLhltGrhu0F+xCaRVGs1tTut34BixSSeDgranlRiXZ0wlVOzBGrDHLkoLxFSRRy43BN4TSiv05WLBZba7ypGYBbDrLrG5nFPnT6n9d4ZgFHHHwyvI2ymdSs6/EJwZRXmr2Ehm0HzetA27FB1/Q3kc0=
+notifications:
+ email: false
+install:
+- travis_retry pip install coverage
+- travis_retry pip install coveralls
+- pip freeze
+script:
+- coverage run --source=multipletau tests/runtests.py
+- coverage report -m
+after_success:
+- coveralls --verbose
+- git config credential.helper "store --file=.git/credentials"
+- echo "https://${GH_TOKEN}:@github.com" > .git/credentials
+- if [[ $TRAVIS_PYTHON_VERSION == 3.4 ]]; then pip install numpydoc sphinx; fi
+- if [[ $TRAVIS_PYTHON_VERSION == 3.4 ]]; then python doc/deploy_ghpages.py; fi
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8044355..cbf4fd3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,8 +1,10 @@
+0.1.5
+- update documentation
+- officially support Python 3
0.1.4
- integer and boolean input types are now automatically converted to floats
- `multipletau.correlate` now works with complex data types
- `multipletau.correlate` now checks if input data are same objects
- documentation now contains examples
-
0.1.3
- first non-cython implementation
diff --git a/MANIFEST.in b/MANIFEST.in
index b2c1156..6f47c76 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,3 +1,9 @@
include CHANGELOG.md
include README.txt
-include test/*.py
+include tests/*.py
+include tests/*.md
+include examples/*.py
+include doc/*.py
+include doc/*.rst
+include doc/*.md
+include doc/extensions/*.py
diff --git a/README.md b/README.md
index faf2982..cf5d8ef 100644
--- a/README.md
+++ b/README.md
@@ -1,22 +1,30 @@
multipletau
===========
+[![PyPI](http://img.shields.io/pypi/v/multipletau.svg)](https://pypi.python.org/pypi/multipletau)
+[![Travis](http://img.shields.io/travis/FCS-analysis/multipletau.svg)](https://travis-ci.org/FCS-analysis/multipletau)
+[![Coveralls](https://img.shields.io/coveralls/FCS-analysis/multipletau.svg)](https://coveralls.io/r/FCS-analysis/multipletau)
+
+
This repo contains a multiple-tau algorithm for Python
- **multipletau** multiple-tau package, implemented using [numpy](http://www.numpy.org/)
- **test** testing the algorithm
-- **doc** the source of the [documentation](http://paulmueller.github.io/multipletau/)
+- **doc** the source of the [documentation](http://FCS-analysis.github.io/multipletau/)
+
+
Installation
-============
+------------
The package can be installed from the Python package index.
+
pip install multipletau
Usage
-=====
+-----
>>> import numpy as np
>>> import multipletau
@@ -27,3 +35,17 @@ Usage
[ 2. , 530.37477692],
[ 4. , 491.85812017],
[ 8. , 386.39500297]])
+
+
+Citing
+------
+The multipletau package should be cited like this (replace "x.x.x" with the actual version of multipletau that you used and "DD Month YYYY" with a matching date).
+
+Paul Müller (2012) _Python multiple-tau algorithm_ (Version x.x.x) [Computer program]. Available at https://pypi.python.org/pypi/multipletau/ (Accessed DD Month YYYY)
+
+You can find out what version you are using by typing (in a Python console):
+
+
+ >>> import multipletau
+ >>> multipletau.__version__
+ '0.1.4'
diff --git a/README.txt b/README.txt
index b8f0467..98db327 100644
--- a/README.txt
+++ b/README.txt
@@ -5,7 +5,7 @@ correlation on a linear scale such as `numpy.correlate`.
Reference
=========
The code is fully documented. An online reference is available
-at http://paulmueller.github.io/multipletau/.
+at http://FCS-analysis.github.io/multipletau/.
Installation
diff --git a/doc/Makefile b/doc/Makefile
deleted file mode 100644
index 9ed47b9..0000000
--- a/doc/Makefile
+++ /dev/null
@@ -1,177 +0,0 @@
-# Makefile for Sphinx documentation
-#
-
-# You can set these variables from the command line.
-SPHINXOPTS =
-SPHINXBUILD = sphinx-build
-PAPER =
-BUILDDIR = _build
-
-# User-friendly check for sphinx-build
-ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
-$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/)
-endif
-
-# Internal variables.
-PAPEROPT_a4 = -D latex_paper_size=a4
-PAPEROPT_letter = -D latex_paper_size=letter
-ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
-# the i18n builder cannot share the environment and doctrees with the others
-I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
-
-.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
-
-help:
- @echo "Please use \`make <target>' where <target> is one of"
- @echo " html to make standalone HTML files"
- @echo " dirhtml to make HTML files named index.html in directories"
- @echo " singlehtml to make a single large HTML file"
- @echo " pickle to make pickle files"
- @echo " json to make JSON files"
- @echo " htmlhelp to make HTML files and a HTML help project"
- @echo " qthelp to make HTML files and a qthelp project"
- @echo " devhelp to make HTML files and a Devhelp project"
- @echo " epub to make an epub"
- @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
- @echo " latexpdf to make LaTeX files and run them through pdflatex"
- @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
- @echo " text to make text files"
- @echo " man to make manual pages"
- @echo " texinfo to make Texinfo files"
- @echo " info to make Texinfo files and run them through makeinfo"
- @echo " gettext to make PO message catalogs"
- @echo " changes to make an overview of all changed/added/deprecated items"
- @echo " xml to make Docutils-native XML files"
- @echo " pseudoxml to make pseudoxml-XML files for display purposes"
- @echo " linkcheck to check all external links for integrity"
- @echo " doctest to run all doctests embedded in the documentation (if enabled)"
-
-clean:
- rm -rf $(BUILDDIR)/*
-
-html:
- $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
- @echo
- @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
-
-dirhtml:
- $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
- @echo
- @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
-
-singlehtml:
- $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
- @echo
- @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
-
-pickle:
- $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
- @echo
- @echo "Build finished; now you can process the pickle files."
-
-json:
- $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
- @echo
- @echo "Build finished; now you can process the JSON files."
-
-htmlhelp:
- $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
- @echo
- @echo "Build finished; now you can run HTML Help Workshop with the" \
- ".hhp project file in $(BUILDDIR)/htmlhelp."
-
-qthelp:
- $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
- @echo
- @echo "Build finished; now you can run "qcollectiongenerator" with the" \
- ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
- @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/multipletau.qhcp"
- @echo "To view the help file:"
- @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/multipletau.qhc"
-
-devhelp:
- $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
- @echo
- @echo "Build finished."
- @echo "To view the help file:"
- @echo "# mkdir -p $$HOME/.local/share/devhelp/multipletau"
- @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/multipletau"
- @echo "# devhelp"
-
-epub:
- $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
- @echo
- @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
-
-latex:
- $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
- @echo
- @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
- @echo "Run \`make' in that directory to run these through (pdf)latex" \
- "(use \`make latexpdf' here to do that automatically)."
-
-latexpdf:
- $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
- @echo "Running LaTeX files through pdflatex..."
- $(MAKE) -C $(BUILDDIR)/latex all-pdf
- @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
-
-latexpdfja:
- $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
- @echo "Running LaTeX files through platex and dvipdfmx..."
- $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
- @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
-
-text:
- $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
- @echo
- @echo "Build finished. The text files are in $(BUILDDIR)/text."
-
-man:
- $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
- @echo
- @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
-
-texinfo:
- $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
- @echo
- @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
- @echo "Run \`make' in that directory to run these through makeinfo" \
- "(use \`make info' here to do that automatically)."
-
-info:
- $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
- @echo "Running Texinfo files through makeinfo..."
- make -C $(BUILDDIR)/texinfo info
- @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
-
-gettext:
- $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
- @echo
- @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
-
-changes:
- $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
- @echo
- @echo "The overview file is in $(BUILDDIR)/changes."
-
-linkcheck:
- $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
- @echo
- @echo "Link check complete; look for any errors in the above output " \
- "or in $(BUILDDIR)/linkcheck/output.txt."
-
-doctest:
- $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
- @echo "Testing of doctests in the sources finished, look at the " \
- "results in $(BUILDDIR)/doctest/output.txt."
-
-xml:
- $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
- @echo
- @echo "Build finished. The XML files are in $(BUILDDIR)/xml."
-
-pseudoxml:
- $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
- @echo
- @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
diff --git a/doc/README.md b/doc/README.md
index b0b54e4..856634a 100644
--- a/doc/README.md
+++ b/doc/README.md
@@ -1,17 +1,19 @@
-Documentation of multipletau
-============================
+multipletau documentation
+=========================
-In order to build the [documentation of multipletau](http://paulmueller.github.io/multipletau/) you need to have
-[Sphinx](http://sphinx-doc.org/) installed.
-You can install it by using pip or via apt-get:
+Install [numpydoc](https://pypi.python.org/pypi/numpydoc):
- pip install sphinx
- apt-get install python-sphinx
-
-The documentation can be build with either of these commands:
+ pip install numpydoc
+
+To compile the documentation, run
+
+ python setup.py build_sphinx
- python make.py
- make html
- make.bat (Windows)
-
+
+To upload the documentation to gh-pages, run
+
+ python setup.py commit_doc
+or
+
+ python doc/commit_gh-pages.py
diff --git a/doc/_extensions/apigen.py b/doc/_extensions/apigen.py
deleted file mode 100644
index 1237409..0000000
--- a/doc/_extensions/apigen.py
+++ /dev/null
@@ -1,427 +0,0 @@
-"""Attempt to generate templates for module reference with Sphinx
-
-XXX - we exclude extension modules
-
-To include extension modules, first identify them as valid in the
-``_uri2path`` method, then handle them in the ``_parse_module`` script.
-
-We get functions and classes by parsing the text of .py files.
-Alternatively we could import the modules for discovery, and we'd have
-to do that for extension modules. This would involve changing the
-``_parse_module`` method to work via import and introspection, and
-might involve changing ``discover_modules`` (which determines which
-files are modules, and therefore which module URIs will be passed to
-``_parse_module``).
-
-NOTE: this is a modified version of a script originally shipped with the
-PyMVPA project, which we've adapted for NIPY use. PyMVPA is an MIT-licensed
-project."""
-
-# Stdlib imports
-import os
-import re
-
-# Functions and classes
-class ApiDocWriter(object):
- ''' Class for automatic detection and parsing of API docs
- to Sphinx-parsable reST format'''
-
- # only separating first two levels
- rst_section_levels = ['*', '=', '-', '~', '^']
-
- def __init__(self,
- package_name,
- rst_extension='.rst',
- package_skip_patterns=None,
- module_skip_patterns=None,
- ):
- ''' Initialize package for parsing
-
- Parameters
- ----------
- package_name : string
- Name of the top-level package. *package_name* must be the
- name of an importable package
- rst_extension : string, optional
- Extension for reST files, default '.rst'
- package_skip_patterns : None or sequence of {strings, regexps}
- Sequence of strings giving URIs of packages to be excluded
- Operates on the package path, starting at (including) the
- first dot in the package path, after *package_name* - so,
- if *package_name* is ``sphinx``, then ``sphinx.util`` will
- result in ``.util`` being passed for earching by these
- regexps. If is None, gives default. Default is:
- ['\.tests$']
- module_skip_patterns : None or sequence
- Sequence of strings giving URIs of modules to be excluded
- Operates on the module name including preceding URI path,
- back to the first dot after *package_name*. For example
- ``sphinx.util.console`` results in the string to search of
- ``.util.console``
- If is None, gives default. Default is:
- ['\.setup$', '\._']
- '''
- if package_skip_patterns is None:
- package_skip_patterns = ['\\.tests$']
- if module_skip_patterns is None:
- module_skip_patterns = ['\\.setup$', '\\._']
- self.package_name = package_name
- self.rst_extension = rst_extension
- self.package_skip_patterns = package_skip_patterns
- self.module_skip_patterns = module_skip_patterns
-
- def get_package_name(self):
- return self._package_name
-
- def set_package_name(self, package_name):
- ''' Set package_name
-
- >>> docwriter = ApiDocWriter('sphinx')
- >>> import sphinx
- >>> docwriter.root_path == sphinx.__path__[0]
- True
- >>> docwriter.package_name = 'docutils'
- >>> import docutils
- >>> docwriter.root_path == docutils.__path__[0]
- True
- '''
- # It's also possible to imagine caching the module parsing here
- self._package_name = package_name
- self.root_module = __import__(package_name)
- self.root_path = self.root_module.__path__[0]
- self.written_modules = None
-
- package_name = property(get_package_name, set_package_name, None,
- 'get/set package_name')
-
- def _get_object_name(self, line):
- ''' Get second token in line
- >>> docwriter = ApiDocWriter('sphinx')
- >>> docwriter._get_object_name(" def func(): ")
- 'func'
- >>> docwriter._get_object_name(" class Klass(object): ")
- 'Klass'
- >>> docwriter._get_object_name(" class Klass: ")
- 'Klass'
- '''
- name = line.split()[1].split('(')[0].strip()
- # in case we have classes which are not derived from object
- # ie. old style classes
- return name.rstrip(':')
-
- def _uri2path(self, uri):
- ''' Convert uri to absolute filepath
-
- Parameters
- ----------
- uri : string
- URI of python module to return path for
-
- Returns
- -------
- path : None or string
- Returns None if there is no valid path for this URI
- Otherwise returns absolute file system path for URI
-
- Examples
- --------
- >>> docwriter = ApiDocWriter('sphinx')
- >>> import sphinx
- >>> modpath = sphinx.__path__[0]
- >>> res = docwriter._uri2path('sphinx.builder')
- >>> res == os.path.join(modpath, 'builder.py')
- True
- >>> res = docwriter._uri2path('sphinx')
- >>> res == os.path.join(modpath, '__init__.py')
- True
- >>> docwriter._uri2path('sphinx.does_not_exist')
-
- '''
- if uri == self.package_name:
- return os.path.join(self.root_path, '__init__.py')
- path = uri.replace('.', os.path.sep)
- path = path.replace(self.package_name + os.path.sep, '')
- path = os.path.join(self.root_path, path)
- # XXX maybe check for extensions as well?
- if os.path.exists(path + '.py'): # file
- path += '.py'
- elif os.path.exists(os.path.join(path, '__init__.py')):
- path = os.path.join(path, '__init__.py')
- else:
- return None
- return path
-
- def _path2uri(self, dirpath):
- ''' Convert directory path to uri '''
- relpath = dirpath.replace(self.root_path, self.package_name)
- if relpath.startswith(os.path.sep):
- relpath = relpath[1:]
- return relpath.replace(os.path.sep, '.')
-
- def _parse_module(self, uri):
- ''' Parse module defined in *uri* '''
- filename = self._uri2path(uri)
- if filename is None:
- # nothing that we could handle here.
- return ([],[])
- f = open(filename, 'rt')
- functions, classes = self._parse_lines(f)
- f.close()
- return functions, classes
-
- def _parse_lines(self, linesource):
- ''' Parse lines of text for functions and classes '''
- functions = []
- classes = []
- for line in linesource:
- if line.startswith('def ') and line.count('('):
- # exclude private stuff
- name = self._get_object_name(line)
- if not name.startswith('_'):
- functions.append(name)
- elif line.startswith('class '):
- # exclude private stuff
- name = self._get_object_name(line)
- if not name.startswith('_'):
- classes.append(name)
- else:
- pass
- functions.sort()
- classes.sort()
- return functions, classes
-
- def generate_api_doc(self, uri):
- '''Make autodoc documentation template string for a module
-
- Parameters
- ----------
- uri : string
- python location of module - e.g 'sphinx.builder'
-
- Returns
- -------
- S : string
- Contents of API doc
- '''
- # get the names of all classes and functions
- functions, classes = self._parse_module(uri)
- if not len(functions) and not len(classes):
- print 'WARNING: Empty -',uri # dbg
- return ''
-
- # Make a shorter version of the uri that omits the package name for
- # titles
- uri_short = re.sub(r'^%s\.' % self.package_name,'',uri)
-
- ad = '.. AUTO-GENERATED FILE -- DO NOT EDIT!\n\n'
-
- chap_title = uri_short
- ad += (chap_title+'\n'+ self.rst_section_levels[1] * len(chap_title)
- + '\n\n')
-
- # Set the chapter title to read 'module' for all modules except for the
- # main packages
- if '.' in uri:
- title = 'Module: :mod:`' + uri_short + '`'
- else:
- title = ':mod:`' + uri_short + '`'
- ad += title + '\n' + self.rst_section_levels[2] * len(title)
-
- if len(classes):
- ad += '\nInheritance diagram for ``%s``:\n\n' % uri
- ad += '.. inheritance-diagram:: %s \n' % uri
- ad += ' :parts: 3\n'
-
- ad += '\n.. automodule:: ' + uri + '\n'
- ad += '\n.. currentmodule:: ' + uri + '\n'
- multi_class = len(classes) > 1
- multi_fx = len(functions) > 1
- if multi_class:
- ad += '\n' + 'Classes' + '\n' + \
- self.rst_section_levels[2] * 7 + '\n'
- elif len(classes) and multi_fx:
- ad += '\n' + 'Class' + '\n' + \
- self.rst_section_levels[2] * 5 + '\n'
- for c in classes:
- ad += '\n:class:`' + c + '`\n' \
- + self.rst_section_levels[multi_class + 2 ] * \
- (len(c)+9) + '\n\n'
- ad += '\n.. autoclass:: ' + c + '\n'
- # must NOT exclude from index to keep cross-refs working
- ad += ' :members:\n' \
- ' :undoc-members:\n' \
- ' :show-inheritance:\n' \
- ' :inherited-members:\n' \
- '\n' \
- ' .. automethod:: __init__\n'
- if multi_fx:
- ad += '\n' + 'Functions' + '\n' + \
- self.rst_section_levels[2] * 9 + '\n\n'
- elif len(functions) and multi_class:
- ad += '\n' + 'Function' + '\n' + \
- self.rst_section_levels[2] * 8 + '\n\n'
- for f in functions:
- # must NOT exclude from index to keep cross-refs working
- ad += '\n.. autofunction:: ' + uri + '.' + f + '\n\n'
- return ad
-
- def _survives_exclude(self, matchstr, match_type):
- ''' Returns True if *matchstr* does not match patterns
-
- ``self.package_name`` removed from front of string if present
-
- Examples
- --------
- >>> dw = ApiDocWriter('sphinx')
- >>> dw._survives_exclude('sphinx.okpkg', 'package')
- True
- >>> dw.package_skip_patterns.append('^\\.badpkg$')
- >>> dw._survives_exclude('sphinx.badpkg', 'package')
- False
- >>> dw._survives_exclude('sphinx.badpkg', 'module')
- True
- >>> dw._survives_exclude('sphinx.badmod', 'module')
- True
- >>> dw.module_skip_patterns.append('^\\.badmod$')
- >>> dw._survives_exclude('sphinx.badmod', 'module')
- False
- '''
- if match_type == 'module':
- patterns = self.module_skip_patterns
- elif match_type == 'package':
- patterns = self.package_skip_patterns
- else:
- raise ValueError('Cannot interpret match type "%s"'
- % match_type)
- # Match to URI without package name
- L = len(self.package_name)
- if matchstr[:L] == self.package_name:
- matchstr = matchstr[L:]
- for pat in patterns:
- try:
- pat.search
- except AttributeError:
- pat = re.compile(pat)
- if pat.search(matchstr):
- return False
- return True
-
- def discover_modules(self):
- ''' Return module sequence discovered from ``self.package_name``
-
-
- Parameters
- ----------
- None
-
- Returns
- -------
- mods : sequence
- Sequence of module names within ``self.package_name``
-
- Examples
- --------
- >>> dw = ApiDocWriter('sphinx')
- >>> mods = dw.discover_modules()
- >>> 'sphinx.util' in mods
- True
- >>> dw.package_skip_patterns.append('\.util$')
- >>> 'sphinx.util' in dw.discover_modules()
- False
- >>>
- '''
- modules = [self.package_name]
- # raw directory parsing
- for dirpath, dirnames, filenames in os.walk(self.root_path):
- # Check directory names for packages
- root_uri = self._path2uri(os.path.join(self.root_path,
- dirpath))
- for dirname in dirnames[:]: # copy list - we modify inplace
- package_uri = '.'.join((root_uri, dirname))
- if (self._uri2path(package_uri) and
- self._survives_exclude(package_uri, 'package')):
- modules.append(package_uri)
- else:
- dirnames.remove(dirname)
- # Check filenames for modules
- for filename in filenames:
- module_name = filename[:-3]
- module_uri = '.'.join((root_uri, module_name))
- if (self._uri2path(module_uri) and
- self._survives_exclude(module_uri, 'module')):
- modules.append(module_uri)
- return sorted(modules)
-
- def write_modules_api(self, modules,outdir):
- # write the list
- written_modules = []
- for m in modules:
- api_str = self.generate_api_doc(m)
- if not api_str:
- continue
- # write out to file
- outfile = os.path.join(outdir,
- m + self.rst_extension)
- fileobj = open(outfile, 'wt')
- fileobj.write(api_str)
- fileobj.close()
- written_modules.append(m)
- self.written_modules = written_modules
-
- def write_api_docs(self, outdir):
- """Generate API reST files.
-
- Parameters
- ----------
- outdir : string
- Directory name in which to store files
- We create automatic filenames for each module
-
- Returns
- -------
- None
-
- Notes
- -----
- Sets self.written_modules to list of written modules
- """
- if not os.path.exists(outdir):
- os.mkdir(outdir)
- # compose list of modules
- modules = self.discover_modules()
- self.write_modules_api(modules,outdir)
-
- def write_index(self, outdir, froot='gen', relative_to=None):
- """Make a reST API index file from written files
-
- Parameters
- ----------
- path : string
- Filename to write index to
- outdir : string
- Directory to which to write generated index file
- froot : string, optional
- root (filename without extension) of filename to write to
- Defaults to 'gen'. We add ``self.rst_extension``.
- relative_to : string
- path to which written filenames are relative. This
- component of the written file path will be removed from
- outdir, in the generated index. Default is None, meaning,
- leave path as it is.
- """
- if self.written_modules is None:
- raise ValueError('No modules written')
- # Get full filename path
- path = os.path.join(outdir, froot+self.rst_extension)
- # Path written into index is relative to rootpath
- if relative_to is not None:
- relpath = outdir.replace(relative_to + os.path.sep, '')
- else:
- relpath = outdir
- idx = open(path,'wt')
- w = idx.write
- w('.. AUTO-GENERATED FILE -- DO NOT EDIT!\n\n')
- w('.. toctree::\n\n')
- for f in self.written_modules:
- w(' %s\n' % os.path.join(relpath,f))
- idx.close()
diff --git a/doc/_extensions/copybutton.js b/doc/_extensions/copybutton.js
deleted file mode 100644
index fe39f87..0000000
--- a/doc/_extensions/copybutton.js
+++ /dev/null
@@ -1,51 +0,0 @@
-$(document).ready(function() {
- /* Add a [>>>] button on the top-right corner of code samples to hide
- * the >>> and ... prompts and the output and thus make the code
- * copyable. */
- var div = $('.highlight-python .highlight,' +
- '.highlight-python3 .highlight')
- var pre = div.find('pre');
- // get the styles from the current theme
- var hide_text = 'Hide the prompts and output';
- var show_text = 'Show the prompts and output';
- var border_width = pre.css('border-top-width');
- var border_style = pre.css('border-top-style');
- var border_color = pre.css('border-top-color');
- var button_styles = {
- 'cursor':'pointer', 'float': 'right', 'margin-top': '-6px', 'margin-right': '-5px',
- 'border-color': border_color, 'border-style': border_style,
- 'border-width': border_width, 'color': border_color, 'text-size': '75%',
- 'font-family': 'monospace', 'padding-left': '0.2em', 'padding-right': '0.2em'
- }
- // create and add the button to all the code blocks that contain >>>
- div.each(function(index) {
- var jthis = $(this);
- if (jthis.find('.gp').length > 0) {
- var button = $('<span class="copybutton">>>></span>');
- button.css(button_styles)
- button.attr('title', hide_text);
- jthis.find('pre').prepend(button);
- }
- // tracebacks (.gt) contain bare text elements that need to be
- // wrapped in a span to work with .nextUntil() (see later)
- jthis.find('pre:has(.gt)').contents().filter(function() {
- return ((this.nodeType == 3) && (this.data.trim().length > 0));
- }).wrap('<span>');
- });
- // define the behavior of the button when it's clicked
- $('.copybutton').toggle(
- function() {
- var button = $(this);
- button.parent().find('.go, .gp, .gt').hide();
- button.next('pre').find('.gt').nextUntil('.gp, .go').css('visibility', 'hidden');
- button.css('text-decoration', 'line-through');
- button.attr('title', show_text);
- },
- function() {
- var button = $(this);
- button.parent().find('.go, .gp, .gt').show();
- button.next('pre').find('.gt').nextUntil('.gp, .go').css('visibility', 'visible');
- button.css('text-decoration', 'none');
- button.attr('title', hide_text);
- });
-});
diff --git a/doc/_extensions/docscrape.py b/doc/_extensions/docscrape.py
deleted file mode 100644
index f374b3d..0000000
--- a/doc/_extensions/docscrape.py
+++ /dev/null
@@ -1,497 +0,0 @@
-"""Extract reference documentation from the NumPy source tree.
-
-"""
-
-import inspect
-import textwrap
-import re
-import pydoc
-from StringIO import StringIO
-from warnings import warn
-4
-class Reader(object):
- """A line-based string reader.
-
- """
- def __init__(self, data):
- """
- Parameters
- ----------
- data : str
- String with lines separated by '\n'.
-
- """
- if isinstance(data,list):
- self._str = data
- else:
- self._str = data.split('\n') # store string as list of lines
-
- self.reset()
-
- def __getitem__(self, n):
- return self._str[n]
-
- def reset(self):
- self._l = 0 # current line nr
-
- def read(self):
- if not self.eof():
- out = self[self._l]
- self._l += 1
- return out
- else:
- return ''
-
- def seek_next_non_empty_line(self):
- for l in self[self._l:]:
- if l.strip():
- break
- else:
- self._l += 1
-
- def eof(self):
- return self._l >= len(self._str)
-
- def read_to_condition(self, condition_func):
- start = self._l
- for line in self[start:]:
- if condition_func(line):
- return self[start:self._l]
- self._l += 1
- if self.eof():
- return self[start:self._l+1]
- return []
-
- def read_to_next_empty_line(self):
- self.seek_next_non_empty_line()
- def is_empty(line):
- return not line.strip()
- return self.read_to_condition(is_empty)
-
- def read_to_next_unindented_line(self):
- def is_unindented(line):
- return (line.strip() and (len(line.lstrip()) == len(line)))
- return self.read_to_condition(is_unindented)
-
- def peek(self,n=0):
- if self._l + n < len(self._str):
- return self[self._l + n]
- else:
- return ''
-
- def is_empty(self):
- return not ''.join(self._str).strip()
-
-
-class NumpyDocString(object):
- def __init__(self,docstring):
- docstring = textwrap.dedent(docstring).split('\n')
-
- self._doc = Reader(docstring)
- self._parsed_data = {
- 'Signature': '',
- 'Summary': [''],
- 'Extended Summary': [],
- 'Parameters': [],
- 'Returns': [],
- 'Raises': [],
- 'Warns': [],
- 'Other Parameters': [],
- 'Attributes': [],
- 'Methods': [],
- 'See Also': [],
- 'Notes': [],
- 'Warnings': [],
- 'References': '',
- 'Examples': '',
- 'index': {}
- }
-
- self._parse()
-
- def __getitem__(self,key):
- return self._parsed_data[key]
-
- def __setitem__(self,key,val):
- if not self._parsed_data.has_key(key):
- warn("Unknown section %s" % key)
- else:
- self._parsed_data[key] = val
-
- def _is_at_section(self):
- self._doc.seek_next_non_empty_line()
-
- if self._doc.eof():
- return False
-
- l1 = self._doc.peek().strip() # e.g. Parameters
-
- if l1.startswith('.. index::'):
- return True
-
- l2 = self._doc.peek(1).strip() # ---------- or ==========
- return l2.startswith('-'*len(l1)) or l2.startswith('='*len(l1))
-
- def _strip(self,doc):
- i = 0
- j = 0
- for i,line in enumerate(doc):
- if line.strip(): break
-
- for j,line in enumerate(doc[::-1]):
- if line.strip(): break
-
- return doc[i:len(doc)-j]
-
- def _read_to_next_section(self):
- section = self._doc.read_to_next_empty_line()
-
- while not self._is_at_section() and not self._doc.eof():
- if not self._doc.peek(-1).strip(): # previous line was empty
- section += ['']
-
- section += self._doc.read_to_next_empty_line()
-
- return section
-
- def _read_sections(self):
- while not self._doc.eof():
- data = self._read_to_next_section()
- name = data[0].strip()
-
- if name.startswith('..'): # index section
- yield name, data[1:]
- elif len(data) < 2:
- yield StopIteration
- else:
- yield name, self._strip(data[2:])
-
- def _parse_param_list(self,content):
- r = Reader(content)
- params = []
- while not r.eof():
- header = r.read().strip()
- if ' : ' in header:
- arg_name, arg_type = header.split(' : ')[:2]
- else:
- arg_name, arg_type = header, ''
-
- desc = r.read_to_next_unindented_line()
- desc = dedent_lines(desc)
-
- params.append((arg_name,arg_type,desc))
-
- return params
-
-
- _name_rgx = re.compile(r"^\s*(:(?P<role>\w+):`(?P<name>[a-zA-Z0-9_.-]+)`|"
- r" (?P<name2>[a-zA-Z0-9_.-]+))\s*", re.X)
- def _parse_see_also(self, content):
- """
- func_name : Descriptive text
- continued text
- another_func_name : Descriptive text
- func_name1, func_name2, :meth:`func_name`, func_name3
-
- """
- items = []
-
- def parse_item_name(text):
- """Match ':role:`name`' or 'name'"""
- m = self._name_rgx.match(text)
- if m:
- g = m.groups()
- if g[1] is None:
- return g[3], None
- else:
- return g[2], g[1]
- raise ValueError("%s is not a item name" % text)
-
- def push_item(name, rest):
- if not name:
- return
- name, role = parse_item_name(name)
- items.append((name, list(rest), role))
- del rest[:]
-
- current_func = None
- rest = []
-
- for line in content:
- if not line.strip(): continue
-
- m = self._name_rgx.match(line)
- if m and line[m.end():].strip().startswith(':'):
- push_item(current_func, rest)
- current_func, line = line[:m.end()], line[m.end():]
- rest = [line.split(':', 1)[1].strip()]
- if not rest[0]:
- rest = []
- elif not line.startswith(' '):
- push_item(current_func, rest)
- current_func = None
- if ',' in line:
- for func in line.split(','):
- push_item(func, [])
- elif line.strip():
- current_func = line
- elif current_func is not None:
- rest.append(line.strip())
- push_item(current_func, rest)
- return items
-
- def _parse_index(self, section, content):
- """
- .. index: default
- :refguide: something, else, and more
-
- """
- def strip_each_in(lst):
- return [s.strip() for s in lst]
-
- out = {}
- section = section.split('::')
- if len(section) > 1:
- out['default'] = strip_each_in(section[1].split(','))[0]
- for line in content:
- line = line.split(':')
- if len(line) > 2:
- out[line[1]] = strip_each_in(line[2].split(','))
- return out
-
- def _parse_summary(self):
- """Grab signature (if given) and summary"""
- if self._is_at_section():
- return
-
- summary = self._doc.read_to_next_empty_line()
- summary_str = " ".join([s.strip() for s in summary]).strip()
- if re.compile('^([\w., ]+=)?\s*[\w\.]+\(.*\)$').match(summary_str):
- self['Signature'] = summary_str
- if not self._is_at_section():
- self['Summary'] = self._doc.read_to_next_empty_line()
- else:
- self['Summary'] = summary
-
- if not self._is_at_section():
- self['Extended Summary'] = self._read_to_next_section()
-
- def _parse(self):
- self._doc.reset()
- self._parse_summary()
-
- for (section,content) in self._read_sections():
- if not section.startswith('..'):
- section = ' '.join([s.capitalize() for s in section.split(' ')])
- if section in ('Parameters', 'Attributes', 'Methods',
- 'Returns', 'Raises', 'Warns'):
- self[section] = self._parse_param_list(content)
- elif section.startswith('.. index::'):
- self['index'] = self._parse_index(section, content)
- elif section == 'See Also':
- self['See Also'] = self._parse_see_also(content)
- else:
- self[section] = content
-
- # string conversion routines
-
- def _str_header(self, name, symbol='-'):
- return [name, len(name)*symbol]
-
- def _str_indent(self, doc, indent=4):
- out = []
- for line in doc:
- out += [' '*indent + line]
- return out
-
- def _str_signature(self):
- if self['Signature']:
- return [self['Signature'].replace('*','\*')] + ['']
- else:
- return ['']
-
- def _str_summary(self):
- if self['Summary']:
- return self['Summary'] + ['']
- else:
- return []
-
- def _str_extended_summary(self):
- if self['Extended Summary']:
- return self['Extended Summary'] + ['']
- else:
- return []
-
- def _str_param_list(self, name):
- out = []
- if self[name]:
- out += self._str_header(name)
- for param,param_type,desc in self[name]:
- out += ['%s : %s' % (param, param_type)]
- out += self._str_indent(desc)
- out += ['']
- return out
-
- def _str_section(self, name):
- out = []
- if self[name]:
- out += self._str_header(name)
- out += self[name]
- out += ['']
- return out
-
- def _str_see_also(self, func_role):
- if not self['See Also']: return []
- out = []
- out += self._str_header("See Also")
- last_had_desc = True
- for func, desc, role in self['See Also']:
- if role:
- link = ':%s:`%s`' % (role, func)
- elif func_role:
- link = ':%s:`%s`' % (func_role, func)
- else:
- link = "`%s`_" % func
- if desc or last_had_desc:
- out += ['']
- out += [link]
- else:
- out[-1] += ", %s" % link
- if desc:
- out += self._str_indent([' '.join(desc)])
- last_had_desc = True
- else:
- last_had_desc = False
- out += ['']
- return out
-
- def _str_index(self):
- idx = self['index']
- out = []
- out += ['.. index:: %s' % idx.get('default','')]
- for section, references in idx.iteritems():
- if section == 'default':
- continue
- out += [' :%s: %s' % (section, ', '.join(references))]
- return out
-
- def __str__(self, func_role=''):
- out = []
- out += self._str_signature()
- out += self._str_summary()
- out += self._str_extended_summary()
- for param_list in ('Parameters','Returns','Raises'):
- out += self._str_param_list(param_list)
- out += self._str_section('Warnings')
- out += self._str_see_also(func_role)
- for s in ('Notes','References','Examples'):
- out += self._str_section(s)
- out += self._str_index()
- return '\n'.join(out)
-
-
-def indent(str,indent=4):
- indent_str = ' '*indent
- if str is None:
- return indent_str
- lines = str.split('\n')
- return '\n'.join(indent_str + l for l in lines)
-
-def dedent_lines(lines):
- """Deindent a list of lines maximally"""
- return textwrap.dedent("\n".join(lines)).split("\n")
-
-def header(text, style='-'):
- return text + '\n' + style*len(text) + '\n'
-
-
-class FunctionDoc(NumpyDocString):
- def __init__(self, func, role='func', doc=None):
- self._f = func
- self._role = role # e.g. "func" or "meth"
- if doc is None:
- doc = inspect.getdoc(func) or ''
- try:
- NumpyDocString.__init__(self, doc)
- except ValueError, e:
- print '*'*78
- print "ERROR: '%s' while parsing `%s`" % (e, self._f)
- print '*'*78
- #print "Docstring follows:"
- #print doclines
- #print '='*78
-
- if not self['Signature']:
- func, func_name = self.get_func()
- try:
- # try to read signature
- argspec = inspect.getargspec(func)
- argspec = inspect.formatargspec(*argspec)
- argspec = argspec.replace('*','\*')
- signature = '%s%s' % (func_name, argspec)
- except TypeError, e:
- signature = '%s()' % func_name
- self['Signature'] = signature
-
- def get_func(self):
- func_name = getattr(self._f, '__name__', self.__class__.__name__)
- if inspect.isclass(self._f):
- func = getattr(self._f, '__call__', self._f.__init__)
- else:
- func = self._f
- return func, func_name
-
- def __str__(self):
- out = ''
-
- func, func_name = self.get_func()
- signature = self['Signature'].replace('*', '\*')
-
- roles = {'func': 'function',
- 'meth': 'method'}
-
- if self._role:
- if not roles.has_key(self._role):
- print "Warning: invalid role %s" % self._role
- out += '.. %s:: %s\n \n\n' % (roles.get(self._role,''),
- func_name)
-
- out += super(FunctionDoc, self).__str__(func_role=self._role)
- return out
-
-
-class ClassDoc(NumpyDocString):
- def __init__(self,cls,modulename='',func_doc=FunctionDoc,doc=None):
- if not inspect.isclass(cls):
- raise ValueError("Initialise using a class. Got %r" % cls)
- self._cls = cls
-
- if modulename and not modulename.endswith('.'):
- modulename += '.'
- self._mod = modulename
- self._name = cls.__name__
- self._func_doc = func_doc
-
- if doc is None:
- doc = pydoc.getdoc(cls)
-
- NumpyDocString.__init__(self, doc)
-
- @property
- def methods(self):
- return [name for name,func in inspect.getmembers(self._cls)
- if not name.startswith('_') and callable(func)]
-
- def __str__(self):
- out = ''
- out += super(ClassDoc, self).__str__()
- out += "\n\n"
-
- #for m in self.methods:
- # print "Parsing `%s`" % m
- # out += str(self._func_doc(getattr(self._cls,m), 'meth')) + '\n\n'
- # out += '.. index::\n single: %s; %s\n\n' % (self._name, m)
-
- return out
-
-
diff --git a/doc/_extensions/docscrape_sphinx.py b/doc/_extensions/docscrape_sphinx.py
deleted file mode 100644
index 77ed271..0000000
--- a/doc/_extensions/docscrape_sphinx.py
+++ /dev/null
@@ -1,136 +0,0 @@
-import re, inspect, textwrap, pydoc
-from docscrape import NumpyDocString, FunctionDoc, ClassDoc
-
-class SphinxDocString(NumpyDocString):
- # string conversion routines
- def _str_header(self, name, symbol='`'):
- return ['.. rubric:: ' + name, '']
-
- def _str_field_list(self, name):
- return [':' + name + ':']
-
- def _str_indent(self, doc, indent=4):
- out = []
- for line in doc:
- out += [' '*indent + line]
- return out
-
- def _str_signature(self):
- return ['']
- if self['Signature']:
- return ['``%s``' % self['Signature']] + ['']
- else:
- return ['']
-
- def _str_summary(self):
- return self['Summary'] + ['']
-
- def _str_extended_summary(self):
- return self['Extended Summary'] + ['']
-
- def _str_param_list(self, name):
- out = []
- if self[name]:
- out += self._str_field_list(name)
- out += ['']
- for param,param_type,desc in self[name]:
- out += self._str_indent(['**%s** : %s' % (param.strip(),
- param_type)])
- out += ['']
- out += self._str_indent(desc,8)
- out += ['']
- return out
-
- def _str_section(self, name):
- out = []
- if self[name]:
- out += self._str_header(name)
- out += ['']
- content = textwrap.dedent("\n".join(self[name])).split("\n")
- out += content
- out += ['']
- return out
-
- def _str_see_also(self, func_role):
- out = []
- if self['See Also']:
- see_also = super(SphinxDocString, self)._str_see_also(func_role)
- out = ['.. seealso::', '']
- out += self._str_indent(see_also[2:])
- return out
-
- def _str_warnings(self):
- out = []
- if self['Warnings']:
- out = ['.. warning::', '']
- out += self._str_indent(self['Warnings'])
- return out
-
- def _str_index(self):
- idx = self['index']
- out = []
- if len(idx) == 0:
- return out
-
- out += ['.. index:: %s' % idx.get('default','')]
- for section, references in idx.iteritems():
- if section == 'default':
- continue
- elif section == 'refguide':
- out += [' single: %s' % (', '.join(references))]
- else:
- out += [' %s: %s' % (section, ','.join(references))]
- return out
-
- def _str_references(self):
- out = []
- if self['References']:
- out += self._str_header('References')
- if isinstance(self['References'], str):
- self['References'] = [self['References']]
- out.extend(self['References'])
- out += ['']
- return out
-
- def __str__(self, indent=0, func_role="obj"):
- out = []
- out += self._str_signature()
- out += self._str_index() + ['']
- out += self._str_summary()
- out += self._str_extended_summary()
- for param_list in ('Parameters', 'Attributes', 'Methods',
- 'Returns','Raises'):
- out += self._str_param_list(param_list)
- out += self._str_warnings()
- out += self._str_see_also(func_role)
- out += self._str_section('Notes')
- out += self._str_references()
- out += self._str_section('Examples')
- out = self._str_indent(out,indent)
- return '\n'.join(out)
-
-class SphinxFunctionDoc(SphinxDocString, FunctionDoc):
- pass
-
-class SphinxClassDoc(SphinxDocString, ClassDoc):
- pass
-
-def get_doc_object(obj, what=None, doc=None):
- if what is None:
- if inspect.isclass(obj):
- what = 'class'
- elif inspect.ismodule(obj):
- what = 'module'
- elif callable(obj):
- what = 'function'
- else:
- what = 'object'
- if what == 'class':
- return SphinxClassDoc(obj, '', func_doc=SphinxFunctionDoc, doc=doc)
- elif what in ('function', 'method'):
- return SphinxFunctionDoc(obj, '', doc=doc)
- else:
- if doc is None:
- doc = pydoc.getdoc(obj)
- return SphinxDocString(doc)
-
diff --git a/doc/_extensions/github.py b/doc/_extensions/github.py
deleted file mode 100644
index a19f599..0000000
--- a/doc/_extensions/github.py
+++ /dev/null
@@ -1,714 +0,0 @@
-
-
-
-<!DOCTYPE html>
-<html>
- <head prefix="og: http://ogp.me/ns# fb: http://ogp.me/ns/fb# githubog: http://ogp.me/ns/fb/githubog#">
- <meta charset='utf-8'>
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
- <title>ipython/docs/sphinxext/github.py at master · ipython/ipython · GitHub</title>
- <link rel="search" type="application/opensearchdescription+xml" href="/opensearch.xml" title="GitHub" />
- <link rel="fluid-icon" href="https://github.com/fluidicon.png" title="GitHub" />
- <link rel="apple-touch-icon" sizes="57x57" href="/apple-touch-icon-114.png" />
- <link rel="apple-touch-icon" sizes="114x114" href="/apple-touch-icon-114.png" />
- <link rel="apple-touch-icon" sizes="72x72" href="/apple-touch-icon-144.png" />
- <link rel="apple-touch-icon" sizes="144x144" href="/apple-touch-icon-144.png" />
- <link rel="logo" type="image/svg" href="http://github-media-downloads.s3.amazonaws.com/github-logo.svg" />
- <link rel="xhr-socket" href="/_sockets" />
-
-
- <meta name="msapplication-TileImage" content="/windows-tile.png" />
- <meta name="msapplication-TileColor" content="#ffffff" />
- <meta name="selected-link" value="repo_source" data-pjax-transient />
- <meta content="collector.githubapp.com" name="octolytics-host" /><meta content="github" name="octolytics-app-id" />
-
-
-
- <link rel="icon" type="image/x-icon" href="/favicon.ico" />
-
- <meta content="authenticity_token" name="csrf-param" />
-<meta content="KxkHbu6uuzb5nYpICaiM/tuRIpoRIcTZQEgfU8NliZg=" name="csrf-token" />
-
- <link href="https://a248.e.akamai.net/assets.github.com/assets/github-d63f89e307e2e357d3b7160b3cd4020463f9bbc1.css" media="all" rel="stylesheet" type="text/css" />
- <link href="https://a248.e.akamai.net/assets.github.com/assets/github2-4a2696ec075bd8d27843df00793c7e9d6525dded.css" media="all" rel="stylesheet" type="text/css" />
-
-
-
- <script src="https://a248.e.akamai.net/assets.github.com/assets/frameworks-92d138f450f2960501e28397a2f63b0f100590f0.js" type="text/javascript"></script>
- <script src="https://a248.e.akamai.net/assets.github.com/assets/github-60bb3beedc339be272bd2acfce1cae3b79371737.js" type="text/javascript"></script>
-
- <meta http-equiv="x-pjax-version" content="7159fafc2fc92e02281814323bde3687">
-
- <link data-pjax-transient rel='permalink' href='/ipython/ipython/blob/831d4eb049fa74f8be85ea7495a9724cb754390f/docs/sphinxext/github.py'>
- <meta property="og:title" content="ipython"/>
- <meta property="og:type" content="githubog:gitrepository"/>
- <meta property="og:url" content="https://github.com/ipython/ipython"/>
- <meta property="og:image" content="https://secure.gravatar.com/avatar/f72497397dd9a0a79c654c8182460bb1?s=420&d=https://a248.e.akamai.net/assets.github.com%2Fimages%2Fgravatars%2Fgravatar-user-420.png"/>
- <meta property="og:site_name" content="GitHub"/>
- <meta property="og:description" content="ipython - Official repository for IPython itself. Other repos in the IPython organization contain things like the website, documentation builds, etc."/>
- <meta property="twitter:card" content="summary"/>
- <meta property="twitter:site" content="@GitHub">
- <meta property="twitter:title" content="ipython/ipython"/>
-
- <meta name="description" content="ipython - Official repository for IPython itself. Other repos in the IPython organization contain things like the website, documentation builds, etc." />
-
-
- <meta content="230453" name="octolytics-dimension-user_id" /><meta content="658518" name="octolytics-dimension-repository_id" />
- <link href="https://github.com/ipython/ipython/commits/master.atom" rel="alternate" title="Recent Commits to ipython:master" type="application/atom+xml" />
-
- </head>
-
-
- <body class="logged_out page-blob windows vis-public env-production ">
- <div id="wrapper">
-
-
-
-
-
-
-
-
- <div class="header header-logged-out">
- <div class="container clearfix">
-
- <a class="header-logo-wordmark" href="https://github.com/">Github</a>
-
- <div class="header-actions">
- <a class="button primary" href="https://github.com/signup">Sign up</a>
- <a class="button" href="https://github.com/login?return_to=%2Fipython%2Fipython%2Fblob%2Fmaster%2Fdocs%2Fsphinxext%2Fgithub.py">Sign in</a>
- </div>
-
- <div class="command-bar js-command-bar in-repository">
-
-
- <ul class="top-nav">
- <li class="explore"><a href="https://github.com/explore">Explore</a></li>
- <li class="features"><a href="https://github.com/features">Features</a></li>
- <li class="blog"><a href="https://github.com/blog">Blog</a></li>
- </ul>
- <form accept-charset="UTF-8" action="/search" class="command-bar-form" id="top_search_form" method="get">
- <a href="/search/advanced" class="advanced-search-icon tooltipped downwards command-bar-search" id="advanced_search" title="Advanced search"><span class="octicon octicon-gear "></span></a>
-
- <input type="text" data-hotkey="/ s" name="q" id="js-command-bar-field" placeholder="Search or type a command" tabindex="1" autocapitalize="off"
-
- data-repo="ipython/ipython"
- data-branch="master"
- data-sha="26bb5f152ca86cb76eb66799c54e217638cd4b6d"
- >
-
- <input type="hidden" name="nwo" value="ipython/ipython" />
-
- <div class="select-menu js-menu-container js-select-menu search-context-select-menu">
- <span class="minibutton select-menu-button js-menu-target">
- <span class="js-select-button">This repository</span>
- </span>
-
- <div class="select-menu-modal-holder js-menu-content js-navigation-container">
- <div class="select-menu-modal">
-
- <div class="select-menu-item js-navigation-item selected">
- <span class="select-menu-item-icon octicon octicon-check"></span>
- <input type="radio" class="js-search-this-repository" name="search_target" value="repository" checked="checked" />
- <div class="select-menu-item-text js-select-button-text">This repository</div>
- </div> <!-- /.select-menu-item -->
-
- <div class="select-menu-item js-navigation-item">
- <span class="select-menu-item-icon octicon octicon-check"></span>
- <input type="radio" name="search_target" value="global" />
- <div class="select-menu-item-text js-select-button-text">All repositories</div>
- </div> <!-- /.select-menu-item -->
-
- </div>
- </div>
- </div>
-
- <span class="octicon help tooltipped downwards" title="Show command bar help">
- <span class="octicon octicon-question"></span>
- </span>
-
-
- <input type="hidden" name="ref" value="cmdform">
-
- <div class="divider-vertical"></div>
-
-</form>
- </div>
-
- </div>
-</div>
-
-
-
-
-
-
-
- <div class="site hfeed" itemscope itemtype="http://schema.org/WebPage">
- <div class="hentry">
-
- <div class="pagehead repohead instapaper_ignore readability-menu ">
- <div class="container">
- <div class="title-actions-bar">
-
-
-<ul class="pagehead-actions">
-
-
-
- <li>
- <a href="/login?return_to=%2Fipython%2Fipython"
- class="minibutton js-toggler-target star-button entice tooltipped upwards"
- title="You must be signed in to use this feature" rel="nofollow">
- <span class="octicon octicon-star"></span>Star
- </a>
- <a class="social-count js-social-count" href="/ipython/ipython/stargazers">
- 1,895
- </a>
- </li>
- <li>
- <a href="/login?return_to=%2Fipython%2Fipython"
- class="minibutton js-toggler-target fork-button entice tooltipped upwards"
- title="You must be signed in to fork a repository" rel="nofollow">
- <span class="octicon octicon-git-branch"></span>Fork
- </a>
- <a href="/ipython/ipython/network" class="social-count">
- 586
- </a>
- </li>
-</ul>
-
- <h1 itemscope itemtype="http://data-vocabulary.org/Breadcrumb" class="entry-title public">
- <span class="repo-label"><span>public</span></span>
- <span class="mega-octicon octicon-repo"></span>
- <span class="author vcard">
- <a href="/ipython" class="url fn" itemprop="url" rel="author">
- <span itemprop="title">ipython</span>
- </a></span> /
- <strong><a href="/ipython/ipython" class="js-current-repository">ipython</a></strong>
- </h1>
- </div>
-
-
- <ul class="tabs">
- <li class="pulse-nav"><a href="/ipython/ipython/pulse" class="js-selected-navigation-item " data-selected-links="pulse /ipython/ipython/pulse" rel="nofollow"><span class="octicon octicon-pulse"></span></a></li>
- <li><a href="/ipython/ipython" class="js-selected-navigation-item selected" data-selected-links="repo_source repo_downloads repo_commits repo_tags repo_branches /ipython/ipython">Code</a></li>
- <li><a href="/ipython/ipython/network" class="js-selected-navigation-item " data-selected-links="repo_network /ipython/ipython/network">Network</a></li>
- <li><a href="/ipython/ipython/pulls" class="js-selected-navigation-item " data-selected-links="repo_pulls /ipython/ipython/pulls">Pull Requests <span class='counter'>15</span></a></li>
-
- <li><a href="/ipython/ipython/issues" class="js-selected-navigation-item " data-selected-links="repo_issues /ipython/ipython/issues">Issues <span class='counter'>567</span></a></li>
-
- <li><a href="/ipython/ipython/wiki" class="js-selected-navigation-item " data-selected-links="repo_wiki /ipython/ipython/wiki">Wiki</a></li>
-
-
- <li><a href="/ipython/ipython/graphs" class="js-selected-navigation-item " data-selected-links="repo_graphs repo_contributors /ipython/ipython/graphs">Graphs</a></li>
-
-
- </ul>
-
-<div class="tabnav">
-
- <span class="tabnav-right">
- <ul class="tabnav-tabs">
- <li><a href="/ipython/ipython/tags" class="js-selected-navigation-item tabnav-tab" data-selected-links="repo_tags /ipython/ipython/tags">Tags <span class="counter ">13</span></a></li>
- </ul>
- </span>
-
- <div class="tabnav-widget scope">
-
-
- <div class="select-menu js-menu-container js-select-menu js-branch-menu">
- <a class="minibutton select-menu-button js-menu-target" data-hotkey="w" data-ref="master">
- <span class="octicon octicon-branch"></span>
- <i>branch:</i>
- <span class="js-select-button">master</span>
- </a>
-
- <div class="select-menu-modal-holder js-menu-content js-navigation-container">
-
- <div class="select-menu-modal">
- <div class="select-menu-header">
- <span class="select-menu-title">Switch branches/tags</span>
- <span class="octicon octicon-remove-close js-menu-close"></span>
- </div> <!-- /.select-menu-header -->
-
- <div class="select-menu-filters">
- <div class="select-menu-text-filter">
- <input type="text" id="commitish-filter-field" class="js-filterable-field js-navigation-enable" placeholder="Filter branches/tags">
- </div>
- <div class="select-menu-tabs">
- <ul>
- <li class="select-menu-tab">
- <a href="#" data-tab-filter="branches" class="js-select-menu-tab">Branches</a>
- </li>
- <li class="select-menu-tab">
- <a href="#" data-tab-filter="tags" class="js-select-menu-tab">Tags</a>
- </li>
- </ul>
- </div><!-- /.select-menu-tabs -->
- </div><!-- /.select-menu-filters -->
-
- <div class="select-menu-list select-menu-tab-bucket js-select-menu-tab-bucket css-truncate" data-tab-filter="branches">
-
- <div data-filterable-for="commitish-filter-field" data-filterable-type="substring">
-
- <div class="select-menu-item js-navigation-item ">
- <span class="select-menu-item-icon octicon octicon-check"></span>
- <a href="/ipython/ipython/blob/0.10.2/docs/sphinxext/github.py" class="js-navigation-open select-menu-item-text js-select-button-text css-truncate-target" data-name="0.10.2" rel="nofollow" title="0.10.2">0.10.2</a>
- </div> <!-- /.select-menu-item -->
- <div class="select-menu-item js-navigation-item ">
- <span class="select-menu-item-icon octicon octicon-check"></span>
- <a href="/ipython/ipython/blob/0.12.1/docs/sphinxext/github.py" class="js-navigation-open select-menu-item-text js-select-button-text css-truncate-target" data-name="0.12.1" rel="nofollow" title="0.12.1">0.12.1</a>
- </div> <!-- /.select-menu-item -->
- <div class="select-menu-item js-navigation-item ">
- <span class="select-menu-item-icon octicon octicon-check"></span>
- <a href="/ipython/ipython/blob/0.13.x/docs/sphinxext/github.py" class="js-navigation-open select-menu-item-text js-select-button-text css-truncate-target" data-name="0.13.x" rel="nofollow" title="0.13.x">0.13.x</a>
- </div> <!-- /.select-menu-item -->
- <div class="select-menu-item js-navigation-item selected">
- <span class="select-menu-item-icon octicon octicon-check"></span>
- <a href="/ipython/ipython/blob/master/docs/sphinxext/github.py" class="js-navigation-open select-menu-item-text js-select-button-text css-truncate-target" data-name="master" rel="nofollow" title="master">master</a>
- </div> <!-- /.select-menu-item -->
- </div>
-
- <div class="select-menu-no-results">Nothing to show</div>
- </div> <!-- /.select-menu-list -->
-
-
- <div class="select-menu-list select-menu-tab-bucket js-select-menu-tab-bucket css-truncate" data-tab-filter="tags">
- <div data-filterable-for="commitish-filter-field" data-filterable-type="substring">
-
- <div class="select-menu-item js-navigation-item ">
- <span class="select-menu-item-icon octicon octicon-check"></span>
- <a href="/ipython/ipython/blob/rel-0.13.2/docs/sphinxext/github.py" class="js-navigation-open select-menu-item-text js-select-button-text css-truncate-target" data-name="rel-0.13.2" rel="nofollow" title="rel-0.13.2">rel-0.13.2</a>
- </div> <!-- /.select-menu-item -->
- <div class="select-menu-item js-navigation-item ">
- <span class="select-menu-item-icon octicon octicon-check"></span>
- <a href="/ipython/ipython/blob/rel-0.13.1/docs/sphinxext/github.py" class="js-navigation-open select-menu-item-text js-select-button-text css-truncate-target" data-name="rel-0.13.1" rel="nofollow" title="rel-0.13.1">rel-0.13.1</a>
- </div> <!-- /.select-menu-item -->
- <div class="select-menu-item js-navigation-item ">
- <span class="select-menu-item-icon octicon octicon-check"></span>
- <a href="/ipython/ipython/blob/rel-0.13/docs/sphinxext/github.py" class="js-navigation-open select-menu-item-text js-select-button-text css-truncate-target" data-name="rel-0.13" rel="nofollow" title="rel-0.13">rel-0.13</a>
- </div> <!-- /.select-menu-item -->
- <div class="select-menu-item js-navigation-item ">
- <span class="select-menu-item-icon octicon octicon-check"></span>
- <a href="/ipython/ipython/blob/rel-0.12.1/docs/sphinxext/github.py" class="js-navigation-open select-menu-item-text js-select-button-text css-truncate-target" data-name="rel-0.12.1" rel="nofollow" title="rel-0.12.1">rel-0.12.1</a>
- </div> <!-- /.select-menu-item -->
- <div class="select-menu-item js-navigation-item ">
- <span class="select-menu-item-icon octicon octicon-check"></span>
- <a href="/ipython/ipython/blob/rel-0.12/docs/sphinxext/github.py" class="js-navigation-open select-menu-item-text js-select-button-text css-truncate-target" data-name="rel-0.12" rel="nofollow" title="rel-0.12">rel-0.12</a>
- </div> <!-- /.select-menu-item -->
- <div class="select-menu-item js-navigation-item ">
- <span class="select-menu-item-icon octicon octicon-check"></span>
- <a href="/ipython/ipython/blob/rel-0.11/docs/sphinxext/github.py" class="js-navigation-open select-menu-item-text js-select-button-text css-truncate-target" data-name="rel-0.11" rel="nofollow" title="rel-0.11">rel-0.11</a>
- </div> <!-- /.select-menu-item -->
- <div class="select-menu-item js-navigation-item ">
- <span class="select-menu-item-icon octicon octicon-check"></span>
- <a href="/ipython/ipython/blob/rel-0.10.2/docs/sphinxext/github.py" class="js-navigation-open select-menu-item-text js-select-button-text css-truncate-target" data-name="rel-0.10.2" rel="nofollow" title="rel-0.10.2">rel-0.10.2</a>
- </div> <!-- /.select-menu-item -->
- <div class="select-menu-item js-navigation-item ">
- <span class="select-menu-item-icon octicon octicon-check"></span>
- <a href="/ipython/ipython/blob/rel-0.10.1/docs/sphinxext/github.py" class="js-navigation-open select-menu-item-text js-select-button-text css-truncate-target" data-name="rel-0.10.1" rel="nofollow" title="rel-0.10.1">rel-0.10.1</a>
- </div> <!-- /.select-menu-item -->
- <div class="select-menu-item js-navigation-item ">
- <span class="select-menu-item-icon octicon octicon-check"></span>
- <a href="/ipython/ipython/blob/rel-0.10/docs/sphinxext/github.py" class="js-navigation-open select-menu-item-text js-select-button-text css-truncate-target" data-name="rel-0.10" rel="nofollow" title="rel-0.10">rel-0.10</a>
- </div> <!-- /.select-menu-item -->
- <div class="select-menu-item js-navigation-item ">
- <span class="select-menu-item-icon octicon octicon-check"></span>
- <a href="/ipython/ipython/blob/rel-0.9.1/docs/sphinxext/github.py" class="js-navigation-open select-menu-item-text js-select-button-text css-truncate-target" data-name="rel-0.9.1" rel="nofollow" title="rel-0.9.1">rel-0.9.1</a>
- </div> <!-- /.select-menu-item -->
- <div class="select-menu-item js-navigation-item ">
- <span class="select-menu-item-icon octicon octicon-check"></span>
- <a href="/ipython/ipython/blob/rel-0.9/docs/sphinxext/github.py" class="js-navigation-open select-menu-item-text js-select-button-text css-truncate-target" data-name="rel-0.9" rel="nofollow" title="rel-0.9">rel-0.9</a>
- </div> <!-- /.select-menu-item -->
- <div class="select-menu-item js-navigation-item ">
- <span class="select-menu-item-icon octicon octicon-check"></span>
- <a href="/ipython/ipython/blob/rel-0.8.4/docs/sphinxext/github.py" class="js-navigation-open select-menu-item-text js-select-button-text css-truncate-target" data-name="rel-0.8.4" rel="nofollow" title="rel-0.8.4">rel-0.8.4</a>
- </div> <!-- /.select-menu-item -->
- <div class="select-menu-item js-navigation-item ">
- <span class="select-menu-item-icon octicon octicon-check"></span>
- <a href="/ipython/ipython/blob/dev-0.11/docs/sphinxext/github.py" class="js-navigation-open select-menu-item-text js-select-button-text css-truncate-target" data-name="dev-0.11" rel="nofollow" title="dev-0.11">dev-0.11</a>
- </div> <!-- /.select-menu-item -->
- </div>
-
- <div class="select-menu-no-results">Nothing to show</div>
-
- </div> <!-- /.select-menu-list -->
-
- </div> <!-- /.select-menu-modal -->
- </div> <!-- /.select-menu-modal-holder -->
- </div> <!-- /.select-menu -->
-
- </div> <!-- /.scope -->
-
- <ul class="tabnav-tabs">
- <li><a href="/ipython/ipython" class="selected js-selected-navigation-item tabnav-tab" data-selected-links="repo_source /ipython/ipython">Files</a></li>
- <li><a href="/ipython/ipython/commits/master" class="js-selected-navigation-item tabnav-tab" data-selected-links="repo_commits /ipython/ipython/commits/master">Commits</a></li>
- <li><a href="/ipython/ipython/branches" class="js-selected-navigation-item tabnav-tab" data-selected-links="repo_branches /ipython/ipython/branches" rel="nofollow">Branches <span class="counter ">4</span></a></li>
- </ul>
-
-</div>
-
-
-
-
-
-
-
- </div>
- </div><!-- /.repohead -->
-
- <div id="js-repo-pjax-container" class="container context-loader-container" data-pjax-container>
-
-
-
-<!-- blob contrib key: blob_contributors:v21:5a715cc18d66347c4a5af2652afee082 -->
-<!-- blob contrib frag key: views10/v8/blob_contributors:v21:5a715cc18d66347c4a5af2652afee082 -->
-
-
-<div id="slider">
- <div class="frame-meta">
-
- <p title="This is a placeholder element" class="js-history-link-replace hidden"></p>
-
- <div class="breadcrumb">
- <span class='bold'><span itemscope="" itemtype="http://data-vocabulary.org/Breadcrumb"><a href="/ipython/ipython" class="js-slide-to" data-branch="master" data-direction="back" itemscope="url"><span itemprop="title">ipython</span></a></span></span><span class="separator"> / </span><span itemscope="" itemtype="http://data-vocabulary.org/Breadcrumb"><a href="/ipython/ipython/tree/master/docs" class="js-slide-to" data-branch="master" data-direction="back" itemscope="url"><span ite [...]
- </div>
-
- <a href="/ipython/ipython/find/master" class="js-slide-to" data-hotkey="t" style="display:none">Show File Finder</a>
-
-
- <div class="commit commit-loader file-history-tease js-deferred-content" data-url="/ipython/ipython/contributors/master/docs/sphinxext/github.py">
- Fetching contributors…
-
- <div class="participation">
- <p class="loader-loading"><img alt="Octocat-spinner-32-eaf2f5" height="16" src="https://a248.e.akamai.net/assets.github.com/images/spinners/octocat-spinner-32-EAF2F5.gif?1340659530" width="16" /></p>
- <p class="loader-error">Cannot retrieve contributors at this time</p>
- </div>
- </div>
-
- </div><!-- ./.frame-meta -->
-
- <div class="frames">
- <div class="frame" data-permalink-url="/ipython/ipython/blob/831d4eb049fa74f8be85ea7495a9724cb754390f/docs/sphinxext/github.py" data-title="ipython/docs/sphinxext/github.py at master · ipython/ipython · GitHub" data-type="blob">
-
- <div id="files" class="bubble">
- <div class="file">
- <div class="meta">
- <div class="info">
- <span class="icon"><b class="octicon octicon-file-text"></b></span>
- <span class="mode" title="File Mode">file</span>
- <span>156 lines (132 sloc)</span>
- <span>5.379 kb</span>
- </div>
- <div class="actions">
- <div class="button-group">
- <a class="minibutton js-entice" href=""
- data-entice="You must be signed in and on a branch to make or propose changes">Edit</a>
- <a href="/ipython/ipython/raw/master/docs/sphinxext/github.py" class="button minibutton " id="raw-url">Raw</a>
- <a href="/ipython/ipython/blame/master/docs/sphinxext/github.py" class="button minibutton ">Blame</a>
- <a href="/ipython/ipython/commits/master/docs/sphinxext/github.py" class="button minibutton " rel="nofollow">History</a>
- </div><!-- /.button-group -->
- </div><!-- /.actions -->
-
- </div>
- <div class="blob-wrapper data type-python js-blob-data">
- <table class="file-code file-diff">
- <tr class="file-code-line">
- <td class="blob-line-nums">
- <span id="L1" rel="#L1">1</span>
-<span id="L2" rel="#L2">2</span>
-<span id="L3" rel="#L3">3</span>
-<span id="L4" rel="#L4">4</span>
-<span id="L5" rel="#L5">5</span>
-<span id="L6" rel="#L6">6</span>
-<span id="L7" rel="#L7">7</span>
-<span id="L8" rel="#L8">8</span>
-<span id="L9" rel="#L9">9</span>
-<span id="L10" rel="#L10">10</span>
-<span id="L11" rel="#L11">11</span>
-<span id="L12" rel="#L12">12</span>
-<span id="L13" rel="#L13">13</span>
-<span id="L14" rel="#L14">14</span>
-<span id="L15" rel="#L15">15</span>
-<span id="L16" rel="#L16">16</span>
-<span id="L17" rel="#L17">17</span>
-<span id="L18" rel="#L18">18</span>
-<span id="L19" rel="#L19">19</span>
-<span id="L20" rel="#L20">20</span>
-<span id="L21" rel="#L21">21</span>
-<span id="L22" rel="#L22">22</span>
-<span id="L23" rel="#L23">23</span>
-<span id="L24" rel="#L24">24</span>
-<span id="L25" rel="#L25">25</span>
-<span id="L26" rel="#L26">26</span>
-<span id="L27" rel="#L27">27</span>
-<span id="L28" rel="#L28">28</span>
-<span id="L29" rel="#L29">29</span>
-<span id="L30" rel="#L30">30</span>
-<span id="L31" rel="#L31">31</span>
-<span id="L32" rel="#L32">32</span>
-<span id="L33" rel="#L33">33</span>
-<span id="L34" rel="#L34">34</span>
-<span id="L35" rel="#L35">35</span>
-<span id="L36" rel="#L36">36</span>
-<span id="L37" rel="#L37">37</span>
-<span id="L38" rel="#L38">38</span>
-<span id="L39" rel="#L39">39</span>
-<span id="L40" rel="#L40">40</span>
-<span id="L41" rel="#L41">41</span>
-<span id="L42" rel="#L42">42</span>
-<span id="L43" rel="#L43">43</span>
-<span id="L44" rel="#L44">44</span>
-<span id="L45" rel="#L45">45</span>
-<span id="L46" rel="#L46">46</span>
-<span id="L47" rel="#L47">47</span>
-<span id="L48" rel="#L48">48</span>
-<span id="L49" rel="#L49">49</span>
-<span id="L50" rel="#L50">50</span>
-<span id="L51" rel="#L51">51</span>
-<span id="L52" rel="#L52">52</span>
-<span id="L53" rel="#L53">53</span>
-<span id="L54" rel="#L54">54</span>
-<span id="L55" rel="#L55">55</span>
-<span id="L56" rel="#L56">56</span>
-<span id="L57" rel="#L57">57</span>
-<span id="L58" rel="#L58">58</span>
-<span id="L59" rel="#L59">59</span>
-<span id="L60" rel="#L60">60</span>
-<span id="L61" rel="#L61">61</span>
-<span id="L62" rel="#L62">62</span>
-<span id="L63" rel="#L63">63</span>
-<span id="L64" rel="#L64">64</span>
-<span id="L65" rel="#L65">65</span>
-<span id="L66" rel="#L66">66</span>
-<span id="L67" rel="#L67">67</span>
-<span id="L68" rel="#L68">68</span>
-<span id="L69" rel="#L69">69</span>
-<span id="L70" rel="#L70">70</span>
-<span id="L71" rel="#L71">71</span>
-<span id="L72" rel="#L72">72</span>
-<span id="L73" rel="#L73">73</span>
-<span id="L74" rel="#L74">74</span>
-<span id="L75" rel="#L75">75</span>
-<span id="L76" rel="#L76">76</span>
-<span id="L77" rel="#L77">77</span>
-<span id="L78" rel="#L78">78</span>
-<span id="L79" rel="#L79">79</span>
-<span id="L80" rel="#L80">80</span>
-<span id="L81" rel="#L81">81</span>
-<span id="L82" rel="#L82">82</span>
-<span id="L83" rel="#L83">83</span>
-<span id="L84" rel="#L84">84</span>
-<span id="L85" rel="#L85">85</span>
-<span id="L86" rel="#L86">86</span>
-<span id="L87" rel="#L87">87</span>
-<span id="L88" rel="#L88">88</span>
-<span id="L89" rel="#L89">89</span>
-<span id="L90" rel="#L90">90</span>
-<span id="L91" rel="#L91">91</span>
-<span id="L92" rel="#L92">92</span>
-<span id="L93" rel="#L93">93</span>
-<span id="L94" rel="#L94">94</span>
-<span id="L95" rel="#L95">95</span>
-<span id="L96" rel="#L96">96</span>
-<span id="L97" rel="#L97">97</span>
-<span id="L98" rel="#L98">98</span>
-<span id="L99" rel="#L99">99</span>
-<span id="L100" rel="#L100">100</span>
-<span id="L101" rel="#L101">101</span>
-<span id="L102" rel="#L102">102</span>
-<span id="L103" rel="#L103">103</span>
-<span id="L104" rel="#L104">104</span>
-<span id="L105" rel="#L105">105</span>
-<span id="L106" rel="#L106">106</span>
-<span id="L107" rel="#L107">107</span>
-<span id="L108" rel="#L108">108</span>
-<span id="L109" rel="#L109">109</span>
-<span id="L110" rel="#L110">110</span>
-<span id="L111" rel="#L111">111</span>
-<span id="L112" rel="#L112">112</span>
-<span id="L113" rel="#L113">113</span>
-<span id="L114" rel="#L114">114</span>
-<span id="L115" rel="#L115">115</span>
-<span id="L116" rel="#L116">116</span>
-<span id="L117" rel="#L117">117</span>
-<span id="L118" rel="#L118">118</span>
-<span id="L119" rel="#L119">119</span>
-<span id="L120" rel="#L120">120</span>
-<span id="L121" rel="#L121">121</span>
-<span id="L122" rel="#L122">122</span>
-<span id="L123" rel="#L123">123</span>
-<span id="L124" rel="#L124">124</span>
-<span id="L125" rel="#L125">125</span>
-<span id="L126" rel="#L126">126</span>
-<span id="L127" rel="#L127">127</span>
-<span id="L128" rel="#L128">128</span>
-<span id="L129" rel="#L129">129</span>
-<span id="L130" rel="#L130">130</span>
-<span id="L131" rel="#L131">131</span>
-<span id="L132" rel="#L132">132</span>
-<span id="L133" rel="#L133">133</span>
-<span id="L134" rel="#L134">134</span>
-<span id="L135" rel="#L135">135</span>
-<span id="L136" rel="#L136">136</span>
-<span id="L137" rel="#L137">137</span>
-<span id="L138" rel="#L138">138</span>
-<span id="L139" rel="#L139">139</span>
-<span id="L140" rel="#L140">140</span>
-<span id="L141" rel="#L141">141</span>
-<span id="L142" rel="#L142">142</span>
-<span id="L143" rel="#L143">143</span>
-<span id="L144" rel="#L144">144</span>
-<span id="L145" rel="#L145">145</span>
-<span id="L146" rel="#L146">146</span>
-<span id="L147" rel="#L147">147</span>
-<span id="L148" rel="#L148">148</span>
-<span id="L149" rel="#L149">149</span>
-<span id="L150" rel="#L150">150</span>
-<span id="L151" rel="#L151">151</span>
-<span id="L152" rel="#L152">152</span>
-<span id="L153" rel="#L153">153</span>
-<span id="L154" rel="#L154">154</span>
-<span id="L155" rel="#L155">155</span>
-
- </td>
- <td class="blob-line-code">
- <div class="highlight"><pre><div class='line' id='LC1'><span class="sd">"""Define text roles for GitHub</span></div><div class='line' id='LC2'><br/></div><div class='line' id='LC3'><span class="sd">* ghissue - Issue</span></div><div class='line' id='LC4'><span class="sd">* ghpull - Pull Request</span></div><div class='line' id='LC5'><span class="sd">* ghuser - User</span></div><div class='line' id='LC6'><br/></div><div class='line' id='LC7'><span class="s [...]
- </td>
- </tr>
- </table>
- </div>
-
- </div>
- </div>
-
- <a href="#jump-to-line" rel="facebox" data-hotkey="l" class="js-jump-to-line" style="display:none">Jump to Line</a>
- <div id="jump-to-line" style="display:none">
- <h2>Jump to Line</h2>
- <form accept-charset="UTF-8" class="js-jump-to-line-form">
- <input class="textfield js-jump-to-line-field" type="text">
- <div class="full-button">
- <button type="submit" class="button">Go</button>
- </div>
- </form>
- </div>
-
- </div>
- </div>
-</div>
-
-<div id="js-frame-loading-template" class="frame frame-loading large-loading-area" style="display:none;">
- <img class="js-frame-loading-spinner" src="https://a248.e.akamai.net/assets.github.com/images/spinners/octocat-spinner-128.gif?1347543525" height="64" width="64">
-</div>
-
-
- </div>
- </div>
- <div class="modal-backdrop"></div>
- </div>
-
- <div id="footer-push"></div><!-- hack for sticky footer -->
- </div><!-- end of wrapper - hack for sticky footer -->
-
- <!-- footer -->
- <div id="footer">
- <div class="container clearfix">
-
- <dl class="footer_nav">
- <dt>GitHub</dt>
- <dd><a href="https://github.com/about">About us</a></dd>
- <dd><a href="https://github.com/blog">Blog</a></dd>
- <dd><a href="https://github.com/contact">Contact & support</a></dd>
- <dd><a href="http://enterprise.github.com/">GitHub Enterprise</a></dd>
- <dd><a href="http://status.github.com/">Site status</a></dd>
- </dl>
-
- <dl class="footer_nav">
- <dt>Applications</dt>
- <dd><a href="http://mac.github.com/">GitHub for Mac</a></dd>
- <dd><a href="http://windows.github.com/">GitHub for Windows</a></dd>
- <dd><a href="http://eclipse.github.com/">GitHub for Eclipse</a></dd>
- <dd><a href="http://mobile.github.com/">GitHub mobile apps</a></dd>
- </dl>
-
- <dl class="footer_nav">
- <dt>Services</dt>
- <dd><a href="http://get.gaug.es/">Gauges: Web analytics</a></dd>
- <dd><a href="http://speakerdeck.com">Speaker Deck: Presentations</a></dd>
- <dd><a href="https://gist.github.com">Gist: Code snippets</a></dd>
- <dd><a href="http://jobs.github.com/">Job board</a></dd>
- </dl>
-
- <dl class="footer_nav">
- <dt>Documentation</dt>
- <dd><a href="http://help.github.com/">GitHub Help</a></dd>
- <dd><a href="http://developer.github.com/">Developer API</a></dd>
- <dd><a href="http://github.github.com/github-flavored-markdown/">GitHub Flavored Markdown</a></dd>
- <dd><a href="http://pages.github.com/">GitHub Pages</a></dd>
- </dl>
-
- <dl class="footer_nav">
- <dt>More</dt>
- <dd><a href="http://training.github.com/">Training</a></dd>
- <dd><a href="https://github.com/edu">Students & teachers</a></dd>
- <dd><a href="http://shop.github.com">The Shop</a></dd>
- <dd><a href="/plans">Plans & pricing</a></dd>
- <dd><a href="http://octodex.github.com/">The Octodex</a></dd>
- </dl>
-
- <hr class="footer-divider">
-
-
- <p class="right">© 2013 <span title="0.12974s from fe17.rs.github.com">GitHub</span>, Inc. All rights reserved.</p>
- <a class="left" href="https://github.com/">
- <span class="mega-octicon octicon-mark-github"></span>
- </a>
- <ul id="legal">
- <li><a href="https://github.com/site/terms">Terms of Service</a></li>
- <li><a href="https://github.com/site/privacy">Privacy</a></li>
- <li><a href="https://github.com/security">Security</a></li>
- </ul>
-
- </div><!-- /.container -->
-
-</div><!-- /.#footer -->
-
-
- <div class="fullscreen-overlay js-fullscreen-overlay" id="fullscreen_overlay">
- <div class="fullscreen-container js-fullscreen-container">
- <div class="textarea-wrap">
- <textarea name="fullscreen-contents" id="fullscreen-contents" class="js-fullscreen-contents" placeholder="" data-suggester="fullscreen_suggester"></textarea>
- <div class="suggester-container">
- <div class="suggester fullscreen-suggester js-navigation-container" id="fullscreen_suggester"
- data-url="/ipython/ipython/suggestions/commit">
- </div>
- </div>
- </div>
- </div>
- <div class="fullscreen-sidebar">
- <a href="#" class="exit-fullscreen js-exit-fullscreen tooltipped leftwards" title="Exit Zen Mode">
- <span class="mega-octicon octicon-screen-normal"></span>
- </a>
- <a href="#" class="theme-switcher js-theme-switcher tooltipped leftwards"
- title="Switch themes">
- <span class="octicon octicon-color-mode"></span>
- </a>
- </div>
-</div>
-
-
-
- <div id="ajax-error-message" class="flash flash-error">
- <span class="octicon octicon-alert"></span>
- Something went wrong with that request. Please try again.
- <a href="#" class="octicon octicon-remove-close ajax-error-dismiss"></a>
- </div>
-
-
-
- <span id='server_response_time' data-time='0.13024' data-host='fe17'></span>
-
- </body>
-</html>
-
diff --git a/doc/_extensions/hidden_code_block.py b/doc/_extensions/hidden_code_block.py
deleted file mode 100644
index e9ee9fe..0000000
--- a/doc/_extensions/hidden_code_block.py
+++ /dev/null
@@ -1,128 +0,0 @@
-"""Simple, inelegant Sphinx extension which adds a directive for a
-highlighted code-block that may be toggled hidden and shown in HTML.
-This is possibly useful for teaching courses.
-
-The directive, like the standard code-block directive, takes
-a language argument and an optional linenos parameter. The
-hidden-code-block adds starthidden and label as optional
-parameters.
-
-Examples:
-
-.. hidden-code-block:: python
- :starthidden: False
-
- a = 10
- b = a + 5
-
-.. hidden-code-block:: python
- :label: --- SHOW/HIDE ---
-
- x = 10
- y = x + 5
-
-Thanks to http://www.javascriptkit.com/javatutors/dom3.shtml for
-inspiration on the javascript.
-
-Thanks to Milad 'animal' Fatenejad for suggesting this extension
-in the first place.
-
-Written by Anthony 'el Scopz' Scopatz, January 2012.
-
-Released under the WTFPL (http://sam.zoy.org/wtfpl/).
-"""
-
-from docutils import nodes
-from docutils.parsers.rst import directives
-from sphinx.directives.code import CodeBlock
-from sphinx.util.compat import make_admonition
-
-HCB_COUNTER = 0
-
-js_showhide = """\
-<script type="text/javascript">
- function showhide(element){
- if (!document.getElementById)
- return
-
- if (element.style.display == "block")
- element.style.display = "none"
- else
- element.style.display = "block"
- };
-</script>
-"""
-
-def nice_bool(arg):
- tvalues = ('true', 't', 'yes', 'y')
- fvalues = ('false', 'f', 'no', 'n')
- arg = directives.choice(arg, tvalues + fvalues)
- return arg in tvalues
-
-
-class hidden_code_block(nodes.General, nodes.FixedTextElement):
- pass
-
-
-class HiddenCodeBlock(CodeBlock):
- """Hidden code block is Hidden"""
-
- option_spec = dict(starthidden=nice_bool,
- label=str,
- **CodeBlock.option_spec)
-
- def run(self):
- # Body of the method is more or less copied from CodeBlock
- code = u'\n'.join(self.content)
- hcb = hidden_code_block(code, code)
- hcb['language'] = self.arguments[0]
- hcb['linenos'] = 'linenos' in self.options
- hcb['starthidden'] = self.options.get('starthidden', True)
- hcb['label'] = self.options.get('label', '+ show/hide code')
- hcb.line = self.lineno
- return [hcb]
-
-
-def visit_hcb_html(self, node):
- """Visit hidden code block"""
- global HCB_COUNTER
- HCB_COUNTER += 1
-
- # We want to use the original highlighter so that we don't
- # have to reimplement it. However it raises a SkipNode
- # error at the end of the function call. Thus we intercept
- # it and raise it again later.
- try:
- self.visit_literal_block(node)
- except nodes.SkipNode:
- pass
-
- # The last element of the body should be the literal code
- # block that was just made.
- code_block = self.body[-1]
-
- fill_header = {'divname': 'hiddencodeblock{}'.format(HCB_COUNTER),
- 'startdisplay': 'none' if node['starthidden'] else 'block',
- 'label': node.get('label'),
- }
-
- divheader = ("""<a href="javascript:showhide(document.getElementById('{divname}'))">"""
- """{label}</a><br />"""
- '''<div id="{divname}" style="display: {startdisplay}">'''
- ).format(**fill_header)
-
- code_block = js_showhide + divheader + code_block + "</div>"
-
- # reassign and exit
- self.body[-1] = code_block
- raise nodes.SkipNode
-
-
-def depart_hcb_html(self, node):
- """Depart hidden code block"""
- # Stub because of SkipNode in visit
-
-
-def setup(app):
- app.add_directive('hidden-code-block', HiddenCodeBlock)
- app.add_node(hidden_code_block, html=(visit_hcb_html, depart_hcb_html))
diff --git a/doc/_extensions/inheritance_diagram.py b/doc/_extensions/inheritance_diagram.py
deleted file mode 100644
index 407fc13..0000000
--- a/doc/_extensions/inheritance_diagram.py
+++ /dev/null
@@ -1,407 +0,0 @@
-"""
-Defines a docutils directive for inserting inheritance diagrams.
-
-Provide the directive with one or more classes or modules (separated
-by whitespace). For modules, all of the classes in that module will
-be used.
-
-Example::
-
- Given the following classes:
-
- class A: pass
- class B(A): pass
- class C(A): pass
- class D(B, C): pass
- class E(B): pass
-
- .. inheritance-diagram: D E
-
- Produces a graph like the following:
-
- A
- / \
- B C
- / \ /
- E D
-
-The graph is inserted as a PNG+image map into HTML and a PDF in
-LaTeX.
-"""
-
-import inspect
-import os
-import re
-import subprocess
-try:
- from hashlib import md5
-except ImportError:
- from md5 import md5
-
-from docutils.nodes import Body, Element
-from docutils.parsers.rst import directives
-from sphinx.roles import xfileref_role
-
-def my_import(name):
- """Module importer - taken from the python documentation.
-
- This function allows importing names with dots in them."""
-
- mod = __import__(name)
- components = name.split('.')
- for comp in components[1:]:
- mod = getattr(mod, comp)
- return mod
-
-class DotException(Exception):
- pass
-
-class InheritanceGraph(object):
- """
- Given a list of classes, determines the set of classes that
- they inherit from all the way to the root "object", and then
- is able to generate a graphviz dot graph from them.
- """
- def __init__(self, class_names, show_builtins=False):
- """
- *class_names* is a list of child classes to show bases from.
-
- If *show_builtins* is True, then Python builtins will be shown
- in the graph.
- """
- self.class_names = class_names
- self.classes = self._import_classes(class_names)
- self.all_classes = self._all_classes(self.classes)
- if len(self.all_classes) == 0:
- raise ValueError("No classes found for inheritance diagram")
- self.show_builtins = show_builtins
-
- py_sig_re = re.compile(r'''^([\w.]*\.)? # class names
- (\w+) \s* $ # optionally arguments
- ''', re.VERBOSE)
-
- def _import_class_or_module(self, name):
- """
- Import a class using its fully-qualified *name*.
- """
- try:
- path, base = self.py_sig_re.match(name).groups()
- except:
- raise ValueError(
- "Invalid class or module '%s' specified for inheritance diagram" % name)
- fullname = (path or '') + base
- path = (path and path.rstrip('.'))
- if not path:
- path = base
- try:
- module = __import__(path, None, None, [])
- # We must do an import of the fully qualified name. Otherwise if a
- # subpackage 'a.b' is requested where 'import a' does NOT provide
- # 'a.b' automatically, then 'a.b' will not be found below. This
- # second call will force the equivalent of 'import a.b' to happen
- # after the top-level import above.
- my_import(fullname)
-
- except ImportError:
- raise ValueError(
- "Could not import class or module '%s' specified for inheritance diagram" % name)
-
- try:
- todoc = module
- for comp in fullname.split('.')[1:]:
- todoc = getattr(todoc, comp)
- except AttributeError:
- raise ValueError(
- "Could not find class or module '%s' specified for inheritance diagram" % name)
-
- # If a class, just return it
- if inspect.isclass(todoc):
- return [todoc]
- elif inspect.ismodule(todoc):
- classes = []
- for cls in todoc.__dict__.values():
- if inspect.isclass(cls) and cls.__module__ == todoc.__name__:
- classes.append(cls)
- return classes
- raise ValueError(
- "'%s' does not resolve to a class or module" % name)
-
- def _import_classes(self, class_names):
- """
- Import a list of classes.
- """
- classes = []
- for name in class_names:
- classes.extend(self._import_class_or_module(name))
- return classes
-
- def _all_classes(self, classes):
- """
- Return a list of all classes that are ancestors of *classes*.
- """
- all_classes = {}
-
- def recurse(cls):
- all_classes[cls] = None
- for c in cls.__bases__:
- if c not in all_classes:
- recurse(c)
-
- for cls in classes:
- recurse(cls)
-
- return all_classes.keys()
-
- def class_name(self, cls, parts=0):
- """
- Given a class object, return a fully-qualified name. This
- works for things I've tested in matplotlib so far, but may not
- be completely general.
- """
- module = cls.__module__
- if module == '__builtin__':
- fullname = cls.__name__
- else:
- fullname = "%s.%s" % (module, cls.__name__)
- if parts == 0:
- return fullname
- name_parts = fullname.split('.')
- return '.'.join(name_parts[-parts:])
-
- def get_all_class_names(self):
- """
- Get all of the class names involved in the graph.
- """
- return [self.class_name(x) for x in self.all_classes]
-
- # These are the default options for graphviz
- default_graph_options = {
- "rankdir": "LR",
- "size": '"8.0, 12.0"'
- }
- default_node_options = {
- "shape": "box",
- "fontsize": 10,
- "height": 0.25,
- "fontname": "Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",
- "style": '"setlinewidth(0.5)"'
- }
- default_edge_options = {
- "arrowsize": 0.5,
- "style": '"setlinewidth(0.5)"'
- }
-
- def _format_node_options(self, options):
- return ','.join(["%s=%s" % x for x in options.items()])
- def _format_graph_options(self, options):
- return ''.join(["%s=%s;\n" % x for x in options.items()])
-
- def generate_dot(self, fd, name, parts=0, urls={},
- graph_options={}, node_options={},
- edge_options={}):
- """
- Generate a graphviz dot graph from the classes that
- were passed in to __init__.
-
- *fd* is a Python file-like object to write to.
-
- *name* is the name of the graph
-
- *urls* is a dictionary mapping class names to http urls
-
- *graph_options*, *node_options*, *edge_options* are
- dictionaries containing key/value pairs to pass on as graphviz
- properties.
- """
- g_options = self.default_graph_options.copy()
- g_options.update(graph_options)
- n_options = self.default_node_options.copy()
- n_options.update(node_options)
- e_options = self.default_edge_options.copy()
- e_options.update(edge_options)
-
- fd.write('digraph %s {\n' % name)
- fd.write(self._format_graph_options(g_options))
-
- for cls in self.all_classes:
- if not self.show_builtins and cls in __builtins__.values():
- continue
-
- name = self.class_name(cls, parts)
-
- # Write the node
- this_node_options = n_options.copy()
- url = urls.get(self.class_name(cls))
- if url is not None:
- this_node_options['URL'] = '"%s"' % url
- fd.write(' "%s" [%s];\n' %
- (name, self._format_node_options(this_node_options)))
-
- # Write the edges
- for base in cls.__bases__:
- if not self.show_builtins and base in __builtins__.values():
- continue
-
- base_name = self.class_name(base, parts)
- fd.write(' "%s" -> "%s" [%s];\n' %
- (base_name, name,
- self._format_node_options(e_options)))
- fd.write('}\n')
-
- def run_dot(self, args, name, parts=0, urls={},
- graph_options={}, node_options={}, edge_options={}):
- """
- Run graphviz 'dot' over this graph, returning whatever 'dot'
- writes to stdout.
-
- *args* will be passed along as commandline arguments.
-
- *name* is the name of the graph
-
- *urls* is a dictionary mapping class names to http urls
-
- Raises DotException for any of the many os and
- installation-related errors that may occur.
- """
- try:
- dot = subprocess.Popen(['dot'] + list(args),
- stdin=subprocess.PIPE, stdout=subprocess.PIPE,
- close_fds=True)
- except OSError:
- raise DotException("Could not execute 'dot'. Are you sure you have 'graphviz' installed?")
- except ValueError:
- raise DotException("'dot' called with invalid arguments")
- except:
- raise DotException("Unexpected error calling 'dot'")
-
- self.generate_dot(dot.stdin, name, parts, urls, graph_options,
- node_options, edge_options)
- dot.stdin.close()
- result = dot.stdout.read()
- returncode = dot.wait()
- if returncode != 0:
- raise DotException("'dot' returned the errorcode %d" % returncode)
- return result
-
-class inheritance_diagram(Body, Element):
- """
- A docutils node to use as a placeholder for the inheritance
- diagram.
- """
- pass
-
-def inheritance_diagram_directive(name, arguments, options, content, lineno,
- content_offset, block_text, state,
- state_machine):
- """
- Run when the inheritance_diagram directive is first encountered.
- """
- node = inheritance_diagram()
-
- class_names = arguments
-
- # Create a graph starting with the list of classes
- graph = InheritanceGraph(class_names)
-
- # Create xref nodes for each target of the graph's image map and
- # add them to the doc tree so that Sphinx can resolve the
- # references to real URLs later. These nodes will eventually be
- # removed from the doctree after we're done with them.
- for name in graph.get_all_class_names():
- refnodes, x = xfileref_role(
- 'class', ':class:`%s`' % name, name, 0, state)
- node.extend(refnodes)
- # Store the graph object so we can use it to generate the
- # dot file later
- node['graph'] = graph
- # Store the original content for use as a hash
- node['parts'] = options.get('parts', 0)
- node['content'] = " ".join(class_names)
- return [node]
-
-def get_graph_hash(node):
- return md5(node['content'] + str(node['parts'])).hexdigest()[-10:]
-
-def html_output_graph(self, node):
- """
- Output the graph for HTML. This will insert a PNG with clickable
- image map.
- """
- graph = node['graph']
- parts = node['parts']
-
- graph_hash = get_graph_hash(node)
- name = "inheritance%s" % graph_hash
- path = '_images'
- dest_path = os.path.join(setup.app.builder.outdir, path)
- if not os.path.exists(dest_path):
- os.makedirs(dest_path)
- png_path = os.path.join(dest_path, name + ".png")
- path = setup.app.builder.imgpath
-
- # Create a mapping from fully-qualified class names to URLs.
- urls = {}
- for child in node:
- if child.get('refuri') is not None:
- urls[child['reftitle']] = child.get('refuri')
- elif child.get('refid') is not None:
- urls[child['reftitle']] = '#' + child.get('refid')
-
- # These arguments to dot will save a PNG file to disk and write
- # an HTML image map to stdout.
- image_map = graph.run_dot(['-Tpng', '-o%s' % png_path, '-Tcmapx'],
- name, parts, urls)
- return ('<img src="%s/%s.png" usemap="#%s" class="inheritance"/>%s' %
- (path, name, name, image_map))
-
-def latex_output_graph(self, node):
- """
- Output the graph for LaTeX. This will insert a PDF.
- """
- graph = node['graph']
- parts = node['parts']
-
- graph_hash = get_graph_hash(node)
- name = "inheritance%s" % graph_hash
- dest_path = os.path.abspath(os.path.join(setup.app.builder.outdir, '_images'))
- if not os.path.exists(dest_path):
- os.makedirs(dest_path)
- pdf_path = os.path.abspath(os.path.join(dest_path, name + ".pdf"))
-
- graph.run_dot(['-Tpdf', '-o%s' % pdf_path],
- name, parts, graph_options={'size': '"6.0,6.0"'})
- return '\n\\includegraphics{%s}\n\n' % pdf_path
-
-def visit_inheritance_diagram(inner_func):
- """
- This is just a wrapper around html/latex_output_graph to make it
- easier to handle errors and insert warnings.
- """
- def visitor(self, node):
- try:
- content = inner_func(self, node)
- except DotException, e:
- # Insert the exception as a warning in the document
- warning = self.document.reporter.warning(str(e), line=node.line)
- warning.parent = node
- node.children = [warning]
- else:
- source = self.document.attributes['source']
- self.body.append(content)
- node.children = []
- return visitor
-
-def do_nothing(self, node):
- pass
-
-def setup(app):
- setup.app = app
- setup.confdir = app.confdir
-
- app.add_node(
- inheritance_diagram,
- latex=(visit_inheritance_diagram(latex_output_graph), do_nothing),
- html=(visit_inheritance_diagram(html_output_graph), do_nothing))
- app.add_directive(
- 'inheritance-diagram', inheritance_diagram_directive,
- False, (1, 100, 0), parts = directives.nonnegative_int)
diff --git a/doc/_extensions/ipython_console_highlighting.py b/doc/_extensions/ipython_console_highlighting.py
deleted file mode 100644
index 217b779..0000000
--- a/doc/_extensions/ipython_console_highlighting.py
+++ /dev/null
@@ -1,114 +0,0 @@
-"""reST directive for syntax-highlighting ipython interactive sessions.
-
-XXX - See what improvements can be made based on the new (as of Sept 2009)
-'pycon' lexer for the python console. At the very least it will give better
-highlighted tracebacks.
-"""
-
-#-----------------------------------------------------------------------------
-# Needed modules
-
-# Standard library
-import re
-
-# Third party
-from pygments.lexer import Lexer, do_insertions
-from pygments.lexers.agile import (PythonConsoleLexer, PythonLexer,
- PythonTracebackLexer)
-from pygments.token import Comment, Generic
-
-from sphinx import highlighting
-
-#-----------------------------------------------------------------------------
-# Global constants
-line_re = re.compile('.*?\n')
-
-#-----------------------------------------------------------------------------
-# Code begins - classes and functions
-
-class IPythonConsoleLexer(Lexer):
- """
- For IPython console output or doctests, such as:
-
- .. sourcecode:: ipython
-
- In [1]: a = 'foo'
-
- In [2]: a
- Out[2]: 'foo'
-
- In [3]: print a
- foo
-
- In [4]: 1 / 0
-
- Notes:
-
- - Tracebacks are not currently supported.
-
- - It assumes the default IPython prompts, not customized ones.
- """
-
- name = 'IPython console session'
- aliases = ['ipython']
- mimetypes = ['text/x-ipython-console']
- input_prompt = re.compile("(In \[[0-9]+\]: )|( \.\.\.+:)")
- output_prompt = re.compile("(Out\[[0-9]+\]: )|( \.\.\.+:)")
- continue_prompt = re.compile(" \.\.\.+:")
- tb_start = re.compile("\-+")
-
- def get_tokens_unprocessed(self, text):
- pylexer = PythonLexer(**self.options)
- tblexer = PythonTracebackLexer(**self.options)
-
- curcode = ''
- insertions = []
- for match in line_re.finditer(text):
- line = match.group()
- input_prompt = self.input_prompt.match(line)
- continue_prompt = self.continue_prompt.match(line.rstrip())
- output_prompt = self.output_prompt.match(line)
- if line.startswith("#"):
- insertions.append((len(curcode),
- [(0, Comment, line)]))
- elif input_prompt is not None:
- insertions.append((len(curcode),
- [(0, Generic.Prompt, input_prompt.group())]))
- curcode += line[input_prompt.end():]
- elif continue_prompt is not None:
- insertions.append((len(curcode),
- [(0, Generic.Prompt, continue_prompt.group())]))
- curcode += line[continue_prompt.end():]
- elif output_prompt is not None:
- # Use the 'error' token for output. We should probably make
- # our own token, but error is typicaly in a bright color like
- # red, so it works fine for our output prompts.
- insertions.append((len(curcode),
- [(0, Generic.Error, output_prompt.group())]))
- curcode += line[output_prompt.end():]
- else:
- if curcode:
- for item in do_insertions(insertions,
- pylexer.get_tokens_unprocessed(curcode)):
- yield item
- curcode = ''
- insertions = []
- yield match.start(), Generic.Output, line
- if curcode:
- for item in do_insertions(insertions,
- pylexer.get_tokens_unprocessed(curcode)):
- yield item
-
-
-def setup(app):
- """Setup as a sphinx extension."""
-
- # This is only a lexer, so adding it below to pygments appears sufficient.
- # But if somebody knows that the right API usage should be to do that via
- # sphinx, by all means fix it here. At least having this setup.py
- # suppresses the sphinx warning we'd get without it.
- pass
-
-#-----------------------------------------------------------------------------
-# Register the extension as a valid pygments lexer
-highlighting.lexers['ipython'] = IPythonConsoleLexer()
diff --git a/doc/_extensions/ipython_directive.py b/doc/_extensions/ipython_directive.py
deleted file mode 100644
index e69de29..0000000
diff --git a/doc/_extensions/numpydoc.py b/doc/_extensions/numpydoc.py
deleted file mode 100644
index ff6c44c..0000000
--- a/doc/_extensions/numpydoc.py
+++ /dev/null
@@ -1,116 +0,0 @@
-"""
-========
-numpydoc
-========
-
-Sphinx extension that handles docstrings in the Numpy standard format. [1]
-
-It will:
-
-- Convert Parameters etc. sections to field lists.
-- Convert See Also section to a See also entry.
-- Renumber references.
-- Extract the signature from the docstring, if it can't be determined otherwise.
-
-.. [1] http://projects.scipy.org/scipy/numpy/wiki/CodingStyleGuidelines#docstring-standard
-
-"""
-
-import os, re, pydoc
-from docscrape_sphinx import get_doc_object, SphinxDocString
-import inspect
-
-def mangle_docstrings(app, what, name, obj, options, lines,
- reference_offset=[0]):
- if what == 'module':
- # Strip top title
- title_re = re.compile(r'^\s*[#*=]{4,}\n[a-z0-9 -]+\n[#*=]{4,}\s*',
- re.I|re.S)
- lines[:] = title_re.sub('', "\n".join(lines)).split("\n")
- else:
- doc = get_doc_object(obj, what, "\n".join(lines))
- lines[:] = str(doc).split("\n")
-
- if app.config.numpydoc_edit_link and hasattr(obj, '__name__') and \
- obj.__name__:
- if hasattr(obj, '__module__'):
- v = dict(full_name="%s.%s" % (obj.__module__, obj.__name__))
- else:
- v = dict(full_name=obj.__name__)
- lines += ['', '.. htmlonly::', '']
- lines += [' %s' % x for x in
- (app.config.numpydoc_edit_link % v).split("\n")]
-
- # replace reference numbers so that there are no duplicates
- references = []
- for l in lines:
- l = l.strip()
- if l.startswith('.. ['):
- try:
- references.append(int(l[len('.. ['):l.index(']')]))
- except ValueError:
- print "WARNING: invalid reference in %s docstring" % name
-
- # Start renaming from the biggest number, otherwise we may
- # overwrite references.
- references.sort()
- if references:
- for i, line in enumerate(lines):
- for r in references:
- new_r = reference_offset[0] + r
- lines[i] = lines[i].replace('[%d]_' % r,
- '[%d]_' % new_r)
- lines[i] = lines[i].replace('.. [%d]' % r,
- '.. [%d]' % new_r)
-
- reference_offset[0] += len(references)
-
-def mangle_signature(app, what, name, obj, options, sig, retann):
- # Do not try to inspect classes that don't define `__init__`
- if (inspect.isclass(obj) and
- 'initializes x; see ' in pydoc.getdoc(obj.__init__)):
- return '', ''
-
- if not (callable(obj) or hasattr(obj, '__argspec_is_invalid_')): return
- if not hasattr(obj, '__doc__'): return
-
- doc = SphinxDocString(pydoc.getdoc(obj))
- if doc['Signature']:
- sig = re.sub("^[^(]*", "", doc['Signature'])
- return sig, ''
-
-def initialize(app):
- try:
- app.connect('autodoc-process-signature', mangle_signature)
- except:
- monkeypatch_sphinx_ext_autodoc()
-
-def setup(app, get_doc_object_=get_doc_object):
- global get_doc_object
- get_doc_object = get_doc_object_
-
- app.connect('autodoc-process-docstring', mangle_docstrings)
- app.connect('builder-inited', initialize)
- app.add_config_value('numpydoc_edit_link', None, True)
-
-#------------------------------------------------------------------------------
-# Monkeypatch sphinx.ext.autodoc to accept argspecless autodocs (Sphinx < 0.5)
-#------------------------------------------------------------------------------
-
-def monkeypatch_sphinx_ext_autodoc():
- global _original_format_signature
- import sphinx.ext.autodoc
-
- if sphinx.ext.autodoc.format_signature is our_format_signature:
- return
-
- print "[numpydoc] Monkeypatching sphinx.ext.autodoc ..."
- _original_format_signature = sphinx.ext.autodoc.format_signature
- sphinx.ext.autodoc.format_signature = our_format_signature
-
-def our_format_signature(what, obj):
- r = mangle_signature(None, what, None, obj, None, None, None)
- if r is not None:
- return r[0]
- else:
- return _original_format_signature(what, obj)
diff --git a/doc/conf.py b/doc/conf.py
index ed3d742..e5fcc79 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
#
-# multipletau documentation build configuration file, created by
+# project documentation build configuration file, created by
# sphinx-quickstart on Sat Feb 22 09:35:49 2014.
#
# This file is execfile()d with the current directory set to its
@@ -20,12 +20,22 @@ import os
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.insert(0, os.path.abspath('.'))
-sys.path.insert(0, os.path.abspath('../multipletau'))
-sys.path.insert(0, os.path.abspath('../'))
-sys.path.append(os.path.abspath('_extensions'))
+sys.path.insert(0, os.path.abspath(os.path.join(os.path.abspath(
+ os.path.dirname(__file__)), '../')))
+
+sys.path.append(os.path.abspath('extensions'))
+
+# include examples
+sys.path.append(os.path.abspath(os.path.dirname(__file__)+"/../examples"))
+
+
+# There should be a file "setup.py" that has the property "version"
+from setup import author, authors, description, name, version, year
+projectname = name
+projectdescription = description
+
-import multipletau
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
@@ -48,19 +58,20 @@ extensions = [
# 'matplotlib.sphinxext.only_directives',
# 'matplotlib.sphinxext.plot_directive',
# 'sphinx.ext.viewcode',
-# 'ipython_directive',
+# 'ipython_directive',
'sphinx.ext.intersphinx',
-# 'sphinx.ext.autosummary',
+ 'sphinx.ext.autosummary',
'sphinx.ext.autodoc',
# 'sphinx.ext.doctest',
# 'ipython_console_highlighting',
-# 'sphinx.ext.pngmath',
+# 'sphinx.ext.pngmath',
'sphinx.ext.mathjax',
+# 'sphinx.ext.viewcode',
# 'sphinx.ext.todo',
-# 'inheritance_diagram',
+# 'inheritance_diagram',
'numpydoc',
+ 'myviewcode',
# 'hidden_code_block',
-# 'sphinx.ext.autosummary'
]
@@ -78,17 +89,16 @@ source_suffix = '.rst'
master_doc = 'index'
# General information about the project.
-project = u'multipletau'
-copyright = u'2014, Paul Müller'
+project = projectname
+copyright = year+", "+author
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
-version = multipletau.__version__
# The full version, including alpha/beta/rc tags.
-release = multipletau.__version__
+release = version
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
@@ -102,7 +112,6 @@ release = multipletau.__version__
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
-exclude_patterns = ['_build']
# The reST default role (used for this markup: `text`) to use for all
# documents.
@@ -133,12 +142,12 @@ exclude_patterns = ['_build']
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
-html_theme = 'nature'
+html_theme = 'classic'
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
-#html_theme_options = {}
+html_theme_options = {"stickysidebar": True}
# Add any paths that contain custom themes here, relative to this directory.
#html_theme_path = []
@@ -211,7 +220,7 @@ html_theme = 'nature'
#html_file_suffix = None
# Output file base name for HTML help builder.
-htmlhelp_basename = 'multipletaudoc'
+htmlhelp_basename = projectname+'doc'
# -- Options for LaTeX output ---------------------------------------------
@@ -231,8 +240,8 @@ latex_elements = {
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
- ('index', 'multipletau.tex', u'multipletau Documentation',
- u'Paul Müller', 'manual'),
+ ('index', projectname+'.tex', projectname+' Documentation',
+ author, 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
@@ -261,8 +270,8 @@ latex_documents = [
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
- ('index', 'multipletau', u'multipletau Documentation',
- [u'Paul Müller'], 1)
+ ('index', projectname, projectname+' Documentation',
+ authors, 1)
]
# If true, show URL addresses after external links.
@@ -275,9 +284,9 @@ man_pages = [
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
- ('index', 'multipletau', u'multipletau Documentation',
- u'Paul Müller', 'multipletau',
- 'A multiple-tau algorithm that utilizes numpy.',
+ ('index', projectname, projectname+u' Documentation',
+ author, projectname,
+ projectdescription,
'Numeric'),
]
diff --git a/doc/deploy_ghpages.py b/doc/deploy_ghpages.py
new file mode 100644
index 0000000..1a98abf
--- /dev/null
+++ b/doc/deploy_ghpages.py
@@ -0,0 +1,83 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+"""
+Publish the documentation on GitHub Pages.
+
+Prerequisites
+-------------
+
+1. Create empty gh-pages branch:
+
+ git branch gh-pages
+ git checkout gh-pages
+ git symbolic-ref HEAD refs/heads/gh-pages
+ rm .git/index
+ git clean -fdx
+
+
+2. Setup sphinx.
+
+ python setup.py build_sphinx
+
+ should create a build/sphinx/html folder in the repository root.
+
+
+3. Create GitHub repo token and encrypt it
+
+ gem install travis
+ travis encrypt GH_TOKEN="<token>" --add
+
+
+4. Add the encrypted token to .travis.yml
+
+ env:
+ global:
+ - GH_REF: github.com/<your name>/<your repo>.git
+ - secure: "jdcn3kM/dI0zvVTn0UKgal8Br+745Qc1plaKXHcoKhwcwN+0Q1y5H1BnaF0KV2dWWeExVXMpqQMLOCylUSUmd30+hFqUgd3gFQ+oh9pF/+N72uzjnxHAyVjai5Lh7QnjN0SLCd2/xLYwaUIHjWbWsr5t2vK9UuyphZ6/F+7OHf+u8BErviE9HUunD7u4Q2XRaUF0oHuF8stoWbJgnQZtUZFr+qS1Gc3vF6/KBkMqjnq/DgBV61cWsnVUS1HVak/sGClPRXZMSGyz8d63zDxfA5NDO6AbPVgK02k+QV8KQCyIX7of8rBvBmWkBYGw5RnaeETLIAf6JrCKMiQzlJQZiMyLUvd/WflSIBKJyr5YmUKCjFkwvbKKvCU3WBUxFT2p7trKZip5JWg37OMvOAO8eiatf2FC1klNly1KHADU88QqNoi/0y2R/a+1Csrl8Gr/lXZkW4mMkI2due9epLwccDJtMF8 [...]
+
+5. Add the deploy command to .travis.yml
+
+ after_success:
+ - git config credential.helper "store --file=.git/credentials"
+ - echo "https://${GH_TOKEN}:@github.com" > .git/credentials
+ - if [[ $TRAVIS_PYTHON_VERSION == 3.4 ]]; then pip install numpydoc sphinx; fi
+ - if [[ $TRAVIS_PYTHON_VERSION == 3.4 ]]; then python doc/deploy_ghpages.py; fi
+
+"""
+from __future__ import print_function
+import os
+from os.path import dirname, abspath
+import subprocess as sp
+
+
+# go to root of repository
+os.chdir(dirname(dirname(abspath(__file__))))
+
+# build sphinx
+sp.check_output("python setup.py build_sphinx", shell=True)
+
+# clone into new folder the gh-pages branch
+sp.check_output("git config --global user.email 'travis at example.com'", shell=True)
+sp.check_output("git config --global user.name 'Travis CI'", shell=True)
+sp.check_output("git config --global credential.helper 'store --file=.git/credentials'", shell=True)
+sp.check_output("echo 'https://${GH_TOKEN}:@github.com' > .git/credentials", shell=True)
+sp.check_output("git clone --depth 1 -b gh-pages https://${GH_TOKEN}@${GH_REF} gh_pages", shell=True)
+
+# copy everything from ./build/sphinx/html to ./gh_pages
+#sp.check_output("cp -r ./build/sphinx/html/* ./gh_pages/", shell=True)
+sp.check_output("rsync -rt --del --exclude='.git' --exclude='.nojekyll' ./build/sphinx/html/* ./gh_pages/", shell=True)
+
+# commit changes
+os.chdir("gh_pages")
+sp.check_output("echo 'https://${GH_TOKEN}:@github.com' > .git/credentials", shell=True)
+sp.check_output("git add --all ./*", shell=True)
+
+try:
+ # If there is nothing to commit, then 'git commit' returns non-zero exit status
+ errorcode = sp.check_output("git commit -a -m 'travis bot build {} [ci skip]'".format(os.getenv("TRAVIS_COMMIT")), shell=True)
+ print("git commit returned:", errorcode)
+except:
+ pass
+else:
+ sp.check_output("git push --force --quiet origin gh-pages", shell=True)
+
diff --git a/doc/extensions/myviewcode.py b/doc/extensions/myviewcode.py
new file mode 100644
index 0000000..d49b435
--- /dev/null
+++ b/doc/extensions/myviewcode.py
@@ -0,0 +1,240 @@
+"""
+ sphinx.ext.viewcode
+ ~~~~~~~~~~~~~~~~~~~
+ Add links to module code in Python object descriptions.
+ :copyright: Copyright 2007-2015 by the Sphinx team, see AUTHORS.
+ :license: BSD, see LICENSE for details.
+
+ Edited by Paul Mueller to support imports from submodules. Uses the
+ importlib library. Changes marked with "## EDIT". 2015-02-22
+"""
+
+## EDIT
+import importlib
+##
+
+import traceback
+
+from six import iteritems, text_type
+from docutils import nodes
+
+import sphinx
+from sphinx import addnodes
+from sphinx.locale import _
+from sphinx.pycode import ModuleAnalyzer
+from sphinx.util import get_full_modname
+from sphinx.util.nodes import make_refnode
+from sphinx.util.console import blue
+
+
+def _get_full_modname(app, modname, attribute):
+ try:
+ return get_full_modname(modname, attribute)
+ except AttributeError:
+ # sphinx.ext.viewcode can't follow class instance attribute
+ # then AttributeError logging output only verbose mode.
+ app.verbose('Didn\'t find %s in %s' % (attribute, modname))
+ return None
+ except Exception as e:
+ # sphinx.ext.viewcode follow python domain directives.
+ # because of that, if there are no real modules exists that specified
+ # by py:function or other directives, viewcode emits a lot of warnings.
+ # It should be displayed only verbose mode.
+ app.verbose(traceback.format_exc().rstrip())
+ app.verbose('viewcode can\'t import %s, failed with error "%s"' %
+ (modname, e))
+ return None
+
+
+def doctree_read(app, doctree):
+ env = app.builder.env
+ if not hasattr(env, '_viewcode_modules'):
+ env._viewcode_modules = {}
+
+ def has_tag(modname, fullname, docname, refname):
+ entry = env._viewcode_modules.get(modname, None)
+ try:
+ analyzer = ModuleAnalyzer.for_module(modname)
+ except Exception:
+ env._viewcode_modules[modname] = False
+ return
+ if not isinstance(analyzer.code, text_type):
+ code = analyzer.code.decode(analyzer.encoding)
+ else:
+ code = analyzer.code
+ if entry is None or entry[0] != code:
+ analyzer.find_tags()
+ entry = code, analyzer.tags, {}, refname
+ env._viewcode_modules[modname] = entry
+ elif entry is False:
+ return
+ _, tags, used, _ = entry
+ if fullname in tags:
+ used[fullname] = docname
+ return True
+
+ for objnode in doctree.traverse(addnodes.desc):
+ if objnode.get('domain') != 'py':
+ continue
+ names = set()
+ for signode in objnode:
+ if not isinstance(signode, addnodes.desc_signature):
+ continue
+ modname = signode.get('module')
+ fullname = signode.get('fullname')
+ refname = modname
+ if env.config.viewcode_import:
+ modname = _get_full_modname(app, modname, fullname)
+ if not modname:
+ continue
+ fullname = signode.get('fullname')
+
+ ## EDIT
+ fullname, modname = find_modname(fullname, modname)
+ ##
+
+ if not has_tag(modname, fullname, env.docname, refname):
+ continue
+ if fullname in names:
+ # only one link per name, please
+ continue
+ names.add(fullname)
+ pagename = '_modules/' + modname.replace('.', '/')
+ onlynode = addnodes.only(expr='html')
+ onlynode += addnodes.pending_xref(
+ '', reftype='viewcode', refdomain='std', refexplicit=False,
+ reftarget=pagename, refid=fullname,
+ refdoc=env.docname)
+ onlynode[0] += nodes.inline('', _('[source]'),
+ classes=['viewcode-link'])
+ signode += onlynode
+
+
+def env_merge_info(app, env, docnames, other):
+ if not hasattr(other, '_viewcode_modules'):
+ return
+ # create a _viewcode_modules dict on the main environment
+ if not hasattr(env, '_viewcode_modules'):
+ env._viewcode_modules = {}
+ # now merge in the information from the subprocess
+ env._viewcode_modules.update(other._viewcode_modules)
+
+
+## EDIT
+def find_modname(fullname, modname):
+ mod = importlib.import_module(modname)
+ if hasattr(mod, fullname):
+ func = getattr(mod, fullname)
+ modname = func.__module__
+ fullname = func.__name__
+ return fullname, modname
+##
+
+
+def missing_reference(app, env, node, contnode):
+ # resolve our "viewcode" reference nodes -- they need special treatment
+ if node['reftype'] == 'viewcode':
+ return make_refnode(app.builder, node['refdoc'], node['reftarget'],
+ node['refid'], contnode)
+
+
+def collect_pages(app):
+ env = app.builder.env
+ if not hasattr(env, '_viewcode_modules'):
+ return
+ highlighter = app.builder.highlighter
+ urito = app.builder.get_relative_uri
+
+ modnames = set(env._viewcode_modules)
+
+# app.builder.info(' (%d module code pages)' %
+# len(env._viewcode_modules), nonl=1)
+
+ for modname, entry in app.status_iterator(
+ iteritems(env._viewcode_modules), 'highlighting module code... ',
+ blue, len(env._viewcode_modules), lambda x: x[0]):
+ if not entry:
+ continue
+ code, tags, used, refname = entry
+ # construct a page name for the highlighted source
+ pagename = '_modules/' + modname.replace('.', '/')
+ # highlight the source using the builder's highlighter
+ highlighted = highlighter.highlight_block(code, 'python', linenos=False)
+ # split the code into lines
+ lines = highlighted.splitlines()
+ # split off wrap markup from the first line of the actual code
+ before, after = lines[0].split('<pre>')
+ lines[0:1] = [before + '<pre>', after]
+ # nothing to do for the last line; it always starts with </pre> anyway
+ # now that we have code lines (starting at index 1), insert anchors for
+ # the collected tags (HACK: this only works if the tag boundaries are
+ # properly nested!)
+ maxindex = len(lines) - 1
+ for name, docname in iteritems(used):
+ type, start, end = tags[name]
+ backlink = urito(pagename, docname) + '#' + refname + '.' + name
+ lines[start] = (
+ '<div class="viewcode-block" id="%s"><a class="viewcode-back" '
+ 'href="%s">%s</a>' % (name, backlink, _('[docs]')) +
+ lines[start])
+ lines[min(end - 1, maxindex)] += '</div>'
+ # try to find parents (for submodules)
+ parents = []
+ parent = modname
+ while '.' in parent:
+ parent = parent.rsplit('.', 1)[0]
+ if parent in modnames:
+ parents.append({
+ 'link': urito(pagename, '_modules/' +
+ parent.replace('.', '/')),
+ 'title': parent})
+ parents.append({'link': urito(pagename, '_modules/index'),
+ 'title': _('Module code')})
+ parents.reverse()
+ # putting it all together
+ context = {
+ 'parents': parents,
+ 'title': modname,
+ 'body': (_('<h1>Source code for %s</h1>') % modname +
+ '\n'.join(lines)),
+ }
+ yield (pagename, context, 'page.html')
+
+ if not modnames:
+ return
+
+ html = ['\n']
+ # the stack logic is needed for using nested lists for submodules
+ stack = ['']
+ for modname in sorted(modnames):
+ if modname.startswith(stack[-1]):
+ stack.append(modname + '.')
+ html.append('<ul>')
+ else:
+ stack.pop()
+ while not modname.startswith(stack[-1]):
+ stack.pop()
+ html.append('</ul>')
+ stack.append(modname + '.')
+ html.append('<li><a href="%s">%s</a></li>\n' % (
+ urito('_modules/index', '_modules/' + modname.replace('.', '/')),
+ modname))
+ html.append('</ul>' * (len(stack) - 1))
+ context = {
+ 'title': _('Overview: module code'),
+ 'body': (_('<h1>All modules for which code is available</h1>') +
+ ''.join(html)),
+ }
+
+ yield ('_modules/index', context, 'page.html')
+
+
+def setup(app):
+ app.add_config_value('viewcode_import', True, False)
+ app.connect('doctree-read', doctree_read)
+ app.connect('env-merge-info', env_merge_info)
+ app.connect('html-collect-pages', collect_pages)
+ app.connect('missing-reference', missing_reference)
+ # app.add_config_value('viewcode_include_modules', [], 'env')
+ # app.add_config_value('viewcode_exclude_modules', [], 'env')
+ return {'version': sphinx.__display_version__, 'parallel_read_safe': True}
\ No newline at end of file
diff --git a/doc/index.rst b/doc/index.rst
index 2ae9de5..b0b6ab7 100644
--- a/doc/index.rst
+++ b/doc/index.rst
@@ -1,11 +1,38 @@
multipletau reference
=====================
+
+General
+:::::::
.. automodule:: multipletau
- :members: autocorrelate, correlate, correlate_numpy
+ :members:
+
+Methods
+:::::::
+
+Summary:
+
+.. autosummary::
+ autocorrelate
+ correlate
+ correlate_numpy
+
+For a quick overview, see :ref:`genindex`.
+
+Autocorrelation
+---------------
+.. autofunction:: autocorrelate
+
+Cross-correlation
+-----------------
+.. autofunction:: correlate
+
+Cross-correlation (NumPy)
+-------------------------
+.. autofunction:: correlate_numpy
-testing multipletau
-===================
-.. automodule:: test
+Examples
+========
+.. automodule:: compare_correlation_methods
:members:
diff --git a/doc/make.bat b/doc/make.bat
deleted file mode 100644
index cd549e4..0000000
--- a/doc/make.bat
+++ /dev/null
@@ -1,242 +0,0 @@
- at ECHO OFF
-
-REM Command file for Sphinx documentation
-
-if "%SPHINXBUILD%" == "" (
- set SPHINXBUILD=sphinx-build
-)
-set BUILDDIR=_build
-set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
-set I18NSPHINXOPTS=%SPHINXOPTS% .
-if NOT "%PAPER%" == "" (
- set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
- set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
-)
-
-if "%1" == "" goto help
-
-if "%1" == "help" (
- :help
- echo.Please use `make ^<target^>` where ^<target^> is one of
- echo. html to make standalone HTML files
- echo. dirhtml to make HTML files named index.html in directories
- echo. singlehtml to make a single large HTML file
- echo. pickle to make pickle files
- echo. json to make JSON files
- echo. htmlhelp to make HTML files and a HTML help project
- echo. qthelp to make HTML files and a qthelp project
- echo. devhelp to make HTML files and a Devhelp project
- echo. epub to make an epub
- echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
- echo. text to make text files
- echo. man to make manual pages
- echo. texinfo to make Texinfo files
- echo. gettext to make PO message catalogs
- echo. changes to make an overview over all changed/added/deprecated items
- echo. xml to make Docutils-native XML files
- echo. pseudoxml to make pseudoxml-XML files for display purposes
- echo. linkcheck to check all external links for integrity
- echo. doctest to run all doctests embedded in the documentation if enabled
- goto end
-)
-
-if "%1" == "clean" (
- for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
- del /q /s %BUILDDIR%\*
- goto end
-)
-
-
-%SPHINXBUILD% 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
-)
-
-if "%1" == "html" (
- %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The HTML pages are in %BUILDDIR%/html.
- goto end
-)
-
-if "%1" == "dirhtml" (
- %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
- goto end
-)
-
-if "%1" == "singlehtml" (
- %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
- goto end
-)
-
-if "%1" == "pickle" (
- %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished; now you can process the pickle files.
- goto end
-)
-
-if "%1" == "json" (
- %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished; now you can process the JSON files.
- goto end
-)
-
-if "%1" == "htmlhelp" (
- %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished; now you can run HTML Help Workshop with the ^
-.hhp project file in %BUILDDIR%/htmlhelp.
- goto end
-)
-
-if "%1" == "qthelp" (
- %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished; now you can run "qcollectiongenerator" with the ^
-.qhcp project file in %BUILDDIR%/qthelp, like this:
- echo.^> qcollectiongenerator %BUILDDIR%\qthelp\PKSLiver.qhcp
- echo.To view the help file:
- echo.^> assistant -collectionFile %BUILDDIR%\qthelp\PKSLiver.ghc
- goto end
-)
-
-if "%1" == "devhelp" (
- %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished.
- goto end
-)
-
-if "%1" == "epub" (
- %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The epub file is in %BUILDDIR%/epub.
- goto end
-)
-
-if "%1" == "latex" (
- %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
- goto end
-)
-
-if "%1" == "latexpdf" (
- %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
- cd %BUILDDIR%/latex
- make all-pdf
- cd %BUILDDIR%/..
- echo.
- echo.Build finished; the PDF files are in %BUILDDIR%/latex.
- goto end
-)
-
-if "%1" == "latexpdfja" (
- %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
- cd %BUILDDIR%/latex
- make all-pdf-ja
- cd %BUILDDIR%/..
- echo.
- echo.Build finished; the PDF files are in %BUILDDIR%/latex.
- goto end
-)
-
-if "%1" == "text" (
- %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The text files are in %BUILDDIR%/text.
- goto end
-)
-
-if "%1" == "man" (
- %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The manual pages are in %BUILDDIR%/man.
- goto end
-)
-
-if "%1" == "texinfo" (
- %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
- goto end
-)
-
-if "%1" == "gettext" (
- %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
- goto end
-)
-
-if "%1" == "changes" (
- %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
- if errorlevel 1 exit /b 1
- echo.
- echo.The overview file is in %BUILDDIR%/changes.
- goto end
-)
-
-if "%1" == "linkcheck" (
- %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
- if errorlevel 1 exit /b 1
- echo.
- echo.Link check complete; look for any errors in the above output ^
-or in %BUILDDIR%/linkcheck/output.txt.
- goto end
-)
-
-if "%1" == "doctest" (
- %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
- if errorlevel 1 exit /b 1
- echo.
- echo.Testing of doctests in the sources finished, look at the ^
-results in %BUILDDIR%/doctest/output.txt.
- goto end
-)
-
-if "%1" == "xml" (
- %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The XML files are in %BUILDDIR%/xml.
- goto end
-)
-
-if "%1" == "pseudoxml" (
- %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
- if errorlevel 1 exit /b 1
- echo.
- echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
- goto end
-)
-
-:end
diff --git a/doc/make.py b/doc/make.py
deleted file mode 100644
index adec117..0000000
--- a/doc/make.py
+++ /dev/null
@@ -1,14 +0,0 @@
-import os
-import sys
-sys.path.insert(0, '..')
-import shutil
-import fnmatch
-
-
-os.system('make html')
-
-# os.system('make latex')
-# olddir = os.curdir
-# os.chdir('_build\\latex\\')
-# os.system('pdflatex multipletau.tex')
-# os.chdir(olddir)
diff --git a/doc/testing_multipletau.png b/doc/testing_multipletau.png
deleted file mode 100644
index c1bdb0e..0000000
Binary files a/doc/testing_multipletau.png and /dev/null differ
diff --git a/examples/compare_correlation_methods.png b/examples/compare_correlation_methods.png
new file mode 100644
index 0000000..22543db
Binary files /dev/null and b/examples/compare_correlation_methods.png differ
diff --git a/test/__main__.py b/examples/compare_correlation_methods.py
similarity index 74%
rename from test/__main__.py
rename to examples/compare_correlation_methods.py
index a1f7bc9..361a0a0 100644
--- a/test/__main__.py
+++ b/examples/compare_correlation_methods.py
@@ -1,14 +1,32 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
-from .__init__ import noise_exponential, noise_cross_exponential
+"""
+Comparison of correlation methods
+---------------------------------
+Illustration of the difference between
+:py:func:`multipletau.correlate` and :py:func:`numpy.correlate`.
-def test():
- import numpy as np
- import os
- import sys
- from matplotlib import pylab as plt
- sys.path.append(os.path.realpath(os.path.dirname(__file__)+"/../"))
- from multipletau import autocorrelate, correlate, correlate_numpy
+.. image:: ../examples/compare_correlation_methods.png
+ :align: center
+
+Download the
+:download:`full example <../examples/compare_correlation_methods.py>`.
+"""
+from __future__ import print_function
+
+import numpy as np
+import os
+from os.path import abspath, dirname, join
+import sys
+import time
+
+sys.path.insert(0, dirname(dirname(abspath(__file__))))
+
+from noise_generator import noise_exponential, noise_cross_exponential
+from multipletau import autocorrelate, correlate, correlate_numpy
+
+
+def compare_corr():
## Starting parameters
N = np.int(np.pi*1e3)
countrate = 250. * 1e-3 # in Hz
@@ -100,9 +118,17 @@ def test():
plt.legend(loc=0, fontsize='small')
plt.ylim( -ampcc*.2, ampcc*1.2)
-
plt.tight_layout()
- plt.show()
+
+ savename = __file__[:-3]+".png"
+ if os.path.exists(savename):
+ savename = __file__[:-3]+time.strftime("_%Y-%m-%d_%H-%M-%S.png")
+
+ plt.savefig(savename)
+ print("Saved output to", savename)
+
if __name__ == '__main__':
- test()
+ # move mpl import to main so travis automated doc build does not complain
+ from matplotlib import pylab as plt
+ compare_corr()
diff --git a/test/__init__.py b/examples/noise_generator.py
similarity index 87%
rename from test/__init__.py
rename to examples/noise_generator.py
index a39687e..13a2cb8 100644
--- a/test/__init__.py
+++ b/examples/noise_generator.py
@@ -1,16 +1,8 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
-""" This module is used for testing the multiple-tau algorithm.
- Executing this module as a package by invoking
-
- python -m test
-
- creates plots that illustrate the difference between
- :py:func:`multipletau.correlate` and :py:func:`numpy.correlate`.
-
- .. image:: testing_multipletau.png
- :width: 500 px
-
+"""
+This module contains methods for correlated noise generation.
+
"""
from __future__ import division
@@ -18,7 +10,7 @@ from __future__ import print_function
import numpy as np
-__all__=["noise_exponential", "noise_cross_exponential"]
+__all__ = ["noise_exponential", "noise_cross_exponential"]
def noise_exponential(N, tau=20, variance=1, deltat=1):
"""
@@ -132,7 +124,3 @@ def noise_cross_exponential(N, tau=20, variance=1, deltat=1):
return a, randarray
-def test():
- from .__main__ import test
- test()
-
diff --git a/multipletau/__init__.py b/multipletau/__init__.py
index 79b5fbc..4eee6b6 100644
--- a/multipletau/__init__.py
+++ b/multipletau/__init__.py
@@ -1,31 +1,76 @@
-#!/usr/bin/python
+#!/usr/bin/env python
# -*- coding: utf-8 -*-
-"""
- Provides a multiple-τ algorithm for Python 2.7 and Python 3.x and
- requires the package :py:mod:`numpy`.
-
- Multipe-τ correlation is computed on a logarithmic scale (less
- data points are computed) and is thus much faster than conventional
- correlation on a linear scale such as :py:func:`numpy.correlate`.
-
- Recommended literature:
-
- - Klaus Schaetzel and Rainer Peters; *Noise on multiple-tau photon
- correlation data*. Proc. SPIE 1430, Photon Correlation
- Spectroscopy: Multicomponent Systems, 109 (June 1, 1991);
- http://doi.org/10.1117/12.44160
-
- - Thorsten Wohland, Rudolf Rigler, and Horst Vogel; *The Standard
- Deviation in Fluorescence Correlation Spectroscopy*. Biophysical
- Journal, 80 (June 1, 2001);
- http://dx.doi.org/10.1016/S0006-3495(01)76264-9
-
- The source code of multipletau is available at
- https://github.com/paulmueller/multipletau.
+u"""
+This package provides a multiple-τ algorithm for Python 2.7 and
+Python 3.x and requires the package :py:mod:`numpy`.
+
+Multipe-τ correlation is computed on a logarithmic scale (less
+data points are computed) and is thus much faster than conventional
+correlation on a linear scale such as :py:func:`numpy.correlate`.
+
+Recommended literature
+----------------------
+
+- Klaus Schaetzel and Rainer Peters; *Noise on multiple-tau photon
+ correlation data*. Proc. SPIE 1430, Photon Correlation
+ Spectroscopy: Multicomponent Systems, 109 (June 1, 1991);
+ http://doi.org/10.1117/12.44160
+
+- Thorsten Wohland, Rudolf Rigler, and Horst Vogel; *The Standard
+ Deviation in Fluorescence Correlation Spectroscopy*. Biophysical
+ Journal, 80 (June 1, 2001);
+ http://dx.doi.org/10.1016/S0006-3495(01)76264-9
+
+Obtaining multipletau
+---------------------
+If you have Python and :py:mod:`numpy` installed, simply run
+
+ pip install multipletau
+
+The source code of multipletau is available at
+https://github.com/FCS-analysis/multipletau.
+
+
+Citing multipletau
+------------------
+The multipletau package should be cited like this (replace "x.x.x"
+with the actual version of multipletau that you used and "DD Month YYYY"
+with a matching date).
+
+.. topic:: cite
+
+ Paul Müller (2012) *Python multiple-tau algorithm* (Version x.x.x)
+ [Computer program].
+ Available at https://pypi.python.org/pypi/multipletau/
+ (Accessed DD Month YYYY)
+
+
+You can find out what version you are using by typing
+(in a Python console):
+
+
+ >>> import multipletau
+ >>> multipletau.__version__
+ '0.1.4'
+
+
+Usage
+-----
+The package is straightforward to use. Here is a quick example:
+
+ >>> import numpy as np
+ >>> import multipletau
+ >>> a = np.linspace(2,5,42)
+ >>> v = np.linspace(1,6,42)
+ >>> multipletau.correlate(a, v, m=2)
+ array([[ 1. , 549.87804878],
+ [ 2. , 530.37477692],
+ [ 4. , 491.85812017],
+ [ 8. , 386.39500297]])
+
"""
from ._multipletau import *
+from ._version import version as __version__
-__version__ = "0.1.4"
-__author__ = "Paul Mueller"
-__email__ = "paul.mueller at biotec.tu-dresden.de"
-__license__ = "OpenBSD"
+__author__ = u"Paul Müller"
+__license__ = "BSD (3 clause)"
diff --git a/multipletau/_multipletau.py b/multipletau/_multipletau.py
index 159b2e9..585dfc8 100755
--- a/multipletau/_multipletau.py
+++ b/multipletau/_multipletau.py
@@ -1,37 +1,37 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
- A multiple-τ algorithm for Python 2.7 and 3.x.
-
- Copyright (c) 2014 Paul Müller
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are
- met:
-
- 1. Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the
- distribution.
-
- 3. Neither the name of multipletau nor the names of its contributors
- may be used to endorse or promote products derived from this
- software without specific prior written permission.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INFRAE OR
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+A multiple-τ algorithm for Python 2.7 and 3.x.
+
+Copyright (c) 2014 Paul Müller
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the
+ distribution.
+
+ 3. Neither the name of multipletau nor the names of its contributors
+ may be used to endorse or promote products derived from this
+ software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INFRAE OR
+CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
from __future__ import division
@@ -46,13 +46,14 @@ def autocorrelate(a, m=16, deltat=1, normalize=False,
copy=True, dtype=None):
"""
Autocorrelation of a 1-dimensional sequence on a log2-scale.
-
+
This computes the correlation according to
:py:func:`numpy.correlate` for positive :math:`k` on a base 2
logarithmic scale.
- numpy.correlate(a, a, mode="full")[len(a)-1:]
+ :func:`numpy.correlate(a, a, mode="full")[len(a)-1:]`
+
:math:`z_k = \Sigma_n a_n a_{n+k}`
@@ -89,10 +90,10 @@ def autocorrelate(a, m=16, deltat=1, normalize=False,
-----
The algorithm computes the correlation with the convention of the
curve decaying to zero.
-
+
For experiments like e.g. fluorescence correlation spectroscopy,
the signal can be normalized to `M-k` by invoking:
-
+
normalize = True
For emulating the numpy.correlate behavior on a logarithmic
@@ -114,83 +115,83 @@ def autocorrelate(a, m=16, deltat=1, normalize=False,
"""
traceavg = np.average(a)
if normalize and traceavg == 0:
- raise ZeroDivisionError("Normalization not possible. "+
- "The average of the input *binned_array* is zero.")
+ raise ZeroDivisionError("Normalization not possible. The " +
+ "average of the input *binned_array* " +
+ "is zero.")
trace = np.array(a, dtype=dtype, copy=copy)
dtype = trace.dtype
- if dtype.kind in ["b","i","u"]:
+ if dtype.kind in ["b", "i", "u"]:
warnings.warn("Converting input data type ({}) to float.".
format(dtype))
dtype = np.dtype(float)
trace = np.array(a, dtype=dtype, copy=copy)
-
+
# Complex data
if dtype.kind == "c":
raise NotImplementedError(
- "Please use `multipletau.correlate` for complex data.")
+ "Please use `multipletau.correlate` for complex data.")
-
# Check parameters
- if np.around(m/2) != m/2:
- mold = 1*m
- m = int((np.around(m/2)+1) * 2)
+ if np.around(m / 2) != m / 2:
+ mold = 1 * m
+ m = int((np.around(m / 2) + 1) * 2)
warnings.warn("Invalid value of m={}. Using m={} instead"
- .format(mold,m))
+ .format(mold, m))
else:
m = int(m)
N = N0 = len(trace)
-
+
# Find out the length of the correlation function.
# The integer k defines how many times we can average over
# two neighboring array elements in order to obtain an array of
# length just larger than m.
- k = int(np.floor(np.log2(N/m)))
+ k = int(np.floor(np.log2(N / m)))
# In the base2 multiple-tau scheme, the length of the correlation
# array is (only taking into account values that are computed from
- # traces that are just larger than m):
- lenG = np.int(np.floor(m + k*m/2))
-
+ # traces that are just larger than m):
+ lenG = np.int(np.floor(m + k * m / 2))
+
G = np.zeros((lenG, 2), dtype=dtype)
normstat = np.zeros(lenG, dtype=dtype)
normnump = np.zeros(lenG, dtype=dtype)
-
+
# We use the fluctuation of the signal around the mean
if normalize:
trace -= traceavg
- if N < 2*m:
+ if N < 2 * m:
# Otherwise the following for-loop will fail:
raise ValueError("len(binned_array) must be larger than 2m.")
- ## Calculate autocorrelation function for first m bins
+ # Calculate autocorrelation function for first m bins
# Discrete convolution of m elements
- for n in range(1,m+1):
- G[n-1,0] = deltat * n
+ for n in range(1, m + 1):
+ G[n - 1, 0] = deltat * n
# This is the computationally intensive step
- G[n-1,1] = np.sum(trace[:N-n]*trace[n:], dtype=dtype)
- normstat[n-1] = N-n
- normnump[n-1] = N
+ G[n - 1, 1] = np.sum(trace[:N - n] * trace[n:], dtype=dtype)
+ normstat[n - 1] = N - n
+ normnump[n - 1] = N
# Now that we calculated the first m elements of G, let us
# go on with the next m/2 elements.
# Check if len(trace) is even:
- if N%2 == 1:
+ if N % 2 == 1:
N -= 1
# Add up every second element
- trace = (trace[:N:2]+trace[1:N+1:2])/2
+ trace = (trace[:N:2] + trace[1:N + 1:2]) / 2
N /= 2
- ## Start iteration for each m/2 values
- for step in range(1,k+1):
- ## Get the next m/2 values via correlation of the trace
- for n in range(1,int(m/2)+1):
- idx = int(m + n - 1 + (step-1)*m/2)
- if len(trace[:N-(n+m/2)]) == 0:
+ # Start iteration for each m/2 values
+ for step in range(1, k + 1):
+ # Get the next m/2 values via correlation of the trace
+ for n in range(1, int(m / 2) + 1):
+ idx = int(m + n - 1 + (step - 1) * m / 2)
+ if len(trace[:N - (n + m / 2)]) == 0:
# This is a shortcut that stops the iteration once the
- # length of the trace is too small to compute a corre-
- # lation. The actual length of the correlation function
- # does not only depend on k - We also must be able to
+ # length of the trace is too small to compute a corre-
+ # lation. The actual length of the correlation function
+ # does not only depend on k - We also must be able to
# perform the sum with repect to k for all elements.
# For small N, the sum over zero elements would be
# computed here.
@@ -199,37 +200,36 @@ def autocorrelate(a, m=16, deltat=1, normalize=False,
# maxval1 = int(m/2)
# maxval2 = int(N-m/2-1)
# maxval = min(maxval1, maxval2)
- # However, we then would also need to find out which
+ # However, we then would also need to find out which
# element in G is the last element...
- G = G[:idx-1]
- normstat = normstat[:idx-1]
- normnump = normnump[:idx-1]
+ G = G[:idx - 1]
+ normstat = normstat[:idx - 1]
+ normnump = normnump[:idx - 1]
# Note that this break only breaks out of the current
# for loop. However, we are already in the last loop
# of the step-for-loop. That is because we calculated
# k in advance.
break
else:
- G[idx,0] = deltat * (n+m/2) * 2**step
+ G[idx, 0] = deltat * (n + m / 2) * 2**step
# This is the computationally intensive step
- G[idx,1] = np.sum(trace[:N-(n+m/2)]*trace[(n+m/2):],
- dtype=dtype)
- normstat[idx] = N-(n+m/2)
+ G[idx, 1] = np.sum(trace[:N - (n + m / 2)] *
+ trace[(n + m / 2):], dtype=dtype)
+ normstat[idx] = N - (n + m / 2)
normnump[idx] = N
# Check if len(trace) is even:
- if N%2 == 1:
+ if N % 2 == 1:
N -= 1
# Add up every second element
- trace = (trace[:N:2]+trace[1:N+1:2])/2
+ trace = (trace[:N:2] + trace[1:N + 1:2]) / 2
N /= 2
if normalize:
- G[:,1] /= traceavg**2 * normstat
+ G[:, 1] /= traceavg**2 * normstat
else:
- G[:,1] *= N0/normnump
-
- return G
+ G[:, 1] *= N0 / normnump
+ return G
def correlate(a, v, m=16, deltat=1, normalize=False,
@@ -237,19 +237,19 @@ def correlate(a, v, m=16, deltat=1, normalize=False,
"""
Cross-correlation of two 1-dimensional sequences
on a log2-scale.
-
+
This computes the cross-correlation according to
:py:func:`numpy.correlate` for positive :math:`k` on a base 2
logarithmic scale.
-
+
numpy.correlate(a, v, mode="full")[len(a)-1:]
-
+
:math:`z_k = \Sigma_n a_n v_{n+k}`
-
+
Note that only the correlation
in the positive direction is computed.
-
-
+
+
Parameters
----------
a, v : array_like
@@ -274,16 +274,16 @@ def correlate(a, v, m=16, deltat=1, normalize=False,
-------
crosscorrelation : ndarray
Nx2 array containing lag time and cross-correlation
-
-
+
+
Notes
-----
The algorithm computes the correlation with the convention of the
curve decaying to zero.
-
+
For experiments like e.g. fluorescence correlation spectroscopy,
the signal can be normalized to `M-k` by invoking:
-
+
normalize = True
For emulating the numpy.correlate behavior on a logarithmic
@@ -303,121 +303,122 @@ def correlate(a, v, m=16, deltat=1, normalize=False,
[ 8.00000000e+00, 1.58508000e+04]])
"""
- ## See `autocorrelation` for better documented code.
+ # See `autocorrelation` for better documented code.
traceavg1 = np.average(v)
traceavg2 = np.average(a)
- if normalize and traceavg1*traceavg2 == 0:
- raise ZeroDivisionError("Normalization not possible. "+
- "The average of the input *binned_array* is zero.")
+ if normalize and traceavg1 * traceavg2 == 0:
+ raise ZeroDivisionError("Normalization not possible. The " +
+ "average of the input *binned_array* " +
+ "is zero.")
trace1 = np.array(v, dtype=dtype, copy=copy)
dtype = trace1.dtype
- if dtype.kind in ["b","i","u"]:
+ if dtype.kind in ["b", "i", "u"]:
warnings.warn(
- "Converting input data type ({}) to float.".format(dtype))
+ "Converting input data type ({}) to float.".format(dtype))
dtype = np.dtype(float)
trace1 = np.array(v, dtype=dtype, copy=copy)
-
+
# Prevent traces from overwriting each other
if a is v:
# Force copying trace 2
copy = True
-
+
trace2 = np.array(a, dtype=dtype, copy=copy)
# Complex data
if dtype.kind == "c":
trace1.imag *= -1
-
+
# Check parameters
- if np.around(m/2) != m/2:
- mold = 1*m
- m = int((np.around(m/2)+1) * 2)
+ if np.around(m / 2) != m / 2:
+ mold = 1 * m
+ m = int((np.around(m / 2) + 1) * 2)
warnings.warn("Invalid value of m={}. Using m={} instead"
- .format(mold,m))
+ .format(mold, m))
else:
m = int(m)
-
+
if len(a) != len(v):
raise ValueError("Input arrays must be of equal length.")
-
+
N = N0 = len(trace1)
# Find out the length of the correlation function.
# The integer k defines how many times we can average over
# two neighboring array elements in order to obtain an array of
# length just larger than m.
- k = int(np.floor(np.log2(N/m)))
-
+ k = int(np.floor(np.log2(N / m)))
+
# In the base2 multiple-tau scheme, the length of the correlation
# array is (only taking into account values that are computed from
- # traces that are just larger than m):
- lenG = np.int(np.floor(m + k*m/2))
-
+ # traces that are just larger than m):
+ lenG = np.int(np.floor(m + k * m / 2))
+
G = np.zeros((lenG, 2), dtype=dtype)
normstat = np.zeros(lenG, dtype=dtype)
normnump = np.zeros(lenG, dtype=dtype)
-
+
# We use the fluctuation of the signal around the mean
if normalize:
trace1 -= traceavg1
trace2 -= traceavg2
- if N < 2*m:
+ if N < 2 * m:
# Otherwise the following for-loop will fail:
raise ValueError("len(binned_array) must be larger than 2m.")
# Calculate autocorrelation function for first m bins
- for n in range(1,m+1):
- G[n-1,0] = deltat * n
- G[n-1,1] = np.sum(trace1[:N-n]*trace2[n:])
- normstat[n-1] = N-n
- normnump[n-1] = N
+ for n in range(1, m + 1):
+ G[n - 1, 0] = deltat * n
+ G[n - 1, 1] = np.sum(trace1[:N - n] * trace2[n:])
+ normstat[n - 1] = N - n
+ normnump[n - 1] = N
# Check if len(trace) is even:
- if N%2 == 1:
+ if N % 2 == 1:
N -= 1
# Add up every second element
- trace1 = (trace1[:N:2]+trace1[1:N+1:2])/2
- trace2 = (trace2[:N:2]+trace2[1:N+1:2])/2
+ trace1 = (trace1[:N:2] + trace1[1:N + 1:2]) / 2
+ trace2 = (trace2[:N:2] + trace2[1:N + 1:2]) / 2
N /= 2
- for step in range(1,k+1):
+ for step in range(1, k + 1):
# Get the next m/2 values of the trace
- for n in range(1,int(m/2)+1):
- idx = int(m + n - 1 + (step-1)*m/2)
- if len(trace1[:N-(n+m/2)]) == 0:
+ for n in range(1, int(m / 2) + 1):
+ idx = int(m + n - 1 + (step - 1) * m / 2)
+ if len(trace1[:N - (n + m / 2)]) == 0:
# Abort
- G = G[:idx-1]
- normstat = normstat[:idx-1]
- normnump = normnump[:idx-1]
+ G = G[:idx - 1]
+ normstat = normstat[:idx - 1]
+ normnump = normnump[:idx - 1]
break
else:
- G[idx,0] = deltat * (n+m/2) * 2**step
- G[idx,1] = np.sum(trace1[:N-(n+m/2)]*trace2[(n+m/2):])
- normstat[idx] = N-(n+m/2)
+ G[idx, 0] = deltat * (n + m / 2) * 2**step
+ G[idx, 1] = np.sum(
+ trace1[:N - (n + m / 2)] * trace2[(n + m / 2):])
+ normstat[idx] = N - (n + m / 2)
normnump[idx] = N
# Check if len(trace) is even:
- if N%2 == 1:
+ if N % 2 == 1:
N -= 1
# Add up every second element
- trace1 = (trace1[:N:2]+trace1[1:N+1:2])/2
- trace2 = (trace2[:N:2]+trace2[1:N+1:2])/2
+ trace1 = (trace1[:N:2] + trace1[1:N + 1:2]) / 2
+ trace2 = (trace2[:N:2] + trace2[1:N + 1:2]) / 2
N /= 2
if normalize:
- G[:,1] /= traceavg1*traceavg2 * normstat
+ G[:, 1] /= traceavg1 * traceavg2 * normstat
else:
- G[:,1] *= N0/normnump
-
- return G
+ G[:, 1] *= N0 / normnump
+ return G
def correlate_numpy(a, v, deltat=1, normalize=False,
- dtype=None, copy=True):
+ dtype=None, copy=True):
"""
Convenience function that wraps around numpy.correlate and
returns the data as multipletau.correlate does.
-
+
Parameters
----------
a, v : array_like
@@ -440,27 +441,26 @@ def correlate_numpy(a, v, deltat=1, normalize=False,
crosscorrelation : ndarray
Nx2 array containing lag time and cross-correlation
"""
-
+
avg = np.average(a)
vvg = np.average(v)
-
+
if dtype is None:
dtype = a.dtype
-
+
if len(a) != len(v):
raise ValueError("Arrays must be of same length.")
ab = np.array(a, dtype=dtype, copy=copy)
vb = np.array(v, dtype=dtype, copy=copy)
- Gd = np.correlate(ab-avg, vb-vvg, mode="full")[len(ab)-1:]
+ Gd = np.correlate(ab - avg, vb - vvg, mode="full")[len(ab) - 1:]
if normalize:
N = len(Gd)
m = N - np.arange(N)
Gd /= m * avg * vvg
- G = np.zeros((len(Gd),2))
- G[:,1] = Gd
- G[:,0] = np.arange(len(Gd))*deltat
+ G = np.zeros((len(Gd), 2))
+ G[:, 1] = Gd
+ G[:, 0] = np.arange(len(Gd)) * deltat
return G
-
diff --git a/multipletau/_version.py b/multipletau/_version.py
new file mode 100644
index 0000000..75cddc8
--- /dev/null
+++ b/multipletau/_version.py
@@ -0,0 +1,2 @@
+#!/usr/bin/env python
+version = "0.1.5"
diff --git a/setup.py b/setup.py
index 783eb3a..821da70 100644
--- a/setup.py
+++ b/setup.py
@@ -1,24 +1,89 @@
#!/usr/bin/env python
+# -*- coding: utf-8 -*-
# To create a distribution package for pip or easy-install:
# python setup.py sdist
-from setuptools import setup, find_packages
from os.path import join, dirname, realpath
+from setuptools import setup, find_packages, Command
+import subprocess as sp
+import sys
from warnings import warn
-import multipletau
-
-setup(
- name='multipletau',
- author='Paul Mueller',
- author_email='paul.mueller at biotec.tu-dresden.de',
- url='https://github.com/paulmueller/multipletau',
- version=multipletau.__version__,
- packages=['multipletau'],
- package_dir={'multipletau': 'multipletau'},
- license="OpenBSD",
- description='A multiple-tau algorithm for Python/NumPy.',
- long_description=open(join(dirname(__file__), 'README.txt')).read(),
- install_requires=["NumPy >= 1.5.1"]
- )
+
+author = u"Paul Müller"
+authors = [author]
+description = 'A multiple-tau algorithm for Python/NumPy.'
+name = 'multipletau'
+year = "2013"
+
+
+sys.path.insert(0, realpath(dirname(__file__))+"/"+name)
+try:
+ from _version import version
+except:
+ version = "unknown"
+
+
+
+class PyDocGitHub(Command):
+ """ Upload the docs to GitHub gh-pages branch
+ """
+ user_options = []
+ def initialize_options(self):
+ pass
+
+ def finalize_options(self):
+ pass
+
+ def run(self):
+ errno = sp.call([sys.executable, 'doc/commit_gh-pages.py'])
+ raise SystemExit(errno)
+
+
+class PyTest(Command):
+ """ Perform pytests
+ """
+ user_options = []
+ def initialize_options(self):
+ pass
+
+ def finalize_options(self):
+ pass
+
+ def run(self):
+ errno = sp.call([sys.executable, 'tests/runtests.py'])
+ raise SystemExit(errno)
+
+
+if __name__ == "__main__":
+ setup(
+ name=name,
+ author=author,
+ author_email='paul.mueller at biotec.tu-dresden.de',
+ url='https://github.com/FCS-analysis/multipletau',
+ version=version,
+ packages=[name],
+ package_dir={name: name},
+ license="BSD (3 clause)",
+ description=description,
+ long_description=open(join(dirname(__file__), 'README.txt')).read(),
+ install_requires=["NumPy >= 1.5.1"],
+ keywords=["multiple", "tau", "FCS", "correlation", "spectroscopy",
+ "fluorescence"],
+ extras_require={
+ 'doc': ['sphinx']
+ },
+ classifiers= [
+ 'Operating System :: OS Independent',
+ 'Programming Language :: Python :: 2.7',
+ 'Programming Language :: Python :: 3.2',
+ 'Programming Language :: Python :: 3.3',
+ 'Topic :: Scientific/Engineering :: Visualization',
+ 'Intended Audience :: Science/Research'
+ ],
+ platforms=['ALL'],
+ cmdclass = {'test': PyTest,
+ 'commit_doc': PyDocGitHub,
+ },
+ )
diff --git a/tests/README.md b/tests/README.md
new file mode 100644
index 0000000..0d5eb56
--- /dev/null
+++ b/tests/README.md
@@ -0,0 +1,16 @@
+### Test Scripts
+
+This will run all tests:
+
+ python runtests.py
+
+
+### Running single tests
+
+Directly execute the scripts, e.g.
+
+
+ python test_basic.py
+
+
+
diff --git a/tests/test_basic.py b/tests/test_basic.py
new file mode 100644
index 0000000..5895d35
--- /dev/null
+++ b/tests/test_basic.py
@@ -0,0 +1,37 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+"""
+basic tests also available in the function docs
+"""
+import numpy as np
+from os.path import abspath, dirname, join
+import sys
+
+sys.path.insert(0, dirname(dirname(abspath(__file__))))
+
+from multipletau import autocorrelate, correlate
+
+
+def test_ac():
+ ist = autocorrelate(range(42), m=2, dtype=np.dtype(float))
+
+ soll = np.array([[ 1.00000000e+00, 2.29600000e+04],
+ [ 2.00000000e+00, 2.21000000e+04],
+ [ 4.00000000e+00, 2.03775000e+04],
+ [ 8.00000000e+00, 1.50612000e+04]])
+ assert np.allclose(soll, ist)
+
+
+def test_cc():
+ soll = correlate(range(42), range(1,43), m=2, dtype=np.dtype(float))
+ ist = np.array([[ 1.00000000e+00, 2.38210000e+04],
+ [ 2.00000000e+00, 2.29600000e+04],
+ [ 4.00000000e+00, 2.12325000e+04],
+ [ 8.00000000e+00, 1.58508000e+04]])
+ assert np.allclose(soll, ist)
+
+
+if __name__ == "__main__":
+ test_ac()
+ test_cc()
+
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/python-multipletau.git
More information about the debian-med-commit
mailing list