Skip to content
Open
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions .github/workflows/run_demos_python.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
name: Python demos

# Uses the cron schedule for github actions
#
# will run at 00H00 run on the 1 and 15 of every month
#
# https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows#scheduled-events
#
# ┌───────────── minute (0 - 59)
# │ ┌───────────── hour (0 - 23)
# │ │ ┌───────────── day of the month (1 - 31)
# │ │ │ ┌───────────── month (1 - 12 or JAN-DEC): * means all
# │ │ │ │ ┌───────────── day of the week (0 - 6 or SUN-SAT): * means all
# │ │ │ │ │
# │ │ │ │ │
# │ │ │ │ │
#
# - cron "0 0 1,15 * *"

on:
schedule:
- cron: "0 0 1,15 * *"

push:
branches: ["*"]

jobs:
demos:
continue-on-error: true
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest]
python-version: ["3.9"]

steps:
- name: Shallow clone GLMsingle
uses: actions/checkout@v3
with:
submodules: "recursive"
fetch-depth: 0

- 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 setuptools
pip install .
pip install -r requirements_dev.txt

- name: Display Python version and packages
run: |
python -c "import sys; print(sys.version)"
pip list

- name: Run notebooks
run: pytest --nbmake --nbmake-timeout=3000 "./examples"
54 changes: 54 additions & 0 deletions .github/workflows/run_tests_python.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: Python tests

on:
push:
branches: ["*"]
pull_request:
branches: ["*"]

jobs:
tests:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macOS-latest, windows-latest]
python-version: ["3.7", "3.8", "3.9"] # fails on 3.10
fail-fast: true # cancel all jobs if one fails

steps:
- name: Shallow clone GLMsingle
uses: actions/checkout@v3
with:
submodules: "recursive"
fetch-depth: 0

- 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 setuptools
pip install .
pip install -r requirements_dev.txt

- name: Display Python version and packages
run: |
python -c "import sys; print(sys.version)"
pip list

- name: Prepare data
run: make tests/data/nsdcoreexampledataset.mat

- name: Run tests and generate coverage report
run: pytest -v --cov glmsingle --cov-report xml tests

- name: Upload coverage to Codecov
uses: codecov/codecov-action@v1
with:
file: ./coverage.xml
flags: python
name: codecov-umbrella
fail_ci_if_error: true
verbose: true
62 changes: 57 additions & 5 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Information for anyone who would like to contribute to this repository.
├── .git
├── .github
│ └── workflows # Github continuous integration set up
├── examples
├── examples # Python demos: jupyter notebooks
│ ├── data
│ ├── example1outputs
│ ├── example2outputs
Expand All @@ -20,11 +20,11 @@ Information for anyone who would like to contribute to this repository.
│ ├── ols
│ ├── ssq
│ └── utils
├── matlab # Matlab implementation
│ ├── examples
├── matlab # MATLAB implementation
│ ├── examples # MATLAB demos
│ ├── fracridge
│ └── utilities
└── tests # Python and Matlab tests
└── tests # Python and MATLAB tests
└── data

```
Expand All @@ -47,10 +47,62 @@ Information for anyone who would like to contribute to this repository.

## Python

All the packages required to help with the python development of GLMsingle can
be installed with:

```bash
pip install -r requirements_dev.txt
```

### Style guide

[black](https://black.readthedocs.io/en/stable/) (code formater) and
[flake8](https://flake8.pycqa.org/en/latest/) (style guide enforcement) are used
on the test code base.

Ypu can use make to run them automatically with

```bash
make lint/black # to run black
make lint/flake8 # to run flake8
make lint # to run both
```
Comment on lines +59 to +69
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some of those are for code styling, so it does not have to be done manually. Only applies to the test code base.

Can remove it if you want.


### Tests

The tests can be run with with pytest via the make command:

```bash
make test-python
```

#### Demos

### Continuous integration
The jupyter notebook are tested with the
[`nbmake` plugin for pytest](https://pypi.org/project/nbmake/).

They can be run with the make command:

```bash
make test-notebooks
```

### Continuous integration

We use Github to run several workflows for continuous integration.

#### Tests

The python tests are run by the workflow:
`.github/workflows/run_tests_python.yaml`.

Those tests should be run with every push on the `master` branch and on pull
request that target the `master` branch.

#### Demos

The demos in the `examples` folder are run automatically in Github CI at regular
intervals.

The jupyter notebooks are run by the workflow
`.github/workflows/run_demos_python.yaml`.
8 changes: 3 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -97,17 +97,15 @@ lint/black: ## check style with black
black tests

test-python: tests/data/nsdcoreexampledataset.mat ## run tests quickly with the default Python
pytest
pytest -vv

test-notebooks:
pytest --nbmake --nbmake-timeout=3000 "./examples"
pytest -vv --nbmake --nbmake-timeout=3000 "./examples"
test-all: ## run tests on every Python version with tox
tox

coverage-python: ## check code coverage quickly with the default Python
coverage run --source glmsingle -m pytest
coverage report -m
coverage html
pytest -vv --cov glmsingle --cov-report html:htmlcov
$(BROWSER) htmlcov/index.html

install: clean ## install the package to the active Python's site-packages
Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@


[![Python tests](https://github.com/cvnlab/GLMsingle/actions/workflows/run_tests_python.yml/badge.svg)](https://github.com/cvnlab/GLMsingle/actions/workflows/run_tests_python.yml)
[![Python demos](https://github.com/cvnlab/GLMsingle/actions/workflows/run_demos_python.yml/badge.svg)](https://github.com/cvnlab/GLMsingle/actions/workflows/run_demos_python.yml)
[![Python-coverage](https://codecov.io/gh/Remi-Gau/GLMsingle/branch/main/graph/badge.svg?token=H75TAAUVSW)](https://codecov.io/gh/Remi-Gau/GLMsingle)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code coverage is not yet uploaded and so this might require some tweaking after merging:

  • setting up an account for cvnlab on codecov (can simply link the github account)
  • changing the URL of this badge

But once set up you can know how pull request change the code coverage: like this
Remi-Gau#3 (comment)

# GLMsingle

![image](https://user-images.githubusercontent.com/35503086/151108958-24479034-c7f7-4734-b903-9046ba6a78ac.png)
Expand Down
4 changes: 3 additions & 1 deletion examples/example1.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,9 @@
"\n",
"# note: the fracridge repository is also necessary to run this code\n",
"# for example, you could do:\n",
"# git clone https://github.com/nrdg/fracridge.git"
"# git clone https://github.com/nrdg/fracridge.git\n",
"\n",
"raise NameError('test')"
]
},
{
Expand Down
16 changes: 8 additions & 8 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
numpy
scipy
sklearn
matplotlib
tqdm
fracridge
nibabel
h5py
fracridge>=1.4.3
h5py>=3.1.0
matplotlib>=3.3.4
nibabel>=3.2.2
numpy>=1.17.0
scikit-learn>=0.23.2
scipy>=1.5.4
tqdm>=4.63.1
Comment on lines +1 to +8
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have pinned the dependency minimum version for GLMsingle to be those that were installed by default when using python 3.6.

10 changes: 6 additions & 4 deletions requirements_dev.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
# Base requirements
-r requirements.txt

# Matlab dev
miss_hit

# Python dev
black
flake8
tox
coverage
pytest
black
nbmake
pytest-cov
nbmake
tox
18 changes: 18 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[flake8]
max-line-length = 99

ignore = D203, W503

exclude =
.git,
docs,
__pycache__,
old,
build,
dist
'matlab/fracridge'

max-complexity = 10

[tool:pytest]
testpaths = tests
5 changes: 3 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

setup(
name='GLMsingle',
version='0.0.1',
version='1.0.0',
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To match what the README and the github tag say

description='Python GLMsingle',
url='https://github.com/kendrickkay/GLMsingle',
long_description=long_description,
Expand All @@ -28,5 +28,6 @@
packages=find_packages(),
include_package_data=True,
zip_safe=False,
install_requires=requires
install_requires=requires,
python_requires='>=3.6, <3.10'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Specifying which python version to use

)
1 change: 1 addition & 0 deletions tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Unit test package for glmsingle."""
52 changes: 52 additions & 0 deletions tests/expected/python/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Generate expected data

Generated from the output of one run from the files in `tests/outputs/python`

```python
import numpy as np

tmp = np.load("TYPEB_FITHRF.npy", allow_pickle=True)
results = tmp.item(0)["HRFindex"]
np.save("TYPEB_FITHRF_HRFindex.npy", results)

tmp = np.load("TYPEC_FITHRF_GLMDENOISE.npy", allow_pickle=True)
results = tmp.item(0)["HRFindex"]
np.save("TYPEC_FITHRF_HRFindex.npy", results)

tmp = np.load("TYPED_FITHRF_GLMDENOISE_RR.npy", allow_pickle=True)
results = tmp.item(0)["HRFindex"]
np.save("TYPED_FITHRF_HRFindex.npy", results)

results = tmp.item(0)["R2"]
np.save("TYPED_FITHRF_R2.npy", results)
```

<!-- TODO ?
## For CSV

```python
import numpy as np

tmp = np.load("TYPEB_FITHRF.npy", allow_pickle=True)
results = tmp.item(0)["HRFindex"]
results = results.squeeze();
np.savetxt("TYPEB_FITHRF_HRFindex.csv", results, delimiter=",", fmt="%i")

tmp = np.load("TYPEC_FITHRF_GLMDENOISE.npy", allow_pickle=True)
results = tmp.item(0)["HRFindex"]
results = results.squeeze();
np.savetxt("TYPEC_FITHRF_HRFindex.csv", results, delimiter=",", fmt="%i")

tmp = np.load("TYPED_FITHRF_GLMDENOISE_RR.npy", allow_pickle=True)
results = tmp.item(0)["HRFindex"]
results = results.squeeze();
np.savetxt("TYPED_FITHRF_HRFindex.csv", results, delimiter=",", fmt="%i")
```

Read from csv

```python
from numpy import genfromtxt

my_data = genfromtxt('TYPEB_FITHRF_HRFindex.csv', delimiter=',')
``` -->
Binary file added tests/expected/python/TYPEB_FITHRF_HRFindex.npy
Binary file not shown.
Binary file added tests/expected/python/TYPEC_FITHRF_HRFindex.npy
Binary file not shown.
Binary file added tests/expected/python/TYPED_FITHRF_HRFindex.npy
Binary file not shown.
Binary file added tests/expected/python/TYPED_FITHRF_R2.npy
Binary file not shown.
Loading