From 616c9e719f99d9ed1a1a80c9b74b76d71ca2fcf4 Mon Sep 17 00:00:00 2001
From: Samuel Farrens
Date: Wed, 31 Mar 2021 18:39:35 +0200
Subject: [PATCH] ModOpt v1.5 release (#108)
* added workflows
* test update to deploy test results from fork
* fix typo
* test commands copied from yaml
* removed test deployment
* Pyralid style update (#104)
* first iteration of pyralid style update
* updated progress on pyralid style refactor
* further updates
* latest update
* all tests passing locally
* all doctests passing locally
* removed autodoc files
* updated refactoring
* test pull_request_target and add main branch
* added logo and fixed link to api docs
* added develop branch to CI
* updated workflow
* test PR review
* reverted to standard PR directive
* updated readme
* test deploy test results from fork
* attempt to fix fomatting
* removed test deployment
* added #97 GPU compatibility in consistent style
* additional clean up
* more clean up
* fixed mistake
* Update modopt/interface/errors.py
Co-authored-by: Zaccharie Ramzi
* Update modopt/tests/test_opt.py
Co-authored-by: Zaccharie Ramzi
* Update modopt/tests/test_opt.py
Co-authored-by: Zaccharie Ramzi
* Update modopt/tests/test_opt.py
Co-authored-by: Zaccharie Ramzi
* Update modopt/tests/test_opt.py
Co-authored-by: Zaccharie Ramzi
* Update modopt/tests/test_opt.py
Co-authored-by: Zaccharie Ramzi
* Update modopt/tests/test_math.py
Co-authored-by: Zaccharie Ramzi
* Update modopt/tests/test_math.py
Co-authored-by: Zaccharie Ramzi
* removed doc requirements from basic test suite
* removed contents as they are now automatically generated on GitHub
* fix GPU bug in PowerMethod
* Update modopt/tests/test_opt.py
Co-authored-by: Zaccharie Ramzi
* Update modopt/tests/test_opt.py
Co-authored-by: Zaccharie Ramzi
* Update modopt/tests/test_opt.py
Co-authored-by: Zaccharie Ramzi
* Update modopt/tests/test_opt.py
Co-authored-by: Zaccharie Ramzi
* Update modopt/tests/test_opt.py
Co-authored-by: Zaccharie Ramzi
* Update modopt/tests/test_opt.py
Co-authored-by: Zaccharie Ramzi
* Update modopt/tests/test_opt.py
Co-authored-by: Zaccharie Ramzi
* Update modopt/tests/test_opt.py
Co-authored-by: Zaccharie Ramzi
* Update modopt/tests/test_opt.py
Co-authored-by: Zaccharie Ramzi
* Update modopt/tests/test_opt.py
Co-authored-by: Zaccharie Ramzi
* Update modopt/tests/test_opt.py
Co-authored-by: Zaccharie Ramzi
* Update modopt/tests/test_opt.py
Co-authored-by: Zaccharie Ramzi
* Update modopt/tests/test_opt.py
Co-authored-by: Zaccharie Ramzi
* Update modopt/tests/test_opt.py
Co-authored-by: Zaccharie Ramzi
* Update modopt/tests/test_opt.py
Co-authored-by: Zaccharie Ramzi
* renamed dummy functions in test_opt.py
Co-authored-by: Zaccharie Ramzi
* Release cleanup (#109)
* cleaned up readme
* cleaned up api docs
Co-authored-by: Zaccharie Ramzi
---
.github/workflows/cd-build.yml | 87 ++
.github/workflows/ci-build.yml | 126 +++
.gitignore | 149 ++-
.pylintrc | 2 +
.pyup.yml | 11 +
.travis.yml | 43 -
MANIFEST.in | 2 +
README.md | 79 ++
README.rst | 152 ----
develop.txt | 8 +
docs/_templates/module.rst_t | 8 +
docs/_templates/package.rst_t | 54 ++
docs/_templates/toc.rst_t | 8 +
docs/requirements.txt | 7 +
docs/source/about.rst | 48 +
docs/source/citing.rst | 7 +
docs/source/conf.py | 416 +++------
docs/source/contributing.rst | 9 +
docs/source/cosmostat_logo.jpg | Bin 0 -> 169466 bytes
docs/source/dependencies.rst | 98 ++
docs/source/examples.rst | 6 -
docs/source/index.rst | 142 +--
docs/source/installation.rst | 50 ++
docs/source/modopt.base.np_adjust.rst | 7 -
docs/source/modopt.base.observable.rst | 7 -
docs/source/modopt.base.rst | 22 -
docs/source/modopt.base.transform.rst | 7 -
docs/source/modopt.base.types.rst | 7 -
docs/source/modopt.base.wrappers.rst | 7 -
docs/source/modopt.info.rst | 7 -
docs/source/modopt.interface.errors.rst | 7 -
docs/source/modopt.interface.log.rst | 7 -
docs/source/modopt.interface.rst | 19 -
docs/source/modopt.math.convolve.rst | 7 -
docs/source/modopt.math.matrix.rst | 7 -
docs/source/modopt.math.metrics.rst | 7 -
docs/source/modopt.math.rst | 21 -
docs/source/modopt.math.stats.rst | 7 -
docs/source/modopt.opt.algorithms.rst | 7 -
docs/source/modopt.opt.cost.rst | 7 -
docs/source/modopt.opt.gradient.rst | 7 -
docs/source/modopt.opt.linear.rst | 7 -
docs/source/modopt.opt.proximity.rst | 7 -
docs/source/modopt.opt.reweight.rst | 7 -
docs/source/modopt.opt.rst | 23 -
docs/source/modopt.plot.cost_plot.rst | 7 -
docs/source/modopt.plot.rst | 18 -
docs/source/modopt.rst | 31 -
docs/source/modopt.signal.filter.rst | 7 -
docs/source/modopt.signal.noise.rst | 7 -
docs/source/modopt.signal.positivity.rst | 7 -
docs/source/modopt.signal.rst | 23 -
docs/source/modopt.signal.svd.rst | 7 -
docs/source/modopt.signal.validation.rst | 7 -
docs/source/modopt.signal.wavelet.rst | 7 -
docs/source/modopt_logo.png | Bin 0 -> 622687 bytes
docs/source/modules.rst | 7 -
docs/source/my_ref.bib | 17 +
docs/source/neurospin_logo.png | Bin 0 -> 62657 bytes
docs/source/notebooks.rst | 8 +
docs/source/quickstart.rst | 12 +
docs/source/toc.rst | 35 +
docs/source/z_ref.rst | 5 +
modopt/__init__.py | 23 +-
modopt/base/__init__.py | 2 +-
modopt/base/backend.py | 187 ++++
modopt/base/np_adjust.py | 94 +-
modopt/base/observable.py | 121 +--
modopt/base/transform.py | 130 +--
modopt/base/types.py | 135 ++-
modopt/base/wrappers.py | 25 +-
modopt/info.py | 25 -
modopt/interface/__init__.py | 4 +-
modopt/interface/errors.py | 74 +-
modopt/interface/log.py | 20 +-
modopt/math/__init__.py | 4 +-
modopt/math/convolve.py | 86 +-
modopt/math/matrix.py | 163 ++--
modopt/math/metrics.py | 71 +-
modopt/math/stats.py | 110 ++-
modopt/opt/__init__.py | 4 +-
modopt/opt/algorithms.py | 736 +++++++++------
modopt/opt/cost.py | 100 ++-
modopt/opt/gradient.py | 158 ++--
modopt/opt/linear.py | 117 +--
modopt/opt/proximity.py | 660 ++++++++------
modopt/opt/reweight.py | 58 +-
modopt/plot/__init__.py | 4 +-
modopt/plot/cost_plot.py | 22 +-
modopt/signal/__init__.py | 4 +-
modopt/signal/filter.py | 57 +-
modopt/signal/noise.py | 93 +-
modopt/signal/positivity.py | 94 +-
modopt/signal/svd.py | 167 ++--
modopt/signal/validation.py | 34 +-
modopt/signal/wavelet.py | 186 ++--
modopt/tests/test_base.py | 295 +++---
modopt/tests/test_math.py | 570 +++++++-----
modopt/tests/test_opt.py | 1049 ++++++++++++++--------
modopt/tests/test_signal.py | 457 ++++++----
notebooks/.gitkeep | 0
requirements.txt | 7 +-
setup.cfg | 80 +-
setup.py | 75 +-
104 files changed, 4868 insertions(+), 3361 deletions(-)
create mode 100644 .github/workflows/cd-build.yml
create mode 100644 .github/workflows/ci-build.yml
create mode 100644 .pylintrc
create mode 100644 .pyup.yml
delete mode 100644 .travis.yml
create mode 100644 README.md
delete mode 100644 README.rst
create mode 100644 develop.txt
create mode 100644 docs/_templates/module.rst_t
create mode 100644 docs/_templates/package.rst_t
create mode 100644 docs/_templates/toc.rst_t
create mode 100644 docs/requirements.txt
create mode 100644 docs/source/about.rst
create mode 100644 docs/source/citing.rst
create mode 100644 docs/source/contributing.rst
create mode 100644 docs/source/cosmostat_logo.jpg
create mode 100644 docs/source/dependencies.rst
delete mode 100644 docs/source/examples.rst
create mode 100644 docs/source/installation.rst
delete mode 100644 docs/source/modopt.base.np_adjust.rst
delete mode 100644 docs/source/modopt.base.observable.rst
delete mode 100644 docs/source/modopt.base.rst
delete mode 100644 docs/source/modopt.base.transform.rst
delete mode 100644 docs/source/modopt.base.types.rst
delete mode 100644 docs/source/modopt.base.wrappers.rst
delete mode 100644 docs/source/modopt.info.rst
delete mode 100644 docs/source/modopt.interface.errors.rst
delete mode 100644 docs/source/modopt.interface.log.rst
delete mode 100644 docs/source/modopt.interface.rst
delete mode 100644 docs/source/modopt.math.convolve.rst
delete mode 100644 docs/source/modopt.math.matrix.rst
delete mode 100644 docs/source/modopt.math.metrics.rst
delete mode 100644 docs/source/modopt.math.rst
delete mode 100644 docs/source/modopt.math.stats.rst
delete mode 100644 docs/source/modopt.opt.algorithms.rst
delete mode 100644 docs/source/modopt.opt.cost.rst
delete mode 100644 docs/source/modopt.opt.gradient.rst
delete mode 100644 docs/source/modopt.opt.linear.rst
delete mode 100644 docs/source/modopt.opt.proximity.rst
delete mode 100644 docs/source/modopt.opt.reweight.rst
delete mode 100644 docs/source/modopt.opt.rst
delete mode 100644 docs/source/modopt.plot.cost_plot.rst
delete mode 100644 docs/source/modopt.plot.rst
delete mode 100644 docs/source/modopt.rst
delete mode 100644 docs/source/modopt.signal.filter.rst
delete mode 100644 docs/source/modopt.signal.noise.rst
delete mode 100644 docs/source/modopt.signal.positivity.rst
delete mode 100644 docs/source/modopt.signal.rst
delete mode 100644 docs/source/modopt.signal.svd.rst
delete mode 100644 docs/source/modopt.signal.validation.rst
delete mode 100644 docs/source/modopt.signal.wavelet.rst
create mode 100644 docs/source/modopt_logo.png
delete mode 100644 docs/source/modules.rst
create mode 100644 docs/source/my_ref.bib
create mode 100644 docs/source/neurospin_logo.png
create mode 100644 docs/source/notebooks.rst
create mode 100644 docs/source/quickstart.rst
create mode 100644 docs/source/toc.rst
create mode 100644 docs/source/z_ref.rst
create mode 100644 modopt/base/backend.py
mode change 100755 => 100644 modopt/base/observable.py
delete mode 100644 modopt/info.py
create mode 100644 notebooks/.gitkeep
diff --git a/.github/workflows/cd-build.yml b/.github/workflows/cd-build.yml
new file mode 100644
index 00000000..1e49f8bc
--- /dev/null
+++ b/.github/workflows/cd-build.yml
@@ -0,0 +1,87 @@
+name: CD
+
+on:
+ push:
+ branches:
+ - master
+ - main
+
+jobs:
+
+ coverage:
+ name: Deploy Coverage Results
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+
+ - name: Set up Conda with Python 3.8
+ uses: conda-incubator/setup-miniconda@v2
+ with:
+ auto-update-conda: true
+ python-version: 3.8
+ auto-activate-base: false
+
+ - name: Install dependencies
+ shell: bash -l {0}
+ run: |
+ python -m pip install --upgrade pip
+ python -m pip install -r develop.txt
+ python -m pip install twine
+ python -m pip install .
+
+ - name: Run Tests
+ shell: bash -l {0}
+ run: |
+ python setup.py test
+
+ - name: Check distribution
+ shell: bash -l {0}
+ run: |
+ python setup.py sdist
+ twine check dist/*
+
+ - name: Upload coverage to Codecov
+ uses: codecov/codecov-action@v1
+ with:
+ token: ${{ secrets.CODECOV_TOKEN }}
+ file: coverage.xml
+ flags: unittests
+
+ api:
+ name: Deploy API Documentation
+ needs: coverage
+ runs-on: ubuntu-latest
+ if: success()
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+
+ - name: Set up Conda with Python 3.8
+ uses: conda-incubator/setup-miniconda@v2
+ with:
+ auto-update-conda: true
+ python-version: 3.8
+ auto-activate-base: false
+
+ - name: Install dependencies
+ shell: bash -l {0}
+ run: |
+ conda install -c conda-forge pandoc
+ python -m pip install --upgrade pip
+ python -m pip install -r docs/requirements.txt
+ python -m pip install .
+
+ - name: Build API documentation
+ shell: bash -l {0}
+ run: |
+ sphinx-apidoc -t docs/_templates -feTMo docs/source modopt
+ sphinx-build -E docs/source docs/_build
+
+ - name: Deploy API documentation
+ uses: peaceiris/actions-gh-pages@v3.5.9
+ with:
+ github_token: ${{ secrets.GITHUB_TOKEN }}
+ publish_dir: docs/_build
diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml
new file mode 100644
index 00000000..2ed4960d
--- /dev/null
+++ b/.github/workflows/ci-build.yml
@@ -0,0 +1,126 @@
+name: CI
+
+on:
+ pull_request:
+ branches:
+ - develop
+ - master
+ - main
+
+jobs:
+ test-full:
+ name: Full Test Suite
+ runs-on: ${{ matrix.os }}
+
+ strategy:
+ fail-fast: false
+ matrix:
+ os: [ubuntu-latest, macos-latest]
+ python-version: [3.8]
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+
+ - name: Report WPS Errors
+ uses: wemake-services/wemake-python-styleguide@0.14.1
+ continue-on-error: true
+ with:
+ reporter: 'github-pr-review'
+ path: './modopt'
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+
+ - name: Set up Conda with Python ${{ matrix.python-version }}
+ uses: conda-incubator/setup-miniconda@v2
+ with:
+ auto-update-conda: true
+ python-version: ${{ matrix.python-version }}
+ auto-activate-base: false
+
+ - name: Check Conda
+ shell: bash -l {0}
+ run: |
+ conda info
+ conda list
+ python --version
+
+ - name: Install Dependencies
+ shell: bash -l {0}
+ run: |
+ python --version
+ python -m pip install --upgrade pip
+ python -m pip install -r develop.txt
+ python -m pip install -r docs/requirements.txt
+ python -m pip install astropy scikit-image scikit-learn
+ python -m pip install twine
+ python -m pip install .
+
+ - name: Run Tests
+ shell: bash -l {0}
+ run: |
+ export PATH=/usr/share/miniconda/bin:$PATH
+ python setup.py test
+
+ - name: Save Test Results
+ if: always()
+ uses: actions/upload-artifact@v2
+ with:
+ name: unit-test-results-${{ matrix.os }}-${{ matrix.python-version }}
+ path: pytest.xml
+
+ - name: Check Distribution
+ shell: bash -l {0}
+ run: |
+ python setup.py sdist
+ twine check dist/*
+
+ - name: Check API Documentation build
+ shell: bash -l {0}
+ run: |
+ conda install -c conda-forge pandoc
+ sphinx-apidoc -t docs/_templates -feTMo docs/source modopt
+ sphinx-build -b doctest -E docs/source docs/_build
+
+ - name: Upload Coverage to Codecov
+ uses: codecov/codecov-action@v1
+ with:
+ token: ${{ secrets.CODECOV_TOKEN }}
+ file: coverage.xml
+ flags: unittests
+
+ test-basic:
+ name: Basic Test Suite
+ runs-on: ${{ matrix.os }}
+
+ strategy:
+ fail-fast: false
+ matrix:
+ os: [ubuntu-latest, macos-latest]
+ python-version: [3.6, 3.7, 3.9]
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+
+ - name: Set up Conda with Python ${{ matrix.python-version }}
+ uses: conda-incubator/setup-miniconda@v2
+ with:
+ auto-update-conda: true
+ python-version: ${{ matrix.python-version }}
+ auto-activate-base: false
+
+ - name: Install Dependencies
+ shell: bash -l {0}
+ run: |
+ python --version
+ python -m pip install --upgrade pip
+ python -m pip install -r develop.txt
+ python -m pip install astropy scikit-image scikit-learn
+ python -m pip install .
+
+ - name: Run Tests
+ shell: bash -l {0}
+ run: |
+ export PATH=/usr/share/miniconda/bin:$PATH
+ python setup.py test
diff --git a/.gitignore b/.gitignore
index f76522d1..06dff8db 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,21 +1,142 @@
-# Ignore Python compilation
-*.pyc
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
-# Ignore scripts
-*.sh
+# C extensions
+*.so
-# Ignore cache
-*.cache/
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+
+# PyInstaller
+# Usually these files are written by a python script from a template
+# before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
-# Ignore coverage tests
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.nox/
.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+*.py,cover
+.hypothesis/
.pytest_cache/
+cover/
+pytest.xml
-# Ignore installation
-.eggs/
-modopt.egg-info/
-dist/
-build/
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+local_settings.py
+db.sqlite3
+db.sqlite3-journal
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+docs/source/fortuna.*
+docs/source/scripts.*
+docs/source/*.nblink
+
+# PyBuilder
+.pybuilder/
+target/
+
+# Jupyter Notebook
+.ipynb_checkpoints
+
+# IPython
+profile_default/
+ipython_config.py
+
+# pyenv
+# For a library or package, you might want to ignore these files since the code is
+# intended to run in multiple environments; otherwise, check them in:
+# .python-version
+
+# pipenv
+# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
+# However, in case of collaboration, if having platform-specific dependencies or dependencies
+# having no cross-platform support, pipenv may install dependencies that don't work, or not
+# install all needed dependencies.
+#Pipfile.lock
+
+# PEP 582; used by e.g. github.com/David-OConnor/pyflow
+__pypackages__/
+
+# Celery stuff
+celerybeat-schedule
+celerybeat.pid
+
+# SageMath parsed files
+*.sage.py
+
+# Environments
+.env
+.venv
+env/
+venv/
+ENV/
+env.bak/
+venv.bak/
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+
+# Pyre type checker
+.pyre/
+
+# pytype static type analyzer
+.pytype/
-# Ignore pypi config
-.pypirc
+# Cython debug symbols
+cython_debug/
diff --git a/.pylintrc b/.pylintrc
new file mode 100644
index 00000000..3ac9aef9
--- /dev/null
+++ b/.pylintrc
@@ -0,0 +1,2 @@
+[MASTER]
+ignore-patterns=**/docs/**/*.py
diff --git a/.pyup.yml b/.pyup.yml
new file mode 100644
index 00000000..d844b78b
--- /dev/null
+++ b/.pyup.yml
@@ -0,0 +1,11 @@
+# autogenerated pyup.io config file
+# see https://pyup.io/docs/configuration/ for all available options
+
+schedule: ''
+update: all
+label_prs: update
+assignees: sfarrens
+requirements:
+ - requirements.txt
+ - develop.txt
+ - docs/requirements.txt
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index b5b770d7..00000000
--- a/.travis.yml
+++ /dev/null
@@ -1,43 +0,0 @@
-language: python
-dist: focal
-sudo: required
-
-# GitHub branch
-branches:
- only:
- - master
-
-# build jobs
-jobs:
- include:
- - python: 3.6
- - python: 3.7
- - python: 3.8
- after_success:
- - coveralls
- - stage: deploy
- install:
- - pip install numpy scipy progressbar2
- - pip install sphinx sphinx-rtd-theme sphinxcontrib-bibtex numpydoc==0.9.2 travis-sphinx
- script:
- - sphinx-apidoc -feo docs/source modopt
- - travis-sphinx -v -o docs/build build -n -s docs/source
- after_success:
- - travis-sphinx -o docs/build deploy
-
-# update pre-installed packages
-before_install:
- - pip list --outdated --format=freeze | grep -v '^\-e' | cut -d = -f 1 | xargs -n1 pip install -U
-
-# install dependencies
-install:
- - pip install scikit-learn
- - pip install astropy scikit-image
-
-# run unit tests
-script:
- - python setup.py test
-
-# notification settings
-notification:
- email: false
diff --git a/MANIFEST.in b/MANIFEST.in
index 916c2c9b..9a2f374e 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,3 +1,5 @@
include requirements.txt
+include develop.txt
+include docs/requirements.txt
include README.rst
include LICENSE.txt
diff --git a/README.md b/README.md
new file mode 100644
index 00000000..aa72d976
--- /dev/null
+++ b/README.md
@@ -0,0 +1,79 @@
+# ModOpt
+
+
+
+| Usage | Development | Release |
+| ----- | ----------- | ------- |
+| [![docs](https://img.shields.io/badge/docs-Sphinx-blue)](https://cea-cosmic.github.io/ModOpt/) | [![build](https://github.com/CEA-COSMIC/modopt/workflows/CI/badge.svg)](https://github.com/CEA-COSMIC/modopt/actions?query=workflow%3ACI) | [![release](https://img.shields.io/github/v/release/CEA-COSMIC/modopt)](https://github.com/CEA-COSMIC/modopt/releases/latest) |
+| [![license](https://img.shields.io/github/license/CEA-COSMIC/modopt)](https://github.com/CEA-COSMIC/modopt/blob/master/LICENCE.txt) | [![deploy](https://github.com/CEA-COSMIC/modopt/workflows/CD/badge.svg)](https://github.com/CEA-COSMIC/modopt/actions?query=workflow%3ACD) | [![pypi](https://img.shields.io/pypi/v/modopt)](https://pypi.org/project/modopt/) |
+| [![wemake-python-styleguide](https://img.shields.io/badge/style-wemake-000000.svg)](https://github.com/wemake-services/wemake-python-styleguide) | [![codecov](https://codecov.io/gh/CEA-COSMIC/modopt/branch/master/graph/badge.svg?token=XHJIQXV7AX)](https://codecov.io/gh/CEA-COSMIC/modopt) | [![python](https://img.shields.io/pypi/pyversions/modopt)](https://www.python.org/downloads/source/) |
+| [![contribute](https://img.shields.io/badge/contribute-read-lightgrey)](https://github.com/CEA-COSMIC/modopt/blob/master/CONTRIBUTING.md) | [![CodeFactor](https://www.codefactor.io/repository/github/CEA-COSMIC/modopt/badge)](https://www.codefactor.io/repository/github/CEA-COSMIC/modopt) | |
+| [![coc](https://img.shields.io/badge/conduct-read-lightgrey)](https://github.com/CEA-COSMIC/modopt/blob/master/CODE_OF_CONDUCT.md) | [![Updates](https://pyup.io/repos/github/CEA-COSMIC/modopt/shield.svg)](https://pyup.io/repos/github/CEA-COSMIC/ModOpt/) | |
+
+ModOpt is a series of **Modular Optimisation** tools for solving inverse problems.
+
+See [documentation](https://CEA-COSMIC.github.io/ModOpt/) for more details.
+
+## Installation
+
+To install using `pip` run the following command:
+
+```bash
+ $ pip install modopt
+```
+
+To clone the ModOpt repository from GitHub run the following command:
+
+```bash
+ $ git clone https://github.com/CEA-COSMIC/ModOpt.git
+```
+
+## Dependencies
+
+All packages required by ModOpt should be installed automatically. Optional packages, however, will need to be installed manually.
+
+### Required Packages
+
+In order to run the code in this repository the following packages must be
+installed:
+
+* [Python](https://www.python.org/) [> 3.6]
+* [importlib_metadata](https://importlib-metadata.readthedocs.io/en/latest/) [==3.7.0]
+* [Numpy](http://www.numpy.org/) [==1.19.5]
+* [Scipy](http://www.scipy.org/) [==1.5.4]
+* [Progressbar 2](https://progressbar-2.readthedocs.io/) [==3.53.1]
+
+### Optional Packages
+
+The following packages can optionally be installed to add extra functionality:
+
+* [Astropy](http://www.astropy.org/)
+* [Matplotlib](http://matplotlib.org/)
+* [Scikit-Image](https://scikit-image.org/)
+* [Scikit-Learn](https://scikit-learn.org/)
+* [Termcolor](https://pypi.python.org/pypi/termcolor)
+
+For (partial) GPU compliance the following packages can also be installed.
+Note that none of these are required for running on a CPU.
+
+* [CuPy](https://cupy.dev/)
+* [Torch](https://pytorch.org/)
+
+## Citation
+
+If you use ModOpt in a scientific publication, we would appreciate citations to the following paper:
+
+[PySAP: Python Sparse Data Analysis Package for multidisciplinary image processing](https://www.sciencedirect.com/science/article/pii/S2213133720300561), S. Farrens et al., Astronomy and Computing 32, 2020
+
+The BibTeX citation is the following:
+```
+@Article{farrens2020pysap,
+ title={{PySAP: Python Sparse Data Analysis Package for multidisciplinary image processing}},
+ author={Farrens, S and Grigis, A and El Gueddari, L and Ramzi, Z and Chaithya, GR and Starck, S and Sarthou, B and Cherkaoui, H and Ciuciu, P and Starck, J-L},
+ journal={Astronomy and Computing},
+ volume={32},
+ pages={100402},
+ year={2020},
+ publisher={Elsevier}
+}
+```
diff --git a/README.rst b/README.rst
deleted file mode 100644
index 9690f9d4..00000000
--- a/README.rst
+++ /dev/null
@@ -1,152 +0,0 @@
-ModOpt
-======
-
-|travis| |coveralls| |license| |python36| |python37| |python38| |pypi|
-
-.. |travis| image:: https://travis-ci.org/CEA-COSMIC/ModOpt.svg?branch=master
- :target: https://travis-ci.org/CEA-COSMIC/ModOpt
-
-.. |coveralls| image:: https://coveralls.io/repos/github/CEA-COSMIC/ModOpt/badge.svg
- :target: https://coveralls.io/github/CEA-COSMIC/ModOpt
-
-.. |license| image:: https://img.shields.io/github/license/mashape/apistatus.svg
- :target: https://github.com/CEA-COSMIC/ModOpt/blob/master/LICENCE.txt
-
-.. |python36| image:: https://img.shields.io/badge/python-3.6-green.svg
- :target: https://www.python.org/
-
-.. |python37| image:: https://img.shields.io/badge/python-3.7-green.svg
- :target: https://www.python.org/
-
-.. |python38| image:: https://img.shields.io/badge/python-3.8-green.svg
- :target: https://www.python.org/
-
-.. |pypi| image:: https://badge.fury.io/py/modopt.svg
- :target: https://badge.fury.io/py/modopt
-
-
-:Author: Samuel Farrens `(samuel.farrens@cea.fr) `_
-
-:Version: 1.4.4
-
-:Release Date: 16/06/2020
-
-:Documentation: |link-to-docs|
-
-:Repository: |link-to-repo|
-
-.. |link-to-docs| raw:: html
-
- https://cea-cosmic.github.io/ModOpt/
-
-.. |link-to-repo| raw:: html
-
- https://github.com/CEA-COSMIC/ModOpt
-
-ModOpt is a series of Modular Optimisation tools for solving inverse problems.
-
-Contents
-========
-
-1. `Dependencies`_
-2. `Installation`_
-
-Dependencies
-============
-
-Required Packages
------------------
-
-In order to run the code in this repository the following packages must be
-installed:
-
-* |link-to-python| [Last tested with v3.8.2]
-
-* |link-to-numpy| [Tested with v1.18.3]
-
-* |link-to-scipy| [Tested with v1.4.1]
-
-* |link-to-progressbar| [Tested with v3.51.1]
-
-.. |link-to-python| raw:: html
-
- Python
-
-.. |link-to-numpy| raw:: html
-
- Numpy
-
-.. |link-to-scipy| raw:: html
-
- Scipy
-
-.. |link-to-progressbar| raw:: html
-
- Progressbar 2
-
-Optional Packages
------------------
-
-The following packages can optionally be installed to add extra functionality:
-
-* |link-to-astropy| [Last tested with v4.0.1]
-
-* |link-to-matplotlib| [Last tested with v3.2.1]
-
-* |link-to-skimage| [Requires >=v0.16.2]
-
-* |link-to-sklearn| [Requires >=v0.22.2]
-
-* |link-to-termcolor| [Last tested with v1.1.0]
-
-.. |link-to-astropy| raw:: html
-
- Astropy
-
-.. |link-to-matplotlib| raw:: html
-
- Matplotlib
-
-.. |link-to-skimage| raw:: html
-
- Scikit-Image
-
-.. |link-to-sklearn| raw:: html
-
- Scikit-Learn
-
-.. |link-to-termcolor| raw:: html
-
- Termcolor
-
-Installation
-============
-
-To install using `pip` run the following command:
-
-.. code-block:: bash
-
- $ pip install modopt
-
-To install using `easy_install` run the following command:
-
-.. code-block:: bash
-
- $ easy_install modopt
-
-To clone the ModOpt repository from GitHub run the following command:
-
-.. code-block:: bash
-
- $ git clone https://github.com/cea-cosmic/ModOpt
diff --git a/develop.txt b/develop.txt
new file mode 100644
index 00000000..b88396e7
--- /dev/null
+++ b/develop.txt
@@ -0,0 +1,8 @@
+coverage==5.5
+nose==1.3.7
+pytest==6.2.2
+pytest-cov==2.11.1
+pytest-pep8==1.0.6
+pytest-emoji==0.2.0
+pytest-flake8==1.0.7
+wemake-python-styleguide==0.15.2
diff --git a/docs/_templates/module.rst_t b/docs/_templates/module.rst_t
new file mode 100644
index 00000000..73ad73fc
--- /dev/null
+++ b/docs/_templates/module.rst_t
@@ -0,0 +1,8 @@
+{%- if show_headings %}
+{{- basename | e | heading(2) }}
+
+{% endif -%}
+.. automodule:: {{ qualname }}
+{%- for option in automodule_options %}
+ :{{ option }}:
+{%- endfor %}
diff --git a/docs/_templates/package.rst_t b/docs/_templates/package.rst_t
new file mode 100644
index 00000000..344f9d16
--- /dev/null
+++ b/docs/_templates/package.rst_t
@@ -0,0 +1,54 @@
+{%- macro automodule(modname, options) -%}
+.. automodule:: {{ modname }}
+{%- for option in options %}
+ :{{ option }}:
+{%- endfor %}
+{%- endmacro %}
+
+{%- macro toctree(docnames) -%}
+.. toctree::
+ :maxdepth: {{ maxdepth }}
+{% for docname in docnames %}
+ {{ docname }}
+{%- endfor %}
+{%- endmacro %}
+
+{%- if is_namespace %}
+{{- [pkgname, "namespace"] | join(" ") | e | heading }}
+{% else %}
+{{- pkgname | e | heading }}
+
+{% endif %}
+
+{%- if modulefirst and not is_namespace %}
+{{ automodule(pkgname, automodule_options) }}
+{% endif %}
+
+{%- if subpackages %}
+Subpackages
+-----------
+
+{{ toctree(subpackages) }}
+{% endif %}
+
+{%- if submodules %}
+Submodules
+----------
+{% if separatemodules %}
+{{ toctree(submodules) }}
+{% else %}
+{%- for submodule in submodules %}
+{% if show_headings %}
+{{- submodule | e | heading(2) }}
+{% endif %}
+{{ automodule(submodule, automodule_options) }}
+{% endfor %}
+{%- endif %}
+{%- endif %}
+
+{%- if not modulefirst and not is_namespace %}
+Module contents
+---------------
+
+{{ automodule(pkgname, automodule_options) }}
+{% endif %}
diff --git a/docs/_templates/toc.rst_t b/docs/_templates/toc.rst_t
new file mode 100644
index 00000000..f0877eeb
--- /dev/null
+++ b/docs/_templates/toc.rst_t
@@ -0,0 +1,8 @@
+{{ header | heading }}
+
+.. toctree::
+ :maxdepth: {{ maxdepth }}
+{% for docname in docnames %}
+ {{ docname }}
+{%- endfor %}
+
diff --git a/docs/requirements.txt b/docs/requirements.txt
new file mode 100644
index 00000000..e1c873a2
--- /dev/null
+++ b/docs/requirements.txt
@@ -0,0 +1,7 @@
+jupyter==1.0.0
+nbsphinx==0.8.2
+nbsphinx-link==1.3.0
+numpydoc==1.1.0
+sphinx==3.5.2
+sphinxcontrib-bibtex==2.2.0
+sphinxawesome-theme==1.19.2
diff --git a/docs/source/about.rst b/docs/source/about.rst
new file mode 100644
index 00000000..0d412b5d
--- /dev/null
+++ b/docs/source/about.rst
@@ -0,0 +1,48 @@
+About
+=====
+
+ModOpt was developed as part of |link-to-cosmic|, a multi-disciplinary collaboration
+between |link-to-neurospin|, experts in biomedical imaging, and |link-to-cosmostat|,
+experts in astrophysical image processing. The package was
+designed to provide the backend optimisation algorithms for
+|link-to-pysap| :cite:`farrens:2020`, but also serves as a stand-alone library
+of inverse problem solving tools. While PySAP aims to provide
+application-specific tools for solving complex imaging problems, ModOpt can in
+principle be applied to any linear inverse problem.
+
+Contributors
+------------
+
+You can find a |link-to-contributors|.
+
+.. |link-to-cosmic| raw:: html
+
+ COSMIC
+
+.. |link-to-neurospin| raw:: html
+
+ NeuroSpin
+
+.. |link-to-cosmostat| raw:: html
+
+ CosmoStat
+
+.. |link-to-pysap| raw:: html
+
+ PySAP
+
+.. |link-to-contributors| raw:: html
+
+ list of ModOpt contributors here
+
+
+.. image:: cosmostat_logo.jpg
+ :width: 300
+ :alt: CosmoStat Logo
+
+.. image:: neurospin_logo.png
+ :width: 300
+ :alt: NeuroSpin Logo
diff --git a/docs/source/citing.rst b/docs/source/citing.rst
new file mode 100644
index 00000000..19471a51
--- /dev/null
+++ b/docs/source/citing.rst
@@ -0,0 +1,7 @@
+Citing this Package
+===================
+
+We kindly request that any academic work making use of this package to cite :cite:`farrens:2020`.
+
+.. bibliography:: my_ref.bib
+ :style: alpha
diff --git a/docs/source/conf.py b/docs/source/conf.py
index cca36eb4..95aaba20 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -1,19 +1,10 @@
# -*- coding: utf-8 -*-
-#
-# ModOpt documentation build configuration file, created by
-# sphinx-quickstart on Mon Oct 24 16:46:22 2016.
-#
-# This file is execfile()d with the current directory set to its
-# containing dir.
-#
-# Note that not all possible configuration values are present in this
-# autogenerated file.
-#
-# All configuration values have a default; values that are commented out
-# serve to show the default.
+# Python Template sphinx config
+# Import relevant modules
import sys
import os
+from importlib_metadata import metadata
# 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
@@ -22,8 +13,17 @@
# -- General configuration ------------------------------------------------
+# General information about the project.
+project = 'modopt'
+
+mdata = metadata(project)
+author = mdata['Author']
+version = mdata['Version']
+copyright = '2020, {}'.format(author)
+gh_user = 'sfarrens'
+
# If your documentation needs a minimal Sphinx version, state it here.
-# needs_sphinx = '1.0'
+needs_sphinx = '3.3'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
@@ -31,128 +31,79 @@
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.autosummary',
- 'sphinxcontrib.bibtex',
+ 'sphinx.ext.coverage',
'sphinx.ext.doctest',
+ 'sphinx.ext.ifconfig',
'sphinx.ext.intersphinx',
- 'sphinx.ext.todo',
- 'sphinx.ext.coverage',
'sphinx.ext.mathjax',
- 'sphinx.ext.ifconfig',
- 'sphinx.ext.viewcode',
'sphinx.ext.napoleon',
- 'numpydoc'
+ 'sphinx.ext.todo',
+ 'sphinx.ext.viewcode',
+ 'sphinxawesome_theme',
+ 'sphinxcontrib.bibtex',
+ 'nbsphinx',
+ 'nbsphinx_link',
+ 'numpydoc',
]
-# Include init in class documentation.
-autoclass_content = 'both'
+# Include module names for objects
+add_module_names = False
-# Order docstrings as in the source
-autodoc_member_order = 'bysource'
+# Set class documentation standard.
+autoclass_content = 'class'
-# Include private class methods
-autodoc_default_flags = ['members', 'private-members']
+# Audodoc options
+autodoc_default_options = {
+ 'member-order': 'bysource',
+ 'private-members': True,
+ 'show-inheritance': True
+}
+
+# Generate summaries
+autosummary_generate = True
# Suppress class members in toctree.
numpydoc_show_class_members = False
-# Add any paths that contain templates here, relative to this directory.
-templates_path = ['_templates']
-
# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
-# source_suffix = ['.rst', '.md']
-source_suffix = '.rst'
-
-# The encoding of source files.
-# source_encoding = 'utf-8-sig'
+source_suffix = ['.rst', '.md']
# The master toctree document.
master_doc = 'index'
-# General information about the project.
-project = u'modopt'
-copyright = u'2017, Samuel Farrens'
-author = u'Samuel Farrens'
-
-# 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 = u'1.0'
-# The full version, including alpha/beta/rc tags.
-release = u'1.0'
-
-# The language for content autogenerated by Sphinx. Refer to documentation
-# for a list of supported languages.
-#
-# This is also used if you do content translation via gettext catalogs.
-# Usually you set "language" from the command line for these cases.
-language = None
-
-# There are two options for replacing |today|: either, you set today to some
-# non-false value, then it is used:
-# today = ''
-# Else, today_fmt is used as the format for a strftime call.
-# today_fmt = '%B %d, %Y'
-
-# List of patterns, relative to source directory, that match files and
-# directories to ignore when looking for source files.
-exclude_patterns = []
-
-# The reST default role (used for this markup: `text`) to use for all
-# documents.
-# default_role = None
-
-# If true, '()' will be appended to :func: etc. cross-reference text.
-# add_function_parentheses = True
-
-# If true, the current module name will be prepended to all description
-# unit titles (such as .. function::).
-# add_module_names = True
-
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
show_authors = True
# The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
-
-# A list of ignored prefixes for module index sorting.
-# modindex_common_prefix = []
-
-# If true, keep warnings as "system message" paragraphs in the built documents.
-# keep_warnings = False
+pygments_style = 'default'
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = True
-
# -- Options for HTML output ----------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
-html_theme = 'sphinx_rtd_theme'
-# html_theme = 'bizstyle'
+html_theme = 'sphinxawesome_theme'
+# html_theme = 'sphinx_book_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
# documentation.
-# html_theme_options = {}
html_theme_options = {
- 'collapse_navigation': False,
- 'display_version': True,
- 'navigation_depth': 3,
- 'titles_only': True,
- 'includehidden': False,
+ "nav_include_hidden": True,
+ "show_nav": True,
+ "show_breadcrumbs": False,
+ "breadcrumbs_separator": "/"
}
+html_collapsible_definitions = True
-# Add any paths that contain custom themes here, relative to this directory.
-# html_theme_path = []
# The name for this set of Sphinx documents. If None, it defaults to
# " v documentation".
-# html_title = None
+html_title = '{0} v{1}'.format(project, version)
# A shorter title for the navigation bar. Default is the same as html_title.
# html_short_title = None
@@ -166,236 +117,111 @@
# pixels large.
# html_favicon = None
-# Add any paths that contain custom static files (such as style sheets) here,
-# relative to this directory. They are copied after the builtin static files,
-# so a file named "default.css" will overwrite the builtin "default.css".
-# html_static_path = ['_static']
-html_static_path = []
-
-# Add any extra paths that contain custom files (such as robots.txt or
-# .htaccess) here, relative to this directory. These files are copied
-# directly to the root of the documentation.
-# html_extra_path = []
-
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
-# html_last_updated_fmt = '%b %d, %Y'
+html_last_updated_fmt = '%d %b, %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
-# html_use_smartypants = True
-
-# Custom sidebar templates, maps document names to template names.
-# html_sidebars = {}
-html_sidebars = {'**': ['globaltoc.html', 'relations.html',
- 'sourcelink.html', 'searchbox.html'], }
-
-
-# Additional templates that should be rendered to pages, maps page names to
-# template names.
-# html_additional_pages = {}
-
-# If false, no module index is generated.
-# html_domain_indices = True
-
-# If false, no index is generated.
-# html_use_index = True
-
-# If true, the index is split into individual pages for each letter.
-# html_split_index = False
-
-# If true, links to the reST sources are added to the pages.
-# html_show_sourcelink = True
+html_use_smartypants = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
-# html_show_sphinx = True
+html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
-# html_show_copyright = True
-
-# If true, an OpenSearch description file will be output, and all pages will
-# contain a tag referring to it. The value of this option must be the
-# base URL from which the finished HTML is served.
-# html_use_opensearch = ''
-
-# This is the file name suffix for HTML files (e.g. ".xhtml").
-# html_file_suffix = None
-
-# Language to be used for generating the HTML full-text search index.
-# Sphinx supports the following languages:
-# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
-# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr'
-# html_search_language = 'en'
+html_show_copyright = True
-# A dictionary with options for the search language support, empty by default.
-# Now only 'ja' uses this config value
-# html_search_options = {'type': 'default'}
+# -- Options for nbshpinx output ------------------------------------------
-# The name of a javascript file (relative to the configuration directory) that
-# implements a search results scorer. If empty, the default will be used.
-# html_search_scorer = 'scorer.js'
-# Output file base name for HTML help builder.
-htmlhelp_basename = 'sftoolsdoc'
+# Custom fucntion to find notebooks, create .nblink files and update the
+# notebooks.rst file
+def add_notebooks(nb_path='../../notebooks'):
-# -- Options for LaTeX output ---------------------------------------------
+ print('Looking for notebooks')
+ nb_ext = '.ipynb'
+ nb_rst_file_name = 'notebooks.rst'
+ nb_link_format = '{{\n "path": "{0}/{1}"\n}}'
-latex_elements = {
- # The paper size ('letterpaper' or 'a4paper').
- # 'papersize': 'letterpaper',
+ nbs = sorted([nb for nb in os.listdir(nb_path) if nb.endswith(nb_ext)])
- # The font size ('10pt', '11pt' or '12pt').
- # 'pointsize': '10pt',
+ for list_pos, nb in enumerate(nbs):
- # Additional stuff for the LaTeX preamble.
- # 'preamble': '',
+ nb_name = nb.rstrip(nb_ext)
- # Latex figure (float) alignment
- # 'figure_align': 'htbp',
-}
-
-# Grouping the document tree into LaTeX files. List of tuples
-# (source start file, target name, title,
-# author, documentclass [howto, manual, or own class]).
-latex_documents = [
- (master_doc, 'modopt.tex', u'modopt Documentation',
- u'Samuel Farrens', 'manual'),
-]
-
-# The name of an image file (relative to this directory) to place at the top of
-# the title page.
-# latex_logo = None
-
-# 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
-
-# Documents to append as an appendix to all manuals.
-# latex_appendices = []
-
-# If false, no module index is generated.
-# latex_domain_indices = True
-
-
-# -- Options for manual page output ---------------------------------------
-
-# One entry per manual page. List of tuples
-# (source start file, name, description, authors, manual section).
-man_pages = [
- (master_doc, 'modopt', u'modopt Documentation',
- [author], 1)
-]
-
-# If true, show URL addresses after external links.
-# man_show_urls = False
-
-
-# -- Options for Texinfo output -------------------------------------------
-
-# Grouping the document tree into Texinfo files. List of tuples
-# (source start file, target name, title, author,
-# dir menu entry, description, category)
-texinfo_documents = [
- (master_doc, 'modopt', u'modopt Documentation',
- author, 'modopt', 'One line description of project.',
- 'Miscellaneous'),
-]
-
-# Documents to append as an appendix to all manuals.
-# texinfo_appendices = []
-
-# If false, no module index is generated.
-# texinfo_domain_indices = True
-
-# How to display URL addresses: 'footnote', 'no', or 'inline'.
-# texinfo_show_urls = 'footnote'
-
-# If true, do not generate a @detailmenu in the "Top" node's menu.
-# texinfo_no_detailmenu = False
-
-
-# -- Options for Epub output ----------------------------------------------
-
-# Bibliographic Dublin Core info.
-epub_title = project
-epub_author = author
-epub_publisher = author
-epub_copyright = copyright
-
-# The basename for the epub file. It defaults to the project name.
-# epub_basename = project
+ nb_link_file_name = nb_name + '.nblink'
+ print('Writing {0}'.format(nb_link_file_name))
+ with open(nb_link_file_name, 'w') as nb_link_file:
+ nb_link_file.write(nb_link_format.format(nb_path, nb))
-# The HTML theme for the epub output. Since the default themes are not
-# optimized for small screen space, using the same theme for HTML and epub
-# output is usually not wise. This defaults to 'epub', a theme designed to save
-# visual space.
-# epub_theme = 'epub'
+ print('Looking for {0} in {1}'.format(nb_name, nb_rst_file_name))
+ with open(nb_rst_file_name, 'r') as nb_rst_file:
+ check_name = nb_name not in nb_rst_file.read()
-# The language of the text. It defaults to the language option
-# or 'en' if the language is not set.
-# epub_language = ''
+ if check_name:
+ print('Adding {0} to {1}'.format(nb_name, nb_rst_file_name))
+ with open(nb_rst_file_name, 'a') as nb_rst_file:
+ if list_pos == 0:
+ nb_rst_file.write('\n')
+ nb_rst_file.write(' {0}\n'.format(nb_name))
-# The scheme of the identifier. Typical schemes are ISBN or URL.
-# epub_scheme = ''
+ return nbs
-# The unique identifier of the text. This can be a ISBN number
-# or the project homepage.
-# epub_identifier = ''
-# A unique identification for the text.
-# epub_uid = ''
+# Add notebooks
+add_notebooks()
-# A tuple containing the cover image and cover page html template filenames.
-# epub_cover = ()
+binder = 'https://mybinder.org/v2/gh'
+binder_badge = 'https://mybinder.org/badge_logo.svg'
+github = 'https://github.com/'
+github_badge = 'https://badgen.net/badge/icon/github?icon=github&label'
-# A sequence of (type, uri, title) tuples for the guide element of content.opf.
-# epub_guide = ()
+# Remove promts and add binder badge
+nb_header_pt1 = r'''
+{% if env.metadata[env.docname]['nbsphinx-link-target'] %}
+{% set docpath = env.metadata[env.docname]['nbsphinx-link-target'] %}
+{% else %}
+{% set docpath = env.doc2path(env.docname, base='docs/source/') %}
+{% endif %}
-# HTML files that should be inserted before the pages created by sphinx.
-# The format is a list of tuples containing the path and title.
-# epub_pre_files = []
+.. raw:: html
-# HTML files that should be inserted after the pages created by sphinx.
-# The format is a list of tuples containing the path and title.
-# epub_post_files = []
+
-# A list of files that should not be packed into the epub file.
-epub_exclude_files = ['search.html']
+'''
+nb_header_pt2 = (
+ r''' '''
+ r'''
'''
+)
-# The depth of the table of contents in toc.ncx.
-# epub_tocdepth = 3
+nbsphinx_prolog = nb_header_pt1 + nb_header_pt2
-# Allow duplicate toc entries.
-# epub_tocdup = True
+# -- Intersphinx Mapping ----------------------------------------------
-# Choose between 'default' and 'includehidden'.
-# epub_tocscope = 'default'
-
-# Fix unsupported image types using the Pillow.
-# epub_fix_images = False
-
-# Scale large images.
-# epub_max_image_width = 0
-
-# How to display URL addresses: 'footnote', 'no', or 'inline'.
-# epub_show_urls = 'inline'
-
-# If false, no index is generated.
-# epub_use_index = True
-
-
-# Example configuration for intersphinx: refer to the Python standard library.
-# intersphinx_mapping = {'https://docs.python.org/': None}
+# Refer to the package libraries for type definitions
intersphinx_mapping = {
- 'python': ('https://docs.python.org/3/', None),
- 'numpy': ('https://docs.scipy.org/doc/numpy', None),
- 'scipy': ('http://docs.scipy.org/doc/scipy/reference/', None),
- 'matplotlib': ('http://matplotlib.sourceforge.net/', None),
- 'astropy': ('http://docs.astropy.org/en/latest/', None)
+ 'python': ('http://docs.python.org/3', None),
+ 'numpy': ('https://numpy.org/doc/stable/', None),
+ 'scipy': ('https://docs.scipy.org/doc/scipy/reference', None),
+ 'matplotlib': ('https://matplotlib.org', None),
+ 'astropy': ('http://docs.astropy.org/en/latest/', None),
+ 'cupy': ('https://docs-cupy.chainer.org/en/stable/', None),
+ 'torch': ('https://pytorch.org/docs/stable/', None),
}
+
+# -- BibTeX Setting ----------------------------------------------
+
+bibtex_bibfiles = ['refs.bib', 'my_ref.bib']
diff --git a/docs/source/contributing.rst b/docs/source/contributing.rst
new file mode 100644
index 00000000..f983d030
--- /dev/null
+++ b/docs/source/contributing.rst
@@ -0,0 +1,9 @@
+Contributing
+============
+
+Read our `Contribution Guidelines `_
+for details on how to contribute to the development of this package.
+
+All contributors are kindly asked to adhere to the
+`Code of Conduct `_
+at all times to ensure a safe and inclusive environment for everyone.
diff --git a/docs/source/cosmostat_logo.jpg b/docs/source/cosmostat_logo.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..4945c4684b87ba27a90190c52fa95dbeede8cd9c
GIT binary patch
literal 169466
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 |