pydra-compose-bidsapp 0.1.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pydra_compose_bidsapp-0.1.1/.DS_Store +0 -0
- pydra_compose_bidsapp-0.1.1/.coveragerc +4 -0
- pydra_compose_bidsapp-0.1.1/.flake8 +15 -0
- pydra_compose_bidsapp-0.1.1/.github/workflows/ci-cd.yaml +85 -0
- pydra_compose_bidsapp-0.1.1/.gitignore +144 -0
- pydra_compose_bidsapp-0.1.1/.pre-commit-config.yaml +14 -0
- pydra_compose_bidsapp-0.1.1/LICENSE +13 -0
- pydra_compose_bidsapp-0.1.1/PKG-INFO +69 -0
- pydra_compose_bidsapp-0.1.1/README.md +17 -0
- pydra_compose_bidsapp-0.1.1/codecov.yml +12 -0
- pydra_compose_bidsapp-0.1.1/conftest.py +221 -0
- pydra_compose_bidsapp-0.1.1/docs/Makefile +20 -0
- pydra_compose_bidsapp-0.1.1/docs/conf.py +51 -0
- pydra_compose_bidsapp-0.1.1/docs/index.rst +15 -0
- pydra_compose_bidsapp-0.1.1/docs/make.bat +35 -0
- pydra_compose_bidsapp-0.1.1/pydra/.DS_Store +0 -0
- pydra_compose_bidsapp-0.1.1/pydra/compose/.DS_Store +0 -0
- pydra_compose_bidsapp-0.1.1/pydra/compose/bidsapp/__init__.py +20 -0
- pydra_compose_bidsapp-0.1.1/pydra/compose/bidsapp/_version.py +21 -0
- pydra_compose_bidsapp-0.1.1/pydra/compose/bidsapp/app.py +53 -0
- pydra_compose_bidsapp-0.1.1/pydra/compose/bidsapp/builder.py +199 -0
- pydra_compose_bidsapp-0.1.1/pydra/compose/bidsapp/fields.py +88 -0
- pydra_compose_bidsapp-0.1.1/pydra/compose/bidsapp/task.py +169 -0
- pydra_compose_bidsapp-0.1.1/pydra/compose/bidsapp/tests/test_bids_app.py +91 -0
- pydra_compose_bidsapp-0.1.1/pyproject.toml +77 -0
- pydra_compose_bidsapp-0.1.1/test-data/.DS_Store +0 -0
- pydra_compose_bidsapp-0.1.1/test-data/nifti/anat/T1w.json +69 -0
- pydra_compose_bidsapp-0.1.1/test-data/nifti/anat/T1w.nii.gz +0 -0
- pydra_compose_bidsapp-0.1.1/test-data/nifti/anat/T2w.json +71 -0
- pydra_compose_bidsapp-0.1.1/test-data/nifti/anat/T2w.nii.gz +0 -0
- pydra_compose_bidsapp-0.1.1/test-data/nifti/anat/T2w_mask.nii.gz +0 -0
- pydra_compose_bidsapp-0.1.1/test-data/nifti/dwi/dwi.bval +1 -0
- pydra_compose_bidsapp-0.1.1/test-data/nifti/dwi/dwi.bvec +3 -0
- pydra_compose_bidsapp-0.1.1/test-data/nifti/dwi/dwi.json +137 -0
- pydra_compose_bidsapp-0.1.1/test-data/nifti/dwi/dwi.nii.gz +0 -0
- pydra_compose_bidsapp-0.1.1/test-data/nifti/func/bold.json +101 -0
- pydra_compose_bidsapp-0.1.1/test-data/nifti/func/bold.nii.gz +0 -0
- pydra_compose_bidsapp-0.1.1/test-data/nifti/func/bold_ref.nii.gz +0 -0
|
Binary file
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
|
|
2
|
+
[flake8]
|
|
3
|
+
doctests = True
|
|
4
|
+
exclude =
|
|
5
|
+
**/__init__.py
|
|
6
|
+
*build/
|
|
7
|
+
docs/sphinxext/
|
|
8
|
+
docs/tools/
|
|
9
|
+
docs/conf.py
|
|
10
|
+
docs/source/conf.py
|
|
11
|
+
max-line-length = 88
|
|
12
|
+
select = C,E,F,W,B,B950
|
|
13
|
+
extend-ignore = E203,E501,E129,W503
|
|
14
|
+
per-file-ignores =
|
|
15
|
+
__init__.py:F401,F403
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
#This workflow will install Python dependencies, run tests and lint with a variety of Python versions
|
|
2
|
+
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
|
|
3
|
+
|
|
4
|
+
# For deployment, it will be necessary to create a PyPI API token and store it as a secret
|
|
5
|
+
# https://docs.github.com/en/actions/reference/encrypted-secrets
|
|
6
|
+
|
|
7
|
+
name: CI/CD
|
|
8
|
+
|
|
9
|
+
on:
|
|
10
|
+
push:
|
|
11
|
+
branches: [ main, develop ]
|
|
12
|
+
tags: [ '*' ]
|
|
13
|
+
pull_request:
|
|
14
|
+
branches: [ main, develop ]
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
|
|
18
|
+
test:
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
strategy:
|
|
21
|
+
matrix:
|
|
22
|
+
python-version: ['3.11', '3.12', '3.13']
|
|
23
|
+
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@v4
|
|
26
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
27
|
+
uses: actions/setup-python@v5
|
|
28
|
+
with:
|
|
29
|
+
python-version: ${{ matrix.python-version }}
|
|
30
|
+
- name: Install build dependencies
|
|
31
|
+
run: |
|
|
32
|
+
python -m pip install --upgrade pip
|
|
33
|
+
- name: Install task package
|
|
34
|
+
run: |
|
|
35
|
+
pip install ".[test]"
|
|
36
|
+
python -c "import pydra.compose.bidsapp as m; print(f'{m.__name__} {m.__version__} @ {m.__file__}')"
|
|
37
|
+
- name: Test with pytest
|
|
38
|
+
run: |
|
|
39
|
+
pytest -sv --doctest-modules pydra/compose/bidsapp \
|
|
40
|
+
--cov pydra.compose.bidsapp --cov-report xml
|
|
41
|
+
- uses: codecov/codecov-action@v3
|
|
42
|
+
if: ${{ always() }}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
deploy:
|
|
46
|
+
needs: [test]
|
|
47
|
+
runs-on: ubuntu-latest
|
|
48
|
+
strategy:
|
|
49
|
+
matrix:
|
|
50
|
+
python-version: [3.9]
|
|
51
|
+
steps:
|
|
52
|
+
- uses: actions/checkout@v4
|
|
53
|
+
with:
|
|
54
|
+
submodules: recursive
|
|
55
|
+
fetch-depth: 0
|
|
56
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
57
|
+
uses: actions/setup-python@v5
|
|
58
|
+
with:
|
|
59
|
+
python-version: ${{ matrix.python-version }}
|
|
60
|
+
- name: Install build tools
|
|
61
|
+
run: python -m pip install build twine
|
|
62
|
+
- name: Build source and wheel distributions
|
|
63
|
+
run: python -m build
|
|
64
|
+
- name: Check distributions
|
|
65
|
+
run: twine check dist/*
|
|
66
|
+
- uses: actions/upload-artifact@v4
|
|
67
|
+
with:
|
|
68
|
+
name: distributions
|
|
69
|
+
path: dist/
|
|
70
|
+
# Deploy on tags if PYPI_API_TOKEN is defined in the repository secrets.
|
|
71
|
+
# Secrets are not accessible in the if: condition [0], so set an output variable [1]
|
|
72
|
+
# [0] https://github.community/t/16928
|
|
73
|
+
# [1] https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-output-parameter
|
|
74
|
+
- name: Check for PyPI token on tag
|
|
75
|
+
id: deployable
|
|
76
|
+
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')
|
|
77
|
+
env:
|
|
78
|
+
PYPI_API_TOKEN: "${{ secrets.PYPI_API_TOKEN }}"
|
|
79
|
+
run: if [ -n "$PYPI_API_TOKEN" ]; then echo "DEPLOY=true" >> $GITHUB_OUTPUT; fi
|
|
80
|
+
- name: Upload to PyPI
|
|
81
|
+
if: steps.deployable.outputs.DEPLOY
|
|
82
|
+
uses: pypa/gh-action-pypi-publish@37f50c210e3d2f9450da2cd423303d6a14a6e29f # v1.5.1
|
|
83
|
+
with:
|
|
84
|
+
user: __token__
|
|
85
|
+
password: ${{ secrets.PYPI_API_TOKEN }}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
|
|
6
|
+
# C extensions
|
|
7
|
+
*.so
|
|
8
|
+
|
|
9
|
+
# Distribution / packaging
|
|
10
|
+
.Python
|
|
11
|
+
build/
|
|
12
|
+
develop-eggs/
|
|
13
|
+
dist/
|
|
14
|
+
downloads/
|
|
15
|
+
eggs/
|
|
16
|
+
.eggs/
|
|
17
|
+
lib/
|
|
18
|
+
lib64/
|
|
19
|
+
parts/
|
|
20
|
+
sdist/
|
|
21
|
+
var/
|
|
22
|
+
wheels/
|
|
23
|
+
pip-wheel-metadata/
|
|
24
|
+
share/python-wheels/
|
|
25
|
+
*.egg-info/
|
|
26
|
+
.installed.cfg
|
|
27
|
+
*.egg
|
|
28
|
+
MANIFEST
|
|
29
|
+
|
|
30
|
+
# PyInstaller
|
|
31
|
+
# Usually these files are written by a python script from a template
|
|
32
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
|
33
|
+
*.manifest
|
|
34
|
+
*.spec
|
|
35
|
+
|
|
36
|
+
# Installer logs
|
|
37
|
+
pip-log.txt
|
|
38
|
+
pip-delete-this-directory.txt
|
|
39
|
+
|
|
40
|
+
# Unit test / coverage reports
|
|
41
|
+
htmlcov/
|
|
42
|
+
.tox/
|
|
43
|
+
.nox/
|
|
44
|
+
.coverage
|
|
45
|
+
.coverage.*
|
|
46
|
+
.cache
|
|
47
|
+
nosetests.xml
|
|
48
|
+
coverage.xml
|
|
49
|
+
*.cover
|
|
50
|
+
*.py,cover
|
|
51
|
+
.hypothesis/
|
|
52
|
+
.pytest_cache/
|
|
53
|
+
|
|
54
|
+
# Translations
|
|
55
|
+
*.mo
|
|
56
|
+
*.pot
|
|
57
|
+
|
|
58
|
+
# Django stuff:
|
|
59
|
+
*.log
|
|
60
|
+
local_settings.py
|
|
61
|
+
db.sqlite3
|
|
62
|
+
db.sqlite3-journal
|
|
63
|
+
|
|
64
|
+
# Flask stuff:
|
|
65
|
+
instance/
|
|
66
|
+
.webassets-cache
|
|
67
|
+
|
|
68
|
+
# Scrapy stuff:
|
|
69
|
+
.scrapy
|
|
70
|
+
|
|
71
|
+
# Sphinx documentation
|
|
72
|
+
docs/_build/
|
|
73
|
+
|
|
74
|
+
# PyBuilder
|
|
75
|
+
target/
|
|
76
|
+
|
|
77
|
+
# Jupyter Notebook
|
|
78
|
+
.ipynb_checkpoints
|
|
79
|
+
|
|
80
|
+
# IPython
|
|
81
|
+
profile_default/
|
|
82
|
+
ipython_config.py
|
|
83
|
+
|
|
84
|
+
# pyenv
|
|
85
|
+
.python-version
|
|
86
|
+
|
|
87
|
+
# pipenv
|
|
88
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
|
89
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
|
90
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
|
91
|
+
# install all needed dependencies.
|
|
92
|
+
#Pipfile.lock
|
|
93
|
+
|
|
94
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
|
|
95
|
+
__pypackages__/
|
|
96
|
+
|
|
97
|
+
# Celery stuff
|
|
98
|
+
celerybeat-schedule
|
|
99
|
+
celerybeat.pid
|
|
100
|
+
|
|
101
|
+
# SageMath parsed files
|
|
102
|
+
*.sage.py
|
|
103
|
+
|
|
104
|
+
# Environments
|
|
105
|
+
.env
|
|
106
|
+
.venv
|
|
107
|
+
env/
|
|
108
|
+
venv/
|
|
109
|
+
ENV/
|
|
110
|
+
env.bak/
|
|
111
|
+
venv.bak/
|
|
112
|
+
|
|
113
|
+
# Spyder project settings
|
|
114
|
+
.spyderproject
|
|
115
|
+
.spyproject
|
|
116
|
+
|
|
117
|
+
# Rope project settings
|
|
118
|
+
.ropeproject
|
|
119
|
+
|
|
120
|
+
# mkdocs documentation
|
|
121
|
+
/site
|
|
122
|
+
|
|
123
|
+
# mypy
|
|
124
|
+
.mypy_cache/
|
|
125
|
+
.dmypy.json
|
|
126
|
+
dmypy.json
|
|
127
|
+
|
|
128
|
+
# Pyre type checker
|
|
129
|
+
.pyre/
|
|
130
|
+
|
|
131
|
+
# Pycharm
|
|
132
|
+
.idea
|
|
133
|
+
|
|
134
|
+
# Vim
|
|
135
|
+
.*.sw[op]
|
|
136
|
+
|
|
137
|
+
# VS Code
|
|
138
|
+
.vscode
|
|
139
|
+
|
|
140
|
+
# Mac garbarge
|
|
141
|
+
.DS_store
|
|
142
|
+
|
|
143
|
+
# Generated files
|
|
144
|
+
/pydra/compose/bidsapp/_version.py
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# See https://pre-commit.com for more information
|
|
2
|
+
# See https://pre-commit.com/hooks.html for more hooks
|
|
3
|
+
repos:
|
|
4
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
5
|
+
rev: v4.4.0
|
|
6
|
+
hooks:
|
|
7
|
+
- id: trailing-whitespace
|
|
8
|
+
- id: end-of-file-fixer
|
|
9
|
+
- id: check-yaml
|
|
10
|
+
- id: check-added-large-files
|
|
11
|
+
- repo: https://github.com/psf/black
|
|
12
|
+
rev: 22.12.0
|
|
13
|
+
hooks:
|
|
14
|
+
- id: black
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Copyright 2021 Nipype developers
|
|
2
|
+
|
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
you may not use this file except in compliance with the License.
|
|
5
|
+
You may obtain a copy of the License at
|
|
6
|
+
|
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
|
|
9
|
+
Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
See the License for the specific language governing permissions and
|
|
13
|
+
limitations under the License.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: pydra-compose-bidsapp
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: Pydra compose package for wrapping BIDS Apps in Pydra tasks
|
|
5
|
+
Author-email: "Thomas G. Close" <tom.g.close@gmail.com>
|
|
6
|
+
Maintainer-email: "Thomas G. Close" <tom.g.close@gmail.com>
|
|
7
|
+
License: Copyright 2021 Nipype developers
|
|
8
|
+
|
|
9
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
10
|
+
you may not use this file except in compliance with the License.
|
|
11
|
+
You may obtain a copy of the License at
|
|
12
|
+
|
|
13
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
14
|
+
|
|
15
|
+
Unless required by applicable law or agreed to in writing, software
|
|
16
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
17
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
18
|
+
See the License for the specific language governing permissions and
|
|
19
|
+
limitations under the License.
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Keywords: pydra
|
|
22
|
+
Classifier: Development Status :: 2 - Pre-Alpha
|
|
23
|
+
Classifier: Environment :: Console
|
|
24
|
+
Classifier: Intended Audience :: Science/Research
|
|
25
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
26
|
+
Classifier: Operating System :: MacOS :: MacOS X
|
|
27
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
28
|
+
Classifier: Programming Language :: Python :: 3
|
|
29
|
+
Classifier: Topic :: Scientific/Engineering
|
|
30
|
+
Requires-Python: >=3.11
|
|
31
|
+
Requires-Dist: docker>=7.0.0
|
|
32
|
+
Requires-Dist: frametree-bids
|
|
33
|
+
Requires-Dist: pydra>=1.0a
|
|
34
|
+
Provides-Extra: dev
|
|
35
|
+
Requires-Dist: black; extra == 'dev'
|
|
36
|
+
Requires-Dist: pre-commit; extra == 'dev'
|
|
37
|
+
Provides-Extra: doc
|
|
38
|
+
Requires-Dist: packaging; extra == 'doc'
|
|
39
|
+
Requires-Dist: sphinx-rtd-theme; extra == 'doc'
|
|
40
|
+
Requires-Dist: sphinx>=2.1.2; extra == 'doc'
|
|
41
|
+
Requires-Dist: sphinxcontrib-apidoc~=0.3.0; extra == 'doc'
|
|
42
|
+
Requires-Dist: sphinxcontrib-napoleon; extra == 'doc'
|
|
43
|
+
Requires-Dist: sphinxcontrib-versioning; extra == 'doc'
|
|
44
|
+
Provides-Extra: test
|
|
45
|
+
Requires-Dist: codecov; extra == 'test'
|
|
46
|
+
Requires-Dist: pytest-cov; extra == 'test'
|
|
47
|
+
Requires-Dist: pytest-env; extra == 'test'
|
|
48
|
+
Requires-Dist: pytest-rerunfailures; extra == 'test'
|
|
49
|
+
Requires-Dist: pytest-xdist; extra == 'test'
|
|
50
|
+
Requires-Dist: pytest>=4.4.0; extra == 'test'
|
|
51
|
+
Description-Content-Type: text/markdown
|
|
52
|
+
|
|
53
|
+
# Pydra-compose-bidsapp plugin
|
|
54
|
+
|
|
55
|
+
Pydra-compose-bidsapp is a plugin package for the [Pydra dataflow engine](https://nipype.github.io/pydra),
|
|
56
|
+
which adds the feature to wrap up [BIDS Apps](https://bids-apps.neuroimaging.io/) into
|
|
57
|
+
Pydra task classes that take input files, stores them in a BIDS dataset created on the
|
|
58
|
+
fly, runs the BIDS App on them, then extracts the files into the tasks outputs. It can
|
|
59
|
+
be useful when running BIDS app on non-BIDS structured data (e.g. XNAT or LORIS repositories).
|
|
60
|
+
|
|
61
|
+
## For developers
|
|
62
|
+
|
|
63
|
+
Install repo in developer mode from the source directory. It is also useful to
|
|
64
|
+
install pre-commit to take care of styling via [black](https://black.readthedocs.io/):
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
python3 -m pip install -e '.[dev]'
|
|
68
|
+
pre-commit install
|
|
69
|
+
```
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Pydra-compose-bidsapp plugin
|
|
2
|
+
|
|
3
|
+
Pydra-compose-bidsapp is a plugin package for the [Pydra dataflow engine](https://nipype.github.io/pydra),
|
|
4
|
+
which adds the feature to wrap up [BIDS Apps](https://bids-apps.neuroimaging.io/) into
|
|
5
|
+
Pydra task classes that take input files, stores them in a BIDS dataset created on the
|
|
6
|
+
fly, runs the BIDS App on them, then extracts the files into the tasks outputs. It can
|
|
7
|
+
be useful when running BIDS app on non-BIDS structured data (e.g. XNAT or LORIS repositories).
|
|
8
|
+
|
|
9
|
+
## For developers
|
|
10
|
+
|
|
11
|
+
Install repo in developer mode from the source directory. It is also useful to
|
|
12
|
+
install pre-commit to take care of styling via [black](https://black.readthedocs.io/):
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
python3 -m pip install -e '.[dev]'
|
|
16
|
+
pre-commit install
|
|
17
|
+
```
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import pytest
|
|
3
|
+
import requests
|
|
4
|
+
from warnings import warn
|
|
5
|
+
import typing as ty
|
|
6
|
+
from tempfile import mkdtemp
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
import docker
|
|
9
|
+
from fileformats.medimage import NiftiGzX
|
|
10
|
+
|
|
11
|
+
PKG_DIR = Path(__file__).parent
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@pytest.fixture(scope="session")
|
|
15
|
+
def build_cache_dir() -> Path:
|
|
16
|
+
# build_cache_dir = Path.home() / '.frametree-test-build-cache'
|
|
17
|
+
# if build_cache_dir.exists():
|
|
18
|
+
# shutil.rmtree(build_cache_dir)
|
|
19
|
+
# build_cache_dir.mkdir()
|
|
20
|
+
return Path(mkdtemp())
|
|
21
|
+
# return build_cache_dir
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@pytest.fixture
|
|
25
|
+
def work_dir() -> Path: # type: ignore[misc]
|
|
26
|
+
# work_dir = Path.home() / '.frametree-tests'
|
|
27
|
+
# work_dir.mkdir(exist_ok=True)
|
|
28
|
+
# return work_dir
|
|
29
|
+
work_dir = mkdtemp()
|
|
30
|
+
yield Path(work_dir)
|
|
31
|
+
# shutil.rmtree(work_dir)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@pytest.fixture(scope="session")
|
|
35
|
+
def pkg_dir() -> Path:
|
|
36
|
+
return PKG_DIR
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
@pytest.fixture(scope="session")
|
|
40
|
+
def nifti_sample_dir(pkg_dir):
|
|
41
|
+
return pkg_dir / "test-data" / "nifti"
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
# FIXME: should be converted to python script to be Windows compatible
|
|
45
|
+
@pytest.fixture(scope="session")
|
|
46
|
+
def mock_bids_app_script():
|
|
47
|
+
file_tests = ""
|
|
48
|
+
for inpt_path, datatype in [
|
|
49
|
+
("anat/T1w", NiftiGzX),
|
|
50
|
+
("anat/T2w", NiftiGzX),
|
|
51
|
+
("dwi/dwi", NiftiGzX),
|
|
52
|
+
]:
|
|
53
|
+
subdir, suffix = inpt_path.split("/")
|
|
54
|
+
fpath = (
|
|
55
|
+
f"$BIDS_DATASET/sub-${{SUBJ_ID}}/{subdir}/"
|
|
56
|
+
f"sub-${{SUBJ_ID}}_{suffix}{datatype.ext}"
|
|
57
|
+
)
|
|
58
|
+
file_tests += f"""
|
|
59
|
+
if [ ! -f {fpath} ]; then
|
|
60
|
+
echo "Did not find {suffix} file at {fpath}"
|
|
61
|
+
exit 1;
|
|
62
|
+
fi
|
|
63
|
+
"""
|
|
64
|
+
|
|
65
|
+
return f"""#!/bin/sh
|
|
66
|
+
BIDS_DATASET=$1
|
|
67
|
+
OUTPUTS_DIR=$2
|
|
68
|
+
SUBJ_ID=$5
|
|
69
|
+
{file_tests}
|
|
70
|
+
# Write mock output files to 'derivatives' Directory
|
|
71
|
+
mkdir -p $OUTPUTS_DIR
|
|
72
|
+
echo 'file1' > $OUTPUTS_DIR/sub-${{SUBJ_ID}}_file1.txt
|
|
73
|
+
echo 'file2' > $OUTPUTS_DIR/sub-${{SUBJ_ID}}_file2.txt
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
# For debugging in IDE's don't catch raised exceptions and let the IDE
|
|
78
|
+
# break at it
|
|
79
|
+
if os.getenv("_PYTEST_RAISE", "0") != "0":
|
|
80
|
+
|
|
81
|
+
@pytest.hookimpl(tryfirst=True)
|
|
82
|
+
def pytest_exception_interact(call: pytest.CallInfo[ty.Any]) -> None:
|
|
83
|
+
if call.excinfo is not None:
|
|
84
|
+
raise call.excinfo.value
|
|
85
|
+
|
|
86
|
+
@pytest.hookimpl(tryfirst=True)
|
|
87
|
+
def pytest_internalerror(excinfo: pytest.ExceptionInfo[BaseException]) -> None:
|
|
88
|
+
raise excinfo.value
|
|
89
|
+
|
|
90
|
+
CATCH_CLI_EXCEPTIONS = False
|
|
91
|
+
else:
|
|
92
|
+
CATCH_CLI_EXCEPTIONS = True
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
@pytest.fixture(scope="session")
|
|
96
|
+
def bids_validator_app_image(
|
|
97
|
+
bids_validator_app_script, bids_validator_docker, build_cache_dir
|
|
98
|
+
):
|
|
99
|
+
return build_app_image(
|
|
100
|
+
BIDS_VALIDATOR_APP_IMAGE,
|
|
101
|
+
bids_validator_app_script,
|
|
102
|
+
build_cache_dir,
|
|
103
|
+
base_image=bids_validator_docker,
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def build_app_image(tag_name, script, build_cache_dir, base_image):
|
|
108
|
+
dc = docker.from_env()
|
|
109
|
+
|
|
110
|
+
# Create executable that runs validator then produces some mock output
|
|
111
|
+
# files
|
|
112
|
+
build_dir = build_cache_dir / tag_name.replace(":", "__i__")
|
|
113
|
+
build_dir.mkdir()
|
|
114
|
+
launch_sh = build_dir / "launch.sh"
|
|
115
|
+
with open(launch_sh, "w") as f:
|
|
116
|
+
f.write(script)
|
|
117
|
+
|
|
118
|
+
# Build mock BIDS app image
|
|
119
|
+
with open(build_dir / "Dockerfile", "w") as f:
|
|
120
|
+
f.write(
|
|
121
|
+
f"""FROM {base_image}
|
|
122
|
+
ADD ./launch.sh /launch.sh
|
|
123
|
+
RUN chmod +x /launch.sh
|
|
124
|
+
ENTRYPOINT ["/launch.sh"]"""
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
dc.images.build(path=str(build_dir), tag=tag_name)
|
|
128
|
+
|
|
129
|
+
return tag_name
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
@pytest.fixture(scope="session")
|
|
133
|
+
def bids_command_spec(mock_bids_app_executable):
|
|
134
|
+
inputs = {
|
|
135
|
+
"T1w": {
|
|
136
|
+
"configuration": {
|
|
137
|
+
"path": "anat/T1w",
|
|
138
|
+
},
|
|
139
|
+
"datatype": "medimage:NiftiGzX",
|
|
140
|
+
"help": "T1-weighted image",
|
|
141
|
+
},
|
|
142
|
+
"T2w": {
|
|
143
|
+
"configuration": {
|
|
144
|
+
"path": "anat/T2w",
|
|
145
|
+
},
|
|
146
|
+
"datatype": "medimage:NiftiGzX",
|
|
147
|
+
"help": "T2-weighted image",
|
|
148
|
+
},
|
|
149
|
+
"DWI": {
|
|
150
|
+
"configuration": {
|
|
151
|
+
"path": "dwi/dwi",
|
|
152
|
+
},
|
|
153
|
+
"datatype": "medimage:NiftiGzXBvec",
|
|
154
|
+
"help": "DWI-weighted image",
|
|
155
|
+
},
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
outputs = {
|
|
159
|
+
"file1": {
|
|
160
|
+
"configuration": {
|
|
161
|
+
"path": "file1",
|
|
162
|
+
},
|
|
163
|
+
"datatype": "common:Text",
|
|
164
|
+
"help": "an output file",
|
|
165
|
+
},
|
|
166
|
+
"file2": {
|
|
167
|
+
"configuration": {
|
|
168
|
+
"path": "file2",
|
|
169
|
+
},
|
|
170
|
+
"datatype": "common:Text",
|
|
171
|
+
"help": "another output file",
|
|
172
|
+
},
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return {
|
|
176
|
+
"task": "frametree.bids.tasks:bids_app",
|
|
177
|
+
"inputs": inputs,
|
|
178
|
+
"outputs": outputs,
|
|
179
|
+
"row_frequency": "session",
|
|
180
|
+
"configuration": {
|
|
181
|
+
"inputs": inputs,
|
|
182
|
+
"outputs": outputs,
|
|
183
|
+
"executable": str(mock_bids_app_executable),
|
|
184
|
+
},
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
@pytest.fixture(scope="session")
|
|
189
|
+
def bids_validator_docker():
|
|
190
|
+
dc = docker.from_env()
|
|
191
|
+
try:
|
|
192
|
+
dc.images.pull(BIDS_VALIDATOR_DOCKER)
|
|
193
|
+
except requests.exceptions.HTTPError:
|
|
194
|
+
warn("No internet connection, so couldn't download latest BIDS validator")
|
|
195
|
+
return BIDS_VALIDATOR_DOCKER
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
@pytest.fixture(scope="session")
|
|
199
|
+
def bids_validator_app_script():
|
|
200
|
+
return f"""#!/bin/sh
|
|
201
|
+
# Echo inputs to get rid of any quotes
|
|
202
|
+
BIDS_DATASET=$(echo $1)
|
|
203
|
+
OUTPUTS_DIR=$(echo $2)
|
|
204
|
+
SUBJ_ID=$5
|
|
205
|
+
# Run BIDS validator to check whether BIDS dataset is created properly
|
|
206
|
+
output=$(/usr/local/bin/bids-validator "$BIDS_DATASET")
|
|
207
|
+
if [[ "$output" != *"{SUCCESS_STR}"* ]]; then
|
|
208
|
+
echo "BIDS validation was not successful, exiting:\n "
|
|
209
|
+
echo $output
|
|
210
|
+
exit 1;
|
|
211
|
+
fi
|
|
212
|
+
# Write mock output files to 'derivatives' Directory
|
|
213
|
+
mkdir -p $OUTPUTS_DIR
|
|
214
|
+
echo 'file1' > $OUTPUTS_DIR/sub-${{SUBJ_ID}}_file1.txt
|
|
215
|
+
echo 'file2' > $OUTPUTS_DIR/sub-${{SUBJ_ID}}_file2.txt
|
|
216
|
+
"""
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
BIDS_VALIDATOR_DOCKER = "bids/validator:latest"
|
|
220
|
+
SUCCESS_STR = "This dataset appears to be BIDS compatible"
|
|
221
|
+
BIDS_VALIDATOR_APP_IMAGE = "pydra-compose-bidsapp-validator"
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Minimal makefile for Sphinx documentation
|
|
2
|
+
#
|
|
3
|
+
|
|
4
|
+
# You can set these variables from the command line, and also
|
|
5
|
+
# from the environment for the first two.
|
|
6
|
+
SPHINXOPTS ?=
|
|
7
|
+
SPHINXBUILD ?= sphinx-build
|
|
8
|
+
SOURCEDIR = .
|
|
9
|
+
BUILDDIR = _build
|
|
10
|
+
|
|
11
|
+
# Put it first so that "make" without argument is like "make help".
|
|
12
|
+
help:
|
|
13
|
+
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
|
14
|
+
|
|
15
|
+
.PHONY: help Makefile
|
|
16
|
+
|
|
17
|
+
# Catch-all target: route all unknown targets to Sphinx using the new
|
|
18
|
+
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
|
|
19
|
+
%: Makefile
|
|
20
|
+
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Configuration file for the Sphinx documentation builder.
|
|
2
|
+
#
|
|
3
|
+
# This file only contains a selection of the most common options. For a full
|
|
4
|
+
# list see the documentation:
|
|
5
|
+
# https://www.sphinx-doc.org/en/master/usage/configuration.html
|
|
6
|
+
|
|
7
|
+
# -- Path setup --------------------------------------------------------------
|
|
8
|
+
|
|
9
|
+
# If extensions (or modules to document with autodoc) are in another directory,
|
|
10
|
+
# add these directories to sys.path here. If the directory is relative to the
|
|
11
|
+
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
|
12
|
+
#
|
|
13
|
+
# import os
|
|
14
|
+
# import sys
|
|
15
|
+
# sys.path.insert(0, os.path.abspath('.'))
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# -- Project information -----------------------------------------------------
|
|
19
|
+
|
|
20
|
+
project = "pydra-compose-bidsapp"
|
|
21
|
+
copyright = "2020, Xihe Xie"
|
|
22
|
+
author = "Xihe Xie"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# -- General configuration ---------------------------------------------------
|
|
26
|
+
|
|
27
|
+
# Add any Sphinx extension module names here, as strings. They can be
|
|
28
|
+
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
|
29
|
+
# ones.
|
|
30
|
+
extensions = []
|
|
31
|
+
|
|
32
|
+
# Add any paths that contain templates here, relative to this directory.
|
|
33
|
+
templates_path = ["_templates"]
|
|
34
|
+
|
|
35
|
+
# List of patterns, relative to source directory, that match files and
|
|
36
|
+
# directories to ignore when looking for source files.
|
|
37
|
+
# This pattern also affects html_static_path and html_extra_path.
|
|
38
|
+
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
# -- Options for HTML output -------------------------------------------------
|
|
42
|
+
|
|
43
|
+
# The theme to use for HTML and HTML Help pages. See the documentation for
|
|
44
|
+
# a list of builtin themes.
|
|
45
|
+
#
|
|
46
|
+
html_theme = "alabaster"
|
|
47
|
+
|
|
48
|
+
# Add any paths that contain custom static files (such as style sheets) here,
|
|
49
|
+
# relative to this directory. They are copied after the builtin static files,
|
|
50
|
+
# so a file named "default.css" will overwrite the builtin "default.css".
|
|
51
|
+
html_static_path = ["_static"]
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
Welcome to pydra-compose-bidsapp's documentation!
|
|
2
|
+
==================================================
|
|
3
|
+
|
|
4
|
+
.. toctree::
|
|
5
|
+
:maxdepth: 2
|
|
6
|
+
:caption: Contents:
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
Indices and tables
|
|
11
|
+
==================
|
|
12
|
+
|
|
13
|
+
* :ref:`genindex`
|
|
14
|
+
* :ref:`modindex`
|
|
15
|
+
* :ref:`search`
|