Skip to content

Commit

Permalink
lint: ruff
Browse files Browse the repository at this point in the history
  • Loading branch information
paquiteau committed Oct 16, 2024
1 parent 80fa50b commit 0983eb1
Show file tree
Hide file tree
Showing 21 changed files with 61 additions and 47 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
- name: Linter
run: |
black --check src tests
ruff .
ruff check .
- name: Annotate locations with typos
uses: codespell-project/codespell-problem-matcher@v1
- name: Codespell
Expand Down
3 changes: 2 additions & 1 deletion examples/example_anat_EPI.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@
#
# The simulation acquires
# the data describe in a phantom. A phantom consists of fuzzy segmentation of
# head tissue, and their MR intrisic parameters (density, T1, T2, T2*, magnetic susceptibilities)
# head tissue, and their MR intrisic parameters

Check failure on line 44 in examples/example_anat_EPI.py

View workflow job for this annotation

GitHub Actions / test (3.10, ubuntu-latest)

intrisic ==> intrinsic
# (density, T1, T2, T2*, magnetic susceptibilities)
#
# Here we use Brainweb reference mask and values for convenience.

Expand Down
10 changes: 5 additions & 5 deletions examples/example_generate_phantom.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@
Example for generating a phantom and visualizing the contrast at different TE values.
"""

import numpy as np
from snake.core.phantom import Phantom
from snake.core.engine.utils import get_ideal_phantom
from snake.core.simulation import SimConfig, GreConfig


# +
# This notebook has interactive widgets, run it in google colab or locally to enjoy it fully
# -

# %%
# This notebook has interactive widgets, run it in google colab or locally to
# enjoy it fully
#

# %%
shape = (181, 217, 181)
TR = 100
TE = 25
Expand Down
1 change: 0 additions & 1 deletion examples/example_gpu_anat_spirals.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
# %%

# Imports
import numpy as np
from snake.core.simulation import SimConfig, default_hardware, GreConfig
from snake.core.phantom import Phantom
from snake.core.smaps import get_smaps
Expand Down
2 changes: 1 addition & 1 deletion src/snake/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
"""SNAKE Package"""
"""SNAKE Package."""
2 changes: 0 additions & 2 deletions src/snake/core/engine/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
from collections.abc import Mapping, Sequence
from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor, as_completed
from multiprocessing.managers import SharedMemoryManager
from pathlib import Path
from tempfile import TemporaryDirectory
from typing import Any, ClassVar

Expand Down Expand Up @@ -164,7 +163,6 @@ def __call__(
**kwargs: Any,
):
"""Perform the acquisition and fill the dataset."""

# Create the base dataset
make_base_mrd(filename, sampler, phantom, sim_conf, handlers, smaps, coil_cov)

Expand Down
1 change: 0 additions & 1 deletion src/snake/core/engine/nufft.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
"""Acquisition engine using nufft."""

from collections.abc import Sequence
from copy import deepcopy

import ismrmrd as mrd
import numpy as np
Expand Down
3 changes: 2 additions & 1 deletion src/snake/core/handlers/motion/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/usr/bin/env python3
"""Motion Handler Module."""

from .image import RandomMotionImageHandler

__all__ = ["RandomMotionImageHandler"]
14 changes: 8 additions & 6 deletions src/snake/core/handlers/noise.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
"""Handler that add noise to the phantom in the image domain."""

import numpy as np
from numpy.typing import NDArray
from copy import deepcopy

from numpy.typing import NDArray
import pandas as pd
from functools import partial

from ..._meta import LogMixin
from ..phantom import Phantom, DynamicData
from ..simulation import SimConfig
from .base import AbstractHandler


def apply_noise(phantom: Phantom, data, idx, variance) -> Phantom:
def apply_noise(phantom: Phantom, data: NDArray, idx: int, variance: float) -> Phantom:
"""Apply noise to the phantom at time idx."""
rng = np.random.default_rng((int(data[0, idx]), idx)) # new seed for every frame
noise_tissue = rng.standard_normal(size=phantom.masks.shape[1:]) * np.sqrt(variance)
new_phantom = deepcopy(phantom)
Expand All @@ -21,12 +22,13 @@ def apply_noise(phantom: Phantom, data, idx, variance) -> Phantom:


class NoiseHandler(AbstractHandler):
"""Handler that add noise tot the phantom in the image domain."""

__handler_name__ = "noise-image"
variance: float

def get_static(self, phantom: Phantom, sim_conf: SimConfig) -> Phantom:
"""Add a static noise tissue"""
"""Add a static noise tissue."""
noise_tissue = np.ones_like(phantom.masks[0])
noise_props = np.array([[100000, 100000, 100000, 1, 0]])
new_phantom = phantom.add_tissue(
Expand All @@ -36,7 +38,7 @@ def get_static(self, phantom: Phantom, sim_conf: SimConfig) -> Phantom:
return new_phantom

def get_dynamic(self, phantom: Phantom, sim_conf: SimConfig) -> DynamicData:
"""Add a dynamic noise tissue"""
"""Add a dynamic noise tissue."""
return DynamicData(
"noise",
data=np.ones((1, sim_conf.max_n_shots), dtype=np.int32) * sim_conf.rng_seed,
Expand Down
2 changes: 1 addition & 1 deletion src/snake/core/phantom/static.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def add_tissue(
tissue_name: str,
mask: NDArray[np.float32],
props: NDArray[np.float32],
phantom_name=None,
phantom_name: str | None = None,
) -> Phantom:
"""Add a tissue to the phantom. Creates a new Phantom object."""
masks = np.concatenate((self.masks, mask[None, ...]), axis=0)
Expand Down
2 changes: 1 addition & 1 deletion src/snake/core/sampling/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ def get_kspace_slice_loc(
)
rng = validate_rng(rng)

def _get_samples(p):
def _get_samples(p: NDArray) -> list[int]:
p /= np.sum(p)
return list(rng.choice(borders, size=n_samples_borders, replace=False, p=p))

Expand Down
2 changes: 0 additions & 2 deletions src/snake/core/sampling/samplers.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,6 @@ class LoadTrajectorySampler(NonCartesianAcquisitionSampler):

def _single_frame(self, sim_conf: SimConfig) -> NDArray:
"""Load the trajectory."""

data = read_trajectory(self.path, raster_time=self.raster_time)[0]
data /= 0.5 * data.max()
return data
Expand Down Expand Up @@ -262,7 +261,6 @@ class EPI3dAcquisitionSampler(BaseSampler):

def _single_frame(self, sim_conf: SimConfig) -> NDArray:
"""Generate the sampling pattern."""

return stacked_epi_factory(
shape=sim_conf.shape,
accelz=self.accelz,
Expand Down
3 changes: 2 additions & 1 deletion src/snake/core/simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ def _repr_html_(obj: Any, vertical: bool = True) -> str:
field_value_str = repr(field_value)

table_rows.append(
f"<tr><td>{field_name} (<i>{field_type}</i>)</td><td>{field_value_str}</td></tr>"
f"<tr><td>{field_name}(<i>{field_type}</i>)</td>"
f"<td>{field_value_str}</td></tr>"
)
else:
table_rows.append(
Expand Down
6 changes: 4 additions & 2 deletions src/snake/toolkit/analysis/metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,10 @@ def get_snr(test: NDArray, ref: NDArray, roi: NDArray | None = None) -> float:
return np.sqrt(np.mean(abs(signal) ** 2) / np.mean(abs(noise) ** 2))


def get_snr_console_db(test: NDArray, roi_data=None, roi_noise=None) -> float:
"""Compute the SNR 'like at the console'
def get_snr_console_db(
test: NDArray, roi_data: NDArray = None, roi_noise: NDArray = None
) -> float:
"""Compute the SNR 'like at the console'.
using region of interest for the signal and noise in the same image.
Expand Down
1 change: 0 additions & 1 deletion src/snake/toolkit/analysis/stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import numpy as np

from nilearn.glm.first_level import make_first_level_design_matrix, run_glm
from nilearn.glm.first_level.hemodynamic_models import _resample_regressor
from nilearn.glm import compute_contrast, expression_to_contrast_vector
from nilearn.glm.thresholding import fdr_threshold
from scipy.stats import norm
Expand Down
1 change: 0 additions & 1 deletion src/snake/toolkit/cli/acquisition.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from omegaconf import OmegaConf
from snake.core.engine import BaseAcquisitionEngine
from snake.core.handlers import HandlerList
from snake.mrd_utils import make_base_mrd
from snake.core.phantom import Phantom
from snake.core.smaps import get_smaps
from snake.toolkit.cli.config import ConfigSNAKE, cleanup_cuda, make_hydra_cli
Expand Down
10 changes: 2 additions & 8 deletions src/snake/toolkit/cli/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
from dataclasses import dataclass, field
import hydra
from hydra.core.config_store import ConfigStore
from hydra import compose, initialize
from omegaconf import OmegaConf, DictConfig

from snake.core.simulation import SimConfig
Expand Down Expand Up @@ -122,13 +121,8 @@ def cleanup_cuda() -> None:
cp._default_pinned_memory_pool = cp.cuda.PinnedMemoryPool()


def make_hydra_cli(fun):
def make_hydra_cli(fun: callable) -> callable:
"""Create a Hydra CLI for the function."""
return hydra.main(
version_base=None, config_path="../../../cli-conf", config_name="config"
)(fun)


def load_config(filename, *overrides):
with initialize(config_path="../../../cli-conf", job_name="test_app"):
cfg = compose(config_name="config", overrides=list(overrides))
return cfg
2 changes: 1 addition & 1 deletion src/snake/toolkit/cli/reconstruction.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ def reconstruction(cfg: DictConfig) -> None:
gc.collect()

results = []
for name, rec in cfg.reconstructors.items():
for _name, rec in cfg.reconstructors.items():
rec_str = str(rec) # FIXME Also use parameters of reconstructors
data_rec_file = Path(f"data_rec_{rec_str}.npy").resolve()
data_zscore_file = Path(f"data_zscore_{rec_str}.npy").resolve()
Expand Down
18 changes: 12 additions & 6 deletions src/snake/toolkit/plotting.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,21 @@ def get_axis_properties(
cmin = max(0, cmin - arr_pad)
cmax = min(cmax + arr_pad, mask.shape[1])
bbox[i] = (slice(rmin, rmax), slice(cmin, cmax))
hdiv, vdiv = get_hdiv_vdiv(array_bg, bbox, slices, width_inches, cbar=cbar)
hdiv, vdiv = _get_hdiv_vdiv(array_bg, bbox, slices, width_inches, cbar=cbar)

return hdiv, vdiv, tuple(bbox), slices


def get_hdiv_vdiv(array_bg, bbox, slices, width_inches, cbar=False):
def _get_hdiv_vdiv(
array_bg: NDArray,
bbox: tuple[tuple[slice]],
slices: tuple[slice],
width_inches: float,
cbar: bool = False,
) -> tuple[NDArray, NDArray]:
sizes = np.array([(bb.stop - bb.start) for b in bbox for bb in b])

sizes = tuple(array_bg[s][b].shape for s, b in zip(slices, bbox))
sizes = tuple(array_bg[s][b].shape for s, b in zip(slices, bbox, strict=False))
alpha1 = sizes[1][1] / sizes[2][1]
update_sizes = [[0, 0], [0, 0], [0, 0]]
update_sizes[2][0] = sizes[2][0]
Expand All @@ -90,7 +96,7 @@ def get_hdiv_vdiv(array_bg, bbox, slices, width_inches, cbar=False):
0.02 * hdiv[0],
]
)
hdivv = np.array(hdiv)
np.array(hdiv)
height_inches = width_inches * aspect
vdiv = np.array([height_inches * split_tb, height_inches * (1 - split_tb)])
return hdiv, vdiv
Expand All @@ -113,7 +119,7 @@ def plot_frames_activ(
bbox: tuple[Any, ...],
z_thresh: float = 3,
z_max: float = 11,
bg_cmap="gray",
bg_cmap: str = "gray",
) -> tuple[plt.Axes, matplotlib.image.AxesImage]:
"""Plot activation maps and background.
Expand Down Expand Up @@ -189,7 +195,7 @@ def axis3dcut(
background, cuts_, width_inches, cbar=cbar
)
elif bbox is not None and slices is not None:
hdiv, vdiv = get_hdiv_vdiv(background, bbox, slices, width_inches, cbar=cbar)
hdiv, vdiv = _get_hdiv_vdiv(background, bbox, slices, width_inches, cbar=cbar)
bbox_ = bbox
slices_ = slices
else:
Expand Down
3 changes: 2 additions & 1 deletion src/snake/toolkit/reconstructors/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/usr/bin/env python3
"""Reconstructors wrapping different reconstruction algorithms."""

from .base import BaseReconstructor
from .pysap import ZeroFilledReconstructor, SequentialReconstructor

Expand Down
20 changes: 17 additions & 3 deletions src/snake/toolkit/reconstructors/fourier.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
"""FFT operators for MRI reconstruction."""

from numpy.typing import NDArray
import scipy as sp


def fft(image, axis=-1):
def fft(image: NDArray, axis: int | tuple[int] = -1) -> NDArray:
"""Apply the FFT operator.
Parameters
Expand All @@ -24,8 +25,21 @@ def fft(image, axis=-1):
)


def ifft(kspace_data, axis=-1):
"""Apply the inverse FFT operator."""
def ifft(kspace_data: NDArray, axis: int | tuple[int] = -1) -> NDArray:
"""Apply the inverse FFT operator.
Parameters
----------
kspace_data : array
Image in space.
axis : int
Axis to apply the FFT.
Returns
-------
image_data : array
image data.
"""
return sp.fft.fftshift(
sp.fft.ifftn(sp.fft.ifftshift(kspace_data, axes=axis), norm="ortho", axes=axis),
axes=axis,
Expand Down

0 comments on commit 0983eb1

Please sign in to comment.