diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index bbfd35e24..017ce2de3 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -17,24 +17,22 @@ repos: - id: trailing-whitespace args: [--markdown-linebreak-ext=md] - repo: https://github.com/abravalheri/validate-pyproject - rev: v0.23 + rev: v0.24.1 hooks: - id: validate-pyproject - - repo: https://github.com/psf/black-pre-commit-mirror - rev: 24.10.0 - hooks: - - id: black - exclude: ^(docs/|examples/|tools/) - args: [--check] - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.9.3 + rev: v0.11.2 hooks: - id: ruff types_or: [python, jupyter] exclude: ^(__init__.py) args: [--output-format, grouped, --show-fixes] + - id: ruff-format + types_or: [python, jupyter] + exclude: ^(__init__.py) + args: [--check, --diff] - repo: https://github.com/codespell-project/codespell - rev: v2.4.0 + rev: v2.4.1 hooks: - id: codespell exclude: ^(.github/|docs/) @@ -47,10 +45,3 @@ repos: - id: rst-backticks - id: rst-directive-colons - id: rst-inline-touching-normal - - repo: https://github.com/adamchainz/blacken-docs - rev: "1.19.1" - hooks: - - id: blacken-docs - additional_dependencies: - - black==24.4.2 - args: [-l 79] diff --git a/README.md b/README.md index b30d48439..87c303509 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,6 @@ [![Anaconda-Server Badge](https://anaconda.org/conda-forge/junifer/badges/version.svg)](https://anaconda.org/conda-forge/junifer) ![GitHub](https://img.shields.io/github/license/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) [![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) [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.8176570.svg)](https://doi.org/10.5281/zenodo.8176570) diff --git a/conda-env.yml b/conda-env.yml index f50aa5330..ac1c7544d 100644 --- a/conda-env.yml +++ b/conda-env.yml @@ -1,33 +1,45 @@ name: junifer-dev channels: - conda-forge - - defaults dependencies: - - python>=3.10,<=3.11 - - click=8.1.* - - numpy>=1.22,<1.27 - - pandas>=1.4.0,<2.2 - - nibabel>=3.2.0,<5.2 - - nilearn>=0.9.0,<=0.10.1 - - sqlalchemy>=1.4.27,<= 2.0.21 - - ruamel.yaml=0.17.* - - h5py>=3.8,<=3.9 - - seaborn>=0.11,<=0.13 - - sphinx>=5.3,<7.3 - - sphinx-gallery>=0.11.0,<0.15.0 - - furo>=2022.9.29,<2023.10.0 - - numpydoc>=1.5.0,<1.6 + - python>=3.10,<=3.13 + - click>=8.1.3,<8.2 + - numpy>=1.26.0,<2.0.0 + - scipy>=1.10.0,<=1.15.0 + - pandas>=2.0.0,<2.3.0 + - nibabel>=5.2.0,<5.4.0 + - nilearn>=0.10.3,<=0.10.4 + - sqlalchemy>=2.0.25,<=2.1.0 + - ruamel.yaml>=0.17,<0.19 + - h5py>=3.10 + - tqdm>=4.66.1,<4.67.0 + - templateflow>=23.0.0 + - lapy>=1.0.0,<2.0.0 + - lazy_loader==0.4 + - importlib_metadata + - looseversion==1.3.0 + - bctpy==0.6.0 + - neurokit2>=0.1.7 + - seaborn>=0.13.0,<0.14.0 + - sphinx>=7.3.0,<8.1.0 + - sphinx-gallery>=0.17.0,<0.18.0 + - furo>=2024.4.27,<2024.9.0 + - numpydoc>=1.6.0,<1.9.0 - sphinx-copybutton>=0.5.1,<0.5.3 - - towncrier>=22.12.0,<23.7 + - towncrier>=23.10.0,<24.7.0 - sphinxcontrib-mermaid>=0.8.1,<0.10 + - sphinxcontrib-towncrier==0.4.0a0 + - setuptools-scm>=8 - tox + - pre-commit + - ruff>=0.1.0 - ipykernel - pytest-cov - pytest - - black - - ruff - codespell + - tomli - pip - pip: - - datalad>=0.15.4,<0.20 - - julearn==0.3.0 + - datalad>=1.0.0,<1.2.0 + - julearn==0.3.3 + - junifer_data==1.3.0 diff --git a/docs/changes/newsfragments/441.misc b/docs/changes/newsfragments/441.misc new file mode 100644 index 000000000..c238dbe7e --- /dev/null +++ b/docs/changes/newsfragments/441.misc @@ -0,0 +1 @@ +Regular repository maintenance by updating ``.pre-commit-config.yaml``, replacing ``black`` with ``ruff-format`` and updating tool configs by `Synchon Mandal`_ diff --git a/junifer/api/decorators.py b/junifer/api/decorators.py index bf39c6c5c..e69e3be3c 100644 --- a/junifer/api/decorators.py +++ b/junifer/api/decorators.py @@ -5,7 +5,6 @@ # Synchon Mandal # License: AGPL - from ..pipeline import PipelineComponentRegistry from ..typing import DataGrabberLike, MarkerLike, PreprocessorLike, StorageLike diff --git a/junifer/api/functions.py b/junifer/api/functions.py index 122e8f8c5..5b21bb2e1 100644 --- a/junifer/api/functions.py +++ b/junifer/api/functions.py @@ -294,8 +294,7 @@ def queue( valid_kind = ["HTCondor", "GNUParallelLocal"] if kind not in valid_kind: raise_error( - f"Invalid value for `kind`: {kind}, " - f"must be one of {valid_kind}" + f"Invalid value for `kind`: {kind}, must be one of {valid_kind}" ) # Create a folder within the CWD to store the job files / config diff --git a/junifer/api/queue_context/gnu_parallel_local_adapter.py b/junifer/api/queue_context/gnu_parallel_local_adapter.py index 792c2b91b..fbb7fadf7 100644 --- a/junifer/api/queue_context/gnu_parallel_local_adapter.py +++ b/junifer/api/queue_context/gnu_parallel_local_adapter.py @@ -218,8 +218,7 @@ class GnuParallelLocalAdapter(QueueContextAdapter): # Copy executable if not local if hasattr(self, "_exec_path"): logger.info( - f"Copying {self._executable} to " - f"{self._exec_path.resolve()!s}" + f"Copying {self._executable} to {self._exec_path.resolve()!s}" ) shutil.copy( src=Path(__file__).parent.parent / "res" / self._executable, @@ -235,15 +234,14 @@ class GnuParallelLocalAdapter(QueueContextAdapter): self._elements_file_path.write_text(textwrap.dedent(self.elements())) # Create pre run logger.info( - f"Writing {self._pre_run_path.name} to " - f"{self._job_dir.resolve()!s}" + f"Writing {self._pre_run_path.name} to {self._job_dir.resolve()!s}" ) self._pre_run_path.touch() self._pre_run_path.write_text(textwrap.dedent(self.pre_run())) make_executable(self._pre_run_path) # Create run logger.info( - f"Writing {self._run_path.name} to " f"{self._job_dir.resolve()!s}" + f"Writing {self._run_path.name} to {self._job_dir.resolve()!s}" ) self._run_path.touch() self._run_path.write_text(textwrap.dedent(self.run())) @@ -258,8 +256,7 @@ class GnuParallelLocalAdapter(QueueContextAdapter): make_executable(self._pre_collect_path) # Create collect logger.info( - f"Writing {self._collect_path.name} to " - f"{self._job_dir.resolve()!s}" + f"Writing {self._collect_path.name} to {self._job_dir.resolve()!s}" ) self._collect_path.touch() self._collect_path.write_text(textwrap.dedent(self.collect())) diff --git a/junifer/api/queue_context/htcondor_adapter.py b/junifer/api/queue_context/htcondor_adapter.py index d6fd44630..6715b6dd9 100644 --- a/junifer/api/queue_context/htcondor_adapter.py +++ b/junifer/api/queue_context/htcondor_adapter.py @@ -264,9 +264,7 @@ class HTCondorAdapter(QueueContextAdapter): ) junifer_collect_args = ( - "collect " - f"{self._yaml_config_path.resolve()!s} " - f"{verbose_args}" + f"collect {self._yaml_config_path.resolve()!s} {verbose_args}" ) log_dir_prefix = f"{self._log_dir.resolve()!s}/junifer_collect" fixed = ( @@ -316,7 +314,7 @@ class HTCondorAdapter(QueueContextAdapter): "$DAG_STATUS\n" ) elif self._collect == "on_success_only": - var += f"JOB collect {self._submit_collect_path}\n" "PARENT " + var += f"JOB collect {self._submit_collect_path}\nPARENT " for idx, _ in enumerate(self._elements): var += f"run{idx} " var += "CHILD collect\n" @@ -328,14 +326,13 @@ class HTCondorAdapter(QueueContextAdapter): logger.info("Creating HTCondor job") # Create logs logger.info( - f"Creating logs directory under " f"{self._job_dir.resolve()!s}" + f"Creating logs directory under {self._job_dir.resolve()!s}" ) self._log_dir.mkdir(exist_ok=True, parents=True) # Copy executable if not local if hasattr(self, "_exec_path"): logger.info( - f"Copying {self._executable} to " - f"{self._exec_path.resolve()!s}" + f"Copying {self._executable} to {self._exec_path.resolve()!s}" ) shutil.copy( src=Path(__file__).parent.parent / "res" / self._executable, @@ -344,8 +341,7 @@ class HTCondorAdapter(QueueContextAdapter): make_executable(self._exec_path) # Create pre run logger.info( - f"Writing {self._pre_run_path.name} to " - f"{self._job_dir.resolve()!s}" + f"Writing {self._pre_run_path.name} to {self._job_dir.resolve()!s}" ) self._pre_run_path.touch() self._pre_run_path.write_text(textwrap.dedent(self.pre_run())) @@ -374,7 +370,7 @@ class HTCondorAdapter(QueueContextAdapter): self._submit_collect_path.write_text(textwrap.dedent(self.collect())) # Create DAG logger.debug( - f"Writing {self._dag_path.name} to " f"{self._job_dir.resolve()!s}" + f"Writing {self._dag_path.name} to {self._job_dir.resolve()!s}" ) self._dag_path.touch() self._dag_path.write_text(textwrap.dedent(self.dag())) diff --git a/junifer/cli/tests/test_parser.py b/junifer/cli/tests/test_parser.py index e17e21854..e4d77258e 100644 --- a/junifer/cli/tests/test_parser.py +++ b/junifer/cli/tests/test_parser.py @@ -18,6 +18,23 @@ def test_parse_yaml_failure() -> None: parse_yaml("foo.yaml") +def test_parse_yaml_empty_elements_failure(tmp_path: Path) -> None: + """Test YAML parsing with empty elements failure. + + Parameters + ---------- + tmp_path : pathlib.Path + The path to the test directory. + + """ + # Write test file + fname = tmp_path / "test_parse_yaml_empty_elements_failure.yaml" + fname.write_text("elements:") + # Check test file + with pytest.raises(ValueError, match="elements key was defined"): + parse_yaml(fname) + + def test_parse_yaml_success(tmp_path: Path) -> None: """Test YAML parsing success. @@ -159,6 +176,41 @@ def test_parse_yaml_absolute_path(tmp_path: Path) -> None: parse_yaml(yaml_fname) +def test_parse_yaml_multi_module_deps(tmp_path: Path) -> None: + """Test YAML parsing with multi-module import with deps. + + Parameters + ---------- + tmp_path : pathlib.Path + The path to the test directory. + + """ + t_tmp_path = tmp_path / "test_with_multi_module" + + # Write .py to include + py_path = t_tmp_path / "external" + py_path.mkdir(exist_ok=True, parents=True) + py_fname_1 = py_path / "first.py" + py_fname_1.write_text( + "import numpy as np\nfrom second import hej\n" + "def junifer_module_deps(): return ['second.py']\n" + ) + py_fname_2 = py_path / "second.py" + py_fname_2.write_text("def hej(): print('hej')\n") + + # Write yaml + yaml_path = t_tmp_path / "yamls" + yaml_path.mkdir(exist_ok=True, parents=True) + yaml_fname = yaml_path / "test_parse_yaml_multi_module.yaml" + + yaml_fname.write_text( + "foo: bar\nwith:\n - ../external/first.py\n - scipy\n" + ) + + # Check test file + parse_yaml(yaml_fname) + + def test_parse_storage_uri_relative(tmp_path: Path) -> None: """Test YAML parsing with storage and relative URI. @@ -212,3 +264,17 @@ def test_parse_storage_uri_relative(tmp_path: Path) -> None: assert "foo" in contents assert contents["foo"] == "bar" assert "storage" in contents + + +def test_parse_yaml_queue_venv_relative(tmp_path: Path) -> None: + """Test YAML parsing with relative venv queue. + + Parameters + ---------- + tmp_path : pathlib.Path + The path to the test directory. + + """ + fname = tmp_path / "test_parse_yaml_queue_venv_relative.yaml" + fname.write_text("queue:\n env:\n kind: venv\n name: .venv\n") + _ = parse_yaml(fname) diff --git a/junifer/data/_dispatch.py b/junifer/data/_dispatch.py index c3aa1cef0..4d94f46b4 100644 --- a/junifer/data/_dispatch.py +++ b/junifer/data/_dispatch.py @@ -95,7 +95,7 @@ def get_data( target_data=target_data, extra_input=extra_input, ) - else: + else: # pragma: no cover raise_error(f"Unknown data kind: {kind}") @@ -125,7 +125,7 @@ def list_data(kind: str) -> list[str]: return ParcellationRegistry().list elif kind == "mask": return MaskRegistry().list - else: + else: # pragma: no cover raise_error(f"Unknown data kind: {kind}") @@ -172,7 +172,7 @@ def load_data( return ParcellationRegistry().load(name=name, **kwargs) elif kind == "mask": return MaskRegistry().load(name=name, **kwargs) - else: + else: # pragma: no cover raise_error(f"Unknown data kind: {kind}") @@ -217,7 +217,7 @@ def register_data( return MaskRegistry().register( name=name, space=space, overwrite=overwrite, **kwargs ) - else: + else: # pragma: no cover raise_error(f"Unknown data kind: {kind}") @@ -244,5 +244,5 @@ def deregister_data(kind: str, name: str) -> None: return ParcellationRegistry().deregister(name=name) elif kind == "mask": return MaskRegistry().deregister(name=name) - else: + else: # pragma: no cover raise_error(f"Unknown data kind: {kind}") diff --git a/junifer/data/coordinates/VOIs/meta/AutobiographicalMemory_VOIs.txt b/junifer/data/coordinates/VOIs/meta/AutobiographicalMemory_VOIs.txt deleted file mode 100644 index efa86cbf3..000000000 --- a/junifer/data/coordinates/VOIs/meta/AutobiographicalMemory_VOIs.txt +++ /dev/null @@ -1,23 +0,0 @@ --2 -53 18 PCu-PCC_LR --25 -26 -14 HC-PHC-AMG_L --47 -61 26 TPJ_L --3 47 -1 Medial-prefrontal-cortex_rACC(bilateral)_L --56 -8 -14 STS_MTG_inferior-temporal-sulcus_L --47 25 -5 Ventrolateral-prefrontal-cortex_temporal-pole_L -23 -31 -12 HC-PHC_R --3 12 57 Middle-frontal-gyrus_LR -49 -59 27 TPJ_R --45 3 45 Posterior-lateral-prefrontal-cortex_L --40 47 14 Frontal-pole(lateral)_L -23 -13 -15 HC-PHC_R -49 -5 -13 Temporal-pole_STS_MTG_R --37 14 -32 Temporal-pole_L --37 -81 30 Occ_L --46 24 21 Dorsolateral-prefrontal-cortex_L -50 27 -5 Ventrolateral-prefrontal-cortex_R --11 55 17 Frontal_pole(medial)_L -3 -9 5 Thalamus_R --5 33 22 rACC_L --6 -37 33 PCC_L --28 9 51 Superior-frontal-sulcus_L -28 1 -19 AMG_R diff --git a/junifer/data/coordinates/VOIs/meta/CogAC_VOIs.txt b/junifer/data/coordinates/VOIs/meta/CogAC_VOIs.txt deleted file mode 100644 index de0a46bdd..000000000 --- a/junifer/data/coordinates/VOIs/meta/CogAC_VOIs.txt +++ /dev/null @@ -1,19 +0,0 @@ -36.0 22.0 -4.0 RaIns -2.0 16.0 48.0 preSMA -48.0 12.0 30.0 rIFGp -36.0 2.0 54.0 rdPMC -48.0 30.0 24.0 rIFGa --38.0 -44.0 46.0 lIPS --24.0 -66.0 48.0 lSPL -40.0 -46.0 46.0 rIPS -60.0 -44.0 24.0 rIPC -30.0 -62.0 52.0 rSPL --44.0 10.0 30.0 lIFG --34.0 20.0 -4.0 LaIns --26.0 2.0 52.0 ldPMC -6.0 -18.0 -2.0 rThal --40.0 -66.0 -10.0 lIOG -48.0 19.0 6.0 rIFG -8.0 29.0 30.0 aMCC --45.0 27.0 30.0 lIFG -11.0 7.0 7.0 rNcaud diff --git a/junifer/data/coordinates/VOIs/meta/CogAR_VOIs.txt b/junifer/data/coordinates/VOIs/meta/CogAR_VOIs.txt deleted file mode 100644 index f5c477b9a..000000000 --- a/junifer/data/coordinates/VOIs/meta/CogAR_VOIs.txt +++ /dev/null @@ -1,8 +0,0 @@ --40 -64 -12 Fusiform_L -36 22 -4 Insula_R --44 10 32 Precentral_L -60 -44 24 Temporal_Sup_R -0 18 48 Supp_Motor_Area_L --36 -46 46 Parietal_Inf_L -38 -46 44 Parietal_Inf_R --26 0 54 Frontal_Mid_L diff --git a/junifer/data/coordinates/VOIs/meta/DMNBuckner_VOIs.txt b/junifer/data/coordinates/VOIs/meta/DMNBuckner_VOIs.txt deleted file mode 100644 index e03a949bd..000000000 --- a/junifer/data/coordinates/VOIs/meta/DMNBuckner_VOIs.txt +++ /dev/null @@ -1,6 +0,0 @@ -0 -53 26 PCC -0 52 -6 MPFC --48 -62 36 lAG -46 -62 32 rAG --24 -22 -20 lHF -24 -22 -20 rHF diff --git a/junifer/data/coordinates/VOIs/meta/Dosenbach2010_MNI_VOIs.txt b/junifer/data/coordinates/VOIs/meta/Dosenbach2010_MNI_VOIs.txt deleted file mode 100644 index 37a70997b..000000000 --- a/junifer/data/coordinates/VOIs/meta/Dosenbach2010_MNI_VOIs.txt +++ /dev/null @@ -1,160 +0,0 @@ -6 64 3 vmPFC -29 57 18 aPFC --29 57 10 aPFC -0 51 32 mPFC --25 51 27 aPFC -9 51 16 vmPFC --6 50 -1 vmPFC -27 49 26 aPFC -42 48 -3 vent aPFC --43 47 2 vent aPFC --11 45 17 vmPFC -39 42 16 vlPFC -8 42 -5 vmPFC -9 39 20 ACC -46 39 -15 vlPFC -40 36 29 dlPFC -23 33 47 sup frontal -34 32 7 vPFC --2 30 27 ACC --16 29 54 sup frontal --1 28 40 ACC -46 28 31 dlPFC --52 28 17 vPFC --44 27 33 dlPFC -51 23 8 vFC -38 21 -1 ant insula -9 20 34 dACC --36 18 2 ant insula -40 17 40 dFC --6 17 34 basal ganglia -0 15 45 mFC -58 11 14 frontal --46 10 14 vFC -44 8 34 dFC -60 8 34 dFC --42 7 36 dFC --55 7 23 vFC --20 6 7 basal ganglia -14 6 7 basal ganglia --48 6 1 vFC -10 5 51 pre-SMA -43 1 12 vFC -0 -1 52 SMA -37 -2 -3 mid insula -53 -3 32 frontal -58 -3 17 precentral gyrus --12 -3 13 thalamus --42 -3 11 mid insula --44 -6 49 precentral gyrus --26 -8 54 parietal -46 -8 24 precentral gyrus --54 -9 23 precentral gyrus -44 -11 38 precentral gyrus --47 -12 36 parietal -33 -12 16 mid insula --36 -12 15 mid insula --12 -12 6 thalamus -11 -12 6 thalamus -32 -12 2 mid insula -59 -13 8 temporal --30 -14 1 mid insula --38 -15 59 parietal -52 -15 -13 inf temporal --47 -18 50 parietal -46 -20 45 parietal --55 -22 38 parietal --54 -22 22 precentral gyrus --54 -22 9 temporal -41 -23 55 parietal -42 -24 17 post insula -11 -24 2 basal ganglia --59 -25 -15 inf temporal -1 -26 31 post cingulate -18 -27 62 parietal --38 -27 60 parietal --30 -28 9 post insula --24 -30 64 parietal -51 -30 5 temporal --41 -31 48 post parietal --4 -31 -4 post cingulate -54 -31 -18 fusiform --41 -37 16 temporal --53 -37 13 temporal -28 -37 -15 fusiform --3 -38 45 precuneus -34 -39 65 sup parietal -8 -40 50 precuneus --41 -40 42 IPL -58 -41 20 parietal --8 -41 3 post cingulate --61 -41 -2 inf temporal --28 -42 -11 occipital --5 -43 25 post cingulate -9 -43 25 precuneus -43 -43 8 temporal -54 -44 43 IPL --55 -44 30 parietal --28 -44 -25 lat cerebellum --35 -46 48 post parietal -42 -46 21 sup temporal --48 -47 49 IPL --41 -47 29 angular gyrus --59 -47 11 temporal --53 -50 39 IPL -5 -50 33 precuneus --18 -50 1 occipital -44 -52 47 IPL --5 -52 17 post cingulate --24 -54 -21 lat cerebellum --37 -54 -37 inf cerebellum -10 -55 17 post cingulate --6 -56 29 precuneus --34 -57 -24 lat cerebellum --32 -58 46 IPS --11 -58 17 post cingulate -32 -59 41 IPS -51 -59 34 angular gyrus --34 -60 -5 occipital -36 -60 -8 occipital --6 -60 -15 med cerebellum --25 -60 -34 inf cerebellum -32 -61 -31 inf cerebellum -46 -62 5 temporal --48 -63 35 angular gyrus --52 -63 15 TPJ --44 -63 -7 occipital --16 -64 -21 med cerebellum -21 -64 -22 lat cerebellum -19 -66 -1 occipital -1 -66 -24 med cerebellum --34 -67 -29 inf cerebellum -11 -68 42 precuneus -17 -68 20 occipital --36 -69 40 IPS -39 -71 13 occipital --9 -72 41 occipital -45 -72 29 occipital --11 -72 -14 med cerebellum -29 -73 29 occipital -33 -73 -30 inf cerebellum --2 -75 32 occipital --29 -75 28 occipital -5 -75 -11 med cerebellum -14 -75 -21 med cerebellum --16 -76 33 occipital --42 -76 26 occipital -9 -76 14 occipital -15 -77 32 occipital -20 -78 -2 occipital --21 -79 -33 inf cerebellum --6 -79 -33 inf cerebellum --5 -80 9 post occipital -29 -81 14 post occipital -33 -81 -2 post occipital -18 -81 -33 inf cerebellum --37 -83 -2 post occipital --29 -88 8 post occipital -13 -91 2 post occipital -27 -91 2 post occipital --4 -94 12 post occipital diff --git a/junifer/data/coordinates/VOIs/meta/Empathy_VOIs.txt b/junifer/data/coordinates/VOIs/meta/Empathy_VOIs.txt deleted file mode 100644 index bb7da896b..000000000 --- a/junifer/data/coordinates/VOIs/meta/Empathy_VOIs.txt +++ /dev/null @@ -1,22 +0,0 @@ -2.0 56.0 18.0 dmPFC --8.0 54.0 34.0 dmPFC -36.0 22.0 -8.0 raI --30.0 20.0 4.0 laI -50.0 12.0 -8.0 rIFG -54.0 16.0 20.0 rIFG/Area44 -50.0 30.0 4.0 rIFG/Area45 --44.0 24.0 -6.0 lIFG --4.0 18.0 50.0 SMA --2.0 28.0 20.0 aMCC --4.0 42.0 18.0 rACC --2.0 -32.0 28.0 PCC -52.0 -58.0 22.0 rTPJ --56.0 -58.0 22.0 lTPJ -22.0 -2.0 -16.0 rAm -54.0 -8.0 -16.0 rMTG -52.0 -36.0 2.0 rpSTS --12.0 -4.0 12.0 laTh -6.0 -32.0 2.0 rpTh -26.0 -26.0 -12.0 rHippo -2.0 -20.0 -12.0 Midbrain -14.0 4.0 0.0 rGP diff --git a/junifer/data/coordinates/VOIs/meta/Motor_VOIs.txt b/junifer/data/coordinates/VOIs/meta/Motor_VOIs.txt deleted file mode 100644 index 7659dcc91..000000000 --- a/junifer/data/coordinates/VOIs/meta/Motor_VOIs.txt +++ /dev/null @@ -1,10 +0,0 @@ --39.0 -21.0 54.0 lSMC* -41.0 -16.0 57.0 rSMC* --3.0 -2.0 54.0 SMA --57.0 2.0 32.0 lPMCv --53.0 -24.0 21.0 lIPC -45.0 -38.0 48.0 rIPC --23.0 -7.0 1.0 lBG -25.0 -8.0 3.0 rBG --22.0 -52.0 26.0 lCba -18.0 -54.0 -22.0 rCba diff --git a/junifer/data/coordinates/VOIs/meta/MultiTask_VOIs.txt b/junifer/data/coordinates/VOIs/meta/MultiTask_VOIs.txt deleted file mode 100644 index 19383f19a..000000000 --- a/junifer/data/coordinates/VOIs/meta/MultiTask_VOIs.txt +++ /dev/null @@ -1,9 +0,0 @@ --34 22 -4 leftInsula -34 24 0 rightInsula --26 0 52 Frontal_Mid_L -44 38 28 Frontal_Inf_Tri_R -46 10 28 Frontal_Inf_Oper_R --6 18 50 Supp_Motor_Area_L --34 -52 56 Parietal_Inf_L -32 -52 50 Parietal_Inf_R -32 6 58 Frontal_Mid_R diff --git a/junifer/data/coordinates/VOIs/meta/PhysioStress_VOIs.txt b/junifer/data/coordinates/VOIs/meta/PhysioStress_VOIs.txt deleted file mode 100644 index 2967c228f..000000000 --- a/junifer/data/coordinates/VOIs/meta/PhysioStress_VOIs.txt +++ /dev/null @@ -1,18 +0,0 @@ -38.0 18.0 0.0 rIns -52.0 12.0 -4.0 rSTG -60.0 6.0 2.0 rTP -22.0 0.0 -4.0 rPall --38.0 14.0 4.0 lIns --58.0 0.0 6.0 lOP4 --20.0 6.0 2.0 lPut -4.0 6.0 46.0 rSMA -0.0 14.0 36.0 lMCC --42.0 -18.0 18.0 lOP3 --54.0 -24.0 24.0 lSMG --36.0 -20.0 2.0 lIns --14.0 -12.0 10.0 lTh -10.0 -18.0 4.0 rTh -56.0 -24.0 24.0 lSMG -44.0 -14.0 16.0 rOP3 -38.0 50.0 12.0 rMFG --24.0 -66.0 -26.0 lCb diff --git a/junifer/data/coordinates/VOIs/meta/Power2011_MNI_VOIs.txt b/junifer/data/coordinates/VOIs/meta/Power2011_MNI_VOIs.txt deleted file mode 100644 index b9ba98236..000000000 --- a/junifer/data/coordinates/VOIs/meta/Power2011_MNI_VOIs.txt +++ /dev/null @@ -1,264 +0,0 @@ --25 -98 -12 1 -27 -97 -13 2 -24 32 -18 3 --56 -45 -24 4 -8 41 -24 5 --21 -22 -20 6 -17 -28 -17 7 --37 -29 -26 8 -65 -24 -19 9 -52 -34 -27 10 -55 -31 -17 11 -34 38 -12 12 --7 -52 61 13 --14 -18 40 14 -0 -15 47 15 -10 -2 45 16 --7 -21 65 17 --7 -33 72 18 -13 -33 75 19 --54 -23 43 20 -29 -17 71 21 -10 -46 73 22 --23 -30 72 23 --40 -19 54 24 -29 -39 59 25 -50 -20 42 26 --38 -27 69 27 -20 -29 60 28 -44 -8 57 29 --29 -43 61 30 -10 -17 74 31 -22 -42 69 32 --45 -32 47 33 --21 -31 61 34 --13 -17 75 35 -42 -20 55 36 --38 -15 69 37 --16 -46 73 38 -2 -28 60 39 -3 -17 58 40 -38 -17 45 41 --49 -11 35 42 -36 -9 14 43 -51 -6 32 44 --53 -10 24 45 -66 -8 25 46 --3 2 53 47 -54 -28 34 48 -19 -8 64 49 --16 -5 71 50 --10 -2 42 51 -37 1 -4 52 -13 -1 70 53 -7 8 51 54 --45 0 9 55 -49 8 -1 56 --34 3 4 57 --51 8 -2 58 --5 18 34 59 -36 10 1 60 -32 -26 13 61 -65 -33 20 62 -58 -16 7 63 --38 -33 17 64 --60 -25 14 65 --49 -26 5 66 -43 -23 20 67 --50 -34 26 68 --53 -22 23 69 --55 -9 12 70 -56 -5 13 71 -59 -17 29 72 --30 -27 12 73 --41 -75 26 74 -6 67 -4 75 -8 48 -15 76 --13 -40 1 77 --18 63 -9 78 --46 -61 21 79 -43 -72 28 80 --44 12 -34 81 -46 16 -30 82 --68 -23 -16 83 --58 -26 -15 84 -27 16 -17 85 --44 -65 35 86 --39 -75 44 87 --7 -55 27 88 -6 -59 35 89 --11 -56 16 90 --3 -49 13 91 -8 -48 31 92 -15 -63 26 93 --2 -37 44 94 -11 -54 17 95 -52 -59 36 96 -23 33 48 97 --10 39 52 98 --16 29 53 99 --35 20 51 100 -22 39 39 101 -13 55 38 102 --10 55 39 103 --20 45 39 104 -6 54 16 105 -6 64 22 106 --7 51 -1 107 -9 54 3 108 --3 44 -9 109 -8 42 -5 110 --11 45 8 111 --2 38 36 112 --3 42 16 113 --20 64 19 114 --8 48 23 115 -65 -12 -19 116 --56 -13 -10 117 --58 -30 -4 118 -65 -31 -9 119 --68 -41 -5 120 -13 30 59 121 -12 36 20 122 -52 -2 -16 123 --26 -40 -8 124 -27 -37 -13 125 --34 -38 -16 126 -28 -77 -32 127 -52 7 -30 128 --53 3 -27 129 -47 -50 29 130 --49 -42 1 131 --31 19 -19 132 --2 -35 31 133 --7 -71 42 134 -11 -66 42 135 -4 -48 51 136 --46 31 -13 137 --10 11 67 138 -49 35 -12 139 -8 -91 -7 140 -17 -91 -14 141 --12 -95 -13 142 -18 -47 -10 143 -40 -72 14 144 -8 -72 11 145 --8 -81 7 146 --28 -79 19 147 -20 -66 2 148 --24 -91 19 149 -27 -59 -9 150 --15 -72 -8 151 --18 -68 5 152 -43 -78 -12 153 --47 -76 -10 154 --14 -91 31 155 -15 -87 37 156 -29 -77 25 157 -20 -86 -2 158 -15 -77 31 159 --16 -52 -1 160 -42 -66 -8 161 -24 -87 24 162 -6 -72 24 163 --42 -74 0 164 -26 -79 -16 165 --16 -77 34 166 --3 -81 21 167 --40 -88 -6 168 -37 -84 13 169 -6 -81 6 170 --26 -90 3 171 --33 -79 -13 172 -37 -81 1 173 --44 2 46 174 -48 25 27 175 --47 11 23 176 --53 -49 43 177 --23 11 64 178 -58 -53 -14 179 -24 45 -15 180 -34 54 -13 181 --21 41 -20 182 --18 -76 -24 183 -17 -80 -34 184 -35 -67 -34 185 -47 10 33 186 --41 6 33 187 --42 38 21 188 -38 43 15 189 -49 -42 45 190 --28 -58 48 191 -44 -53 47 192 -32 14 56 193 -37 -65 40 194 --42 -55 45 195 -40 18 40 196 --34 55 4 197 --42 45 -2 198 -33 -53 44 199 -43 49 -2 200 --42 25 30 201 --3 26 44 202 -11 -39 50 203 -55 -45 37 204 -42 -0 47 205 -31 33 26 206 -48 22 10 207 --35 20 0 208 -36 22 3 209 -37 32 -2 210 -34 16 -8 211 --11 26 25 212 --1 15 44 213 --28 52 21 214 --0 30 27 215 -5 23 37 216 -10 22 27 217 -31 56 14 218 -26 50 27 219 --39 51 17 220 -2 -24 30 221 -6 -24 -0 222 --2 -13 12 223 --10 -18 7 224 -12 -17 8 225 --5 -28 -4 226 --22 7 -5 227 --15 4 8 228 -31 -14 2 229 -23 10 1 230 -29 1 4 231 --31 -11 -0 232 -15 5 7 233 -9 -4 6 234 -54 -43 22 235 --56 -50 10 236 --55 -40 14 237 -52 -33 8 238 -51 -29 -4 239 -56 -46 11 240 -53 33 1 241 --49 25 -1 242 --16 -65 -20 243 --32 -55 -25 244 -22 -58 -23 245 -1 -62 -18 246 -33 -12 -34 247 --31 -10 -36 248 -49 -3 -38 249 --50 -7 -39 250 -10 -62 61 251 --52 -63 5 252 --47 -51 -21 253 -46 -47 -17 254 -47 -30 49 255 -22 -65 48 256 -46 -59 4 257 -25 -58 60 258 --33 -46 47 259 --27 -71 37 260 --32 -1 54 261 --42 -60 -9 262 --17 -59 64 263 -29 -5 54 264 diff --git a/junifer/data/coordinates/VOIs/meta/Power2013_MNI_VOIs.tsv b/junifer/data/coordinates/VOIs/meta/Power2013_MNI_VOIs.tsv deleted file mode 100644 index 088a08a26..000000000 --- a/junifer/data/coordinates/VOIs/meta/Power2013_MNI_VOIs.tsv +++ /dev/null @@ -1,264 +0,0 @@ -22 -65 48 1 -25 -58 60 2 --35 20 0 3 -12 36 20 4 -40 18 40 5 -54 -28 34 6 -36 22 3 7 -59 -17 29 8 --45 0 9 9 -46 -59 4 10 --32 -1 54 11 -32 14 56 12 --42 -60 -9 13 --34 3 4 14 -37 1 -4 15 -29 -5 54 16 -11 -39 50 17 -37 -65 40 18 --34 -38 -16 19 --52 -63 5 20 --10 11 67 21 --44 2 46 22 --3 26 44 23 -49 8 -1 24 --33 -46 47 25 --27 -71 37 26 -55 -45 37 27 -7 8 51 28 -36 10 1 29 --39 51 17 30 -10 -62 61 31 --16 -5 71 32 -43 49 -2 33 -37 32 -2 34 -10 -2 45 35 -47 -30 49 36 -36 -9 14 37 --3 2 53 38 --51 8 -2 39 --1 15 44 40 -31 -14 2 41 -19 -8 64 42 --10 -2 42 43 -65 -33 20 44 --30 -27 12 45 -6 -72 24 46 --7 -52 61 47 --49 -42 1 48 --49 25 -1 49 --5 18 34 50 --23 11 64 51 -31 33 26 52 --0 30 27 53 --53 -22 23 54 --42 -55 45 55 --50 -34 26 56 -48 22 10 57 -31 56 14 58 -44 -8 57 59 -49 35 -12 60 --56 -50 10 61 -2 -24 30 62 -29 -39 59 63 --42 -74 0 64 --34 55 4 65 -13 -1 70 66 -42 -0 47 67 --3 42 16 68 -5 23 37 69 -51 -29 -4 70 -0 -15 47 71 -52 -33 8 72 -34 16 -8 73 --7 -71 42 74 --29 -43 61 75 -33 -53 44 76 --55 -40 14 77 --17 -59 64 78 -56 -5 13 79 -46 -47 -17 80 --11 26 25 81 -22 -42 69 82 --13 -40 1 83 -43 -23 20 84 --53 -49 43 85 --47 11 23 86 -54 -43 22 87 -53 33 1 88 -10 22 27 89 --55 -9 12 90 --58 -30 -4 91 --42 45 -2 92 -56 -46 11 93 --45 -32 47 94 -11 -66 42 95 --28 -79 19 96 --47 -76 -10 97 --2 38 36 98 --54 -23 43 99 --28 52 21 100 -47 -50 29 101 --2 -35 31 102 -50 -20 42 103 --42 38 21 104 -26 50 27 105 -58 -53 -14 106 -47 10 33 107 -32 -26 13 108 --46 31 -13 109 -10 -46 73 110 -27 -37 -13 111 -43 -72 28 112 -52 -2 -16 113 --2 -37 44 114 -38 43 15 115 --60 -25 14 116 --41 6 33 117 --2 -13 12 118 -42 -66 -8 119 -9 -4 6 120 -29 1 4 121 -15 5 7 122 --42 25 30 123 --26 -40 -8 124 -65 -31 -9 125 -44 -53 47 126 --18 -76 -24 127 --35 20 51 128 --28 -58 48 129 --49 -26 5 130 --53 -10 24 131 --47 -51 -21 132 -58 -16 7 133 -49 -42 45 134 -40 -72 14 135 --32 -55 -25 136 --14 -18 40 137 --41 -75 26 138 --16 -77 34 139 -4 -48 51 140 --68 -41 -5 141 -35 -67 -34 142 -22 39 39 143 --56 -13 -10 144 -15 -63 26 145 --15 4 8 146 -29 -77 25 147 -38 -17 45 148 -23 10 1 149 -66 -8 25 150 -51 -6 32 151 --39 -75 44 152 --11 45 8 153 -52 7 -30 154 --21 41 -20 155 --12 -95 -13 156 -8 42 -5 157 -34 38 -12 158 --16 -46 73 159 -37 -84 13 160 -18 -47 -10 161 --11 -56 16 162 -48 25 27 163 --53 3 -27 164 -46 16 -30 165 --31 19 -19 166 -37 -81 1 167 -52 -59 36 168 -27 16 -17 169 -24 45 -15 170 --44 12 -34 171 --46 -61 21 172 --49 -11 35 173 --25 -98 -12 174 --33 -79 -13 175 -11 -54 17 176 -23 33 48 177 --3 -49 13 178 -12 -17 8 179 --38 -33 17 180 -8 48 -15 181 --10 39 52 182 -43 -78 -12 183 -20 -29 60 184 --40 -19 54 185 --20 45 39 186 -13 30 59 187 --24 -91 19 188 --16 29 53 189 -8 -91 -7 190 --21 -31 61 191 -6 67 -4 192 -17 -80 -34 193 --23 -30 72 194 -2 -28 60 195 -15 -77 31 196 -3 -17 58 197 -55 -31 -17 198 --31 -10 -36 199 --40 -88 -6 200 --18 63 -9 201 -27 -59 -9 202 -49 -3 -38 203 --31 -11 -0 204 -65 -24 -19 205 -17 -28 -17 206 --7 51 -1 207 -24 32 -18 208 -9 54 3 209 --7 -55 27 210 --21 -22 -20 211 -34 54 -13 212 --38 -15 69 213 --38 -27 69 214 -65 -12 -19 215 --16 -52 -1 216 --8 48 23 217 --3 44 -9 218 --37 -29 -26 219 -27 -97 -13 220 -17 -91 -14 221 -6 54 16 222 -8 41 -24 223 -8 -48 31 224 -24 -87 24 225 --58 -26 -15 226 -29 -17 71 227 --68 -23 -16 228 --10 -18 7 229 --13 -17 75 230 --7 -33 72 231 -15 -87 37 232 --20 64 19 233 -42 -20 55 234 -26 -79 -16 235 --10 55 39 236 -13 -33 75 237 -33 -12 -34 238 --26 -90 3 239 --7 -21 65 240 -10 -17 74 241 --44 -65 35 242 -6 -59 35 243 -6 64 22 244 --18 -68 5 245 --16 -65 -20 246 -8 -72 11 247 -13 55 38 248 --14 -91 31 249 --3 -81 21 250 -20 -86 -2 251 --50 -7 -39 252 --56 -45 -24 253 --8 -81 7 254 -20 -66 2 255 -6 -81 6 256 -52 -34 -27 257 --15 -72 -8 258 -6 -24 -0 259 -28 -77 -32 260 -22 -58 -23 261 -1 -62 -18 262 --22 7 -5 263 --5 -28 -4 264 diff --git a/junifer/data/coordinates/VOIs/meta/Rew_VOIs.txt b/junifer/data/coordinates/VOIs/meta/Rew_VOIs.txt deleted file mode 100644 index cadddcf20..000000000 --- a/junifer/data/coordinates/VOIs/meta/Rew_VOIs.txt +++ /dev/null @@ -1,25 +0,0 @@ -12.0 10.0 -6.0 rNAc --10.0 8.0 -4.0 lPall -36.0 20.0 -6.0 rIns --32.0 20.0 -4.0 lIns -0.0 24.0 40.0 dmPFC -0.0 54.0 -8.0 medOFC -24.0 -2.0 -16.0 rAm -6.0 -14.0 8.0 rTh --6.0 -16.0 8.0 lTh -0.0 8.0 48.0 SMA -8.0 -18.0 -10.0 rBrainStem --6.0 -18.0 -10.0 lBrainStem -2.0 44.0 20.0 ACC --24.0 2.0 52.0 lMFG --38.0 -4.0 6.0 lIns(Id3) -24.0 40.0 -14.0 rMidOFC(Fo3) --16.0 42.0 -14.0 lMidOFC(Fo3) -40.0 32.0 32.0 raMFG --28.0 -56.0 48.0 lIPL(IPS) -28.0 -58.0 50.0 rAG -0.0 -32.0 32.0 PCC --36.0 50.0 10.0 lFP --46.0 42.0 -4.0 lLOFC -30.0 4.0 50.0 rpMFG --22.0 30.0 48.0 lSFG diff --git a/junifer/data/coordinates/VOIs/meta/Somatosensory_VOIs.txt b/junifer/data/coordinates/VOIs/meta/Somatosensory_VOIs.txt deleted file mode 100644 index 3fa59e405..000000000 --- a/junifer/data/coordinates/VOIs/meta/Somatosensory_VOIs.txt +++ /dev/null @@ -1,10 +0,0 @@ --48.0 -20.0 20.0 S1_L --54.0 -20.0 48.0 postcentralG_S1_L --44.0 -26.0 58.0 postcentralG_S1_L --38.0 -12.0 4.0 Ins_claustrum_L --40.0 4.0 10.0 pars_opercularis_Ins_L -56.0 -22.0 20.0 SMG_R -56.0 -34.0 18.0 pSTG_R -56.0 -38.0 28.0 IPL_SMG_R -60.0 -20.0 32.0 postcentralG_R --4.0 14.0 36.0 MCC_L diff --git a/junifer/data/coordinates/VOIs/meta/ToM_VOIs.txt b/junifer/data/coordinates/VOIs/meta/ToM_VOIs.txt deleted file mode 100644 index 8f0dcccb2..000000000 --- a/junifer/data/coordinates/VOIs/meta/ToM_VOIs.txt +++ /dev/null @@ -1,15 +0,0 @@ -0.0 52.0 -12.0 vmPFC -2.0 58.0 12.0 FP --8.0 56.0 30.0 dmPFC -2.0 -56.0 30.0 Prc -56.0 -50.0 18.0 rTPJ --48.0 -56.0 24.0 lTPJ -54.0 -2.0 -20.0 rTP --54.0 -2.0 -24.0 lTP -52.0 -18.0 -12.0 rMTG --54.0 -28.0 -4.0 lMTG -50.0 -34.0 0.0 rpSTS --58.0 -44.0 4.0 lpSTS -54.0 28.0 6.0 rIFG --48.0 30.0 -12.0 lIFG -48.0 -72.0 8.0 rV5 diff --git a/junifer/data/coordinates/VOIs/meta/VigAtt_VOIs.txt b/junifer/data/coordinates/VOIs/meta/VigAtt_VOIs.txt deleted file mode 100644 index 10a244cc3..000000000 --- a/junifer/data/coordinates/VOIs/meta/VigAtt_VOIs.txt +++ /dev/null @@ -1,16 +0,0 @@ --2.0 8.0 50.0 aParacentralL -8.0 32.0 46.0 rmpSFG -0.0 26.0 34.0 dMCC -50.0 8.0 32.0 rIFJ -40.0 22.0 -4.0 raI -46.0 36.0 20.0 rIFS --40.0 -12.0 60.0 lPrecentralG --46.0 -68.0 -6.0 lIOG --48.0 8.0 30.0 lIFJ -62.0 -38.0 17.0 rTPJ -8.0 -12.0 6.0 rTh -32.0 -90.0 4.0 rMOG --42.0 12.0 -2.0 laI --10.0 -14.0 6.0 lTh -6.0 -58.0 -18.0 Cb -44.0 -44.0 46.0 rIPL diff --git a/junifer/data/coordinates/VOIs/meta/WM_VOIs.txt b/junifer/data/coordinates/VOIs/meta/WM_VOIs.txt deleted file mode 100644 index 426b061f8..000000000 --- a/junifer/data/coordinates/VOIs/meta/WM_VOIs.txt +++ /dev/null @@ -1,23 +0,0 @@ --32.0 22.0 -2.0 aIns_l --48.0 10.0 26.0 IFG_l --46.0 26.0 24.0 lPFCc_l --38.0 50.0 10.0 lPFCr_l -36.0 22.0 -6.0 aIns_r -50.0 14.0 24.0 IFG_r -44.0 34.0 32.0 lPFCc_r -38.0 54.0 6.0 lPFCr_l -2.0 18.0 48.0 pmFC --28.0 0.0 56.0 psFC -30.0 2.0 56.0 psFC --42.0 -42.0 46.0 IPS_l --34.0 -52.0 48.0 SPL_l --24.0 -66.0 54.0 SPLp_l -42.0 -44.0 44.0 IPSa_r -32.0 -58.0 48.0 IPSp_r -16.0 -66.0 56.0 SPLp_r --12.0 -12.0 12.0 Thal_l --16.0 2.0 14.0 Ncaud_l --16.0 0.0 2.0 GP_l -12.0 -10.0 10.0 Thal_r --34.0 -66.0 -20.0 Cb_FG_l -32.0 -64.0 -18.0 Cb_FG_r diff --git a/junifer/data/coordinates/VOIs/meta/eMDN_VOIs.txt b/junifer/data/coordinates/VOIs/meta/eMDN_VOIs.txt deleted file mode 100644 index aa93cda2e..000000000 --- a/junifer/data/coordinates/VOIs/meta/eMDN_VOIs.txt +++ /dev/null @@ -1,17 +0,0 @@ --46.0 6.0 30.0 IFG_l -50.0 12.0 28.0 IFG_r --32.0 20.0 2.0 aIns_l -36.0 22.0 0.0 aIns_r --4.0 14.0 44.0 SMA_l -6.0 18.0 46.0 SMA_r --32.0 -52.0 46.0 IPS_l -32.0 -58.0 48.0 IPS_r -44.0 36.0 20.0 MFG_r --28.0 -4.0 52.0 dPMC_l --44.0 32.0 22.0 MFG_l -32.0 0.0 52.0 dPMC_r --20.0 6.0 4.0 Put_l -10.0 -12.0 8.0 Thal_r --46.0 -60.0 -10.0 ITG_l -22.0 6.0 4.0 Put_r --10.0 -16.0 6.0 Thal_l diff --git a/junifer/data/coordinates/VOIs/meta/eSAD_VOIs.txt b/junifer/data/coordinates/VOIs/meta/eSAD_VOIs.txt deleted file mode 100644 index 005cdba17..000000000 --- a/junifer/data/coordinates/VOIs/meta/eSAD_VOIs.txt +++ /dev/null @@ -1,12 +0,0 @@ -0.0 38.0 10.0 ACC --24.0 -10.0 -20.0 AmyHipp_L -24.0 -8.0 -22.0 AmyHipp_R --2.0 -52.0 26.0 PrC --2.0 32.0 -8.0 SGC --46.0 -66.0 18.0 TPJ_L -50.0 -60.0 18.0 TPJ_R --2.0 52.0 14.0 dmPFC --6.0 10.0 -8.0 vBG_L -6.0 10.0 -8.0 vBG_R --2.0 50.0 -10.0 vmPFC --54.0 -10.0 -20.0 aMTS/aMTG diff --git a/junifer/data/coordinates/VOIs/meta/extDMN_VOIs.txt b/junifer/data/coordinates/VOIs/meta/extDMN_VOIs.txt deleted file mode 100644 index f6539daad..000000000 --- a/junifer/data/coordinates/VOIs/meta/extDMN_VOIs.txt +++ /dev/null @@ -1,16 +0,0 @@ -0 -53 6 PCC -0 52 -6 MPFC --48 -62 36 lAG -46 -62 32 rAG --24 -22 -20 lHF -24 -22 -20 rHF -10 -22 42 Middlecingulate --48 -20 38 lIPG -0 -48 -30 cerebellum -34 -80 -34 rCerebellum -56 30 8 rdlPFC --42 -82 10 lateraloccipital --54 24 10 rdrPFC -22 34 54 RSFG --50 14 -40 lTempP --38 14 54 leftmiddlefrontalgyrus(BA6) diff --git a/junifer/data/coordinates/_ants_coordinates_warper.py b/junifer/data/coordinates/_ants_coordinates_warper.py index 106da582e..02c032b38 100644 --- a/junifer/data/coordinates/_ants_coordinates_warper.py +++ b/junifer/data/coordinates/_ants_coordinates_warper.py @@ -27,7 +27,7 @@ class ANTsCoordinatesWarper: seeds: ArrayLike, target_data: dict[str, Any], warp_data: dict[str, Any], - ) -> ArrayLike: + ) -> ArrayLike: # pragma: no cover """Warp ``seeds`` to correct space. Parameters diff --git a/junifer/data/coordinates/_coordinates.py b/junifer/data/coordinates/_coordinates.py index 66193be2a..bc88e0eb2 100644 --- a/junifer/data/coordinates/_coordinates.py +++ b/junifer/data/coordinates/_coordinates.py @@ -339,7 +339,7 @@ class CoordinatesRegistry(BasePipelineDataRegistry, metaclass=Singleton): seeds, labels, _ = self.load(name=coords) # Transform coordinate if target data is native - if target_data["space"] == "native": + if target_data["space"] == "native": # pragma: no cover # Check for extra inputs if extra_input is None: raise_error( diff --git a/junifer/data/coordinates/_fsl_coordinates_warper.py b/junifer/data/coordinates/_fsl_coordinates_warper.py index 22f142d6f..0f36e0bdb 100644 --- a/junifer/data/coordinates/_fsl_coordinates_warper.py +++ b/junifer/data/coordinates/_fsl_coordinates_warper.py @@ -27,7 +27,7 @@ class FSLCoordinatesWarper: seeds: ArrayLike, target_data: dict[str, Any], warp_data: dict[str, Any], - ) -> ArrayLike: + ) -> ArrayLike: # pragma: no cover """Warp ``seeds`` to correct space. Parameters diff --git a/junifer/data/coordinates/tests/test_coordinates.py b/junifer/data/coordinates/tests/test_coordinates.py index eefd8bffb..4620c80da 100644 --- a/junifer/data/coordinates/tests/test_coordinates.py +++ b/junifer/data/coordinates/tests/test_coordinates.py @@ -8,7 +8,13 @@ import numpy as np import pytest from numpy.testing import assert_array_equal -from junifer.data import CoordinatesRegistry +from junifer.data import ( + deregister_data, + get_data, + list_data, + load_data, + register_data, +) from junifer.datareader import DefaultDataReader from junifer.testing.datagrabbers import OasisVBMTestingDataGrabber @@ -16,7 +22,8 @@ from junifer.testing.datagrabbers import OasisVBMTestingDataGrabber def test_register_built_in_check() -> None: """Test coordinates registration check for built-in coordinates.""" with pytest.raises(ValueError, match=r"built-in"): - CoordinatesRegistry().register( + register_data( + kind="coordinates", name="DMNBuckner", coordinates=np.zeros(2), voi_names=["1", "2"], @@ -26,14 +33,16 @@ def test_register_built_in_check() -> None: def test_register_overwrite() -> None: """Test coordinates registration check for overwriting.""" - CoordinatesRegistry().register( + register_data( + kind="coordinates", name="MyList", coordinates=np.zeros((2, 3)), voi_names=["roi1", "roi2"], space="MNI", ) with pytest.raises(ValueError, match=r"already registered"): - CoordinatesRegistry().register( + register_data( + kind="coordinates", name="MyList", coordinates=np.ones((2, 3)), voi_names=["roi2", "roi3"], @@ -41,7 +50,8 @@ def test_register_overwrite() -> None: overwrite=False, ) - CoordinatesRegistry().register( + register_data( + kind="coordinates", name="MyList", coordinates=np.ones((2, 3)), voi_names=["roi2", "roi3"], @@ -49,7 +59,7 @@ def test_register_overwrite() -> None: overwrite=True, ) - coord, names, space = CoordinatesRegistry().load("MyList") + coord, names, space = load_data(kind="coordinates", name="MyList") assert_array_equal(coord, np.ones((2, 3))) assert names == ["roi2", "roi3"] assert space == "MNI" @@ -58,7 +68,8 @@ def test_register_overwrite() -> None: def test_register_valid_input() -> None: """Test coordinates registration check for valid input.""" with pytest.raises(TypeError, match=r"numpy.ndarray"): - CoordinatesRegistry().register( + register_data( + kind="coordinates", name="MyList", coordinates=[1, 2], voi_names=["roi1", "roi2"], @@ -66,7 +77,8 @@ def test_register_valid_input() -> None: overwrite=True, ) with pytest.raises(ValueError, match=r"2D array"): - CoordinatesRegistry().register( + register_data( + kind="coordinates", name="MyList", coordinates=np.zeros((2, 3, 4)), voi_names=["roi1", "roi2"], @@ -75,7 +87,8 @@ def test_register_valid_input() -> None: ) with pytest.raises(ValueError, match=r"3 values"): - CoordinatesRegistry().register( + register_data( + kind="coordinates", name="MyList", coordinates=np.zeros((2, 4)), voi_names=["roi1", "roi2"], @@ -83,7 +96,8 @@ def test_register_valid_input() -> None: overwrite=True, ) with pytest.raises(ValueError, match=r"voi_names"): - CoordinatesRegistry().register( + register_data( + kind="coordinates", name="MyList", coordinates=np.zeros((2, 3)), voi_names=["roi1", "roi2", "roi3"], @@ -95,13 +109,13 @@ def test_register_valid_input() -> None: def test_list() -> None: """Test listing of available coordinates.""" assert {"DMNBuckner", "MultiTask", "VigAtt", "WM"}.issubset( - set(CoordinatesRegistry().list) + set(list_data(kind="coordinates")) ) def test_load() -> None: """Test loading coordinates from file.""" - coord, names, space = CoordinatesRegistry().load("DMNBuckner") + coord, names, space = load_data(kind="coordinates", name="DMNBuckner") assert coord.shape == (6, 3) # type: ignore assert names == ["PCC", "MPFC", "lAG", "rAG", "lHF", "rHF"] assert space == "MNI" @@ -110,7 +124,7 @@ def test_load() -> None: def test_load_nonexisting() -> None: """Test loading coordinates that not exist.""" with pytest.raises(ValueError, match=r"not found"): - CoordinatesRegistry().load("NonExisting") + load_data(kind="coordinates", name="NonExisting") def test_get() -> None: @@ -121,11 +135,19 @@ def test_get() -> None: element_data = reader.fit_transform(element) vbm_gm = element_data["VBM_GM"] # Get tailored coordinates - tailored_coords, tailored_labels = CoordinatesRegistry().get( - coords="DMNBuckner", target_data=vbm_gm + tailored_coords, tailored_labels = get_data( + kind="coordinates", names="DMNBuckner", target_data=vbm_gm ) # Get raw coordinates - raw_coords, raw_labels, _ = CoordinatesRegistry().load("DMNBuckner") + raw_coords, raw_labels, _ = load_data( + kind="coordinates", name="DMNBuckner" + ) # Both tailored and raw should be same for now assert_array_equal(tailored_coords, raw_coords) assert tailored_labels == raw_labels + + +def test_deregister() -> None: + """Test coordinates deregistration.""" + deregister_data(kind="coordinates", name="MyList") + assert "MyList" not in list_data(kind="coordinates") diff --git a/junifer/data/masks/_ants_mask_warper.py b/junifer/data/masks/_ants_mask_warper.py index 5b07a6675..af478c1c2 100644 --- a/junifer/data/masks/_ants_mask_warper.py +++ b/junifer/data/masks/_ants_mask_warper.py @@ -56,7 +56,7 @@ class ANTsMaskWarper: dst: str, target_data: dict[str, Any], warp_data: Optional[dict[str, Any]], - ) -> "Nifti1Image": + ) -> "Nifti1Image": # pragma: no cover """Warp ``mask_img`` to correct space. Parameters diff --git a/junifer/data/masks/_fsl_mask_warper.py b/junifer/data/masks/_fsl_mask_warper.py index 8510318e3..50eb36b9a 100644 --- a/junifer/data/masks/_fsl_mask_warper.py +++ b/junifer/data/masks/_fsl_mask_warper.py @@ -53,7 +53,7 @@ class FSLMaskWarper: mask_img: "Nifti1Image", target_data: dict[str, Any], warp_data: dict[str, Any], - ) -> "Nifti1Image": + ) -> "Nifti1Image": # pragma: no cover """Warp ``mask_img`` to correct space. Parameters diff --git a/junifer/data/masks/tests/test_masks.py b/junifer/data/masks/tests/test_masks.py index a51380062..91eb8b16d 100644 --- a/junifer/data/masks/tests/test_masks.py +++ b/junifer/data/masks/tests/test_masks.py @@ -20,7 +20,14 @@ from nilearn.masking import ( ) from numpy.testing import assert_array_almost_equal, assert_array_equal -from junifer.data import MaskRegistry +from junifer.data import ( + MaskRegistry, + deregister_data, + get_data, + list_data, + load_data, + register_data, +) from junifer.data.masks import compute_brain_mask from junifer.data.masks._masks import ( _load_ukb_mask, @@ -112,7 +119,8 @@ def test_compute_brain_mask_for_native(mask_type: str) -> None: def test_register_built_in_check() -> None: """Test mask registration check for built-in masks.""" with pytest.raises(ValueError, match=r"built-in mask"): - MaskRegistry().register( + register_data( + kind="mask", name="GM_prob0.2", mask_path="testmask.nii.gz", space="MNI", @@ -122,36 +130,39 @@ def test_register_built_in_check() -> None: def test_list_incorrect() -> None: """Test incorrect information check for list masks.""" - assert "testmask" not in MaskRegistry().list + assert "testmask" not in list_data(kind="mask") def test_register_already_registered() -> None: """Test mask registration check for already registered.""" # Register custom mask - MaskRegistry().register( + register_data( + kind="mask", name="testmask", mask_path="testmask.nii.gz", space="MNI", ) - out = MaskRegistry().load("testmask", path_only=True) + out = load_data(kind="mask", name="testmask", path_only=True) assert out[1] is not None assert out[1].name == "testmask.nii.gz" # Try registering again with pytest.raises(ValueError, match=r"already registered."): - MaskRegistry().register( + register_data( + kind="mask", name="testmask", mask_path="testmask.nii.gz", space="MNI", ) - MaskRegistry().register( + register_data( + kind="mask", name="testmask", mask_path="testmask2.nii.gz", space="MNI", overwrite=True, ) - out = MaskRegistry().load("testmask", path_only=True) + out = load_data(kind="mask", name="testmask", path_only=True) assert out[1] is not None assert out[1].name == "testmask2.nii.gz" @@ -185,16 +196,17 @@ def test_register( """ # Register custom mask - MaskRegistry().register( + register_data( + kind="mask", name=name, mask_path=mask_path, space=space, overwrite=overwrite, ) # List available mask and check registration - assert name in MaskRegistry().list + assert name in list_data(kind="mask") # Load registered mask - _, fname, mask_space = MaskRegistry().load(name=name, path_only=True) + _, fname, mask_space = load_data(kind="mask", name=name, path_only=True) # Check values for registered mask assert fname is not None assert fname.name == f"{name}.nii.gz" @@ -218,7 +230,7 @@ def test_list_correct(mask_name: str) -> None: The parametrized mask name. """ - assert mask_name in MaskRegistry().list + assert mask_name in list_data(kind="mask") def test_load_incorrect() -> None: @@ -270,9 +282,12 @@ def test_vickery_patil( The parametrized name of the mask file. """ - mask, mask_fname, space = MaskRegistry().load(name, resolution=resolution) + mask, mask_fname, space = load_data( + kind="mask", name=name, resolution=resolution + ) assert_array_almost_equal( - mask.header["pixdim"][1:4], pixdim # type: ignore + mask.header["pixdim"][1:4], + pixdim, # type: ignore ) assert space == "IXI549Space" assert mask_fname is not None @@ -287,7 +302,9 @@ def test_vickery_patil_error() -> None: def test_ukb() -> None: """Test UKB mask.""" - mask, mask_fname, space = MaskRegistry().load("UKB_15K_GM", resolution=2.0) + mask, mask_fname, space = load_data( + kind="mask", name="UKB_15K_GM", resolution=2.0 + ) assert_array_almost_equal(mask.header["pixdim"][1:4], 2.0) # type: ignore assert space == "MNI152NLin6Asym" assert mask_fname is not None @@ -306,8 +323,8 @@ def test_get() -> None: element_data = DefaultDataReader().fit_transform(dg["sub-01"]) vbm_gm = element_data["VBM_GM"] vbm_gm_img = vbm_gm["data"] - mask = MaskRegistry().get( - masks="compute_brain_mask", target_data=vbm_gm + mask = get_data( + kind="mask", names="compute_brain_mask", target_data=vbm_gm ) assert mask.shape == vbm_gm_img.shape @@ -355,28 +372,33 @@ def test_get_errors() -> None: vbm_gm = element_data["VBM_GM"] # Test wrong masks definitions (more than one key per dict) with pytest.raises(ValueError, match=r"only one key"): - MaskRegistry().get( - masks={"GM_prob0.2": {}, "Other": {}}, target_data=vbm_gm + get_data( + kind="mask", + names={"GM_prob0.2": {}, "Other": {}}, + target_data=vbm_gm, ) # Test wrong masks definitions (pass paramaeters to non-callable mask) with pytest.raises(ValueError, match=r"callable params"): - MaskRegistry().get( - masks={"GM_prob0.2": {"param": 1}}, target_data=vbm_gm + get_data( + kind="mask", + names={"GM_prob0.2": {"param": 1}}, + target_data=vbm_gm, ) # Pass only parameters to the intersection function with pytest.raises( ValueError, match=r" At least one mask is required." ): - MaskRegistry().get(masks={"threshold": 1}, target_data=vbm_gm) + get_data(kind="mask", names={"threshold": 1}, target_data=vbm_gm) # Pass parameters to the intersection function when only one mask with pytest.raises( ValueError, match=r"parameters to the intersection" ): - MaskRegistry().get( - masks=["compute_brain_mask", {"threshold": 1}], + get_data( + kind="mask", + names=["compute_brain_mask", {"threshold": 1}], target_data=vbm_gm, ) @@ -423,7 +445,7 @@ def test_nilearn_compute_masks( else: mask_spec = {mask_name: params} - mask = MaskRegistry().get(masks=mask_spec, target_data=bold) + mask = get_data(kind="mask", names=mask_spec, target_data=bold) assert_array_equal(mask.affine, bold_img.affine) @@ -449,8 +471,9 @@ def test_get_inherit() -> None: gm_mask = compute_brain_mask(element_data["BOLD"], threshold=0.2) # Get mask using the compute_brain_mask function - mask1 = MaskRegistry().get( - masks={"compute_brain_mask": {"threshold": 0.2}}, + mask1 = get_data( + kind="mask", + names={"compute_brain_mask": {"threshold": 0.2}}, target_data=element_data["BOLD"], ) @@ -461,8 +484,9 @@ def test_get_inherit() -> None: "data": gm_mask, "space": element_data["BOLD"]["space"], } - mask2 = MaskRegistry().get( - masks="inherit", + mask2 = get_data( + kind="mask", + names="inherit", target_data=bold_dict, ) @@ -503,8 +527,8 @@ def test_get_multiple( target_img = element_data["BOLD"]["data"] resolution = np.min(target_img.header.get_zooms()[:3]) - computed = MaskRegistry().get( - masks=junifer_masks, target_data=element_data["BOLD"] + computed = get_data( + kind="mask", names=junifer_masks, target_data=element_data["BOLD"] ) masks_names = [ @@ -523,8 +547,11 @@ def test_get_multiple( ] mask_imgs = [ - MaskRegistry().load( - t_mask, path_only=False, resolution=resolution + load_data( + kind="mask", + name=t_mask, + path_only=False, + resolution=resolution, )[0] for t_mask in mask_files ] @@ -554,3 +581,9 @@ def test_get_multiple( expected = intersect_masks(mask_imgs, **params) assert_array_equal(computed.get_fdata(), expected.get_fdata()) + + +def test_deregister() -> None: + """Test mask deregistration.""" + deregister_data(kind="mask", name="testmask") + assert "testmask" not in list_data(kind="mask") diff --git a/junifer/data/masks/ukb/UKB_15K_GM_template.nii.gz b/junifer/data/masks/ukb/UKB_15K_GM_template.nii.gz deleted file mode 100644 index 289394f95..000000000 Binary files a/junifer/data/masks/ukb/UKB_15K_GM_template.nii.gz and /dev/null differ diff --git a/junifer/data/masks/vickery-patil/CAT12_IXI555_MNI152_TMP_GS_GMprob0.2_clean.nii.gz b/junifer/data/masks/vickery-patil/CAT12_IXI555_MNI152_TMP_GS_GMprob0.2_clean.nii.gz deleted file mode 100644 index 329197283..000000000 Binary files a/junifer/data/masks/vickery-patil/CAT12_IXI555_MNI152_TMP_GS_GMprob0.2_clean.nii.gz and /dev/null differ diff --git a/junifer/data/masks/vickery-patil/CAT12_IXI555_MNI152_TMP_GS_GMprob0.2_clean_3mm.nii.gz b/junifer/data/masks/vickery-patil/CAT12_IXI555_MNI152_TMP_GS_GMprob0.2_clean_3mm.nii.gz deleted file mode 100644 index 597c1d44f..000000000 Binary files a/junifer/data/masks/vickery-patil/CAT12_IXI555_MNI152_TMP_GS_GMprob0.2_clean_3mm.nii.gz and /dev/null differ diff --git a/junifer/data/masks/vickery-patil/GMprob0.2_cortex_3mm_NA_rm.nii.gz b/junifer/data/masks/vickery-patil/GMprob0.2_cortex_3mm_NA_rm.nii.gz deleted file mode 100644 index cd749ffbc..000000000 Binary files a/junifer/data/masks/vickery-patil/GMprob0.2_cortex_3mm_NA_rm.nii.gz and /dev/null differ diff --git a/junifer/data/parcellations/_ants_parcellation_warper.py b/junifer/data/parcellations/_ants_parcellation_warper.py index d9a429d09..f87aca737 100644 --- a/junifer/data/parcellations/_ants_parcellation_warper.py +++ b/junifer/data/parcellations/_ants_parcellation_warper.py @@ -84,7 +84,7 @@ class ANTsParcellationWarper: ) # Native space warping - if dst == "native": + if dst == "native": # pragma: no cover # Warp data check if warp_data is None: raise_error("No `warp_data` provided") diff --git a/junifer/data/parcellations/_fsl_parcellation_warper.py b/junifer/data/parcellations/_fsl_parcellation_warper.py index 7f6c9493f..b94849e69 100644 --- a/junifer/data/parcellations/_fsl_parcellation_warper.py +++ b/junifer/data/parcellations/_fsl_parcellation_warper.py @@ -32,7 +32,7 @@ class FSLParcellationWarper: parcellation_img: "Nifti1Image", target_data: dict[str, Any], warp_data: dict[str, Any], - ) -> "Nifti1Image": + ) -> "Nifti1Image": # pragma: no cover """Warp ``parcellation_img`` to correct space. Parameters diff --git a/junifer/data/parcellations/_parcellations.py b/junifer/data/parcellations/_parcellations.py index c4de43544..71ab71b12 100644 --- a/junifer/data/parcellations/_parcellations.py +++ b/junifer/data/parcellations/_parcellations.py @@ -1035,17 +1035,17 @@ def _retrieve_shen( ) if n_rois in (268, 368) and year == 2013: raise_error( - f"The parameter combination `resolution = {resolution}` and " + f"The parameter combination `n_rois = {n_rois}` and " "`year = 2013` is invalid" ) if n_rois in (50, 100, 150) and year in (2015, 2019): raise_error( - f"The parameter combination `resolution = {resolution}` and " + f"The parameter combination `n_rois = {n_rois}` and " f"`year = {year}` is invalid" ) if (n_rois == 268 and year == 2019) or (n_rois == 368 and year == 2015): raise_error( - f"The parameter combination `resolution = {resolution}` and " + f"The parameter combination `n_rois = {n_rois}` and " f"`year = {year}` is invalid" ) @@ -1312,11 +1312,11 @@ def merge_parcellations( parcellations_names: list[str], labels_lists: list[list[str]], ) -> tuple["Nifti1Image", list[str]]: - """Merge all parcellations from a list into one parcellation. + """Merge multiple parcellations. Parameters ---------- - parcellations_list : list of niimg-like object + parcellations_list : list of Niimg-like object List of parcellations to merge. parcellations_names: list of str List of names for parcellations at the corresponding indices. @@ -1326,10 +1326,10 @@ def merge_parcellations( Returns ------- - parcellation : niimg-like object + Niimg-like object The parcellation that results from merging the list of input parcellations. - labels : list of str + list of str List of labels for the resultant parcellation. """ diff --git a/junifer/data/parcellations/tests/test_parcellations.py b/junifer/data/parcellations/tests/test_parcellations.py index 6765aafe4..be82f3643 100644 --- a/junifer/data/parcellations/tests/test_parcellations.py +++ b/junifer/data/parcellations/tests/test_parcellations.py @@ -13,7 +13,12 @@ import pytest from nilearn.image import new_img_like, resample_to_img from numpy.testing import assert_array_almost_equal, assert_array_equal -from junifer.data import ParcellationRegistry +from junifer.data import ( + get_data, + list_data, + load_data, + register_data, +) from junifer.data.parcellations import merge_parcellations from junifer.data.parcellations._parcellations import ( _retrieve_aicha, @@ -35,7 +40,8 @@ from junifer.testing.datagrabbers import ( def test_register_built_in_check() -> None: """Test parcellation registration check for built-in parcellations.""" with pytest.raises(ValueError, match=r"built-in parcellation"): - ParcellationRegistry().register( + register_data( + kind="parcellation", name="SUITxSUIT", parcellation_path="testparc.nii.gz", parcels_labels=["1", "2", "3"], @@ -46,34 +52,40 @@ def test_register_built_in_check() -> None: def test_list_incorrect() -> None: """Test incorrect information check for list parcellations.""" - assert "testparc" not in ParcellationRegistry().list + assert "testparc" not in list_data(kind="parcellation") def test_register_already_registered() -> None: """Test parcellation registration check for already registered.""" # Register custom parcellation - ParcellationRegistry().register( + register_data( + kind="parcellation", name="testparc", parcellation_path="testparc.nii.gz", parcels_labels=["1", "2", "3"], space="MNI152Lin", ) assert ( - ParcellationRegistry() - .load("testparc", target_space="MNI152Lin", path_only=True)[2] - .name + load_data( + kind="parcellation", + name="testparc", + target_space="MNI152Lin", + path_only=True, + )[2].name == "testparc.nii.gz" ) # Try registering again with pytest.raises(ValueError, match=r"already registered."): - ParcellationRegistry().register( + register_data( + kind="parcellation", name="testparc", parcellation_path="testparc.nii.gz", parcels_labels=["1", "2", "3"], space="MNI152Lin", ) - ParcellationRegistry().register( + register_data( + kind="parcellation", name="testparc", parcellation_path="testparc2.nii.gz", parcels_labels=["1", "2", "3"], @@ -82,9 +94,12 @@ def test_register_already_registered() -> None: ) assert ( - ParcellationRegistry() - .load("testparc", target_space="MNI152Lin", path_only=True)[2] - .name + load_data( + kind="parcellation", + name="testparc", + target_space="MNI152Lin", + path_only=True, + )[2].name == "testparc2.nii.gz" ) @@ -98,27 +113,44 @@ def test_parcellation_wrong_labels_values(tmp_path: Path) -> None: The path to the test directory. """ - schaefer, labels, schaefer_path, _ = ParcellationRegistry().load( - "Schaefer100x7", - "MNI152NLin6Asym", + schaefer, labels, schaefer_path, _ = load_data( + kind="parcellation", + name="Schaefer100x7", + target_space="MNI152NLin6Asym", ) assert schaefer is not None # Test wrong number of labels - ParcellationRegistry().register( - "WrongLabels", schaefer_path, labels[:10], "MNI152Lin" + register_data( + kind="parcellation", + name="WrongLabels", + parcellation_path=schaefer_path, + parcels_labels=labels[:10], + space="MNI152Lin", ) with pytest.raises(ValueError, match=r"has 100 parcels but 10"): - ParcellationRegistry().load("WrongLabels", "MNI152NLin6Asym") + load_data( + kind="parcellation", + name="WrongLabels", + target_space="MNI152NLin6Asym", + ) # Test wrong number of labels - ParcellationRegistry().register( - "WrongLabels2", schaefer_path, [*labels, "wrong"], "MNI152Lin" + register_data( + kind="parcellation", + name="WrongLabels2", + parcellation_path=schaefer_path, + parcels_labels=[*labels, "wrong"], + space="MNI152Lin", ) with pytest.raises(ValueError, match=r"has 100 parcels but 101"): - ParcellationRegistry().load("WrongLabels2", "MNI152NLin6Asym") + load_data( + kind="parcellation", + name="WrongLabels2", + target_space="MNI152NLin6Asym", + ) schaefer_data = schaefer.get_fdata().copy() schaefer_data[schaefer_data == 50] = 0 @@ -126,11 +158,19 @@ def test_parcellation_wrong_labels_values(tmp_path: Path) -> None: new_schaefer_img = new_img_like(schaefer, schaefer_data) nib.save(new_schaefer_img, new_schaefer_path) - ParcellationRegistry().register( - "WrongValues", new_schaefer_path, labels[:-1], "MNI152Lin" + register_data( + kind="parcellation", + name="WrongValues", + parcellation_path=new_schaefer_path, + parcels_labels=labels[:-1], + space="MNI152Lin", ) with pytest.raises(ValueError, match=r"must have all the values in the"): - ParcellationRegistry().load("WrongValues", "MNI152NLin6Asym") + load_data( + kind="parcellation", + name="WrongValues", + target_space="MNI152NLin6Asym", + ) schaefer_data = schaefer.get_fdata().copy() schaefer_data[schaefer_data == 50] = 200 @@ -138,11 +178,19 @@ def test_parcellation_wrong_labels_values(tmp_path: Path) -> None: new_schaefer_img = new_img_like(schaefer, schaefer_data) nib.save(new_schaefer_img, new_schaefer_path) - ParcellationRegistry().register( - "WrongValues2", new_schaefer_path, labels, "MNI152Lin" + register_data( + kind="parcellation", + name="WrongValues2", + parcellation_path=new_schaefer_path, + parcels_labels=labels, + space="MNI152Lin", ) with pytest.raises(ValueError, match=r"must have all the values in the"): - ParcellationRegistry().load("WrongValues2", "MNI152NLin6Asym") + load_data( + kind="parcellation", + name="WrongValues2", + target_space="MNI152NLin6Asym", + ) @pytest.mark.parametrize( @@ -195,7 +243,8 @@ def test_register( """ # Register custom parcellation - ParcellationRegistry().register( + register_data( + kind="parcellation", name=name, parcellation_path=parcellation_path, parcels_labels=parcels_labels, @@ -203,10 +252,13 @@ def test_register( overwrite=overwrite, ) # List available parcellation and check registration - assert name in ParcellationRegistry().list + assert name in list_data(kind="parcellation") # Load registered parcellation - _, lbl, fname, parcellation_space = ParcellationRegistry().load( - name=name, target_space=space, path_only=True + _, lbl, fname, parcellation_space = load_data( + kind="parcellation", + name=name, + target_space=space, + path_only=True, ) # Check values for registered parcellation assert lbl == parcels_labels @@ -237,13 +289,17 @@ def test_list_correct(parcellation_name: str) -> None: The parametrized parcellation name. """ - assert parcellation_name in ParcellationRegistry().list + assert parcellation_name in list_data(kind="parcellation") def test_load_incorrect() -> None: """Test loading of invalid parcellations.""" with pytest.raises(ValueError, match=r"not found"): - ParcellationRegistry().load("wrongparcellation", "MNI152NLin6Asym") + load_data( + kind="parcellation", + name="wrongparcellation", + target_space="MNI152NLin6Asym", + ) @pytest.mark.parametrize( @@ -309,14 +365,15 @@ def test_schaefer( """ parcellation_name = f"Schaefer{n_rois}x{yeo_networks}" - assert parcellation_name in ParcellationRegistry().list + assert parcellation_name in list_data(kind="parcellation") parcellation_file = ( f"Schaefer2018_{n_rois}Parcels_{yeo_networks}Networks_order_FSLMNI152_" f"{int(resolution)}mm.nii.gz" ) # Load parcellation - img, label, img_path, space = ParcellationRegistry().load( + img, label, img_path, space = load_data( + kind="parcellation", name=parcellation_name, target_space="MNI152NLin6Asym", resolution=resolution, @@ -326,7 +383,8 @@ def test_schaefer( assert len(label) == n_rois assert space == "MNI152NLin6Asym" assert_array_equal( - img.header["pixdim"][1:4], 3 * [resolution] # type: ignore + img.header["pixdim"][1:4], + 3 * [resolution], # type: ignore ) @@ -365,9 +423,10 @@ def test_suit(space_key: str, space: str) -> None: The parametrized space values. """ - assert f"SUITx{space_key}" in ParcellationRegistry().list + assert f"SUITx{space_key}" in list_data(kind="parcellation") # Load parcellation - img, label, img_path, parcellation_space = ParcellationRegistry().load( + img, label, img_path, parcellation_space = load_data( + kind="parcellation", name=f"SUITx{space_key}", target_space=space, ) @@ -398,13 +457,14 @@ def test_tian_3T_6thgeneration(scale: int, n_label: int) -> None: The parametrized n_label values. """ - parcellations = ParcellationRegistry().list + parcellations = list_data(kind="parcellation") assert "TianxS1x3TxMNI6thgeneration" in parcellations assert "TianxS2x3TxMNI6thgeneration" in parcellations assert "TianxS3x3TxMNI6thgeneration" in parcellations assert "TianxS4x3TxMNI6thgeneration" in parcellations # Load parcellation - img, lbl, fname, space = ParcellationRegistry().load( + img, lbl, fname, space = load_data( + kind="parcellation", name=f"TianxS{scale}x3TxMNI6thgeneration", target_space="MNI152NLin2009cAsym", # force highest resolution ) @@ -415,7 +475,8 @@ def test_tian_3T_6thgeneration(scale: int, n_label: int) -> None: assert len(lbl) == n_label assert_array_equal(img.header["pixdim"][1:4], [1, 1, 1]) # Load parcellation - img, lbl, fname, space = ParcellationRegistry().load( + img, lbl, fname, space = load_data( + kind="parcellation", name=f"TianxS{scale}x3TxMNI6thgeneration", target_space="MNI152NLin6Asym", resolution=2, @@ -442,13 +503,14 @@ def test_tian_3T_nonlinear2009cAsym(scale: int, n_label: int) -> None: The parametrized n_label values. """ - parcellations = ParcellationRegistry().list + parcellations = list_data(kind="parcellation") assert "TianxS1x3TxMNInonlinear2009cAsym" in parcellations assert "TianxS2x3TxMNInonlinear2009cAsym" in parcellations assert "TianxS3x3TxMNInonlinear2009cAsym" in parcellations assert "TianxS4x3TxMNInonlinear2009cAsym" in parcellations # Load parcellation - img, lbl, fname, space = ParcellationRegistry().load( + img, lbl, fname, space = load_data( + kind="parcellation", name=f"TianxS{scale}x3TxMNInonlinear2009cAsym", target_space="MNI152NLin6Asym", # force highest resolution ) @@ -459,7 +521,8 @@ def test_tian_3T_nonlinear2009cAsym(scale: int, n_label: int) -> None: assert len(lbl) == n_label assert_array_equal(img.header["pixdim"][1:4], [1, 1, 1]) # Load parcellation - img, lbl, fname, space = ParcellationRegistry().load( + img, lbl, fname, space = load_data( + kind="parcellation", name=f"TianxS{scale}x3TxMNInonlinear2009cAsym", target_space="MNI152NLin2009cAsym", resolution=2, @@ -486,13 +549,14 @@ def test_tian_7T_6thgeneration(scale: int, n_label: int) -> None: The parametrized n_label values. """ - parcellations = ParcellationRegistry().list + parcellations = list_data(kind="parcellation") assert "TianxS1x7TxMNI6thgeneration" in parcellations assert "TianxS2x7TxMNI6thgeneration" in parcellations assert "TianxS3x7TxMNI6thgeneration" in parcellations assert "TianxS4x7TxMNI6thgeneration" in parcellations # Load parcellation - img, lbl, fname, space = ParcellationRegistry().load( + img, lbl, fname, space = load_data( + kind="parcellation", name=f"TianxS{scale}x7TxMNI6thgeneration", target_space="MNI152NLin6Asym", ) @@ -502,7 +566,8 @@ def test_tian_7T_6thgeneration(scale: int, n_label: int) -> None: assert space == "MNI152NLin6Asym" assert len(lbl) == n_label assert_array_almost_equal( - img.header["pixdim"][1:4], [1.6, 1.6, 1.6] # type: ignore + img.header["pixdim"][1:4], + [1.6, 1.6, 1.6], # type: ignore ) @@ -552,9 +617,10 @@ def test_aicha(version: int) -> None: The parametrized version values. """ - assert f"AICHA_v{version}" in ParcellationRegistry().list + assert f"AICHA_v{version}" in list_data(kind="parcellation") # Load parcellation - img, label, img_path, space = ParcellationRegistry().load( + img, label, img_path, space = load_data( + kind="parcellation", name=f"AICHA_v{version}", target_space="IXI549Space", ) @@ -610,9 +676,10 @@ def test_shen( The parametrized partial file names. """ - assert f"Shen_{year}_{n_rois}" in ParcellationRegistry().list + assert f"Shen_{year}_{n_rois}" in list_data(kind="parcellation") # Load parcellation - img, label, img_path, space = ParcellationRegistry().load( + img, label, img_path, space = load_data( + kind="parcellation", name=f"Shen_{year}_{n_rois}", target_space="MNI152NLin2009cAsym", resolution=resolution, @@ -622,7 +689,8 @@ def test_shen( assert space == "MNI152NLin2009cAsym" assert len(label) == n_labels assert_array_equal( - img.header["pixdim"][1:4], 3 * [resolution] # type: ignore + img.header["pixdim"][1:4], + 3 * [resolution], # type: ignore ) @@ -771,7 +839,7 @@ def test_yan( The parametrized Kong networks values. """ - parcellations = ParcellationRegistry().list + parcellations = list_data(kind="parcellation") if yeo_networks: parcellation_name = f"Yan{n_rois}xYeo{yeo_networks}" assert parcellation_name in parcellations @@ -787,7 +855,8 @@ def test_yan( f"{int(resolution)}mm.nii.gz" ) # Load parcellation - img, label, img_path, space = ParcellationRegistry().load( + img, label, img_path, space = load_data( + kind="parcellation", name=parcellation_name, target_space="MNI152NLin6Asym", resolution=resolution, @@ -797,7 +866,8 @@ def test_yan( assert space == "MNI152NLin6Asym" assert len(label) == n_rois assert_array_equal( - img.header["pixdim"][1:4], 3 * [resolution] # type: ignore + img.header["pixdim"][1:4], + 3 * [resolution], # type: ignore ) @@ -877,7 +947,7 @@ def test_brainnetome( The parametrized threshold values. """ - parcellations = ParcellationRegistry().list + parcellations = list_data(kind="parcellation") parcellation_name = f"Brainnetome_thr{threshold}" assert parcellation_name in parcellations @@ -887,7 +957,8 @@ def test_brainnetome( parcellation_file = f"BNA-maxprob-thr{threshold}-{resolution}mm.nii.gz" # Load parcellation - img, label, img_path, space = ParcellationRegistry().load( + img, label, img_path, space = load_data( + kind="parcellation", name=parcellation_name, target_space="MNI152NLin6Asym", resolution=resolution, @@ -897,7 +968,8 @@ def test_brainnetome( assert space == "MNI152NLin6Asym" assert len(label) == 246 assert_array_equal( - img.header["pixdim"][1:4], 3 * [resolution] # type: ignore + img.header["pixdim"][1:4], + 3 * [resolution], # type: ignore ) @@ -912,11 +984,14 @@ def test_retrieve_brainnetome_incorrect_threshold() -> None: def test_merge_parcellations() -> None: """Test merging parcellations.""" # load some parcellations for testing - schaefer_parcellation, schaefer_labels, _, _ = ParcellationRegistry().load( - "Schaefer100x17", target_space="MNI152NLin2009cAsym" + schaefer_parcellation, schaefer_labels, _, _ = load_data( + kind="parcellation", + name="Schaefer100x17", + target_space="MNI152NLin2009cAsym", ) - tian_parcellation, tian_labels, _, _ = ParcellationRegistry().load( - "TianxS2x3TxMNInonlinear2009cAsym", + tian_parcellation, tian_labels, _, _ = load_data( + kind="parcellation", + name="TianxS2x3TxMNInonlinear2009cAsym", target_space="MNI152NLin2009cAsym", ) # prepare the list of the actual parcellations @@ -949,8 +1024,10 @@ def test_merge_parcellations_3D_multiple_non_overlapping( """ # Get the testing parcellation - parcellation, labels, _, _ = ParcellationRegistry().load( - "Schaefer100x7", target_space="MNI152NLin2009cAsym" + parcellation, labels, _, _ = load_data( + kind="parcellation", + name="Schaefer100x7", + target_space="MNI152NLin2009cAsym", ) assert parcellation is not None @@ -986,8 +1063,10 @@ def test_merge_parcellations_3D_multiple_overlapping() -> None: """Test merge_parcellations with multiple overlapping parcellations.""" # Get the testing parcellation - parcellation, labels, _, _ = ParcellationRegistry().load( - "Schaefer100x7", target_space="MNI152NLin2009cAsym" + parcellation, labels, _, _ = load_data( + kind="parcellation", + name="Schaefer100x7", + target_space="MNI152NLin2009cAsym", ) assert parcellation is not None @@ -1023,8 +1102,10 @@ def test_merge_parcellations_3D_multiple_duplicated_labels() -> None: """Test merge_parcellations with duplicated labels.""" # Get the testing parcellation - parcellation, labels, _, _ = ParcellationRegistry().load( - "Schaefer100x7", target_space="MNI152NLin2009cAsym" + parcellation, labels, _, _ = load_data( + kind="parcellation", + name="Schaefer100x7", + target_space="MNI152NLin2009cAsym", ) assert parcellation is not None @@ -1064,15 +1145,17 @@ def test_get_single() -> None: bold = element_data["BOLD"] bold_img = bold["data"] # Get tailored parcellation - tailored_parcellation, tailored_labels = ParcellationRegistry().get( - parcellations=["Shen_2015_268"], + tailored_parcellation, tailored_labels = get_data( + kind="parcellation", + names=["Shen_2015_268"], target_data=bold, ) # Check shape and affine with original element data assert tailored_parcellation.shape == bold_img.shape[:3] assert_array_equal(tailored_parcellation.affine, bold_img.affine) # Get raw parcellation - raw_parcellation, raw_labels, _, _ = ParcellationRegistry().load( + raw_parcellation, raw_labels, _, _ = load_data( + kind="parcellation", name="Shen_2015_268", target_space="MNI152NLin2009cAsym", resolution=4, @@ -1098,8 +1181,9 @@ def test_get_multi_same_space() -> None: bold = element_data["BOLD"] bold_img = bold["data"] # Get tailored parcellation - tailored_parcellation, tailored_labels = ParcellationRegistry().get( - parcellations=[ + tailored_parcellation, tailored_labels = get_data( + kind="parcellation", + names=[ "Shen_2015_268", "TianxS1x3TxMNInonlinear2009cAsym", ], @@ -1116,7 +1200,8 @@ def test_get_multi_same_space() -> None: "TianxS1x3TxMNInonlinear2009cAsym", ] for name in parcellations_names: - img, labels, _, _ = ParcellationRegistry().load( + img, labels, _, _ = load_data( + kind="parcellation", name=name, target_space="MNI152NLin2009cAsym", resolution=4, @@ -1152,8 +1237,9 @@ def test_get_multi_different_space() -> None: with OasisVBMTestingDataGrabber() as dg: element_data = DefaultDataReader().fit_transform(dg["sub-01"]) # Get tailored parcellation - ParcellationRegistry().get( - parcellations=[ + get_data( + kind="parcellation", + names=[ "Schaefer100x7", "TianxS1x3TxMNInonlinear2009cAsym", ], diff --git a/junifer/data/tests/test_data_utils.py b/junifer/data/tests/test_data_utils.py index 97b1268b4..050fba22b 100644 --- a/junifer/data/tests/test_data_utils.py +++ b/junifer/data/tests/test_data_utils.py @@ -3,7 +3,6 @@ # Authors: Federico Raimondo # License: AGPL - import numpy as np import pytest diff --git a/junifer/data/utils.py b/junifer/data/utils.py index 836f96599..865c3d2bf 100644 --- a/junifer/data/utils.py +++ b/junifer/data/utils.py @@ -76,7 +76,7 @@ def get_native_warper( target_data: MutableMapping, other_data: MutableMapping, inverse: bool = False, -) -> dict: +) -> dict: # pragma: no cover """Get correct warping specification for native space. Parameters diff --git a/junifer/datagrabber/aomic/id1000.py b/junifer/datagrabber/aomic/id1000.py index 760faa50d..10b50f39e 100644 --- a/junifer/datagrabber/aomic/id1000.py +++ b/junifer/datagrabber/aomic/id1000.py @@ -35,6 +35,12 @@ class DataladAOMICID1000(PatternDataladDataGrabber): space : {"native", "MNI152NLin2009cAsym"}, optional The space to use for the data (default "MNI152NLin2009cAsym"). + Raises + ------ + ValueError + If invalid value is passed for: + * ``space`` + """ def __init__( diff --git a/junifer/datagrabber/aomic/piop1.py b/junifer/datagrabber/aomic/piop1.py index 3afc74f03..2e1bf8f58 100644 --- a/junifer/datagrabber/aomic/piop1.py +++ b/junifer/datagrabber/aomic/piop1.py @@ -43,7 +43,9 @@ class DataladAOMICPIOP1(PatternDataladDataGrabber): Raises ------ ValueError - If invalid value is passed for ``tasks``. + If invalid value is passed for: + * ``tasks`` + * ``space`` """ @@ -79,8 +81,7 @@ class DataladAOMICPIOP1(PatternDataladDataGrabber): for t in tasks: if t not in all_tasks: raise_error( - f"{t} is not a valid task in the AOMIC PIOP1" - " dataset!" + f"{t} is not a valid task in the AOMIC PIOP1 dataset!" ) self.tasks = tasks # Descriptor for space in `anat` diff --git a/junifer/datagrabber/aomic/piop2.py b/junifer/datagrabber/aomic/piop2.py index 7bee74f61..1203efed2 100644 --- a/junifer/datagrabber/aomic/piop2.py +++ b/junifer/datagrabber/aomic/piop2.py @@ -43,7 +43,9 @@ class DataladAOMICPIOP2(PatternDataladDataGrabber): Raises ------ ValueError - If invalid value is passed for ``tasks``. + If invalid value is passed for: + * ``tasks`` + * ``space`` """ @@ -77,8 +79,7 @@ class DataladAOMICPIOP2(PatternDataladDataGrabber): for t in tasks: if t not in all_tasks: raise_error( - f"{t} is not a valid task in the AOMIC PIOP2" - " dataset!" + f"{t} is not a valid task in the AOMIC PIOP2 dataset!" ) self.tasks = tasks # Descriptor for space in `anat` diff --git a/junifer/datagrabber/pattern_datalad.py b/junifer/datagrabber/pattern_datalad.py index ccf47fe52..112c1955d 100644 --- a/junifer/datagrabber/pattern_datalad.py +++ b/junifer/datagrabber/pattern_datalad.py @@ -5,7 +5,6 @@ # Synchon Mandal # License: AGPL - from ..api.decorators import register_datagrabber from ..utils import logger from .datalad_base import DataladDataGrabber diff --git a/junifer/datagrabber/pattern_validation_mixin.py b/junifer/datagrabber/pattern_validation_mixin.py index c3a950182..52479b183 100644 --- a/junifer/datagrabber/pattern_validation_mixin.py +++ b/junifer/datagrabber/pattern_validation_mixin.py @@ -3,7 +3,6 @@ # Authors: Synchon Mandal # License: AGPL - from ..typing import DataGrabberPatterns from ..utils import logger, raise_error, warn_with_log diff --git a/junifer/datagrabber/tests/test_dmcc13_benchmark.py b/junifer/datagrabber/tests/test_dmcc13_benchmark.py index 3b7342292..d3e124c90 100644 --- a/junifer/datagrabber/tests/test_dmcc13_benchmark.py +++ b/junifer/datagrabber/tests/test_dmcc13_benchmark.py @@ -264,7 +264,7 @@ def test_DMCC13Benchmark_invalid_sessions(): """Test DMCC13Benchmark DataGrabber invalid sessions.""" with pytest.raises( ValueError, - match=("phonyses is not a valid session in " "the DMCC dataset"), + match=("phonyses is not a valid session in the DMCC dataset"), ): DMCC13Benchmark(sessions="phonyses") @@ -273,9 +273,7 @@ def test_DMCC13Benchmark_invalid_tasks(): """Test DMCC13Benchmark DataGrabber invalid tasks.""" with pytest.raises( ValueError, - match=( - "thisisnotarealtask is not a valid task in " "the DMCC dataset" - ), + match=("thisisnotarealtask is not a valid task in the DMCC dataset"), ): DMCC13Benchmark(tasks="thisisnotarealtask") @@ -284,9 +282,7 @@ def test_DMCC13Benchmark_phase_encodings(): """Test DMCC13Benchmark DataGrabber invalid phase encodings.""" with pytest.raises( ValueError, - match=( - "moonphase is not a valid phase encoding in " "the DMCC dataset" - ), + match=("moonphase is not a valid phase encoding in the DMCC dataset"), ): DMCC13Benchmark(phase_encodings="moonphase") @@ -295,6 +291,6 @@ def test_DMCC13Benchmark_runs(): """Test DMCC13Benchmark DataGrabber invalid runs.""" with pytest.raises( ValueError, - match=("cerebralrun is not a valid run in " "the DMCC dataset"), + match=("cerebralrun is not a valid run in the DMCC dataset"), ): DMCC13Benchmark(runs="cerebralrun") diff --git a/junifer/markers/base.py b/junifer/markers/base.py index e40d7bb09..cc7a8b684 100644 --- a/junifer/markers/base.py +++ b/junifer/markers/base.py @@ -229,9 +229,9 @@ class BaseMarker(ABC, PipelineStepMixin, UpdateMetaMixin): # feature data is not manipulated, only meta self.update_meta(feature_data_copy, "marker") # Update marker feature's metadata name - feature_data_copy["meta"]["marker"][ - "name" - ] += f"_{feature_name}" + feature_data_copy["meta"]["marker"]["name"] += ( + f"_{feature_name}" + ) if storage is not None: logger.info(f"Storing in {storage}") diff --git a/junifer/markers/brainprint.py b/junifer/markers/brainprint.py index ea6a81fec..815c3f820 100644 --- a/junifer/markers/brainprint.py +++ b/junifer/markers/brainprint.py @@ -116,7 +116,7 @@ class BrainPrint(BaseMarker): aseg_path: Path, norm_path: Path, indices: list, - ) -> Path: + ) -> Path: # pragma: no cover """Generate a surface from the aseg and label files. Parameters @@ -191,7 +191,7 @@ class BrainPrint(BaseMarker): self, aseg_path: Path, norm_path: Path, - ) -> dict[str, Path]: + ) -> dict[str, Path]: # pragma: no cover """Create surfaces from FreeSurfer aseg labels. Parameters @@ -266,7 +266,7 @@ class BrainPrint(BaseMarker): rh_white_path: Path, lh_pial_path: Path, rh_pial_path: Path, - ) -> dict[str, Path]: + ) -> dict[str, Path]: # pragma: no cover """Create cortical surfaces from FreeSurfer labels. Parameters @@ -308,7 +308,7 @@ class BrainPrint(BaseMarker): def _fix_nan( self, input_data: list[Union[float, str, npt.ArrayLike]], - ) -> np.ndarray: + ) -> np.ndarray: # pragma: no cover """Convert BrainPrint output with string NaN to ``numpy.nan``. Parameters @@ -330,7 +330,7 @@ class BrainPrint(BaseMarker): self, input: dict[str, Any], extra_input: Optional[dict] = None, - ) -> dict: + ) -> dict: # pragma: no cover """Compute. Parameters diff --git a/junifer/markers/complexity/multiscale_entropy_auc.py b/junifer/markers/complexity/multiscale_entropy_auc.py index 66ce3c514..bd156ad35 100644 --- a/junifer/markers/complexity/multiscale_entropy_auc.py +++ b/junifer/markers/complexity/multiscale_entropy_auc.py @@ -114,9 +114,9 @@ class MultiscaleEntropyAUC(ComplexityBase): assert isinstance(emb_dim, int), "Embedding dimension must be integer." assert isinstance(scale, int), "Scale must be integer." - assert isinstance( - tol, float - ), "Tolerance must be a positive float number." + assert isinstance(tol, float), ( + "Tolerance must be a positive float number." + ) _, n_roi = extracted_bold_values.shape MSEn_auc_roi = np.zeros((n_roi, 1)) diff --git a/junifer/markers/complexity/range_entropy.py b/junifer/markers/complexity/range_entropy.py index bccca8309..e67154543 100644 --- a/junifer/markers/complexity/range_entropy.py +++ b/junifer/markers/complexity/range_entropy.py @@ -114,9 +114,9 @@ class RangeEntropy(ComplexityBase): assert isinstance(emb_dim, int), "Embedding dimension must be integer." assert isinstance(delay, int), "Delay must be integer." - assert isinstance( - tolerance, float - ), "Tolerance must be a float number between 0 and 1." + assert isinstance(tolerance, float), ( + "Tolerance must be a float number between 0 and 1." + ) _, n_roi = extracted_bold_values.shape range_en_roi = np.zeros((n_roi, 1)) diff --git a/junifer/markers/complexity/sample_entropy.py b/junifer/markers/complexity/sample_entropy.py index e41add496..a8199b114 100644 --- a/junifer/markers/complexity/sample_entropy.py +++ b/junifer/markers/complexity/sample_entropy.py @@ -115,9 +115,9 @@ class SampleEntropy(ComplexityBase): assert isinstance(emb_dim, int), "Embedding dimension must be integer." assert isinstance(delay, int), "Delay must be integer." - assert isinstance( - tol, float - ), "Tolerance must be a positive float number." + assert isinstance(tol, float), ( + "Tolerance must be a positive float number." + ) _, n_roi = extracted_bold_values.shape samp_en_roi = np.zeros((n_roi, 1)) diff --git a/junifer/markers/falff/falff_parcels.py b/junifer/markers/falff/falff_parcels.py index ddf985956..7fbaf896b 100644 --- a/junifer/markers/falff/falff_parcels.py +++ b/junifer/markers/falff/falff_parcels.py @@ -151,9 +151,7 @@ class ALFFParcels(ALFFBase): ).compute( input=aggregation_alff_input, extra_input=extra_input, - )[ - "aggregation" - ], + )["aggregation"], }, "falff": { **ParcelAggregation( @@ -165,8 +163,6 @@ class ALFFParcels(ALFFBase): ).compute( input=aggregation_falff_input, extra_input=extra_input, - )[ - "aggregation" - ], + )["aggregation"], }, } diff --git a/junifer/markers/falff/falff_spheres.py b/junifer/markers/falff/falff_spheres.py index 3d70fb26e..faee35b57 100644 --- a/junifer/markers/falff/falff_spheres.py +++ b/junifer/markers/falff/falff_spheres.py @@ -164,9 +164,7 @@ class ALFFSpheres(ALFFBase): ).compute( input=aggregation_alff_input, extra_input=extra_input, - )[ - "aggregation" - ], + )["aggregation"], }, "falff": { **SphereAggregation( @@ -180,8 +178,6 @@ class ALFFSpheres(ALFFBase): ).compute( input=aggregation_falff_input, extra_input=extra_input, - )[ - "aggregation" - ], + )["aggregation"], }, } diff --git a/junifer/markers/functional_connectivity/functional_connectivity_base.py b/junifer/markers/functional_connectivity/functional_connectivity_base.py index 6394a3751..e35bf23d3 100644 --- a/junifer/markers/functional_connectivity/functional_connectivity_base.py +++ b/junifer/markers/functional_connectivity/functional_connectivity_base.py @@ -3,7 +3,6 @@ # Authors: Synchon Mandal # License: AGPL - from abc import abstractmethod from typing import Any, ClassVar, Optional, Union diff --git a/junifer/markers/functional_connectivity/tests/test_functional_connectivity_parcels.py b/junifer/markers/functional_connectivity/tests/test_functional_connectivity_parcels.py index fdc50b354..07757e1d0 100644 --- a/junifer/markers/functional_connectivity/tests/test_functional_connectivity_parcels.py +++ b/junifer/markers/functional_connectivity/tests/test_functional_connectivity_parcels.py @@ -91,7 +91,8 @@ def test_FunctionalConnectivityParcels( ) # Compute the connectivity measure connectivity_measure = ConnectivityMeasure( - cov_estimator=cov_estimator, kind="correlation" # type: ignore + cov_estimator=cov_estimator, + kind="correlation", # type: ignore ).fit_transform([extracted_timeseries])[0] # Check that FC are almost equal diff --git a/junifer/markers/functional_connectivity/tests/test_functional_connectivity_spheres.py b/junifer/markers/functional_connectivity/tests/test_functional_connectivity_spheres.py index 789fdada5..854961804 100644 --- a/junifer/markers/functional_connectivity/tests/test_functional_connectivity_spheres.py +++ b/junifer/markers/functional_connectivity/tests/test_functional_connectivity_spheres.py @@ -92,7 +92,8 @@ def test_FunctionalConnectivitySpheres( ) # Compute the connectivity measure connectivity_measure = ConnectivityMeasure( - cov_estimator=cov_estimator, kind="correlation" # type: ignore + cov_estimator=cov_estimator, + kind="correlation", # type: ignore ).fit_transform([extracted_timeseries])[0] # Check that FC are almost equal diff --git a/junifer/markers/reho/_afni_reho.py b/junifer/markers/reho/_afni_reho.py index e73cecc78..47f3a2341 100644 --- a/junifer/markers/reho/_afni_reho.py +++ b/junifer/markers/reho/_afni_reho.py @@ -41,7 +41,7 @@ class AFNIReHo(metaclass=Singleton): }, ] - def __del__(self) -> None: + def __del__(self) -> None: # pragma: no cover """Terminate the class.""" # Clear the computation cache logger.debug("Clearing cache for ReHo computation via AFNI") diff --git a/junifer/markers/reho/reho_base.py b/junifer/markers/reho/reho_base.py index 1877bacc5..cb0e363ed 100644 --- a/junifer/markers/reho/reho_base.py +++ b/junifer/markers/reho/reho_base.py @@ -3,7 +3,6 @@ # Authors: Synchon Mandal # License: AGPL - from pathlib import Path from typing import ( TYPE_CHECKING, diff --git a/junifer/markers/reho/reho_parcels.py b/junifer/markers/reho/reho_parcels.py index 2dcb81824..f78a84251 100644 --- a/junifer/markers/reho/reho_parcels.py +++ b/junifer/markers/reho/reho_parcels.py @@ -3,7 +3,6 @@ # Authors: Synchon Mandal # License: AGPL - from typing import Any, Optional, Union import numpy as np diff --git a/junifer/markers/reho/reho_spheres.py b/junifer/markers/reho/reho_spheres.py index ea45e2029..0d6afb38d 100644 --- a/junifer/markers/reho/reho_spheres.py +++ b/junifer/markers/reho/reho_spheres.py @@ -3,7 +3,6 @@ # Authors: Synchon Mandal # License: AGPL - from typing import Any, Optional, Union import numpy as np diff --git a/junifer/markers/temporal_snr/temporal_snr_base.py b/junifer/markers/temporal_snr/temporal_snr_base.py index 361eb99a8..c0f946c12 100644 --- a/junifer/markers/temporal_snr/temporal_snr_base.py +++ b/junifer/markers/temporal_snr/temporal_snr_base.py @@ -3,7 +3,6 @@ # Authors: Leonard Sasse # License: AGPL - from abc import abstractmethod from typing import Any, ClassVar, Optional, Union diff --git a/junifer/markers/tests/test_markers_base.py b/junifer/markers/tests/test_markers_base.py index 4e383186a..b513bc003 100644 --- a/junifer/markers/tests/test_markers_base.py +++ b/junifer/markers/tests/test_markers_base.py @@ -20,7 +20,6 @@ def test_base_marker_subclassing() -> None: # Create concrete class class MyBaseMarker(BaseMarker): - _MARKER_INOUT_MAPPINGS = { # noqa: RUF012 "BOLD": { "feat_1": "timeseries", diff --git a/junifer/onthefly/_brainprint.py b/junifer/onthefly/_brainprint.py index 3e4b71e9a..2f8743369 100644 --- a/junifer/onthefly/_brainprint.py +++ b/junifer/onthefly/_brainprint.py @@ -19,7 +19,7 @@ def normalize( storage: StorageLike, features: dict[str, dict[str, Optional[str]]], kind: str, -) -> pd.DataFrame: +) -> pd.DataFrame: # pragma: no cover """Read stored brainprint data and normalize either surfaces or volumes. Parameters @@ -79,7 +79,7 @@ def normalize( ) else: raise_error( - "Invalid value for `kind`, should be one of: " f"{valid_kind}" + f"Invalid value for `kind`, should be one of: {valid_kind}" ) return normalized_df @@ -89,7 +89,7 @@ def reweight( storage: StorageLike, feature_name: Optional[str] = None, feature_md5: Optional[str] = None, -) -> pd.DataFrame: +) -> pd.DataFrame: # pragma: no cover """Read stored brainprint data and reweight eigenvalues. Parameters diff --git a/junifer/onthefly/read_transform.py b/junifer/onthefly/read_transform.py index 9913c2a46..122f1f436 100644 --- a/junifer/onthefly/read_transform.py +++ b/junifer/onthefly/read_transform.py @@ -3,7 +3,6 @@ # Authors: Synchon Mandal # License: AGPL - from typing import Optional import pandas as pd @@ -85,7 +84,7 @@ def read_transform( # Check bctpy import try: import bct - except ImportError as err: + except ImportError as err: # pragma: no cover raise_error(msg=str(err), klass=ImportError) # Warning about function usage diff --git a/junifer/onthefly/tests/test_read_transform.py b/junifer/onthefly/tests/test_read_transform.py index 0eec389f5..948dabfd1 100644 --- a/junifer/onthefly/tests/test_read_transform.py +++ b/junifer/onthefly/tests/test_read_transform.py @@ -3,7 +3,6 @@ # Authors: Synchon Mandal # License: AGPL - import logging from pathlib import Path diff --git a/junifer/pipeline/tests/test_marker_collection.py b/junifer/pipeline/tests/test_marker_collection.py index 378c76778..9a96893f9 100644 --- a/junifer/pipeline/tests/test_marker_collection.py +++ b/junifer/pipeline/tests/test_marker_collection.py @@ -186,7 +186,8 @@ def test_marker_collection_storage(tmp_path: Path) -> None: assert out is None mc2 = MarkerCollection( - markers=markers, datareader=DefaultDataReader() # type: ignore + markers=markers, + datareader=DefaultDataReader(), # type: ignore ) mc2.validate(dg) assert mc2._storage is None diff --git a/junifer/pipeline/workdir_manager.py b/junifer/pipeline/workdir_manager.py index 93b62a132..2c8ca515c 100644 --- a/junifer/pipeline/workdir_manager.py +++ b/junifer/pipeline/workdir_manager.py @@ -197,8 +197,7 @@ class WorkDirManager(metaclass=Singleton): return if self._elementdir is not None: logger.debug( - "Deleting element directory at " - f"{self._elementdir.resolve()!s}" + f"Deleting element directory at {self._elementdir.resolve()!s}" ) shutil.rmtree(self._elementdir, ignore_errors=True) self._elementdir = None diff --git a/junifer/preprocess/confounds/fmriprep_confound_remover.py b/junifer/preprocess/confounds/fmriprep_confound_remover.py index 2cce6714b..9bdf66533 100644 --- a/junifer/preprocess/confounds/fmriprep_confound_remover.py +++ b/junifer/preprocess/confounds/fmriprep_confound_remover.py @@ -572,7 +572,7 @@ class fMRIPrepConfoundRemover(BasePreprocessor): if bold_img.get_fdata().shape[3] != len(confound_df): raise_error( "Image time series and confounds have different length!\n" - f"\tImage time series: { bold_img.get_fdata().shape[3]}\n" + f"\tImage time series: {bold_img.get_fdata().shape[3]}\n" f"\tConfounds: {len(confound_df)}" ) diff --git a/junifer/preprocess/confounds/tests/test_fmriprep_confound_remover.py b/junifer/preprocess/confounds/tests/test_fmriprep_confound_remover.py index 51bfafb01..770a61e7a 100644 --- a/junifer/preprocess/confounds/tests/test_fmriprep_confound_remover.py +++ b/junifer/preprocess/confounds/tests/test_fmriprep_confound_remover.py @@ -5,7 +5,6 @@ # Synchon Mandal # License: AGPL - import numpy as np import pandas as pd import pytest diff --git a/junifer/preprocess/smoothing/tests/test_smoothing.py b/junifer/preprocess/smoothing/tests/test_smoothing.py index 6fe66c55b..cd50fce86 100644 --- a/junifer/preprocess/smoothing/tests/test_smoothing.py +++ b/junifer/preprocess/smoothing/tests/test_smoothing.py @@ -3,7 +3,6 @@ # Authors: Synchon Mandal # License: AGPL - import pytest from junifer.datareader import DefaultDataReader diff --git a/junifer/preprocess/warping/_ants_warper.py b/junifer/preprocess/warping/_ants_warper.py index 98112f51a..3ecb5711c 100644 --- a/junifer/preprocess/warping/_ants_warper.py +++ b/junifer/preprocess/warping/_ants_warper.py @@ -72,7 +72,7 @@ class ANTsWarper: ) # Native space warping - if reference == "T1w": + if reference == "T1w": # pragma: no cover logger.debug("Using ANTs for space warping") # Get the min of the voxel sizes from input and use it as the @@ -237,8 +237,7 @@ class ANTsWarper: if input.get("mask") is not None: # Create a tempfile for warped mask output apply_transforms_mask_out_path = element_tempdir / ( - f"warped_mask_from_{input['space']}_to_" - f"{reference}.nii.gz" + f"warped_mask_from_{input['space']}_to_{reference}.nii.gz" ) # Set antsApplyTransforms command apply_transforms_mask_cmd = [ diff --git a/junifer/preprocess/warping/_fsl_warper.py b/junifer/preprocess/warping/_fsl_warper.py index 2d66982f9..3edae21f2 100644 --- a/junifer/preprocess/warping/_fsl_warper.py +++ b/junifer/preprocess/warping/_fsl_warper.py @@ -40,7 +40,7 @@ class FSLWarper: self, input: dict[str, Any], extra_input: dict[str, Any], - ) -> dict[str, Any]: + ) -> dict[str, Any]: # pragma: no cover """Preprocess using FSL. Parameters diff --git a/junifer/preprocess/warping/space_warper.py b/junifer/preprocess/warping/space_warper.py index b34df8650..789ea9a63 100644 --- a/junifer/preprocess/warping/space_warper.py +++ b/junifer/preprocess/warping/space_warper.py @@ -77,7 +77,7 @@ class SpaceWarper(BasePreprocessor): self.reference = reference # Set required data types based on reference and # initialize superclass - if self.reference == "T1w": + if self.reference == "T1w": # pragma: no cover required_data_types = [self.reference, "Warp"] # Listify on if not isinstance(on, list): @@ -170,7 +170,9 @@ class SpaceWarper(BasePreprocessor): """ logger.info(f"Warping to {self.reference} space using SpaceWarper") # Transform to native space - if self.using in ["fsl", "ants", "auto"] and self.reference == "T1w": + if ( + self.using in ["fsl", "ants", "auto"] and self.reference == "T1w" + ): # pragma: no cover # Check for extra inputs if extra_input is None: raise_error( diff --git a/junifer/storage/pandas_base.py b/junifer/storage/pandas_base.py index e78d57e17..fbc66b9f4 100644 --- a/junifer/storage/pandas_base.py +++ b/junifer/storage/pandas_base.py @@ -187,7 +187,9 @@ class PandasBaseFeatureStorage(BaseFeatureStorage): ) # Prepare new dataframe df = pd.DataFrame( - data=data, columns=col_names, index=idx # type: ignore + data=data, + columns=col_names, + index=idx, # type: ignore ) # Store dataframe self.store_df(meta_md5=meta_md5, element=element, df=df) diff --git a/junifer/storage/sqlite.py b/junifer/storage/sqlite.py index f12ed3b4b..6c0fb03d3 100644 --- a/junifer/storage/sqlite.py +++ b/junifer/storage/sqlite.py @@ -229,9 +229,7 @@ class SQLiteFeatureStorage(PandasBaseFeatureStorage): # Format index names for retrieved data meta_df.index = meta_df.index.str.replace(r"meta_", "") # Convert dataframe to dictionary - out: dict[str, dict[str, str]] = meta_df.to_dict( - orient="index" - ) # type: ignore + out: dict[str, dict[str, str]] = meta_df.to_dict(orient="index") # type: ignore # Format output for md5, t_meta in out.items(): for k, v in t_meta.items(): @@ -536,8 +534,7 @@ class SQLiteFeatureStorage(PandasBaseFeatureStorage): klass=IOError, ) logger.info( - "Collecting data from " - f"{self.uri.parent}/*{self.uri.name}" # type: ignore + f"Collecting data from {self.uri.parent}/*{self.uri.name}" # type: ignore ) # Create new instance out_storage = SQLiteFeatureStorage(uri=self.uri, upsert="ignore") @@ -596,9 +593,7 @@ def _generate_update_statements(table, index_col, rows_to_update): for i, (_, keys) in enumerate(pk_indb.iterrows()): stmt = ( table.update() - .where( - and_(col == keys[j] for j, col in enumerate(pk_cols)) - ) # type: ignore + .where(and_(col == keys[j] for j, col in enumerate(pk_cols))) # type: ignore .values(new_records[i]) ) stmts.append(stmt) diff --git a/junifer/storage/tests/test_pandas_base.py b/junifer/storage/tests/test_pandas_base.py index 2bd46a183..ead32012a 100644 --- a/junifer/storage/tests/test_pandas_base.py +++ b/junifer/storage/tests/test_pandas_base.py @@ -37,7 +37,8 @@ def test_element_to_index() -> None: assert index.levels[1].name == "idx" # type: ignore # Check second index level values assert all( - x == i for i, x in enumerate(index.levels[1].values) # type: ignore + x == i + for i, x in enumerate(index.levels[1].values) # type: ignore ) # Check second index level values shape assert index.levels[1].values.shape == (10,) # type: ignore @@ -69,7 +70,8 @@ def test_element_to_index() -> None: assert index.levels[1].name == "scan" # type: ignore # Check second index level values assert all( - x == i for i, x in enumerate(index.levels[1].values) # type: ignore + x == i + for i, x in enumerate(index.levels[1].values) # type: ignore ) # Check second index level values shape assert index.levels[1].values.shape == (7,) # type: ignore @@ -97,7 +99,8 @@ def test_element_to_index() -> None: assert index.levels[2].name == "idx" # type: ignore # Check third index level values assert all( - x == i for i, x in enumerate(index.levels[2].values) # type: ignore + x == i + for i, x in enumerate(index.levels[2].values) # type: ignore ) # Check third index level values shape assert index.levels[2].values.shape == (10,) # type: ignore diff --git a/junifer/storage/tests/test_storage_base.py b/junifer/storage/tests/test_storage_base.py index add40d5df..5463909bc 100644 --- a/junifer/storage/tests/test_storage_base.py +++ b/junifer/storage/tests/test_storage_base.py @@ -13,7 +13,8 @@ def test_BaseFeatureStorage_abstractness() -> None: """Test BaseFeatureStorage is abstract base class.""" with pytest.raises(TypeError, match=r"abstract"): BaseFeatureStorage( - uri="/tmp", storage_types=["matrix"] # type: ignore + uri="/tmp", + storage_types=["matrix"], # type: ignore ) diff --git a/junifer/utils/logging.py b/junifer/utils/logging.py index ecaccadca..0951285d3 100644 --- a/junifer/utils/logging.py +++ b/junifer/utils/logging.py @@ -8,15 +8,14 @@ import os import sys -if sys.version_info < (3, 12): +if sys.version_info < (3, 12): # pragma: no cover from distutils.version import LooseVersion -else: # pragma: no cover +else: from looseversion import LooseVersion import logging import warnings from pathlib import Path -from subprocess import PIPE, Popen, TimeoutExpired from typing import ClassVar, NoReturn, Optional, Union from warnings import warn @@ -77,7 +76,7 @@ class WrapStdOut(logging.StreamHandler): # just stdout) in order for this to work (tested on OSX and Linux) if hasattr(sys.stdout, name): return getattr(sys.stdout, name) - else: + else: # pragma: no cover raise AttributeError(f"'file' object has not attribute '{name}'") @@ -107,11 +106,13 @@ class ColorFormatter(logging.Formatter): COLOR_SEQ: str = "\033[1;%dm" BOLD_SEQ: str = "\033[1m" - def __init__(self, fmt: str, datefmt: Optional[str] = None) -> None: + def __init__( + self, fmt: str, datefmt: Optional[str] = None + ) -> None: # pragma: no cover """Initialize the ColorFormatter.""" logging.Formatter.__init__(self, fmt, datefmt) - def format(self, record: logging.LogRecord) -> str: + def format(self, record: logging.LogRecord) -> str: # pragma: no cover """Format the log record. Parameters @@ -134,45 +135,6 @@ class ColorFormatter(logging.Formatter): return logging.Formatter.format(self, record) -def _get_git_head(path: Path) -> str: - """Aux function to read HEAD from git. - - Parameters - ---------- - path : pathlib.Path - The path to read git HEAD from. - - Returns - ------- - str - Empty string if timeout expired for subprocess command execution else - git HEAD information. - - Raises - ------ - FileNotFoundError - If ``path`` is invalid. - - """ - if not path.exists(): - raise_error( - msg=f"This path does not exist: {path}", klass=FileNotFoundError - ) - command = f"cd {path}; git rev-parse --verify HEAD" - process = Popen( - args=command, - stdout=PIPE, - shell=True, - ) - try: - stdout, _ = process.communicate(timeout=10) - proc_stdout = stdout.strip().decode() - except TimeoutExpired: - process.kill() - proc_stdout = "" - return proc_stdout - - def get_versions() -> dict: """Import stuff and get versions if module. @@ -182,52 +144,22 @@ def get_versions() -> dict: The module names and corresponding versions. """ + # Setup dictionary to track versions of modules module_versions = {} for name, module in sys.modules.copy().items(): # Bypassing sub-modules of packages and # allowing ruamel.yaml if "." in name and name != "ruamel.yaml": continue - if name in ["_curses"]: - continue + # Get version or None as string vstring = str(getattr(module, "__version__", None)) - module_version = LooseVersion(vstring) - module_version = getattr(module_version, "vstring", None) - if module_version is None: - module_version = None - elif "git" in module_version: - git_path = Path(module.__file__).resolve().parent # type: ignore - head = _get_git_head(git_path) - module_version += f"-HEAD:{head}" - + # Get module version + module_version = getattr(LooseVersion(vstring), "vstring", None) module_versions[name] = module_version return module_versions -# def get_ext_versions(tbox_path: Path) -> Dict: -# """Get versions of external tools used by junifer. - -# Parameters -# ---------- -# tbox_path : pathlib.Path -# The path to external toolboxes. - -# Returns -# ------- -# dict -# The dependency information. - -# """ -# versions = {} -# # spm_path = tbox_path / 'spm12' -# # if spm_path.exists(): -# # head = _get_git_head(spm_path) -# # module_version = 'SPM12-HEAD:{}'.format(head) -# # versions['spm'] = module_version -# return versions - - -def _close_handlers(logger: logging.Logger) -> None: +def _close_handlers(logger: logging.Logger) -> None: # pragma: no cover """Safely close relevant handlers for logger. Parameters @@ -243,55 +175,37 @@ def _close_handlers(logger: logging.Logger) -> None: logger.removeHandler(handler) -def _safe_log(versions: dict, name: str) -> None: - """Log with safety. - - Parameters - ---------- - versions : dict - The dictionary with keys as dependency names and values as the - versions. - name : str - The dependency to look up in `versions`. - - """ - if name in versions: - logger.info(f"{name}: {versions[name]}") - - -def log_versions(tbox_path: Optional[Path] = None) -> None: - """Log versions of dependencies and junifer. - - If `tbox_path` is specified, can also log versions of external toolboxes. - - Parameters - ---------- - tbox_path : pathlib.Path, optional - The path to external toolboxes (default None). - - """ +def log_versions() -> None: + """Log versions of dependencies and junifer.""" # Get versions of all found packages versions = get_versions() - + # Set packages to log + pkgs_to_log = [ + "click", + "numpy", + "scipy", + "datalad", + "pandas", + "nibabel", + "nilearn", + "sqlalchemy", + "ruamel.yaml", + "h5py", + "tqdm", + "templateflow", + "lapy", + "junifer_data", + "junifer", + ] + # Log logger.info("===== Lib Versions =====") - _safe_log(versions, "numpy") - _safe_log(versions, "scipy") - _safe_log(versions, "pandas") - _safe_log(versions, "nipype") - _safe_log(versions, "nitime") - _safe_log(versions, "nilearn") - _safe_log(versions, "nibabel") - _safe_log(versions, "junifer") + for pkg in pkgs_to_log: + if pkg in versions: + logger.info(f"{pkg}: {versions[pkg]}") logger.info("========================") - if tbox_path is not None: - # ext_versions = get_ext_versions(tbox_path) - # logger.info('spm: {}'.format(ext_versions['spm'])) - # logger.info('========================') - pass - -def _can_use_color(handler: logging.Handler) -> bool: +def _can_use_color(handler: logging.Handler) -> bool: # pragma: no cover """Check if color can be used in the logging output. Parameters @@ -391,11 +305,7 @@ def configure_logging( # Set logging format if output_format is None: output_format = "%(asctime)s - %(name)s - %(levelname)s - %(message)s" - # ( - # "%(asctime)s [%(levelname)s] %(message)s " - # "(%(filename)s:%(lineno)s)" - # ) - if _can_use_color(lh): + if _can_use_color(lh): # pragma: no cover formatter = ColorFormatter(fmt=output_format) else: formatter = logging.Formatter(fmt=output_format) diff --git a/junifer/utils/tests/test_logging.py b/junifer/utils/tests/test_logging.py index 92a1102ef..9913be467 100644 --- a/junifer/utils/tests/test_logging.py +++ b/junifer/utils/tests/test_logging.py @@ -68,7 +68,9 @@ def test_log_file(tmp_path: Path) -> None: assert any("Warn message" in line for line in lines) assert any("Error message" in line for line in lines) - configure_logging(fname=tmp_path / "test2.log", level="INFO") + configure_logging( + fname=str((tmp_path / "test2.log").resolve()), level="INFO" + ) logger.debug("Debug message") logger.info("Info message") logger.warning("Warn message") @@ -81,7 +83,9 @@ def test_log_file(tmp_path: Path) -> None: assert any("Warn message" in line for line in lines) assert any("Error message" in line for line in lines) - configure_logging(fname=tmp_path / "test3.log", level="WARNING") + configure_logging( + fname=tmp_path / "test3.log", level="WARNING", level_datalad="WARNING" + ) logger.debug("Debug message") logger.info("Info message") logger.warning("Warn message") @@ -94,7 +98,7 @@ def test_log_file(tmp_path: Path) -> None: assert any("Warn message" in line for line in lines) assert any("Error message" in line for line in lines) - configure_logging(fname=tmp_path / "test4.log", level="ERROR") + configure_logging(fname=tmp_path / "test4.log", level=logging.ERROR) logger.debug("Debug message") logger.info("Info message") logger.warning("Warn message") @@ -107,7 +111,11 @@ def test_log_file(tmp_path: Path) -> None: assert any("Error message" in line for line in lines) with pytest.warns(UserWarning, match="to avoid this message"): - configure_logging(fname=tmp_path / "test4.log", level="WARNING") + configure_logging( + fname=tmp_path / "test4.log", + level="WARNING", + level_datalad=logging.WARNING, + ) logger.debug("Debug2 message") logger.info("Info2 message") logger.warning("Warn2 message") diff --git a/pyproject.toml b/pyproject.toml index feb8713d3..2c5d8056a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -75,7 +75,12 @@ onthefly = [ "bctpy==0.6.0" ] neurokit2 = ["neurokit2>=0.1.7"] -dev = ["tox", "pre-commit"] +dev = [ + "tox", + "pre-commit", + "ruff", + "towncrier", +] docs = [ "seaborn>=0.13.0,<0.14.0", "sphinx>=7.3.0,<8.1.0", @@ -107,16 +112,6 @@ version_scheme = "guess-next-dev" local_scheme = "no-local-version" write_to = "junifer/_version.py" -[tool.black] -line-length = 79 -target-version = ["py39", "py310", "py311", "py312", "py313"] -extend-exclude = """ -( - junifer/external/h5io - | junifer/external/BrainPrint -) -""" - [tool.codespell] skip = "*/auto_examples/*,*.html,.git/,*.pyc,*/_build/*,*/h5io/*,*/BrainPrint/*" count = "" @@ -136,6 +131,7 @@ extend-exclude = [ "examples", "tools", ] +target-version = "py39" [tool.ruff.lint] select = [ @@ -275,3 +271,31 @@ showcontent = true [tool.towncrier.fragment.change] name = "API Changes" showcontent = true + +[tool.coverage.paths] +source = [ + "junifer", + "*/site-packages/junifer", +] + +[tool.coverage.run] +branch = true +omit = [ + "*/setup.py", + "*/_version.py", + "*/tests/*", + "*/junifer/configs/*", + "*/junifer/external/h5io/*", + "*/junifer/external/BrainPrint/*", +] + +[tool.coverage.report] +exclude_lines = [ + # Have to re-enable the standard pragma + "pragma: no cover", + # Type checking if statements should not be considered + "if TYPE_CHECKING:", + # Don't complain if non-runnable code isn't run: + "if __name__ == .__main__.:", +] +precision = 2 diff --git a/tox.ini b/tox.ini index 0548c0674..a61fc48e3 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,13 @@ [tox] -envlist = ruff, black, test, coverage, codespell, py3{9,10,11,12,13} +requires = + tox>=4 +env_list = + ruff, + changelog, + test, + coverage, + codespell, + py3{9,10,11,12,13} isolated_build = true [gh-actions] @@ -22,20 +30,27 @@ commands = pytest [testenv:ruff] +description = run ruff skip_install = true deps = ruff>=0.1.0 commands = + ruff format {toxinidir} ruff check {toxinidir} -[testenv:black] +[testenv:changelog] +description = show changelog skip_install = true +# See https://github.com/sphinx-contrib/sphinxcontrib-towncrier/issues/92 +# Pin also present in pyproject.toml deps = - black + towncrier<24.7 + lazy_loader==0.4 commands = - black --check --diff {toxinidir}/junifer {toxinidir}/setup.py + towncrier build --draft [testenv:test] +description = run tests skip_install = false passenv = HOME @@ -45,6 +60,7 @@ commands = pytest [testenv:coverage] +description = run tests with coverage skip_install = false deps = bctpy==0.6.0 @@ -52,42 +68,13 @@ deps = pytest pytest-cov commands = - pytest --cov={envsitepackagesdir}/junifer --cov-report=xml --cov-report=term {envsitepackagesdir}/junifer + pytest --cov={envsitepackagesdir}/junifer --cov-report=xml --cov-report=term --cov-config=pyproject.toml {envsitepackagesdir}/junifer [testenv:codespell] +description = run codespell skip_install = true deps = codespell tomli commands = codespell --toml {toxinidir}/pyproject.toml {toxinidir}/docs/ {toxinidir}/examples/ {toxinidir}/junifer/ {toxinidir}/tools/ {toxinidir}/README.md - -################ -# Tool configs # -################ - -[coverage:paths] -source = - junifer - */site-packages/junifer - -[coverage:run] -branch = true -omit = - */setup.py - */_version.py - */tests/* - */junifer/configs/* - */junifer/external/h5io/* - */junifer/external/BrainPrint/* -parallel = false - -[coverage:report] -exclude_lines = - # Have to re-enable the standard pragma - pragma: no cover - # Type checking if statements should not be considered - if TYPE_CHECKING: - # Don't complain if non-runnable code isn't run: - if __name__ == .__main__.: -precision = 2