[MAINT]: Drop Python 3.9 and add Python 3.14 support #474

Merged
synchon merged 11 commits from chore/maintenance into main 2026-03-12 12:19:51 +00:00
122 changed files with 3960 additions and 722 deletions

1
.python-version Normal file
View file

@ -0,0 +1 @@
3.12
fraimondo commented 2025-11-07 11:59:57 +00:00 (Migrated from github.com)

why do we need this?

why do we need this?
synchon commented 2025-11-07 13:30:29 +00:00 (Migrated from github.com)

It's for uv to use that version when one does uv sync or any uv stuff. 3.13 or 3.14 does not work due to a versioning issue in scikit-learn.

It's for ``uv`` to use that version when one does ``uv sync`` or any ``uv`` stuff. 3.13 or 3.14 does not work due to a versioning issue in ``scikit-learn``.
fraimondo commented 2025-11-07 17:05:18 +00:00 (Migrated from github.com)

the uv.lock file is needed too?

the `uv.lock` file is needed too?
synchon commented 2025-11-07 17:08:59 +00:00 (Migrated from github.com)

Yes, for reproducible installs using uv.

Yes, for reproducible installs using uv.

View file

@ -0,0 +1 @@
Drop Python 3.9 and add Python 3.14 support, upgrade codebase to follow modern syntax, bump dependencies and add ``uv`` support.

View file

@ -8,7 +8,6 @@
import os import os
import shutil import shutil
from pathlib import Path from pathlib import Path
from typing import Optional, Union
from ..api.queue_context import GnuParallelLocalAdapter, HTCondorAdapter from ..api.queue_context import GnuParallelLocalAdapter, HTCondorAdapter
from ..datagrabber import BaseDataGrabber from ..datagrabber import BaseDataGrabber
@ -122,12 +121,12 @@ def _get_storage(storage_config: dict) -> StorageLike:
def run( def run(
workdir: Union[str, Path, dict], workdir: str | Path | dict,
datagrabber: dict, datagrabber: dict,
markers: list[dict], markers: list[dict],
storage: dict, storage: dict,
preprocessors: Optional[list[dict]] = None, preprocessors: list[dict] | None = None,
elements: Optional[Elements] = None, elements: Elements | None = None,
) -> None: ) -> None:
"""Run the pipeline on the selected element. """Run the pipeline on the selected element.
@ -166,7 +165,7 @@ def run(
""" """
# Conditional to handle workdir config # Conditional to handle workdir config
if isinstance(workdir, (str, Path)): if isinstance(workdir, str | Path):
if isinstance(workdir, str): if isinstance(workdir, str):
workdir = {"workdir": Path(workdir), "cleanup": True} workdir = {"workdir": Path(workdir), "cleanup": True}
else: else:
@ -263,8 +262,8 @@ def queue(
kind: str, kind: str,
jobname: str = "junifer_job", jobname: str = "junifer_job",
overwrite: bool = False, overwrite: bool = False,
elements: Optional[Elements] = None, elements: Elements | None = None,
**kwargs: Union[str, int, bool, dict, tuple, list], **kwargs: str | int | bool | dict | tuple | list,
) -> None: ) -> None:
"""Queue a job to be executed later. """Queue a job to be executed later.
@ -425,7 +424,7 @@ def reset(config: dict) -> None:
def list_elements( def list_elements(
datagrabber: dict, datagrabber: dict,
elements: Optional[Elements] = None, elements: Elements | None = None,
) -> str: ) -> str:
"""List elements of the datagrabber filtered using `elements`. """List elements of the datagrabber filtered using `elements`.

View file

@ -6,7 +6,6 @@
import shutil import shutil
import textwrap import textwrap
from pathlib import Path from pathlib import Path
from typing import Optional
from ...typing import Elements from ...typing import Elements
from ...utils import logger, make_executable, raise_error, run_ext_cmd from ...utils import logger, make_executable, raise_error, run_ext_cmd
@ -65,11 +64,11 @@ class GnuParallelLocalAdapter(QueueContextAdapter):
job_dir: Path, job_dir: Path,
yaml_config_path: Path, yaml_config_path: Path,
elements: Elements, elements: Elements,
pre_run: Optional[str] = None, pre_run: str | None = None,
pre_collect: Optional[str] = None, pre_collect: str | None = None,
env: Optional[dict[str, str]] = None, env: dict[str, str] | None = None,
verbose: str = "info", verbose: str = "info",
verbose_datalad: Optional[str] = None, verbose_datalad: str | None = None,
submit: bool = False, submit: bool = False,
) -> None: ) -> None:
"""Initialize the class.""" """Initialize the class."""
@ -92,7 +91,7 @@ class GnuParallelLocalAdapter(QueueContextAdapter):
self._run_joblog_path = self._job_dir / f"run_{self._job_name}_joblog" self._run_joblog_path = self._job_dir / f"run_{self._job_name}_joblog"
self._elements_file_path = self._job_dir / "elements" self._elements_file_path = self._job_dir / "elements"
def _check_env(self, env: Optional[dict[str, str]]) -> None: def _check_env(self, env: dict[str, str] | None) -> None:
"""Check value of env parameter on init. """Check value of env parameter on init.
Parameters Parameters

View file

@ -6,7 +6,6 @@
import shutil import shutil
import textwrap import textwrap
from pathlib import Path from pathlib import Path
from typing import Optional
from ...typing import Elements from ...typing import Elements
from ...utils import logger, make_executable, raise_error, run_ext_cmd from ...utils import logger, make_executable, raise_error, run_ext_cmd
@ -83,15 +82,15 @@ class HTCondorAdapter(QueueContextAdapter):
job_dir: Path, job_dir: Path,
yaml_config_path: Path, yaml_config_path: Path,
elements: Elements, elements: Elements,
pre_run: Optional[str] = None, pre_run: str | None = None,
pre_collect: Optional[str] = None, pre_collect: str | None = None,
env: Optional[dict[str, str]] = None, env: dict[str, str] | None = None,
verbose: str = "info", verbose: str = "info",
verbose_datalad: Optional[str] = None, verbose_datalad: str | None = None,
cpus: int = 1, cpus: int = 1,
mem: str = "8G", mem: str = "8G",
disk: str = "1G", disk: str = "1G",
extra_preamble: Optional[str] = None, extra_preamble: str | None = None,
collect: str = "yes", collect: str = "yes",
submit: bool = False, submit: bool = False,
) -> None: ) -> None:
@ -121,7 +120,7 @@ class HTCondorAdapter(QueueContextAdapter):
) )
self._dag_path = self._job_dir / f"{self._job_name}.dag" self._dag_path = self._job_dir / f"{self._job_name}.dag"
def _check_env(self, env: Optional[dict[str, str]]) -> None: def _check_env(self, env: dict[str, str] | None) -> None:
"""Check value of env parameter on init. """Check value of env parameter on init.
Parameters Parameters

View file

@ -5,7 +5,6 @@
import logging import logging
from pathlib import Path from pathlib import Path
from typing import Optional, Union
import pytest import pytest
@ -44,7 +43,7 @@ def test_GnuParallelLocalAdapter_env_shell_error() -> None:
], ],
) )
def test_GnuParallelLocalAdapter_elements( def test_GnuParallelLocalAdapter_elements(
elements: list[Union[str, tuple]], elements: list[str | tuple],
expected_text: str, expected_text: str,
) -> None: ) -> None:
"""Test GnuParallelLocalAdapter elements(). """Test GnuParallelLocalAdapter elements().
@ -76,7 +75,7 @@ def test_GnuParallelLocalAdapter_elements(
], ],
) )
def test_GnuParallelLocalAdapter_pre_run( def test_GnuParallelLocalAdapter_pre_run(
pre_run: Optional[str], pre_run: str | None,
expected_text: str, expected_text: str,
shell: str, shell: str,
) -> None: ) -> None:
@ -114,7 +113,7 @@ def test_GnuParallelLocalAdapter_pre_run(
], ],
) )
def test_GnuParallelLocalAdapter_pre_collect( def test_GnuParallelLocalAdapter_pre_collect(
pre_collect: Optional[str], pre_collect: str | None,
expected_text: str, expected_text: str,
shell: str, shell: str,
) -> None: ) -> None:

View file

@ -5,7 +5,6 @@
import logging import logging
from pathlib import Path from pathlib import Path
from typing import Optional, Union
import pytest import pytest
@ -58,7 +57,7 @@ def test_HTCondorAdapter_collect_error() -> None:
], ],
) )
def test_HTCondorAdapter_pre_run( def test_HTCondorAdapter_pre_run(
pre_run: Optional[str], pre_run: str | None,
expected_text: str, expected_text: str,
shell: str, shell: str,
) -> None: ) -> None:
@ -100,7 +99,7 @@ def test_HTCondorAdapter_pre_run(
], ],
) )
def test_HTCondorAdapter_pre_collect( def test_HTCondorAdapter_pre_collect(
pre_collect: Optional[str], pre_collect: str | None,
expected_text: str, expected_text: str,
collect: str, collect: str,
shell: str, shell: str,
@ -140,7 +139,7 @@ def test_HTCondorAdapter_pre_collect(
], ],
) )
def test_HTCondorAdapter_run_collect( def test_HTCondorAdapter_run_collect(
extra_preamble: Optional[str], expected_text: str extra_preamble: str | None, expected_text: str
) -> None: ) -> None:
"""Test HTCondorAdapter run() and collect(). """Test HTCondorAdapter run() and collect().
@ -181,7 +180,7 @@ def test_HTCondorAdapter_run_collect(
], ],
) )
def test_HTCondor_dag( def test_HTCondor_dag(
elements: list[Union[str, tuple]], collect: str, expected_text: str elements: list[str | tuple], collect: str, expected_text: str
) -> None: ) -> None:
"""Test HTCondorAdapter dag(). """Test HTCondorAdapter dag().

View file

@ -8,7 +8,7 @@
import logging import logging
from contextlib import AbstractContextManager, nullcontext from contextlib import AbstractContextManager, nullcontext
from pathlib import Path from pathlib import Path
from typing import Any, Optional, Union from typing import Any
import pytest import pytest
from nibabel.filebasedimages import ImageFileError from nibabel.filebasedimages import ImageFileError
@ -516,7 +516,7 @@ def test_queue_with_imports(
tmp_path: Path, tmp_path: Path,
monkeypatch: pytest.MonkeyPatch, monkeypatch: pytest.MonkeyPatch,
caplog: pytest.LogCaptureFixture, caplog: pytest.LogCaptureFixture,
with_: Union[str, list[str]], with_: str | list[str],
) -> None: ) -> None:
"""Test queue with `with` imports. """Test queue with `with` imports.
@ -742,7 +742,7 @@ def test_reset_queue(
) )
def test_list_elements( def test_list_elements(
datagrabber: dict[str, str], datagrabber: dict[str, str],
elements: Optional[list[tuple[str, ...]]], elements: list[tuple[str, ...]] | None,
) -> None: ) -> None:
"""Test elements listing. """Test elements listing.

View file

@ -8,7 +8,6 @@ import pathlib
import subprocess import subprocess
import sys import sys
from pathlib import Path from pathlib import Path
from typing import Optional, Union
import click import click
@ -46,7 +45,7 @@ __all__ = [
def _validate_optional_verbose( def _validate_optional_verbose(
ctx: click.Context, param: str, value: Optional[str] ctx: click.Context, param: str, value: str | None
): ):
"""Validate optional verbose option. """Validate optional verbose option.
@ -71,9 +70,7 @@ def _validate_optional_verbose(
return _validate_verbose(ctx, param, value) return _validate_verbose(ctx, param, value)
def _validate_verbose( def _validate_verbose(ctx: click.Context, param: str, value: str) -> str | int:
ctx: click.Context, param: str, value: str
) -> Union[str, int]:
"""Validate verbose option. """Validate verbose option.
Parameters Parameters
@ -142,8 +139,8 @@ def cli() -> None: # pragma: no cover
def run( def run(
filepath: click.Path, filepath: click.Path,
element: tuple[str], element: tuple[str],
verbose: Union[str, int], verbose: str | int,
verbose_datalad: Optional[Union[str, int]], verbose_datalad: str | int | None,
) -> None: ) -> None:
"""Run feature extraction. """Run feature extraction.
@ -214,8 +211,8 @@ def run(
) )
def collect( def collect(
filepath: click.Path, filepath: click.Path,
verbose: Union[str, int], verbose: str | int,
verbose_datalad: Union[str, int, None], verbose_datalad: str | int | None,
) -> None: ) -> None:
"""Collect extracted features. """Collect extracted features.
@ -270,8 +267,8 @@ def queue(
element: tuple[str], element: tuple[str],
overwrite: bool, overwrite: bool,
submit: bool, submit: bool,
verbose: Union[str, int], verbose: str | int,
verbose_datalad: Union[str, int, None], verbose_datalad: str | int | None,
) -> None: ) -> None:
"""Queue feature extraction. """Queue feature extraction.
@ -433,8 +430,8 @@ def selftest(subpkg: str) -> None:
) )
def reset( def reset(
filepath: click.Path, filepath: click.Path,
verbose: Union[str, int], verbose: str | int,
verbose_datalad: Union[str, int, None], verbose_datalad: str | int | None,
) -> None: ) -> None:
"""Reset generated assets. """Reset generated assets.
@ -487,9 +484,9 @@ def reset(
def list_elements( def list_elements(
filepath: click.Path, filepath: click.Path,
element: tuple[str], element: tuple[str],
output_file: Optional[click.Path], output_file: click.Path | None,
verbose: Union[str, int], verbose: str | int,
verbose_datalad: Union[str, int, None], verbose_datalad: str | int | None,
) -> None: ) -> None:
"""List elements of a dataset. """List elements of a dataset.

View file

@ -8,7 +8,6 @@ import importlib
import importlib.util import importlib.util
import sys import sys
from pathlib import Path from pathlib import Path
from typing import Union
import pandas as pd import pandas as pd
@ -19,7 +18,7 @@ from ..utils import logger, raise_error, warn_with_log, yaml
__all__ = ["parse_elements", "parse_yaml"] __all__ = ["parse_elements", "parse_yaml"]
def parse_yaml(filepath: Union[str, Path]) -> dict: # noqa: C901 def parse_yaml(filepath: str | Path) -> dict: # noqa: C901
"""Parse YAML. """Parse YAML.
Parameters Parameters
@ -141,9 +140,7 @@ def parse_yaml(filepath: Union[str, Path]) -> dict: # noqa: C901
return contents return contents
def parse_elements( def parse_elements(element: tuple[str, ...], config: dict) -> Elements | None:
element: tuple[str, ...], config: dict
) -> Union[Elements, None]:
"""Parse elements from cli. """Parse elements from cli.
Parameters Parameters

View file

@ -4,8 +4,8 @@
# Synchon Mandal <s.mandal@fz-juelich.de> # Synchon Mandal <s.mandal@fz-juelich.de>
# License: AGPL # License: AGPL
from collections.abc import Callable
from pathlib import Path from pathlib import Path
from typing import Callable
import pytest import pytest
from click.testing import CliRunner from click.testing import CliRunner

View file

@ -5,7 +5,6 @@
# License: AGPL # License: AGPL
from pathlib import Path from pathlib import Path
from typing import Union
from ....api.decorators import register_datagrabber from ....api.decorators import register_datagrabber
from ....datagrabber import PatternDataladDataGrabber from ....datagrabber import PatternDataladDataGrabber
@ -29,7 +28,7 @@ class JuselessDataladAOMICID1000VBM(PatternDataladDataGrabber):
""" """
def __init__(self, datadir: Union[str, Path, None] = None) -> None: def __init__(self, datadir: str | Path | None = None) -> None:
uri = "https://gin.g-node.org/felixh/ds003097_ReproVBM" uri = "https://gin.g-node.org/felixh/ds003097_ReproVBM"
types = ["VBM_GM"] types = ["VBM_GM"]
replacements = ["subject"] replacements = ["subject"]

View file

@ -6,7 +6,6 @@
# License: AGPL # License: AGPL
from pathlib import Path from pathlib import Path
from typing import Union
from ....api.decorators import register_datagrabber from ....api.decorators import register_datagrabber
from ....datagrabber import PatternDataladDataGrabber from ....datagrabber import PatternDataladDataGrabber
@ -30,7 +29,7 @@ class JuselessDataladCamCANVBM(PatternDataladDataGrabber):
""" """
def __init__(self, datadir: Union[str, Path, None] = None) -> None: def __init__(self, datadir: str | Path | None = None) -> None:
uri = ( uri = (
"ria+http://cat_12.5.ds.inm7.de" "ria+http://cat_12.5.ds.inm7.de"
"#a139b26a-8406-11ea-8f94-a0369f287950" "#a139b26a-8406-11ea-8f94-a0369f287950"

View file

@ -6,7 +6,6 @@
# License: AGPL # License: AGPL
from pathlib import Path from pathlib import Path
from typing import Union
from ....api.decorators import register_datagrabber from ....api.decorators import register_datagrabber
from ....datagrabber import PatternDataladDataGrabber from ....datagrabber import PatternDataladDataGrabber
@ -36,8 +35,8 @@ class JuselessDataladIXIVBM(PatternDataladDataGrabber):
def __init__( def __init__(
self, self,
datadir: Union[str, Path, None] = None, datadir: str | Path | None = None,
sites: Union[str, list[str], None] = None, sites: str | list[str] | None = None,
) -> None: ) -> None:
uri = ( uri = (
"ria+http://cat_12.5.ds.inm7.de" "ria+http://cat_12.5.ds.inm7.de"

View file

@ -6,7 +6,6 @@
# License: AGPL # License: AGPL
import socket import socket
from typing import Optional, Union
import pytest import pytest
@ -53,7 +52,7 @@ def test_JuselessUCLA() -> None:
], ],
) )
def test_JuselessUCLA_partial_data_access( def test_JuselessUCLA_partial_data_access(
types: Union[str, list[str]], types: str | list[str],
) -> None: ) -> None:
"""Test JuselessUCLA DataGrabber partial data access. """Test JuselessUCLA DataGrabber partial data access.
@ -92,7 +91,7 @@ def test_JuselessUCLA_incorrect_data_type() -> None:
"tasks", "tasks",
[None, "rest", ["rest", "stopsignal"]], [None, "rest", ["rest", "stopsignal"]],
) )
def test_JuselessUCLA_task_params(tasks: Optional[str]) -> None: def test_JuselessUCLA_task_params(tasks: str | None) -> None:
"""Test JuselessUCLA with different task parameters. """Test JuselessUCLA with different task parameters.
Parameters Parameters

View file

@ -5,7 +5,6 @@
# License: AGPL # License: AGPL
from pathlib import Path from pathlib import Path
from typing import Union
from ....api.decorators import register_datagrabber from ....api.decorators import register_datagrabber
from ....datagrabber import PatternDataGrabber from ....datagrabber import PatternDataGrabber
@ -40,11 +39,9 @@ class JuselessUCLA(PatternDataGrabber):
def __init__( def __init__(
self, self,
datadir: Union[ datadir: str | Path = "/data/project/psychosis_thalamus/data/fmriprep",
str, Path types: str | list[str] | None = None,
] = "/data/project/psychosis_thalamus/data/fmriprep", tasks: str | list[str] | None = None,
types: Union[str, list[str], None] = None,
tasks: Union[str, list[str], None] = None,
) -> None: ) -> None:
# Declare all tasks # Declare all tasks
all_tasks = [ all_tasks = [

View file

@ -6,7 +6,6 @@
# License: AGPL # License: AGPL
from pathlib import Path from pathlib import Path
from typing import Union
from ....api.decorators import register_datagrabber from ....api.decorators import register_datagrabber
from ....datagrabber import PatternDataladDataGrabber from ....datagrabber import PatternDataladDataGrabber
@ -30,7 +29,7 @@ class JuselessDataladUKBVBM(PatternDataladDataGrabber):
""" """
def __init__(self, datadir: Union[str, Path, None] = None) -> None: def __init__(self, datadir: str | Path | None = None) -> None:
uri = "ria+http://ukb.ds.inm7.de#~cat_m0wp1" uri = "ria+http://ukb.ds.inm7.de#~cat_m0wp1"
rootdir = "m0wp1" rootdir = "m0wp1"
types = ["VBM_GM"] types = ["VBM_GM"]

View file

@ -3,12 +3,11 @@
# Authors: Synchon Mandal <s.mandal@fz-juelich.de> # Authors: Synchon Mandal <s.mandal@fz-juelich.de>
# License: AGPL # License: AGPL
from collections.abc import Iterator, MutableMapping from collections.abc import Callable, Iterator, MutableMapping
from pathlib import Path from pathlib import Path
from typing import ( from typing import (
TYPE_CHECKING, TYPE_CHECKING,
Any, Any,
Callable,
Optional, Optional,
Union, Union,
) )
@ -110,14 +109,9 @@ class DataDispatcher(MutableMapping):
def get_data( def get_data(
kind: str, kind: str,
names: Union[ names: str | list[str] | dict | list[dict],
str, # coordinates, parcellation, mask
list[str], # parcellation, mask
dict, # mask
list[dict], # mask
],
target_data: dict[str, Any], target_data: dict[str, Any],
extra_input: Optional[dict[str, Any]] = None, extra_input: dict[str, Any] | None = None,
) -> Union[ ) -> Union[
tuple[ArrayLike, list[str]], # coordinates tuple[ArrayLike, list[str]], # coordinates
tuple["Nifti1Image", dict[int, str]], # parcellation tuple["Nifti1Image", dict[int, str]], # parcellation
@ -196,15 +190,11 @@ def load_data(
kind: str, kind: str,
name: str, name: str,
**kwargs, **kwargs,
) -> Union[ ) -> (
tuple[ArrayLike, list[str], str], # coordinates tuple[ArrayLike, list[str], str]
tuple[ | tuple[Optional["Nifti1Image"], list[str], Path, str]
Optional["Nifti1Image"], list[str], Path, str | tuple[Union["Nifti1Image", Callable] | None, Path | None, str]
], # parcellation / maps ):
tuple[
Optional[Union["Nifti1Image", Callable]], Optional[Path], str
], # mask
]:
"""Load ``kind`` named ``name``. """Load ``kind`` named ``name``.
Parameters Parameters

View file

@ -5,7 +5,7 @@
# License: AGPL # License: AGPL
from pathlib import Path from pathlib import Path
from typing import Any, Optional from typing import Any
import numpy as np import numpy as np
import pandas as pd import pandas as pd
@ -135,7 +135,7 @@ class CoordinatesRegistry(BasePipelineDataRegistry):
coordinates: ArrayLike, coordinates: ArrayLike,
voi_names: list[str], voi_names: list[str],
space: str, space: str,
overwrite: Optional[bool] = False, overwrite: bool | None = False,
) -> None: ) -> None:
"""Register a custom user coordinates. """Register a custom user coordinates.
@ -302,7 +302,7 @@ class CoordinatesRegistry(BasePipelineDataRegistry):
self, self,
coords: str, coords: str,
target_data: dict[str, Any], target_data: dict[str, Any],
extra_input: Optional[dict[str, Any]] = None, extra_input: dict[str, Any] | None = None,
) -> tuple[ArrayLike, list[str]]: ) -> tuple[ArrayLike, list[str]]:
"""Get coordinates, tailored for the target data. """Get coordinates, tailored for the target data.

View file

@ -4,7 +4,7 @@
# License: AGPL # License: AGPL
import uuid import uuid
from typing import TYPE_CHECKING, Any, Optional from typing import TYPE_CHECKING, Any
import nibabel as nib import nibabel as nib
@ -34,7 +34,7 @@ class ANTsMapsWarper:
src: str, src: str,
dst: str, dst: str,
target_data: dict[str, Any], target_data: dict[str, Any],
warp_data: Optional[dict[str, Any]], warp_data: dict[str, Any] | None,
) -> "Nifti1Image": ) -> "Nifti1Image":
"""Warp ``maps_img`` to correct space. """Warp ``maps_img`` to correct space.

View file

@ -4,7 +4,7 @@
# License: AGPL # License: AGPL
from pathlib import Path from pathlib import Path
from typing import TYPE_CHECKING, Any, Optional, Union from typing import TYPE_CHECKING, Any, Optional
import nibabel as nib import nibabel as nib
import nilearn.image as nimg import nilearn.image as nimg
@ -74,7 +74,7 @@ class MapsRegistry(BasePipelineDataRegistry):
def register( def register(
self, self,
name: str, name: str,
maps_path: Union[str, Path], maps_path: str | Path,
maps_labels: list[str], maps_labels: list[str],
space: str, space: str,
overwrite: bool = False, overwrite: bool = False,
@ -156,7 +156,7 @@ class MapsRegistry(BasePipelineDataRegistry):
self, self,
name: str, name: str,
target_space: str, target_space: str,
resolution: Optional[float] = None, resolution: float | None = None,
path_only: bool = False, path_only: bool = False,
) -> tuple[Optional["Nifti1Image"], list[str], Path, str]: ) -> tuple[Optional["Nifti1Image"], list[str], Path, str]:
"""Load map(s) and labels. """Load map(s) and labels.
@ -251,7 +251,7 @@ class MapsRegistry(BasePipelineDataRegistry):
self, self,
maps: str, maps: str,
target_data: dict[str, Any], target_data: dict[str, Any],
extra_input: Optional[dict[str, Any]] = None, extra_input: dict[str, Any] | None = None,
) -> tuple["Nifti1Image", list[str]]: ) -> tuple["Nifti1Image", list[str]]:
"""Get map(s), tailored for the target image. """Get map(s), tailored for the target image.
@ -376,9 +376,9 @@ class MapsRegistry(BasePipelineDataRegistry):
def _retrieve_smith( def _retrieve_smith(
resolution: Optional[float] = None, resolution: float | None = None,
components: Optional[str] = None, components: str | None = None,
dimension: Optional[int] = None, dimension: int | None = None,
) -> tuple[Path, list[str]]: ) -> tuple[Path, list[str]]:
"""Retrieve Smith maps. """Retrieve Smith maps.

View file

@ -4,7 +4,7 @@
# License: AGPL # License: AGPL
import uuid import uuid
from typing import TYPE_CHECKING, Any, Optional from typing import TYPE_CHECKING, Any
import nibabel as nib import nibabel as nib
import numpy as np import numpy as np
@ -55,7 +55,7 @@ class ANTsMaskWarper:
src: str, src: str,
dst: str, dst: str,
target_data: dict[str, Any], target_data: dict[str, Any],
warp_data: Optional[dict[str, Any]], warp_data: dict[str, Any] | None,
) -> "Nifti1Image": # pragma: no cover ) -> "Nifti1Image": # pragma: no cover
"""Warp ``mask_img`` to correct space. """Warp ``mask_img`` to correct space.

View file

@ -4,12 +4,11 @@
# Synchon Mandal <s.mandal@fz-juelich.de> # Synchon Mandal <s.mandal@fz-juelich.de>
# License: AGPL # License: AGPL
from collections.abc import Callable
from pathlib import Path from pathlib import Path
from typing import ( from typing import (
TYPE_CHECKING, TYPE_CHECKING,
Any, Any,
Callable,
Optional,
Union, Union,
) )
@ -45,12 +44,12 @@ __all__ = ["MaskRegistry", "compute_brain_mask"]
def compute_brain_mask( def compute_brain_mask(
target_data: dict[str, Any], target_data: dict[str, Any],
warp_data: Optional[dict[str, Any]] = None, warp_data: dict[str, Any] | None = None,
mask_type: str = "brain", mask_type: str = "brain",
threshold: float = 0.5, threshold: float = 0.5,
source: str = "template", source: str = "template",
template_space: Optional[str] = None, template_space: str | None = None,
extra_input: Optional[dict[str, Any]] = None, extra_input: dict[str, Any] | None = None,
) -> "Nifti1Image": ) -> "Nifti1Image":
"""Compute the whole-brain, grey-matter or white-matter mask. """Compute the whole-brain, grey-matter or white-matter mask.
@ -281,7 +280,7 @@ class MaskRegistry(BasePipelineDataRegistry):
def register( def register(
self, self,
name: str, name: str,
mask_path: Union[str, Path], mask_path: str | Path,
space: str, space: str,
overwrite: bool = False, overwrite: bool = False,
) -> None: ) -> None:
@ -355,9 +354,9 @@ class MaskRegistry(BasePipelineDataRegistry):
def load( def load(
self, self,
name: str, name: str,
resolution: Optional[float] = None, resolution: float | None = None,
path_only: bool = False, path_only: bool = False,
) -> tuple[Optional[Union["Nifti1Image", Callable]], Optional[Path], str]: ) -> tuple[Union["Nifti1Image", Callable] | None, Path | None, str]:
"""Load mask. """Load mask.
Parameters Parameters
@ -428,9 +427,9 @@ class MaskRegistry(BasePipelineDataRegistry):
def get( # noqa: C901 def get( # noqa: C901
self, self,
masks: Union[str, dict, list[Union[dict, str]]], masks: str | dict | list[dict | str],
target_data: dict[str, Any], target_data: dict[str, Any],
extra_input: Optional[dict[str, Any]] = None, extra_input: dict[str, Any] | None = None,
) -> "Nifti1Image": ) -> "Nifti1Image":
"""Get mask, tailored for the target image. """Get mask, tailored for the target image.
@ -718,7 +717,7 @@ class MaskRegistry(BasePipelineDataRegistry):
def _load_vickery_patil_mask( def _load_vickery_patil_mask(
name: str, name: str,
resolution: Optional[float] = None, resolution: float | None = None,
) -> Path: ) -> Path:
"""Load Vickery-Patil mask. """Load Vickery-Patil mask.

View file

@ -6,8 +6,8 @@
# License: AGPL # License: AGPL
import socket import socket
from collections.abc import Callable
from pathlib import Path from pathlib import Path
from typing import Callable, Optional, Union
import nibabel as nib import nibabel as nib
import numpy as np import numpy as np
@ -264,7 +264,7 @@ def test_load_incorrect() -> None:
) )
def test_vickery_patil( def test_vickery_patil(
name: str, name: str,
resolution: Optional[float], resolution: float | None,
pixdim: list[float], pixdim: list[float],
fname: str, fname: str,
) -> None: ) -> None:
@ -417,7 +417,7 @@ def test_get_errors() -> None:
def test_nilearn_compute_masks( def test_nilearn_compute_masks(
mask_name: str, mask_name: str,
function: Callable, function: Callable,
params: Union[dict, None], params: dict | None,
resample: bool, resample: bool,
) -> None: ) -> None:
"""Test using nilearn compute mask functions. """Test using nilearn compute mask functions.
@ -502,7 +502,7 @@ def test_get_inherit() -> None:
], ],
) )
def test_get_multiple( def test_get_multiple(
masks: Union[str, dict, list[Union[dict, str]]], params: dict masks: str | dict | list[dict | str], params: dict
) -> None: ) -> None:
"""Test getting multiple masks. """Test getting multiple masks.

View file

@ -4,7 +4,7 @@
# License: AGPL # License: AGPL
import uuid import uuid
from typing import TYPE_CHECKING, Any, Optional from typing import TYPE_CHECKING, Any
import nibabel as nib import nibabel as nib
@ -34,7 +34,7 @@ class ANTsParcellationWarper:
src: str, src: str,
dst: str, dst: str,
target_data: dict[str, Any], target_data: dict[str, Any],
warp_data: Optional[dict[str, Any]], warp_data: dict[str, Any] | None,
) -> "Nifti1Image": ) -> "Nifti1Image":
"""Warp ``parcellation_img`` to correct space. """Warp ``parcellation_img`` to correct space.

View file

@ -7,7 +7,7 @@
from itertools import product from itertools import product
from pathlib import Path from pathlib import Path
from typing import TYPE_CHECKING, Any, Optional, Union from typing import TYPE_CHECKING, Any, Optional
import nibabel as nib import nibabel as nib
import nilearn.image as nimg import nilearn.image as nimg
@ -226,7 +226,7 @@ class ParcellationRegistry(BasePipelineDataRegistry):
def register( def register(
self, self,
name: str, name: str,
parcellation_path: Union[str, Path], parcellation_path: str | Path,
parcels_labels: list[str], parcels_labels: list[str],
space: str, space: str,
overwrite: bool = False, overwrite: bool = False,
@ -309,7 +309,7 @@ class ParcellationRegistry(BasePipelineDataRegistry):
self, self,
name: str, name: str,
target_space: str, target_space: str,
resolution: Optional[float] = None, resolution: float | None = None,
path_only: bool = False, path_only: bool = False,
) -> tuple[Optional["Nifti1Image"], list[str], Path, str]: ) -> tuple[Optional["Nifti1Image"], list[str], Path, str]:
"""Load parcellation and labels. """Load parcellation and labels.
@ -463,9 +463,9 @@ class ParcellationRegistry(BasePipelineDataRegistry):
def get( def get(
self, self,
parcellations: Union[str, list[str]], parcellations: str | list[str],
target_data: dict[str, Any], target_data: dict[str, Any],
extra_input: Optional[dict[str, Any]] = None, extra_input: dict[str, Any] | None = None,
) -> tuple["Nifti1Image", dict[int, str]]: ) -> tuple["Nifti1Image", dict[int, str]]:
"""Get parcellation, tailored for the target image. """Get parcellation, tailored for the target image.
@ -608,6 +608,7 @@ class ParcellationRegistry(BasePipelineDataRegistry):
) )
), ),
all_labels[0], all_labels[0],
strict=False,
) )
) )
# Parcellations are already transformed to target standard space # Parcellations are already transformed to target standard space
@ -623,8 +624,8 @@ class ParcellationRegistry(BasePipelineDataRegistry):
def _retrieve_schaefer( def _retrieve_schaefer(
resolution: Optional[float] = None, resolution: float | None = None,
n_rois: Optional[int] = None, n_rois: int | None = None,
yeo_networks: int = 7, yeo_networks: int = 7,
) -> tuple[Path, list[str]]: ) -> tuple[Path, list[str]]:
"""Retrieve Schaefer parcellation. """Retrieve Schaefer parcellation.
@ -707,8 +708,8 @@ def _retrieve_schaefer(
def _retrieve_tian( def _retrieve_tian(
resolution: Optional[float] = None, resolution: float | None = None,
scale: Optional[int] = None, scale: int | None = None,
space: str = "MNI152NLin6Asym", space: str = "MNI152NLin6Asym",
magneticfield: str = "3T", magneticfield: str = "3T",
) -> tuple[Path, list[str]]: ) -> tuple[Path, list[str]]:
@ -847,7 +848,7 @@ def _retrieve_tian(
def _retrieve_suit( def _retrieve_suit(
resolution: Optional[float], resolution: float | None,
space: str = "MNI152NLin6Asym", space: str = "MNI152NLin6Asym",
) -> tuple[Path, list[str]]: ) -> tuple[Path, list[str]]:
"""Retrieve SUIT parcellation. """Retrieve SUIT parcellation.
@ -919,7 +920,7 @@ def _retrieve_suit(
def _retrieve_aicha( def _retrieve_aicha(
resolution: Optional[float] = None, resolution: float | None = None,
version: int = 2, version: int = 2,
) -> tuple[Path, list[str]]: ) -> tuple[Path, list[str]]:
"""Retrieve AICHA parcellation. """Retrieve AICHA parcellation.
@ -1013,7 +1014,7 @@ def _retrieve_aicha(
def _retrieve_shen( def _retrieve_shen(
resolution: Optional[float] = None, resolution: float | None = None,
year: int = 2015, year: int = 2015,
n_rois: int = 268, n_rois: int = 268,
) -> tuple[Path, list[str]]: ) -> tuple[Path, list[str]]:
@ -1139,10 +1140,10 @@ def _retrieve_shen(
def _retrieve_yan( def _retrieve_yan(
resolution: Optional[float] = None, resolution: float | None = None,
n_rois: Optional[int] = None, n_rois: int | None = None,
yeo_networks: Optional[int] = None, yeo_networks: int | None = None,
kong_networks: Optional[int] = None, kong_networks: int | None = None,
) -> tuple[Path, list[str]]: ) -> tuple[Path, list[str]]:
"""Retrieve Yan parcellation. """Retrieve Yan parcellation.
@ -1264,8 +1265,8 @@ def _retrieve_yan(
def _retrieve_brainnetome( def _retrieve_brainnetome(
resolution: Optional[float] = None, resolution: float | None = None,
threshold: Optional[int] = None, threshold: int | None = None,
) -> tuple[Path, list[str]]: ) -> tuple[Path, list[str]]:
"""Retrieve Brainnetome parcellation. """Retrieve Brainnetome parcellation.
@ -1355,7 +1356,7 @@ def _retrieve_brainnetome(
def _retrieve_aseg( def _retrieve_aseg(
resolution: Optional[float] = None, resolution: float | None = None,
) -> tuple[Path, list[str]]: ) -> tuple[Path, list[str]]:
"""Retrieve aseg generated from FreeSurfer 7.4.1 . """Retrieve aseg generated from FreeSurfer 7.4.1 .
@ -1455,7 +1456,7 @@ def _retrieve_aseg(
def _retrieve_glasser( def _retrieve_glasser(
resolution: Optional[float] = None, resolution: float | None = None,
) -> tuple[Path, list[str]]: ) -> tuple[Path, list[str]]:
"""Retrieve Glasser v1.0 . """Retrieve Glasser v1.0 .
@ -1499,7 +1500,7 @@ def _retrieve_glasser(
def _retrieve_julich_brain( def _retrieve_julich_brain(
resolution: Optional[float] = None, resolution: float | None = None,
version: str = "v3_1", version: str = "v3_1",
) -> tuple[Path, list[str]]: ) -> tuple[Path, list[str]]:
"""Retrieve Julich-Brain labelled parcellations. """Retrieve Julich-Brain labelled parcellations.
@ -1613,11 +1614,12 @@ def merge_parcellations(
zip( zip(
np.trim_zeros(np.unique(ref_parc_data.astype(int))), np.trim_zeros(np.unique(ref_parc_data.astype(int))),
labels_lists[0], labels_lists[0],
strict=False,
), ),
) )
for idx, (parc, labs) in enumerate( for idx, (parc, labs) in enumerate(
zip(parcellations_list[1:], labels_lists[1:]) zip(parcellations_list[1:], labels_lists[1:], strict=False)
): ):
# Resample to reference (1st in the list) parcellation # Resample to reference (1st in the list) parcellation
if parc.shape != ref_parc.shape: if parc.shape != ref_parc.shape:
@ -1637,7 +1639,13 @@ def merge_parcellations(
# and update label mapping # and update label mapping
parc_data[parc_data != 0] += (idx + 1) * max_val parc_data[parc_data != 0] += (idx + 1) * max_val
val_label_map.update( val_label_map.update(
dict(zip(np.trim_zeros(np.unique(parc_data.astype(int))), labs)) dict(
zip(
np.trim_zeros(np.unique(parc_data.astype(int))),
labs,
strict=False,
)
)
) )
# Only set new values for the voxels that are 0 # Only set new values for the voxels that are 0
# This makes sure that the voxels that are in multiple # This makes sure that the voxels that are in multiple

View file

@ -4,7 +4,7 @@
# License: AGPL # License: AGPL
from pathlib import Path from pathlib import Path
from typing import Any, Optional, Union from typing import Any, Union
import nibabel as nib import nibabel as nib
import numpy as np import numpy as np
@ -47,9 +47,9 @@ def get_xfm(src: str, dst: str) -> Path: # pragma: no cover
def get_template( def get_template(
space: str, space: str,
target_img: nib.Nifti1Image, target_img: nib.Nifti1Image,
extra_input: Optional[dict[str, Any]] = None, extra_input: dict[str, Any] | None = None,
template_type: str = "T1w", template_type: str = "T1w",
resolution: Optional[Union[int, "str"]] = None, resolution: Union[int, "str"] | None = None,
) -> nib.Nifti1Image: ) -> nib.Nifti1Image:
"""Get template for the space, tailored for the target image. """Get template for the space, tailored for the target image.

View file

@ -6,7 +6,6 @@
from collections.abc import MutableMapping from collections.abc import MutableMapping
from pathlib import Path from pathlib import Path
from typing import Optional, Union
import numpy as np import numpy as np
@ -36,9 +35,9 @@ JUNIFER_DATA_PARAMS = {
def closest_resolution( def closest_resolution(
resolution: Optional[Union[float, int]], resolution: float | int | None,
valid_resolution: Union[list[float], list[int], np.ndarray], valid_resolution: list[float] | list[int] | np.ndarray,
) -> Union[float, int]: ) -> float | int:
"""Find the closest resolution. """Find the closest resolution.
Parameters Parameters
@ -136,7 +135,7 @@ def get_native_warper(
return possible_warpers[0] return possible_warpers[0]
def get_dataset_path() -> Optional[Path]: def get_dataset_path() -> Path | None:
"""Get junifer-data dataset path. """Get junifer-data dataset path.
Returns Returns

View file

@ -8,7 +8,6 @@
# License: AGPL # License: AGPL
from pathlib import Path from pathlib import Path
from typing import Union
from ...api.decorators import register_datagrabber from ...api.decorators import register_datagrabber
from ...utils import raise_error from ...utils import raise_error
@ -45,8 +44,8 @@ class DataladAOMICID1000(PatternDataladDataGrabber):
def __init__( def __init__(
self, self,
datadir: Union[str, Path, None] = None, datadir: str | Path | None = None,
types: Union[str, list[str], None] = None, types: str | list[str] | None = None,
space: str = "MNI152NLin2009cAsym", space: str = "MNI152NLin2009cAsym",
) -> None: ) -> None:
valid_spaces = ["native", "MNI152NLin2009cAsym"] valid_spaces = ["native", "MNI152NLin2009cAsym"]

View file

@ -9,7 +9,6 @@
from itertools import product from itertools import product
from pathlib import Path from pathlib import Path
from typing import Union
from ...api.decorators import register_datagrabber from ...api.decorators import register_datagrabber
from ...utils import raise_error from ...utils import raise_error
@ -51,9 +50,9 @@ class DataladAOMICPIOP1(PatternDataladDataGrabber):
def __init__( def __init__(
self, self,
datadir: Union[str, Path, None] = None, datadir: str | Path | None = None,
types: Union[str, list[str], None] = None, types: str | list[str] | None = None,
tasks: Union[str, list[str], None] = None, tasks: str | list[str] | None = None,
space: str = "MNI152NLin2009cAsym", space: str = "MNI152NLin2009cAsym",
) -> None: ) -> None:
valid_spaces = ["native", "MNI152NLin2009cAsym"] valid_spaces = ["native", "MNI152NLin2009cAsym"]

View file

@ -9,7 +9,6 @@
from itertools import product from itertools import product
from pathlib import Path from pathlib import Path
from typing import Union
from ...api.decorators import register_datagrabber from ...api.decorators import register_datagrabber
from ...utils import raise_error from ...utils import raise_error
@ -51,9 +50,9 @@ class DataladAOMICPIOP2(PatternDataladDataGrabber):
def __init__( def __init__(
self, self,
datadir: Union[str, Path, None] = None, datadir: str | Path | None = None,
types: Union[str, list[str], None] = None, types: str | list[str] | None = None,
tasks: Union[str, list[str], None] = None, tasks: str | list[str] | None = None,
space: str = "MNI152NLin2009cAsym", space: str = "MNI152NLin2009cAsym",
) -> None: ) -> None:
valid_spaces = ["native", "MNI152NLin2009cAsym"] valid_spaces = ["native", "MNI152NLin2009cAsym"]

View file

@ -7,8 +7,6 @@
# Synchon Mandal <s.mandal@fz-juelich.de> # Synchon Mandal <s.mandal@fz-juelich.de>
# License: AGPL # License: AGPL
from typing import Optional, Union
import pytest import pytest
from junifer.datagrabber.aomic.id1000 import DataladAOMICID1000 from junifer.datagrabber.aomic.id1000 import DataladAOMICID1000
@ -35,7 +33,7 @@ URI = "https://gin.g-node.org/juaml/datalad-example-aomic1000"
) )
def test_DataladAOMICID1000( def test_DataladAOMICID1000(
type_: str, type_: str,
nested_types: Optional[list[str]], nested_types: list[str] | None,
space: str, space: str,
) -> None: ) -> None:
"""Test DataladAOMICID1000 DataGrabber. """Test DataladAOMICID1000 DataGrabber.
@ -94,7 +92,7 @@ def test_DataladAOMICID1000(
], ],
) )
def test_DataladAOMICID1000_partial_data_access( def test_DataladAOMICID1000_partial_data_access(
types: Union[str, list[str]], types: str | list[str],
) -> None: ) -> None:
"""Test DataladAOMICID1000 DataGrabber partial data access. """Test DataladAOMICID1000 DataGrabber partial data access.

View file

@ -7,8 +7,6 @@
# Synchon Mandal <s.mandal@fz-juelich.de> # Synchon Mandal <s.mandal@fz-juelich.de>
# License: AGPL # License: AGPL
from typing import Optional, Union
import pytest import pytest
from junifer.datagrabber import DataladAOMICPIOP1 from junifer.datagrabber import DataladAOMICPIOP1
@ -71,8 +69,8 @@ URI = "https://gin.g-node.org/juaml/datalad-example-aomicpiop1"
) )
def test_DataladAOMICPIOP1( def test_DataladAOMICPIOP1(
type_: str, type_: str,
nested_types: Optional[list[str]], nested_types: list[str] | None,
tasks: Optional[list[str]], tasks: list[str] | None,
space: str, space: str,
) -> None: ) -> None:
"""Test DataladAOMICPIOP1 DataGrabber. """Test DataladAOMICPIOP1 DataGrabber.
@ -151,7 +149,7 @@ def test_DataladAOMICPIOP1(
], ],
) )
def test_DataladAOMICPIOP1_partial_data_access( def test_DataladAOMICPIOP1_partial_data_access(
types: Union[str, list[str]], types: str | list[str],
) -> None: ) -> None:
"""Test DataladAOMICPIOP1 DataGrabber partial data access. """Test DataladAOMICPIOP1 DataGrabber partial data access.

View file

@ -7,8 +7,6 @@
# Synchon Mandal <s.mandal@fz-juelich.de> # Synchon Mandal <s.mandal@fz-juelich.de>
# License: AGPL # License: AGPL
from typing import Optional, Union
import pytest import pytest
from junifer.datagrabber import DataladAOMICPIOP2 from junifer.datagrabber import DataladAOMICPIOP2
@ -65,8 +63,8 @@ URI = "https://gin.g-node.org/juaml/datalad-example-aomicpiop2"
) )
def test_DataladAOMICPIOP2( def test_DataladAOMICPIOP2(
type_: str, type_: str,
nested_types: Optional[list[str]], nested_types: list[str] | None,
tasks: Optional[list[str]], tasks: list[str] | None,
space: str, space: str,
) -> None: ) -> None:
"""Test DataladAOMICPIOP2 DataGrabber. """Test DataladAOMICPIOP2 DataGrabber.
@ -130,7 +128,7 @@ def test_DataladAOMICPIOP2(
], ],
) )
def test_DataladAOMICPIOP2_partial_data_access( def test_DataladAOMICPIOP2_partial_data_access(
types: Union[str, list[str]], types: str | list[str],
) -> None: ) -> None:
"""Test DataladAOMICPIOP2 DataGrabber partial data access. """Test DataladAOMICPIOP2 DataGrabber partial data access.

View file

@ -8,7 +8,6 @@
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from collections.abc import Iterator from collections.abc import Iterator
from pathlib import Path from pathlib import Path
from typing import Union
from ..pipeline import UpdateMetaMixin from ..pipeline import UpdateMetaMixin
from ..typing import Element, Elements from ..typing import Element, Elements
@ -38,7 +37,7 @@ class BaseDataGrabber(ABC, UpdateMetaMixin):
""" """
def __init__(self, types: list[str], datadir: Union[str, Path]) -> None: def __init__(self, types: list[str], datadir: str | Path) -> None:
# Validate types # Validate types
if not isinstance(types, list): if not isinstance(types, list):
raise_error(msg="`types` must be a list", klass=TypeError) raise_error(msg="`types` must be a list", klass=TypeError)
@ -89,7 +88,9 @@ class BaseDataGrabber(ABC, UpdateMetaMixin):
element = (element,) element = (element,)
# Zip through element keys and actual values to construct element # Zip through element keys and actual values to construct element
# access dictionary # access dictionary
named_element: dict = dict(zip(self.get_element_keys(), element)) named_element: dict = dict(
zip(self.get_element_keys(), element, strict=False)
)
logger.debug(f"Named element: {named_element}") logger.debug(f"Named element: {named_element}")
# Fetch element # Fetch element
out = self.get_item(**named_element) out = self.get_item(**named_element)

View file

@ -9,7 +9,6 @@ import atexit
import os import os
import tempfile import tempfile
from pathlib import Path from pathlib import Path
from typing import Optional, Union
import datalad import datalad
import datalad.api as dl import datalad.api as dl
@ -71,9 +70,9 @@ class DataladDataGrabber(BaseDataGrabber):
def __init__( def __init__(
self, self,
rootdir: Union[str, Path] = ".", rootdir: str | Path = ".",
datadir: Union[str, Path, None] = None, datadir: str | Path | None = None,
uri: Optional[str] = None, uri: str | None = None,
**kwargs, **kwargs,
): ):
if datadir is None: if datadir is None:

View file

@ -5,7 +5,6 @@
from itertools import product from itertools import product
from pathlib import Path from pathlib import Path
from typing import Union
from ..api.decorators import register_datagrabber from ..api.decorators import register_datagrabber
from ..utils import raise_error from ..utils import raise_error
@ -58,12 +57,12 @@ class DMCC13Benchmark(PatternDataladDataGrabber):
def __init__( def __init__(
self, self,
datadir: Union[str, Path, None] = None, datadir: str | Path | None = None,
types: Union[str, list[str], None] = None, types: str | list[str] | None = None,
sessions: Union[str, list[str], None] = None, sessions: str | list[str] | None = None,
tasks: Union[str, list[str], None] = None, tasks: str | list[str] | None = None,
phase_encodings: Union[str, list[str], None] = None, phase_encodings: str | list[str] | None = None,
runs: Union[str, list[str], None] = None, runs: str | list[str] | None = None,
native_t1w: bool = False, native_t1w: bool = False,
) -> None: ) -> None:
# Declare all sessions # Declare all sessions

View file

@ -6,7 +6,6 @@
# License: AGPL # License: AGPL
from pathlib import Path from pathlib import Path
from typing import Union
from junifer.datagrabber.datalad_base import DataladDataGrabber from junifer.datagrabber.datalad_base import DataladDataGrabber
@ -49,9 +48,9 @@ class DataladHCP1200(DataladDataGrabber, HCP1200):
def __init__( def __init__(
self, self,
datadir: Union[str, Path, None] = None, datadir: str | Path | None = None,
tasks: Union[str, list[str], None] = None, tasks: str | list[str] | None = None,
phase_encodings: Union[str, list[str], None] = None, phase_encodings: str | list[str] | None = None,
ica_fix: bool = False, ica_fix: bool = False,
) -> None: ) -> None:
uri = ( uri = (

View file

@ -7,7 +7,6 @@
from itertools import product from itertools import product
from pathlib import Path from pathlib import Path
from typing import Union
from ...api.decorators import register_datagrabber from ...api.decorators import register_datagrabber
from ...utils import raise_error from ...utils import raise_error
@ -47,9 +46,9 @@ class HCP1200(PatternDataGrabber):
def __init__( def __init__(
self, self,
datadir: Union[str, Path], datadir: str | Path,
tasks: Union[str, list[str], None] = None, tasks: str | list[str] | None = None,
phase_encodings: Union[str, list[str], None] = None, phase_encodings: str | list[str] | None = None,
ica_fix: bool = False, ica_fix: bool = False,
) -> None: ) -> None:
# All tasks # All tasks

View file

@ -7,7 +7,6 @@ import shutil
import tempfile import tempfile
from collections.abc import Iterable from collections.abc import Iterable
from pathlib import Path from pathlib import Path
from typing import Optional
import pytest import pytest
@ -64,8 +63,8 @@ def hcpdg() -> Iterable[DataladHCP1200]:
) )
def test_HCP1200( def test_HCP1200(
hcpdg: DataladHCP1200, hcpdg: DataladHCP1200,
tasks: Optional[str], tasks: str | None,
phase_encodings: Optional[str], phase_encodings: str | None,
ica_fix: bool, ica_fix: bool,
expected_path_name: str, expected_path_name: str,
) -> None: ) -> None:
@ -140,8 +139,8 @@ def test_HCP1200(
) )
def test_HCP1200_single_access( def test_HCP1200_single_access(
hcpdg: DataladHCP1200, hcpdg: DataladHCP1200,
tasks: Optional[str], tasks: str | None,
phase_encodings: Optional[str], phase_encodings: str | None,
) -> None: ) -> None:
"""Test HCP1200 DataGrabber single access. """Test HCP1200 DataGrabber single access.
@ -180,8 +179,8 @@ def test_HCP1200_single_access(
) )
def test_HCP1200_multi_access( def test_HCP1200_multi_access(
hcpdg: DataladHCP1200, hcpdg: DataladHCP1200,
tasks: Optional[str], tasks: str | None,
phase_encodings: Optional[str], phase_encodings: str | None,
) -> None: ) -> None:
"""Test HCP1200 DataGrabber multiple access. """Test HCP1200 DataGrabber multiple access.
@ -275,8 +274,8 @@ def test_HCP1200_multi_access_phase_simple(
], ],
) )
def test_HCP1200_incorrect_access_task( def test_HCP1200_incorrect_access_task(
tasks: Optional[str], tasks: str | None,
phase_encodings: Optional[str], phase_encodings: str | None,
) -> None: ) -> None:
"""Test HCP1200 DataGrabber incorrect access for task. """Test HCP1200 DataGrabber incorrect access for task.
@ -307,8 +306,8 @@ def test_HCP1200_incorrect_access_task(
], ],
) )
def test_HCP1200_incorrect_access_phase( def test_HCP1200_incorrect_access_phase(
tasks: Optional[str], tasks: str | None,
phase_encodings: Optional[str], phase_encodings: str | None,
) -> None: ) -> None:
"""Test HCP1200 DataGrabber incorrect access for phase. """Test HCP1200 DataGrabber incorrect access for phase.
@ -374,7 +373,7 @@ def test_HCP1200_elements(
], ],
) )
def test_HCP1200_incorrect_access_icafix( def test_HCP1200_incorrect_access_icafix(
tasks: Optional[str], ica_fix: bool tasks: str | None, ica_fix: bool
) -> None: ) -> None:
"""Test HCP1200 DataGrabber incorrect access for icafix. """Test HCP1200 DataGrabber incorrect access for icafix.

View file

@ -5,8 +5,6 @@
# Synchon Mandal <s.mandal@fz-juelich.de> # Synchon Mandal <s.mandal@fz-juelich.de>
# License: AGPL # License: AGPL
from typing import Union
from ..api.decorators import register_datagrabber from ..api.decorators import register_datagrabber
from ..typing import DataGrabberLike from ..typing import DataGrabberLike
from ..utils import deep_update, raise_error from ..utils import deep_update, raise_error
@ -79,7 +77,7 @@ class MultipleDataGrabber(BaseDataGrabber):
) )
self._datagrabbers = datagrabbers self._datagrabbers = datagrabbers
def __getitem__(self, element: Union[str, tuple]) -> dict: def __getitem__(self, element: str | tuple) -> dict:
"""Implement indexing. """Implement indexing.
Parameters Parameters

View file

@ -8,7 +8,6 @@
import re import re
from copy import deepcopy from copy import deepcopy
from pathlib import Path from pathlib import Path
from typing import Optional, Union
import numpy as np import numpy as np
@ -173,9 +172,9 @@ class PatternDataGrabber(BaseDataGrabber, PatternValidationMixin):
self, self,
types: list[str], types: list[str],
patterns: DataGrabberPatterns, patterns: DataGrabberPatterns,
replacements: Union[list[str], str], replacements: list[str] | str,
datadir: Union[str, Path], datadir: str | Path,
confounds_format: Optional[str] = None, confounds_format: str | None = None,
partial_pattern_ok: bool = False, partial_pattern_ok: bool = False,
) -> None: ) -> None:
# Convert replacements to list if not already # Convert replacements to list if not already

View file

@ -3,8 +3,6 @@
# Authors: Synchon Mandal <s.mandal@fz-juelich.de> # Authors: Synchon Mandal <s.mandal@fz-juelich.de>
# License: AGPL # License: AGPL
from typing import Optional, Union
import pytest import pytest
from junifer.datagrabber import DMCC13Benchmark from junifer.datagrabber import DMCC13Benchmark
@ -48,10 +46,10 @@ URI = "https://gin.g-node.org/synchon/datalad-example-dmcc13-benchmark"
], ],
) )
def test_DMCC13Benchmark( def test_DMCC13Benchmark(
sessions: Optional[str], sessions: str | None,
tasks: Optional[str], tasks: str | None,
phase_encodings: Optional[str], phase_encodings: str | None,
runs: Optional[str], runs: str | None,
native_t1w: bool, native_t1w: bool,
) -> None: ) -> None:
"""Test DMCC13Benchmark DataGrabber. """Test DMCC13Benchmark DataGrabber.
@ -129,7 +127,9 @@ def test_DMCC13Benchmark(
"sub-01_space-MNI152NLin2009cAsym_desc-preproc_T1w.nii.gz" "sub-01_space-MNI152NLin2009cAsym_desc-preproc_T1w.nii.gz"
) )
for data_type, data_file_name in zip(data_types, data_file_names): for data_type, data_file_name in zip(
data_types, data_file_names, strict=False
):
# Assert data type # Assert data type
assert data_type in out assert data_type in out
# Conditional for Warp # Conditional for Warp
@ -166,6 +166,7 @@ def test_DMCC13Benchmark(
"desc-confounds_regressors.tsv" "desc-confounds_regressors.tsv"
), ),
), ),
strict=False,
): ):
# Assert data type # Assert data type
assert type_ in out["BOLD"] assert type_ in out["BOLD"]
@ -218,7 +219,7 @@ def test_DMCC13Benchmark(
], ],
) )
def test_DMCC13Benchmark_partial_data_access( def test_DMCC13Benchmark_partial_data_access(
types: Union[str, list[str]], types: str | list[str],
native_t1w: bool, native_t1w: bool,
) -> None: ) -> None:
"""Test DMCC13Benchmark DataGrabber partial data access. """Test DMCC13Benchmark DataGrabber partial data access.

View file

@ -5,7 +5,6 @@
# License: AGPL # License: AGPL
from contextlib import AbstractContextManager, nullcontext from contextlib import AbstractContextManager, nullcontext
from typing import Union
import pytest import pytest
@ -289,9 +288,9 @@ def test_register_data_type() -> None:
], ],
) )
def test_PatternValidationMixin( def test_PatternValidationMixin(
types: Union[str, list[str], list[int]], types: str | list[str] | list[int],
replacements: Union[str, list[str], list[int]], replacements: str | list[str] | list[int],
patterns: Union[str, dict[str, dict[str, str]]], patterns: str | dict[str, dict[str, str]],
expect: AbstractContextManager, expect: AbstractContextManager,
) -> None: ) -> None:
"""Test validation. """Test validation.

View file

@ -5,7 +5,6 @@
# License: AGPL # License: AGPL
from pathlib import Path from pathlib import Path
from typing import Optional, Union
import nibabel as nib import nibabel as nib
import pandas as pd import pandas as pd
@ -59,7 +58,7 @@ class DefaultDataReader(PipelineStepMixin, UpdateMetaMixin):
def _fit_transform( def _fit_transform(
self, self,
input: dict[str, dict], input: dict[str, dict],
params: Optional[dict] = None, params: dict | None = None,
) -> dict: ) -> dict:
"""Fit and transform. """Fit and transform.
@ -149,7 +148,7 @@ class DefaultDataReader(PipelineStepMixin, UpdateMetaMixin):
def _read_data( def _read_data(
data_type: str, path: Path, read_params: dict data_type: str, path: Path, read_params: dict
) -> Union[nib.Nifti1Image, pd.DataFrame, None]: ) -> nib.Nifti1Image | pd.DataFrame | None:
"""Read data for data type. """Read data for data type.
Parameters Parameters

View file

@ -3,9 +3,8 @@
# Authors: Synchon Mandal <s.mandal@fz-juelich.de> # Authors: Synchon Mandal <s.mandal@fz-juelich.de>
# License: AGPL # License: AGPL
import sys from collections.abc import Callable
from itertools import product from itertools import product
from typing import Callable, Optional
import numpy as np import numpy as np
from nilearn import signal from nilearn import signal
@ -189,9 +188,9 @@ def _map_eigenvalues(
def _geometric_mean( def _geometric_mean(
matrices: list[np.ndarray], matrices: list[np.ndarray],
init: Optional[np.ndarray] = None, init: np.ndarray | None = None,
max_iter: int = 10, max_iter: int = 10,
tol: Optional[float] = 1e-7, tol: float | None = 1e-7,
) -> np.ndarray: ) -> np.ndarray:
"""Compute the geometric mean of symmetric positive definite matrices. """Compute the geometric mean of symmetric positive definite matrices.
@ -431,14 +430,6 @@ class JuniferConnectivityMeasure(ConnectivityMeasure):
connectivities = [cov_to_corr(cov) for cov in covariances_std] connectivities = [cov_to_corr(cov) for cov in covariances_std]
elif self.kind == "xi correlation": elif self.kind == "xi correlation":
if sys.version_info < (3, 10): # pragma: no cover
raise_error(
klass=RuntimeError,
msg=(
"scipy.stats.chatterjeexi is available from "
"scipy 1.15.0 and that requires Python 3.10 and above."
),
)
connectivities = [] connectivities = []
for x in X: for x in X:
n_rois = x.shape[1] n_rois = x.shape[1]

View file

@ -3,7 +3,8 @@
# Authors: Synchon Mandal <s.mandal@fz-juelich.de> # Authors: Synchon Mandal <s.mandal@fz-juelich.de>
# License: AGPL # License: AGPL
from typing import TYPE_CHECKING, Callable, Optional, Union from collections.abc import Callable
from typing import TYPE_CHECKING, Union
import numpy as np import numpy as np
from nilearn import image, masking from nilearn import image, masking
@ -133,7 +134,7 @@ def _apply_mask_and_get_affinity(
interpolation="nearest", interpolation="nearest",
) )
mask, _ = masking.load_mask_img(mask_img) mask, _ = masking.load_mask_img(mask_img)
mask_coords = list(zip(*np.where(mask != 0))) mask_coords = list(zip(*np.where(mask != 0), strict=False))
X = masking.apply_mask_fmri(niimg, mask_img) X = masking.apply_mask_fmri(niimg, mask_img)
@ -166,7 +167,7 @@ def _apply_mask_and_get_affinity(
except ValueError: except ValueError:
nearests.append(None) nearests.append(None)
mask_coords = np.asarray(list(zip(*mask_coords))) mask_coords = np.asarray(list(zip(*mask_coords, strict=False)))
mask_coords = image.resampling.coord_transform( mask_coords = image.resampling.coord_transform(
mask_coords[0], mask_coords[1], mask_coords[2], affine mask_coords[0], mask_coords[1], mask_coords[2], affine
) )
@ -255,7 +256,7 @@ class _JuniferExtractionFunctor:
def __init__( def __init__(
self, self,
seeds_: "ArrayLike", seeds_: "ArrayLike",
radius: Optional[float], radius: float | None,
mask_img: Union["Nifti1Image", "Nifti2Image", None], mask_img: Union["Nifti1Image", "Nifti2Image", None],
agg_func: Callable, agg_func: Callable,
allow_overlap: bool, allow_overlap: bool,
@ -352,7 +353,7 @@ class JuniferNiftiSpheresMasker(NiftiSpheresMasker):
def __init__( def __init__(
self, self,
seeds: "ArrayLike", seeds: "ArrayLike",
radius: Optional[float] = None, radius: float | None = None,
mask_img: Union["Nifti1Image", "Nifti2Image", None] = None, mask_img: Union["Nifti1Image", "Nifti2Image", None] = None,
agg_func: Callable = np.mean, agg_func: Callable = np.mean,
allow_overlap: bool = False, allow_overlap: bool = False,

View file

@ -7,7 +7,7 @@ import copy
import sys import sys
import warnings import warnings
from math import cosh, exp, log, sinh, sqrt from math import cosh, exp, log, sinh, sqrt
from typing import TYPE_CHECKING, Optional, Union from typing import TYPE_CHECKING, Optional
import numpy as np import numpy as np
import pytest import pytest
@ -88,7 +88,7 @@ def random_diagonal(
p: int, p: int,
v_min: float = 1.0, v_min: float = 1.0,
v_max: float = 2.0, v_max: float = 2.0,
random_state: Union[int, np.random.RandomState] = 0, random_state: int | np.random.RandomState = 0,
) -> np.ndarray: ) -> np.ndarray:
"""Generate a random diagonal matrix. """Generate a random diagonal matrix.
@ -120,7 +120,7 @@ def random_spd(
p: int, p: int,
eig_min: float, eig_min: float,
cond: float, cond: float,
random_state: Union[int, np.random.RandomState] = 0, random_state: int | np.random.RandomState = 0,
) -> np.ndarray: ) -> np.ndarray:
"""Generate a random symmetric positive definite matrix. """Generate a random symmetric positive definite matrix.
@ -190,7 +190,7 @@ def signals() -> list[np.ndarray]:
@pytest.fixture @pytest.fixture
def signals_and_covariances( def signals_and_covariances(
cov_estimator: Union[LedoitWolf, EmpiricalCovariance], cov_estimator: LedoitWolf | EmpiricalCovariance,
) -> tuple[list[np.ndarray], list[float]]: ) -> tuple[list[np.ndarray], list[float]]:
"""Return signals and covariances for a covariance estimator. """Return signals and covariances for a covariance estimator.
@ -343,7 +343,7 @@ def test_geometric_mean_properties() -> None:
# Generic # Generic
assert isinstance(spds, list) assert isinstance(spds, list)
for spd, input_spd in zip(spds, input_spds): for spd, input_spd in zip(spds, input_spds, strict=False):
assert_array_equal(spd, input_spd) assert_array_equal(spd, input_spd)
assert is_spd(gmean, decimal=7) assert is_spd(gmean, decimal=7)
@ -352,7 +352,7 @@ def random_non_singular(
p: int, p: int,
sing_min: float = 1.0, sing_min: float = 1.0,
sing_max: float = 2.0, sing_max: float = 2.0,
random_state: Union[int, np.random.RandomState] = 0, random_state: int | np.random.RandomState = 0,
) -> np.ndarray: ) -> np.ndarray:
"""Generate a random nonsingular matrix. """Generate a random nonsingular matrix.
@ -669,7 +669,7 @@ def _assert_connectivity_tangent(connectivities, conn_measure, covs) -> None:
""" """
for true_covariance_matrix, estimated_covariance_matrix in zip( for true_covariance_matrix, estimated_covariance_matrix in zip(
covs, connectivities covs, connectivities, strict=False
): ):
assert_array_almost_equal( assert_array_almost_equal(
estimated_covariance_matrix, estimated_covariance_matrix.T estimated_covariance_matrix, estimated_covariance_matrix.T
@ -701,7 +701,7 @@ def _assert_connectivity_precision(connectivities, covs) -> None:
""" """
for true_covariance_matrix, estimated_covariance_matrix in zip( for true_covariance_matrix, estimated_covariance_matrix in zip(
covs, connectivities covs, connectivities, strict=False
): ):
assert is_spd(estimated_covariance_matrix, decimal=7) assert is_spd(estimated_covariance_matrix, decimal=7)
assert_array_almost_equal( assert_array_almost_equal(
@ -729,7 +729,7 @@ def _assert_connectivity_correlation(
""" """
for true_covariance_matrix, estimated_covariance_matrix in zip( for true_covariance_matrix, estimated_covariance_matrix in zip(
covs, connectivities covs, connectivities, strict=False
): ):
assert is_spd(estimated_covariance_matrix, decimal=7) assert is_spd(estimated_covariance_matrix, decimal=7)
@ -750,7 +750,7 @@ def _assert_connectivity_correlation(
def _assert_connectivity_partial_correlation(connectivities, covs) -> None: def _assert_connectivity_partial_correlation(connectivities, covs) -> None:
"""Assert partial correlation connectivity matrix.""" """Assert partial correlation connectivity matrix."""
for true_covariance_matrix, estimated_covariance_matrix in zip( for true_covariance_matrix, estimated_covariance_matrix in zip(
covs, connectivities covs, connectivities, strict=False
): ):
precision_matrix = linalg.inv(true_covariance_matrix) precision_matrix = linalg.inv(true_covariance_matrix)

View file

@ -6,7 +6,7 @@
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from copy import deepcopy from copy import deepcopy
from typing import Any, ClassVar, Optional, Union from typing import Any, ClassVar
from ..pipeline import PipelineStepMixin, UpdateMetaMixin from ..pipeline import PipelineStepMixin, UpdateMetaMixin
from ..typing import MarkerInOutMappings, StorageLike from ..typing import MarkerInOutMappings, StorageLike
@ -44,8 +44,8 @@ class BaseMarker(ABC, PipelineStepMixin, UpdateMetaMixin):
def __init__( def __init__(
self, self,
on: Optional[Union[list[str], str]] = None, on: list[str] | str | None = None,
name: Optional[str] = None, name: str | None = None,
) -> None: ) -> None:
# Check for missing mapping attribute # Check for missing mapping attribute
if not hasattr(self, "_MARKER_INOUT_MAPPINGS"): if not hasattr(self, "_MARKER_INOUT_MAPPINGS"):
@ -126,7 +126,7 @@ class BaseMarker(ABC, PipelineStepMixin, UpdateMetaMixin):
return self._MARKER_INOUT_MAPPINGS[input_type][output_feature] return self._MARKER_INOUT_MAPPINGS[input_type][output_feature]
@abstractmethod @abstractmethod
def compute(self, input: dict, extra_input: Optional[dict] = None) -> dict: def compute(self, input: dict, extra_input: dict | None = None) -> dict:
"""Compute. """Compute.
Parameters Parameters
@ -181,7 +181,7 @@ class BaseMarker(ABC, PipelineStepMixin, UpdateMetaMixin):
def _fit_transform( def _fit_transform(
self, self,
input: dict[str, dict], input: dict[str, dict],
storage: Optional[StorageLike] = None, storage: StorageLike | None = None,
) -> dict: ) -> dict:
"""Fit and transform. """Fit and transform.

View file

@ -8,8 +8,6 @@ from pathlib import Path
from typing import ( from typing import (
Any, Any,
ClassVar, ClassVar,
Optional,
Union,
) )
import numpy as np import numpy as np
@ -99,7 +97,7 @@ class BrainPrint(BaseMarker):
asymmetry: bool = False, asymmetry: bool = False,
asymmetry_distance: str = "euc", asymmetry_distance: str = "euc",
use_cholmod: bool = False, use_cholmod: bool = False,
name: Optional[str] = None, name: str | None = None,
) -> None: ) -> None:
self.num = num self.num = num
self.skip_cortex = skip_cortex self.skip_cortex = skip_cortex
@ -307,7 +305,7 @@ class BrainPrint(BaseMarker):
def _fix_nan( def _fix_nan(
self, self,
input_data: list[Union[float, str, npt.ArrayLike]], input_data: list[float | str | npt.ArrayLike],
) -> np.ndarray: # pragma: no cover ) -> np.ndarray: # pragma: no cover
"""Convert BrainPrint output with string NaN to ``numpy.nan``. """Convert BrainPrint output with string NaN to ``numpy.nan``.
@ -329,7 +327,7 @@ class BrainPrint(BaseMarker):
def compute( def compute(
self, self,
input: dict[str, Any], input: dict[str, Any],
extra_input: Optional[dict] = None, extra_input: dict | None = None,
) -> dict: # pragma: no cover ) -> dict: # pragma: no cover
"""Compute. """Compute.

View file

@ -8,8 +8,6 @@ from typing import (
TYPE_CHECKING, TYPE_CHECKING,
Any, Any,
ClassVar, ClassVar,
Optional,
Union,
) )
from ...typing import Dependencies, MarkerInOutMappings from ...typing import Dependencies, MarkerInOutMappings
@ -59,11 +57,11 @@ class ComplexityBase(BaseMarker):
def __init__( def __init__(
self, self,
parcellation: Union[str, list[str]], parcellation: str | list[str],
agg_method: str = "mean", agg_method: str = "mean",
agg_method_params: Optional[dict] = None, agg_method_params: dict | None = None,
masks: Union[str, dict, list[Union[dict, str]], None] = None, masks: str | dict | list[dict | str] | None = None,
name: Optional[str] = None, name: str | None = None,
) -> None: ) -> None:
self.parcellation = parcellation self.parcellation = parcellation
self.agg_method = agg_method self.agg_method = agg_method
@ -85,7 +83,7 @@ class ComplexityBase(BaseMarker):
def compute( def compute(
self, self,
input: dict[str, Any], input: dict[str, Any],
extra_input: Optional[dict[str, Any]] = None, extra_input: dict[str, Any] | None = None,
) -> dict[str, Any]: ) -> dict[str, Any]:
"""Compute. """Compute.

View file

@ -4,8 +4,6 @@
# Leonard Sasse <l.sasse@fz-juelich.de> # Leonard Sasse <l.sasse@fz-juelich.de>
# License: AGPL # License: AGPL
from typing import Optional, Union
import neurokit2 as nk import neurokit2 as nk
import numpy as np import numpy as np
@ -55,12 +53,12 @@ class HurstExponent(ComplexityBase):
def __init__( def __init__(
self, self,
parcellation: Union[str, list[str]], parcellation: str | list[str],
agg_method: str = "mean", agg_method: str = "mean",
agg_method_params: Optional[dict] = None, agg_method_params: dict | None = None,
masks: Union[str, dict, list[Union[dict, str]], None] = None, masks: str | dict | list[dict | str] | None = None,
params: Optional[dict] = None, params: dict | None = None,
name: Optional[str] = None, name: str | None = None,
) -> None: ) -> None:
super().__init__( super().__init__(
parcellation=parcellation, parcellation=parcellation,

View file

@ -4,8 +4,6 @@
# Leonard Sasse <l.sasse@fz-juelich.de> # Leonard Sasse <l.sasse@fz-juelich.de>
# License: AGPL # License: AGPL
from typing import Optional, Union
import neurokit2 as nk import neurokit2 as nk
import numpy as np import numpy as np
@ -56,12 +54,12 @@ class MultiscaleEntropyAUC(ComplexityBase):
def __init__( def __init__(
self, self,
parcellation: Union[str, list[str]], parcellation: str | list[str],
agg_method: str = "mean", agg_method: str = "mean",
agg_method_params: Optional[dict] = None, agg_method_params: dict | None = None,
masks: Union[str, dict, list[Union[dict, str]], None] = None, masks: str | dict | list[dict | str] | None = None,
params: Optional[dict] = None, params: dict | None = None,
name: Optional[str] = None, name: str | None = None,
) -> None: ) -> None:
super().__init__( super().__init__(
parcellation=parcellation, parcellation=parcellation,

View file

@ -4,8 +4,6 @@
# Leonard Sasse <l.sasse@fz-juelich.de> # Leonard Sasse <l.sasse@fz-juelich.de>
# License: AGPL # License: AGPL
from typing import Optional, Union
import neurokit2 as nk import neurokit2 as nk
import numpy as np import numpy as np
@ -56,12 +54,12 @@ class PermEntropy(ComplexityBase):
def __init__( def __init__(
self, self,
parcellation: Union[str, list[str]], parcellation: str | list[str],
agg_method: str = "mean", agg_method: str = "mean",
agg_method_params: Optional[dict] = None, agg_method_params: dict | None = None,
masks: Union[str, dict, list[Union[dict, str]], None] = None, masks: str | dict | list[dict | str] | None = None,
params: Optional[dict] = None, params: dict | None = None,
name: Optional[str] = None, name: str | None = None,
) -> None: ) -> None:
super().__init__( super().__init__(
parcellation=parcellation, parcellation=parcellation,

View file

@ -4,8 +4,6 @@
# Leonard Sasse <l.sasse@fz-juelich.de> # Leonard Sasse <l.sasse@fz-juelich.de>
# License: AGPL # License: AGPL
from typing import Optional, Union
import neurokit2 as nk import neurokit2 as nk
import numpy as np import numpy as np
@ -56,12 +54,12 @@ class RangeEntropy(ComplexityBase):
def __init__( def __init__(
self, self,
parcellation: Union[str, list[str]], parcellation: str | list[str],
agg_method: str = "mean", agg_method: str = "mean",
agg_method_params: Optional[dict] = None, agg_method_params: dict | None = None,
masks: Union[str, dict, list[Union[dict, str]], None] = None, masks: str | dict | list[dict | str] | None = None,
params: Optional[dict] = None, params: dict | None = None,
name: Optional[str] = None, name: str | None = None,
) -> None: ) -> None:
super().__init__( super().__init__(
parcellation=parcellation, parcellation=parcellation,

View file

@ -4,8 +4,6 @@
# Leonard Sasse <l.sasse@fz-juelich.de> # Leonard Sasse <l.sasse@fz-juelich.de>
# License: AGPL # License: AGPL
from typing import Optional, Union
import neurokit2 as nk import neurokit2 as nk
import numpy as np import numpy as np
@ -56,12 +54,12 @@ class RangeEntropyAUC(ComplexityBase):
def __init__( def __init__(
self, self,
parcellation: Union[str, list[str]], parcellation: str | list[str],
agg_method: str = "mean", agg_method: str = "mean",
agg_method_params: Optional[dict] = None, agg_method_params: dict | None = None,
masks: Union[str, dict, list[Union[dict, str]], None] = None, masks: str | dict | list[dict | str] | None = None,
params: Optional[dict] = None, params: dict | None = None,
name: Optional[str] = None, name: str | None = None,
) -> None: ) -> None:
super().__init__( super().__init__(
parcellation=parcellation, parcellation=parcellation,
@ -138,7 +136,11 @@ class RangeEntropyAUC(ComplexityBase):
range_ent_vec[idx_r] = range_en_auc_roi_tmp[0] range_ent_vec[idx_r] = range_en_auc_roi_tmp[0]
idx_r = idx_r + 1 idx_r = idx_r + 1
range_en_auc_roi[idx_roi] = np.trapz(range_ent_vec) range_en_auc_roi[idx_roi] = (
np.trapezoid(range_ent_vec)
if int(np.__version__[0]) > 1
else np.trapz(range_ent_vec)
)
range_en_auc_roi = range_en_auc_roi / n_r range_en_auc_roi = range_en_auc_roi / n_r

View file

@ -4,8 +4,6 @@
# Leonard Sasse <l.sasse@fz-juelich.de> # Leonard Sasse <l.sasse@fz-juelich.de>
# License: AGPL # License: AGPL
from typing import Optional, Union
import neurokit2 as nk import neurokit2 as nk
import numpy as np import numpy as np
@ -57,12 +55,12 @@ class SampleEntropy(ComplexityBase):
def __init__( def __init__(
self, self,
parcellation: Union[str, list[str]], parcellation: str | list[str],
agg_method: str = "mean", agg_method: str = "mean",
agg_method_params: Optional[dict] = None, agg_method_params: dict | None = None,
masks: Union[str, dict, list[Union[dict, str]], None] = None, masks: str | dict | list[dict | str] | None = None,
params: Optional[dict] = None, params: dict | None = None,
name: Optional[str] = None, name: str | None = None,
) -> None: ) -> None:
super().__init__( super().__init__(
parcellation=parcellation, parcellation=parcellation,

View file

@ -4,8 +4,6 @@
# Leonard Sasse <l.sasse@fz-juelich.de> # Leonard Sasse <l.sasse@fz-juelich.de>
# License: AGPL # License: AGPL
from typing import Optional, Union
import neurokit2 as nk import neurokit2 as nk
import numpy as np import numpy as np
@ -57,12 +55,12 @@ class WeightedPermEntropy(ComplexityBase):
def __init__( def __init__(
self, self,
parcellation: Union[str, list[str]], parcellation: str | list[str],
agg_method: str = "mean", agg_method: str = "mean",
agg_method_params: Optional[dict] = None, agg_method_params: dict | None = None,
masks: Union[str, dict, list[Union[dict, str]], None] = None, masks: str | dict | list[dict | str] | None = None,
params: Optional[dict] = None, params: dict | None = None,
name: Optional[str] = None, name: str | None = None,
) -> None: ) -> None:
super().__init__( super().__init__(
parcellation=parcellation, parcellation=parcellation,

View file

@ -6,7 +6,7 @@
# Synchon Mandal <s.mandal@fz-juelich.de> # Synchon Mandal <s.mandal@fz-juelich.de>
# License: AGPL # License: AGPL
from typing import Any, ClassVar, Optional, Union from typing import Any, ClassVar
import numpy as np import numpy as np
@ -56,11 +56,11 @@ class RSSETSMarker(BaseMarker):
def __init__( def __init__(
self, self,
parcellation: Union[str, list[str]], parcellation: str | list[str],
agg_method: str = "mean", agg_method: str = "mean",
agg_method_params: Optional[dict] = None, agg_method_params: dict | None = None,
masks: Union[str, dict, list[Union[dict, str]], None] = None, masks: str | dict | list[dict | str] | None = None,
name: Optional[str] = None, name: str | None = None,
) -> None: ) -> None:
self.parcellation = parcellation self.parcellation = parcellation
self.agg_method = agg_method self.agg_method = agg_method
@ -71,7 +71,7 @@ class RSSETSMarker(BaseMarker):
def compute( def compute(
self, self,
input: dict[str, Any], input: dict[str, Any],
extra_input: Optional[dict] = None, extra_input: dict | None = None,
) -> dict: ) -> dict:
"""Compute. """Compute.

View file

@ -8,7 +8,6 @@ from pathlib import Path
from typing import ( from typing import (
TYPE_CHECKING, TYPE_CHECKING,
ClassVar, ClassVar,
Optional,
) )
import nibabel as nib import nibabel as nib
@ -53,7 +52,7 @@ class AFNIALFF(metaclass=Singleton):
input_path: Path, input_path: Path,
highpass: float, highpass: float,
lowpass: float, lowpass: float,
tr: Optional[float], tr: float | None,
) -> tuple["Nifti1Image", "Nifti1Image", Path, Path]: ) -> tuple["Nifti1Image", "Nifti1Image", Path, Path]:
"""Compute ALFF + fALFF map. """Compute ALFF + fALFF map.

View file

@ -8,7 +8,6 @@ from pathlib import Path
from typing import ( from typing import (
TYPE_CHECKING, TYPE_CHECKING,
ClassVar, ClassVar,
Optional,
) )
import nibabel as nib import nibabel as nib
@ -50,7 +49,7 @@ class JuniferALFF(metaclass=Singleton):
input_path: Path, input_path: Path,
highpass: float, highpass: float,
lowpass: float, lowpass: float,
tr: Optional[float], tr: float | None,
) -> tuple["Nifti1Image", "Nifti1Image", Path, Path]: ) -> tuple["Nifti1Image", "Nifti1Image", Path, Path]:
"""Compute ALFF + fALFF map. """Compute ALFF + fALFF map.

View file

@ -11,7 +11,6 @@ from typing import (
TYPE_CHECKING, TYPE_CHECKING,
Any, Any,
ClassVar, ClassVar,
Optional,
) )
from ...typing import ConditionalDependencies, MarkerInOutMappings from ...typing import ConditionalDependencies, MarkerInOutMappings
@ -91,8 +90,8 @@ class ALFFBase(BaseMarker):
highpass: float, highpass: float,
lowpass: float, lowpass: float,
using: str, using: str,
tr: Optional[float] = None, tr: float | None = None,
name: Optional[str] = None, name: str | None = None,
) -> None: ) -> None:
if highpass < 0: if highpass < 0:
raise_error("Highpass must be positive or 0") raise_error("Highpass must be positive or 0")

View file

@ -3,7 +3,7 @@
# Authors: Synchon Mandal <s.mandal@fz-juelich.de> # Authors: Synchon Mandal <s.mandal@fz-juelich.de>
# License: AGPL # License: AGPL
from typing import Any, Optional, Union from typing import Any
from ...api.decorators import register_marker from ...api.decorators import register_marker
from ...utils import logger from ...utils import logger
@ -65,9 +65,9 @@ class ALFFMaps(ALFFBase):
using: str, using: str,
highpass: float = 0.01, highpass: float = 0.01,
lowpass: float = 0.1, lowpass: float = 0.1,
tr: Optional[float] = None, tr: float | None = None,
masks: Union[str, dict, list[Union[dict, str]], None] = None, masks: str | dict | list[dict | str] | None = None,
name: Optional[str] = None, name: str | None = None,
) -> None: ) -> None:
# Superclass init first to validate `using` parameter # Superclass init first to validate `using` parameter
super().__init__( super().__init__(
@ -83,7 +83,7 @@ class ALFFMaps(ALFFBase):
def compute( def compute(
self, self,
input: dict[str, Any], input: dict[str, Any],
extra_input: Optional[dict[str, Any]] = None, extra_input: dict[str, Any] | None = None,
) -> dict[str, Any]: ) -> dict[str, Any]:
"""Compute. """Compute.

View file

@ -6,7 +6,7 @@
# Synchon Mandal <s.mandal@fz-juelich.de> # Synchon Mandal <s.mandal@fz-juelich.de>
# License: AGPL # License: AGPL
from typing import Any, Optional, Union from typing import Any
from ...api.decorators import register_marker from ...api.decorators import register_marker
from ...utils import logger from ...utils import logger
@ -70,15 +70,15 @@ class ALFFParcels(ALFFBase):
def __init__( def __init__(
self, self,
parcellation: Union[str, list[str]], parcellation: str | list[str],
using: str, using: str,
highpass: float = 0.01, highpass: float = 0.01,
lowpass: float = 0.1, lowpass: float = 0.1,
tr: Optional[float] = None, tr: float | None = None,
agg_method: str = "mean", agg_method: str = "mean",
agg_method_params: Optional[dict] = None, agg_method_params: dict | None = None,
masks: Union[str, dict, list[Union[dict, str]], None] = None, masks: str | dict | list[dict | str] | None = None,
name: Optional[str] = None, name: str | None = None,
) -> None: ) -> None:
# Superclass init first to validate `using` parameter # Superclass init first to validate `using` parameter
super().__init__( super().__init__(
@ -96,7 +96,7 @@ class ALFFParcels(ALFFBase):
def compute( def compute(
self, self,
input: dict[str, Any], input: dict[str, Any],
extra_input: Optional[dict[str, Any]] = None, extra_input: dict[str, Any] | None = None,
) -> dict[str, Any]: ) -> dict[str, Any]:
"""Compute. """Compute.

View file

@ -6,7 +6,7 @@
# Synchon Mandal <s.mandal@fz-juelich.de> # Synchon Mandal <s.mandal@fz-juelich.de>
# License: AGPL # License: AGPL
from typing import Any, Optional, Union from typing import Any
from ...api.decorators import register_marker from ...api.decorators import register_marker
from ...utils import logger from ...utils import logger
@ -79,15 +79,15 @@ class ALFFSpheres(ALFFBase):
self, self,
coords: str, coords: str,
using: str, using: str,
radius: Optional[float] = None, radius: float | None = None,
allow_overlap: bool = False, allow_overlap: bool = False,
highpass: float = 0.01, highpass: float = 0.01,
lowpass: float = 0.1, lowpass: float = 0.1,
tr: Optional[float] = None, tr: float | None = None,
agg_method: str = "mean", agg_method: str = "mean",
agg_method_params: Optional[dict] = None, agg_method_params: dict | None = None,
masks: Union[str, dict, list[Union[dict, str]], None] = None, masks: str | dict | list[dict | str] | None = None,
name: Optional[str] = None, name: str | None = None,
) -> None: ) -> None:
# Superclass init first to validate `using` parameter # Superclass init first to validate `using` parameter
super().__init__( super().__init__(
@ -107,7 +107,7 @@ class ALFFSpheres(ALFFBase):
def compute( def compute(
self, self,
input: dict[str, Any], input: dict[str, Any],
extra_input: Optional[dict[str, Any]] = None, extra_input: dict[str, Any] | None = None,
) -> dict[str, Any]: ) -> dict[str, Any]:
"""Compute. """Compute.

View file

@ -4,7 +4,7 @@
# Kaustubh R. Patil <k.patil@fz-juelich.de> # Kaustubh R. Patil <k.patil@fz-juelich.de>
# License: AGPL # License: AGPL
from typing import Any, ClassVar, Optional, Union from typing import Any, ClassVar
import pandas as pd import pandas as pd
@ -63,10 +63,10 @@ class CrossParcellationFC(BaseMarker):
parcellation_one: str, parcellation_one: str,
parcellation_two: str, parcellation_two: str,
agg_method: str = "mean", agg_method: str = "mean",
agg_method_params: Optional[dict] = None, agg_method_params: dict | None = None,
corr_method: str = "pearson", corr_method: str = "pearson",
masks: Union[str, dict, list[Union[dict, str]], None] = None, masks: str | dict | list[dict | str] | None = None,
name: Optional[str] = None, name: str | None = None,
) -> None: ) -> None:
if parcellation_one == parcellation_two: if parcellation_one == parcellation_two:
raise_error( raise_error(
@ -83,7 +83,7 @@ class CrossParcellationFC(BaseMarker):
def compute( def compute(
self, self,
input: dict[str, Any], input: dict[str, Any],
extra_input: Optional[dict] = None, extra_input: dict | None = None,
) -> dict: ) -> dict:
"""Compute. """Compute.

View file

@ -3,7 +3,7 @@
# Authors: Synchon Mandal <s.mandal@fz-juelich.de> # Authors: Synchon Mandal <s.mandal@fz-juelich.de>
# License: AGPL # License: AGPL
from typing import Any, Optional, Union from typing import Any
from ...api.decorators import register_marker from ...api.decorators import register_marker
from ..maps_aggregation import MapsAggregation from ..maps_aggregation import MapsAggregation
@ -54,9 +54,9 @@ class EdgeCentricFCMaps(FunctionalConnectivityBase):
self, self,
maps: str, maps: str,
conn_method: str = "correlation", conn_method: str = "correlation",
conn_method_params: Optional[dict] = None, conn_method_params: dict | None = None,
masks: Union[str, dict, list[Union[dict, str]], None] = None, masks: str | dict | list[dict | str] | None = None,
name: Optional[str] = None, name: str | None = None,
) -> None: ) -> None:
self.maps = maps self.maps = maps
super().__init__( super().__init__(
@ -67,7 +67,7 @@ class EdgeCentricFCMaps(FunctionalConnectivityBase):
) )
def aggregate( def aggregate(
self, input: dict[str, Any], extra_input: Optional[dict] = None self, input: dict[str, Any], extra_input: dict | None = None
) -> dict: ) -> dict:
"""Perform maps aggregation and ETS computation. """Perform maps aggregation and ETS computation.

View file

@ -4,7 +4,7 @@
# Synchon Mandal <s.mandal@fz-juelich.de> # Synchon Mandal <s.mandal@fz-juelich.de>
# License: AGPL # License: AGPL
from typing import Any, Optional, Union from typing import Any
from ...api.decorators import register_marker from ...api.decorators import register_marker
from ..parcel_aggregation import ParcelAggregation from ..parcel_aggregation import ParcelAggregation
@ -61,13 +61,13 @@ class EdgeCentricFCParcels(FunctionalConnectivityBase):
def __init__( def __init__(
self, self,
parcellation: Union[str, list[str]], parcellation: str | list[str],
agg_method: str = "mean", agg_method: str = "mean",
agg_method_params: Optional[dict] = None, agg_method_params: dict | None = None,
conn_method: str = "correlation", conn_method: str = "correlation",
conn_method_params: Optional[dict] = None, conn_method_params: dict | None = None,
masks: Union[str, dict, list[Union[dict, str]], None] = None, masks: str | dict | list[dict | str] | None = None,
name: Optional[str] = None, name: str | None = None,
) -> None: ) -> None:
self.parcellation = parcellation self.parcellation = parcellation
super().__init__( super().__init__(
@ -80,7 +80,7 @@ class EdgeCentricFCParcels(FunctionalConnectivityBase):
) )
def aggregate( def aggregate(
self, input: dict[str, Any], extra_input: Optional[dict] = None self, input: dict[str, Any], extra_input: dict | None = None
) -> dict: ) -> dict:
"""Perform parcel aggregation and ETS computation. """Perform parcel aggregation and ETS computation.

View file

@ -4,7 +4,7 @@
# Synchon Mandal <s.mandal@fz-juelich.de> # Synchon Mandal <s.mandal@fz-juelich.de>
# License: AGPL # License: AGPL
from typing import Any, Optional, Union from typing import Any
from ...api.decorators import register_marker from ...api.decorators import register_marker
from ..sphere_aggregation import SphereAggregation from ..sphere_aggregation import SphereAggregation
@ -70,14 +70,14 @@ class EdgeCentricFCSpheres(FunctionalConnectivityBase):
def __init__( def __init__(
self, self,
coords: str, coords: str,
radius: Optional[float] = None, radius: float | None = None,
allow_overlap: bool = False, allow_overlap: bool = False,
agg_method: str = "mean", agg_method: str = "mean",
agg_method_params: Optional[dict] = None, agg_method_params: dict | None = None,
conn_method: str = "correlation", conn_method: str = "correlation",
conn_method_params: Optional[dict] = None, conn_method_params: dict | None = None,
masks: Union[str, dict, list[Union[dict, str]], None] = None, masks: str | dict | list[dict | str] | None = None,
name: Optional[str] = None, name: str | None = None,
) -> None: ) -> None:
self.coords = coords self.coords = coords
self.radius = radius self.radius = radius
@ -94,7 +94,7 @@ class EdgeCentricFCSpheres(FunctionalConnectivityBase):
) )
def aggregate( def aggregate(
self, input: dict[str, Any], extra_input: Optional[dict] = None self, input: dict[str, Any], extra_input: dict | None = None
) -> dict: ) -> dict:
"""Perform sphere aggregation and ETS computation. """Perform sphere aggregation and ETS computation.

View file

@ -4,7 +4,7 @@
# License: AGPL # License: AGPL
from abc import abstractmethod from abc import abstractmethod
from typing import Any, ClassVar, Optional, Union from typing import Any, ClassVar
from sklearn.covariance import EmpiricalCovariance, LedoitWolf from sklearn.covariance import EmpiricalCovariance, LedoitWolf
@ -62,11 +62,11 @@ class FunctionalConnectivityBase(BaseMarker):
def __init__( def __init__(
self, self,
agg_method: str = "mean", agg_method: str = "mean",
agg_method_params: Optional[dict] = None, agg_method_params: dict | None = None,
conn_method: str = "correlation", conn_method: str = "correlation",
conn_method_params: Optional[dict] = None, conn_method_params: dict | None = None,
masks: Union[str, dict, list[Union[dict, str]], None] = None, masks: str | dict | list[dict | str] | None = None,
name: Optional[str] = None, name: str | None = None,
) -> None: ) -> None:
self.agg_method = agg_method self.agg_method = agg_method
self.agg_method_params = agg_method_params self.agg_method_params = agg_method_params
@ -83,7 +83,7 @@ class FunctionalConnectivityBase(BaseMarker):
def aggregate( def aggregate(
self, self,
input: dict[str, Any], input: dict[str, Any],
extra_input: Optional[dict[str, Any]] = None, extra_input: dict[str, Any] | None = None,
) -> dict[str, Any]: ) -> dict[str, Any]:
"""Perform aggregation.""" """Perform aggregation."""
raise_error( raise_error(
@ -94,7 +94,7 @@ class FunctionalConnectivityBase(BaseMarker):
def compute( def compute(
self, self,
input: dict[str, Any], input: dict[str, Any],
extra_input: Optional[dict] = None, extra_input: dict | None = None,
) -> dict: ) -> dict:
"""Compute. """Compute.

View file

@ -3,7 +3,7 @@
# Authors: Synchon Mandal <s.mandal@fz-juelich.de> # Authors: Synchon Mandal <s.mandal@fz-juelich.de>
# License: AGPL # License: AGPL
from typing import Any, Optional, Union from typing import Any
from ...api.decorators import register_marker from ...api.decorators import register_marker
from ..maps_aggregation import MapsAggregation from ..maps_aggregation import MapsAggregation
@ -47,9 +47,9 @@ class FunctionalConnectivityMaps(FunctionalConnectivityBase):
self, self,
maps: str, maps: str,
conn_method: str = "correlation", conn_method: str = "correlation",
conn_method_params: Optional[dict] = None, conn_method_params: dict | None = None,
masks: Union[str, dict, list[Union[dict, str]], None] = None, masks: str | dict | list[dict | str] | None = None,
name: Optional[str] = None, name: str | None = None,
) -> None: ) -> None:
self.maps = maps self.maps = maps
super().__init__( super().__init__(
@ -60,7 +60,7 @@ class FunctionalConnectivityMaps(FunctionalConnectivityBase):
) )
def aggregate( def aggregate(
self, input: dict[str, Any], extra_input: Optional[dict] = None self, input: dict[str, Any], extra_input: dict | None = None
) -> dict: ) -> dict:
"""Perform maps aggregation. """Perform maps aggregation.

View file

@ -5,7 +5,7 @@
# Synchon Mandal <s.mandal@fz-juelich.de> # Synchon Mandal <s.mandal@fz-juelich.de>
# License: AGPL # License: AGPL
from typing import Any, Optional, Union from typing import Any
from ...api.decorators import register_marker from ...api.decorators import register_marker
from ..parcel_aggregation import ParcelAggregation from ..parcel_aggregation import ParcelAggregation
@ -55,13 +55,13 @@ class FunctionalConnectivityParcels(FunctionalConnectivityBase):
def __init__( def __init__(
self, self,
parcellation: Union[str, list[str]], parcellation: str | list[str],
agg_method: str = "mean", agg_method: str = "mean",
agg_method_params: Optional[dict] = None, agg_method_params: dict | None = None,
conn_method: str = "correlation", conn_method: str = "correlation",
conn_method_params: Optional[dict] = None, conn_method_params: dict | None = None,
masks: Union[str, dict, list[Union[dict, str]], None] = None, masks: str | dict | list[dict | str] | None = None,
name: Optional[str] = None, name: str | None = None,
) -> None: ) -> None:
self.parcellation = parcellation self.parcellation = parcellation
super().__init__( super().__init__(
@ -74,7 +74,7 @@ class FunctionalConnectivityParcels(FunctionalConnectivityBase):
) )
def aggregate( def aggregate(
self, input: dict[str, Any], extra_input: Optional[dict] = None self, input: dict[str, Any], extra_input: dict | None = None
) -> dict: ) -> dict:
"""Perform parcel aggregation. """Perform parcel aggregation.

View file

@ -5,7 +5,7 @@
# Synchon Mandal <s.mandal@fz-juelich.de> # Synchon Mandal <s.mandal@fz-juelich.de>
# License: AGPL # License: AGPL
from typing import Any, Optional, Union from typing import Any
from ...api.decorators import register_marker from ...api.decorators import register_marker
from ..sphere_aggregation import SphereAggregation from ..sphere_aggregation import SphereAggregation
@ -65,14 +65,14 @@ class FunctionalConnectivitySpheres(FunctionalConnectivityBase):
def __init__( def __init__(
self, self,
coords: str, coords: str,
radius: Optional[float] = None, radius: float | None = None,
allow_overlap: bool = False, allow_overlap: bool = False,
agg_method: str = "mean", agg_method: str = "mean",
agg_method_params: Optional[dict] = None, agg_method_params: dict | None = None,
conn_method: str = "correlation", conn_method: str = "correlation",
conn_method_params: Optional[dict] = None, conn_method_params: dict | None = None,
masks: Union[str, dict, list[Union[dict, str]], None] = None, masks: str | dict | list[dict | str] | None = None,
name: Optional[str] = None, name: str | None = None,
) -> None: ) -> None:
self.coords = coords self.coords = coords
self.radius = radius self.radius = radius
@ -89,7 +89,7 @@ class FunctionalConnectivitySpheres(FunctionalConnectivityBase):
) )
def aggregate( def aggregate(
self, input: dict[str, Any], extra_input: Optional[dict] = None self, input: dict[str, Any], extra_input: dict | None = None
) -> dict: ) -> dict:
"""Perform sphere aggregation. """Perform sphere aggregation.

View file

@ -3,7 +3,7 @@
# Authors: Synchon Mandal <s.mandal@fz-juelich.de> # Authors: Synchon Mandal <s.mandal@fz-juelich.de>
# License: AGPL # License: AGPL
from typing import Any, ClassVar, Optional, Union from typing import Any, ClassVar
from nilearn.maskers import NiftiMapsMasker from nilearn.maskers import NiftiMapsMasker
@ -88,11 +88,11 @@ class MapsAggregation(BaseMarker):
def __init__( def __init__(
self, self,
maps: str, maps: str,
time_method: Optional[str] = None, time_method: str | None = None,
time_method_params: Optional[dict[str, Any]] = None, time_method_params: dict[str, Any] | None = None,
masks: Union[str, dict, list[Union[dict, str]], None] = None, masks: str | dict | list[dict | str] | None = None,
on: Union[list[str], str, None] = None, on: list[str] | str | None = None,
name: Optional[str] = None, name: str | None = None,
) -> None: ) -> None:
self.maps = maps self.maps = maps
self.masks = masks self.masks = masks
@ -113,7 +113,7 @@ class MapsAggregation(BaseMarker):
self.time_method_params = time_method_params or {} self.time_method_params = time_method_params or {}
def compute( def compute(
self, input: dict[str, Any], extra_input: Optional[dict] = None self, input: dict[str, Any], extra_input: dict | None = None
) -> dict: ) -> dict:
"""Compute. """Compute.

View file

@ -4,7 +4,7 @@
# Synchon Mandal <s.mandal@fz-juelich.de> # Synchon Mandal <s.mandal@fz-juelich.de>
# License: AGPL # License: AGPL
from typing import Any, ClassVar, Optional, Union from typing import Any, ClassVar
import numpy as np import numpy as np
from nilearn.image import math_img from nilearn.image import math_img
@ -96,14 +96,14 @@ class ParcelAggregation(BaseMarker):
def __init__( def __init__(
self, self,
parcellation: Union[str, list[str]], parcellation: str | list[str],
method: str, method: str,
method_params: Optional[dict[str, Any]] = None, method_params: dict[str, Any] | None = None,
time_method: Optional[str] = None, time_method: str | None = None,
time_method_params: Optional[dict[str, Any]] = None, time_method_params: dict[str, Any] | None = None,
masks: Union[str, dict, list[Union[dict, str]], None] = None, masks: str | dict | list[dict | str] | None = None,
on: Union[list[str], str, None] = None, on: list[str] | str | None = None,
name: Optional[str] = None, name: str | None = None,
) -> None: ) -> None:
if not isinstance(parcellation, list): if not isinstance(parcellation, list):
parcellation = [parcellation] parcellation = [parcellation]
@ -128,7 +128,7 @@ class ParcelAggregation(BaseMarker):
self.time_method_params = time_method_params or {} self.time_method_params = time_method_params or {}
def compute( def compute(
self, input: dict[str, Any], extra_input: Optional[dict] = None self, input: dict[str, Any], extra_input: dict | None = None
) -> dict: ) -> dict:
"""Compute. """Compute.

View file

@ -8,7 +8,6 @@ from pathlib import Path
from typing import ( from typing import (
TYPE_CHECKING, TYPE_CHECKING,
ClassVar, ClassVar,
Optional,
) )
import nibabel as nib import nibabel as nib
@ -52,14 +51,14 @@ class AFNIReHo(metaclass=Singleton):
self, self,
input_path: Path, input_path: Path,
nneigh: int = 27, nneigh: int = 27,
neigh_rad: Optional[float] = None, neigh_rad: float | None = None,
neigh_x: Optional[float] = None, neigh_x: float | None = None,
neigh_y: Optional[float] = None, neigh_y: float | None = None,
neigh_z: Optional[float] = None, neigh_z: float | None = None,
box_rad: Optional[int] = None, box_rad: int | None = None,
box_x: Optional[int] = None, box_x: int | None = None,
box_y: Optional[int] = None, box_y: int | None = None,
box_z: Optional[int] = None, box_z: int | None = None,
) -> tuple["Nifti1Image", Path]: ) -> tuple["Nifti1Image", Path]:
"""Compute ReHo map. """Compute ReHo map.

View file

@ -8,7 +8,6 @@ from typing import (
TYPE_CHECKING, TYPE_CHECKING,
Any, Any,
ClassVar, ClassVar,
Optional,
) )
from ...typing import ConditionalDependencies, MarkerInOutMappings from ...typing import ConditionalDependencies, MarkerInOutMappings
@ -66,7 +65,7 @@ class ReHoBase(BaseMarker):
def __init__( def __init__(
self, self,
using: str, using: str,
name: Optional[str] = None, name: str | None = None,
) -> None: ) -> None:
# Validate `using` parameter # Validate `using` parameter
valid_using = [dep["using"] for dep in self._CONDITIONAL_DEPENDENCIES] valid_using = [dep["using"] for dep in self._CONDITIONAL_DEPENDENCIES]

View file

@ -3,7 +3,7 @@
# Authors: Synchon Mandal <s.mandal@fz-juelich.de> # Authors: Synchon Mandal <s.mandal@fz-juelich.de>
# License: AGPL # License: AGPL
from typing import Any, Optional, Union from typing import Any
import numpy as np import numpy as np
@ -87,9 +87,9 @@ class ReHoMaps(ReHoBase):
self, self,
maps: str, maps: str,
using: str, using: str,
reho_params: Optional[dict] = None, reho_params: dict | None = None,
masks: Union[str, dict, list[Union[dict, str]], None] = None, masks: str | dict | list[dict | str] | None = None,
name: Optional[str] = None, name: str | None = None,
) -> None: ) -> None:
# Superclass init first to validate `using` parameter # Superclass init first to validate `using` parameter
super().__init__(using=using, name=name) super().__init__(using=using, name=name)
@ -100,7 +100,7 @@ class ReHoMaps(ReHoBase):
def compute( def compute(
self, self,
input: dict[str, Any], input: dict[str, Any],
extra_input: Optional[dict[str, Any]] = None, extra_input: dict[str, Any] | None = None,
) -> dict[str, Any]: ) -> dict[str, Any]:
"""Compute. """Compute.

View file

@ -3,7 +3,7 @@
# Authors: Synchon Mandal <s.mandal@fz-juelich.de> # Authors: Synchon Mandal <s.mandal@fz-juelich.de>
# License: AGPL # License: AGPL
from typing import Any, Optional, Union from typing import Any
import numpy as np import numpy as np
@ -91,13 +91,13 @@ class ReHoParcels(ReHoBase):
def __init__( def __init__(
self, self,
parcellation: Union[str, list[str]], parcellation: str | list[str],
using: str, using: str,
reho_params: Optional[dict] = None, reho_params: dict | None = None,
agg_method: str = "mean", agg_method: str = "mean",
agg_method_params: Optional[dict] = None, agg_method_params: dict | None = None,
masks: Union[str, dict, list[Union[dict, str]], None] = None, masks: str | dict | list[dict | str] | None = None,
name: Optional[str] = None, name: str | None = None,
) -> None: ) -> None:
# Superclass init first to validate `using` parameter # Superclass init first to validate `using` parameter
super().__init__(using=using, name=name) super().__init__(using=using, name=name)
@ -110,7 +110,7 @@ class ReHoParcels(ReHoBase):
def compute( def compute(
self, self,
input: dict[str, Any], input: dict[str, Any],
extra_input: Optional[dict[str, Any]] = None, extra_input: dict[str, Any] | None = None,
) -> dict[str, Any]: ) -> dict[str, Any]:
"""Compute. """Compute.

View file

@ -3,7 +3,7 @@
# Authors: Synchon Mandal <s.mandal@fz-juelich.de> # Authors: Synchon Mandal <s.mandal@fz-juelich.de>
# License: AGPL # License: AGPL
from typing import Any, Optional, Union from typing import Any
import numpy as np import numpy as np
@ -104,13 +104,13 @@ class ReHoSpheres(ReHoBase):
self, self,
coords: str, coords: str,
using: str, using: str,
radius: Optional[float] = None, radius: float | None = None,
allow_overlap: bool = False, allow_overlap: bool = False,
reho_params: Optional[dict] = None, reho_params: dict | None = None,
agg_method: str = "mean", agg_method: str = "mean",
agg_method_params: Optional[dict] = None, agg_method_params: dict | None = None,
masks: Union[str, dict, list[Union[dict, str]], None] = None, masks: str | dict | list[dict | str] | None = None,
name: Optional[str] = None, name: str | None = None,
) -> None: ) -> None:
# Superclass init first to validate `using` parameter # Superclass init first to validate `using` parameter
super().__init__(using=using, name=name) super().__init__(using=using, name=name)
@ -125,7 +125,7 @@ class ReHoSpheres(ReHoBase):
def compute( def compute(
self, self,
input: dict[str, Any], input: dict[str, Any],
extra_input: Optional[dict[str, Any]] = None, extra_input: dict[str, Any] | None = None,
) -> dict[str, Any]: ) -> dict[str, Any]:
"""Compute. """Compute.

View file

@ -4,7 +4,7 @@
# Synchon Mandal <s.mandal@fz-juelich.de> # Synchon Mandal <s.mandal@fz-juelich.de>
# License: AGPL # License: AGPL
from typing import Any, ClassVar, Optional, Union from typing import Any, ClassVar
from ..api.decorators import register_marker from ..api.decorators import register_marker
from ..data import get_data from ..data import get_data
@ -102,15 +102,15 @@ class SphereAggregation(BaseMarker):
def __init__( def __init__(
self, self,
coords: str, coords: str,
radius: Optional[float] = None, radius: float | None = None,
allow_overlap: bool = False, allow_overlap: bool = False,
method: str = "mean", method: str = "mean",
method_params: Optional[dict[str, Any]] = None, method_params: dict[str, Any] | None = None,
time_method: Optional[str] = None, time_method: str | None = None,
time_method_params: Optional[dict[str, Any]] = None, time_method_params: dict[str, Any] | None = None,
masks: Union[str, dict, list[Union[dict, str]], None] = None, masks: str | dict | list[dict | str] | None = None,
on: Union[list[str], str, None] = None, on: list[str] | str | None = None,
name: Optional[str] = None, name: str | None = None,
) -> None: ) -> None:
self.coords = coords self.coords = coords
self.radius = radius self.radius = radius
@ -137,7 +137,7 @@ class SphereAggregation(BaseMarker):
def compute( def compute(
self, self,
input: dict[str, Any], input: dict[str, Any],
extra_input: Optional[dict] = None, extra_input: dict | None = None,
) -> dict: ) -> dict:
"""Compute. """Compute.

View file

@ -4,7 +4,7 @@
# License: AGPL # License: AGPL
from abc import abstractmethod from abc import abstractmethod
from typing import Any, ClassVar, Optional, Union from typing import Any, ClassVar
from nilearn import image as nimg from nilearn import image as nimg
@ -48,9 +48,9 @@ class TemporalSNRBase(BaseMarker):
def __init__( def __init__(
self, self,
agg_method: str = "mean", agg_method: str = "mean",
agg_method_params: Optional[dict] = None, agg_method_params: dict | None = None,
masks: Union[str, dict, list[Union[dict, str]], None] = None, masks: str | dict | list[dict | str] | None = None,
name: Optional[str] = None, name: str | None = None,
) -> None: ) -> None:
self.agg_method = agg_method self.agg_method = agg_method
self.agg_method_params = agg_method_params self.agg_method_params = agg_method_params
@ -59,7 +59,7 @@ class TemporalSNRBase(BaseMarker):
@abstractmethod @abstractmethod
def aggregate( def aggregate(
self, input: dict[str, Any], extra_input: Optional[dict] = None self, input: dict[str, Any], extra_input: dict | None = None
) -> dict[str, Any]: ) -> dict[str, Any]:
"""Perform aggregation.""" """Perform aggregation."""
raise_error( raise_error(
@ -70,7 +70,7 @@ class TemporalSNRBase(BaseMarker):
def compute( def compute(
self, self,
input: dict[str, Any], input: dict[str, Any],
extra_input: Optional[dict] = None, extra_input: dict | None = None,
) -> dict: ) -> dict:
"""Compute. """Compute.

View file

@ -3,7 +3,7 @@
# Authors: Synchon Mandal <s.mandal@fz-juelich.de> # Authors: Synchon Mandal <s.mandal@fz-juelich.de>
# License: AGPL # License: AGPL
from typing import Any, Optional, Union from typing import Any
from ...api.decorators import register_marker from ...api.decorators import register_marker
from ..maps_aggregation import MapsAggregation from ..maps_aggregation import MapsAggregation
@ -35,8 +35,8 @@ class TemporalSNRMaps(TemporalSNRBase):
def __init__( def __init__(
self, self,
maps: str, maps: str,
masks: Union[str, dict, list[Union[dict, str]], None] = None, masks: str | dict | list[dict | str] | None = None,
name: Optional[str] = None, name: str | None = None,
) -> None: ) -> None:
self.maps = maps self.maps = maps
super().__init__( super().__init__(
@ -45,7 +45,7 @@ class TemporalSNRMaps(TemporalSNRBase):
) )
def aggregate( def aggregate(
self, input: dict[str, Any], extra_input: Optional[dict] = None self, input: dict[str, Any], extra_input: dict | None = None
) -> dict: ) -> dict:
"""Perform maps aggregation. """Perform maps aggregation.

View file

@ -3,7 +3,7 @@
# Authors: Leonard Sasse <l.sasse@fz-juelich.de> # Authors: Leonard Sasse <l.sasse@fz-juelich.de>
# License: AGPL # License: AGPL
from typing import Any, Optional, Union from typing import Any
from ...api.decorators import register_marker from ...api.decorators import register_marker
from ..parcel_aggregation import ParcelAggregation from ..parcel_aggregation import ParcelAggregation
@ -40,11 +40,11 @@ class TemporalSNRParcels(TemporalSNRBase):
def __init__( def __init__(
self, self,
parcellation: Union[str, list[str]], parcellation: str | list[str],
agg_method: str = "mean", agg_method: str = "mean",
agg_method_params: Optional[dict] = None, agg_method_params: dict | None = None,
masks: Union[str, dict, list[Union[dict, str]], None] = None, masks: str | dict | list[dict | str] | None = None,
name: Optional[str] = None, name: str | None = None,
) -> None: ) -> None:
self.parcellation = parcellation self.parcellation = parcellation
super().__init__( super().__init__(
@ -55,7 +55,7 @@ class TemporalSNRParcels(TemporalSNRBase):
) )
def aggregate( def aggregate(
self, input: dict[str, Any], extra_input: Optional[dict] = None self, input: dict[str, Any], extra_input: dict | None = None
) -> dict: ) -> dict:
"""Perform parcel aggregation. """Perform parcel aggregation.

View file

@ -3,7 +3,7 @@
# Authors: Leonard Sasse <l.sasse@fz-juelich.de> # Authors: Leonard Sasse <l.sasse@fz-juelich.de>
# License: AGPL # License: AGPL
from typing import Any, Optional, Union from typing import Any
from ...api.decorators import register_marker from ...api.decorators import register_marker
from ..sphere_aggregation import SphereAggregation from ..sphere_aggregation import SphereAggregation
@ -50,12 +50,12 @@ class TemporalSNRSpheres(TemporalSNRBase):
def __init__( def __init__(
self, self,
coords: str, coords: str,
radius: Optional[float] = None, radius: float | None = None,
allow_overlap: bool = False, allow_overlap: bool = False,
agg_method: str = "mean", agg_method: str = "mean",
agg_method_params: Optional[dict] = None, agg_method_params: dict | None = None,
masks: Union[str, dict, list[Union[dict, str]], None] = None, masks: str | dict | list[dict | str] | None = None,
name: Optional[str] = None, name: str | None = None,
) -> None: ) -> None:
self.coords = coords self.coords = coords
self.radius = radius self.radius = radius
@ -70,7 +70,7 @@ class TemporalSNRSpheres(TemporalSNRBase):
) )
def aggregate( def aggregate(
self, input: dict[str, Any], extra_input: Optional[dict] = None self, input: dict[str, Any], extra_input: dict | None = None
) -> dict: ) -> dict:
"""Perform sphere aggregation. """Perform sphere aggregation.

View file

@ -8,7 +8,7 @@
# Amir Omidvarnia <a.omidvarnia@fz-juelich.de> # Amir Omidvarnia <a.omidvarnia@fz-juelich.de>
# License: AGPL # License: AGPL
from typing import Callable, Optional, Union from collections.abc import Callable
import numpy as np import numpy as np
import pandas as pd import pandas as pd
@ -19,8 +19,8 @@ from ..utils import raise_error
def _ets( def _ets(
bold_ts: np.ndarray, bold_ts: np.ndarray,
roi_names: Union[None, list[str]] = None, roi_names: None | list[str] = None,
) -> tuple[np.ndarray, Optional[list[str]]]: ) -> tuple[np.ndarray, list[str] | None]:
"""Compute the edge-wise time series based on BOLD time series. """Compute the edge-wise time series based on BOLD time series.
Take a timeseries of brain areas, and calculate timeseries for each Take a timeseries of brain areas, and calculate timeseries for each
@ -73,7 +73,8 @@ def _ets(
) )
_roi_names = np.array(roi_names) _roi_names = np.array(roi_names)
edge_names = [ edge_names = [
"~".join([x, y]) for x, y in zip(_roi_names[u], _roi_names[v]) "~".join([x, y])
for x, y in zip(_roi_names[u], _roi_names[v], strict=False)
] ]
return ets, edge_names return ets, edge_names
@ -81,7 +82,7 @@ def _ets(
def _correlate_dataframes( def _correlate_dataframes(
df1: pd.DataFrame, df1: pd.DataFrame,
df2: pd.DataFrame, df2: pd.DataFrame,
method: Union[str, Callable] = "pearson", method: str | Callable = "pearson",
) -> pd.DataFrame: ) -> pd.DataFrame:
"""Column-wise correlations between two dataframes. """Column-wise correlations between two dataframes.

View file

@ -3,8 +3,6 @@
# Authors: Synchon Mandal <s.mandal@fz-juelich.de> # Authors: Synchon Mandal <s.mandal@fz-juelich.de>
# License: AGPL # License: AGPL
from typing import Optional
import numpy as np import numpy as np
import pandas as pd import pandas as pd
@ -17,7 +15,7 @@ __all__ = ["normalize", "reweight"]
def normalize( def normalize(
storage: StorageLike, storage: StorageLike,
features: dict[str, dict[str, Optional[str]]], features: dict[str, dict[str, str | None]],
kind: str, kind: str,
) -> pd.DataFrame: # pragma: no cover ) -> pd.DataFrame: # pragma: no cover
"""Read stored brainprint data and normalize either surfaces or volumes. """Read stored brainprint data and normalize either surfaces or volumes.
@ -87,8 +85,8 @@ def normalize(
def reweight( def reweight(
storage: StorageLike, storage: StorageLike,
feature_name: Optional[str] = None, feature_name: str | None = None,
feature_md5: Optional[str] = None, feature_md5: str | None = None,
) -> pd.DataFrame: # pragma: no cover ) -> pd.DataFrame: # pragma: no cover
"""Read stored brainprint data and reweight eigenvalues. """Read stored brainprint data and reweight eigenvalues.

View file

@ -3,8 +3,6 @@
# Authors: Synchon Mandal <s.mandal@fz-juelich.de> # Authors: Synchon Mandal <s.mandal@fz-juelich.de>
# License: AGPL # License: AGPL
from typing import Optional
import numpy as np import numpy as np
import pandas as pd import pandas as pd
@ -18,11 +16,11 @@ __all__ = ["read_transform"]
def read_transform( def read_transform(
storage: StorageLike, storage: StorageLike,
transform: str, transform: str,
feature_name: Optional[str] = None, feature_name: str | None = None,
feature_md5: Optional[str] = None, feature_md5: str | None = None,
nan_policy: Optional[str] = "bypass", nan_policy: str | None = "bypass",
transform_args: Optional[tuple] = None, transform_args: tuple | None = None,
transform_kw_args: Optional[dict] = None, transform_kw_args: dict | None = None,
) -> pd.DataFrame: ) -> pd.DataFrame:
"""Read stored feature and transform to specific statistical output. """Read stored feature and transform to specific statistical output.

View file

@ -6,7 +6,6 @@
from collections import Counter from collections import Counter
from pathlib import Path from pathlib import Path
from typing import Optional
from ..datareader import DefaultDataReader from ..datareader import DefaultDataReader
from ..pipeline import DataObjectDumper, PipelineStepMixin, WorkDirManager from ..pipeline import DataObjectDumper, PipelineStepMixin, WorkDirManager
@ -41,9 +40,9 @@ class MarkerCollection:
def __init__( def __init__(
self, self,
markers: list[MarkerLike], markers: list[MarkerLike],
datareader: Optional[PipelineStepMixin] = None, datareader: PipelineStepMixin | None = None,
preprocessors: Optional[list[PreprocessorLike]] = None, preprocessors: list[PreprocessorLike] | None = None,
storage: Optional[StorageLike] = None, storage: StorageLike | None = None,
): ):
# Check that the markers have different names # Check that the markers have different names
marker_names = [m.name for m in markers] marker_names = [m.name for m in markers]
@ -60,7 +59,7 @@ class MarkerCollection:
self._preprocessors = preprocessors self._preprocessors = preprocessors
self._storage = storage self._storage = storage
def fit(self, input: dict[str, dict]) -> Optional[dict]: def fit(self, input: dict[str, dict]) -> dict | None:
"""Fit the pipeline. """Fit the pipeline.
Parameters Parameters

View file

@ -7,7 +7,6 @@
import importlib import importlib
from collections.abc import Mapping from collections.abc import Mapping
from typing import Optional, Union
from ..typing import DataGrabberLike, MarkerLike, PreprocessorLike, StorageLike from ..typing import DataGrabberLike, MarkerLike, PreprocessorLike, StorageLike
from ..utils import logger, raise_error from ..utils import logger, raise_error
@ -119,7 +118,7 @@ class PipelineComponentRegistry(metaclass=Singleton):
return self._steps return self._steps
@property @property
def components(self) -> Mapping[str, Mapping[str, Union[str, type]]]: def components(self) -> Mapping[str, Mapping[str, str | type]]:
"""Get registered components for valid pipeline steps.""" """Get registered components for valid pipeline steps."""
return self._components return self._components
@ -238,8 +237,8 @@ class PipelineComponentRegistry(metaclass=Singleton):
step: str, step: str,
name: str, name: str,
baseclass: type, baseclass: type,
init_params: Optional[dict] = None, init_params: dict | None = None,
) -> Union[DataGrabberLike, PreprocessorLike, MarkerLike, StorageLike]: ) -> DataGrabberLike | PreprocessorLike | MarkerLike | StorageLike:
"""Build an instance of class registered as ``name``. """Build an instance of class registered as ``name``.
Parameters Parameters

View file

@ -5,7 +5,6 @@
import pickle import pickle
from pathlib import Path from pathlib import Path
from typing import Union
import nibabel import nibabel
import pytest import pytest
@ -36,9 +35,9 @@ from junifer.utils import config
], ],
) )
def test_dispatcher_addition_errors( def test_dispatcher_addition_errors(
dispatcher: Union[AssetDumperDispatcher, AssetLoaderDispatcher], dispatcher: AssetDumperDispatcher | AssetLoaderDispatcher,
inbuilt_key: Union[str, type], inbuilt_key: str | type,
ext_key: Union[str, type], ext_key: str | type,
val: type, val: type,
) -> None: ) -> None:
"""Test asset dumper / loader addition errors. """Test asset dumper / loader addition errors.
@ -70,9 +69,9 @@ def test_dispatcher_addition_errors(
], ],
) )
def test_dispatcher_removal_errors( def test_dispatcher_removal_errors(
dispatcher: Union[AssetDumperDispatcher, AssetLoaderDispatcher], dispatcher: AssetDumperDispatcher | AssetLoaderDispatcher,
inbuilt_key: Union[str, type], inbuilt_key: str | type,
ext_key: Union[str, type], ext_key: str | type,
) -> None: ) -> None:
"""Test asset dumper / loader removal errors. """Test asset dumper / loader removal errors.

View file

@ -4,8 +4,6 @@
# Synchon Mandal <s.mandal@fz-juelich.de> # Synchon Mandal <s.mandal@fz-juelich.de>
# License: AGPL # License: AGPL
from typing import Union
import pytest import pytest
from junifer.pipeline.update_meta_mixin import UpdateMetaMixin from junifer.pipeline.update_meta_mixin import UpdateMetaMixin
@ -23,7 +21,7 @@ from junifer.pipeline.update_meta_mixin import UpdateMetaMixin
def test_UpdateMetaMixin( def test_UpdateMetaMixin(
input: dict, input: dict,
step_name: str, step_name: str,
dependencies: Union[set, list, str, None], dependencies: set | list | str | None,
expected: set, expected: set,
) -> None: ) -> None:
"""Test UpdateMetaMixin. """Test UpdateMetaMixin.

View file

@ -4,9 +4,6 @@
# Synchon Mandal <s.mandal@fz-juelich.de> # Synchon Mandal <s.mandal@fz-juelich.de>
# License: AGPL # License: AGPL
from typing import Union
__all__ = ["UpdateMetaMixin"] __all__ = ["UpdateMetaMixin"]
@ -15,7 +12,7 @@ class UpdateMetaMixin:
def update_meta( def update_meta(
self, self,
input: Union[dict, list[dict]], input: dict | list[dict],
step_name: str, step_name: str,
) -> None: ) -> None:
"""Update metadata. """Update metadata.
@ -51,6 +48,6 @@ class UpdateMetaMixin:
# Update step dependencies # Update step dependencies
dependencies = getattr(self, "_DEPENDENCIES", set()) dependencies = getattr(self, "_DEPENDENCIES", set())
if dependencies is not None: if dependencies is not None:
if not isinstance(dependencies, (set, list)): if not isinstance(dependencies, set | list):
dependencies = {dependencies} dependencies = {dependencies}
entry["meta"]["dependencies"].update(dependencies) entry["meta"]["dependencies"].update(dependencies)

View file

@ -5,7 +5,7 @@
# License: AGPL # License: AGPL
import subprocess import subprocess
from typing import Any, Optional from typing import Any
from junifer.utils.logging import raise_error, warn_with_log from junifer.utils.logging import raise_error, warn_with_log
@ -71,7 +71,7 @@ def check_ext_dependencies(
return found return found
def _check_afni(commands: Optional[list[str]] = None) -> bool: def _check_afni(commands: list[str] | None = None) -> bool:
"""Check if AFNI is present in the system. """Check if AFNI is present in the system.
Parameters Parameters
@ -131,7 +131,7 @@ def _check_afni(commands: Optional[list[str]] = None) -> bool:
return afni_found return afni_found
def _check_fsl(commands: Optional[list[str]] = None) -> bool: def _check_fsl(commands: list[str] | None = None) -> bool:
"""Check if FSL is present in the system. """Check if FSL is present in the system.
Parameters Parameters
@ -195,7 +195,7 @@ def _check_fsl(commands: Optional[list[str]] = None) -> bool:
return fsl_found return fsl_found
def _check_ants(commands: Optional[list[str]] = None) -> bool: def _check_ants(commands: list[str] | None = None) -> bool:
"""Check if ANTs is present in the system. """Check if ANTs is present in the system.
Parameters Parameters
@ -255,7 +255,7 @@ def _check_ants(commands: Optional[list[str]] = None) -> bool:
return ants_found return ants_found
def _check_freesurfer(commands: Optional[list[str]] = None) -> bool: def _check_freesurfer(commands: list[str] | None = None) -> bool:
"""Check if FreeSurfer is present in the system. """Check if FreeSurfer is present in the system.
Parameters Parameters

View file

@ -7,7 +7,6 @@
import shutil import shutil
import tempfile import tempfile
from pathlib import Path from pathlib import Path
from typing import Optional, Union
from ..utils import logger from ..utils import logger
from ..utils.singleton import Singleton from ..utils.singleton import Singleton
@ -46,7 +45,7 @@ class WorkDirManager(metaclass=Singleton):
""" """
def __init__( def __init__(
self, workdir: Optional[Union[str, Path]] = None, cleanup: bool = True self, workdir: str | Path | None = None, cleanup: bool = True
) -> None: ) -> None:
"""Initialize the class.""" """Initialize the class."""
self._workdir = Path(workdir) if isinstance(workdir, str) else workdir self._workdir = Path(workdir) if isinstance(workdir, str) else workdir
@ -97,7 +96,7 @@ class WorkDirManager(metaclass=Singleton):
return self._workdir # type: ignore return self._workdir # type: ignore
@workdir.setter @workdir.setter
def workdir(self, path: Union[str, Path]) -> None: def workdir(self, path: str | Path) -> None:
"""Set working directory. """Set working directory.
The directory path is created if it doesn't exist yet. The directory path is created if it doesn't exist yet.
@ -130,7 +129,7 @@ class WorkDirManager(metaclass=Singleton):
return self._elementdir # type: ignore return self._elementdir # type: ignore
def get_element_tempdir( def get_element_tempdir(
self, prefix: Optional[str] = None, suffix: Optional[str] = None self, prefix: str | None = None, suffix: str | None = None
) -> Path: ) -> Path:
"""Get an element-scoped temporary directory. """Get an element-scoped temporary directory.
@ -203,12 +202,12 @@ class WorkDirManager(metaclass=Singleton):
self._elementdir = None self._elementdir = None
@property @property
def root_tempdir(self) -> Optional[Path]: def root_tempdir(self) -> Path | None:
"""Get root temporary directory.""" """Get root temporary directory."""
return self._root_tempdir return self._root_tempdir
def get_tempdir( def get_tempdir(
self, prefix: Optional[str] = None, suffix: Optional[str] = None self, prefix: str | None = None, suffix: str | None = None
) -> Path: ) -> Path:
"""Get a component-scoped temporary directory. """Get a component-scoped temporary directory.

View file

@ -9,8 +9,6 @@ from collections.abc import Sequence
from typing import ( from typing import (
Any, Any,
ClassVar, ClassVar,
Optional,
Union,
) )
import nibabel as nib import nibabel as nib
@ -63,10 +61,10 @@ class TemporalFilter(BasePreprocessor):
self, self,
detrend: bool = True, detrend: bool = True,
standardize: bool = True, standardize: bool = True,
low_pass: Optional[float] = None, low_pass: float | None = None,
high_pass: Optional[float] = None, high_pass: float | None = None,
t_r: Optional[float] = None, t_r: float | None = None,
masks: Union[str, dict, list[Union[dict, str]], None] = None, masks: str | dict | list[dict | str] | None = None,
) -> None: ) -> None:
"""Initialize the class.""" """Initialize the class."""
self.detrend = detrend self.detrend = detrend
@ -102,7 +100,7 @@ class TemporalFilter(BasePreprocessor):
def preprocess( def preprocess(
self, self,
input: dict[str, Any], input: dict[str, Any],
extra_input: Optional[dict[str, Any]] = None, extra_input: dict[str, Any] | None = None,
) -> dict[str, Any]: ) -> dict[str, Any]:
"""Preprocess. """Preprocess.

View file

@ -4,7 +4,7 @@
# License: AGPL # License: AGPL
from collections.abc import Sequence from collections.abc import Sequence
from typing import Any, ClassVar, Optional from typing import Any, ClassVar
import nibabel as nib import nibabel as nib
import nilearn.image as nimg import nilearn.image as nimg
@ -51,9 +51,9 @@ class TemporalSlicer(BasePreprocessor):
def __init__( def __init__(
self, self,
start: float, start: float,
stop: Optional[float], stop: float | None,
duration: Optional[float] = None, duration: float | None = None,
t_r: Optional[float] = None, t_r: float | None = None,
) -> None: ) -> None:
"""Initialize the class.""" """Initialize the class."""
if start < 0: if start < 0:
@ -68,7 +68,7 @@ class TemporalSlicer(BasePreprocessor):
def preprocess( def preprocess(
self, self,
input: dict[str, Any], input: dict[str, Any],
extra_input: Optional[dict[str, Any]] = None, extra_input: dict[str, Any] | None = None,
) -> dict[str, Any]: ) -> dict[str, Any]:
"""Preprocess. """Preprocess.

View file

@ -6,7 +6,7 @@
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from collections.abc import Sequence from collections.abc import Sequence
from typing import Any, ClassVar, Optional, Union from typing import Any, ClassVar
from ..pipeline import PipelineStepMixin, UpdateMetaMixin from ..pipeline import PipelineStepMixin, UpdateMetaMixin
from ..utils import logger, raise_error from ..utils import logger, raise_error
@ -43,8 +43,8 @@ class BasePreprocessor(ABC, PipelineStepMixin, UpdateMetaMixin):
def __init__( def __init__(
self, self,
on: Optional[Union[list[str], str]] = None, on: list[str] | str | None = None,
required_data_types: Optional[Union[list[str], str]] = None, required_data_types: list[str] | str | None = None,
) -> None: ) -> None:
"""Initialize the class.""" """Initialize the class."""
# Check for missing data types attributes # Check for missing data types attributes
@ -119,7 +119,7 @@ class BasePreprocessor(ABC, PipelineStepMixin, UpdateMetaMixin):
def preprocess( def preprocess(
self, self,
input: dict[str, Any], input: dict[str, Any],
extra_input: Optional[dict[str, Any]] = None, extra_input: dict[str, Any] | None = None,
) -> dict[str, Any]: ) -> dict[str, Any]:
"""Preprocess. """Preprocess.

View file

@ -9,8 +9,6 @@ from collections.abc import Sequence
from typing import ( from typing import (
Any, Any,
ClassVar, ClassVar,
Optional,
Union,
) )
import nibabel as nib import nibabel as nib
@ -180,17 +178,17 @@ class fMRIPrepConfoundRemover(BasePreprocessor):
def __init__( def __init__(
self, self,
strategy: Optional[dict[str, Union[str, bool]]] = None, strategy: dict[str, str | bool] | None = None,
spike: Optional[float] = None, spike: float | None = None,
scrub: Optional[int] = None, scrub: int | None = None,
fd_threshold: Optional[float] = None, fd_threshold: float | None = None,
std_dvars_threshold: Optional[float] = None, std_dvars_threshold: float | None = None,
detrend: bool = True, detrend: bool = True,
standardize: bool = True, standardize: bool = True,
low_pass: Optional[float] = None, low_pass: float | None = None,
high_pass: Optional[float] = None, high_pass: float | None = None,
t_r: Optional[float] = None, t_r: float | None = None,
masks: Union[str, dict, list[Union[dict, str]], None] = None, masks: str | dict | list[dict | str] | None = None,
) -> None: ) -> None:
"""Initialize the class.""" """Initialize the class."""
if strategy is None: if strategy is None:
@ -593,7 +591,7 @@ class fMRIPrepConfoundRemover(BasePreprocessor):
def preprocess( def preprocess(
self, self,
input: dict[str, Any], input: dict[str, Any],
extra_input: Optional[dict[str, Any]] = None, extra_input: dict[str, Any] | None = None,
) -> dict[str, Any]: ) -> dict[str, Any]:
"""Preprocess. """Preprocess.

View file

@ -83,7 +83,7 @@ def test_fMRIPrepConfoundRemover__map_adhoc_to_fmriprep() -> None:
] ]
# Build mappings dictionary # Build mappings dictionary
mappings = dict(zip(adhoc_names, fmriprep_names)) mappings = dict(zip(adhoc_names, fmriprep_names, strict=False))
input = { input = {
"mappings": {"fmriprep": mappings}, "mappings": {"fmriprep": mappings},
"data": adhoc_df, "data": adhoc_df,
@ -238,7 +238,7 @@ def test_fMRIPrepConfoundRemover__pick_confounds_adhoc() -> None:
] ]
# Build mappings dictionary # Build mappings dictionary
mappings = dict(zip(adhoc_names, fmriprep_names)) mappings = dict(zip(adhoc_names, fmriprep_names, strict=False))
input = { input = {
"mappings": {"fmriprep": mappings}, "mappings": {"fmriprep": mappings},
"data": adhoc_df, "data": adhoc_df,

Some files were not shown because too many files have changed in this diff Show more