Repository: ComPWA/tensorwaves (language: python)

Issue:
build!: define dev deps through requirements.txt
Related to https://github.com/ComPWA/PWA-pages/issues/54


Discussion / hints:
# [Codecov](https://codecov.io/gh/ComPWA/tensorwaves/pull/179?src=pr&el=h1) Report
> Merging [#179](https://codecov.io/gh/ComPWA/tensorwaves/pull/179?src=pr&el=desc) (64c1e80) into [master](https://codecov.io/gh/ComPWA/tensorwaves/commit/b1883ccf5763247fbb49653b6963f9590350484f?el=desc) (b1883cc) will **not change** coverage.
> The diff coverage is `n/a`.

[![Impacted file tree graph](https://codecov.io/gh/ComPWA/tensorwaves/pull/179/graphs/tree.svg?width=650&height=150&src=pr&token=WONFVU9I7F)](https://codecov.io/gh/ComPWA/tensorwaves/pull/179?src=pr&el=tree)

```diff
@@           Coverage Diff           @@
##           master     #179   +/-   ##
=======================================
  Coverage   76.17%   76.17%           
=======================================
  Files          12       12           
  Lines         596      596           
  Branches       84       84           
=======================================
  Hits          454      454           
  Misses        107      107           
  Partials       35       35           
```

| Flag | Coverage Δ | |
|---|---|---|
| unittests | `76.17% <ø> (ø)` | |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags#carryforward-flags-in-the-pull-request-comment) to find out more.


Changes that were implemented by https://github.com/ComPWA/expertsystem/pull/412 and https://github.com/ComPWA/expertsystem/pull/413 should be implemented here. But let's first see whether everything works well in the `expertsystsem`.

Fix patch:
diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml
index 237b4700..b0864a5f 100644
--- a/.github/workflows/cd.yml
+++ b/.github/workflows/cd.yml
@@ -1,4 +1,4 @@
-# cspell:ignore bdist noreply prereleased pypa sdist
+# cspell:ignore bdist noreply prereleased sdist
 
 name: CD
 
@@ -9,90 +9,10 @@ on:
       - released
 
 jobs:
-  test:
-    name: Run pytest
-    if: startsWith(github.ref, 'refs/tags')
-    runs-on: ${{ matrix.os }}
-    strategy:
-      matrix:
-        os:
-          - macos-10.15
-          - ubuntu-18.04
-        python-version: [3.6, 3.7, 3.8]
-        exclude:
-          - os: macos-10.15
-            python-version: 3.6
-          - os: macos-10.15
-            python-version: 3.8
-    steps:
-      - uses: actions/checkout@v2
-      - name: Set up Python ${{ matrix.python-version }}
-        uses: actions/setup-python@v2
-        with:
-          python-version: ${{ matrix.python-version }}
-      - name: Install dependencies
-        run: |
-          python -m pip install --upgrade pip
-          pip install .[test]
-      - name: Test with pytest
-        env:
-          PYTEST_RUN_SLOW_TESTS: YES
-        run: pytest -n auto
-
-  documentation:
-    name: Build documentation and run notebooks
-    if: startsWith(github.ref, 'refs/tags')
-    runs-on: ubuntu-18.04
-    steps:
-      - uses: actions/checkout@v2
-      - name: Set up Python 3.7
-        uses: actions/setup-python@v2
-        with:
-          python-version: 3.7
-      - name: Install dependencies
-        run: |
-          python -m pip install --upgrade pip
-          pip install .[doc]
-          sudo apt-get -y install pandoc graphviz
-      - name: Build documentation and run notebooks
-        working-directory: docs
-        env:
-          EXECUTE_NB: YES
-        run: make html
-      - name: Test doctests in docstrings
-        working-directory: docs
-        run: make ignore-warnings=1 doctest
-
-  style:
-    name: Style checks
-    if: startsWith(github.ref, 'refs/tags')
-    runs-on: ubuntu-18.04
-    steps:
-      - uses: actions/checkout@v2
-      - name: Set up Python 3.7
-        uses: actions/setup-python@v2
-        with:
-          python-version: 3.7
-      - name: Install dependencies
-        run: |
-          python -m pip install --upgrade pip
-          pip install .[precommit]
-          sudo npm install -g cspell pyright
-      - name: Perform style checks
-        run: pre-commit run -a
-      - name: Check spelling
-        run: cspell $(git ls-files)
-      - name: Run pyright
-        run: pyright
-
   push:
     name: Push to stable branch
     if: startsWith(github.ref, 'refs/tags')
-    runs-on: ubuntu-18.04
-    needs:
-      - documentation
-      - style
-      - test
+    runs-on: ubuntu-20.04
     steps:
       - uses: actions/checkout@master
       - name: Push to stable branch
@@ -105,7 +25,7 @@ jobs:
     name: Publish to PyPI
     if: startsWith(github.ref, 'refs/tags')
     needs: push
-    runs-on: ubuntu-latest
+    runs-on: ubuntu-20.04
     steps:
       - uses: actions/checkout@v2
       - name: Set up Python
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 1a19012a..5c599325 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,4 +1,4 @@
-# cspell:ignore unittests, CUDA
+# cspell:ignore CUDA unittests
 
 name: CI
 
@@ -20,7 +20,7 @@ jobs:
     runs-on: ${{ matrix.os }}
     strategy:
       matrix:
-        os: [ubuntu-18.04]
+        os: [ubuntu-20.04]
         python-version: [3.7]
     steps:
       - uses: actions/checkout@master
@@ -31,7 +31,8 @@ jobs:
       - name: Install dependencies
         run: |
           python -m pip install --upgrade pip
-          pip install .[test]
+          pip install -r reqs/${{ matrix.python-version }}/requirements-test.txt
+          pip install .
       - name: Test with pytest-cov
         env:
           CUDA_VISIBLE_DEVICES: "-1"
@@ -49,14 +50,14 @@ jobs:
       matrix:
         os:
           - macos-10.15
-          - ubuntu-18.04
+          - ubuntu-20.04
         python-version: [3.6, 3.7, 3.8]
         exclude:
           - os: macos-10.15
             python-version: 3.6
           - os: macos-10.15
             python-version: 3.8
-          - os: ubuntu-18.04 # coverage job
+          - os: ubuntu-20.04 # coverage job
             python-version: 3.7
     steps:
       - uses: actions/checkout@v2
@@ -67,7 +68,8 @@ jobs:
       - name: Install dependencies
         run: |
           python -m pip install --upgrade pip
-          pip install .[test]
+          pip install -r reqs/${{ matrix.python-version }}/requirements-test.txt
+          pip install .
       - name: Test with pytest
         env:
           CUDA_VISIBLE_DEVICES: "-1"
@@ -79,7 +81,7 @@ jobs:
   documentation:
     name: Build documentation and run notebooks
     if: github.event.pull_request.draft == false
-    runs-on: ubuntu-18.04
+    runs-on: ubuntu-20.04
     steps:
       - uses: actions/checkout@v2
       - name: Set up Python 3.7
@@ -89,8 +91,9 @@ jobs:
       - name: Install dependencies
         run: |
           python -m pip install --upgrade pip
-          pip install .[doc]
+          pip install -r reqs/3.7/requirements-doc.txt
           pip install tensorflow-cpu
+          pip install .
           sudo apt-get -y install pandoc graphviz
       - name: Build documentation and run notebooks
         working-directory: docs
@@ -98,6 +101,11 @@ jobs:
           CUDA_VISIBLE_DEVICES: "-1"
           EXECUTE_NB: YES
         run: make html
+      - uses: actions/upload-artifact@v2
+        if: ${{ failure() }}
+        with:
+          name: html
+          path: docs/_build/html
       - name: Test doctests in docstrings
         working-directory: docs
         run: make ignore-warnings=1 doctest
@@ -105,7 +113,7 @@ jobs:
   style:
     name: Style checks
     if: github.event.pull_request.draft == false
-    runs-on: ubuntu-18.04
+    runs-on: ubuntu-20.04
     steps:
       - uses: actions/checkout@v2
       - name: Set up Python 3.7
@@ -115,11 +123,12 @@ jobs:
       - name: Install dependencies
         run: |
           python -m pip install --upgrade pip
-          pip install .[precommit]
+          pip install -r reqs/3.7/requirements-sty.txt
+          pip install .
           sudo npm install -g cspell pyright
       - name: Perform style checks
         run: pre-commit run -a
       - name: Check spelling
-        run: cspell $(git ls-files)
+        run: cspell --no-progress $(git ls-files)
       - name: Run pyright
         run: pyright
diff --git a/.github/workflows/linkcheck.yml b/.github/workflows/linkcheck.yml
index ebc41369..6022f494 100644
--- a/.github/workflows/linkcheck.yml
+++ b/.github/workflows/linkcheck.yml
@@ -1,3 +1,5 @@
+# cspell:ignore reqs
+
 name: Linkcheck
 
 on:
@@ -15,7 +17,7 @@ jobs:
   check_links:
     name: Check external links
     if: github.event.pull_request.draft == false
-    runs-on: ubuntu-18.04
+    runs-on: ubuntu-20.04
     steps:
       - uses: actions/checkout@v2
       - name: Set up Python 3.7
@@ -25,7 +27,8 @@ jobs:
       - name: Install dependencies
         run: |
           python -m pip install --upgrade pip
-          pip install .[doc]
+          pip install -r reqs/3.7/requirements-doc.txt
+          pip install .
           sudo apt-get -y install pandoc
       - name: Check external links
         working-directory: docs
diff --git a/.github/workflows/pr-linting.yml b/.github/workflows/pr-linting.yml
index 8ede36e6..b1a7d1c8 100644
--- a/.github/workflows/pr-linting.yml
+++ b/.github/workflows/pr-linting.yml
@@ -14,7 +14,7 @@ on:
 jobs:
   check-labels:
     name: Check labels
-    runs-on: ubuntu-latest
+    runs-on: ubuntu-20.04
     steps:
       - uses: docker://agilepathway/pull-request-label-checker:latest
         with:
@@ -24,7 +24,7 @@ jobs:
 
   check-title:
     name: Check title
-    runs-on: ubuntu-latest
+    runs-on: ubuntu-20.04
     steps:
       - uses: actions/checkout@v1
       - name: Install Dependencies
diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml
index 17fdb961..a3373592 100644
--- a/.github/workflows/release-drafter.yml
+++ b/.github/workflows/release-drafter.yml
@@ -7,7 +7,7 @@ on:
 
 jobs:
   update_release_draft:
-    runs-on: ubuntu-latest
+    runs-on: ubuntu-20.04
     steps:
       - uses: release-drafter/release-drafter@v5
         env:
diff --git a/.github/workflows/requirements-cron.yml b/.github/workflows/requirements-cron.yml
new file mode 100644
index 00000000..2a060fb3
--- /dev/null
+++ b/.github/workflows/requirements-cron.yml
@@ -0,0 +1,68 @@
+# cspell:ignore noreply
+
+name: Requirements (scheduled)
+
+on:
+  schedule:
+    - cron: "0 2 * * 1"
+
+jobs:
+  upgrade:
+    name: Upgrade requirement files
+    runs-on: ubuntu-20.04
+    strategy:
+      matrix:
+        python-version:
+          - 3.6
+          - 3.7
+          - 3.8
+    steps:
+      - uses: actions/checkout@v2
+      - name: Set up Python ${{ matrix.python-version }}
+        uses: actions/setup-python@master
+        with:
+          python-version: ${{ matrix.python-version }}
+      - name: Install dependencies
+        run: |
+          python -m pip install --upgrade pip
+          pip install pip-tools
+      - name: Upgrade dependencies
+        run: bash reqs/upgrade.sh
+      - uses: actions/upload-artifact@v2
+        with:
+          name: ${{ matrix.python-version }}
+          path: reqs/${{ matrix.python-version }}
+
+  push:
+    name: Create PR
+    runs-on: ubuntu-20.04
+    needs:
+      - upgrade
+    steps:
+      - uses: actions/checkout@v2
+        with:
+          token: ${{ secrets.PAT }}
+      - uses: actions/download-artifact@v2
+        with:
+          path: reqs
+      - run: git status -s
+      - name: Create Pull Request
+        uses: peter-evans/create-pull-request@v3
+        with:
+          commit-message: "ci: upgrade developer dependencies"
+          committer: GitHub <noreply@github.com>
+          author:
+            ${{ github.actor }} <${{ github.actor }}@users.noreply.github.com>
+          title: "ci: upgrade developer dependencies"
+          assignees: ${{ github.actor }}
+          reviewers: ${{ github.actor }}
+          labels: |
+            🖱️ DX
+            🔨 Maintenance
+          branch-suffix: timestamp
+          delete-branch: true
+          token: ${{ secrets.PAT }}
+      - name: Print PR info
+        run: |
+          echo "Pull Request Number - ${{ steps.cpr.outputs.pull-request-number }}"
+          echo "Pull Request URL - ${{ steps.cpr.outputs.pull-request-url }}"
diff --git a/.github/workflows/requirements-pr.yml b/.github/workflows/requirements-pr.yml
new file mode 100644
index 00000000..41c090a6
--- /dev/null
+++ b/.github/workflows/requirements-pr.yml
@@ -0,0 +1,89 @@
+# cspell:ignore noreply
+
+name: Requirements (PR)
+
+on:
+  pull_request:
+    branches: [master]
+    types:
+      - opened
+      - synchronize
+      - reopened
+      - ready_for_review
+
+jobs:
+  upgrade:
+    name: Upgrade requirement files
+    if: github.event.pull_request.draft == false
+    runs-on: ubuntu-20.04
+    strategy:
+      matrix:
+        python-version:
+          - 3.6
+          - 3.7
+          - 3.8
+    steps:
+      - uses: actions/checkout@v2
+      - run: git fetch origin
+      - name: Check for modified dependencies
+        id: git-diff
+        run:
+          echo "::set-output name=dependency-changes::$(git diff
+          origin/$GITHUB_BASE_REF --name-only -- reqs setup.cfg)"
+        # Also triggers on (unwanted) changes to requirements.txt files
+      - name: Show dependency changes changes
+        run:
+          git diff origin/$GITHUB_BASE_REF -- reqs/requirements*.in setup.cfg
+      - name: Abort if fork PR and dependency changes
+        if:
+          github.event.pull_request.head.repo.full_name != github.repository &&
+          steps.git-diff.outputs.dependency-changes != ''
+        run: |
+          echo "::error::Cannot modify package dependencies through a PR from a fork"
+          exit 1
+      - name: Set up Python ${{ matrix.python-version }}
+        if: steps.git-diff.outputs.dependency-changes != ''
+        uses: actions/setup-python@master
+        with:
+          python-version: ${{ matrix.python-version }}
+      - name: Install dependencies
+        if: steps.git-diff.outputs.dependency-changes != ''
+        run: |
+          python -m pip install --upgrade pip
+          pip install pip-tools
+      - name: Upgrade dependencies
+        if: steps.git-diff.outputs.dependency-changes != ''
+        run: bash reqs/upgrade.sh
+      - uses: actions/upload-artifact@v2
+        with:
+          name: ${{ matrix.python-version }}
+          path: reqs/${{ matrix.python-version }}
+
+  push:
+    name: Push changes
+    if: github.event.pull_request.draft == false
+    runs-on: ubuntu-20.04
+    needs:
+      - upgrade
+    steps:
+      - uses: actions/checkout@v2
+        with:
+          token: ${{ secrets.PAT }}
+      - uses: actions/download-artifact@v2
+        with:
+          path: reqs
+      - run: git status -s
+      - name: Commit and push changes
+        run: |
+          git remote set-url origin https://x-access-token:${{ secrets.PAT }}@github.com/${{ github.repository }}
+          git config --global user.name ${{ github.actor }}
+          git config --global user.email "${{ github.actor }}@users.noreply.github.com"
+          git checkout -b ${GITHUB_HEAD_REF}
+          FILES_TO_COMMIT="reqs/*/requirements*.txt"
+          if [[ $(git diff -- ${FILES_TO_COMMIT}) ]]; then
+            git add ${FILES_TO_COMMIT}
+            git commit -m "ci: upgrade developer dependencies (automatic)"
+            git config pull.rebase true
+            git pull origin ${GITHUB_HEAD_REF}
+            git push origin HEAD:${GITHUB_HEAD_REF}
+          fi
diff --git a/.gitpod.yml b/.gitpod.yml
index 8d64240c..8a5d12f3 100644
--- a/.gitpod.yml
+++ b/.gitpod.yml
@@ -1,5 +1,5 @@
 tasks:
-  - init: pip install -e .[dev]
+  - init: pip install -r reqs/3.8/requirements-dev.txt -e .
 
 github:
   prebuilds:
diff --git a/.readthedocs.yml b/.readthedocs.yml
index 684468e8..88f0b24f 100644
--- a/.readthedocs.yml
+++ b/.readthedocs.yml
@@ -9,7 +9,8 @@ formats:
   - htmlzip
 
 python:
-  version: 3.7
+  version: 3.8
   install:
+    - requirements: reqs/3.8/requirements-doc.txt
     - method: pip
-      path: .[doc]
+      path: .
diff --git a/.vscode/settings.json b/.vscode/settings.json
index e0db188a..f9ce291f 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -60,6 +60,7 @@
   "search.exclude": {
     "**/tests/**/__init__.py": true,
     "docs/tox.ini": true,
+    "reqs/3.*/*.txt": true,
     "tests/tox.ini": true
   },
   "telemetry.enableCrashReporter": false,
diff --git a/cspell.json b/cspell.json
index cab82d7c..ab833501 100644
--- a/cspell.json
+++ b/cspell.json
@@ -36,6 +36,8 @@
         "docs/conf.py",
         "pyproject.toml",
         "pyrightconfig.json",
+        "reqs/**/*.in",
+        "reqs/**/*.txt",
         "setup.cfg",
         "setup.py",
         "tox.ini"
@@ -69,6 +71,7 @@
         "jupyter",
         "mathbb",
         "matplotlib",
+        "mkdir",
         "mypy",
         "nishijima",
         "numpy",
@@ -80,6 +83,7 @@
         "pylint",
         "pytest",
         "redeboer",
+        "reqs",
         "setuptools",
         "spflueger",
         "struct",
diff --git a/docs/install.md b/docs/install.md
index 557bb10b..2ee5b01a 100644
--- a/docs/install.md
+++ b/docs/install.md
@@ -32,12 +32,14 @@ This goes as follows:
    {ref}`here <pwa:develop:Virtual environment>`).
 
 3. Install the project in
-   {ref}`'editable installation' <pwa:develop:Editable installation>` with
-   {ref}`additional dependencies <pwa:develop:Additional dependencies>` for the
-   developer:
+   {ref}`'editable installation' <pwa:develop:Editable installation>`, as well
+   as {ref}`additional dependencies <pwa:develop:Additional dependencies>` for
+   the developer:
 
    ```shell
-   python3 -m pip install -e .[dev]
+   # pin dependencies first!
+   python3 -m pip install -r reqs/PYTHON_VERSION/requirements-dev.txt
+   python3 -m pip install -e .
    ```
 
 That's all! Have a look at the {doc}`/usage` page to try out the package, and
diff --git a/environment.yml b/environment.yml
index c12bbd99..6e36ba1e 100644
--- a/environment.yml
+++ b/environment.yml
@@ -2,8 +2,9 @@ name: tw
 channels:
   - defaults
 dependencies:
-  - python>=3.6,<3.9
+  - python==3.8.*
   - pip>=19
   - graphviz # for binder
   - pip:
-      - -e .[doc]
+      - -r reqs/3.8/requirements-dev.txt
+      - -e .
diff --git a/reqs/.gitignore b/reqs/.gitignore
new file mode 100644
index 00000000..8d0647e4
--- /dev/null
+++ b/reqs/.gitignore
@@ -0,0 +1,2 @@
+requirements.in
+*/requirements*.in
diff --git a/reqs/3.6/requirements-dev.txt b/reqs/3.6/requirements-dev.txt
new file mode 100644
index 00000000..b67533dc
--- /dev/null
+++ b/reqs/3.6/requirements-dev.txt
@@ -0,0 +1,222 @@
+#
+# This file is autogenerated by pip-compile
+# To update, run:
+#
+#    pip-compile --no-annotate --output-file=reqs/3.6/requirements-dev.txt reqs/requirements-dev.in reqs/requirements-doc.in reqs/requirements-sty.in reqs/requirements-test.in reqs/requirements.in
+#
+absl-py==0.11.0
+alabaster==0.7.12
+amplitf==0.0.1a2
+anyio==2.0.2
+apipkg==1.5
+appdirs==1.4.4
+argon2-cffi==20.1.0
+astroid==2.4.2
+astunparse==1.6.3
+async-generator==1.10
+attrs==20.3.0
+babel==2.9.0
+backcall==0.2.0
+beautifulsoup4==4.9.3
+black==20.8b1
+bleach==3.2.1
+cachetools==4.2.0
+certifi==2020.12.5
+cffi==1.14.4
+cfgv==3.2.0
+chardet==4.0.0
+click==7.1.2
+cloudpickle==1.6.0
+colorama==0.4.4
+contextvars==2.4
+coverage==5.3.1
+cycler==0.10.0
+dataclasses==0.8
+decorator==4.4.2
+defusedxml==0.6.0
+distlib==0.3.1
+dm-tree==0.1.5
+doc8==0.8.1
+docutils==0.16
+entrypoints==0.3
+execnet==1.7.1
+expertsystem==0.6.5
+filelock==3.0.12
+flake8-blind-except==0.1.1
+flake8-bugbear==20.11.1
+flake8-builtins==1.5.3
+flake8-polyfill==1.0.2
+flake8-rst-docstrings==0.0.14
+flake8==3.8.4
+flatbuffers==1.12
+fuzzywuzzy==0.18.0
+gast==0.3.3
+gitdb==4.0.5
+gitpython==3.1.11
+google-auth-oauthlib==0.4.2
+google-auth==1.24.0
+google-pasta==0.2.0
+gprof2dot==2019.11.30
+graphviz==0.16
+grpcio==1.32.0
+h5py==2.10.0
+hepunits==2.0.1
+identify==1.5.11
+idna==2.10
+imagesize==1.2.0
+iminuit==1.5.4
+immutables==0.14
+importlib-metadata==2.1.1
+importlib-resources==3.0.0
+iniconfig==1.1.1
+ipykernel==5.4.2
+ipython-genutils==0.2.0
+ipython==7.16.1
+ipywidgets==7.6.2
+isort==5.7.0
+jedi==0.18.0
+jinja2==2.11.2
+json5==0.9.5
+jsonschema==3.2.0
+jupyter-cache==0.4.1
+jupyter-client==6.1.7
+jupyter-console==6.2.0
+jupyter-core==4.7.0
+jupyter-server==1.1.3
+jupyter-sphinx==0.3.2
+jupyter==1.0.0
+jupyterlab-code-formatter==1.4.1
+jupyterlab-server==2.0.0
+jupyterlab-widgets==1.0.0
+jupyterlab==3.0.0
+keras-preprocessing==1.1.2
+kiwisolver==1.3.1
+labels==20.1.0
+lazy-object-proxy==1.4.3
+markdown-it-py==0.5.8
+markdown==3.3.3
+markupsafe==1.1.1
+matplotlib==3.3.3
+mccabe==0.6.1
+mistune==0.8.4
+mpmath==1.1.0
+mypy-extensions==0.4.3
+mypy==0.790
+myst-nb==0.10.1
+myst-parser==0.12.10
+nbclassic==0.2.5
+nbclient==0.5.1
+nbconvert==5.6.1
+nbdime==2.1.0
+nbformat==5.0.8
+nbstripout==0.3.9
+nest-asyncio==1.4.3
+nodeenv==1.5.0
+notebook==6.1.6
+numpy==1.19.4
+oauthlib==3.1.0
+opt-einsum==3.3.0
+packaging==20.8
+pandas==1.1.5
+pandocfilters==1.4.3
+parso==0.8.1
+particle==0.14.0
+pathspec==0.8.1
+pbr==5.5.1
+pep8-naming==0.11.1
+pexpect==4.8.0
+phasespace==1.2.0
+pickleshare==0.7.5
+pillow==8.1.0
+pip-tools==5.5.0
+pluggy==0.13.1
+pre-commit==2.9.3
+prometheus-client==0.9.0
+prompt-toolkit==3.0.8
+protobuf==3.14.0
+ptyprocess==0.7.0
+py==1.10.0
+pyasn1-modules==0.2.8
+pyasn1==0.4.8
+pycodestyle==2.6.0
+pycparser==2.20
+pydata-sphinx-theme==0.4.1
+pydeps==1.9.13
+pydocstyle==5.1.1
+pydot==1.4.1
+pyflakes==2.2.0
+pygments==2.7.3
+pylint==2.6.0
+pyparsing==2.4.7
+pyrsistent==0.17.3
+pytest-cov==2.10.1
+pytest-forked==1.3.0
+pytest-profiling==1.7.0
+pytest-xdist==2.2.0
+pytest==6.2.1
+python-constraint==1.4.0
+python-dateutil==2.8.1
+pytoml==0.1.21
+pytz==2020.5
+pyyaml==5.3.1
+pyzmq==20.0.0
+qtconsole==5.0.1
+qtpy==1.9.0
+regex==2020.11.13
+requests-oauthlib==1.3.0
+requests==2.25.1
+restructuredtext-lint==1.3.2
+rsa==4.6
+rstcheck==3.3.1
+send2trash==1.5.0
+six==1.15.0
+smmap==3.0.4
+sniffio==1.2.0
+snowballstemmer==2.0.0
+soupsieve==2.1
+sphinx-book-theme==0.0.39
+sphinx-copybutton==0.3.1
+sphinx-panels==0.5.2
+sphinx-thebe==0.0.8
+sphinx-togglebutton==0.2.3
+sphinx==3.4.1
+sphinxcontrib-applehelp==1.0.2
+sphinxcontrib-devhelp==1.0.2
+sphinxcontrib-htmlhelp==1.0.3
+sphinxcontrib-jsmath==1.0.1
+sphinxcontrib-qthelp==1.0.3
+sphinxcontrib-serializinghtml==1.1.4
+sphobjinv==2.0.1
+sqlalchemy==1.3.22
+stdlib-list==0.8.0
+stevedore==3.3.0
+sympy==1.7.1
+tensorboard-plugin-wit==1.7.0
+tensorboard==2.4.0
+tensorflow-estimator==2.4.0
+tensorflow-probability==0.12.1
+tensorflow==2.4.0
+termcolor==1.1.0
+terminado==0.9.1
+testpath==0.4.4
+toml==0.10.2
+tornado==6.1
+tox==3.20.1
+tqdm==4.55.1
+traitlets==4.3.3
+typed-ast==1.4.2
+typing-extensions==3.7.4.3
+urllib3==1.26.2
+virtualenv==20.2.2
+wcwidth==0.2.5
+webencodings==0.5.1
+werkzeug==1.0.1
+wheel==0.36.2
+widgetsnbextension==3.5.1
+wrapt==1.12.1
+xmltodict==0.12.0
+zipp==3.4.0
+
+# The following packages are considered to be unsafe in a requirements file:
+# pip
+# setuptools
diff --git a/reqs/3.6/requirements-doc.txt b/reqs/3.6/requirements-doc.txt
new file mode 100644
index 00000000..5241e6de
--- /dev/null
+++ b/reqs/3.6/requirements-doc.txt
@@ -0,0 +1,157 @@
+#
+# This file is autogenerated by pip-compile
+# To update, run:
+#
+#    pip-compile --no-annotate --output-file=reqs/3.6/requirements-doc.txt reqs/3.6/requirements-doc.in
+#
+absl-py==0.11.0
+alabaster==0.7.12
+amplitf==0.0.1a2
+argon2-cffi==20.1.0
+astunparse==1.6.3
+async-generator==1.10
+attrs==20.3.0
+babel==2.9.0
+backcall==0.2.0
+beautifulsoup4==4.9.3
+bleach==3.2.1
+cachetools==4.2.0
+certifi==2020.12.5
+cffi==1.14.4
+chardet==4.0.0
+click==7.1.2
+cloudpickle==1.6.0
+colorama==0.4.4
+cycler==0.10.0
+decorator==4.4.2
+defusedxml==0.6.0
+dm-tree==0.1.5
+docutils==0.16
+entrypoints==0.3
+expertsystem==0.6.5
+flatbuffers==1.12
+fuzzywuzzy==0.18.0
+gast==0.3.3
+gitdb==4.0.5
+gitpython==3.1.11
+google-auth-oauthlib==0.4.2
+google-auth==1.24.0
+google-pasta==0.2.0
+graphviz==0.16
+grpcio==1.32.0
+h5py==2.10.0
+hepunits==2.0.1
+idna==2.10
+imagesize==1.2.0
+iminuit==1.5.4
+importlib-metadata==2.1.1
+importlib-resources==3.0.0
+ipykernel==5.4.2
+ipython-genutils==0.2.0
+ipython==7.16.1
+ipywidgets==7.6.2
+jedi==0.18.0
+jinja2==2.11.2
+jsonschema==3.2.0
+jupyter-cache==0.4.1
+jupyter-client==6.1.7
+jupyter-console==6.2.0
+jupyter-core==4.7.0
+jupyter-sphinx==0.3.2
+jupyter==1.0.0
+jupyterlab-widgets==1.0.0
+keras-preprocessing==1.1.2
+kiwisolver==1.3.1
+markdown-it-py==0.5.8
+markdown==3.3.3
+markupsafe==1.1.1
+matplotlib==3.3.3
+mistune==0.8.4
+mpmath==1.1.0
+myst-nb==0.10.1
+myst-parser==0.12.10
+nbclient==0.5.1
+nbconvert==5.6.1
+nbdime==2.1.0
+nbformat==5.0.8
+nest-asyncio==1.4.3
+notebook==6.1.6
+numpy==1.19.4
+oauthlib==3.1.0
+opt-einsum==3.3.0
+packaging==20.8
+pandas==1.1.5
+pandocfilters==1.4.3
+parso==0.8.1
+particle==0.14.0
+pexpect==4.8.0
+phasespace==1.2.0
+pickleshare==0.7.5
+pillow==8.1.0
+prometheus-client==0.9.0
+prompt-toolkit==3.0.8
+protobuf==3.14.0
+ptyprocess==0.7.0
+pyasn1-modules==0.2.8
+pyasn1==0.4.8
+pycparser==2.20
+pydata-sphinx-theme==0.4.1
+pydeps==1.9.13
+pygments==2.7.3
+pyparsing==2.4.7
+pyrsistent==0.17.3
+python-constraint==1.4.0
+python-dateutil==2.8.1
+pytz==2020.5
+pyyaml==5.3.1
+pyzmq==20.0.0
+qtconsole==5.0.1
+qtpy==1.9.0
+requests-oauthlib==1.3.0
+requests==2.25.1
+rsa==4.6
+send2trash==1.5.0
+six==1.15.0
+smmap==3.0.4
+snowballstemmer==2.0.0
+soupsieve==2.1
+sphinx-book-theme==0.0.39
+sphinx-copybutton==0.3.1
+sphinx-panels==0.5.2
+sphinx-thebe==0.0.8
+sphinx-togglebutton==0.2.3
+sphinx==3.4.1
+sphinxcontrib-applehelp==1.0.2
+sphinxcontrib-devhelp==1.0.2
+sphinxcontrib-htmlhelp==1.0.3
+sphinxcontrib-jsmath==1.0.1
+sphinxcontrib-qthelp==1.0.3
+sphinxcontrib-serializinghtml==1.1.4
+sphobjinv==2.0.1
+sqlalchemy==1.3.22
+stdlib-list==0.8.0
+sympy==1.7.1
+tensorboard-plugin-wit==1.7.0
+tensorboard==2.4.0
+tensorflow-estimator==2.4.0
+tensorflow-probability==0.12.1
+tensorflow==2.4.0
+termcolor==1.1.0
+terminado==0.9.1
+testpath==0.4.4
+tornado==6.1
+tqdm==4.55.1
+traitlets==4.3.3
+typing-extensions==3.7.4.3
+urllib3==1.26.2
+wcwidth==0.2.5
+webencodings==0.5.1
+werkzeug==1.0.1
+wheel==0.36.2
+widgetsnbextension==3.5.1
+wrapt==1.12.1
+xmltodict==0.12.0
+zipp==3.4.0
+
+# The following packages are considered to be unsafe in a requirements file:
+# setuptools
diff --git a/reqs/3.6/requirements-sty.txt b/reqs/3.6/requirements-sty.txt
new file mode 100644
index 00000000..a3b74836
--- /dev/null
+++ b/reqs/3.6/requirements-sty.txt
@@ -0,0 +1,129 @@
+#
+# This file is autogenerated by pip-compile
+# To update, run:
+#
+#    pip-compile --no-annotate --output-file=reqs/3.6/requirements-sty.txt reqs/3.6/requirements-sty.in
+#
+absl-py==0.11.0
+amplitf==0.0.1a2
+apipkg==1.5
+appdirs==1.4.4
+astroid==2.4.2
+astunparse==1.6.3
+attrs==20.3.0
+black==20.8b1
+cachetools==4.2.0
+certifi==2020.12.5
+cfgv==3.2.0
+chardet==4.0.0
+click==7.1.2
+cloudpickle==1.6.0
+coverage==5.3.1
+dataclasses==0.8
+decorator==4.4.2
+distlib==0.3.1
+dm-tree==0.1.5
+doc8==0.8.1
+docutils==0.16
+execnet==1.7.1
+expertsystem==0.6.5
+filelock==3.0.12
+flake8-blind-except==0.1.1
+flake8-bugbear==20.11.1
+flake8-builtins==1.5.3
+flake8-polyfill==1.0.2
+flake8-rst-docstrings==0.0.14
+flake8==3.8.4
+flatbuffers==1.12
+gast==0.3.3
+google-auth-oauthlib==0.4.2
+google-auth==1.24.0
+google-pasta==0.2.0
+gprof2dot==2019.11.30
+grpcio==1.32.0
+h5py==2.10.0
+hepunits==2.0.1
+identify==1.5.11
+idna==2.10
+iminuit==1.5.4
+importlib-metadata==2.1.1
+importlib-resources==3.0.0
+iniconfig==1.1.1
+ipython-genutils==0.2.0
+isort==5.7.0
+jsonschema==3.2.0
+jupyter-core==4.7.0
+keras-preprocessing==1.1.2
+lazy-object-proxy==1.4.3
+markdown==3.3.3
+mccabe==0.6.1
+mpmath==1.1.0
+mypy-extensions==0.4.3
+mypy==0.790
+nbformat==5.0.8
+nbstripout==0.3.9
+nodeenv==1.5.0
+numpy==1.19.4
+oauthlib==3.1.0
+opt-einsum==3.3.0
+packaging==20.8
+pandas==1.1.5
+particle==0.14.0
+pathspec==0.8.1
+pbr==5.5.1
+pep8-naming==0.11.1
+phasespace==1.2.0
+pluggy==0.13.1
+pre-commit==2.9.3
+protobuf==3.14.0
+py==1.10.0
+pyasn1-modules==0.2.8
+pyasn1==0.4.8
+pycodestyle==2.6.0
+pydocstyle==5.1.1
+pydot==1.4.1
+pyflakes==2.2.0
+pygments==2.7.3
+pylint==2.6.0
+pyparsing==2.4.7
+pyrsistent==0.17.3
+pytest-cov==2.10.1
+pytest-forked==1.3.0
+pytest-profiling==1.7.0
+pytest-xdist==2.2.0
+pytest==6.2.1
+python-constraint==1.4.0
+python-dateutil==2.8.1
+pytz==2020.5
+pyyaml==5.3.1
+regex==2020.11.13
+requests-oauthlib==1.3.0
+requests==2.25.1
+restructuredtext-lint==1.3.2
+rsa==4.6
+rstcheck==3.3.1
+six==1.15.0
+snowballstemmer==2.0.0
+stevedore==3.3.0
+sympy==1.7.1
+tensorboard-plugin-wit==1.7.0
+tensorboard==2.4.0
+tensorflow-estimator==2.4.0
+tensorflow-probability==0.12.1
+tensorflow==2.4.0
+termcolor==1.1.0
+toml==0.10.2
+tqdm==4.55.1
+traitlets==4.3.3
+typed-ast==1.4.2
+typing-extensions==3.7.4.3
+urllib3==1.26.2
+virtualenv==20.2.2
+werkzeug==1.0.1
+wheel==0.36.2
+wrapt==1.12.1
+xmltodict==0.12.0
+zipp==3.4.0
+
+# The following packages are considered to be unsafe in a requirements file:
+# setuptools
diff --git a/reqs/3.6/requirements.txt b/reqs/3.6/requirements.txt
new file mode 100644
index 00000000..af7b7c8b
--- /dev/null
+++ b/reqs/3.6/requirements.txt
@@ -0,0 +1,69 @@
+#
+# This file is autogenerated by pip-compile
+# To update, run:
+#
+#    pip-compile --no-annotate --output-file=reqs/3.6/requirements.txt reqs/3.6/requirements.in
+#
+absl-py==0.11.0
+amplitf==0.0.1a2
+astunparse==1.6.3
+attrs==20.3.0
+cachetools==4.2.0
+certifi==2020.12.5
+chardet==4.0.0
+cloudpickle==1.6.0
+decorator==4.4.2
+dm-tree==0.1.5
+expertsystem==0.6.5
+flatbuffers==1.12
+gast==0.3.3
+google-auth-oauthlib==0.4.2
+google-auth==1.24.0
+google-pasta==0.2.0
+grpcio==1.32.0
+h5py==2.10.0
+hepunits==2.0.1
+idna==2.10
+iminuit==1.5.4
+importlib-metadata==2.1.1
+importlib-resources==3.0.0
+jsonschema==3.2.0
+keras-preprocessing==1.1.2
+markdown==3.3.3
+mpmath==1.1.0
+numpy==1.19.4
+oauthlib==3.1.0
+opt-einsum==3.3.0
+pandas==1.1.5
+particle==0.14.0
+phasespace==1.2.0
+protobuf==3.14.0
+pyasn1-modules==0.2.8
+pyasn1==0.4.8
+pyrsistent==0.17.3
+python-constraint==1.4.0
+python-dateutil==2.8.1
+pytz==2020.5
+pyyaml==5.3.1
+requests-oauthlib==1.3.0
+requests==2.25.1
+rsa==4.6
+six==1.15.0
+sympy==1.7.1
+tensorboard-plugin-wit==1.7.0
+tensorboard==2.4.0
+tensorflow-estimator==2.4.0
+tensorflow-probability==0.12.1
+tensorflow==2.4.0
+termcolor==1.1.0
+tqdm==4.55.1
+typing-extensions==3.7.4.3
+urllib3==1.26.2
+werkzeug==1.0.1
+wheel==0.36.2
+wrapt==1.12.1
+xmltodict==0.12.0
+zipp==3.4.0
+
+# The following packages are considered to be unsafe in a requirements file:
+# setuptools
diff --git a/reqs/3.7/requirements-dev.txt b/reqs/3.7/requirements-dev.txt
new file mode 100644
index 00000000..418d8671
--- /dev/null
+++ b/reqs/3.7/requirements-dev.txt
@@ -0,0 +1,218 @@
+#
+# This file is autogenerated by pip-compile
+# To update, run:
+#
+#    pip-compile --no-annotate --output-file=reqs/3.7/requirements-dev.txt reqs/requirements-dev.in reqs/requirements-doc.in reqs/requirements-sty.in reqs/requirements-test.in reqs/requirements.in
+#
+absl-py==0.11.0
+alabaster==0.7.12
+amplitf==0.0.1a2
+anyio==2.0.2
+apipkg==1.5
+appdirs==1.4.4
+argon2-cffi==20.1.0
+astroid==2.4.2
+astunparse==1.6.3
+async-generator==1.10
+attrs==20.3.0
+babel==2.9.0
+backcall==0.2.0
+beautifulsoup4==4.9.3
+black==20.8b1
+bleach==3.2.1
+cachetools==4.2.0
+certifi==2020.12.5
+cffi==1.14.4
+cfgv==3.2.0
+chardet==4.0.0
+click==7.1.2
+cloudpickle==1.6.0
+colorama==0.4.4
+coverage==5.3.1
+cycler==0.10.0
+decorator==4.4.2
+defusedxml==0.6.0
+distlib==0.3.1
+dm-tree==0.1.5
+doc8==0.8.1
+docutils==0.16
+entrypoints==0.3
+execnet==1.7.1
+expertsystem==0.6.5
+filelock==3.0.12
+flake8-blind-except==0.1.1
+flake8-bugbear==20.11.1
+flake8-builtins==1.5.3
+flake8-polyfill==1.0.2
+flake8-rst-docstrings==0.0.14
+flake8==3.8.4
+flatbuffers==1.12
+fuzzywuzzy==0.18.0
+gast==0.3.3
+gitdb==4.0.5
+gitpython==3.1.11
+google-auth-oauthlib==0.4.2
+google-auth==1.24.0
+google-pasta==0.2.0
+gprof2dot==2019.11.30
+graphviz==0.16
+grpcio==1.32.0
+h5py==2.10.0
+hepunits==2.0.1
+identify==1.5.11
+idna==2.10
+imagesize==1.2.0
+iminuit==1.5.4
+importlib-metadata==2.1.1
+iniconfig==1.1.1
+ipykernel==5.4.2
+ipython-genutils==0.2.0
+ipython==7.19.0
+ipywidgets==7.6.2
+isort==5.7.0
+jedi==0.18.0
+jinja2==2.11.2
+json5==0.9.5
+jsonschema==3.2.0
+jupyter-cache==0.4.1
+jupyter-client==6.1.7
+jupyter-console==6.2.0
+jupyter-core==4.7.0
+jupyter-server==1.1.3
+jupyter-sphinx==0.3.2
+jupyter==1.0.0
+jupyterlab-code-formatter==1.4.1
+jupyterlab-server==2.0.0
+jupyterlab-widgets==1.0.0
+jupyterlab==3.0.0
+keras-preprocessing==1.1.2
+kiwisolver==1.3.1
+labels==20.1.0
+lazy-object-proxy==1.4.3
+markdown-it-py==0.5.8
+markdown==3.3.3
+markupsafe==1.1.1
+matplotlib==3.3.3
+mccabe==0.6.1
+mistune==0.8.4
+mpmath==1.1.0
+mypy-extensions==0.4.3
+mypy==0.790
+myst-nb==0.10.1
+myst-parser==0.12.10
+nbclassic==0.2.5
+nbclient==0.5.1
+nbconvert==5.6.1
+nbdime==2.1.0
+nbformat==5.0.8
+nbstripout==0.3.9
+nest-asyncio==1.4.3
+nodeenv==1.5.0
+notebook==6.1.6
+numpy==1.19.4
+oauthlib==3.1.0
+opt-einsum==3.3.0
+packaging==20.8
+pandas==1.2.0
+pandocfilters==1.4.3
+parso==0.8.1
+particle==0.14.0
+pathspec==0.8.1
+pbr==5.5.1
+pep8-naming==0.11.1
+pexpect==4.8.0
+phasespace==1.2.0
+pickleshare==0.7.5
+pillow==8.1.0
+pip-tools==5.5.0
+pluggy==0.13.1
+pre-commit==2.9.3
+prometheus-client==0.9.0
+prompt-toolkit==3.0.8
+protobuf==3.14.0
+ptyprocess==0.7.0
+py==1.10.0
+pyasn1-modules==0.2.8
+pyasn1==0.4.8
+pycodestyle==2.6.0
+pycparser==2.20
+pydata-sphinx-theme==0.4.1
+pydeps==1.9.13
+pydocstyle==5.1.1
+pydot==1.4.1
+pyflakes==2.2.0
+pygments==2.7.3
+pylint==2.6.0
+pyparsing==2.4.7
+pyrsistent==0.17.3
+pytest-cov==2.10.1
+pytest-forked==1.3.0
+pytest-profiling==1.7.0
+pytest-xdist==2.2.0
+pytest==6.2.1
+python-constraint==1.4.0
+python-dateutil==2.8.1
+pytoml==0.1.21
+pytz==2020.5
+pyyaml==5.3.1
+pyzmq==20.0.0
+qtconsole==5.0.1
+qtpy==1.9.0
+regex==2020.11.13
+requests-oauthlib==1.3.0
+requests==2.25.1
+restructuredtext-lint==1.3.2
+rsa==4.6
+rstcheck==3.3.1
+send2trash==1.5.0
+six==1.15.0
+smmap==3.0.4
+sniffio==1.2.0
+snowballstemmer==2.0.0
+soupsieve==2.1
+sphinx-book-theme==0.0.39
+sphinx-copybutton==0.3.1
+sphinx-panels==0.5.2
+sphinx-thebe==0.0.8
+sphinx-togglebutton==0.2.3
+sphinx==3.4.1
+sphinxcontrib-applehelp==1.0.2
+sphinxcontrib-devhelp==1.0.2
+sphinxcontrib-htmlhelp==1.0.3
+sphinxcontrib-jsmath==1.0.1
+sphinxcontrib-qthelp==1.0.3
+sphinxcontrib-serializinghtml==1.1.4
+sphobjinv==2.0.1
+sqlalchemy==1.3.22
+stdlib-list==0.8.0
+stevedore==3.3.0
+sympy==1.7.1
+tensorboard-plugin-wit==1.7.0
+tensorboard==2.4.0
+tensorflow-estimator==2.4.0
+tensorflow-probability==0.12.1
+tensorflow==2.4.0
+termcolor==1.1.0
+terminado==0.9.1
+testpath==0.4.4
+toml==0.10.2
+tornado==6.1
+tox==3.20.1
+tqdm==4.55.1
+traitlets==5.0.5
+typed-ast==1.4.2
+typing-extensions==3.7.4.3
+urllib3==1.26.2
+virtualenv==20.2.2
+wcwidth==0.2.5
+webencodings==0.5.1
+werkzeug==1.0.1
+wheel==0.36.2
+widgetsnbextension==3.5.1
+wrapt==1.12.1
+xmltodict==0.12.0
+zipp==3.4.0
+
+# The following packages are considered to be unsafe in a requirements file:
+# pip
+# setuptools
diff --git a/reqs/3.7/requirements-doc.txt b/reqs/3.7/requirements-doc.txt
new file mode 100644
index 00000000..9eb20f32
--- /dev/null
+++ b/reqs/3.7/requirements-doc.txt
@@ -0,0 +1,156 @@
+#
+# This file is autogenerated by pip-compile
+# To update, run:
+#
+#    pip-compile --no-annotate --output-file=reqs/3.7/requirements-doc.txt reqs/3.7/requirements-doc.in
+#
+absl-py==0.11.0
+alabaster==0.7.12
+amplitf==0.0.1a2
+argon2-cffi==20.1.0
+astunparse==1.6.3
+async-generator==1.10
+attrs==20.3.0
+babel==2.9.0
+backcall==0.2.0
+beautifulsoup4==4.9.3
+bleach==3.2.1
+cachetools==4.2.0
+certifi==2020.12.5
+cffi==1.14.4
+chardet==4.0.0
+click==7.1.2
+cloudpickle==1.6.0
+colorama==0.4.4
+cycler==0.10.0
+decorator==4.4.2
+defusedxml==0.6.0
+dm-tree==0.1.5
+docutils==0.16
+entrypoints==0.3
+expertsystem==0.6.5
+flatbuffers==1.12
+fuzzywuzzy==0.18.0
+gast==0.3.3
+gitdb==4.0.5
+gitpython==3.1.11
+google-auth-oauthlib==0.4.2
+google-auth==1.24.0
+google-pasta==0.2.0
+graphviz==0.16
+grpcio==1.32.0
+h5py==2.10.0
+hepunits==2.0.1
+idna==2.10
+imagesize==1.2.0
+iminuit==1.5.4
+importlib-metadata==2.1.1
+ipykernel==5.4.2
+ipython-genutils==0.2.0
+ipython==7.19.0
+ipywidgets==7.6.2
+jedi==0.18.0
+jinja2==2.11.2
+jsonschema==3.2.0
+jupyter-cache==0.4.1
+jupyter-client==6.1.7
+jupyter-console==6.2.0
+jupyter-core==4.7.0
+jupyter-sphinx==0.3.2
+jupyter==1.0.0
+jupyterlab-widgets==1.0.0
+keras-preprocessing==1.1.2
+kiwisolver==1.3.1
+markdown-it-py==0.5.8
+markdown==3.3.3
+markupsafe==1.1.1
+matplotlib==3.3.3
+mistune==0.8.4
+mpmath==1.1.0
+myst-nb==0.10.1
+myst-parser==0.12.10
+nbclient==0.5.1
+nbconvert==5.6.1
+nbdime==2.1.0
+nbformat==5.0.8
+nest-asyncio==1.4.3
+notebook==6.1.6
+numpy==1.19.4
+oauthlib==3.1.0
+opt-einsum==3.3.0
+packaging==20.8
+pandas==1.2.0
+pandocfilters==1.4.3
+parso==0.8.1
+particle==0.14.0
+pexpect==4.8.0
+phasespace==1.2.0
+pickleshare==0.7.5
+pillow==8.1.0
+prometheus-client==0.9.0
+prompt-toolkit==3.0.8
+protobuf==3.14.0
+ptyprocess==0.7.0
+pyasn1-modules==0.2.8
+pyasn1==0.4.8
+pycparser==2.20
+pydata-sphinx-theme==0.4.1
+pydeps==1.9.13
+pygments==2.7.3
+pyparsing==2.4.7
+pyrsistent==0.17.3
+python-constraint==1.4.0
+python-dateutil==2.8.1
+pytz==2020.5
+pyyaml==5.3.1
+pyzmq==20.0.0
+qtconsole==5.0.1
+qtpy==1.9.0
+requests-oauthlib==1.3.0
+requests==2.25.1
+rsa==4.6
+send2trash==1.5.0
+six==1.15.0
+smmap==3.0.4
+snowballstemmer==2.0.0
+soupsieve==2.1
+sphinx-book-theme==0.0.39
+sphinx-copybutton==0.3.1
+sphinx-panels==0.5.2
+sphinx-thebe==0.0.8
+sphinx-togglebutton==0.2.3
+sphinx==3.4.1
+sphinxcontrib-applehelp==1.0.2
+sphinxcontrib-devhelp==1.0.2
+sphinxcontrib-htmlhelp==1.0.3
+sphinxcontrib-jsmath==1.0.1
+sphinxcontrib-qthelp==1.0.3
+sphinxcontrib-serializinghtml==1.1.4
+sphobjinv==2.0.1
+sqlalchemy==1.3.22
+stdlib-list==0.8.0
+sympy==1.7.1
+tensorboard-plugin-wit==1.7.0
+tensorboard==2.4.0
+tensorflow-estimator==2.4.0
+tensorflow-probability==0.12.1
+tensorflow==2.4.0
+termcolor==1.1.0
+terminado==0.9.1
+testpath==0.4.4
+tornado==6.1
+tqdm==4.55.1
+traitlets==5.0.5
+typing-extensions==3.7.4.3
+urllib3==1.26.2
+wcwidth==0.2.5
+webencodings==0.5.1
+werkzeug==1.0.1
+wheel==0.36.2
+widgetsnbextension==3.5.1
+wrapt==1.12.1
+xmltodict==0.12.0
+zipp==3.4.0
+
+# The following packages are considered to be unsafe in a requirements file:
+# setuptools
diff --git a/reqs/3.7/requirements-sty.txt b/reqs/3.7/requirements-sty.txt
new file mode 100644
index 00000000..05fe6437
--- /dev/null
+++ b/reqs/3.7/requirements-sty.txt
@@ -0,0 +1,127 @@
+#
+# This file is autogenerated by pip-compile
+# To update, run:
+#
+#    pip-compile --no-annotate --output-file=reqs/3.7/requirements-sty.txt reqs/3.7/requirements-sty.in
+#
+absl-py==0.11.0
+amplitf==0.0.1a2
+apipkg==1.5
+appdirs==1.4.4
+astroid==2.4.2
+astunparse==1.6.3
+attrs==20.3.0
+black==20.8b1
+cachetools==4.2.0
+certifi==2020.12.5
+cfgv==3.2.0
+chardet==4.0.0
+click==7.1.2
+cloudpickle==1.6.0
+coverage==5.3.1
+decorator==4.4.2
+distlib==0.3.1
+dm-tree==0.1.5
+doc8==0.8.1
+docutils==0.16
+execnet==1.7.1
+expertsystem==0.6.5
+filelock==3.0.12
+flake8-blind-except==0.1.1
+flake8-bugbear==20.11.1
+flake8-builtins==1.5.3
+flake8-polyfill==1.0.2
+flake8-rst-docstrings==0.0.14
+flake8==3.8.4
+flatbuffers==1.12
+gast==0.3.3
+google-auth-oauthlib==0.4.2
+google-auth==1.24.0
+google-pasta==0.2.0
+gprof2dot==2019.11.30
+grpcio==1.32.0
+h5py==2.10.0
+hepunits==2.0.1
+identify==1.5.11
+idna==2.10
+iminuit==1.5.4
+importlib-metadata==2.1.1
+iniconfig==1.1.1
+ipython-genutils==0.2.0
+isort==5.7.0
+jsonschema==3.2.0
+jupyter-core==4.7.0
+keras-preprocessing==1.1.2
+lazy-object-proxy==1.4.3
+markdown==3.3.3
+mccabe==0.6.1
+mpmath==1.1.0
+mypy-extensions==0.4.3
+mypy==0.790
+nbformat==5.0.8
+nbstripout==0.3.9
+nodeenv==1.5.0
+numpy==1.19.4
+oauthlib==3.1.0
+opt-einsum==3.3.0
+packaging==20.8
+pandas==1.2.0
+particle==0.14.0
+pathspec==0.8.1
+pbr==5.5.1
+pep8-naming==0.11.1
+phasespace==1.2.0
+pluggy==0.13.1
+pre-commit==2.9.3
+protobuf==3.14.0
+py==1.10.0
+pyasn1-modules==0.2.8
+pyasn1==0.4.8
+pycodestyle==2.6.0
+pydocstyle==5.1.1
+pydot==1.4.1
+pyflakes==2.2.0
+pygments==2.7.3
+pylint==2.6.0
+pyparsing==2.4.7
+pyrsistent==0.17.3
+pytest-cov==2.10.1
+pytest-forked==1.3.0
+pytest-profiling==1.7.0
+pytest-xdist==2.2.0
+pytest==6.2.1
+python-constraint==1.4.0
+python-dateutil==2.8.1
+pytz==2020.5
+pyyaml==5.3.1
+regex==2020.11.13
+requests-oauthlib==1.3.0
+requests==2.25.1
+restructuredtext-lint==1.3.2
+rsa==4.6
+rstcheck==3.3.1
+six==1.15.0
+snowballstemmer==2.0.0
+stevedore==3.3.0
+sympy==1.7.1
+tensorboard-plugin-wit==1.7.0
+tensorboard==2.4.0
+tensorflow-estimator==2.4.0
+tensorflow-probability==0.12.1
+tensorflow==2.4.0
+termcolor==1.1.0
+toml==0.10.2
+tqdm==4.55.1
+traitlets==5.0.5
+typed-ast==1.4.2
+typing-extensions==3.7.4.3
+urllib3==1.26.2
+virtualenv==20.2.2
+werkzeug==1.0.1
+wheel==0.36.2
+wrapt==1.12.1
+xmltodict==0.12.0
+zipp==3.4.0
+
+# The following packages are considered to be unsafe in a requirements file:
+# setuptools
diff --git a/reqs/3.7/requirements.txt b/reqs/3.7/requirements.txt
new file mode 100644
index 00000000..29d53ad8
--- /dev/null
+++ b/reqs/3.7/requirements.txt
@@ -0,0 +1,68 @@
+#
+# This file is autogenerated by pip-compile
+# To update, run:
+#
+#    pip-compile --no-annotate --output-file=reqs/3.7/requirements.txt reqs/3.7/requirements.in
+#
+absl-py==0.11.0
+amplitf==0.0.1a2
+astunparse==1.6.3
+attrs==20.3.0
+cachetools==4.2.0
+certifi==2020.12.5
+chardet==4.0.0
+cloudpickle==1.6.0
+decorator==4.4.2
+dm-tree==0.1.5
+expertsystem==0.6.5
+flatbuffers==1.12
+gast==0.3.3
+google-auth-oauthlib==0.4.2
+google-auth==1.24.0
+google-pasta==0.2.0
+grpcio==1.32.0
+h5py==2.10.0
+hepunits==2.0.1
+idna==2.10
+iminuit==1.5.4
+importlib-metadata==2.1.1
+jsonschema==3.2.0
+keras-preprocessing==1.1.2
+markdown==3.3.3
+mpmath==1.1.0
+numpy==1.19.4
+oauthlib==3.1.0
+opt-einsum==3.3.0
+pandas==1.2.0
+particle==0.14.0
+phasespace==1.2.0
+protobuf==3.14.0
+pyasn1-modules==0.2.8
+pyasn1==0.4.8
+pyrsistent==0.17.3
+python-constraint==1.4.0
+python-dateutil==2.8.1
+pytz==2020.5
+pyyaml==5.3.1
+requests-oauthlib==1.3.0
+requests==2.25.1
+rsa==4.6
+six==1.15.0
+sympy==1.7.1
+tensorboard-plugin-wit==1.7.0
+tensorboard==2.4.0
+tensorflow-estimator==2.4.0
+tensorflow-probability==0.12.1
+tensorflow==2.4.0
+termcolor==1.1.0
+tqdm==4.55.1
+typing-extensions==3.7.4.3
+urllib3==1.26.2
+werkzeug==1.0.1
+wheel==0.36.2
+wrapt==1.12.1
+xmltodict==0.12.0
+zipp==3.4.0
+
+# The following packages are considered to be unsafe in a requirements file:
+# setuptools
diff --git a/reqs/3.8/requirements-dev.txt b/reqs/3.8/requirements-dev.txt
new file mode 100644
index 00000000..4c862bfe
--- /dev/null
+++ b/reqs/3.8/requirements-dev.txt
@@ -0,0 +1,218 @@
+#
+# This file is autogenerated by pip-compile
+# To update, run:
+#
+#    pip-compile --no-annotate --output-file=reqs/3.8/requirements-dev.txt reqs/requirements-dev.in reqs/requirements-doc.in reqs/requirements-sty.in reqs/requirements-test.in reqs/requirements.in
+#
+absl-py==0.11.0
+alabaster==0.7.12
+amplitf==0.0.1a2
+anyio==2.0.2
+apipkg==1.5
+appdirs==1.4.4
+argon2-cffi==20.1.0
+astroid==2.4.2
+astunparse==1.6.3
+async-generator==1.10
+attrs==20.3.0
+babel==2.9.0
+backcall==0.2.0
+beautifulsoup4==4.9.3
+black==20.8b1
+bleach==3.2.1
+cachetools==4.2.0
+certifi==2020.12.5
+cffi==1.14.4
+cfgv==3.2.0
+chardet==4.0.0
+click==7.1.2
+cloudpickle==1.6.0
+colorama==0.4.4
+coverage==5.3.1
+cycler==0.10.0
+decorator==4.4.2
+defusedxml==0.6.0
+distlib==0.3.1
+dm-tree==0.1.5
+doc8==0.8.1
+docutils==0.16
+entrypoints==0.3
+execnet==1.7.1
+expertsystem==0.6.5
+filelock==3.0.12
+flake8-blind-except==0.1.1
+flake8-bugbear==20.11.1
+flake8-builtins==1.5.3
+flake8-polyfill==1.0.2
+flake8-rst-docstrings==0.0.14
+flake8==3.8.4
+flatbuffers==1.12
+fuzzywuzzy==0.18.0
+gast==0.3.3
+gitdb==4.0.5
+gitpython==3.1.11
+google-auth-oauthlib==0.4.2
+google-auth==1.24.0
+google-pasta==0.2.0
+gprof2dot==2019.11.30
+graphviz==0.16
+grpcio==1.32.0
+h5py==2.10.0
+hepunits==2.0.1
+identify==1.5.11
+idna==2.10
+imagesize==1.2.0
+iminuit==1.5.4
+importlib-metadata==3.3.0
+iniconfig==1.1.1
+ipykernel==5.4.2
+ipython-genutils==0.2.0
+ipython==7.19.0
+ipywidgets==7.6.2
+isort==5.7.0
+jedi==0.18.0
+jinja2==2.11.2
+json5==0.9.5
+jsonschema==3.2.0
+jupyter-cache==0.4.1
+jupyter-client==6.1.7
+jupyter-console==6.2.0
+jupyter-core==4.7.0
+jupyter-server==1.1.3
+jupyter-sphinx==0.3.2
+jupyter==1.0.0
+jupyterlab-code-formatter==1.4.1
+jupyterlab-server==2.0.0
+jupyterlab-widgets==1.0.0
+jupyterlab==3.0.0
+keras-preprocessing==1.1.2
+kiwisolver==1.3.1
+labels==20.1.0
+lazy-object-proxy==1.4.3
+markdown-it-py==0.5.8
+markdown==3.3.3
+markupsafe==1.1.1
+matplotlib==3.3.3
+mccabe==0.6.1
+mistune==0.8.4
+mpmath==1.1.0
+mypy-extensions==0.4.3
+mypy==0.790
+myst-nb==0.10.1
+myst-parser==0.12.10
+nbclassic==0.2.5
+nbclient==0.5.1
+nbconvert==5.6.1
+nbdime==2.1.0
+nbformat==5.0.8
+nbstripout==0.3.9
+nest-asyncio==1.4.3
+nodeenv==1.5.0
+notebook==6.1.6
+numpy==1.19.4
+oauthlib==3.1.0
+opt-einsum==3.3.0
+packaging==20.8
+pandas==1.2.0
+pandocfilters==1.4.3
+parso==0.8.1
+particle==0.14.0
+pathspec==0.8.1
+pbr==5.5.1
+pep8-naming==0.11.1
+pexpect==4.8.0
+phasespace==1.2.0
+pickleshare==0.7.5
+pillow==8.1.0
+pip-tools==5.5.0
+pluggy==0.13.1
+pre-commit==2.9.3
+prometheus-client==0.9.0
+prompt-toolkit==3.0.8
+protobuf==3.14.0
+ptyprocess==0.7.0
+py==1.10.0
+pyasn1-modules==0.2.8
+pyasn1==0.4.8
+pycodestyle==2.6.0
+pycparser==2.20
+pydata-sphinx-theme==0.4.1
+pydeps==1.9.13
+pydocstyle==5.1.1
+pydot==1.4.1
+pyflakes==2.2.0
+pygments==2.7.3
+pylint==2.6.0
+pyparsing==2.4.7
+pyrsistent==0.17.3
+pytest-cov==2.10.1
+pytest-forked==1.3.0
+pytest-profiling==1.7.0
+pytest-xdist==2.2.0
+pytest==6.2.1
+python-constraint==1.4.0
+python-dateutil==2.8.1
+pytoml==0.1.21
+pytz==2020.5
+pyyaml==5.3.1
+pyzmq==20.0.0
+qtconsole==5.0.1
+qtpy==1.9.0
+regex==2020.11.13
+requests-oauthlib==1.3.0
+requests==2.25.1
+restructuredtext-lint==1.3.2
+rsa==4.6
+rstcheck==3.3.1
+send2trash==1.5.0
+six==1.15.0
+smmap==3.0.4
+sniffio==1.2.0
+snowballstemmer==2.0.0
+soupsieve==2.1
+sphinx-book-theme==0.0.39
+sphinx-copybutton==0.3.1
+sphinx-panels==0.5.2
+sphinx-thebe==0.0.8
+sphinx-togglebutton==0.2.3
+sphinx==3.4.1
+sphinxcontrib-applehelp==1.0.2
+sphinxcontrib-devhelp==1.0.2
+sphinxcontrib-htmlhelp==1.0.3
+sphinxcontrib-jsmath==1.0.1
+sphinxcontrib-qthelp==1.0.3
+sphinxcontrib-serializinghtml==1.1.4
+sphobjinv==2.0.1
+sqlalchemy==1.3.22
+stdlib-list==0.8.0
+stevedore==3.3.0
+sympy==1.7.1
+tensorboard-plugin-wit==1.7.0
+tensorboard==2.4.0
+tensorflow-estimator==2.4.0
+tensorflow-probability==0.12.1
+tensorflow==2.4.0
+termcolor==1.1.0
+terminado==0.9.1
+testpath==0.4.4
+toml==0.10.2
+tornado==6.1
+tox==3.20.1
+tqdm==4.55.1
+traitlets==5.0.5
+typed-ast==1.4.2
+typing-extensions==3.7.4.3
+urllib3==1.26.2
+virtualenv==20.2.2
+wcwidth==0.2.5
+webencodings==0.5.1
+werkzeug==1.0.1
+wheel==0.36.2
+widgetsnbextension==3.5.1
+wrapt==1.12.1
+xmltodict==0.12.0
+zipp==3.4.0
+
+# The following packages are considered to be unsafe in a requirements file:
+# pip
+# setuptools
diff --git a/reqs/3.8/requirements-doc.txt b/reqs/3.8/requirements-doc.txt
new file mode 100644
index 00000000..16259c1e
--- /dev/null
+++ b/reqs/3.8/requirements-doc.txt
@@ -0,0 +1,156 @@
+#
+# This file is autogenerated by pip-compile
+# To update, run:
+#
+#    pip-compile --no-annotate --output-file=reqs/3.8/requirements-doc.txt reqs/3.8/requirements-doc.in
+#
+absl-py==0.11.0
+alabaster==0.7.12
+amplitf==0.0.1a2
+argon2-cffi==20.1.0
+astunparse==1.6.3
+async-generator==1.10
+attrs==20.3.0
+babel==2.9.0
+backcall==0.2.0
+beautifulsoup4==4.9.3
+bleach==3.2.1
+cachetools==4.2.0
+certifi==2020.12.5
+cffi==1.14.4
+chardet==4.0.0
+click==7.1.2
+cloudpickle==1.6.0
+colorama==0.4.4
+cycler==0.10.0
+decorator==4.4.2
+defusedxml==0.6.0
+dm-tree==0.1.5
+docutils==0.16
+entrypoints==0.3
+expertsystem==0.6.5
+flatbuffers==1.12
+fuzzywuzzy==0.18.0
+gast==0.3.3
+gitdb==4.0.5
+gitpython==3.1.11
+google-auth-oauthlib==0.4.2
+google-auth==1.24.0
+google-pasta==0.2.0
+graphviz==0.16
+grpcio==1.32.0
+h5py==2.10.0
+hepunits==2.0.1
+idna==2.10
+imagesize==1.2.0
+iminuit==1.5.4
+importlib-metadata==3.3.0
+ipykernel==5.4.2
+ipython-genutils==0.2.0
+ipython==7.19.0
+ipywidgets==7.6.2
+jedi==0.18.0
+jinja2==2.11.2
+jsonschema==3.2.0
+jupyter-cache==0.4.1
+jupyter-client==6.1.7
+jupyter-console==6.2.0
+jupyter-core==4.7.0
+jupyter-sphinx==0.3.2
+jupyter==1.0.0
+jupyterlab-widgets==1.0.0
+keras-preprocessing==1.1.2
+kiwisolver==1.3.1
+markdown-it-py==0.5.8
+markdown==3.3.3
+markupsafe==1.1.1
+matplotlib==3.3.3
+mistune==0.8.4
+mpmath==1.1.0
+myst-nb==0.10.1
+myst-parser==0.12.10
+nbclient==0.5.1
+nbconvert==5.6.1
+nbdime==2.1.0
+nbformat==5.0.8
+nest-asyncio==1.4.3
+notebook==6.1.6
+numpy==1.19.4
+oauthlib==3.1.0
+opt-einsum==3.3.0
+packaging==20.8
+pandas==1.2.0
+pandocfilters==1.4.3
+parso==0.8.1
+particle==0.14.0
+pexpect==4.8.0
+phasespace==1.2.0
+pickleshare==0.7.5
+pillow==8.1.0
+prometheus-client==0.9.0
+prompt-toolkit==3.0.8
+protobuf==3.14.0
+ptyprocess==0.7.0
+pyasn1-modules==0.2.8
+pyasn1==0.4.8
+pycparser==2.20
+pydata-sphinx-theme==0.4.1
+pydeps==1.9.13
+pygments==2.7.3
+pyparsing==2.4.7
+pyrsistent==0.17.3
+python-constraint==1.4.0
+python-dateutil==2.8.1
+pytz==2020.5
+pyyaml==5.3.1
+pyzmq==20.0.0
+qtconsole==5.0.1
+qtpy==1.9.0
+requests-oauthlib==1.3.0
+requests==2.25.1
+rsa==4.6
+send2trash==1.5.0
+six==1.15.0
+smmap==3.0.4
+snowballstemmer==2.0.0
+soupsieve==2.1
+sphinx-book-theme==0.0.39
+sphinx-copybutton==0.3.1
+sphinx-panels==0.5.2
+sphinx-thebe==0.0.8
+sphinx-togglebutton==0.2.3
+sphinx==3.4.1
+sphinxcontrib-applehelp==1.0.2
+sphinxcontrib-devhelp==1.0.2
+sphinxcontrib-htmlhelp==1.0.3
+sphinxcontrib-jsmath==1.0.1
+sphinxcontrib-qthelp==1.0.3
+sphinxcontrib-serializinghtml==1.1.4
+sphobjinv==2.0.1
+sqlalchemy==1.3.22
+stdlib-list==0.8.0
+sympy==1.7.1
+tensorboard-plugin-wit==1.7.0
+tensorboard==2.4.0
+tensorflow-estimator==2.4.0
+tensorflow-probability==0.12.1
+tensorflow==2.4.0
+termcolor==1.1.0
+terminado==0.9.1
+testpath==0.4.4
+tornado==6.1
+tqdm==4.55.1
+traitlets==5.0.5
+typing-extensions==3.7.4.3
+urllib3==1.26.2
+wcwidth==0.2.5
+webencodings==0.5.1
+werkzeug==1.0.1
+wheel==0.36.2
+widgetsnbextension==3.5.1
+wrapt==1.12.1
+xmltodict==0.12.0
+zipp==3.4.0
+
+# The following packages are considered to be unsafe in a requirements file:
+# setuptools
diff --git a/reqs/3.8/requirements-sty.txt b/reqs/3.8/requirements-sty.txt
new file mode 100644
index 00000000..4918a194
--- /dev/null
+++ b/reqs/3.8/requirements-sty.txt
@@ -0,0 +1,125 @@
+#
+# This file is autogenerated by pip-compile
+# To update, run:
+#
+#    pip-compile --no-annotate --output-file=reqs/3.8/requirements-sty.txt reqs/3.8/requirements-sty.in
+#
+absl-py==0.11.0
+amplitf==0.0.1a2
+apipkg==1.5
+appdirs==1.4.4
+astroid==2.4.2
+astunparse==1.6.3
+attrs==20.3.0
+black==20.8b1
+cachetools==4.2.0
+certifi==2020.12.5
+cfgv==3.2.0
+chardet==4.0.0
+click==7.1.2
+cloudpickle==1.6.0
+coverage==5.3.1
+decorator==4.4.2
+distlib==0.3.1
+dm-tree==0.1.5
+doc8==0.8.1
+docutils==0.16
+execnet==1.7.1
+expertsystem==0.6.5
+filelock==3.0.12
+flake8-blind-except==0.1.1
+flake8-bugbear==20.11.1
+flake8-builtins==1.5.3
+flake8-polyfill==1.0.2
+flake8-rst-docstrings==0.0.14
+flake8==3.8.4
+flatbuffers==1.12
+gast==0.3.3
+google-auth-oauthlib==0.4.2
+google-auth==1.24.0
+google-pasta==0.2.0
+gprof2dot==2019.11.30
+grpcio==1.32.0
+h5py==2.10.0
+hepunits==2.0.1
+identify==1.5.11
+idna==2.10
+iminuit==1.5.4
+iniconfig==1.1.1
+ipython-genutils==0.2.0
+isort==5.7.0
+jsonschema==3.2.0
+jupyter-core==4.7.0
+keras-preprocessing==1.1.2
+lazy-object-proxy==1.4.3
+markdown==3.3.3
+mccabe==0.6.1
+mpmath==1.1.0
+mypy-extensions==0.4.3
+mypy==0.790
+nbformat==5.0.8
+nbstripout==0.3.9
+nodeenv==1.5.0
+numpy==1.19.4
+oauthlib==3.1.0
+opt-einsum==3.3.0
+packaging==20.8
+pandas==1.2.0
+particle==0.14.0
+pathspec==0.8.1
+pbr==5.5.1
+pep8-naming==0.11.1
+phasespace==1.2.0
+pluggy==0.13.1
+pre-commit==2.9.3
+protobuf==3.14.0
+py==1.10.0
+pyasn1-modules==0.2.8
+pyasn1==0.4.8
+pycodestyle==2.6.0
+pydocstyle==5.1.1
+pydot==1.4.1
+pyflakes==2.2.0
+pygments==2.7.3
+pylint==2.6.0
+pyparsing==2.4.7
+pyrsistent==0.17.3
+pytest-cov==2.10.1
+pytest-forked==1.3.0
+pytest-profiling==1.7.0
+pytest-xdist==2.2.0
+pytest==6.2.1
+python-constraint==1.4.0
+python-dateutil==2.8.1
+pytz==2020.5
+pyyaml==5.3.1
+regex==2020.11.13
+requests-oauthlib==1.3.0
+requests==2.25.1
+restructuredtext-lint==1.3.2
+rsa==4.6
+rstcheck==3.3.1
+six==1.15.0
+snowballstemmer==2.0.0
+stevedore==3.3.0
+sympy==1.7.1
+tensorboard-plugin-wit==1.7.0
+tensorboard==2.4.0
+tensorflow-estimator==2.4.0
+tensorflow-probability==0.12.1
+tensorflow==2.4.0
+termcolor==1.1.0
+toml==0.10.2
+tqdm==4.55.1
+traitlets==5.0.5
+typed-ast==1.4.2
+typing-extensions==3.7.4.3
+urllib3==1.26.2
+virtualenv==20.2.2
+werkzeug==1.0.1
+wheel==0.36.2
+wrapt==1.12.1
+xmltodict==0.12.0
+
+# The following packages are considered to be unsafe in a requirements file:
+# setuptools
diff --git a/reqs/3.8/requirements.txt b/reqs/3.8/requirements.txt
new file mode 100644
index 00000000..f51c5c27
--- /dev/null
+++ b/reqs/3.8/requirements.txt
@@ -0,0 +1,66 @@
+#
+# This file is autogenerated by pip-compile
+# To update, run:
+#
+#    pip-compile --no-annotate --output-file=reqs/3.8/requirements.txt reqs/3.8/requirements.in
+#
+absl-py==0.11.0
+amplitf==0.0.1a2
+astunparse==1.6.3
+attrs==20.3.0
+cachetools==4.2.0
+certifi==2020.12.5
+chardet==4.0.0
+cloudpickle==1.6.0
+decorator==4.4.2
+dm-tree==0.1.5
+expertsystem==0.6.5
+flatbuffers==1.12
+gast==0.3.3
+google-auth-oauthlib==0.4.2
+google-auth==1.24.0
+google-pasta==0.2.0
+grpcio==1.32.0
+h5py==2.10.0
+hepunits==2.0.1
+idna==2.10
+iminuit==1.5.4
+jsonschema==3.2.0
+keras-preprocessing==1.1.2
+markdown==3.3.3
+mpmath==1.1.0
+numpy==1.19.4
+oauthlib==3.1.0
+opt-einsum==3.3.0
+pandas==1.2.0
+particle==0.14.0
+phasespace==1.2.0
+protobuf==3.14.0
+pyasn1-modules==0.2.8
+pyasn1==0.4.8
+pyrsistent==0.17.3
+python-constraint==1.4.0
+python-dateutil==2.8.1
+pytz==2020.5
+pyyaml==5.3.1
+requests-oauthlib==1.3.0
+requests==2.25.1
+rsa==4.6
+six==1.15.0
+sympy==1.7.1
+tensorboard-plugin-wit==1.7.0
+tensorboard==2.4.0
+tensorflow-estimator==2.4.0
+tensorflow-probability==0.12.1
+tensorflow==2.4.0
+termcolor==1.1.0
+tqdm==4.55.1
+typing-extensions==3.7.4.3
+urllib3==1.26.2
+werkzeug==1.0.1
+wheel==0.36.2
+wrapt==1.12.1
+xmltodict==0.12.0
+
+# The following packages are considered to be unsafe in a requirements file:
+# setuptools
diff --git a/reqs/extract_install_requires.py b/reqs/extract_install_requires.py
new file mode 100644
index 00000000..39484f39
--- /dev/null
+++ b/reqs/extract_install_requires.py
@@ -0,0 +1,18 @@
+"""Extract :code:`install_requires` section to :file:`requirements.in`."""
+
+import configparser
+from os.path import dirname, realpath
+
+
+def main() -> None:
+    script_dir = dirname(realpath(__file__))
+    cfg = configparser.ConfigParser()
+    cfg.read(f"{script_dir}/../setup.cfg")
+    install_requires = cfg.get("options", "install_requires", raw=False)
+    install_requires = install_requires[1:]  # remove first line (empty)
+    with open(f"{script_dir}/requirements.in", "w") as stream:
+        stream.write(install_requires)
+
+
+if __name__ == "__main__":
+    main()
diff --git a/reqs/requirements-dev.in b/reqs/requirements-dev.in
new file mode 100644
index 00000000..ec2ad70f
--- /dev/null
+++ b/reqs/requirements-dev.in
@@ -0,0 +1,11 @@
+-r requirements.in
+-r requirements-doc.in
+-r requirements-test.in
+-r requirements-sty.in
+
+# Additional developer tools
+jupyterlab
+jupyterlab-code-formatter
+labels
+pip-tools
+tox >= 1.9  # for skip_install, use_develop
diff --git a/reqs/requirements-doc.in b/reqs/requirements-doc.in
new file mode 100644
index 00000000..b9080e06
--- /dev/null
+++ b/reqs/requirements-doc.in
@@ -0,0 +1,16 @@
+-r requirements.in
+
+# Requirements to build documentation
+graphviz
+ipywidgets
+jupyter
+matplotlib
+myst-nb
+pydeps
+Sphinx >= 3
+sphinx-book-theme
+sphinx-copybutton
+sphinx-panels
+sphinx-thebe
+sphinx-togglebutton
+sphobjinv
diff --git a/reqs/requirements-sty.in b/reqs/requirements-sty.in
new file mode 100644
index 00000000..1c403b36
--- /dev/null
+++ b/reqs/requirements-sty.in
@@ -0,0 +1,24 @@
+-r requirements.in
+-r requirements-test.in  # for pytest type hints
+
+pre-commit >= 1.4.0
+
+# Requirements for formatting files
+black
+isort
+nbstripout
+
+# Lint Python source code
+flake8  >= 3  # for per-file-ignores
+flake8-blind-except
+flake8-bugbear
+flake8-builtins
+flake8-rst-docstrings
+mypy
+pep8-naming
+pydocstyle
+pylint
+
+# Lint documentation files
+doc8
+rstcheck
diff --git a/reqs/upgrade.sh b/reqs/upgrade.sh
new file mode 100644
index 00000000..65a81c46
--- /dev/null
+++ b/reqs/upgrade.sh
@@ -0,0 +1,28 @@
+# https://github.com/jazzband/pip-tools/issues/625
+
+PYTHON_VERSION=$(python -c 'import sys; print(".".join(map(str, sys.version_info[:2])))')
+
+if [[ -z "$PYTHON_VERSION" ]]; then
+    echo -e "\e[31;1mERROR: environment variable PYTHON_VERSION needs to be defined!\e[0m"
+    exit 1
+fi
+
+mkdir -p reqs/$PYTHON_VERSION &&
+    python reqs/extract_install_requires.py &&
+    cp reqs/requirements*.in reqs/$PYTHON_VERSION/ &&
+    rm reqs/$PYTHON_VERSION/requirements-dev.in &&
+    pip-compile --upgrade \
+        --no-annotate \
+        reqs/requirements*.in \
+        -o reqs/$PYTHON_VERSION/requirements-dev.txt &&
+    for in_file in $(ls reqs/$PYTHON_VERSION/requirements*.in); do
+        echo -e "-c requirements-dev.txt\n$(cat ${in_file})" >${in_file}
+        out_file="${in_file/.in/.txt}"
+        pip-compile "${in_file}" -o "${out_file}" --no-annotate
+        # https://github.com/jazzband/pip-tools/issues/431#issuecomment-277300235
+        sed -i -e 's/typing_extensions/typing-extensions/g' "${out_file}"
+    done &&
+    pip-sync reqs/$PYTHON_VERSION/requirements*.txt &&
+    exit 0
+
+exit 1 # if failure
diff --git a/setup.cfg b/setup.cfg
index 9cd94693..c274999b 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -41,16 +41,16 @@ python_requires = >=3.6
 setup_requires =
     setuptools_scm
 install_requires =
-    amplitf==0.0.1a2
-    expertsystem==0.6.4
-    iminuit==1.4.5
-    numpy==1.18.0
-    pandas==1.0.5
-    phasespace==1.2.0
-    PyYAML==5.3
-    sympy==1.6
-    tensorflow==2.3.0
-    tqdm==4.51.0
+    amplitf
+    expertsystem >= 0.6.4
+    iminuit < 2.0
+    numpy
+    pandas
+    phasespace >= 1.2.0
+    PyYAML
+    sympy
+    tensorflow >= 2.0
+    tqdm
 packages = find:
 package_dir =
     =src
@@ -62,65 +62,6 @@ where = src
 tensorwaves =
     py.typed
 
-[options.extras_require]
-doc =
-    graphviz==0.15
-    ipywidgets==7.5.1
-    jupyter==1.0.0
-    matplotlib==3.2.2
-    myst-nb==0.10.1
-    pydeps==1.9.11
-    Sphinx==3.3.1
-    sphinx-book-theme==0.0.39
-    sphinx-copybutton==0.3.1
-    sphinx-panels==0.5.2
-    sphinx-thebe==0.0.8
-    sphinx-togglebutton==0.2.3
-    sphobjinv==2.0.1
-format =
-    black==20.8b1
-    isort==5.6.4
-    nbstripout==0.3.9
-lint-doc =
-    doc8==0.8.1
-    rstcheck==3.3.1
-lint-py =
-    flake8==3.8.4
-    flake8-blind-except==0.1.1
-    flake8-bugbear==20.1.4
-    flake8-builtins==1.5.3
-    flake8-rst-docstrings==0.0.14
-    mypy==0.790
-    pep8-naming==0.11.1
-    pydocstyle==5.1.1
-    pylint==2.6.0
-lint =
-    %(lint-doc)s
-    %(lint-py)s
-test =
-    pydot==1.4.1
-    pytest==6.1.2
-    pytest-cov==2.10.1
-    pytest-profiling==1.7.0
-    pytest-xdist==2.1.0
-precommit =
-    %(format)s
-    %(lint)s
-    %(test)s
-    pre-commit==2.9.0
-tox =
-    %(precommit)s
-    sphinx-autobuild==2020.9.1
-    tox==3.20.1
-tools =
-    jupyterlab==2.2.9
-    jupyterlab_code_formatter==1.3.8
-    labels==20.1.0
-dev =
-    %(doc)s
-    %(tools)s
-    %(tox)s
-
 [doc8]
 extension=.inc
 file-encoding=UTF-8
diff --git a/tox.ini b/tox.ini
index 3dd5cbd0..11f52eb8 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,17 +1,17 @@
 [tox]
-passenv = PYTHONPATH
-skip_install = True
-skip_missing_interpreters=true
-skipsdist = True
 envlist =
     py,
     doc,
     sty,
+passenv = PYTHONPATH
+skip_install = True
+skip_missing_interpreters = True
+skipsdist = True
 
 [testenv]
 description =
     Run all unit tests
-whitelist_externals =
+allowlist_externals =
     pytest
 commands =
     pytest {posargs:tests}
@@ -19,7 +19,7 @@ commands =
 [testenv:cov]
 description =
     Compute test coverage
-whitelist_externals =
+allowlist_externals =
     pytest
 commands =
     pytest {posargs:tests} \
@@ -32,15 +32,15 @@ commands =
 description =
     Build documentation and API through Sphinx
 changedir = docs
-whitelist_externals =
+allowlist_externals =
     make
 commands =
     make html
 
-[testenv:doc-live]
+[testenv:doclive]
 description =
-    Set up a server to preview changes to the HTML pages live
-whitelist_externals =
+    Set up a server to directly preview changes to the HTML pages
+deps =
     sphinx-autobuild
 commands =
     sphinx-autobuild \
@@ -58,7 +58,7 @@ description =
 setenv =
     EXECUTE_NB = "yes"
 changedir = docs
-whitelist_externals =
+allowlist_externals =
     make
 commands =
     make html
@@ -67,7 +67,7 @@ commands =
 description =
     Check the doctests in docstrings of the API
 changedir = docs
-whitelist_externals =
+allowlist_externals =
     make
 commands =
     make ignore-warnings=1 doctest  # for margin directive
@@ -76,7 +76,7 @@ commands =
 description =
     Check external links in the documentation (requires internet connection)
 changedir = docs
-whitelist_externals =
+allowlist_externals =
     make
 commands =
     make ignore-warnings=1 linkcheck  # for margin directive
@@ -86,14 +86,14 @@ description =
     Perform all linting, formatting, and spelling checks
 setenv =
     SKIP = mypy
-whitelist_externals =
+allowlist_externals =
     bash
     mypy
     pre-commit
 commands =
     mypy .  # run separately because of potential caching problems
     pre-commit run {posargs} -a
-    - bash -ec "cspell $(git ls-files)"
+    - bash -ec "cspell --no-progress $(git ls-files)"
 
 [coverage:run]
 branch = True


Test patch:
diff --git a/reqs/3.6/requirements-test.txt b/reqs/3.6/requirements-test.txt
new file mode 100644
index 00000000..99a5f536
--- /dev/null
+++ b/reqs/3.6/requirements-test.txt
@@ -0,0 +1,85 @@
+#
+# This file is autogenerated by pip-compile
+# To update, run:
+#
+#    pip-compile --no-annotate --output-file=reqs/3.6/requirements-test.txt reqs/3.6/requirements-test.in
+#
+absl-py==0.11.0
+amplitf==0.0.1a2
+apipkg==1.5
+astunparse==1.6.3
+attrs==20.3.0
+cachetools==4.2.0
+certifi==2020.12.5
+chardet==4.0.0
+cloudpickle==1.6.0
+coverage==5.3.1
+decorator==4.4.2
+dm-tree==0.1.5
+execnet==1.7.1
+expertsystem==0.6.5
+flatbuffers==1.12
+gast==0.3.3
+google-auth-oauthlib==0.4.2
+google-auth==1.24.0
+google-pasta==0.2.0
+gprof2dot==2019.11.30
+grpcio==1.32.0
+h5py==2.10.0
+hepunits==2.0.1
+idna==2.10
+iminuit==1.5.4
+importlib-metadata==2.1.1
+importlib-resources==3.0.0
+iniconfig==1.1.1
+jsonschema==3.2.0
+keras-preprocessing==1.1.2
+markdown==3.3.3
+mpmath==1.1.0
+numpy==1.19.4
+oauthlib==3.1.0
+opt-einsum==3.3.0
+packaging==20.8
+pandas==1.1.5
+particle==0.14.0
+phasespace==1.2.0
+pluggy==0.13.1
+protobuf==3.14.0
+py==1.10.0
+pyasn1-modules==0.2.8
+pyasn1==0.4.8
+pydot==1.4.1
+pyparsing==2.4.7
+pyrsistent==0.17.3
+pytest-cov==2.10.1
+pytest-forked==1.3.0
+pytest-profiling==1.7.0
+pytest-xdist==2.2.0
+pytest==6.2.1
+python-constraint==1.4.0
+python-dateutil==2.8.1
+pytz==2020.5
+pyyaml==5.3.1
+requests-oauthlib==1.3.0
+requests==2.25.1
+rsa==4.6
+six==1.15.0
+sympy==1.7.1
+tensorboard-plugin-wit==1.7.0
+tensorboard==2.4.0
+tensorflow-estimator==2.4.0
+tensorflow-probability==0.12.1
+tensorflow==2.4.0
+termcolor==1.1.0
+toml==0.10.2
+tqdm==4.55.1
+typing-extensions==3.7.4.3
+urllib3==1.26.2
+werkzeug==1.0.1
+wheel==0.36.2
+wrapt==1.12.1
+xmltodict==0.12.0
+zipp==3.4.0
+
+# The following packages are considered to be unsafe in a requirements file:
+# setuptools
diff --git a/reqs/3.7/requirements-test.txt b/reqs/3.7/requirements-test.txt
new file mode 100644
index 00000000..fa4366b3
--- /dev/null
+++ b/reqs/3.7/requirements-test.txt
@@ -0,0 +1,84 @@
+#
+# This file is autogenerated by pip-compile
+# To update, run:
+#
+#    pip-compile --no-annotate --output-file=reqs/3.7/requirements-test.txt reqs/3.7/requirements-test.in
+#
+absl-py==0.11.0
+amplitf==0.0.1a2
+apipkg==1.5
+astunparse==1.6.3
+attrs==20.3.0
+cachetools==4.2.0
+certifi==2020.12.5
+chardet==4.0.0
+cloudpickle==1.6.0
+coverage==5.3.1
+decorator==4.4.2
+dm-tree==0.1.5
+execnet==1.7.1
+expertsystem==0.6.5
+flatbuffers==1.12
+gast==0.3.3
+google-auth-oauthlib==0.4.2
+google-auth==1.24.0
+google-pasta==0.2.0
+gprof2dot==2019.11.30
+grpcio==1.32.0
+h5py==2.10.0
+hepunits==2.0.1
+idna==2.10
+iminuit==1.5.4
+importlib-metadata==2.1.1
+iniconfig==1.1.1
+jsonschema==3.2.0
+keras-preprocessing==1.1.2
+markdown==3.3.3
+mpmath==1.1.0
+numpy==1.19.4
+oauthlib==3.1.0
+opt-einsum==3.3.0
+packaging==20.8
+pandas==1.2.0
+particle==0.14.0
+phasespace==1.2.0
+pluggy==0.13.1
+protobuf==3.14.0
+py==1.10.0
+pyasn1-modules==0.2.8
+pyasn1==0.4.8
+pydot==1.4.1
+pyparsing==2.4.7
+pyrsistent==0.17.3
+pytest-cov==2.10.1
+pytest-forked==1.3.0
+pytest-profiling==1.7.0
+pytest-xdist==2.2.0
+pytest==6.2.1
+python-constraint==1.4.0
+python-dateutil==2.8.1
+pytz==2020.5
+pyyaml==5.3.1
+requests-oauthlib==1.3.0
+requests==2.25.1
+rsa==4.6
+six==1.15.0
+sympy==1.7.1
+tensorboard-plugin-wit==1.7.0
+tensorboard==2.4.0
+tensorflow-estimator==2.4.0
+tensorflow-probability==0.12.1
+tensorflow==2.4.0
+termcolor==1.1.0
+toml==0.10.2
+tqdm==4.55.1
+typing-extensions==3.7.4.3
+urllib3==1.26.2
+werkzeug==1.0.1
+wheel==0.36.2
+wrapt==1.12.1
+xmltodict==0.12.0
+zipp==3.4.0
+
+# The following packages are considered to be unsafe in a requirements file:
+# setuptools
diff --git a/reqs/3.8/requirements-test.txt b/reqs/3.8/requirements-test.txt
new file mode 100644
index 00000000..4781dddc
--- /dev/null
+++ b/reqs/3.8/requirements-test.txt
@@ -0,0 +1,82 @@
+#
+# This file is autogenerated by pip-compile
+# To update, run:
+#
+#    pip-compile --no-annotate --output-file=reqs/3.8/requirements-test.txt reqs/3.8/requirements-test.in
+#
+absl-py==0.11.0
+amplitf==0.0.1a2
+apipkg==1.5
+astunparse==1.6.3
+attrs==20.3.0
+cachetools==4.2.0
+certifi==2020.12.5
+chardet==4.0.0
+cloudpickle==1.6.0
+coverage==5.3.1
+decorator==4.4.2
+dm-tree==0.1.5
+execnet==1.7.1
+expertsystem==0.6.5
+flatbuffers==1.12
+gast==0.3.3
+google-auth-oauthlib==0.4.2
+google-auth==1.24.0
+google-pasta==0.2.0
+gprof2dot==2019.11.30
+grpcio==1.32.0
+h5py==2.10.0
+hepunits==2.0.1
+idna==2.10
+iminuit==1.5.4
+iniconfig==1.1.1
+jsonschema==3.2.0
+keras-preprocessing==1.1.2
+markdown==3.3.3
+mpmath==1.1.0
+numpy==1.19.4
+oauthlib==3.1.0
+opt-einsum==3.3.0
+packaging==20.8
+pandas==1.2.0
+particle==0.14.0
+phasespace==1.2.0
+pluggy==0.13.1
+protobuf==3.14.0
+py==1.10.0
+pyasn1-modules==0.2.8
+pyasn1==0.4.8
+pydot==1.4.1
+pyparsing==2.4.7
+pyrsistent==0.17.3
+pytest-cov==2.10.1
+pytest-forked==1.3.0
+pytest-profiling==1.7.0
+pytest-xdist==2.2.0
+pytest==6.2.1
+python-constraint==1.4.0
+python-dateutil==2.8.1
+pytz==2020.5
+pyyaml==5.3.1
+requests-oauthlib==1.3.0
+requests==2.25.1
+rsa==4.6
+six==1.15.0
+sympy==1.7.1
+tensorboard-plugin-wit==1.7.0
+tensorboard==2.4.0
+tensorflow-estimator==2.4.0
+tensorflow-probability==0.12.1
+tensorflow==2.4.0
+termcolor==1.1.0
+toml==0.10.2
+tqdm==4.55.1
+typing-extensions==3.7.4.3
+urllib3==1.26.2
+werkzeug==1.0.1
+wheel==0.36.2
+wrapt==1.12.1
+xmltodict==0.12.0
+
+# The following packages are considered to be unsafe in a requirements file:
+# setuptools
diff --git a/reqs/requirements-test.in b/reqs/requirements-test.in
new file mode 100644
index 00000000..0df85b9d
--- /dev/null
+++ b/reqs/requirements-test.in
@@ -0,0 +1,8 @@
+-r requirements.in
+
+# Requirements for running pytest
+pydot
+pytest
+pytest-cov
+pytest-profiling
+pytest-xdist