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