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..c6d5fc23 100644 --- a/.zenodo.json +++ b/.zenodo.json @@ -3,6 +3,11 @@ "title": "dMRIPrep: a robust preprocessing pipeline for diffusion MRI", "description": "

dMRIPrep is a robust and easy-to-use pipeline for preprocessing of diverse dMRI data. The transparent workflow dispenses of manual intervention, thereby ensuring the reproducibility of the results.

", "creators": [ + { + "affiliation": "University of Texas at Austin", + "name": "Pisner, Derek", + "orcid": "0000-0002-1228-0201" + }, { "affiliation": "Stanford University", "name": "Lerma-Usabiaga, Garikoitz", diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst new file mode 100644 index 00000000..a936a315 --- /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/nipy/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/nipy/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..24137982 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,7 @@ FROM ubuntu:xenial-20161213 # Pre-cache neurodebian key -COPY .docker/neurodebian.gpg /usr/local/etc/neurodebian.gpg +COPY docker/files/neurodebian.gpg /usr/local/etc/neurodebian.gpg # Prepare environment RUN apt-get update && \ @@ -16,6 +16,10 @@ RUN apt-get update && \ autoconf \ libtool \ pkg-config \ + vim \ + zip \ + unzip \ + wget \ git && \ curl -sL https://deb.nodesource.com/setup_10.x | bash - && \ apt-get install -y --no-install-recommends \ @@ -27,43 +31,13 @@ RUN curl -o pandoc-2.2.2.1-1-amd64.deb -sSL "https://github.com/jgm/pandoc/relea dpkg -i pandoc-2.2.2.1-1-amd64.deb && \ rm pandoc-2.2.2.1-1-amd64.deb -# Installing freesurfer -RUN curl -sSL https://surfer.nmr.mgh.harvard.edu/pub/dist/freesurfer/6.0.1/freesurfer-Linux-centos6_x86_64-stable-pub-v6.0.1.tar.gz | tar zxv --no-same-owner -C /opt \ - --exclude='freesurfer/diffusion' \ - --exclude='freesurfer/docs' \ - --exclude='freesurfer/fsfast' \ - --exclude='freesurfer/lib/cuda' \ - --exclude='freesurfer/lib/qt' \ - --exclude='freesurfer/matlab' \ - --exclude='freesurfer/mni/share/man' \ - --exclude='freesurfer/subjects/fsaverage_sym' \ - --exclude='freesurfer/subjects/fsaverage3' \ - --exclude='freesurfer/subjects/fsaverage4' \ - --exclude='freesurfer/subjects/cvs_avg35' \ - --exclude='freesurfer/subjects/cvs_avg35_inMNI152' \ - --exclude='freesurfer/subjects/bert' \ - --exclude='freesurfer/subjects/lh.EC_average' \ - --exclude='freesurfer/subjects/rh.EC_average' \ - --exclude='freesurfer/subjects/sample-*.mgz' \ - --exclude='freesurfer/subjects/V1_average' \ - --exclude='freesurfer/trctrain' - ENV FSL_DIR="/usr/share/fsl/5.0" \ OS="Linux" \ FS_OVERRIDE=0 \ FIX_VERTEX_AREA="" \ - FSF_OUTPUT_FORMAT="nii.gz" \ - FREESURFER_HOME="/opt/freesurfer" -ENV SUBJECTS_DIR="$FREESURFER_HOME/subjects" \ - FUNCTIONALS_DIR="$FREESURFER_HOME/sessions" \ - MNI_DIR="$FREESURFER_HOME/mni" \ - LOCAL_DIR="$FREESURFER_HOME/local" \ - MINC_BIN_DIR="$FREESURFER_HOME/mni/bin" \ - MINC_LIB_DIR="$FREESURFER_HOME/mni/lib" \ - MNI_DATAPATH="$FREESURFER_HOME/mni/data" + FSF_OUTPUT_FORMAT="nii.gz" ENV PERL5LIB="$MINC_LIB_DIR/perl5/5.8.5" \ - MNI_PERL5LIB="$MINC_LIB_DIR/perl5/5.8.5" \ - PATH="$FREESURFER_HOME/bin:$FSFAST_HOME/bin:$FREESURFER_HOME/tktools:$MINC_BIN_DIR:$PATH" + MNI_PERL5LIB="$MINC_LIB_DIR/perl5/5.8.5" # Installing Neurodebian packages (FSL, AFNI, git) RUN curl -sSL "http://neuro.debian.net/lists/$( lsb_release -c | cut -f2 ).us-ca.full" >> /etc/apt/sources.list.d/neurodebian.sources.list && \ @@ -72,32 +46,63 @@ RUN curl -sSL "http://neuro.debian.net/lists/$( lsb_release -c | cut -f2 ).us-ca RUN apt-get update && \ apt-get install -y --no-install-recommends \ - fsl-core=5.0.9-5~nd16.04+1 \ - fsl-mni152-templates=5.0.7-2 \ afni=16.2.07~dfsg.1-5~nd16.04+1 \ - convert3d \ git-annex-standalone && \ apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* -ENV FSLDIR="/usr/share/fsl/5.0" \ - FSLOUTPUTTYPE="NIFTI_GZ" \ - FSLMULTIFILEQUIT="TRUE" \ - POSSUMDIR="/usr/share/fsl/5.0" \ - LD_LIBRARY_PATH="/usr/lib/fsl/5.0:$LD_LIBRARY_PATH" \ - FSLTCLSH="/usr/bin/tclsh" \ - FSLWISH="/usr/bin/wish" \ - AFNI_MODELPATH="/usr/lib/afni/models" \ - AFNI_IMSAVE_WARNINGS="NO" \ - AFNI_TTATLAS_DATASET="/usr/share/afni/atlases" \ - AFNI_PLUGINPATH="/usr/lib/afni/plugins" -ENV PATH="/usr/lib/fsl/5.0:/usr/lib/afni/bin:$PATH" +ENV FSLDIR="/opt/fsl-6.0.1" \ + PATH="/opt/fsl-6.0.1/bin:$PATH" \ + FSLOUTPUTTYPE="NIFTI_GZ" +RUN apt-get update -qq \ + && apt-get install -y -q --no-install-recommends \ + bc \ + dc \ + file \ + libfontconfig1 \ + libfreetype6 \ + libgl1-mesa-dev \ + libglu1-mesa-dev \ + libgomp1 \ + libice6 \ + libxcursor1 \ + libxft2 \ + libxinerama1 \ + libxrandr2 \ + libxrender1 \ + libxt6 \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* \ + && echo "Downloading FSL ..." \ + && wget -q http://fsl.fmrib.ox.ac.uk/fsldownloads/fslinstaller.py \ + && chmod 775 fslinstaller.py +RUN /fslinstaller.py -d /opt/fsl-6.0.1 -V 6.0.1 -q + +RUN rm -rf /opt/fsl-6.0.1/data \ + && rm -rf /opt/fsl-6.0.1/bin/FSLeyes* \ + && rm -rf /opt/fsl-6.0.1/src \ + && rm -rf /opt/fsl-6.0.1/extras/src \ + && rm -rf /opt/fsl-6.0.1/doc \ + && rm -rf /opt/fsl-6.0.1/bin/fslview.app \ + && rm -rf /opt/fsl-6.0.1/data/atlases \ + && rm -rf /opt/fsl-6.0.1/data/first \ + && rm -rf /opt/fsl-6.0.1/data/mist \ + && rm -rf /opt/fsl-6.0.1/data/possum # Installing ANTs 2.2.0 (NeuroDocker build) ENV ANTSPATH=/usr/lib/ants RUN mkdir -p $ANTSPATH && \ curl -sSL "https://dl.dropbox.com/s/2f4sui1z6lcgyek/ANTs-Linux-centos5_x86_64-v2.2.0-0740f91.tar.gz" \ | tar -xzC $ANTSPATH --strip-components 1 -ENV PATH=$ANTSPATH:$PATH + +ENV AFNI_INSTALLDIR=/usr/lib/afni \ + PATH=${PATH}:/usr/lib/afni/bin \ + AFNI_PLUGINPATH=/usr/lib/afni/plugins \ + AFNI_MODELPATH=/usr/lib/afni/models \ + AFNI_TTATLAS_DATASET=/usr/share/afni/atlases \ + AFNI_IMSAVE_WARNINGS=NO \ + FSLOUTPUTTYPE=NIFTI_GZ \ + PATH=$ANTSPATH:$PATH \ + ANTS_VERSION=2.2.0 # Create a shared $HOME directory RUN useradd -m -s /bin/bash -G users dmriprep @@ -112,14 +117,6 @@ RUN npm install -g svgo # Installing bids-validator RUN npm install -g bids-validator@1.2.3 -# Installing and setting up ICA_AROMA -RUN mkdir -p /opt/ICA-AROMA && \ - curl -sSL "https://github.com/maartenmennes/ICA-AROMA/archive/v0.4.4-beta.tar.gz" \ - | tar -xzC /opt/ICA-AROMA --strip-components 1 && \ - chmod +x /opt/ICA-AROMA/ICA_AROMA.py - -ENV PATH=/opt/ICA-AROMA:$PATH - # Installing and setting up miniconda RUN curl -sSLO https://repo.continuum.io/miniconda/Miniconda3-4.5.11-Linux-x86_64.sh && \ bash Miniconda3-4.5.11-Linux-x86_64.sh -b -p /usr/local/miniconda && \ @@ -147,6 +144,7 @@ RUN conda install -y python=3.7.1 \ graphviz=2.40.1 \ traits=4.6.0 \ zlib; sync && \ + cython && \ chmod -R a+rX /usr/local/miniconda; sync && \ chmod +x /usr/local/miniconda/bin/*; sync && \ conda build purge-all; sync && \ @@ -161,26 +159,33 @@ ENV MKL_NUM_THREADS=1 \ RUN python -c "from matplotlib import font_manager" && \ sed -i 's/\(backend *: \).*$/\1Agg/g' $( python -c "import matplotlib; print(matplotlib.matplotlib_fname())" ) -# Precaching atlases -RUN pip install --no-cache-dir "templateflow>=0.4.0,<0.5.0a0" && \ - python -c "from templateflow import api as tfapi; \ - tfapi.get('MNI152NLin6Asym', atlas=None, extension=['.nii', '.nii.gz']); \ - tfapi.get('MNI152NLin2009cAsym', atlas=None, extension=['.nii', '.nii.gz']); \ - tfapi.get('OASIS30ANTs', extension=['.nii', '.nii.gz']);" && \ - find $HOME/.cache/templateflow -type d -exec chmod go=u {} + && \ - find $HOME/.cache/templateflow -type f -exec chmod go=u {} + - -# Installing FMRIPREP -COPY . /src/dmriprep -ARG VERSION -# Force static versioning within container -RUN echo "${VERSION}" > /src/dmriprep/dmriprep/VERSION && \ - echo "include dmriprep/VERSION" >> /src/dmriprep/MANIFEST.in && \ - pip install --no-cache-dir "/src/dmriprep[all]" +RUN pip install --upgrade pip + +RUN apt-get update && apt-get install -y \ + gfortran \ + liblapack-dev \ + libopenblas-dev + +RUN pip install ipython cython parse + +# Installing DMRIPREP +RUN git clone -b nipreps https://github.com/dPys/dmriprep.git dmriprep && \ + cd dmriprep && \ + python setup.py install + +RUN pip install ipython cython parse + +RUN pip install --no-cache-dir https://github.com/samuelstjean/nlsam/archive/master.zip RUN find $HOME -type d -exec chmod go=u {} + && \ find $HOME -type f -exec chmod go=u {} + +RUN mkdir /inputs && \ + chmod -R 777 /inputs + +RUN mkdir /outputs && \ + chmod -R 777 /outputs + ENV IS_DOCKER_8395080871=1 RUN ldconfig diff --git a/MANIFEST.in b/MANIFEST.in index 71126fef..06cb4024 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -5,3 +5,20 @@ include LICENSE # versioneer include versioneer.py include dmriprep/_version.py +recursive-include * *.nii.gz +recursive-include * *.html +recursive-include * *.js +recursive-include * *.json +recursive-include * *.txt +recursive-include * *.csv +recursive-include dmriprep/viz * +recursive-include dmriprep/utils * +recursive-include dmriprep/interfaces * +recursive-include dmriprep/data * +recursive-include dmriprep/config * +recursive-include dmriprep/cli * +recursive-include tests * +recursive-exclude * __pycache__ +recursive-exclude * *.py[co] +recursive-include * *.yaml +recursive-include docs *.rst conf.py Makefile make.bat *.jpg *.png *.gif 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..9f6310b4 100644 --- a/README.rst +++ b/README.rst @@ -4,7 +4,7 @@ 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 @@ -49,4 +49,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/.idea/dmriprep.iml b/dmriprep/.idea/dmriprep.iml new file mode 100644 index 00000000..86abb4ca --- /dev/null +++ b/dmriprep/.idea/dmriprep.iml @@ -0,0 +1,13 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/dmriprep/.idea/libraries/R_User_Library.xml b/dmriprep/.idea/libraries/R_User_Library.xml new file mode 100644 index 00000000..71f5ff74 --- /dev/null +++ b/dmriprep/.idea/libraries/R_User_Library.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/dmriprep/.idea/misc.xml b/dmriprep/.idea/misc.xml new file mode 100644 index 00000000..1d8a5d64 --- /dev/null +++ b/dmriprep/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/dmriprep/.idea/modules.xml b/dmriprep/.idea/modules.xml new file mode 100644 index 00000000..3913f593 --- /dev/null +++ b/dmriprep/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/dmriprep/.idea/vcs.xml b/dmriprep/.idea/vcs.xml new file mode 100644 index 00000000..6c0b8635 --- /dev/null +++ b/dmriprep/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/dmriprep/.idea/workspace.xml b/dmriprep/.idea/workspace.xml new file mode 100644 index 00000000..f2bb0f0f --- /dev/null +++ b/dmriprep/.idea/workspace.xml @@ -0,0 +1,274 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + susceptibility_args + /work + work + slm + move + reverse + 'none' + work_dir + rescale + split + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1569954465602 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/dmriprep/__about__.py b/dmriprep/__about__.py index 8f69a634..0b94bc0a 100644 --- a/dmriprep/__about__.py +++ b/dmriprep/__about__.py @@ -1,9 +1,10 @@ # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- # vi: set ft=python sts=4 ts=4 sw=4 et: """Base module variables.""" -from ._version import get_versions -__version__ = get_versions()['version'] -del get_versions +#from ._version import get_versions +#__version__ = get_versions()['version'] +#del get_versions +__version__ = '0.2.1' __packagename__ = 'dmriprep' __copyright__ = 'Copyright 2019, The dMRIPrep developers' 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..4837d96a 100755 --- a/dmriprep/cli/run.py +++ b/dmriprep/cli/run.py @@ -1,44 +1,22 @@ #!/usr/bin/env python """dMRI preprocessing workflow.""" -import os from pathlib import Path -import logging import sys -import gc import uuid import warnings +warnings.filterwarnings("ignore") from argparse import ArgumentParser from argparse import ArgumentDefaultsHelpFormatter from multiprocessing import cpu_count from time import strftime -logging.addLevelName(25, 'IMPORTANT') # Add a new level between INFO and WARNING -logging.addLevelName(15, 'VERBOSE') # Add a new level between INFO and DEBUG -logger = logging.getLogger('cli') - - -def _warn_redirect(message, category, filename, lineno, file=None, line=None): - logger.warning('Captured warning (%s): %s', category, message) - - -def check_deps(workflow): - from nipype.utils.filemanip import which - return sorted( - (node.interface.__class__.__name__, node.interface._cmd) - for node in workflow._get_all_nodes() - if (hasattr(node.interface, '_cmd') and - which(node.interface._cmd.split()[0]) is None)) - def get_parser(): """Build parser object""" - from smriprep.cli.utils import ParseTemplates, output_space as _output_space - from templateflow.api import templates from packaging.version import Version - from ..__about__ import __version__ - from ..config import NONSTANDARD_REFERENCES - from .version import check_latest, is_flagged + from dmriprep.__about__ import __version__ + from dmriprep.cli.version import check_latest, is_flagged verstr = 'dmriprep v{}'.format(__version__) currentv = Version(__version__) @@ -51,379 +29,86 @@ def get_parser(): # required, positional arguments # IMPORTANT: they must go directly with the parser object parser.add_argument('bids_dir', action='store', type=Path, - help='the root folder of a BIDS valid dataset (sub-XXXXX folders should ' + help='The root folder of a BIDS valid dataset (sub-XXXXX folders should ' 'be found at the top level in this folder).') parser.add_argument('output_dir', action='store', type=Path, - help='the output path for the outcomes of preprocessing and visual ' + help='The output path for the outcomes of preprocessing and visual ' 'reports') parser.add_argument('analysis_level', choices=['participant'], - help='processing stage to be run, only "participant" in the case of ' + help='Processing stage to be run, only "participant" in the case of ' 'dMRIPrep (see BIDS-Apps specification).') # optional arguments parser.add_argument('--version', action='version', version=verstr) g_bids = parser.add_argument_group('Options for filtering BIDS queries') - g_bids.add_argument('--skip-bids-validation', action='store_true', default=False, - help='assume the input dataset is BIDS compliant and skip the validation') - g_bids.add_argument('--participant_label', '--participant-label', action='store', nargs='+', - help='a space delimited list of participant identifiers or a single ' + g_bids.add_argument('--skip_bids_validation', action='store_true', default=False, + help='Assume the input dataset is BIDS compliant and skip the validation') + g_bids.add_argument('--participant_label', action='store', nargs='+', + help='A space delimited list of participant identifiers or a single ' 'identifier (the sub- prefix can be removed)') - # Re-enable when option is actually implemented - # g_bids.add_argument('-s', '--session-id', action='store', default='single_session', - # help='select a specific session to be processed') - # 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('-s', '--session_id', action='store', nargs='+', + help='A space delimited list of session identifiers or a single ' + 'identifier (the ses- prefix can be removed)') g_perfm = parser.add_argument_group('Options to handle performance') - g_perfm.add_argument('--nprocs', '--n_cpus', '-n-cpus', action='store', type=int, - help='maximum number of threads across all processes') - g_perfm.add_argument('--omp-nthreads', action='store', type=int, default=0, - help='maximum number of threads per-process') - g_perfm.add_argument('--mem_mb', '--mem-mb', action='store', default=0, type=int, - help='upper bound memory limit for dMRIPrep processes') - g_perfm.add_argument('--low-mem', action='store_true', - help='attempt to reduce memory usage (will increase disk usage ' - 'in working directory)') - g_perfm.add_argument('--use-plugin', action='store', default=None, - help='nipype plugin configuration file') - g_perfm.add_argument('--anat-only', action='store_true', - help='run anatomical workflows only') - g_perfm.add_argument('--boilerplate', action='store_true', - help='generate boilerplate only') - g_perfm.add_argument("-v", "--verbose", dest="verbose_count", action="count", default=0, - help="increases log verbosity for each occurence, debug level is -vvv") + g_perfm.add_argument('--plugin', action='store', type=str, default='MultiProc', + help='Plugin type. Options include MultiProc or Linear') + g_perfm.add_argument('--nprocs', '--n_cpus', action='store', type=int, default=8, + help='Maximum number of threads across all processes. Minimum required is 8.') + g_perfm.add_argument('--omp_nthreads', action='store', type=int, default=2, + help='Maximum number of threads per-process') + g_perfm.add_argument('--mem_gb', action='store', default=16, type=int, + help='Upper bound memory limit for dMRIPrep processes. Minimum required is 16 GB.') + g_perfm.add_argument("-v", "--verbose", action="store_true", default=False, + help="Perform debug and logging.") g_conf = parser.add_argument_group('Workflow configuration') - g_conf.add_argument( - '--ignore', required=False, action='store', nargs="+", default=[], choices=['sdc'], - help='ignore selected aspects of the input dataset to disable corresponding ' - 'parts of the workflow (a space delimited list)') - g_conf.add_argument( - '--longitudinal', action='store_true', - help='treat dataset as longitudinal - may increase runtime') - g_conf.add_argument( - '--output-spaces', nargs='+', action=ParseTemplates, - help="""\ -Standard and non-standard spaces to resample anatomical and functional images to. \ -Standard spaces may be specified by the form \ -``