diff --git a/.circleci/config.yml b/.circleci/config.yml index 20057a3500..8d91c9e98c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -229,10 +229,10 @@ jobs: command: | export PY3=$( pyenv versions | awk '/^\* 3/ { print $2 }' ) pyenv local $PY3 - python3 -m pip install --upgrade setuptools setuptools_scm pip + python3 -m pip install -U build hatch hatchling pip twine docutils # Get version, update files. - THISVERSION=$( python3 -m setuptools_scm ) + THISVERSION=$( python3 -m hatch version | tail -n1 | xargs ) if [[ ${THISVERSION:0:1} == "0" ]] ; then echo "WARNING: latest git tag could not be found" echo "Please, make sure you fetch all tags from upstream with" @@ -255,7 +255,7 @@ jobs: export PY3=$( pyenv versions | awk '/^\* 3/ { print $2 }' ) pyenv local $PY3 # Get version, update files. - THISVERSION=$( python3 -m setuptools_scm ) + THISVERSION=$( python3 -m hatch version | tail -n1 | xargs ) BUILT_VERSION=$( docker run --rm --entrypoint=python nipreps/sdcflows:latest -c "import sdcflows; print(sdcflows.__version__)" ) BUILT_VERSION=${BUILT_VERSION%$'\r'} echo "VERSION: \"$THISVERSION\"" @@ -376,13 +376,13 @@ jobs: command: | python -m venv /tmp/venv source /tmp/venv/bin/activate - python -m pip install -U pip setuptools setuptools_scm - pip install --no-cache-dir -r docs/requirements.txt + python -m pip install -U build hatch hatchling pip twine docutils + python -m pip install --no-cache-dir -r docs/requirements.txt - run: name: Build only this commit command: | source /tmp/venv/bin/activate - python -m setuptools_scm + python -m hatch version | tail -n1 | xargs BRANCH=$( echo $CIRCLE_BRANCH | sed 's+/+_+g' ) make -C docs SPHINXOPTS="-W" BUILDDIR="$HOME/docs" OUTDIR=${CIRCLE_TAG:-$BRANCH} html - store_artifacts: @@ -422,7 +422,7 @@ jobs: command: | python -m venv /tmp/buildenv source /tmp/buildenv/bin/activate - python -m pip install -U build twine setuptools_scm + python3 -m pip install -U build hatch hatchling pip twine docutils python3 -m build twine check dist/sdcflows* - store_artifacts: @@ -435,7 +435,7 @@ jobs: name: Validate version command: | source /tmp/buildenv/bin/activate - THISVERSION=$( python -m setuptools_scm ) + THISVERSION=$( python -m hatch version | tail -n1 | xargs ) python -m pip install dist/*.whl mkdir empty cd empty diff --git a/.git_archival.txt b/.git_archival.txt index 95cb3eea4e..b1a286bbb6 100644 --- a/.git_archival.txt +++ b/.git_archival.txt @@ -1 +1,4 @@ -ref-names: $Format:%D$ +node: $Format:%H$ +node-date: $Format:%cI$ +describe-name: $Format:%(describe:tags=true,match=*[0-9]*)$ +ref-names: $Format:%D$ \ No newline at end of file diff --git a/.gitattributes b/.gitattributes index 555b4f7438..00a7b00c94 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1 @@ -sdcflows/_version.py export-subst .git_archival.txt export-subst diff --git a/.github/workflows/docs-build-pr.yml b/.github/workflows/docs-build-pr.yml index 5052f3a86a..49ce59f696 100644 --- a/.github/workflows/docs-build-pr.yml +++ b/.github/workflows/docs-build-pr.yml @@ -46,9 +46,9 @@ jobs: - name: Install dependencies run: | - pip install -r docs/requirements.txt - pip install --no-cache-dir "setuptools ~= 45.0" "setuptools_scm[toml] >= 3.4" - python setup.py --version + python -m pip install -U build hatch hatchling pip docutils + python -m pip install -r docs/requirements.txt + python -m hatch version | tail -n1 | xargs - name: Build docs run: | diff --git a/.github/workflows/docs-build-update.yml b/.github/workflows/docs-build-update.yml index 9079c0538a..0bfa5451f2 100644 --- a/.github/workflows/docs-build-update.yml +++ b/.github/workflows/docs-build-update.yml @@ -46,9 +46,9 @@ jobs: - name: Install dependencies run: | - pip install -r docs/requirements.txt - pip install --no-cache-dir "setuptools ~= 45.0" "setuptools_scm[toml] >= 3.4" - python setup.py --version + python -m pip install -U build hatch hatchling pip docutils + python -m pip install -r docs/requirements.txt + python -m hatch version | tail -n1 | xargs - name: Build docs run: | diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml index 63cdfa897c..93e6f4d8f3 100644 --- a/.github/workflows/pythonpackage.yml +++ b/.github/workflows/pythonpackage.yml @@ -45,8 +45,8 @@ jobs: if [[ "$GITHUB_REF" == refs/tags/* ]]; then VERSION=${GITHUB_REF##*/} else - pip install setuptools_scm - VERSION=$( python -m setuptools_scm ) + pip install -U build hatch hatchling pip twine docutils + VERSION=$( python -m hatch version | tail -n1 | xargs ) fi echo version=$VERSION | tee -a $GITHUB_OUTPUT @@ -78,7 +78,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.8", "3.12"] + python-version: ["3.10", "3.12"] install: [repo, sdist, wheel, editable] env: @@ -125,8 +125,12 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - name: Set up Python 3 + - name: Set up Python uses: actions/setup-python@v4 - with: - python-version: 3 - - run: pipx run flake8 sdcflows/ + - run: pipx run flake8-pyproject sdcflows/ + + # codespell: + # runs-on: ubuntu-latest + # steps: + # - uses: actions/checkout@v4 + # - uses: codespell-project/actions-codespell@v2 diff --git a/.github/workflows/unittests.yml b/.github/workflows/unittests.yml index cdbaec4c50..e2726e11bd 100644 --- a/.github/workflows/unittests.yml +++ b/.github/workflows/unittests.yml @@ -1,4 +1,4 @@ -name: Deps & CI +name: CI on: push: @@ -31,15 +31,10 @@ jobs: AFNI_TTATLAS_DATASET: /opt/afni/atlases AFNI_PLUGINPATH: /opt/afni/plugins ANTSPATH: /opt/ants - DEPS: ${{ matrix.deps }}.txt strategy: max-parallel: 5 matrix: - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] - deps: ["requirements"] - include: - - python-version: "3.8" - deps: "min-requirements" + python-version: ["3.10", "3.11", "3.12"] steps: - uses: actions/cache@v3 @@ -117,7 +112,6 @@ jobs: - name: Install dependencies timeout-minutes: 5 run: | - pip install -r $DEPS pip install .[tests] diff --git a/.gitignore b/.gitignore index cc963e99c6..bada2f41a9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ # setuptools-scm -sdcflows/_version.py +_version.py # Byte-compiled / optimized / DLL files pip-wheel-metadata diff --git a/.maint/update_requirements.py b/.maint/update_requirements.py index 01fc171ed7..3a10c1508a 100755 --- a/.maint/update_requirements.py +++ b/.maint/update_requirements.py @@ -1,19 +1,21 @@ #!/usr/bin/env python3 from copy import copy -from configparser import ConfigParser from pathlib import Path from packaging.requirements import Requirement, SpecifierSet +try: + from tomllib import loads # Python +3.11 +except ImportError: + from pip._vendor.tomli import loads + repo_root = Path(__file__).parent.parent -setup_cfg = repo_root / "setup.cfg" +pyproject = repo_root / "pyproject.toml" reqs = repo_root / "requirements.txt" min_reqs = repo_root / "min-requirements.txt" -config = ConfigParser() -config.read(setup_cfg) requirements = [ Requirement(req) - for req in config.get("options", "install_requires").strip().splitlines() + for req in loads(pyproject.read_text())["project"]["dependencies"] ] script_name = Path(__file__).relative_to(repo_root) diff --git a/MANIFEST.in b/MANIFEST.in deleted file mode 100644 index f3d419c384..0000000000 --- a/MANIFEST.in +++ /dev/null @@ -1,7 +0,0 @@ -recursive-exclude .circleci/ * -recursive-exclude .docker/ * -recursive-exclude .github/ * -recursive-exclude docs/ * - -exclude .* -exclude Dockerfile diff --git a/min-requirements.txt b/min-requirements.txt index a55b069073..a426f4f74f 100644 --- a/min-requirements.txt +++ b/min-requirements.txt @@ -1,6 +1,5 @@ # Auto-generated by .maint/update_requirements.py attrs==20.1.0 -importlib_resources==5.7; python_version < "3.11" nibabel==3.1.0 nipype==1.8.5 traits<6.4 diff --git a/pyproject.toml b/pyproject.toml index fee7fc6618..befa79cb49 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,10 +1,184 @@ [build-system] -requires = ["setuptools >= 42.0", "wheel", "setuptools_scm[toml] >= 3.4"] - -[tool.setuptools_scm] -write_to = "sdcflows/_version.py" -write_to_template = """\ -\"\"\"Version file, automatically generated by setuptools_scm.\"\"\" -__version__ = "{version}" -""" -fallback_version = "0.0" +requires = ["hatchling", "hatch-vcs", "nipreps-versions"] +build-backend = "hatchling.build" + +[project] +name = "sdcflows" +description = "Susceptibility Distortion Correction (SDC) workflows for EPI MR schemes." +readme = "README.rst" +authors = [{name = "The NiPreps Developers", email = "nipreps@gmail.com"}] +classifiers = [ + "Development Status :: 4 - Beta", + "Intended Audience :: Science/Research", + "Topic :: Scientific/Engineering :: Image Recognition", + "Topic :: Scientific/Engineering :: Bio-Informatics", + "License :: OSI Approved :: Apache Software License", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", +] +license = "Apache-2.0" +requires-python = ">=3.10" +dependencies = [ + "attrs >= 20.1.0", + "nibabel >=3.1.0", + "nipype >=1.8.5,<2.0", + "traits <6.4", + "niworkflows >= 1.7.0", + "nitransforms >= 23.0.1", + "numpy >= 1.21.0", + "pybids >= 0.15.1", + "scikit-image >= 0.18", + "scipy >= 1.8.1", + "templateflow", +] +dynamic = ["version"] + +[project.urls] +Documentation = "https://www.nipreps.org/sdcflows" +Home = "https://github.com/nipreps/sdcflows" +NiPreps = "https://www.nipreps.org/" + +[project.optional-dependencies] +doc = [ + "attrs >= 20.1.0", + "furo", + "importlib_resources", + "matplotlib >= 2.2.0", + "nibabel", + "nipype >= 1.5.1", + "traits < 6.4", + "niworkflows >= 1.7.0", + "numpy", + "packaging", + "pydot >= 1.2.3", + "pydotplus", + "sphinx >= 7.2.2", + "sphinxcontrib-apidoc", + "templateflow" +] + +mem = [ + "psutil" +] + +dev = [ + "black", + "pre-commit", + "isort", + "flake8-pyproject", +] + +test = [ + "coverage", + "pytest", + "pytest-cov", + "pytest-env", + "pytest-xdist" +] + +# Aliases +docs = ["sdcflows[doc]"] +tests = ["sdcflows[test]"] +all = ["sdcflows[doc,test,mem,dev,test]"] + +[project.scripts] +sdcflows-find-estimators = "sdcflows.cli.find_estimators:main" + +# +# Hatch configurations +# + +[tool.hatch.metadata] +allow-direct-references = true + +[tool.hatch.build.targets.sdist] +exclude = [".git_archival.txt"] # No longer needed in sdist + +[tool.hatch.build.targets.wheel] +packages = ["sdcflows"] +# exclude = [ +# "sdcflows/tests/data", # Large test data directory +# ] + +## The following two sections configure setuptools_scm in the hatch way + +[tool.hatch.version] +validate-bump = true +source = "vcs" +raw-options = { version_scheme = "nipreps-calver" } + +[tool.hatch.build.hooks.vcs] +version-file = "sdcflows/_version.py" + +# +# Developer tool configurations +# + +[tool.black] +line-length = 99 +target-version = ['py39'] +skip-string-normalization = true +exclude = ''' +# Directories +/( + \.eggs + | \.git + | \.hg + | \.mypy_cache + | \.tox + | \.venv + | venv + | _build + | build + | dist +)/ +''' + +[tool.isort] +profile = 'black' +skip_gitignore = true + +[tool.flake8] +max-line-length = "99" +doctests = "False" +exclude = "*build/" +ignore = ["W503", "E203"] +per-file-ignores = [ + "**/__init__.py : F401", + "docs/conf.py : E265", +] + +[tool.pytest.ini_options] +norecursedirs = [".git"] +addopts = "-svx --doctest-modules" +doctest_optionflags = "ALLOW_UNICODE NORMALIZE_WHITESPACE ELLIPSIS" +env = "PYTHONHASHSEED=0" +filterwarnings = ["ignore::DeprecationWarning"] +junit_family = "xunit2" + + +[tool.coverage.run] +branch = true +concurrency = 'multiprocessing' +omit = [ + '*/tests/*', + '*/__init__.py', + '*/conftest.py', + 'sdcflows/_version.py' +] + +[tool.coverage.report] +# Regexes for lines to exclude from consideration +exclude_lines = [ + 'raise NotImplementedError', + 'warnings\.warn', +] + +[tool.codespell] +# nd - import scipy.ndimage as nd +# mapp, reson -- Mapp. and Reson. abbreviations in citation +ignore-words-list = 'nd,mapp,reson' +skip = """ +./.git,*.pdf,*.svg,*.min.js,*.ipynb,ORIGINAL_LICENSE,\ +./docs/source/_static/example_anatreport.html""" diff --git a/requirements.txt b/requirements.txt index 058e99062e..190b51e41f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,5 @@ # Auto-generated by .maint/update_requirements.py attrs>=20.1.0 -importlib_resources>=5.7; python_version < "3.11" nibabel>=3.1.0 nipype<2.0,>=1.8.5 traits<6.4 diff --git a/sdcflows/interfaces/tests/test_utils.py b/sdcflows/interfaces/tests/test_utils.py index 702ec5860d..d12d04cbc9 100644 --- a/sdcflows/interfaces/tests/test_utils.py +++ b/sdcflows/interfaces/tests/test_utils.py @@ -55,9 +55,7 @@ def test_ConvertWarp(tmpdir, shape): """Exercise the interface.""" tmpdir.chdir() - nb.Nifti1Image(np.zeros(shape, dtype="uint8"), np.eye(4), None).to_filename( - "3dQwarp.nii.gz" - ) + nb.Nifti1Image(np.zeros(shape, dtype="uint8"), np.eye(4), None).to_filename("3dQwarp.nii.gz") out = ConvertWarp(in_file="3dQwarp.nii.gz").run() @@ -80,9 +78,7 @@ def test_Xeoblique(tmpdir, angles, oblique): tmpdir.chdir() affine = nb.affines.from_matvec(nb.eulerangles.euler2mat(*angles)) - nb.Nifti1Image(np.zeros((10, 10, 10), dtype="uint8"), affine, None).to_filename( - "epi.nii.gz" - ) + nb.Nifti1Image(np.zeros((10, 10, 10), dtype="uint8"), affine, None).to_filename("epi.nii.gz") result = ( Deoblique( @@ -108,12 +104,15 @@ def test_Xeoblique(tmpdir, angles, oblique): assert np.allclose(nb.load(reoblique.out_epi).affine, affine) -@pytest.mark.parametrize("in_shape,expected_shape,padded", [ - ((2,2,2), (2,2,2), False), - ((2,2,3), (2,2,4), True), - ((3,3,2,2), (3,3,2,2), False), - ((3,3,3,2), (3,3,4,2), True), -]) +@pytest.mark.parametrize( + "in_shape,expected_shape,padded", + [ + ((2, 2, 2), (2, 2, 2), False), + ((2, 2, 3), (2, 2, 4), True), + ((3, 3, 2, 2), (3, 3, 2, 2), False), + ((3, 3, 3, 2), (3, 3, 4, 2), True), + ], +) def test_pad_slices(tmpdir, in_shape, expected_shape, padded): tmpdir.chdir() diff --git a/sdcflows/interfaces/utils.py b/sdcflows/interfaces/utils.py index 635c3c0509..554139925b 100644 --- a/sdcflows/interfaces/utils.py +++ b/sdcflows/interfaces/utils.py @@ -83,9 +83,7 @@ def _run_interface(self, runtime): ) # Unzip out_data, out_meta outputs. - self._results["out_data"], self._results["out_meta"] = zip( - *self._results["out_list"] - ) + self._results["out_data"], self._results["out_meta"] = zip(*self._results["out_list"]) return runtime @@ -129,18 +127,14 @@ def _run_interface(self, runtime): continue nii = nb.load(fname) - retval[i] = fname_presuffix( - fname, suffix=f"_regrid{i:03d}", newpath=runtime.cwd - ) + retval[i] = fname_presuffix(fname, suffix=f"_regrid{i:03d}", newpath=runtime.cwd) if np.allclose(nii.shape[:3], refshape) and np.allclose(nii.affine, refaff): if np.all(nii.affine == refaff): retval[i] = fname else: # Set reference's affine if difference is small - nii.__class__(nii.dataobj, refaff, nii.header).to_filename( - retval[i] - ) + nii.__class__(nii.dataobj, refaff, nii.header).to_filename(retval[i]) continue resampler.apply(nii).to_filename(retval[i]) @@ -152,9 +146,7 @@ def _run_interface(self, runtime): class _ReorientImageAndMetadataInputSpec(TraitedSpec): in_file = File(exists=True, mandatory=True, desc="Input 3- or 4D image") - target_orientation = traits.Str( - desc="Axis codes of coordinate system to reorient to" - ) + target_orientation = traits.Str(desc="Axis codes of coordinate system to reorient to") pe_dir = InputMultiObject( traits.Enum( *["".join(p) for p in product("ijkxyz", ("", "-"))], @@ -185,9 +177,7 @@ def _run_interface(self, runtime): target = self.inputs.target_orientation.upper() if not all(code in "RASLPI" for code in target): - raise ValueError( - f"Invalid orientation code {self.inputs.target_orientation}" - ) + raise ValueError(f"Invalid orientation code {self.inputs.target_orientation}") img = nb.load(self.inputs.in_file) img2target = nb.orientations.ornt_transform( @@ -208,9 +198,7 @@ def _run_interface(self, runtime): pe_dirs = [reorient_pedir(pe_dir, img2target) for pe_dir in self.inputs.pe_dir] self._results = dict( - out_file=fname_presuffix( - self.inputs.in_file, suffix=target, newpath=runtime.cwd - ), + out_file=fname_presuffix(self.inputs.in_file, suffix=target, newpath=runtime.cwd), pe_dir=pe_dirs, ) @@ -234,16 +222,12 @@ class ConvertWarp(SimpleInterface): output_spec = _ConvertWarpOutputSpec def _run_interface(self, runtime): - self._results["out_file"] = _qwarp2ants( - self.inputs.in_file, newpath=runtime.cwd - ) + self._results["out_file"] = _qwarp2ants(self.inputs.in_file, newpath=runtime.cwd) return runtime class _DeobliqueInputSpec(BaseInterfaceInputSpec): - in_file = File( - exists=True, mandatory=True, desc="the input dataset potentially oblique" - ) + in_file = File(exists=True, mandatory=True, desc="the input dataset potentially oblique") in_mask = File( exists=True, desc="a binary mask corresponding to the input dataset", @@ -284,9 +268,7 @@ class _ReobliqueInputSpec(BaseInterfaceInputSpec): mandatory=True, desc="the plumb field map, extracted from the displacements field estimated by SyN", ) - in_epi = File( - exists=True, mandatory=True, desc="the original, potentially oblique EPI image" - ) + in_epi = File(exists=True, mandatory=True, desc="the original, potentially oblique EPI image") in_mask = File( exists=True, desc="a binary mask corresponding to the input dataset", @@ -342,9 +324,7 @@ class DenoiseImage(_DenoiseImageBase, _CopyHeaderInterface): class _PadSlicesInputSpec(BaseInterfaceInputSpec): in_file = File(exists=True, mandatory=True, desc="3D or 4D NIfTI image") axis = traits.Int( - 2, - usedefault=True, - desc="The axis through which slices are stacked in the input data" + 2, usedefault=True, desc="The axis through which slices are stacked in the input data" ) @@ -359,12 +339,15 @@ class PadSlices(SimpleInterface): This intends to avoid TOPUP's segfault without changing the standard configuration """ + input_spec = _PadSlicesInputSpec output_spec = _PadSlicesOutputSpec def _run_interface(self, runtime): self._results["out_file"], self._results["padded"] = _pad_num_slices( - self.inputs.in_file, self.inputs.axis, runtime.cwd, + self.inputs.in_file, + self.inputs.axis, + runtime.cwd, ) return runtime @@ -385,10 +368,7 @@ class PositiveDirectionCosines(SimpleInterface): output_spec = _PositiveDirectionCosinesOutputSpec def _run_interface(self, runtime): - ( - self._results["out_file"], - self._results["in_orientation"] - ) = _ensure_positive_cosines( + (self._results["out_file"], self._results["in_orientation"]) = _ensure_positive_cosines( self.inputs.in_file, newpath=runtime.cwd, ) @@ -459,10 +439,7 @@ def _deoblique(in_file, in_affine=None, newpath=None): if in_affine is None: orientation = nb.aff2axcodes(nii.affine) directions = ( - np.array( - [int(l1 == l2) for l1, l2 in zip(orientation, "RAS")], dtype="float32" - ) - * 2 + np.array([int(l1 == l2) for l1, l2 in zip(orientation, "RAS")], dtype="float32") * 2 - 1 ) newaff = np.eye(4) @@ -490,13 +467,10 @@ def _reoblique(in_epi, in_plumb, in_field, in_mask=None, newpath=None): return in_plumb, in_field, in_mask out_files = [ - fname_presuffix(f, suffix="_oriented", newpath=newpath) - for f in (in_plumb, in_field) + fname_presuffix(f, suffix="_oriented", newpath=newpath) for f in (in_plumb, in_field) ] + [None] plumbnii = nb.load(in_plumb) - plumbnii.__class__(plumbnii.dataobj, epinii.affine, epinii.header).to_filename( - out_files[0] - ) + plumbnii.__class__(plumbnii.dataobj, epinii.affine, epinii.header).to_filename(out_files[0]) fmapnii = nb.load(in_field) hdr = fmapnii.header.copy() @@ -546,7 +520,7 @@ def _pad_num_slices(in_file, ax=2, newpath=None): if img.shape[ax] % 2 == 0: return in_file, False - pwidth = [(0,0)] * len(img.shape) + pwidth = [(0, 0)] * len(img.shape) pwidth[ax] = (0, 1) padded = np.pad(img.dataobj, pwidth) hdr = img.header diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index bf6733a744..0000000000 --- a/setup.cfg +++ /dev/null @@ -1,113 +0,0 @@ -[metadata] -author = The SDCflows developers -author_email = nipreps@gmail.com -classifiers = - Development Status :: 4 - Beta - Intended Audience :: Science/Research - Topic :: Scientific/Engineering :: Image Recognition - License :: OSI Approved :: Apache Software License - Programming Language :: Python :: 3.8 - Programming Language :: Python :: 3.9 - Programming Language :: Python :: 3.10 - Programming Language :: Python :: 3.11 - Programming Language :: Python :: 3.12 -description = Susceptibility Distortion Correction (SDC) workflows for EPI MR schemes. -license = Apache-2.0 -long_description = file:README.rst -long_description_content_type = text/x-rst; charset=UTF-8 -name = sdcflows -project_urls = - Documentation = https://www.nipreps.org/sdcflows - GitHub = https://github.com/nipreps/sdcflows - fMRIPrep = https://fmriprep.readthedocs.io -url = https://www.nipreps.org/sdcflows - -[options] -python_requires = >=3.8 -install_requires = - attrs >= 20.1.0 - importlib_resources >= 5.7; python_version < '3.11' - nibabel >=3.1.0 - nipype >=1.8.5,<2.0 - traits <6.4 - niworkflows >= 1.7.0 - nitransforms >= 23.0.1 - numpy >= 1.21.0 - pybids >= 0.15.1 - scikit-image >= 0.18 - scipy >= 1.8.1 - templateflow -packages = find: -include_package_data = True -zip_safe = True - -[options.exclude_package_data] -* = tests - -[options.extras_require] -doc = - furo ~= 2021.10.09 - pydot - pydotplus - sphinx - sphinxcontrib-apidoc - sphinxcontrib-napoleon -docs = - %(doc)s -mem = - psutil - -test = - coverage - pytest - pytest-cov - pytest-env - pytest-xdist -tests = - %(test)s - -all = - %(doc)s - %(mem)s - %(test)s - -[options.package_data] -sdcflows = - data/*.json - data/*.nii.gz - data/*.mat - data/flirtsch/*.cnf - -[options.entry_points] -console_scripts = - sdcflows-find-estimators=sdcflows.cli.find_estimators:main - -[flake8] -max-line-length = 99 -doctests = False -ignore = - W503 - E231 - E203 -exclude = - *build/ - docs/sphinxext/ - docs/tools/ -per-file-ignores = - **/__init__.py : F401 - docs/conf.py : E265 - -[tool:pytest] -norecursedirs = .git -addopts = -vsx --doctest-modules -doctest_optionflags = ALLOW_UNICODE NORMALIZE_WHITESPACE NUMBER -env = - PYTHONHASHSEED=0 -filterwarnings = - ignore::DeprecationWarning - ignore::PendingDeprecationWarning - ignore:cmp not installed:UserWarning - ignore:This has not been fully tested:UserWarning - -[coverage:run] -concurrency = multiprocessing diff --git a/setup.py b/setup.py deleted file mode 100644 index c2b82d2f5b..0000000000 --- a/setup.py +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# @Author: oesteban -# @Date: 2015-11-19 16:44:27 -"""sdcflows setup script.""" - - -def main(): - """Install entry-point.""" - from setuptools import setup - - setup( - name="sdcflows", use_scm_version=True, - ) - - -if __name__ == "__main__": - main()