Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python: ["3.9", "3.10", "3.11", "3.12", "3.13"]
python: ["3.10", "3.11", "3.12", "3.13"]
fail-fast: false

runs-on: ${{ matrix.os }}
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ repos:
rev: v3.20.0
hooks:
- id: pyupgrade
args: ['--py39-plus']
args: ['--py310-plus']

ci:
autoupdate_commit_msg: Autoupdate pre-commit hooks
Expand Down
2 changes: 1 addition & 1 deletion docs/examples/plot_3d_to_2d.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ def plot_batch(sampler):
batch = tio.utils.get_first_item(loader)

_, axes = plt.subplots(4, 4, figsize=(12, 10))
for ax, im in zip(axes.flatten(), batch['t1']['data']):
for ax, im in zip(axes.flatten(), batch['t1']['data'], strict=True):
ax.imshow(im.squeeze(), cmap='gray')
plt.suptitle(sampler.__class__.__name__)
plt.tight_layout()
Expand Down
10 changes: 7 additions & 3 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ bump-python:
)
pyproject_path.write_text(pyproject_text)

deprecate-python:
deprecate-python-in-files:
#!/usr/bin/env -S uv run --script
# /// script
# dependencies = [
Expand Down Expand Up @@ -121,11 +121,15 @@ deprecate-python:
)
tests_workflow_path.write_text(tests_workflow)

quality_cmd := "uv run --group quality"

deprecate-python: deprecate-python-in-files
uv run pre-commit run --all-files pyupgrade
{{quality_cmd}} -- ruff check --fix src docs tests

push:
git push && git push --tags

quality_cmd := "uv run --group quality"

types:
{{quality_cmd}} -- tox -e types

Expand Down
3 changes: 1 addition & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ classifiers = [
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
Expand All @@ -31,7 +30,7 @@ classifiers = [
"Typing :: Typed",
]
keywords = ["medical", "image processing", "pytorch", "augmentation", "mri"]
requires-python = ">=3.9"
requires-python = ">=3.10"
dependencies = [
"deprecated>=1.2",
"einops>=0.3",
Expand Down
2 changes: 1 addition & 1 deletion src/torchio/data/dataset.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from __future__ import annotations

import copy
from collections.abc import Callable
from collections.abc import Iterable
from collections.abc import Sequence
from typing import Callable

from torch.utils.data import Dataset

Expand Down
4 changes: 2 additions & 2 deletions src/torchio/data/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

import warnings
from collections import Counter
from collections.abc import Callable
from collections.abc import Sequence
from pathlib import Path
from typing import Any
from typing import Callable

import humanize
import nibabel as nib
Expand Down Expand Up @@ -424,7 +424,7 @@ def flip_axis(axis: str) -> str:
labels = 'LRPAISTBDV'
first = labels[::2]
last = labels[1::2]
flip_dict = dict(zip(first + last, last + first))
flip_dict = dict(zip(first + last, last + first, strict=True))
axis = axis[0].upper()
flipped_axis = flip_dict.get(axis)
if flipped_axis is None:
Expand Down
6 changes: 3 additions & 3 deletions src/torchio/data/inference/aggregator.py
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ def add_batch(
self._initialize_output_tensor(batch)
assert isinstance(self._output_tensor, torch.Tensor)
if self.overlap_mode == 'crop':
for patch, location in zip(batch, locations_array):
for patch, location in zip(batch, locations_array, strict=True):
cropped_patch, new_location = self._crop_patch(
patch,
location,
Expand All @@ -179,7 +179,7 @@ def add_batch(
elif self.overlap_mode == 'average':
self._initialize_avgmask_tensor(batch)
assert isinstance(self._avgmask_tensor, torch.Tensor)
for patch, location in zip(batch, locations):
for patch, location in zip(batch, locations, strict=True):
i_ini, j_ini, k_ini, i_fin, j_fin, k_fin = location
self._output_tensor[
:,
Expand Down Expand Up @@ -210,7 +210,7 @@ def add_batch(
if self._avgmask_tensor.dtype != torch.float32:
self._avgmask_tensor = self._avgmask_tensor.float()

for patch, location in zip(batch, locations):
for patch, location in zip(batch, locations, strict=True):
i_ini, j_ini, k_ini, i_fin, j_fin, k_fin = location

patch = patch * self._hann_window
Expand Down
2 changes: 1 addition & 1 deletion src/torchio/data/loader.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from __future__ import annotations

from collections.abc import Callable
from typing import Any
from typing import Callable
from typing import TypeVar

import numpy as np
Expand Down
2 changes: 1 addition & 1 deletion src/torchio/data/sampler/grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ def _get_patches_locations(
# [3, 8],
# [5, 10]]
indices = []
zipped = zip(image_size, patch_size, patch_overlap)
zipped = zip(image_size, patch_size, patch_overlap, strict=True)
for im_size_dim, patch_size_dim, patch_overlap_dim in zipped:
end = im_size_dim + 1 - patch_size_dim
step = patch_size_dim - patch_overlap_dim
Expand Down
2 changes: 1 addition & 1 deletion src/torchio/data/sampler/label.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ def get_probabilities_from_label_map(
probability_map = torch.zeros_like(label_map)
label_probs = torch.Tensor(list(label_probabilities_dict.values()))
normalized_probs = label_probs / label_probs.sum()
iterable = zip(label_probabilities_dict, normalized_probs)
iterable = zip(label_probabilities_dict, normalized_probs, strict=True)
for label, label_probability in iterable:
if multichannel:
mask = label_map[label]
Expand Down
2 changes: 1 addition & 1 deletion src/torchio/data/sampler/sampler.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ def _get_crop_transform(
crop_ini = index_ini_array.tolist()
crop_fin = (shape - index_fin).tolist()
start = ()
cropping = sum(zip(crop_ini, crop_fin), start) # type: ignore[arg-type]
cropping = sum(zip(crop_ini, crop_fin, strict=True), start) # type: ignore[arg-type]
return Crop(cropping) # type: ignore[arg-type]

def __call__(
Expand Down
2 changes: 1 addition & 1 deletion src/torchio/datasets/ixi.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ def _get_subjects_list(root):
raise FileNotFoundError(message)

subjects = []
for image_path, label_path in zip(image_paths, label_paths):
for image_path, label_path in zip(image_paths, label_paths, strict=True):
subject_id = get_subject_id(image_path)
subject_dict = {}
subject_dict['image'] = ScalarImage(image_path)
Expand Down
2 changes: 1 addition & 1 deletion src/torchio/datasets/medmnist.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def __init__(self, split, **kwargs):
images = npz_file[f'{split}_images']
labels = npz_file[f'{split}_labels']
subjects = []
for image, label in zip(images, labels):
for image, label in zip(images, labels, strict=True):
image = ScalarImage(tensor=image[np.newaxis])
subject = Subject(image=image, labels=torch.from_numpy(label))
subjects.append(subject)
Expand Down
2 changes: 1 addition & 1 deletion src/torchio/datasets/slicer.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def __init__(self, name='MRHead'):
except KeyError as e:
message = f'Invalid name "{name}". Valid names are: {", ".join(URLS_DICT)}'
raise ValueError(message) from e
for filename, url_file in zip(filenames, url_files):
for filename, url_file in zip(filenames, url_files, strict=True):
filename = filename.replace('-', '_')
url = urllib.parse.urljoin(SLICER_URL, url_file)
download_root = get_torchio_cache_dir() / 'slicer'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from collections import defaultdict
from typing import Union

import numpy as np
import torch
Expand Down Expand Up @@ -36,7 +35,7 @@ class RandomBiasField(RandomTransform, IntensityTransform):

def __init__(
self,
coefficients: Union[float, tuple[float, float]] = 0.5,
coefficients: float | tuple[float, float] = 0.5,
order: int = 3,
**kwargs,
):
Expand Down Expand Up @@ -89,8 +88,8 @@ class BiasField(IntensityTransform):

def __init__(
self,
coefficients: Union[list[float], dict[str, list[float]]],
order: Union[int, dict[str, int]],
coefficients: list[float] | dict[str, list[float]],
order: int | dict[str, int],
**kwargs,
):
super().__init__(**kwargs)
Expand Down
7 changes: 3 additions & 4 deletions src/torchio/transforms/augmentation/intensity/random_blur.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from collections import defaultdict
from typing import Union

import numpy as np
import scipy.ndimage as ndi
Expand Down Expand Up @@ -32,7 +31,7 @@ class RandomBlur(RandomTransform, IntensityTransform):
keyword arguments.
"""

def __init__(self, std: Union[float, tuple[float, float]] = (0, 2), **kwargs):
def __init__(self, std: float | tuple[float, float] = (0, 2), **kwargs):
super().__init__(**kwargs)
self.std_ranges = self.parse_params(std, None, 'std', min_constraint=0)

Expand Down Expand Up @@ -68,7 +67,7 @@ class Blur(IntensityTransform):

def __init__(
self,
std: Union[TypeTripletFloat, dict[str, TypeTripletFloat]],
std: TypeTripletFloat | dict[str, TypeTripletFloat],
**kwargs,
):
super().__init__(**kwargs)
Expand All @@ -85,7 +84,7 @@ def apply_transform(self, subject: Subject) -> Subject:
stds_channels: np.ndarray
stds_channels = np.tile(stds, repets) # type: ignore[arg-type]
transformed_tensors = []
for std, channel in zip(stds_channels, image.data):
for std, channel in zip(stds_channels, image.data, strict=True):
transformed_tensor = blur(
channel,
image.spacing,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ def apply_transform(self, subject: Subject) -> Subject:
gammas = to_tuple(gamma, length=len(image.data))
transformed_tensors = []
image.set_data(image.data.float())
for gamma, tensor in zip(gammas, image.data):
for gamma, tensor in zip(gammas, image.data, strict=True):
if self.invert_transform:
correction = power(tensor, 1 - gamma)
transformed_tensor = tensor * correction
Expand Down
18 changes: 9 additions & 9 deletions src/torchio/transforms/augmentation/intensity/random_motion.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from collections import defaultdict
from collections.abc import Sequence
from typing import Union

import numpy as np
import SimpleITK as sitk
Expand Down Expand Up @@ -49,8 +48,8 @@ class RandomMotion(RandomTransform, IntensityTransform, FourierTransform):

def __init__(
self,
degrees: Union[float, tuple[float, float]] = 10,
translation: Union[float, tuple[float, float]] = 10, # in mm
degrees: float | tuple[float, float] = 10,
translation: float | tuple[float, float] = 10, # in mm
num_transforms: int = 2,
image_interpolation: str = 'linear',
**kwargs,
Expand Down Expand Up @@ -145,10 +144,10 @@ class Motion(IntensityTransform, FourierTransform):

def __init__(
self,
degrees: Union[TypeTripletFloat, dict[str, TypeTripletFloat]],
translation: Union[TypeTripletFloat, dict[str, TypeTripletFloat]],
times: Union[Sequence[float], dict[str, Sequence[float]]],
image_interpolation: Union[Sequence[str], dict[str, Sequence[str]]],
degrees: TypeTripletFloat | dict[str, TypeTripletFloat],
translation: TypeTripletFloat | dict[str, TypeTripletFloat],
times: Sequence[float] | dict[str, Sequence[float]],
image_interpolation: Sequence[str] | dict[str, Sequence[str]],
**kwargs,
):
super().__init__(**kwargs)
Expand Down Expand Up @@ -212,7 +211,8 @@ def get_rigid_transforms(
center_lps = image.TransformContinuousIndexToPhysicalPoint(center_ijk)
identity = np.eye(4)
matrices = [identity]
for degrees, translation in zip(degrees_params, translation_params):
zipped = zip(degrees_params, translation_params, strict=True)
for degrees, translation in zipped:
radians = np.radians(degrees).tolist()
motion = sitk.Euler3DTransform()
motion.SetCenter(center_lps)
Expand Down Expand Up @@ -291,7 +291,7 @@ def add_artifact(
indices: list[int] = indices_array.tolist() # type: ignore[assignment]
indices.append(last_index)
ini = 0
for spectrum, fin in zip(spectra, indices):
for spectrum, fin in zip(spectra, indices, strict=True):
result_spectrum[..., ini:fin] = spectrum[..., ini:fin]
ini = fin
result_image = self.inv_fourier_transform(result_spectrum).real.float()
Expand Down
11 changes: 5 additions & 6 deletions src/torchio/transforms/augmentation/intensity/random_noise.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from collections import defaultdict
from collections.abc import Sequence
from typing import Union

import torch

Expand Down Expand Up @@ -33,8 +32,8 @@ class RandomNoise(RandomTransform, IntensityTransform):

def __init__(
self,
mean: Union[float, tuple[float, float]] = 0,
std: Union[float, tuple[float, float]] = (0, 0.25),
mean: float | tuple[float, float] = 0,
std: float | tuple[float, float] = (0, 0.25),
**kwargs,
):
super().__init__(**kwargs)
Expand Down Expand Up @@ -85,9 +84,9 @@ class Noise(IntensityTransform):

def __init__(
self,
mean: Union[float, dict[str, float]],
std: Union[float, dict[str, float]],
seed: Union[int, Sequence[int]],
mean: float | dict[str, float],
std: float | dict[str, float],
seed: int | Sequence[int],
**kwargs,
):
super().__init__(**kwargs)
Expand Down
9 changes: 4 additions & 5 deletions src/torchio/transforms/augmentation/intensity/random_spike.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from collections import defaultdict
from numbers import Number
from typing import Union

import numpy as np
import torch
Expand Down Expand Up @@ -42,8 +41,8 @@ class RandomSpike(RandomTransform, IntensityTransform, FourierTransform):

def __init__(
self,
num_spikes: Union[int, tuple[int, int]] = 1,
intensity: Union[float, tuple[float, float]] = (1, 3),
num_spikes: int | tuple[int, int] = 1,
intensity: float | tuple[float, float] = (1, 3),
**kwargs,
):
super().__init__(**kwargs)
Expand Down Expand Up @@ -109,8 +108,8 @@ class Spike(IntensityTransform, FourierTransform):

def __init__(
self,
spikes_positions: Union[np.ndarray, dict[str, np.ndarray]],
intensity: Union[float, dict[str, float]],
spikes_positions: np.ndarray | dict[str, np.ndarray],
intensity: float | dict[str, float],
**kwargs,
):
super().__init__(**kwargs)
Expand Down
2 changes: 1 addition & 1 deletion src/torchio/transforms/augmentation/random_transform.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def _get_random_seed() -> int:
@staticmethod
def sample_uniform_sextet(params: TypeSextetFloat) -> TypeTripletFloat:
results = []
for a, b in zip(params[::2], params[1::2]):
for a, b in zip(params[::2], params[1::2], strict=True):
results.append(RandomTransform.sample_uniform(a, b))
sx, sy, sz = results
return sx, sy, sz
Loading
Loading