[MAINT]: Repository maintenance #441

Merged
synchon merged 24 commits from chore/ruff-format into main 2025-04-10 11:08:49 +00:00
87 changed files with 583 additions and 1403 deletions

View file

@ -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]

View file

@ -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)

View file

@ -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

View file

@ -0,0 +1 @@
Regular repository maintenance by updating ``.pre-commit-config.yaml``, replacing ``black`` with ``ruff-format`` and updating tool configs by `Synchon Mandal`_

View file

@ -5,7 +5,6 @@
# Synchon Mandal <s.mandal@fz-juelich.de>
# License: AGPL
from ..pipeline import PipelineComponentRegistry
from ..typing import DataGrabberLike, MarkerLike, PreprocessorLike, StorageLike

View file

@ -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

View file

@ -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()))

View file

@ -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()))

View file

@ -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)

View file

@ -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}")

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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
1 22 -65 48 1
2 25 -58 60 2
3 -35 20 0 3
4 12 36 20 4
5 40 18 40 5
6 54 -28 34 6
7 36 22 3 7
8 59 -17 29 8
9 -45 0 9 9
10 46 -59 4 10
11 -32 -1 54 11
12 32 14 56 12
13 -42 -60 -9 13
14 -34 3 4 14
15 37 1 -4 15
16 29 -5 54 16
17 11 -39 50 17
18 37 -65 40 18
19 -34 -38 -16 19
20 -52 -63 5 20
21 -10 11 67 21
22 -44 2 46 22
23 -3 26 44 23
24 49 8 -1 24
25 -33 -46 47 25
26 -27 -71 37 26
27 55 -45 37 27
28 7 8 51 28
29 36 10 1 29
30 -39 51 17 30
31 10 -62 61 31
32 -16 -5 71 32
33 43 49 -2 33
34 37 32 -2 34
35 10 -2 45 35
36 47 -30 49 36
37 36 -9 14 37
38 -3 2 53 38
39 -51 8 -2 39
40 -1 15 44 40
41 31 -14 2 41
42 19 -8 64 42
43 -10 -2 42 43
44 65 -33 20 44
45 -30 -27 12 45
46 6 -72 24 46
47 -7 -52 61 47
48 -49 -42 1 48
49 -49 25 -1 49
50 -5 18 34 50
51 -23 11 64 51
52 31 33 26 52
53 -0 30 27 53
54 -53 -22 23 54
55 -42 -55 45 55
56 -50 -34 26 56
57 48 22 10 57
58 31 56 14 58
59 44 -8 57 59
60 49 35 -12 60
61 -56 -50 10 61
62 2 -24 30 62
63 29 -39 59 63
64 -42 -74 0 64
65 -34 55 4 65
66 13 -1 70 66
67 42 -0 47 67
68 -3 42 16 68
69 5 23 37 69
70 51 -29 -4 70
71 0 -15 47 71
72 52 -33 8 72
73 34 16 -8 73
74 -7 -71 42 74
75 -29 -43 61 75
76 33 -53 44 76
77 -55 -40 14 77
78 -17 -59 64 78
79 56 -5 13 79
80 46 -47 -17 80
81 -11 26 25 81
82 22 -42 69 82
83 -13 -40 1 83
84 43 -23 20 84
85 -53 -49 43 85
86 -47 11 23 86
87 54 -43 22 87
88 53 33 1 88
89 10 22 27 89
90 -55 -9 12 90
91 -58 -30 -4 91
92 -42 45 -2 92
93 56 -46 11 93
94 -45 -32 47 94
95 11 -66 42 95
96 -28 -79 19 96
97 -47 -76 -10 97
98 -2 38 36 98
99 -54 -23 43 99
100 -28 52 21 100
101 47 -50 29 101
102 -2 -35 31 102
103 50 -20 42 103
104 -42 38 21 104
105 26 50 27 105
106 58 -53 -14 106
107 47 10 33 107
108 32 -26 13 108
109 -46 31 -13 109
110 10 -46 73 110
111 27 -37 -13 111
112 43 -72 28 112
113 52 -2 -16 113
114 -2 -37 44 114
115 38 43 15 115
116 -60 -25 14 116
117 -41 6 33 117
118 -2 -13 12 118
119 42 -66 -8 119
120 9 -4 6 120
121 29 1 4 121
122 15 5 7 122
123 -42 25 30 123
124 -26 -40 -8 124
125 65 -31 -9 125
126 44 -53 47 126
127 -18 -76 -24 127
128 -35 20 51 128
129 -28 -58 48 129
130 -49 -26 5 130
131 -53 -10 24 131
132 -47 -51 -21 132
133 58 -16 7 133
134 49 -42 45 134
135 40 -72 14 135
136 -32 -55 -25 136
137 -14 -18 40 137
138 -41 -75 26 138
139 -16 -77 34 139
140 4 -48 51 140
141 -68 -41 -5 141
142 35 -67 -34 142
143 22 39 39 143
144 -56 -13 -10 144
145 15 -63 26 145
146 -15 4 8 146
147 29 -77 25 147
148 38 -17 45 148
149 23 10 1 149
150 66 -8 25 150
151 51 -6 32 151
152 -39 -75 44 152
153 -11 45 8 153
154 52 7 -30 154
155 -21 41 -20 155
156 -12 -95 -13 156
157 8 42 -5 157
158 34 38 -12 158
159 -16 -46 73 159
160 37 -84 13 160
161 18 -47 -10 161
162 -11 -56 16 162
163 48 25 27 163
164 -53 3 -27 164
165 46 16 -30 165
166 -31 19 -19 166
167 37 -81 1 167
168 52 -59 36 168
169 27 16 -17 169
170 24 45 -15 170
171 -44 12 -34 171
172 -46 -61 21 172
173 -49 -11 35 173
174 -25 -98 -12 174
175 -33 -79 -13 175
176 11 -54 17 176
177 23 33 48 177
178 -3 -49 13 178
179 12 -17 8 179
180 -38 -33 17 180
181 8 48 -15 181
182 -10 39 52 182
183 43 -78 -12 183
184 20 -29 60 184
185 -40 -19 54 185
186 -20 45 39 186
187 13 30 59 187
188 -24 -91 19 188
189 -16 29 53 189
190 8 -91 -7 190
191 -21 -31 61 191
192 6 67 -4 192
193 17 -80 -34 193
194 -23 -30 72 194
195 2 -28 60 195
196 15 -77 31 196
197 3 -17 58 197
198 55 -31 -17 198
199 -31 -10 -36 199
200 -40 -88 -6 200
201 -18 63 -9 201
202 27 -59 -9 202
203 49 -3 -38 203
204 -31 -11 -0 204
205 65 -24 -19 205
206 17 -28 -17 206
207 -7 51 -1 207
208 24 32 -18 208
209 9 54 3 209
210 -7 -55 27 210
211 -21 -22 -20 211
212 34 54 -13 212
213 -38 -15 69 213
214 -38 -27 69 214
215 65 -12 -19 215
216 -16 -52 -1 216
217 -8 48 23 217
218 -3 44 -9 218
219 -37 -29 -26 219
220 27 -97 -13 220
221 17 -91 -14 221
222 6 54 16 222
223 8 41 -24 223
224 8 -48 31 224
225 24 -87 24 225
226 -58 -26 -15 226
227 29 -17 71 227
228 -68 -23 -16 228
229 -10 -18 7 229
230 -13 -17 75 230
231 -7 -33 72 231
232 15 -87 37 232
233 -20 64 19 233
234 42 -20 55 234
235 26 -79 -16 235
236 -10 55 39 236
237 13 -33 75 237
238 33 -12 -34 238
239 -26 -90 3 239
240 -7 -21 65 240
241 10 -17 74 241
242 -44 -65 35 242
243 6 -59 35 243
244 6 64 22 244
245 -18 -68 5 245
246 -16 -65 -20 246
247 8 -72 11 247
248 13 55 38 248
249 -14 -91 31 249
250 -3 -81 21 250
251 20 -86 -2 251
252 -50 -7 -39 252
253 -56 -45 -24 253
254 -8 -81 7 254
255 20 -66 2 255
256 6 -81 6 256
257 52 -34 -27 257
258 -15 -72 -8 258
259 6 -24 -0 259
260 28 -77 -32 260
261 22 -58 -23 261
262 1 -62 -18 262
263 -22 7 -5 263
264 -5 -28 -4 264

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -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(

View file

@ -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

View file

@ -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")

View file

@ -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

View file

@ -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

View file

@ -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")

View file

@ -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")

View file

@ -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

View file

@ -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.
"""

View file

@ -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",
],

View file

@ -3,7 +3,6 @@
# Authors: Federico Raimondo <f.raimondo@fz-juelich.de>
# License: AGPL
import numpy as np
import pytest

View file

@ -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

View file

@ -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__(

View file

@ -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`

View file

@ -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`

View file

@ -5,7 +5,6 @@
# Synchon Mandal <s.mandal@fz-juelich.de>
# License: AGPL
from ..api.decorators import register_datagrabber
from ..utils import logger
from .datalad_base import DataladDataGrabber

View file

@ -3,7 +3,6 @@
# Authors: Synchon Mandal <s.mandal@fz-juelich.de>
# License: AGPL
from ..typing import DataGrabberPatterns
from ..utils import logger, raise_error, warn_with_log

View file

@ -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")

View file

@ -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}")

View file

@ -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

View file

@ -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))

View file

@ -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))

View file

@ -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))

View file

@ -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"],
},
}

View file

@ -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"],
},
}

View file

@ -3,7 +3,6 @@
# Authors: Synchon Mandal <s.mandal@fz-juelich.de>
# License: AGPL
from abc import abstractmethod
from typing import Any, ClassVar, Optional, Union

View file

@ -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

View file

@ -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

View file

@ -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")

View file

@ -3,7 +3,6 @@
# Authors: Synchon Mandal <s.mandal@fz-juelich.de>
# License: AGPL
from pathlib import Path
from typing import (
TYPE_CHECKING,

View file

@ -3,7 +3,6 @@
# Authors: Synchon Mandal <s.mandal@fz-juelich.de>
# License: AGPL
from typing import Any, Optional, Union
import numpy as np

View file

@ -3,7 +3,6 @@
# Authors: Synchon Mandal <s.mandal@fz-juelich.de>
# License: AGPL
from typing import Any, Optional, Union
import numpy as np

View file

@ -3,7 +3,6 @@
# Authors: Leonard Sasse <l.sasse@fz-juelich.de>
# License: AGPL
from abc import abstractmethod
from typing import Any, ClassVar, Optional, Union

View file

@ -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",

View file

@ -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

View file

@ -3,7 +3,6 @@
# Authors: Synchon Mandal <s.mandal@fz-juelich.de>
# 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

View file

@ -3,7 +3,6 @@
# Authors: Synchon Mandal <s.mandal@fz-juelich.de>
# License: AGPL
import logging
from pathlib import Path

View file

@ -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

View file

@ -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

View file

@ -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)}"
)

View file

@ -5,7 +5,6 @@
# Synchon Mandal <s.mandal@fz-juelich.de>
# License: AGPL
import numpy as np
import pandas as pd
import pytest

View file

@ -3,7 +3,6 @@
# Authors: Synchon Mandal <s.mandal@fz-juelich.de>
# License: AGPL
import pytest
from junifer.datareader import DefaultDataReader

View file

@ -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 = [

View file

@ -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

View file

@ -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(

View file

@ -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)

View file

@ -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)

View file

@ -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

View file

@ -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
)

View file

@ -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)

View file

@ -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")

View file

@ -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

57
tox.ini
View file

@ -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