update: add support for pre-commit #232

Merged
synchon merged 10 commits from enh/pre-commit into main 2023-06-21 10:48:42 +00:00
49 changed files with 195 additions and 145 deletions

48
.pre-commit-config.yaml Normal file
View file

@ -0,0 +1,48 @@
ci:
autofix_prs: false
autoupdate_commit_msg: "chore: bump pre-commit repositories"
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: check-ast
- id: check-docstring-first
- id: check-executables-have-shebangs
- id: check-merge-conflict
- id: check-yaml
- id: check-toml
- id: debug-statements
- id: end-of-file-fixer
- id: trailing-whitespace
args: [--markdown-linebreak-ext=md]
- repo: https://github.com/abravalheri/validate-pyproject
rev: v0.12.2
hooks:
- id: validate-pyproject
- repo: https://github.com/psf/black
rev: 23.3.0
hooks:
- id: black
exclude: ^(docs/|examples/|tools/)
args: [--check]
- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: v0.0.267
hooks:
- id: ruff
exclude: ^(__init__.py)
args: [--format, grouped, --show-fixes]
- repo: https://github.com/codespell-project/codespell
rev: v2.2.4
hooks:
- id: codespell
exclude: ^(.github/|docs/)
args: [--config, tox.ini]
- repo: https://github.com/pre-commit/pygrep-hooks
rev: v1.10.0
hooks:
- id: python-no-eval
- id: python-no-log-warn
- id: rst-backticks
- id: rst-directive-colons
- id: rst-inline-touching-normal

View file

@ -10,6 +10,7 @@
![Codecov](https://img.shields.io/codecov/c/github/juaml/junifer?style=flat-square) ![Codecov](https://img.shields.io/codecov/c/github/juaml/junifer?style=flat-square)
[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg?style=flat-square)](https://github.com/psf/black) [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg?style=flat-square)](https://github.com/psf/black)
[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v2.json)](https://github.com/charliermarsh/ruff) [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v2.json)](https://github.com/charliermarsh/ruff)
[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit)](https://github.com/pre-commit/pre-commit)
## About ## About

View file

@ -0,0 +1 @@
Adopt ``pre-commmit`` for adding and managing git pre-commit hooks by `Synchon Mandal`_

View file

@ -38,6 +38,12 @@ Setting up the local development environment
Now you can make your changes locally. Now you can make your changes locally.
#. Make sure you install git pre-commit hooks like so:
.. code-block:: bash
pre-commit install
#. When making changes locally, it is helpful to ``git commit`` your work #. When making changes locally, it is helpful to ``git commit`` your work
regularly. On one hand to save your work and on the other hand, the smaller regularly. On one hand to save your work and on the other hand, the smaller
the steps, the easier it is to review your work later. Please use `semantic the steps, the easier it is to review your work later. Please use `semantic
@ -49,6 +55,14 @@ Setting up the local development environment
git add . git add .
git commit -m "<prefix>: <summary of changes>" git commit -m "<prefix>: <summary of changes>"
In case, you want to commit some WIP (work-in-progress) code, please indicate
that in the commit message and use the flag ``--no-verify`` with
``git commit`` like so:
.. code-block:: bash
git commit --no-verify -m "WIP: <summary of changes>"
#. When you're done making changes, check that your changes pass our test suite. #. When you're done making changes, check that your changes pass our test suite.
This is all included with ``tox``. This is all included with ``tox``.
@ -62,7 +76,6 @@ Setting up the local development environment
tox --parallel tox --parallel
#. Push your branch to GitHub. #. Push your branch to GitHub.
.. code-block:: bash .. code-block:: bash

View file

@ -35,9 +35,9 @@ c. the experiment included resting-stage fMRI and a task named *stroop*
then the *element* should be composed of 3 items: then the *element* should be composed of 3 items:
* ``subject``: The subject IDs, e.g. `sub001`, `sub002`, ... `sub020` * ``subject``: The subject IDs, e.g. ``sub001``, ``sub002``, ... ``sub020``
* ``session``: The session number, e.g. `ses1`, `ses2` * ``session``: The session number, e.g. ``ses1``, ``ses2``
* ``task``: The task performed, e.g. `rest`, `stroop` * ``task``: The task performed, e.g. ``rest``, ``stroop``
If any of these items were not part of the element, then we will have more than If any of these items were not part of the element, then we will have more than
one ``T1w`` and / or ``BOLD`` image for each subject, which is not allowed. one ``T1w`` and / or ``BOLD`` image for each subject, which is not allowed.
@ -49,9 +49,10 @@ for the element (``sub001``, ``ses1``, ``rest``) will be the same as the
``T1w`` image for the element (``sub001``, ``ses1``, ``stroop``). ``T1w`` image for the element (``sub001``, ``ses1``, ``stroop``).
We will now continue this section using as an example, a dataset in BIDS format We will now continue this section using as an example, a dataset in BIDS format
in which 9 subjects (`sub-01` to `sub-09`) were scanned each during 3 in which 9 subjects (``sub-01`` to ``sub-09``) were scanned each during 3
sessions (`ses-01`, `ses-02`, `ses-03`) and each session included a `T1w` and sessions (``ses-01``, ``ses-02``, ``ses-03``) and each session included a
a `BOLD` image (resting-state), except for `ses-03` which was only anatomical. ``T1w`` and a ``BOLD`` image (resting-state), except for ``ses-03`` which was
only anatomical.
Step 2: Think about the dataset's structure Step 2: Think about the dataset's structure
------------------------------------------- -------------------------------------------
@ -63,7 +64,7 @@ the Data Grabber needs to be implemented.
Junifer provides an abstract class to deal with datasets that can be thought in Junifer provides an abstract class to deal with datasets that can be thought in
terms of *patterns*. A *pattern* is a string that contains placeholders that are terms of *patterns*. A *pattern* is a string that contains placeholders that are
replaced by the actual values of the element. In our BIDS example, the path replaced by the actual values of the element. In our BIDS example, the path
to the T1w image of subject `sub-01` and session `ses-01`, relative to the to the T1w image of subject ``sub-01`` and session ``ses-01``, relative to the
dataset location, is ``sub-01/ses-01/anat/sub-01_ses-01_T1w.nii.gz``. By dataset location, is ``sub-01/ses-01/anat/sub-01_ses-01_T1w.nii.gz``. By
replacing ``sub-01`` with ``sub-02``, we can obtain the T1w image of the first replacing ``sub-01`` with ``sub-02``, we can obtain the T1w image of the first
session of the second subject. Indeed, the path to the T1w images can be session of the second subject. Indeed, the path to the T1w images can be

View file

@ -22,4 +22,3 @@ markers:
storage: storage:
kind: SQLiteFeatureStorage kind: SQLiteFeatureStorage
uri: /data/project/ukb_motor/junifer_test/test.sqlite uri: /data/project/ukb_motor/junifer_test/test.sqlite

View file

@ -6,4 +6,3 @@
-36 -46 46 Parietal_Inf_L -36 -46 46 Parietal_Inf_L
38 -46 44 Parietal_Inf_R 38 -46 44 Parietal_Inf_R
-26 0 54 Frontal_Mid_L -26 0 54 Frontal_Mid_L

View file

@ -4,4 +4,3 @@
46 -62 32 rAG 46 -62 32 rAG
-24 -22 -20 lHF -24 -22 -20 lHF
24 -22 -20 rHF 24 -22 -20 rHF

View file

@ -7,4 +7,3 @@
-34 -52 56 Parietal_Inf_L -34 -52 56 Parietal_Inf_L
32 -52 50 Parietal_Inf_R 32 -52 50 Parietal_Inf_R
32 6 58 Frontal_Mid_R 32 6 58 Frontal_Mid_R

View file

@ -20,14 +20,12 @@ _vois_path = Path(__file__).parent / "VOIs"
# Path to the metadata of the VOIs # Path to the metadata of the VOIs
_vois_meta_path = _vois_path / "meta" _vois_meta_path = _vois_path / "meta"
""" # A dictionary containing all supported coordinates and their respective file
A dictionary containing all supported coordinates and their respective file or # or data.
data.
The built-in coordinates are files that are shipped with the package in the # The built-in coordinates are files that are shipped with the package in the
data/VOIs directory. The user can also register their own coordinates, which # data/VOIs directory. The user can also register their own coordinates, which
will be stored as numpy arrays in the dictionary. # will be stored as numpy arrays in the dictionary.
"""
_available_coordinates: Dict[ _available_coordinates: Dict[
str, Union[Path, Dict[str, Union[ArrayLike, List[str]]]] str, Union[Path, Dict[str, Union[ArrayLike, List[str]]]]
] = { ] = {

View file

@ -63,16 +63,14 @@ def _fetch_icbm152_brain_gm_mask(
return mask return mask
""" # A dictionary containing all supported masks and their respective file or
A dictionary containing all supported masks and their respective file or # data.
data.
The built-in masks are files that are shipped with the package in the # The built-in masks are files that are shipped with the package in the
data/masks directory. The user can also register their own masks. # data/masks directory. The user can also register their own masks.
Callable masks should be functions that take at least one parameter: # Callable masks should be functions that take at least one parameter:
* `target_img`: the image to which the mask will be applied. # * `target_img`: the image to which the mask will be applied.
"""
_available_masks: Dict[str, Dict[str, Any]] = { _available_masks: Dict[str, Dict[str, Any]] = {
"GM_prob0.2": {"family": "Vickery-Patil"}, "GM_prob0.2": {"family": "Vickery-Patil"},
"GM_prob0.2_cortex": {"family": "Vickery-Patil"}, "GM_prob0.2_cortex": {"family": "Vickery-Patil"},

View file

@ -26,18 +26,16 @@ if TYPE_CHECKING:
from nibabel import Nifti1Image from nibabel import Nifti1Image
""" # A dictionary containing all supported parcellations and their respective
A dictionary containing all supported parcellations and their respective valid # valid parameters.
parameters.
Each entry is a dictionary that must contain at least the following keys: # Each entry is a dictionary that must contain at least the following keys:
* 'family': the parcellation's family name (e.g. 'Schaefer', 'SUIT') # * 'family': the parcellation's family name (e.g. 'Schaefer', 'SUIT')
Optional keys: # Optional keys:
* 'valid_resolutions': a list of valid resolutions for the parcellation # * 'valid_resolutions': a list of valid resolutions for the parcellation
(e.g. [1, 2]) # (e.g. [1, 2])
"""
# TODO: have separate dictionary for built-in # TODO: have separate dictionary for built-in
_available_parcellations: Dict[str, Dict[Any, Any]] = { _available_parcellations: Dict[str, Dict[Any, Any]] = {
"SUITxSUIT": {"family": "SUIT", "space": "SUIT"}, "SUITxSUIT": {"family": "SUIT", "space": "SUIT"},

View file

@ -29,39 +29,37 @@ if TYPE_CHECKING:
from pandas import DataFrame from pandas import DataFrame
""" # New BSD License
New BSD License
Copyright (c) 2007 - 2022 The nilearn developers. # Copyright (c) 2007 - 2022 The nilearn developers.
All rights reserved. # All rights reserved.
Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: # modification, are permitted provided that the following conditions are met:
a. Redistributions of source code must retain the above copyright notice, # a. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer. # this list of conditions and the following disclaimer.
b. Redistributions in binary form must reproduce the above copyright # b. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the # notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution. # documentation and/or other materials provided with the distribution.
c. Neither the name of the nilearn developers nor the names of # c. Neither the name of the nilearn developers nor the names of
its contributors may be used to endorse or promote products # its contributors may be used to endorse or promote products
derived from this software without specific prior written # derived from this software without specific prior written
permission. # permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR # ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE. # DAMAGE.
"""
def _apply_mask_and_get_affinity( def _apply_mask_and_get_affinity(

View file

@ -15,39 +15,37 @@ from numpy.testing import assert_array_equal
from junifer.external.nilearn import JuniferNiftiSpheresMasker from junifer.external.nilearn import JuniferNiftiSpheresMasker
""" # New BSD License
New BSD License
Copyright (c) 2007 - 2022 The nilearn developers. # Copyright (c) 2007 - 2022 The nilearn developers.
All rights reserved. # All rights reserved.
Redistribution and use in source and binary forms, with or without # Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met: # modification, are permitted provided that the following conditions are met:
a. Redistributions of source code must retain the above copyright notice, # a. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer. # this list of conditions and the following disclaimer.
b. Redistributions in binary form must reproduce the above copyright # b. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the # notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution. # documentation and/or other materials provided with the distribution.
c. Neither the name of the nilearn developers nor the names of # c. Neither the name of the nilearn developers nor the names of
its contributors may be used to endorse or promote products # its contributors may be used to endorse or promote products
derived from this software without specific prior written # derived from this software without specific prior written
permission. # permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR # ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE. # DAMAGE.
"""
def test_seed_extraction() -> None: def test_seed_extraction() -> None:

View file

@ -61,7 +61,7 @@ repository = "https://github.com/juaml/junifer"
junifer = "junifer.api.cli:cli" junifer = "junifer.api.cli:cli"
[project.optional-dependencies] [project.optional-dependencies]
dev = ["tox"] dev = ["tox", "pre-commit"]
docs = [ docs = [
"seaborn>=0.11.2,<0.12", "seaborn>=0.11.2,<0.12",
"Sphinx>=5.3.0,<5.4", "Sphinx>=5.3.0,<5.4",