Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[INFRA] MATLAB test automation #43

Open
wants to merge 30 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
af934b4
Add common tools for MATLAB and Python testing
Remi-Gau Apr 7, 2022
20e6fd9
add smoke tests matlab
Remi-Gau Apr 7, 2022
918091b
add matlab test automation
Remi-Gau Apr 7, 2022
aee01dc
add matlab test demo automation
Remi-Gau Apr 7, 2022
faba452
add expected data and an assert to system test
Remi-Gau Apr 7, 2022
b886a8b
rename test file
Remi-Gau Apr 7, 2022
04508a5
add documentation
Remi-Gau Apr 7, 2022
b9df9f2
lint
Remi-Gau Apr 7, 2022
0eff103
remove unneeded upload coverage artefact from CI workflow
Remi-Gau Apr 7, 2022
3ab086b
run tests matlab demos with CRON job on 1rt and 15th of every month
Remi-Gau Apr 7, 2022
ef3920e
add assert on value of R2
Remi-Gau Apr 7, 2022
8284581
add doc in CI yml and scripts
Remi-Gau Apr 7, 2022
61cfe71
fix typo
Remi-Gau Apr 7, 2022
bd5d8fa
add matlab tests badge to README
Remi-Gau Apr 7, 2022
956da88
add matlab demo badge to README
Remi-Gau Apr 7, 2022
9def9a2
run demos with MOxUnit in CI so that demo2 is run even if demo1 fails
Remi-Gau Apr 8, 2022
c4530c3
force demos to fail to make sure this is picked by CI
Remi-Gau Apr 8, 2022
10161f0
add a check log to try to show workflow as failed
Remi-Gau Apr 8, 2022
f569dd6
remove forced errors in demo and reset to run demos bimonthly
Remi-Gau Apr 8, 2022
26389af
add doc on running tests and demos in CI
Remi-Gau Apr 8, 2022
56807a6
miss_hit lint CI code
Remi-Gau Apr 8, 2022
07da5c3
add miss hit and linting documentation
Remi-Gau Apr 8, 2022
1908552
add pre-commit doc
Remi-Gau Apr 8, 2022
70d205e
update contributors doc
Remi-Gau Apr 8, 2022
731ac95
add doc on generating and chekcing test data
Remi-Gau Apr 8, 2022
a312579
update repo map
Remi-Gau Apr 8, 2022
b35bec6
switch to using png image in doc
Remi-Gau Apr 8, 2022
ca40488
try testing different os and matlab version
Remi-Gau Apr 8, 2022
882cf8e
only run tests on ubuntu latest with matlab 2020a
Remi-Gau Apr 8, 2022
4ae81fd
Update .github/workflows/run_tests_matlab.yaml
Remi-Gau Apr 12, 2022
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
8 changes: 8 additions & 0 deletions .github/workflows/run_demos.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
root_dir = getenv('GITHUB_WORKSPACE');

cd(fullfile(root_dir));

setup();

run matlab/examples/example1;
run matlab/examples/example2;
31 changes: 31 additions & 0 deletions .github/workflows/run_demos_matlab.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: run matlab demos

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

jobs:
demos:
runs-on: ubuntu-20.04

steps:
- name: Install MATLAB
uses: matlab-actions/[email protected]
with:
# MATLAB release to set up R2020a
release: R2020a

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

- name: Run commands
uses: matlab-actions/[email protected]
with:
command:
cd(fullfile(getenv('GITHUB_WORKSPACE'), '.github', 'workflows'));
run run_demos;
56 changes: 56 additions & 0 deletions .github/workflows/run_tests_matlab.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: tests and coverage with matlab

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

jobs:
tests:
runs-on: ubuntu-20.04

steps:
- name: Install MATLAB
uses: matlab-actions/[email protected]
with:
# MATLAB release to set up R2020a
release: R2020a
Remi-Gau marked this conversation as resolved.
Show resolved Hide resolved

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

- name: Install Moxunit and MOcov
run: |
git clone https://github.com/MOxUnit/MOxUnit.git --depth 1
git clone https://github.com/MOcov/MOcov.git --depth 1

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

- name: Run commands
uses: matlab-actions/[email protected]
with:
command: cd(fullfile(getenv('GITHUB_WORKSPACE'), '.github', 'workflows')); run tests_matlab;

- name: Run tests
run: |
cat test_report.log | grep 0
bash <(curl -s https://codecov.io/bash)

- name: Upload coverage
uses: actions/upload-artifact@v1
with:
name: coverage_file
path: coverage.xml

Remi-Gau marked this conversation as resolved.
Show resolved Hide resolved
- name: Code coverage
uses: codecov/codecov-action@v1
with:
file: coverage.xml # optional
flags: matlab # optional
name: codecov-umbrella # optional
fail_ci_if_error: true # optional (default = false)
12 changes: 12 additions & 0 deletions .github/workflows/tests_matlab.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
root_dir = getenv('GITHUB_WORKSPACE');

addpath(fullfile(root_dir, 'MOcov', 'MOcov'));

cd(fullfile(root_dir, 'MOxUnit', 'MOxUnit'));
run moxunit_set_path();

cd(fullfile(root_dir));

setup();

run run_tests();
11 changes: 8 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
#
# vscode files
.vscode/

# test related
tests/outputs/

# data folder
# data folders
data/

# example output folders
Expand All @@ -13,6 +15,9 @@ figures/
report.html
##*.png

# pyenv
Pipfile

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
Expand Down Expand Up @@ -54,6 +59,7 @@ pip-delete-this-directory.txt
htmlcov/
.tox/
.coverage
coverage_html
.coverage.*
.cache
nosetests.xml
Expand Down Expand Up @@ -153,4 +159,3 @@ codegen/

# Octave session info
octave-workspace

7 changes: 7 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# See https://pre-commit.com for more information
# See https://pre-commit.com/hooks.html for more hooks
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.1.0
hooks:
- id: check-yaml
56 changes: 56 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# CONTRIBUTING

Information for anyone who would like to contribute to this repository.

## Repository map

```bash
├── .git
├── .github
│ └── workflows # Github continuous integration set up
├── examples
│ ├── data
│ ├── example1outputs
│ ├── example2outputs
├── glmsingle # Python implementation
│ ├── cod
│ ├── design
│ ├── gmm
│ ├── hrf
│ ├── ols
│ ├── ssq
│ └── utils
├── matlab # Matlab implementation
│ ├── examples
│ ├── fracridge
│ └── utilities
└── tests # Python and Matlab tests
└── data

```

## Generic

### Makefile

### pre-commit

## Matlab

### Style guide

### Tests

#### Demos

### Continuous integration

## Python

### Style guide

### Tests

#### Demos

### Continuous integration
116 changes: 116 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
.DEFAULT_GOAL := help

BROWSER := python -c "$$BROWSER_PYSCRIPT"

# TODO make more general to use the local matlab version
MATLAB = /usr/local/MATLAB/R2017a/bin/matlab
MATLAB_ARG = -nodisplay -nosplash -nodesktop

define BROWSER_PYSCRIPT
import os, webbrowser, sys

from urllib.request import pathname2url

webbrowser.open("file://" + pathname2url(os.path.abspath(sys.argv[1])))
endef
export BROWSER_PYSCRIPT

# determines what "make help" will show
define PRINT_HELP_PYSCRIPT
import re, sys

for line in sys.stdin:
match = re.match(r'^([a-zA-Z_-]+):.*?## (.*)$$', line)
if match:
target, help = match.groups()
print("%-20s %s" % (target, help))
endef
export PRINT_HELP_PYSCRIPT

################################################################################
# GENERIC
.PHONY: help clean clean-test lint install_dev

help:
@python -c "$$PRINT_HELP_PYSCRIPT" < $(MAKEFILE_LIST)
clean: clean-build clean-pyc clean-test ## remove all build, test, coverage artifacts

clean-test: ## remove test and coverage artifacts
rm -rf .tox/
rm -rf .coverage
rm -rf htmlcov/
rm -rf .pytest_cache
rm -rf tests/data
rm -rf test/outputs

install_dev: ## install for both matlab and python developpers
pip install -e .
pip install -r requirements_dev.txt

lint: lint/black lint/flake8 lint/miss_hit ## check style

test: test-matlab test-python

tests/data/nsdcoreexampledataset.mat:
mkdir tests/data
curl -fsSL --retry 5 -o "tests/data/nsdcoreexampledataset.mat" https://osf.io/k89b2/download

################################################################################

################################################################################
# MATLAB

.PHONY: lint/miss_hit

lint/miss_hit: ## lint and checks matlab code
mh_style --fix tests && mh_metric --ci tests && mh_lint tests

test-matlab: tests/data/nsdcoreexampledataset.mat
$(MATLAB) $(MATLAB_ARG) -r "run_tests; exit()"

coverage-matlab: test-matlab
$(BROWSER) coverage_html/index.html

################################################################################

################################################################################
# PYTHON

.PHONY: clean-build clean-pyc coverage-python install lint/flake8 lint/black

clean-build: ## remove build artifacts
rm -fr build/
rm -fr dist/
rm -fr .eggs/
find . -name '*.egg-info' -exec rm -fr {} +
find . -name '*.egg' -exec rm -f {} +

clean-pyc: ## remove Python file artifacts
find . -name '*.pyc' -exec rm -f {} +
find . -name '*.pyo' -exec rm -f {} +
find . -name '*~' -exec rm -f {} +
find . -name '__pycache__' -exec rm -fr {} +

lint/flake8: ## check style with flake8
flake8 tests
lint/black: ## check style with black
black tests

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

test-notebooks:
pytest --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
$(BROWSER) htmlcov/index.html

install: clean ## install the package to the active Python's site-packages
python setup.py install

################################################################################
35 changes: 19 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,20 +33,6 @@ This will also clone [`fracridge`](https://github.com/nrdg/fracridge) as a submo

To use the GLMsingle toolbox, add it and `fracridge` to your MATLAB path by running the `setup.m` script.

## Example scripts

We provide a number of example scripts that demonstrate usage of GLMsingle. You can browse these example scripts here:

(Python Example 1 - event-related design) https://htmlpreview.github.io/?https://github.com/kendrickkay/GLMsingle/blob/main/examples/example1.html

(Python Example 2 - block design) https://htmlpreview.github.io/?https://github.com/kendrickkay/GLMsingle/blob/main/examples/example2.html

(MATLAB Example 1 - event-related design) https://htmlpreview.github.io/?https://github.com/kendrickkay/GLMsingle/blob/main/matlab/examples/example1preview/example1.html

(MATLAB Example 2 - block design) https://htmlpreview.github.io/?https://github.com/kendrickkay/GLMsingle/blob/main/matlab/examples/example2preview/example2.html

If you would like to run these example scripts, the Python versions are available in `/GLMsingle/examples`, and the MATLAB versions are available in `/GLMsingle/matlab/examples`. Each notebook contains a full walkthrough of the process of loading an example dataset and design matrix, estimating neural responses using GLMsingle, estimating the reliability of responses at each voxel, and comparing those achieved via GLMsingle to those achieved using a baseline GLM.

Comment on lines -36 to -49
Copy link
Contributor Author

Choose a reason for hiding this comment

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

FYI Reordered the README to have all the install instructions first for MATLAB and Python and then the examples. Can change it back.

## Python

To install:
Expand All @@ -63,12 +49,25 @@ Running the demos requires:
pip install jupyterlab
```

Code dependencies: see requirements.txt
Code dependencies: see [requirements.txt](./requirements.txt)

Notes:
* Please note that GLMsingle is not (yet) compatible with Python 3.9 (due to an incompatibility between scikit-learn and Python 3.9). Please use Python 3.8 or earlier.
* Currently, numpy has a 4GB limit for the pickle files it writes; thus, GLMsingle will crash if the file outputs exceed that size. One workaround is to turn off "disk saving" and instead get the outputs of GLMsingle in your workspace and save the outputs yourself to HDF5 format.

## Example scripts

We provide a number of example scripts that demonstrate usage of GLMsingle. You can browse these example scripts here:

(Python Example 1 - event-related design) https://htmlpreview.github.io/?https://github.com/kendrickkay/GLMsingle/blob/main/examples/example1.html

(Python Example 2 - block design) https://htmlpreview.github.io/?https://github.com/kendrickkay/GLMsingle/blob/main/examples/example2.html

(MATLAB Example 1 - event-related design) https://htmlpreview.github.io/?https://github.com/kendrickkay/GLMsingle/blob/main/matlab/examples/example1preview/example1.html

(MATLAB Example 2 - block design) https://htmlpreview.github.io/?https://github.com/kendrickkay/GLMsingle/blob/main/matlab/examples/example2preview/example2.html

If you would like to run these example scripts, the Python versions are available in `/GLMsingle/examples`, and the MATLAB versions are available in `/GLMsingle/matlab/examples`. Each notebook contains a full walkthrough of the process of loading an example dataset and design matrix, estimating neural responses using GLMsingle, estimating the reliability of responses at each voxel, and comparing those achieved via GLMsingle to those achieved using a baseline GLM.

## Additional information

For additional information, please visit the Wiki page associated with this
Expand All @@ -80,6 +79,10 @@ If you use GLMsingle in your research, please cite the following paper:

* [Prince, J.S., Charest, I., Kurzawski, J.W., Pyles, J.A., Tarr, M.J., Kay, K.N. GLMsingle: a toolbox for improving single-trial fMRI response estimates. bioRxiv (2022).](https://www.biorxiv.org/content/10.1101/2022.01.31.478431v1)

## Contributing

If you want to contribute to GLMsingle see the [contributing](./CONTRIBUTING.md) documentation to help you know what is where and how to set things up.

## Change history

* 2021/10/12 - Version 1.0 of GLMsingle is now released. A git tag has been added to the repo.
Expand Down
Loading