diff --git a/.dockerignore b/.dockerignore index b5bfff59..a51f661d 100644 --- a/.dockerignore +++ b/.dockerignore @@ -8,8 +8,8 @@ build/**/* build dist/**/* dist -fmriprep.egg-info/**/* -fmriprep.egg-info +dmriprep.egg-info/**/* +dmriprep.egg-info .eggs/**/* .eggs @@ -39,4 +39,4 @@ out/ .zenodo.json .travis.yml .readthedocs.yml -CONTRIBUTING.md \ No newline at end of file +CONTRIBUTING.rst diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..cd5a1171 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +dmriprep/_version.py export-subst diff --git a/.github/config.yml b/.github/config.yml index c65ed7d8..70c14c71 100644 --- a/.github/config.yml +++ b/.github/config.yml @@ -5,8 +5,8 @@ newPRWelcomeComment: > Thanks for opening this pull request! We have detected this is the first time for you to contribute to *dMRIPrep*. - Please check out our [contributing guidelines](https://github.com/nipreps/dmriprep/blob/master/CONTRIBUTING.md). - + Please check out our [contributing guidelines](https://github.com/nipreps/dmriprep/blob/master/CONTRIBUTING.rst). + We invite you to list yourself as a *dMRIPrep* contributor, so if your name is not already mentioned, please modify the [``.zenodo.json``](https://github.com/nipreps/dmriprep/blob/master/.zenodo.json) @@ -25,4 +25,4 @@ newPRWelcomeComment: > Of course, if you want to opt-out this time there is no problem at all with adding your name later. You will be always welcome to add it in the future whenever - you feel it should be listed. \ No newline at end of file + you feel it should be listed. diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml new file mode 100644 index 00000000..075f95b6 --- /dev/null +++ b/.github/release-drafter.yml @@ -0,0 +1,5 @@ +template: | + ## Release Notes + + ## CHANGES + $CHANGES diff --git a/.github/stale.yml b/.github/stale.yml new file mode 100644 index 00000000..28e0d5c1 --- /dev/null +++ b/.github/stale.yml @@ -0,0 +1,20 @@ +# Number of days of inactivity before an issue becomes stale +daysUntilStale: 900 +# Number of days of inactivity before a stale issue is closed +daysUntilClose: 200 +# Issues with these labels will never be considered stale +exemptLabels: + - pinned + - security + - feature + - help wanted + - low priority +# Label to use when marking an issue as stale +staleLabel: stale +# Comment to post when marking an issue as stale. Set to `false` to disable +markComment: > + This issue has been automatically marked as stale because it has not had + recent activity. It will be closed if no further activity occurs. Thank you + for your contributions. +# Comment to post when closing a stale issue. Set to `false` to disable +closeComment: false diff --git a/.gitignore b/.gitignore index a8237ba3..3cae9a46 100644 --- a/.gitignore +++ b/.gitignore @@ -103,6 +103,3 @@ ENV/ # Mac OS nonsense: .DS_Store - -#kubernetes stuff -kubernetes/jobs/ diff --git a/.readthedocs.yml b/.readthedocs.yml new file mode 100644 index 00000000..14d721c1 --- /dev/null +++ b/.readthedocs.yml @@ -0,0 +1,20 @@ +# .readthedocs.yml +# Read the Docs configuration file +# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details + +# Required +version: 2 + +# Build documentation in the docs/ directory with Sphinx +sphinx: + configuration: docs/conf.py + +# Optionally build your docs in additional formats such as PDF and ePub +formats: all + +python: + install: + - method: pip + path: . + extra_requirements: + - doc diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..293b1af1 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,35 @@ +# Config file for automatic testing at travis-ci.org + +language: python +matrix: + include: + - python: 3.5 + dist: trusty + sudo: false + - python: 3.6 + dist: trusty + sudo: false + - python: 3.7 + dist: xenial + sudo: true + +# Command to install dependencies, e.g. pip install -r requirements.txt --use-mirrors +install: pip install -U tox-travis + +# Command to run tests, e.g. python setup.py test +script: tox + +# Assuming you have installed the travis-ci CLI tool, after you +# create the Github repo and add it to Travis, run the +# following command to finish PyPI deployment setup: +# $ travis encrypt --add deploy.password +deploy: + provider: pypi + distributions: sdist bdist_wheel + user: nipy + password: + secure: PLEASE_REPLACE_ME + on: + tags: true + repo: tigrlab/dmriprep + python: 3.7 diff --git a/.zenodo.json b/.zenodo.json index f823aa44..615c6db0 100644 --- a/.zenodo.json +++ b/.zenodo.json @@ -39,6 +39,17 @@ { "name": "nrajamani3", "type": "Researcher" + }, + { + "name": "Mansour, Salim", + "affiliation": "The Centre for Addiction and Mental Health", + "type": "Researcher" + }, + { + "name": "Forde, Natalie", + "affiliation": "The Centre for Addiction and Mental Health", + "orcid": "0000-0002-2005-8774", + "type": "Researcher" } ], "keywords": [ diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst new file mode 100644 index 00000000..956ccfc1 --- /dev/null +++ b/CONTRIBUTING.rst @@ -0,0 +1,181 @@ +.. highlight:: shell + +============ +Contributing +============ + +We love contributions! dmriprep is open source, built on open source, +and we'd love to have you hang out in our community. + +**Imposter syndrome disclaimer**: We want your help. No, really. + +There may be a little voice inside your head that is telling you that +you're not ready to be an open source contributor; that your skills +aren't nearly good enough to contribute. What could you possibly offer a +project like this one? + +We assure you - the little voice in your head is wrong. If you can +write code at all, you can contribute code to open source. Contributing +to open source projects is a fantastic way to advance one's coding +skills. Writing perfect code isn't the measure of a good developer (that +would disqualify all of us!); it's trying to create something, making +mistakes, and learning from those mistakes. That's how we all improve, +and we are happy to help others learn. + +Being an open source contributor doesn't just mean writing code, either. +You can help out by writing documentation, tests, or even giving +feedback about the project (and yes - that includes giving feedback +about the contribution process). Some of these contributions may be the +most valuable to the project as a whole, because you're coming to the +project with fresh eyes, so you can see the errors and assumptions that +seasoned contributors have glossed over. + +Installing a development version of dmriprep +-------------------------------------------- + +First, you can install a development version of dmriprep by cloning this repository +and then typing:: + + $ pip install -e .[dev] + +Activate the pre-commit formatting hook by typing:: + + $ pre-commit install + +Before committing your work, you can check for formatting issues or error by typing:: + + $ make lint + $ make test + +Types of Contributions +---------------------- + +You can contribute in many ways: + +Report Bugs +~~~~~~~~~~~ + +Report bugs at https://github.com/nipreps/dmriprep/issues. + +If you are reporting a bug, please include: + +* Your operating system name and version. +* Any details about your local setup that might be helpful in troubleshooting. +* Detailed steps to reproduce the bug. + +Fix Bugs +~~~~~~~~ + +Look through the GitHub issues for bugs. Anything tagged with "bug" and "help +wanted" is open to whoever wants to implement it. + +Implement Features +~~~~~~~~~~~~~~~~~~ + +Look through the GitHub issues for features. Anything tagged with "enhancement" +and "help wanted" is open to whoever wants to implement it. + +Write Documentation +~~~~~~~~~~~~~~~~~~~ + +dmriprep could always use more documentation, whether as part of the +official dmriprep docs, in docstrings, or even on the web in blog posts, +articles, and such. + +Submit Feedback +~~~~~~~~~~~~~~~ + +The best way to send feedback is to file an issue at https://github.com/nipreps/dmriprep/issues. + +If you are proposing a feature: + +* Explain in detail how it would work. +* Keep the scope as narrow as possible, to make it easier to implement. +* Remember that this is a volunteer-driven project, and that contributions + are welcome :) + +Get Started! +------------ + +Ready to contribute? Here's how to set up `dmriprep` for local development. + +1. Fork the `dmriprep` repo on GitHub. +2. Clone your fork locally:: + + $ git clone git@github.com:your_name_here/dmriprep.git + +3. Install your local copy into a virtualenv. Assuming you have virtualenvwrapper installed, this is how you set up your fork for local development:: + + $ mkvirtualenv dmriprep + $ cd dmriprep/ + $ python setup.py develop + +4. Create a branch for local development:: + + $ git checkout -b name-of-your-bugfix-or-feature + + Now you can make your changes locally. + +5. When you're done making changes, check that your changes pass flake8 and the + tests, including testing other Python versions with tox:: + + $ flake8 dmriprep tests + $ python setup.py test or py.test + $ tox + + To get flake8 and tox, just pip install them into your virtualenv. + +6. Commit your changes and push your branch to GitHub:: + + $ git add . + $ git commit -m "Your detailed description of your changes." + $ git push origin name-of-your-bugfix-or-feature + +7. Submit a pull request through the GitHub website. + +Pull Request Guidelines +----------------------- + +Before you submit a pull request, check that it meets these guidelines: + +1. The pull request should include tests. +2. If the pull request adds functionality, the docs should be updated. Put + your new functionality into a function with a docstring, and add the + feature to the list in README.rst. +3. The pull request should work for Python 3.5, 3.6 and 3.7, and for PyPy. Check + https://travis-ci.org/tigrlab/dmriprep/pull_requests + and make sure that the tests pass for all supported Python versions. + +When opening a pull request, please use one of the following prefixes: + +* **[ENH]** for enhancements +* **[FIX]** for bug fixes +* **[TST]** for new or updated tests +* **[DOC]** for new or updated documentation +* **[STY]** for stylistic changes +* **[REF]** for refactoring existing code + +Tips +---- + +To run a subset of tests:: + +$ py.test tests.test_dmriprep + + +Deploying +--------- + +A reminder for the maintainers on how to deploy. +Make sure all your changes are committed (including an entry in HISTORY.rst). +Then run:: + +$ bumpversion patch # possible: major / minor / patch +$ git push +$ git push --tags + +Travis will then deploy to PyPI if tests pass. + +The imposter syndrome disclaimer was originally written by +`Adrienne Lowe `_ for a `PyCon talk `_, and was +adapted based on its use in the README file for the `MetPy project `_. diff --git a/Dockerfile b/Dockerfile index 9c707115..fe16af09 100644 --- a/Dockerfile +++ b/Dockerfile @@ -170,7 +170,7 @@ RUN pip install --no-cache-dir "templateflow>=0.4.0,<0.5.0a0" && \ find $HOME/.cache/templateflow -type d -exec chmod go=u {} + && \ find $HOME/.cache/templateflow -type f -exec chmod go=u {} + -# Installing FMRIPREP +# Installing DMRIPREP COPY . /src/dmriprep ARG VERSION # Force static versioning within container diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..03b6b514 --- /dev/null +++ b/Makefile @@ -0,0 +1,94 @@ +.PHONY: clean clean-test clean-pyc clean-build docs help +.DEFAULT_GOAL := help + +define BROWSER_PYSCRIPT +import os, webbrowser, sys + +try: + from urllib import pathname2url +except: + from urllib.request import pathname2url + +webbrowser.open("file://" + pathname2url(os.path.abspath(sys.argv[1]))) +endef +export BROWSER_PYSCRIPT + +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 + +BROWSER := python -c "$$BROWSER_PYSCRIPT" + +help: + @python -c "$$PRINT_HELP_PYSCRIPT" < $(MAKEFILE_LIST) + +clean: clean-build clean-pyc clean-test ## remove all build, test, coverage and Python artifacts + +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 {} + + +clean-test: ## remove test and coverage artifacts + rm -fr .tox/ + rm -f .coverage + rm -fr htmlcov/ + rm -fr .pytest_cache + +lint: ## check style with flake8 + flake8 dmriprep tests + +test: ## run tests quickly with the default Python + py.test + +test-all: ## run tests on every Python version with tox + tox + +coverage: ## check code coverage quickly with the default Python + coverage run --source dmriprep -m pytest + coverage report -m + coverage html + $(BROWSER) htmlcov/index.html + +docs: ## generate Sphinx HTML documentation, including API docs + rm -f docs/dmriprep*.rst + rm -f docs/modules.rst + sphinx-apidoc -o docs/ dmriprep + $(MAKE) -C docs clean + $(MAKE) -C docs html + $(BROWSER) docs/_build/html/index.html + +servedocs: docs ## compile the docs watching for changes + watchmedo shell-command -p '*.rst' -c '$(MAKE) -C docs html' -R -D . + +release: dist ## package and upload a release + twine upload dist/* + +dist: clean ## builds source and wheel package + python setup.py sdist + python setup.py bdist_wheel + ls -l dist + +install: clean ## install the package to the active Python's site-packages + python setup.py install + +docker: docker + docker build --rm -t nipreps/dmriprep:latest \ + --build-arg BUILD_DATE=`date -u +"%Y-%m-%dT%H:%M:%SZ"` \ + --build-arg VCS_REF=`git rev-parse --short HEAD` \ + --build-arg VERSION=$( python get_version.py ) . diff --git a/README.rst b/README.rst index f4add394..3070c2fd 100644 --- a/README.rst +++ b/README.rst @@ -4,13 +4,10 @@ dmriprep .. image:: https://badgen.net/badge/chat/on%20mattermost/blue :target: https://mattermost.brainhack.org/brainhack/channels/dmriprep - + .. image:: https://img.shields.io/pypi/v/dmriprep.svg :target: https://pypi.python.org/pypi/dmriprep -.. image:: https://circleci.com/gh/nipreps/dmriprep.svg?style=svg - :target: https://circleci.com/gh/nipreps/dmriprep - .. image:: https://zenodo.org/badge/DOI/10.5281/zenodo.3392201.svg :target: https://doi.org/10.5281/zenodo.3392201 @@ -49,4 +46,4 @@ segmentation, skullstripping etc.) providing outputs that can be easily submitted to a variety of tractography algorithms. [Documentation `dmriprep.org `_] -[Support `neurostars.org `_] +[Support `neurostars.org `_] diff --git a/dmriprep/__init__.py b/dmriprep/__init__.py index 72e61e5a..35bac792 100644 --- a/dmriprep/__init__.py +++ b/dmriprep/__init__.py @@ -15,7 +15,7 @@ '__packagename__', ] -# cmp is not used by fmriprep, so ignore nipype-generated warnings +# cmp is not used by dmriprep, so ignore nipype-generated warnings _warnings.filterwarnings('ignore', r'cmp not installed') _warnings.filterwarnings('ignore', r'This has not been fully tested. Please report any failures.') _warnings.filterwarnings('ignore', r"can't resolve package from __spec__ or __package__") diff --git a/dmriprep/cli/run.py b/dmriprep/cli/run.py index 05f74b0c..30cb3246 100755 --- a/dmriprep/cli/run.py +++ b/dmriprep/cli/run.py @@ -75,6 +75,8 @@ def get_parser(): # Re-enable when option is actually implemented # g_bids.add_argument('-r', '--run-id', action='store', default='single_run', # help='select a specific run to be processed') + g_bids.add_argument('-a', '--acq-id', action='store', + help='select a specific acquisition to be processed') g_perfm = parser.add_argument_group('Options to handle performance') g_perfm.add_argument('--nprocs', '--n_cpus', '-n-cpus', action='store', type=int, @@ -97,7 +99,8 @@ def get_parser(): g_conf = parser.add_argument_group('Workflow configuration') g_conf.add_argument( - '--ignore', required=False, action='store', nargs="+", default=[], choices=['sdc'], + '--ignore', required=False, action='store', nargs="+", default=[], + choices=['denoising', 'unringing', 'fieldmaps'], help='ignore selected aspects of the input dataset to disable corresponding ' 'parts of the workflow (a space delimited list)') g_conf.add_argument( @@ -129,6 +132,17 @@ def get_parser(): help='do not use a random seed for skull-stripping - will ensure ' 'run-to-run replicability when used with --omp-nthreads 1') + # Dwi options + g_dwi = parser.add_argument_group('Specific options for handling dwi scans') + g_dwi.add_argument('--concat-dwis', required=False, action='store', + nargs="+", default=[], + help='space-delimited list of acq-