Skip to content
Merged
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 monai/apps/auto3dseg/ensemble_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ def __init__(self, n_fold: int = 5):
super().__init__()
self.n_fold = n_fold

def collect_algos(self):
def collect_algos(self) -> None:
"""
Rank the algos by finding the best model in each cross-validation fold
"""
Expand Down
9 changes: 5 additions & 4 deletions monai/apps/auto3dseg/hpo_gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import os
from abc import abstractmethod
from copy import deepcopy
from typing import Optional
from warnings import warn

from monai.apps.auto3dseg.bundle_gen import BundleAlgo
Expand Down Expand Up @@ -96,7 +97,7 @@ class NNIGen(HPOGen):
NNI command manually.
"""

def __init__(self, algo=None, params=None):
def __init__(self, algo: Optional[Algo] = None, params=None):
self.algo: Algo
self.hint = ""
self.obj_filename = ""
Expand All @@ -115,7 +116,7 @@ def __init__(self, algo=None, params=None):
else:
self.algo = algo

if isinstance(algo, BundleAlgo):
if isinstance(self.algo, BundleAlgo):
self.obj_filename = algo_to_pickle(self.algo, template_path=self.algo.template_path)
self.print_bundle_algo_instruction()
else:
Expand Down Expand Up @@ -271,7 +272,7 @@ class OptunaGen(HPOGen):

"""

def __init__(self, algo=None, params=None):
def __init__(self, algo: Optional[Algo] = None, params=None) -> None:
self.algo: Algo
self.obj_filename = ""

Expand All @@ -289,7 +290,7 @@ def __init__(self, algo=None, params=None):
else:
self.algo = algo

if isinstance(algo, BundleAlgo):
if isinstance(self.algo, BundleAlgo):
self.obj_filename = algo_to_pickle(self.algo, template_path=self.algo.template_path)
else:
self.obj_filename = algo_to_pickle(self.algo)
Expand Down
18 changes: 10 additions & 8 deletions monai/apps/deepgrow/transforms.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import numpy as np
import torch

from monai.config import IndexSelection, KeysCollection
from monai.config import IndexSelection, KeysCollection, NdarrayOrTensor
from monai.networks.layers import GaussianFilter
from monai.transforms import Resize, SpatialCrop
from monai.transforms.transform import MapTransform, Randomizable, Transform
Expand Down Expand Up @@ -50,7 +50,7 @@ def _apply(self, label):
sids.append(sid)
return np.asarray(sids)

def __call__(self, data):
def __call__(self, data) -> Dict:
d: Dict = dict(data)
label = d[self.label].numpy() if isinstance(data[self.label], torch.Tensor) else data[self.label]
if label.shape[0] != 1:
Expand Down Expand Up @@ -654,7 +654,7 @@ def bounding_box(self, points, img_shape):
box_start[di], box_end[di] = min_d, max_d
return box_start, box_end

def __call__(self, data):
def __call__(self, data) -> Dict:
d: Dict = dict(data)
first_key: Hashable = self.first_key(d)
if first_key == ():
Expand Down Expand Up @@ -741,7 +741,7 @@ def __init__(
self.meta_key_postfix = meta_key_postfix
self.cropped_shape_key = cropped_shape_key

def __call__(self, data):
def __call__(self, data) -> Dict:
d = dict(data)
guidance = d[self.guidance]
meta_dict: Dict = d[self.meta_keys or f"{self.ref_image}_{self.meta_key_postfix}"]
Expand Down Expand Up @@ -836,7 +836,7 @@ def __init__(
self.original_shape_key = original_shape_key
self.cropped_shape_key = cropped_shape_key

def __call__(self, data):
def __call__(self, data) -> Dict:
d = dict(data)
meta_dict: Dict = d[f"{self.ref_image}_{self.meta_key_postfix}"]

Expand All @@ -857,8 +857,9 @@ def __call__(self, data):
box_end = meta_dict[self.end_coord_key]

spatial_dims = min(len(box_start), len(image.shape[1:]))
slices = [slice(None)] + [slice(s, e) for s, e in zip(box_start[:spatial_dims], box_end[:spatial_dims])]
slices = tuple(slices)
slices = tuple(
[slice(None)] + [slice(s, e) for s, e in zip(box_start[:spatial_dims], box_end[:spatial_dims])]
)
result[slices] = image

# Undo Spacing
Expand All @@ -869,10 +870,11 @@ def __call__(self, data):

if np.any(np.not_equal(current_size, spatial_size)):
resizer = Resize(spatial_size=spatial_size, mode=mode)
result = resizer(result, mode=mode, align_corners=align_corners)
result = resizer(result, mode=mode, align_corners=align_corners) # type: ignore

# Undo Slicing
slice_idx = meta_dict.get("slice_idx")
final_result: NdarrayOrTensor
if slice_idx is None or self.slice_only:
final_result = result if len(result.shape) <= 3 else result[0]
else:
Expand Down
14 changes: 7 additions & 7 deletions monai/auto3dseg/analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import time
from abc import ABC, abstractmethod
from copy import deepcopy
from typing import Any, Dict, List, Optional
from typing import Any, Dict, Hashable, List, Mapping, Optional

import numpy as np
import torch
Expand Down Expand Up @@ -377,7 +377,7 @@ def __init__(self, image_key: str, label_key: str, stats_name: str = "label_stat
self.label_key = label_key
self.do_ccp = do_ccp

report_format: Dict[str, Any] = {
report_format: Dict[LabelStatsKeys, Any] = {
LabelStatsKeys.LABEL_UID: None,
LabelStatsKeys.IMAGE_INTST: None,
LabelStatsKeys.LABEL: [{LabelStatsKeys.PIXEL_PCT: None, LabelStatsKeys.IMAGE_INTST: None}],
Expand All @@ -394,7 +394,7 @@ def __init__(self, image_key: str, label_key: str, stats_name: str = "label_stat
id_seq = ID_SEP_KEY.join([LabelStatsKeys.LABEL, "0", LabelStatsKeys.IMAGE_INTST])
self.update_ops_nested_label(id_seq, SampleOperations())

def __call__(self, data):
def __call__(self, data: Mapping[Hashable, MetaTensor]) -> Dict[Hashable, MetaTensor]:
"""
Callable to execute the pre-defined functions.

Expand Down Expand Up @@ -442,7 +442,7 @@ def __call__(self, data):
The stats operation uses numpy and torch to compute max, min, and other
functions. If the input has nan/inf, the stats results will be nan/inf.
"""
d = dict(data)
d: Dict[Hashable, MetaTensor] = dict(data)
start = time.time()
if isinstance(d[self.image_key], (torch.Tensor, MetaTensor)) and d[self.image_key].device.type == "cuda":
using_cuda = True
Expand All @@ -451,13 +451,13 @@ def __call__(self, data):
restore_grad_state = torch.is_grad_enabled()
torch.set_grad_enabled(False)

ndas = [d[self.image_key][i] for i in range(d[self.image_key].shape[0])]
ndas_label = d[self.label_key] # (H,W,D)
ndas: List[MetaTensor] = [d[self.image_key][i] for i in range(d[self.image_key].shape[0])] # type: ignore
ndas_label: MetaTensor = d[self.label_key] # (H,W,D)

if ndas_label.shape != ndas[0].shape:
raise ValueError(f"Label shape {ndas_label.shape} is different from image shape {ndas[0].shape}")

nda_foregrounds = [get_foreground_label(nda, ndas_label) for nda in ndas]
nda_foregrounds: List[torch.Tensor] = [get_foreground_label(nda, ndas_label) for nda in ndas]
nda_foregrounds = [nda if nda.numel() > 0 else torch.Tensor([0]) for nda in nda_foregrounds]

unique_label = unique(ndas_label)
Expand Down
4 changes: 2 additions & 2 deletions monai/data/dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -1075,7 +1075,7 @@ def randomize(self, data: Sequence) -> None:
except TypeError as e:
warnings.warn(f"input data can't be shuffled in SmartCacheDataset with numpy.random.shuffle(): {e}.")

def _compute_data_idx(self):
def _compute_data_idx(self) -> None:
"""
Update the replacement data position in the total data.

Expand Down Expand Up @@ -1209,7 +1209,7 @@ def _try_manage_replacement(self, check_round):
self._compute_replacements()
return False, self._round

def manage_replacement(self):
def manage_replacement(self) -> None:
"""
Background thread for replacement.

Expand Down
12 changes: 6 additions & 6 deletions monai/data/image_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ def read(self, data: Union[Sequence[PathLike], PathLike], **kwargs):
img_.append(itk.imread(name, **kwargs_))
return img_ if len(filenames) > 1 else img_[0]

def get_data(self, img):
def get_data(self, img) -> Tuple[np.ndarray, Dict]:
"""
Extract data array and metadata from loaded image and return them.
This function returns two objects, first is numpy array of image data, second is dict of metadata.
Expand Down Expand Up @@ -564,7 +564,7 @@ def _combine_dicom_series(self, data):

return stack_array, stack_metadata

def get_data(self, data):
def get_data(self, data) -> Tuple[np.ndarray, Dict]:
"""
Extract data array and metadata from loaded image and return them.
This function returns two objects, first is numpy array of image data, second is dict of metadata.
Expand Down Expand Up @@ -929,7 +929,7 @@ def read(self, data: Union[Sequence[PathLike], PathLike], **kwargs):
img_.append(img)
return img_ if len(filenames) > 1 else img_[0]

def get_data(self, img):
def get_data(self, img) -> Tuple[np.ndarray, Dict]:
"""
Extract data array and metadata from loaded image and return them.
This function returns two objects, first is numpy array of image data, second is dict of metadata.
Expand Down Expand Up @@ -1095,7 +1095,7 @@ def read(self, data: Union[Sequence[PathLike], PathLike], **kwargs):

return img_ if len(img_) > 1 else img_[0]

def get_data(self, img):
def get_data(self, img) -> Tuple[np.ndarray, Dict]:
"""
Extract data array and metadata from loaded image and return them.
This function returns two objects, first is numpy array of image data, second is dict of metadata.
Expand All @@ -1113,7 +1113,7 @@ def get_data(self, img):
img = (img,)

for i in ensure_tuple(img):
header = {}
header: Dict[MetaKeys, Any] = {}
if isinstance(i, np.ndarray):
# if `channel_dim` is None, can not detect the channel dim, use all the dims as spatial_shape
spatial_shape = np.asarray(i.shape)
Expand Down Expand Up @@ -1184,7 +1184,7 @@ def read(self, data: Union[Sequence[PathLike], PathLike, np.ndarray], **kwargs):

return img_ if len(filenames) > 1 else img_[0]

def get_data(self, img):
def get_data(self, img) -> Tuple[np.ndarray, Dict]:
"""
Extract data array and metadata from loaded image and return them.
This function returns two objects, first is numpy array of image data, second is dict of metadata.
Expand Down
2 changes: 1 addition & 1 deletion monai/data/meta_obj.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ class MetaObj:

"""

def __init__(self):
def __init__(self) -> None:
self._meta: dict = MetaObj.get_default_meta()
self._applied_operations: list = MetaObj.get_default_applied_operations()
self._pending_operations: list = MetaObj.get_default_applied_operations() # the same default as applied_ops
Expand Down
8 changes: 4 additions & 4 deletions monai/data/meta_tensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ def get_array(self, output_type=np.ndarray, dtype=None, device=None, *_args, **_
"""
return convert_data_type(self, output_type=output_type, dtype=dtype, device=device, wrap_sequence=True)[0]

def set_array(self, src, non_blocking=False, *_args, **_kwargs):
def set_array(self, src, non_blocking: bool = False, *_args, **_kwargs):
"""
Copies the elements from src into self tensor and returns self.
The src tensor must be broadcastable with the self tensor.
Expand All @@ -369,11 +369,11 @@ def set_array(self, src, non_blocking=False, *_args, **_kwargs):
_args: currently unused parameters.
_kwargs: currently unused parameters.
"""
src: torch.Tensor = convert_to_tensor(src, track_meta=False, wrap_sequence=True)
converted: torch.Tensor = convert_to_tensor(src, track_meta=False, wrap_sequence=True)
try:
return self.copy_(src, non_blocking=non_blocking)
return self.copy_(converted, non_blocking=non_blocking)
except RuntimeError: # skip the shape checking
self.data = src
self.data = converted
return self

@property
Expand Down
2 changes: 1 addition & 1 deletion monai/metrics/metric.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ class Cumulative:

"""

def __init__(self):
def __init__(self) -> None:
"""
Initialize the internal buffers.
`self._buffers` are local buffers, they are not usually used directly.
Expand Down
2 changes: 1 addition & 1 deletion monai/networks/blocks/warp.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ def __init__(
self.num_steps = num_steps
self.warp_layer = Warp(mode=mode, padding_mode=padding_mode)

def forward(self, dvf):
def forward(self, dvf: torch.Tensor) -> torch.Tensor:
"""
Args:
dvf: dvf to be transformed, in shape (batch, ``spatial_dims``, H, W[,D])
Expand Down
2 changes: 1 addition & 1 deletion monai/networks/nets/ahnet.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ def __init__(self, spatial_dims: int, psp_block_num: int, in_ch: int, upsample_m
pad_size = (2 ** (i + 3), 2 ** (i + 3), 0)[-spatial_dims:]
self.up_modules.append(conv_trans_type(1, 1, kernel_size=size, stride=size, padding=pad_size))

def forward(self, x):
def forward(self, x: torch.Tensor) -> torch.Tensor:
outputs = []
if self.upsample_mode == "transpose":
for (project_module, pool_module, up_module) in zip(
Expand Down
4 changes: 2 additions & 2 deletions monai/transforms/intensity/dictionary.py
Original file line number Diff line number Diff line change
Expand Up @@ -1577,7 +1577,7 @@ def set_random_state(
self.dropper.set_random_state(seed, state)
return self

def __call__(self, data):
def __call__(self, data: Mapping[Hashable, NdarrayOrTensor]) -> Dict[Hashable, NdarrayOrTensor]:
d = dict(data)
self.randomize(None)
if not self._do_transform:
Expand Down Expand Up @@ -1650,7 +1650,7 @@ def set_random_state(
self.shuffle.set_random_state(seed, state)
return self

def __call__(self, data):
def __call__(self, data: Mapping[Hashable, NdarrayOrTensor]) -> Dict[Hashable, NdarrayOrTensor]:
d = dict(data)
self.randomize(None)
if not self._do_transform:
Expand Down
2 changes: 1 addition & 1 deletion monai/transforms/io/dictionary.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ class LoadImaged(MapTransform):
def __init__(
self,
keys: KeysCollection,
reader: Optional[Union[ImageReader, str]] = None,
reader: Union[Type[ImageReader], str, None] = None,
dtype: DtypeLike = np.float32,
meta_keys: Optional[KeysCollection] = None,
meta_key_postfix: str = DEFAULT_POST_FIX,
Expand Down
10 changes: 8 additions & 2 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,8 @@ ignore_missing_imports = True
no_implicit_optional = True
# Warns about casting an expression to its inferred type.
warn_redundant_casts = True
# No error on unneeded # type: ignore comments.
warn_unused_ignores = False
# Warns about unneeded # type: ignore comments.
warn_unused_ignores = True
# Shows a warning when returning a value with type Any from a function declared with a non-Any return type.
warn_return_any = True
# Prohibit equality checks, identity checks, and container checks between non-overlapping types.
Expand All @@ -169,6 +169,12 @@ show_column_numbers = True
show_error_codes = True
# Use visually nicer output in error messages: use soft word wrap, show source code snippets, and show error location markers.
pretty = False
# Warns about per-module sections in the config file that do not match any files processed when invoking mypy.
warn_unused_configs = True
# Make arguments prepended via Concatenate be truly positional-only.
strict_concatenate = True

exclude = venv/

[mypy-versioneer]
# Ignores all non-fatal errors.
Expand Down
6 changes: 3 additions & 3 deletions tests/test_flexible_unet.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
# limitations under the License.

import unittest
from typing import Union
from typing import Dict, List, Type, Union

import torch
from parameterized import parameterized
Expand Down Expand Up @@ -88,14 +88,14 @@ def get_inplanes():
return [64, 128, 256, 512]

@classmethod
def get_encoder_parameters(cls):
def get_encoder_parameters(cls) -> List[Dict]:
"""
Get parameter list to initialize encoder networks.
Each parameter dict must have `spatial_dims`, `in_channels`
and `pretrained` parameters.
"""
parameter_list = []
res_type: Union[ResNetBlock, ResNetBottleneck]
res_type: Union[Type[ResNetBlock], Type[ResNetBottleneck]]
for backbone in range(len(cls.backbone_names)):
if backbone < 3:
res_type = ResNetBlock
Expand Down
2 changes: 1 addition & 1 deletion tests/test_inverse_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def get_image(dtype, device) -> MetaTensor:
return MetaTensor(img, affine=affine)

@parameterized.expand(TESTS)
def test_inverse_array(self, use_compose, dtype, device):
def test_inverse_array(self, use_compose: bool, dtype: torch.dtype, device: torch.device):
img: MetaTensor
tr = Compose([AddChannel(), Orientation("RAS"), Flip(1), Spacing([1.0, 1.2, 0.9], align_corners=False)])
num_invertible = len([i for i in tr.transforms if isinstance(i, InvertibleTransform)])
Expand Down
Loading