From 8f109126b2fa8560bd1a9adf3d35ae0c37503f19 Mon Sep 17 00:00:00 2001 From: Andre Anjos <andre.dos.anjos@gmail.com> Date: Mon, 15 Aug 2016 09:50:42 +0200 Subject: [PATCH] Standardise --- .gitlab-ci.yml | 275 ++++++++++++++++++++++++++++++++++++++++++ .travis.yml | 36 ------ LICENSE | 23 ++-- MANIFEST.in | 2 +- README.rst | 57 ++++++--- bootstrap-buildout.py | 51 +++++--- buildout.cfg | 34 +----- develop.cfg | 39 ++++++ doc/conf.py | 134 +++++++++----------- doc/img/logo.png | Bin 11280 -> 6266 bytes setup.py | 4 +- 11 files changed, 466 insertions(+), 189 deletions(-) create mode 100644 .gitlab-ci.yml delete mode 100644 .travis.yml create mode 100644 develop.cfg diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..293eb7b --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,275 @@ +# This build file is defined in two parts: 1) a generic set of instructions you +# probably **don't** need to change and 2) a part you may have to tune to your +# project. It heavily uses template features from YAML to help you in only +# changing a minimal part of it and avoid code duplication to a maximum while +# still providing a nice pipeline display on your package. + + +# 1) Generic instructions (only change if you know what you're doing) +# ------------------------------------------------------------------- + +# Definition of our build pipeline +stages: + - build + - test + - docs + - wheels + + +# Global variables +variables: + CONDA_PREFIX: env + + +# Template for the build stage +# Needs to run on all supported architectures, platforms and python versions +.build_template: &build_job + stage: build + before_script: + - git clean -ffdx + - curl --silent https://gitlab.idiap.ch/bob/bob/snippets/7/raw | tr -d '\r' > bootstrap-conda.sh + - chmod 755 ./bootstrap-conda.sh + - ./bootstrap-conda.sh ${CONDA_FOLDER} ${PYTHON_VER} ${CONDA_PREFIX} + variables: &build_variables + BOB_DOCUMENTATION_SERVER: "http://www.idiap.ch/software/bob/docs/latest/bob/%s/master/" + script: + - BOB_PREFIX_PATH=${CONDA_FOLDER}/envs/`cat ${CONDA_FOLDER}/envs/latest-devel-${PYTHON_VER}.txt` ./bin/buildout + - ./bin/sphinx-build doc sphinx + - ./bin/python setup.py bdist_wheel + after_script: + - rm -rf ${CONDA_PREFIX} + artifacts: + expire_in: 1 day + paths: + - bootstrap-conda.sh + - dist/ + - sphinx/ + + +# Template for building on a Linux machine +.build_linux_template: &linux_build_job + <<: *build_job + variables: &linux_build_variables + <<: *build_variables + CONDA_FOLDER: "/local/conda" + CFLAGS: "-D_GLIBCXX_USE_CXX11_ABI=0 -coverage" + CXXFLAGS: "-D_GLIBCXX_USE_CXX11_ABI=0 -coverage" + + +# Template for building on a Mac OSX machine +.build_mac_template: &macosx_build_job + <<: *build_job + variables: &macosx_build_variables + <<: *build_variables + CONDA_FOLDER: "/opt/conda" + MACOSX_DEPLOYMENT_TARGET: "10.9" + CFLAGS: "-pthread -coverage" + CXXFLAGS: "-pthread -coverage" + LDFLAGS: "-lpthread" + + +# Template for the test stage - re-install from uploaded wheels +# Needs to run on all supported architectures, platforms and python versions +.test_template: &test_job + stage: test + before_script: + - ./bootstrap-conda.sh ${CONDA_FOLDER} ${PYTHON_VER} ${CONDA_PREFIX} + - source ${CONDA_FOLDER}/bin/activate ${CONDA_PREFIX} + - pip install --use-wheel --no-index --pre dist/*.whl + script: + - cd ${CONDA_PREFIX} + - python -c "from ${CI_PROJECT_NAME} import get_config; print(get_config())" + - coverage run --source=${CI_PROJECT_NAME} ./bin/nosetests -sv ${CI_PROJECT_NAME} + - coverage report + - sphinx-build -b doctest ../doc ../sphinx + after_script: + - rm -rf ${CONDA_PREFIX} + + +# Template for the wheel uploading stage +# Needs to run against one combination of python 2.x and 3.x if it is a python +# only package, otherwise, needs to run in both pythons to all supported +# architectures (Linux and Mac OSX 64-bit) +.wheels_template: &wheels_job + stage: wheels + only: + - master + - tags + before_script: + - curl --silent https://gitlab.idiap.ch/bob/bob/snippets/8/raw | tr -d '\r' > upload-wheel.sh + - chmod 755 upload-wheel.sh + script: + - ./upload-wheel.sh + + +# Template for (latest) documentation upload stage +# Only one real job needs to do this +.docs_template: &docs_job + stage: docs + only: + - master + before_script: + - curl --silent https://gitlab.idiap.ch/bob/bob/snippets/9/raw | tr -d '\r' > upload-sphinx.sh + - chmod 755 upload-sphinx.sh + script: + - ./upload-sphinx.sh + + +# 2) Package specific instructions (you may tune this if needed) +# -------------------------------------------------------------- + +# Linux + Python 2.7: Builds and tests +build_linux_27: + <<: *linux_build_job + variables: &linux_27_build_variables + <<: *linux_build_variables + PYTHON_VER: "2.7" + tags: + - conda-linux + +test_linux_27: + <<: *test_job + variables: *linux_27_build_variables + dependencies: + - build_linux_27 + tags: + - conda-linux + +wheels_linux_27: + <<: *wheels_job + dependencies: + - build_linux_27 + tags: + - conda-linux + + +# Linux + Python 3.4: Builds and tests +build_linux_34: + <<: *linux_build_job + variables: &linux_34_build_variables + <<: *linux_build_variables + PYTHON_VER: "3.4" + tags: + - conda-linux + +test_linux_34: + <<: *test_job + variables: *linux_34_build_variables + dependencies: + - build_linux_34 + tags: + - conda-linux + +wheels_linux_34: + <<: *wheels_job + dependencies: + - build_linux_34 + tags: + - conda-linux + + +# Linux + Python 3.5: Builds and tests +build_linux_35: + <<: *linux_build_job + variables: &linux_35_build_variables + <<: *linux_build_variables + PYTHON_VER: "3.5" + tags: + - conda-linux + +test_linux_35: + <<: *test_job + variables: *linux_35_build_variables + dependencies: + - build_linux_35 + tags: + - conda-linux + +wheels_linux_35: + <<: *wheels_job + dependencies: + - build_linux_35 + tags: + - conda-linux + +docs_linux_35: + <<: *docs_job + dependencies: + - build_linux_35 + tags: + - conda-linux + + +# Mac OSX + Python 2.7: Builds, tests and uploads the wheel +build_macosx_27: + <<: *macosx_build_job + variables: &macosx_27_build_variables + <<: *macosx_build_variables + PYTHON_VER: "2.7" + tags: + - conda-macosx + +test_macosx_27: + <<: *test_job + variables: *macosx_27_build_variables + dependencies: + - build_macosx_27 + tags: + - conda-macosx + +wheels_macosx_27: + <<: *wheels_job + dependencies: + - build_macosx_27 + tags: + - conda-macosx + + +# Mac OSX + Python 3.4: Builds and tests +build_macosx_34: + <<: *macosx_build_job + variables: &macosx_34_build_variables + <<: *macosx_build_variables + PYTHON_VER: "3.4" + tags: + - conda-macosx + +test_macosx_34: + <<: *test_job + variables: *macosx_34_build_variables + dependencies: + - build_macosx_34 + tags: + - conda-macosx + +wheels_macosx_34: + <<: *wheels_job + dependencies: + - build_macosx_34 + tags: + - conda-macosx + + +# Mac OSX + Python 3.5: Builds, tests, uploads the wheel and the latest docs +build_macosx_35: + <<: *macosx_build_job + variables: &macosx_35_build_variables + <<: *macosx_build_variables + PYTHON_VER: "3.5" + tags: + - conda-macosx + +test_macosx_35: + <<: *test_job + variables: *macosx_35_build_variables + dependencies: + - build_macosx_35 + tags: + - conda-macosx + +wheels_macosx_35: + <<: *wheels_job + dependencies: + - build_macosx_35 + tags: + - conda-macosx \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index c702afe..0000000 --- a/.travis.yml +++ /dev/null @@ -1,36 +0,0 @@ -language: python -env: - global: - - secure: eVYI9c4v/gdgMu9/HUrdOljH6xoWucjRNlQMfh24LA3g6j1dr52+SdCP59mzFqBiAIR8eBtipIkit23sQDn+ulw3bJSrLszXsWCKGywLVG/6QtgsqN9J17/RbUA2ZnfA86famA6Z4+CtJbW7nQPYidRQshPC85iiekftN9DwdeQ= - - secure: a+hf3j24x0fyP8OP/8IiIp5aMn+GfYxf97vWtJV1U76J8eGNLyj+n/AsPx4y6OpRWy2qTf/90W5TxU/ruRxKRl3j78+W2sYCI1LiQIlNlVX6tMrLnm2YS5zvwH3jICCmRUmY7d0Vc5MrqBRoKnmA+1QqyDrdiCjWkNSh6Jcn5KA= - - BOB_UPLOAD_WHEEL=1 -matrix: - include: - - python: 2.7 - env: - - BOB_DOCUMENTATION_SERVER=https://www.idiap.ch/software/bob/docs/latest/bioidiap/%s/master - - python: 3.3 - - python: 3.4 - - python: 3.5 -before_install: -- sudo add-apt-repository -y ppa:biometrics/bob -- sudo apt-get update -qq -- sudo apt-get install -qq --force-yes libboost-all-dev libblitz1-dev libhdf5-serial-dev libatlas-dev libatlas-base-dev liblapack-dev texlive-latex-recommended texlive-latex-extra texlive-fonts-recommended dvipng texlive-latex-base texlive-math-extra -- pip install --upgrade pip -- pip install --find-links https://www.idiap.ch/software/bob/wheels/travis/ --use-wheel sphinx nose numpy matplotlib coverage cpp-coveralls -- pip install --find-links https://www.idiap.ch/software/bob/wheels/travis/ --use-wheel --pre -r requirements.txt coveralls -install: -- python bootstrap-buildout.py -- CPPFLAGS=--coverage LDFLAGS=--coverage ./bin/buildout buildout:debug=false buildout:develop=. buildout:extensions=bob.buildout buildout:auto-checkout= -script: -- ./bin/python -c 'import pkg_resources; from bob.learn.em import get_config; print(get_config())' -- ./bin/coverage run --source=bob.learn.em ./bin/nosetests -sv -- ./bin/sphinx-build -b doctest doc sphinx -- ./bin/sphinx-build -b html doc sphinx -after_success: -- cpp-coveralls --build-root=`pwd` --exclude=src --exclude-pattern=".*Compiler.*" --dump=cpp_cov.json -- coveralls --merge=cpp_cov.json -- wget https://raw.githubusercontent.com/bioidiap/bob.extension/master/scripts/upload-{sphinx,wheel}.sh -- chmod a+x upload-sphinx.sh upload-wheel.sh -- ./upload-sphinx.sh -- ./upload-wheel.sh diff --git a/LICENSE b/LICENSE index 7ac8998..bd46ce1 100644 --- a/LICENSE +++ b/LICENSE @@ -1,16 +1,19 @@ -Copyright (c) 2013, Andre Anjos - Idiap Research Institute -All rights reserved. +Copyright (c) 2016 Idiap Research Institute, http://www.idiap.ch/ +Written by Andre Anjos <andre.anjos@idiap.ch> Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: -Redistributions of source code must retain the above copyright notice, this -list of conditions and the following disclaimer. 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. Neither the name of the Idiap Research Institute nor the -names of its contributors may be used to endorse or promote products derived -from this software without specific prior written permission. +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 the copyright holder 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 @@ -21,4 +24,4 @@ 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. +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/MANIFEST.in b/MANIFEST.in index f333d7a..8901be6 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,4 +1,4 @@ -include LICENSE README.rst bootstrap-buildout.py buildout.cfg requirements.txt version.txt +include LICENSE README.rst bootstrap-buildout.py buildout.cfg develop.cfg requirements.txt version.txt recursive-include doc conf.py *.rst recursive-include bob/learn/em *.cpp *.h recursive-include bob/learn/em/data *.* diff --git a/README.rst b/README.rst index 9ce1a06..8ad2555 100644 --- a/README.rst +++ b/README.rst @@ -1,29 +1,39 @@ .. vim: set fileencoding=utf-8 : -.. Andre Anjos <andre.anjos@idiap.ch> -.. Thu 22 May 2014 15:39:03 CEST +.. Mon 15 Aug 2016 09:48:28 CEST .. image:: http://img.shields.io/badge/docs-stable-yellow.png :target: http://pythonhosted.org/bob.learn.em/index.html .. image:: http://img.shields.io/badge/docs-latest-orange.png :target: https://www.idiap.ch/software/bob/docs/latest/bioidiap/bob.learn.em/master/index.html -.. image:: https://travis-ci.org/bioidiap/bob.learn.em.svg?branch=master - :target: https://travis-ci.org/bioidiap/bob.learn.em?branch=master -.. image:: https://coveralls.io/repos/bioidiap/bob.learn.em/badge.svg?branch=master - :target: https://coveralls.io/r/bioidiap/bob.learn.em?branch=master -.. image:: https://img.shields.io/badge/github-master-0000c0.png - :target: https://github.com/bioidiap/bob.learn.em/tree/master +.. image:: https://gitlab.idiap.ch/bob/bob.learn.em/badges/master/build.svg + :target: https://gitlab.idiap.ch/bob/bob.learn.em/commits/master +.. image:: https://img.shields.io/badge/gitlab-project-0000c0.svg + :target: https://gitlab.idiap.ch/bob/bob.learn.em .. image:: http://img.shields.io/pypi/v/bob.learn.em.png :target: https://pypi.python.org/pypi/bob.learn.em .. image:: http://img.shields.io/pypi/dm/bob.learn.em.png :target: https://pypi.python.org/pypi/bob.learn.em -================================================== - Expectation Maximization Machine Learning Tools -================================================== -The EM algorithm is an iterative method that estimates parameters for statistical models, where the model depends on unobserved latent variables. The EM iteration alternates between performing an expectation (E) step, which creates a function for the expectation of the log-likelihood evaluated using the current estimate for the parameters, and a maximization (M) step, which computes parameters maximizing the expected log-likelihood found on the E step. These parameter-estimates are then used to determine the distribution of the latent variables in the next E step. +================================================= + Expectation Maximization Machine Learning Tools +================================================= + +This package is part of the signal-processing and machine learning toolbox +Bob_. It contains routines for learning probabilistic models via Expectation +Maximization (EM). + +The EM algorithm is an iterative method that estimates parameters for +statistical models, where the model depends on unobserved latent variables. The +EM iteration alternates between performing an expectation (E) step, which +creates a function for the expectation of the log-likelihood evaluated using +the current estimate for the parameters, and a maximization (M) step, which +computes parameters maximizing the expected log-likelihood found on the E step. +These parameter-estimates are then used to determine the distribution of the +latent variables in the next E step. The package includes the machine definition per se and a selection of different trainers for specialized purposes: + - Maximum Likelihood (ML) - Maximum a Posteriori (MAP) - K-Means @@ -36,13 +46,22 @@ The package includes the machine definition per se and a selection of different Installation ------------ -To install this package -- alone or together with other `Packages of Bob <https://github.com/idiap/bob/wiki/Packages>`_ -- please read the `Installation Instructions <https://github.com/idiap/bob/wiki/Installation>`_. -For Bob_ to be able to work properly, some dependent packages are required to be installed. -Please make sure that you have read the `Dependencies <https://github.com/idiap/bob/wiki/Dependencies>`_ for your operating system. -Documentation -------------- -For further documentation on this package, please read the `Stable Version <http://pythonhosted.org/bob.learn.em/index.html>`_ or the `Latest Version <https://www.idiap.ch/software/bob/docs/latest/bioidiap/bob.learn.em/master/index.html>`_ of the documentation. -For a list of tutorials on this or the other packages ob Bob_, or information on submitting issues, asking questions and starting discussions, please visit its website. +Follow our `installation`_ instructions. Then, using the Python interpreter +provided by the distribution, bootstrap and buildout this package:: + + $ python bootstrap-buildout.py + $ ./bin/buildout + + +Contact +------- + +For questions or reporting issues to this software package, contact our +development `mailing list`_. + +.. Place your references here: .. _bob: https://www.idiap.ch/software/bob +.. _installation: https://gitlab.idiap.ch/bob/bob/wikis/Installation +.. _mailing list: https://groups.google.com/forum/?fromgroups#!forum/bob-devel diff --git a/bootstrap-buildout.py b/bootstrap-buildout.py index a629566..a459921 100644 --- a/bootstrap-buildout.py +++ b/bootstrap-buildout.py @@ -25,7 +25,10 @@ import tempfile from optparse import OptionParser -tmpeggs = tempfile.mkdtemp() +__version__ = '2015-07-01' +# See zc.buildout's changelog if this version is up to date. + +tmpeggs = tempfile.mkdtemp(prefix='bootstrap-') usage = '''\ [DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options] @@ -40,8 +43,9 @@ this script from going over the network. ''' parser = OptionParser(usage=usage) -parser.add_option("-v", "--version", help="use a specific zc.buildout version") - +parser.add_option("--version", + action="store_true", default=False, + help=("Return bootstrap.py version.")) parser.add_option("-t", "--accept-buildout-test-releases", dest='accept_buildout_test_releases', action="store_true", default=False, @@ -59,25 +63,33 @@ parser.add_option("-f", "--find-links", parser.add_option("--allow-site-packages", action="store_true", default=False, help=("Let bootstrap.py use existing site packages")) +parser.add_option("--buildout-version", + help="Use a specific zc.buildout version") parser.add_option("--setuptools-version", - help="use a specific setuptools version") - + help="Use a specific setuptools version") +parser.add_option("--setuptools-to-dir", + help=("Allow for re-use of existing directory of " + "setuptools versions")) options, args = parser.parse_args() +if options.version: + print("bootstrap.py version %s" % __version__) + sys.exit(0) + ###################################################################### # load/install setuptools try: - if options.allow_site_packages: - import setuptools - import pkg_resources from urllib.request import urlopen except ImportError: from urllib2 import urlopen ez = {} -exec(urlopen('https://bootstrap.pypa.io/ez_setup.py').read(), ez) +if os.path.exists('ez_setup.py'): + exec(open('ez_setup.py').read(), ez) +else: + exec(urlopen('https://bootstrap.pypa.io/ez_setup.py').read(), ez) if not options.allow_site_packages: # ez_setup imports site, which adds site packages @@ -88,12 +100,19 @@ if not options.allow_site_packages: # We can't remove these reliably if hasattr(site, 'getsitepackages'): for sitepackage_path in site.getsitepackages(): - sys.path[:] = [x for x in sys.path if sitepackage_path not in x] + # Strip all site-packages directories from sys.path that + # are not sys.prefix; this is because on Windows + # sys.prefix is a site-package directory. + if sitepackage_path != sys.prefix: + sys.path[:] = [x for x in sys.path + if sitepackage_path not in x] setup_args = dict(to_dir=tmpeggs, download_delay=0) if options.setuptools_version is not None: setup_args['version'] = options.setuptools_version +if options.setuptools_to_dir is not None: + setup_args['to_dir'] = options.setuptools_to_dir ez['use_setuptools'](**setup_args) import setuptools @@ -110,7 +129,12 @@ for path in sys.path: ws = pkg_resources.working_set +setuptools_path = ws.find( + pkg_resources.Requirement.parse('setuptools')).location + +# Fix sys.path here as easy_install.pth added before PYTHONPATH cmd = [sys.executable, '-c', + 'import sys; sys.path[0:0] = [%r]; ' % setuptools_path + 'from setuptools.command.easy_install import main; main()', '-mZqNxd', tmpeggs] @@ -123,11 +147,8 @@ find_links = os.environ.get( if find_links: cmd.extend(['-f', find_links]) -setuptools_path = ws.find( - pkg_resources.Requirement.parse('setuptools')).location - requirement = 'zc.buildout' -version = options.version +version = options.buildout_version if version is None and not options.accept_buildout_test_releases: # Figure out the most recent final version of zc.buildout. import setuptools.package_index @@ -167,7 +188,7 @@ if version: cmd.append(requirement) import subprocess -if subprocess.call(cmd, env=dict(os.environ, PYTHONPATH=setuptools_path)) != 0: +if subprocess.call(cmd) != 0: raise Exception( "Failed to execute command:\n%s" % repr(cmd)[1:-1]) diff --git a/buildout.cfg b/buildout.cfg index 914e36e..3b7a446 100644 --- a/buildout.cfg +++ b/buildout.cfg @@ -1,39 +1,13 @@ ; vim: set fileencoding=utf-8 : -; Andre Anjos <andre.anjos@idiap.ch> -; Mon 16 Apr 08:29:18 2012 CEST +; Mon 15 Aug 2016 09:48:28 CEST [buildout] parts = scripts +develop = . eggs = bob.learn.em extensions = bob.buildout - mr.developer - -auto-checkout = * -develop = src/bob.extension - src/bob.blitz - src/bob.core - src/bob.io.base - src/bob.sp - src/bob.math - src/bob.learn.activation - src/bob.learn.linear - . - -; options for bob.buildout extension -debug = true -verbose = true newest = false - -[sources] -bob.extension = git https://github.com/bioidiap/bob.extension -bob.blitz = git https://github.com/bioidiap/bob.blitz -bob.core = git https://github.com/bioidiap/bob.core -bob.io.base = git https://github.com/bioidiap/bob.io.base -bob.sp = git https://github.com/bioidiap/bob.sp -bob.math = git https://github.com/bioidiap/bob.math -bob.learn.activation = git https://github.com/bioidiap/bob.learn.activation -bob.learn.linear = git https://github.com/bioidiap/bob.learn.linear +verbose = true [scripts] -recipe = bob.buildout:scripts -dependent-scripts = true +recipe = bob.buildout:scripts \ No newline at end of file diff --git a/develop.cfg b/develop.cfg new file mode 100644 index 0000000..40bd10a --- /dev/null +++ b/develop.cfg @@ -0,0 +1,39 @@ +; vim: set fileencoding=utf-8 : +; Andre Anjos <andre.anjos@idiap.ch> +; Mon 16 Apr 08:29:18 2012 CEST + +[buildout] +parts = scripts +eggs = bob.learn.em +extensions = bob.buildout + mr.developer + +auto-checkout = * +develop = src/bob.extension + src/bob.blitz + src/bob.core + src/bob.io.base + src/bob.sp + src/bob.math + src/bob.learn.activation + src/bob.learn.linear + . + +; options for bob.buildout extension +debug = true +verbose = true +newest = false + +[sources] +bob.extension = git https://gitlab.idiap.ch/bob/bob.extension +bob.blitz = git https://gitlab.idiap.ch/bob/bob.blitz +bob.core = git https://gitlab.idiap.ch/bob/bob.core +bob.io.base = git https://gitlab.idiap.ch/bob/bob.io.base +bob.sp = git https://gitlab.idiap.ch/bob/bob.sp +bob.math = git https://gitlab.idiap.ch/bob/bob.math +bob.learn.activation = git https://gitlab.idiap.ch/bob/bob.learn.activation +bob.learn.linear = git https://gitlab.idiap.ch/bob/bob.learn.linear + +[scripts] +recipe = bob.buildout:scripts +dependent-scripts = true diff --git a/doc/conf.py b/doc/conf.py index 0317ae8..e545a99 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -1,46 +1,47 @@ #!/usr/bin/env python # vim: set fileencoding=utf-8 : -# Andre Anjos <andre.anjos@idiap.ch> -# Tue 15 Oct 16:37:18 2013 CEST -# -# Copyright (C) 2011-2014 Idiap Research Institute, Martigny, Switzerland import os import sys import glob import pkg_resources -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.insert(0, os.path.abspath('.')) # -- General configuration ----------------------------------------------------- # If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' +needs_sphinx = '1.3' # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. extensions = [ - 'sphinx.ext.todo', - 'sphinx.ext.coverage', - 'sphinx.ext.pngmath', - 'sphinx.ext.ifconfig', - 'sphinx.ext.autodoc', - 'sphinx.ext.autosummary', - 'sphinx.ext.doctest', - 'sphinx.ext.intersphinx', - ] + 'sphinx.ext.todo', + 'sphinx.ext.coverage', + 'sphinx.ext.ifconfig', + 'sphinx.ext.autodoc', + 'sphinx.ext.autosummary', + 'sphinx.ext.doctest', + 'sphinx.ext.graphviz', + 'sphinx.ext.intersphinx', + 'sphinx.ext.napoleon', + 'sphinx.ext.viewcode', + ] -# The viewcode extension appeared only on Sphinx >= 1.0.0 import sphinx -if sphinx.__version__ >= "1.0": - extensions.append('sphinx.ext.viewcode') +if sphinx.__version__ >= "1.4.1": + extensions.append('sphinx.ext.imgmath') +else: + extensions.append('sphinx.ext.pngmath') # Always includes todos todo_include_todos = True +# Generates auto-summary automatically +autosummary_generate = True + +# Create numbers on figures with captions +numfig = True + # If we are on OSX, the 'dvipng' path maybe different dvipng_osx = '/opt/local/libexec/texlive/binaries/dvipng' if os.path.exists(dvipng_osx): pngmath_dvipng = dvipng_osx @@ -63,7 +64,7 @@ import time copyright = u'%s, Idiap Research Institute' % time.strftime('%Y') # Grab the setup entry -distribution = pkg_resources.require('bob.learn.em')[0] +distribution = pkg_resources.require(project)[0] # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -108,13 +109,18 @@ pygments_style = 'sphinx' # A list of ignored prefixes for module index sorting. #modindex_common_prefix = [] +# Some variables which are useful for generated material +project_variable = project.replace('.', '_') +short_description = u'Bindings for EM machines and trainers of Bob' +owner = [u'Idiap Research Institute'] + # -- Options for HTML output --------------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -if sphinx.__version__ >= "1.0": - html_theme = 'nature' +import sphinx_rtd_theme +html_theme = 'sphinx_rtd_theme' # 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 @@ -122,14 +128,14 @@ if sphinx.__version__ >= "1.0": #html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] +html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] # The name for this set of Sphinx documents. If None, it defaults to # "<project> v<release> documentation". #html_title = None # A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = 'bob_learn_em' +#html_short_title = project_variable # The name of an image file (relative to this directory) to place at the top # of the sidebar. @@ -187,72 +193,48 @@ html_favicon = 'img/favicon.ico' #html_file_suffix = None # Output file base name for HTML help builder. -htmlhelp_basename = 'bob_learn_em_doc' - - -# -- Options for LaTeX output -------------------------------------------------- - -# The paper size ('letter' or 'a4'). -latex_paper_size = 'a4' - -# The font size ('10pt', '11pt' or '12pt'). -latex_font_size = '10pt' - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, author, documentclass [howto/manual]). -latex_documents = [ - ('index', 'bob_learn_em.tex', u'Bob Miscellaneous Machine Learning Tools', - u'Biometrics Group, Idiap Research Institute', 'manual'), -] +htmlhelp_basename = project_variable + u'_doc' -# The name of an image file (relative to this directory) to place at the top of -# the title page. -latex_logo = '' -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -#latex_use_parts = False - -# If true, show page references after internal links. -#latex_show_pagerefs = False - -# If true, show URL addresses after external links. -#latex_show_urls = False - -# Additional stuff for the LaTeX preamble. -#latex_preamble = '' - -# Documents to append as an appendix to all manuals. -#latex_appendices = [] - -# If false, no module index is generated. -#latex_domain_indices = True +# -- Post configuration -------------------------------------------------------- # Included after all input documents rst_epilog = """ .. |project| replace:: Bob -.. |url| replace:: https://www.idiap.ch/software/bob/ .. |version| replace:: %s .. |current-year| date:: %%Y """ % (version,) -# -- Options for manual page output -------------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - ('index', 'bob_learn_em', u'Bob Miscellaneous Machine Learning Tools', [u'Idiap Research Institute'], 1) -] - # Default processing flags for sphinx -autoclass_content = 'both' +autoclass_content = 'class' autodoc_member_order = 'bysource' -autodoc_default_flags = ['members', 'undoc-members', 'inherited-members', 'show-inheritance'] +autodoc_default_flags = [ + 'members', + 'undoc-members', + 'inherited-members', + 'show-inheritance', + ] # For inter-documentation mapping: from bob.extension.utils import link_documentation intersphinx_mapping = link_documentation() +# We want to remove all private (i.e. _. or __.__) members +# that are not in the list of accepted functions +accepted_private_functions = ['__array__'] + +def member_function_test(app, what, name, obj, skip, options): + # test if we have a private function + if len(name) > 1 and name[0] == '_': + # test if this private function should be allowed + if name not in accepted_private_functions: + # omit privat functions that are not in the list of accepted private functions + return skip + else: + # test if the method is documented + if not hasattr(obj, '__doc__') or not obj.__doc__: + return skip + return False def setup(app): - pass + app.connect('autodoc-skip-member', member_function_test) diff --git a/doc/img/logo.png b/doc/img/logo.png index b9dd573a01019afd1af58a881996930e5212699d..b60858a7068bf45c1ed8e3da12fe244ccdcfe85d 100644 GIT binary patch literal 6266 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 JWt~$(69D)+N{avh literal 11280 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 diff --git a/setup.py b/setup.py index 3f56083..2d1961c 100644 --- a/setup.py +++ b/setup.py @@ -22,8 +22,8 @@ setup( name='bob.learn.em', version=version, - description='Bindings for emelaneous machines and trainers of Bob', - url='http://github.com/bioidiap/bob.learn.em', + description='Bindings for EM machines and trainers of Bob', + url='http://gitlab.idiap.ch/bob/bob.learn.em', license='BSD', author='Andre Anjos', author_email='andre.anjos@idiap.ch', -- GitLab