diff --git a/monai/apps/deepgrow/transforms.py b/monai/apps/deepgrow/transforms.py index 59dee17280..1cef7ff03d 100644 --- a/monai/apps/deepgrow/transforms.py +++ b/monai/apps/deepgrow/transforms.py @@ -652,7 +652,7 @@ def __call__(self, data): return d guidance = d[self.guidance] - original_spatial_shape = d[first_key].shape[1:] # type: ignore + original_spatial_shape = d[first_key].shape[1:] box_start, box_end = self.bounding_box(np.array(guidance[0] + guidance[1]), original_spatial_shape) center = list(np.mean([box_start, box_end], axis=0).astype(int, copy=False)) spatial_size = self.spatial_size diff --git a/monai/apps/pathology/transforms/spatial/array.py b/monai/apps/pathology/transforms/spatial/array.py index fe1383c08d..b271a3331f 100644 --- a/monai/apps/pathology/transforms/spatial/array.py +++ b/monai/apps/pathology/transforms/spatial/array.py @@ -190,8 +190,7 @@ def randomize(self, img_size: Sequence[int]) -> None: self.random_idxs = np.array((0,)) def __call__(self, image: NdarrayOrTensor) -> NdarrayOrTensor: - img_np: np.ndarray - img_np, *_ = convert_data_type(image, np.ndarray) # type: ignore + img_np, *_ = convert_data_type(image, np.ndarray) # add random offset self.randomize(img_size=img_np.shape) diff --git a/monai/config/type_definitions.py b/monai/config/type_definitions.py index 686befb2eb..16919c2ec4 100644 --- a/monai/config/type_definitions.py +++ b/monai/config/type_definitions.py @@ -63,15 +63,14 @@ #: Type of datatypes: Adapted from https://github.com/numpy/numpy/blob/v1.21.4/numpy/typing/_dtype_like.py#L121 DtypeLike = Union[np.dtype, type, str, None] +#: NdarrayOrTensor: Union of numpy.ndarray and torch.Tensor to be used for typing +NdarrayOrTensor = Union[np.ndarray, torch.Tensor] + #: NdarrayTensor # # Generic type which can represent either a numpy.ndarray or a torch.Tensor # Unlike Union can create a dependence between parameter(s) / return(s) -NdarrayTensor = TypeVar("NdarrayTensor", np.ndarray, torch.Tensor) - - -#: NdarrayOrTensor: Union of numpy.ndarray and torch.Tensor to be used for typing -NdarrayOrTensor = Union[np.ndarray, torch.Tensor] +NdarrayTensor = TypeVar("NdarrayTensor", bound=NdarrayOrTensor) #: TensorOrList: The TensorOrList type is used for defining `batch-first Tensor` or `list of channel-first Tensor`. TensorOrList = Union[torch.Tensor, Sequence[torch.Tensor]] diff --git a/monai/data/dataloader.py b/monai/data/dataloader.py index 3117a27c02..d1f5bd4fe1 100644 --- a/monai/data/dataloader.py +++ b/monai/data/dataloader.py @@ -81,4 +81,4 @@ def __init__(self, dataset: Dataset, num_workers: int = 0, **kwargs) -> None: if "worker_init_fn" not in kwargs: kwargs.update({"worker_init_fn": worker_init_fn}) - super().__init__(dataset=dataset, num_workers=num_workers, **kwargs) # type: ignore[call-overload] + super().__init__(dataset=dataset, num_workers=num_workers, **kwargs) diff --git a/monai/data/dataset.py b/monai/data/dataset.py index 426f9856fe..156708c7dd 100644 --- a/monai/data/dataset.py +++ b/monai/data/dataset.py @@ -269,7 +269,7 @@ def _pre_transform(self, item_transformed): random transform object """ - for _transform in self.transform.transforms: # type:ignore + for _transform in self.transform.transforms: # execute all the deterministic transforms if isinstance(_transform, Randomizable) or not isinstance(_transform, Transform): break diff --git a/monai/data/image_reader.py b/monai/data/image_reader.py index df574adf00..9f0e3f32cf 100644 --- a/monai/data/image_reader.py +++ b/monai/data/image_reader.py @@ -25,7 +25,7 @@ from .utils import is_supported_format if TYPE_CHECKING: - import itk # type: ignore + import itk import nibabel as nib from nibabel.nifti1 import Nifti1Image from PIL import Image as PILImage diff --git a/monai/data/nifti_writer.py b/monai/data/nifti_writer.py index 606b0732b3..b658121e49 100644 --- a/monai/data/nifti_writer.py +++ b/monai/data/nifti_writer.py @@ -107,17 +107,15 @@ def write_nifti( sr = min(data.ndim, 3) if affine is None: affine = np.eye(4, dtype=np.float64) - affine = to_affine_nd(sr, affine) # type: ignore + affine = to_affine_nd(sr, affine) if target_affine is None: - target_affine = affine # type: ignore - target_affine, *_ = convert_data_type(to_affine_nd(sr, target_affine), np.ndarray) # type: ignore + target_affine = affine + target_affine, *_ = convert_data_type(to_affine_nd(sr, target_affine), np.ndarray) - if allclose(affine, target_affine, atol=1e-3): # type: ignore + if allclose(affine, target_affine, atol=1e-3): # no affine changes, save (data, affine) - results_img = nib.Nifti1Image( - data.astype(output_dtype, copy=False), to_affine_nd(3, target_affine) # type: ignore - ) + results_img = nib.Nifti1Image(data.astype(output_dtype, copy=False), to_affine_nd(3, target_affine)) nib.save(results_img, file_name) return @@ -128,7 +126,7 @@ def write_nifti( data_shape = data.shape data = nib.orientations.apply_orientation(data, ornt_transform) _affine = affine @ nib.orientations.inv_ornt_aff(ornt_transform, data_shape) - if allclose(_affine, target_affine, atol=1e-3) or not resample: # type: ignore + if allclose(_affine, target_affine, atol=1e-3) or not resample: results_img = nib.Nifti1Image(data.astype(output_dtype, copy=False), to_affine_nd(3, _affine)) # type: ignore nib.save(results_img, file_name) return @@ -139,8 +137,8 @@ def write_nifti( ) transform = np.linalg.inv(_affine) @ target_affine if output_spatial_shape is None: - output_spatial_shape, _ = compute_shape_offset(data.shape, _affine, target_affine) # type: ignore - output_spatial_shape_ = list(output_spatial_shape) if output_spatial_shape is not None else [] # type: ignore + output_spatial_shape, _ = compute_shape_offset(data.shape, _affine, target_affine) + output_spatial_shape_ = list(output_spatial_shape) if output_spatial_shape is not None else [] if data.ndim > 3: # multi channel, resampling each channel while len(output_spatial_shape_) < 3: output_spatial_shape_ = output_spatial_shape_ + [1] @@ -165,8 +163,6 @@ def write_nifti( ) data_np = data_torch.squeeze(0).squeeze(0).detach().cpu().numpy() - results_img = nib.Nifti1Image( - data_np.astype(output_dtype, copy=False), to_affine_nd(3, target_affine) # type: ignore - ) + results_img = nib.Nifti1Image(data_np.astype(output_dtype, copy=False), to_affine_nd(3, target_affine)) nib.save(results_img, file_name) return diff --git a/monai/data/png_writer.py b/monai/data/png_writer.py index f1aa5fc5c8..7fcdb7fdb0 100644 --- a/monai/data/png_writer.py +++ b/monai/data/png_writer.py @@ -65,10 +65,10 @@ def write_png( data = np.expand_dims(data, 0) # make a channel data = xform(data)[0] # type: ignore if mode != InterpolateMode.NEAREST: - data = np.clip(data, _min, _max) # type: ignore + data = np.clip(data, _min, _max) if scale is not None: - data = np.clip(data, 0.0, 1.0) # type: ignore # png writer only can scale data in range [0, 1] + data = np.clip(data, 0.0, 1.0) # png writer only can scale data in range [0, 1] if scale == np.iinfo(np.uint8).max: data = (scale * data).astype(np.uint8, copy=False) elif scale == np.iinfo(np.uint16).max: @@ -77,7 +77,7 @@ def write_png( raise ValueError(f"Unsupported scale: {scale}, available options are [255, 65535]") # PNG data must be int number - if data.dtype not in (np.uint8, np.uint16): # type: ignore + if data.dtype not in (np.uint8, np.uint16): data = data.astype(np.uint8, copy=False) data = np.moveaxis(data, 0, 1) diff --git a/monai/data/samplers.py b/monai/data/samplers.py index 40eed03187..f5175266d8 100644 --- a/monai/data/samplers.py +++ b/monai/data/samplers.py @@ -50,7 +50,7 @@ def __init__( super().__init__(dataset=dataset, num_replicas=num_replicas, rank=rank, shuffle=shuffle, **kwargs) if not even_divisible: - data_len = len(dataset) # type: ignore + data_len = len(dataset) extra_size = self.total_size - data_len if self.rank + extra_size >= self.num_replicas: self.num_samples -= 1 diff --git a/monai/data/utils.py b/monai/data/utils.py index d19a2b133d..779671e793 100644 --- a/monai/data/utils.py +++ b/monai/data/utils.py @@ -27,7 +27,7 @@ import torch from torch.utils.data._utils.collate import default_collate -from monai.config.type_definitions import NdarrayOrTensor, PathLike +from monai.config.type_definitions import NdarrayOrTensor, NdarrayTensor, PathLike from monai.networks.layers.simplelayers import GaussianFilter from monai.utils import ( MAX_SEED, @@ -676,16 +676,16 @@ def compute_shape_offset( """ shape = np.array(spatial_shape, copy=True, dtype=float) sr = len(shape) - in_affine = convert_data_type(to_affine_nd(sr, in_affine), np.ndarray)[0] # type: ignore - out_affine = convert_data_type(to_affine_nd(sr, out_affine), np.ndarray)[0] # type: ignore + in_affine_ = convert_data_type(to_affine_nd(sr, in_affine), np.ndarray)[0] + out_affine_ = convert_data_type(to_affine_nd(sr, out_affine), np.ndarray)[0] in_coords = [(0.0, dim - 1.0) for dim in shape] corners: np.ndarray = np.asarray(np.meshgrid(*in_coords, indexing="ij")).reshape((len(shape), -1)) corners = np.concatenate((corners, np.ones_like(corners[:1]))) - corners = in_affine @ corners # type: ignore + corners = in_affine_ @ corners try: - inv_mat = np.linalg.inv(out_affine) + inv_mat = np.linalg.inv(out_affine_) except np.linalg.LinAlgError as e: - raise ValueError(f"Affine {out_affine} is not invertible") from e + raise ValueError(f"Affine {out_affine_} is not invertible") from e corners_out = inv_mat @ corners corners_out = corners_out[:-1] / corners_out[-1] out_shape = np.round(corners_out.ptp(axis=1) + 1.0) @@ -700,7 +700,7 @@ def compute_shape_offset( return out_shape.astype(int, copy=False), offset -def to_affine_nd(r: Union[np.ndarray, int], affine: NdarrayOrTensor, dtype=np.float64) -> NdarrayOrTensor: +def to_affine_nd(r: Union[np.ndarray, int], affine: NdarrayTensor, dtype=np.float64) -> NdarrayTensor: """ Using elements from affine, to create a new affine matrix by assigning the rotation/zoom/scaling matrix and the translation vector. @@ -728,8 +728,7 @@ def to_affine_nd(r: Union[np.ndarray, int], affine: NdarrayOrTensor, dtype=np.fl an (r+1) x (r+1) matrix (tensor or ndarray depends on the input ``affine`` data type) """ - affine_np: np.ndarray - affine_np = convert_data_type(affine, output_type=np.ndarray, dtype=dtype, wrap_sequence=True)[0] # type: ignore + affine_np = convert_data_type(affine, output_type=np.ndarray, dtype=dtype, wrap_sequence=True)[0] affine_np = affine_np.copy() if affine_np.ndim != 2: raise ValueError(f"affine must have 2 dimensions, got {affine_np.ndim}.") @@ -743,8 +742,8 @@ def to_affine_nd(r: Union[np.ndarray, int], affine: NdarrayOrTensor, dtype=np.fl new_affine[:d, :d] = affine_np[:d, :d] if d > 1: new_affine[:d, -1] = affine_np[:d, -1] - new_affine, *_ = convert_to_dst_type(new_affine, affine, dtype=dtype) # type: ignore - return new_affine + output, *_ = convert_to_dst_type(new_affine, affine, dtype=dtype) + return output def reorient_spatial_axes( @@ -874,7 +873,7 @@ def compute_importance_map( """ mode = look_up_option(mode, BlendMode) - device = torch.device(device) # type: ignore[arg-type] + device = torch.device(device) if mode == BlendMode.CONSTANT: importance_map = torch.ones(patch_size, device=device).float() elif mode == BlendMode.GAUSSIAN: diff --git a/monai/handlers/roc_auc.py b/monai/handlers/roc_auc.py index 31b046064e..68cf2e655e 100644 --- a/monai/handlers/roc_auc.py +++ b/monai/handlers/roc_auc.py @@ -16,7 +16,7 @@ from monai.utils import Average -class ROCAUC(IgniteMetric): # type: ignore[valid-type, misc] # due to optional_import +class ROCAUC(IgniteMetric): """ Computes Area Under the Receiver Operating Characteristic Curve (ROC AUC). accumulating predictions and the ground-truth during an epoch and applying `compute_roc_auc`. diff --git a/monai/metrics/confusion_matrix.py b/monai/metrics/confusion_matrix.py index dd1f81a4b4..eca4663ee7 100644 --- a/monai/metrics/confusion_matrix.py +++ b/monai/metrics/confusion_matrix.py @@ -102,7 +102,7 @@ def _compute_tensor(self, y_pred: torch.Tensor, y: torch.Tensor): # type: ignor return get_confusion_matrix(y_pred=y_pred, y=y, include_background=self.include_background) - def aggregate(self): # type: ignore + def aggregate(self): """ Execute reduction for the confusion matrix values. diff --git a/monai/metrics/cumulative_average.py b/monai/metrics/cumulative_average.py index 090d65a44c..768841f6c7 100644 --- a/monai/metrics/cumulative_average.py +++ b/monai/metrics/cumulative_average.py @@ -51,7 +51,7 @@ def reset(self): self.sum = None self.not_nans = None - def aggregate(self): # type: ignore + def aggregate(self): """ Sync data from all the ranks and compute the average value with previous sum value. diff --git a/monai/metrics/hausdorff_distance.py b/monai/metrics/hausdorff_distance.py index 082311aa67..7644e52f83 100644 --- a/monai/metrics/hausdorff_distance.py +++ b/monai/metrics/hausdorff_distance.py @@ -99,7 +99,7 @@ def _compute_tensor(self, y_pred: torch.Tensor, y: torch.Tensor): # type: ignor directed=self.directed, ) - def aggregate(self): # type: ignore + def aggregate(self): """ Execute reduction logic for the output of `compute_hausdorff_distance`. diff --git a/monai/metrics/meandice.py b/monai/metrics/meandice.py index 1e6065b59c..f1e272bbe5 100644 --- a/monai/metrics/meandice.py +++ b/monai/metrics/meandice.py @@ -79,7 +79,7 @@ def _compute_tensor(self, y_pred: torch.Tensor, y: torch.Tensor): # type: ignor # compute dice (BxC) for each channel for each batch return compute_meandice(y_pred=y_pred, y=y, include_background=self.include_background) - def aggregate(self): # type: ignore + def aggregate(self): """ Execute reduction logic for the output of `compute_meandice`. diff --git a/monai/metrics/metric.py b/monai/metrics/metric.py index 60dcd0b52d..7782c4c468 100644 --- a/monai/metrics/metric.py +++ b/monai/metrics/metric.py @@ -201,8 +201,7 @@ def extend(self, *data) -> None: self._buffers = [[] for _ in data] for b, d in zip(self._buffers, data): # converting to pytorch tensors so that we can use the distributed API - d_t: torch.Tensor - d_t, *_ = convert_data_type(d, output_type=torch.Tensor, wrap_sequence=True) # type: ignore + d_t, *_ = convert_data_type(d, output_type=torch.Tensor, wrap_sequence=True) try: b.extend([x[0] for x in torch.split(d_t, 1, dim=0)]) except (AttributeError, IndexError, RuntimeError) as e: @@ -228,8 +227,7 @@ def append(self, *data) -> None: self._buffers = [[] for _ in data] for b, d in zip(self._buffers, data): # converting to pytorch tensors so that we can use the distributed API - d_t: torch.Tensor - d_t, *_ = convert_data_type(d, output_type=torch.Tensor, wrap_sequence=True) # type: ignore + d_t, *_ = convert_data_type(d, output_type=torch.Tensor, wrap_sequence=True) b.append(d_t) self._synced = False diff --git a/monai/metrics/regression.py b/monai/metrics/regression.py index bd63134d6c..d5733eee97 100644 --- a/monai/metrics/regression.py +++ b/monai/metrics/regression.py @@ -45,7 +45,7 @@ def __init__( self.reduction = reduction self.get_not_nans = get_not_nans - def aggregate(self): # type: ignore + def aggregate(self): data = self.get_buffer() if not isinstance(data, torch.Tensor): raise ValueError("the data to aggregate must be PyTorch Tensor.") diff --git a/monai/metrics/rocauc.py b/monai/metrics/rocauc.py index 73f15534a9..e65d5ae4cb 100644 --- a/monai/metrics/rocauc.py +++ b/monai/metrics/rocauc.py @@ -49,7 +49,7 @@ def __init__(self, average: Union[Average, str] = Average.MACRO) -> None: def _compute_tensor(self, y_pred: torch.Tensor, y: torch.Tensor): # type: ignore return y_pred, y - def aggregate(self): # type: ignore + def aggregate(self): """ As AUC metric needs to execute on the overall data, so usually users accumulate `y_pred` and `y` of every iteration, then execute real computation and reduction on the accumulated data. diff --git a/monai/metrics/surface_distance.py b/monai/metrics/surface_distance.py index 04eed97a5d..11b472185d 100644 --- a/monai/metrics/surface_distance.py +++ b/monai/metrics/surface_distance.py @@ -91,7 +91,7 @@ def _compute_tensor(self, y_pred: torch.Tensor, y: torch.Tensor): # type: ignor distance_metric=self.distance_metric, ) - def aggregate(self): # type: ignore + def aggregate(self): """ Execute reduction logic for the output of `compute_average_surface_distance`. @@ -158,7 +158,7 @@ def compute_average_surface_distance( if surface_distance.shape == (0,): avg_surface_distance = np.nan else: - avg_surface_distance = surface_distance.mean() # type: ignore + avg_surface_distance = surface_distance.mean() if not symmetric: asd[b, c] = avg_surface_distance else: @@ -166,7 +166,7 @@ def compute_average_surface_distance( if surface_distance_2.shape == (0,): avg_surface_distance_2 = np.nan else: - avg_surface_distance_2 = surface_distance_2.mean() # type: ignore + avg_surface_distance_2 = surface_distance_2.mean() asd[b, c] = np.mean((avg_surface_distance, avg_surface_distance_2)) return torch.from_numpy(asd) diff --git a/monai/networks/blocks/acti_norm.py b/monai/networks/blocks/acti_norm.py index d07d78f1ad..65b662ac32 100644 --- a/monai/networks/blocks/acti_norm.py +++ b/monai/networks/blocks/acti_norm.py @@ -98,4 +98,4 @@ def __init__( if item not in op_dict: raise ValueError(f"ordering must be a string of {op_dict}, got {item} in it.") if op_dict[item] is not None: - self.add_module(item, op_dict[item]) # type: ignore + self.add_module(item, op_dict[item]) diff --git a/monai/networks/layers/spatial_transforms.py b/monai/networks/layers/spatial_transforms.py index 56f13736b4..c1bb951c4d 100644 --- a/monai/networks/layers/spatial_transforms.py +++ b/monai/networks/layers/spatial_transforms.py @@ -115,7 +115,7 @@ def grid_pull( for i in ensure_tuple(interpolation) ] out: torch.Tensor - out = _GridPull.apply(input, grid, interpolation, bound, extrapolate) # type: ignore + out = _GridPull.apply(input, grid, interpolation, bound, extrapolate) return out diff --git a/monai/networks/nets/transchex.py b/monai/networks/nets/transchex.py index 7b3afe3e5e..cb9baa5e65 100644 --- a/monai/networks/nets/transchex.py +++ b/monai/networks/nets/transchex.py @@ -217,7 +217,7 @@ class MultiModal(BertPreTrainedModel): """ def __init__( - self, num_language_layers: int, num_vision_layers: int, num_mixed_layers: int, bert_config: dict # type: ignore + self, num_language_layers: int, num_vision_layers: int, num_mixed_layers: int, bert_config: dict ) -> None: """ Args: @@ -254,8 +254,8 @@ class Transchex(torch.nn.Module): def __init__( self, in_channels: int, - img_size: Union[Sequence[int], int], # type: ignore - patch_size: Union[int, Tuple[int, int]], # type: ignore + img_size: Union[Sequence[int], int], + patch_size: Union[int, Tuple[int, int]], num_classes: int, num_language_layers: int, num_vision_layers: int, @@ -352,10 +352,7 @@ def __init__( self.patch_size = patch_size self.num_patches = (img_size[0] // self.patch_size[0]) * (img_size[1] // self.patch_size[1]) # type: ignore self.vision_proj = nn.Conv2d( - in_channels=in_channels, - out_channels=hidden_size, - kernel_size=self.patch_size, # type: ignore - stride=self.patch_size, # type: ignore + in_channels=in_channels, out_channels=hidden_size, kernel_size=self.patch_size, stride=self.patch_size ) self.norm_vision_pos = nn.LayerNorm(hidden_size) self.pos_embed_vis = nn.Parameter(torch.zeros(1, self.num_patches, hidden_size)) diff --git a/monai/transforms/croppad/array.py b/monai/transforms/croppad/array.py index faf5306ce0..199f185500 100644 --- a/monai/transforms/croppad/array.py +++ b/monai/transforms/croppad/array.py @@ -394,13 +394,13 @@ def __init__( data=roi_center, output_type=torch.Tensor, dtype=torch.int16, wrap_sequence=True ) roi_size, *_ = convert_to_dst_type(src=roi_size, dst=roi_center, wrap_sequence=True) - _zeros = torch.zeros_like(roi_center) # type: ignore + _zeros = torch.zeros_like(roi_center) roi_start_torch = maximum(roi_center - floor_divide(roi_size, 2), _zeros) # type: ignore roi_end_torch = maximum(roi_start_torch + roi_size, roi_start_torch) else: if roi_start is None or roi_end is None: raise ValueError("Please specify either roi_center, roi_size or roi_start, roi_end.") - roi_start_torch, *_ = convert_data_type( # type: ignore + roi_start_torch, *_ = convert_data_type( data=roi_start, output_type=torch.Tensor, dtype=torch.int16, wrap_sequence=True ) roi_start_torch = maximum(roi_start_torch, torch.zeros_like(roi_start_torch)) # type: ignore @@ -1162,7 +1162,7 @@ def __call__(self, img: NdarrayOrTensor, mode: Optional[Union[NumpyPadMode, str] If None, defaults to the ``mode`` in construction. See also: https://numpy.org/doc/1.18/reference/generated/numpy.pad.html """ - return self.padder(self.cropper(img), mode=mode) # type: ignore + return self.padder(self.cropper(img), mode=mode) class BoundingRect(Transform): diff --git a/monai/transforms/intensity/array.py b/monai/transforms/intensity/array.py index dab2789425..b5cf61ce0c 100644 --- a/monai/transforms/intensity/array.py +++ b/monai/transforms/intensity/array.py @@ -23,7 +23,7 @@ import torch from monai.config import DtypeLike -from monai.config.type_definitions import NdarrayOrTensor +from monai.config.type_definitions import NdarrayOrTensor, NdarrayTensor from monai.data.utils import get_random_patch, get_valid_patch_size from monai.networks.layers import GaussianFilter, HilbertTransform, SavitzkyGolayFilter from monai.transforms.transform import RandomizableTransform, Transform @@ -106,7 +106,7 @@ def randomize(self, img: NdarrayOrTensor, mean: Optional[float] = None) -> None: rand_std = self.R.uniform(0, self.std) noise = self.R.normal(self.mean if mean is None else mean, rand_std, size=img.shape) # noise is float64 array, convert to the output dtype to save memory - self.noise, *_ = convert_data_type(noise, dtype=self.dtype) # type: ignore + self.noise, *_ = convert_data_type(noise, dtype=self.dtype) def __call__(self, img: NdarrayOrTensor, mean: Optional[float] = None, randomize: bool = True) -> NdarrayOrTensor: """ @@ -694,7 +694,7 @@ def __call__(self, img: NdarrayOrTensor) -> NdarrayOrTensor: else: img = self._normalize(img, self.subtrahend, self.divisor) - out, *_ = convert_data_type(img, dtype=dtype) + out = convert_to_dst_type(img, img, dtype=dtype)[0] return out @@ -779,7 +779,7 @@ def __call__(self, img: NdarrayOrTensor) -> NdarrayOrTensor: img = img * (self.b_max - self.b_min) + self.b_min if self.clip: img = clip(img, self.b_min, self.b_max) - ret, *_ = convert_data_type(img, dtype=dtype) + ret: NdarrayOrTensor = convert_data_type(img, dtype=dtype)[0] return ret @@ -1115,8 +1115,7 @@ def __call__(self, img: NdarrayOrTensor): np.ndarray containing envelope of data in img along the specified axis. """ - img_t: torch.Tensor - img_t, *_ = convert_data_type(img, torch.Tensor) # type: ignore + img_t, *_ = convert_data_type(img, torch.Tensor) # add one to transform axis because a batch axis will be added at dimension 0 hilbert_transform = HilbertTransform(self.axis + 1, self.n) # convert to Tensor and add Batch axis expected by HilbertTransform @@ -1146,9 +1145,8 @@ def __init__(self, sigma: Union[Sequence[float], float] = 1.0, approx: str = "er self.sigma = sigma self.approx = approx - def __call__(self, img: NdarrayOrTensor) -> NdarrayOrTensor: - img_t: torch.Tensor - img_t, *_ = convert_data_type(img, torch.Tensor, dtype=torch.float) # type: ignore + def __call__(self, img: NdarrayTensor) -> NdarrayTensor: + img_t, *_ = convert_data_type(img, torch.Tensor, dtype=torch.float) sigma: Union[Sequence[torch.Tensor], torch.Tensor] if isinstance(self.sigma, Sequence): sigma = [torch.as_tensor(s, device=img_t.device) for s in self.sigma] @@ -1255,9 +1253,8 @@ def __init__( self.alpha = alpha self.approx = approx - def __call__(self, img: NdarrayOrTensor) -> NdarrayOrTensor: - img_t: torch.Tensor - img_t, *_ = convert_data_type(img, torch.Tensor, dtype=torch.float32) # type: ignore + def __call__(self, img: NdarrayTensor) -> NdarrayTensor: + img_t, *_ = convert_data_type(img, torch.Tensor, dtype=torch.float32) gf1, gf2 = ( GaussianFilter(img_t.ndim - 1, sigma, approx=self.approx).to(img_t.device) @@ -1402,8 +1399,7 @@ def __call__(self, img: NdarrayOrTensor, randomize: bool = True) -> NdarrayOrTen if self.reference_control_points is None or self.floating_control_points is None: raise RuntimeError("please call the `randomize()` function first.") - img_np: np.ndarray - img_np, *_ = convert_data_type(img, np.ndarray) # type: ignore + img_np, *_ = convert_data_type(img, np.ndarray) img_min, img_max = img_np.min(), img_np.max() reference_control_points_scaled = self.reference_control_points * (img_max - img_min) + img_min floating_control_points_scaled = self.floating_control_points * (img_max - img_min) + img_min @@ -1626,13 +1622,13 @@ def __call__(self, img: NdarrayOrTensor) -> NdarrayOrTensor: # FT k = self.shift_fourier(img, n_dims) lib = np if isinstance(k, np.ndarray) else torch - log_abs = lib.log(lib.abs(k) + 1e-10) # type: ignore - phase = lib.angle(k) # type: ignore + log_abs = lib.log(lib.abs(k) + 1e-10) + phase = lib.angle(k) k_intensity = self.k_intensity # default log intensity if k_intensity is None: - k_intensity = tuple(lib.mean(log_abs, axis=tuple(range(-n_dims, 0))) * 2.5) # type: ignore + k_intensity = tuple(lib.mean(log_abs, axis=tuple(range(-n_dims, 0))) * 2.5) # highlight if isinstance(self.loc[0], Sequence): @@ -1641,7 +1637,7 @@ def __call__(self, img: NdarrayOrTensor) -> NdarrayOrTensor: else: self._set_spike(log_abs, self.loc, k_intensity) # map back - k = lib.exp(log_abs) * lib.exp(1j * phase) # type: ignore + k = lib.exp(log_abs) * lib.exp(1j * phase) img, *_ = convert_to_dst_type(self.inv_shift_fourier(k, n_dims), dst=img) return img @@ -1816,8 +1812,8 @@ def _set_default_range(self, img: NdarrayOrTensor) -> Sequence[Sequence[float]]: k = self.shift_fourier(img, n_dims) mod = torch if isinstance(k, torch.Tensor) else np - log_abs = mod.log(mod.absolute(k) + 1e-10) # type: ignore - shifted_means = mod.mean(log_abs, dim=tuple(range(-n_dims, 0))) * 2.5 # type: ignore + log_abs = mod.log(mod.absolute(k) + 1e-10) + shifted_means = mod.mean(log_abs, dim=tuple(range(-n_dims, 0))) * 2.5 return tuple((i * 0.95, i * 1.1) for i in shifted_means) @@ -1892,8 +1888,7 @@ def __call__(self, img: NdarrayOrTensor, randomize: bool = True) -> NdarrayOrTen if not self._do_transform: return img - img_np: np.ndarray - img_np, *_ = convert_data_type(img, np.ndarray) # type: ignore + img_np, *_ = convert_data_type(img, np.ndarray) out = self._transform_holes(img=img_np) ret, *_ = convert_to_dst_type(src=out, dst=img) return ret @@ -2048,12 +2043,11 @@ def __init__( self.dtype = dtype def __call__(self, img: NdarrayOrTensor, mask: Optional[NdarrayOrTensor] = None) -> NdarrayOrTensor: - img_np: np.ndarray - img_np, *_ = convert_data_type(img, np.ndarray) # type: ignore + img_np, *_ = convert_data_type(img, np.ndarray) mask = mask if mask is not None else self.mask mask_np: Optional[np.ndarray] = None if mask is not None: - mask_np, *_ = convert_data_type(mask, np.ndarray) # type: ignore + mask_np, *_ = convert_data_type(mask, np.ndarray) ret = equalize_hist(img=img_np, mask=mask_np, num_bins=self.num_bins, min=self.min, max=self.max) out, *_ = convert_to_dst_type(src=ret, dst=img, dtype=self.dtype or img.dtype) diff --git a/monai/transforms/intensity/dictionary.py b/monai/transforms/intensity/dictionary.py index 2d8f46ebd8..b0f5149456 100644 --- a/monai/transforms/intensity/dictionary.py +++ b/monai/transforms/intensity/dictionary.py @@ -1533,7 +1533,7 @@ def __call__(self, data): if first_key == []: return d - self.dropper.randomize(d[first_key].shape[1:]) # type: ignore + self.dropper.randomize(d[first_key].shape[1:]) for key in self.key_iterator(d): d[key] = self.dropper(img=d[key], randomize=False) @@ -1602,7 +1602,7 @@ def __call__(self, data): if first_key == []: return d - self.shuffle.randomize(d[first_key].shape[1:]) # type: ignore + self.shuffle.randomize(d[first_key].shape[1:]) for key in self.key_iterator(d): d[key] = self.shuffle(img=d[key], randomize=False) diff --git a/monai/transforms/post/array.py b/monai/transforms/post/array.py index 6a189d0bb4..dcd32c5d55 100644 --- a/monai/transforms/post/array.py +++ b/monai/transforms/post/array.py @@ -95,8 +95,7 @@ def __call__( raise TypeError(f"other must be None or callable but is {type(other).__name__}.") # convert to float as activation must operate on float tensor - img_t: torch.Tensor - img_t, *_ = convert_data_type(img, torch.Tensor, dtype=torch.float) # type: ignore + img_t, *_ = convert_data_type(img, torch.Tensor, dtype=torch.float) if sigmoid or self.sigmoid: img_t = torch.sigmoid(img_t) if softmax or self.softmax: @@ -232,8 +231,7 @@ def __call__( warnings.warn("`threshold_values=True/False` is deprecated, please use `threshold=value` instead.") threshold = logit_thresh if threshold else None - img_t: torch.Tensor - img_t, *_ = convert_data_type(img, torch.Tensor) # type: ignore + img_t, *_ = convert_data_type(img, torch.Tensor) if argmax or self.argmax: img_t = torch.argmax(img_t, dim=0, keepdim=True) @@ -496,8 +494,7 @@ def __call__(self, img: NdarrayOrTensor) -> NdarrayOrTensor: """ if not isinstance(img, (np.ndarray, torch.Tensor)): raise NotImplementedError(f"{self.__class__} can not handle data of type {type(img)}.") - img_np: np.ndarray - img_np, *_ = convert_data_type(img, np.ndarray) # type: ignore + img_np, *_ = convert_data_type(img, np.ndarray) out_np: np.ndarray = fill_holes(img_np, self.applied_labels, self.connectivity) out, *_ = convert_to_dst_type(out_np, img) return out @@ -539,7 +536,7 @@ def __call__(self, img: NdarrayOrTensor) -> NdarrayOrTensor: ideally the edge should be thin enough, but now it has a thickness. """ - img_: torch.Tensor = convert_data_type(img, torch.Tensor)[0] # type: ignore + img_: torch.Tensor = convert_data_type(img, torch.Tensor)[0] spatial_dims = len(img_.shape) - 1 img_ = img_.unsqueeze(0) # adds a batch dim if spatial_dims == 2: diff --git a/monai/transforms/smooth_field/array.py b/monai/transforms/smooth_field/array.py index 2a8cf6c7f1..f581687ea5 100644 --- a/monai/transforms/smooth_field/array.py +++ b/monai/transforms/smooth_field/array.py @@ -120,7 +120,7 @@ def __call__(self, randomize=False) -> torch.Tensor: if self.spatial_zoom is not None: resized_field = interpolate( # type: ignore - input=field, # type: ignore + input=field, scale_factor=self.spatial_zoom, mode=look_up_option(self.mode, InterpolateMode).value, align_corners=self.align_corners, diff --git a/monai/transforms/spatial/array.py b/monai/transforms/spatial/array.py index b7cb5015ed..7bd5990b3b 100644 --- a/monai/transforms/spatial/array.py +++ b/monai/transforms/spatial/array.py @@ -206,7 +206,7 @@ def __call__( ) except (np.linalg.LinAlgError, RuntimeError) as e: raise ValueError(f"src affine is not invertible: {src_affine}") from e - xform = to_affine_nd(spatial_rank, xform) # type: ignore + xform = to_affine_nd(spatial_rank, xform) # no resampling if it's identity transform if allclose(xform, np.diag(np.ones(len(xform))), atol=AFFINE_TOL): output_data, *_ = convert_to_dst_type(img, img, dtype=torch.float32) @@ -222,8 +222,8 @@ def __call__( spatial_size = spatial_size[:spatial_rank] chns, additional_dims = img.shape[0], img.shape[spatial_rank + 1 :] # beyond three spatial dims # resample - img_ = convert_data_type(img, torch.Tensor, dtype=_dtype)[0] # type: ignore - xform = convert_to_dst_type(xform, img_)[0] # type: ignore + img_ = convert_data_type(img, torch.Tensor, dtype=_dtype)[0] + xform = convert_to_dst_type(xform, img_)[0] align_corners = self.align_corners if align_corners is None else align_corners mode = mode or self.mode padding_mode = padding_mode or self.padding_mode @@ -247,8 +247,8 @@ def __call__( else: affine_xform = AffineTransform( normalized=False, - mode=mode, # type: ignore - padding_mode=padding_mode, # type: ignore + mode=mode, + padding_mode=padding_mode, align_corners=align_corners, reverse_indexing=True, ) @@ -374,8 +374,8 @@ def __call__( affine_np = affine = np.eye(sr + 1, dtype=np.float64) affine_ = np.eye(sr + 1, dtype=np.float64) else: - affine_np, *_ = convert_data_type(affine, np.ndarray) # type: ignore - affine_ = to_affine_nd(sr, affine_np) # type: ignore + affine_np, *_ = convert_data_type(affine, np.ndarray) + affine_ = to_affine_nd(sr, affine_np) out_d = self.pixdim[:sr] if out_d.size < sr: @@ -395,7 +395,7 @@ def __call__( align_corners=align_corners, dtype=dtype, ) - new_affine = to_affine_nd(affine_np, new_affine) # type: ignore + new_affine = to_affine_nd(affine_np, new_affine) new_affine, *_ = convert_to_dst_type(src=new_affine, dst=affine, dtype=torch.float32) if self.image_only: @@ -474,8 +474,8 @@ def __call__( affine_np = affine = np.eye(sr + 1, dtype=np.float64) affine_ = np.eye(sr + 1, dtype=np.float64) else: - affine_np, *_ = convert_data_type(affine, np.ndarray) # type: ignore - affine_ = to_affine_nd(sr, affine_np) # type: ignore + affine_np, *_ = convert_data_type(affine, np.ndarray) + affine_ = to_affine_nd(sr, affine_np) src = nib.io_orientation(affine_) if self.as_closest_canonical: @@ -505,7 +505,7 @@ def __call__( data_array = data_array.permute(full_transpose.tolist()) # type: ignore else: data_array = data_array.transpose(full_transpose) # type: ignore - out, *_ = convert_to_dst_type(src=data_array, dst=data_array) # type: ignore + out, *_ = convert_to_dst_type(src=data_array, dst=data_array) new_affine = to_affine_nd(affine_np, new_affine) new_affine, *_ = convert_to_dst_type(src=new_affine, dst=affine, dtype=torch.float32) @@ -601,7 +601,7 @@ def __call__( ValueError: When ``self.spatial_size`` length is less than ``img`` spatial dimensions. """ - img_, *_ = convert_data_type(img, torch.Tensor, dtype=torch.float) # type: ignore + img_, *_ = convert_data_type(img, torch.Tensor, dtype=torch.float) if self.size_mode == "all": input_ndim = img_.ndim - 1 # spatial ndim output_ndim = len(ensure_tuple(self.spatial_size)) @@ -620,8 +620,8 @@ def __call__( raise ValueError("spatial_size must be an int number if size_mode is 'longest'.") scale = self.spatial_size / max(img_size) spatial_size_ = tuple(int(round(s * scale)) for s in img_size) - resized = torch.nn.functional.interpolate( # type: ignore - input=img_.unsqueeze(0), # type: ignore + resized = torch.nn.functional.interpolate( + input=img_.unsqueeze(0), size=spatial_size_, mode=look_up_option(self.mode if mode is None else mode, InterpolateMode).value, align_corners=self.align_corners if align_corners is None else align_corners, @@ -702,8 +702,7 @@ def __call__( """ _dtype = dtype or self.dtype or img.dtype - img_t: torch.Tensor - img_t, *_ = convert_data_type(img, torch.Tensor, dtype=_dtype) # type: ignore + img_t, *_ = convert_data_type(img, torch.Tensor, dtype=_dtype) im_shape = np.asarray(img_t.shape[1:]) # spatial dimensions input_ndim = len(im_shape) @@ -723,8 +722,7 @@ def __call__( shift_1 = create_translate(input_ndim, (-(output_shape - 1) / 2).tolist()) transform = shift @ transform @ shift_1 - transform_t: torch.Tensor - transform_t, *_ = convert_to_dst_type(transform, img_t) # type: ignore + transform_t, *_ = convert_to_dst_type(transform, img_t) xform = AffineTransform( normalized=False, @@ -821,8 +819,7 @@ def __call__( See also: https://pytorch.org/docs/stable/generated/torch.nn.functional.interpolate.html """ - img_t: torch.Tensor - img_t, *_ = convert_data_type(img, torch.Tensor, dtype=torch.float32) # type: ignore + img_t, *_ = convert_data_type(img, torch.Tensor, dtype=torch.float32) _zoom = ensure_tuple_rep(self.zoom, img.ndim - 1) # match the spatial image dim zoomed: NdarrayOrTensor = torch.nn.functional.interpolate( # type: ignore @@ -1584,11 +1581,9 @@ def __call__( if grid is None: raise ValueError("Unknown grid.") _device = img.device if isinstance(img, torch.Tensor) else self.device - img_t: torch.Tensor - grid_t: torch.Tensor _dtype = dtype or self.dtype or img.dtype - img_t, *_ = convert_data_type(img, torch.Tensor, device=_device, dtype=_dtype) # type: ignore - grid_t = convert_to_dst_type(grid, img_t)[0] # type: ignore + img_t, *_ = convert_data_type(img, torch.Tensor, device=_device, dtype=_dtype) + grid_t = convert_to_dst_type(grid, img_t)[0] if grid_t is grid: # copy if needed (convert_data_type converts to contiguous) grid_t = grid_t.clone(memory_format=torch.contiguous_format) sr = min(len(img_t.shape[1:]), 3) @@ -1625,7 +1620,6 @@ def __call__( padding_mode=self.padding_mode.value if padding_mode is None else GridSamplePadMode(padding_mode).value, align_corners=True, )[0] - out_val: NdarrayOrTensor out_val, *_ = convert_to_dst_type(out, dst=img, dtype=np.float32) return out_val diff --git a/monai/transforms/spatial/dictionary.py b/monai/transforms/spatial/dictionary.py index b319bb44b1..eabf309567 100644 --- a/monai/transforms/spatial/dictionary.py +++ b/monai/transforms/spatial/dictionary.py @@ -158,7 +158,7 @@ def __init__( mode: GridSampleModeSequence = GridSampleMode.BILINEAR, padding_mode: GridSamplePadModeSequence = GridSamplePadMode.BORDER, align_corners: Union[Sequence[bool], bool] = False, - dtype: Optional[Union[Sequence[DtypeLike], DtypeLike]] = np.float64, + dtype: Union[Sequence[DtypeLike], DtypeLike] = np.float64, meta_keys: Optional[KeysCollection] = None, meta_key_postfix: str = DEFAULT_POST_FIX, meta_src_keys: Optional[KeysCollection] = "src_affine", @@ -265,8 +265,8 @@ def inverse(self, data: Mapping[Hashable, NdarrayOrTensor]) -> Dict[Hashable, Nd meta_data = d[transform[TraceKeys.EXTRA_INFO]["meta_key"]] src_key = transform[TraceKeys.EXTRA_INFO]["meta_src_key"] dst_key = transform[TraceKeys.EXTRA_INFO]["meta_dst_key"] - src_affine = meta_data[src_key] # type: ignore - dst_affine = meta_data[dst_key] # type: ignore + src_affine = meta_data[src_key] + dst_affine = meta_data[dst_key] mode = transform[TraceKeys.EXTRA_INFO]["mode"] padding_mode = transform[TraceKeys.EXTRA_INFO]["padding_mode"] align_corners = transform[TraceKeys.EXTRA_INFO]["align_corners"] @@ -313,7 +313,7 @@ def __init__( mode: GridSampleModeSequence = GridSampleMode.BILINEAR, padding_mode: GridSamplePadModeSequence = GridSamplePadMode.BORDER, align_corners: Union[Sequence[bool], bool] = False, - dtype: Optional[Union[Sequence[DtypeLike], DtypeLike]] = np.float64, + dtype: Union[Sequence[DtypeLike], DtypeLike] = np.float64, meta_keys: Optional[KeysCollection] = None, meta_key_postfix: str = DEFAULT_POST_FIX, allow_missing_keys: bool = False, @@ -862,7 +862,7 @@ def inverse(self, data: Mapping[Hashable, NdarrayOrTensor]) -> Dict[Hashable, Nd inv_affine = np.linalg.inv(fwd_affine) affine_grid = AffineGrid(affine=inv_affine) - grid, _ = affine_grid(orig_size) # type: ignore + grid, _ = affine_grid(orig_size) # Apply inverse transform d[key] = self.affine.resampler(d[key], grid, mode, padding_mode) @@ -996,7 +996,7 @@ def __call__(self, data: Mapping[Hashable, NdarrayOrTensor]) -> Dict[Hashable, N grid = self.rand_affine.get_identity_grid(sp_size) if self._do_transform: # add some random factors grid = self.rand_affine.rand_affine_grid(grid=grid) - affine = self.rand_affine.rand_affine_grid.get_transformation_matrix() # type: ignore[assignment] + affine = self.rand_affine.rand_affine_grid.get_transformation_matrix() for key, mode, padding_mode in self.key_iterator(d, self.mode, self.padding_mode): self.push_transform( @@ -1029,7 +1029,7 @@ def inverse(self, data: Mapping[Hashable, NdarrayOrTensor]) -> Dict[Hashable, Nd inv_affine = np.linalg.inv(fwd_affine) affine_grid = AffineGrid(affine=inv_affine) - grid, _ = affine_grid(orig_size) # type: ignore + grid, _ = affine_grid(orig_size) # Apply inverse transform d[key] = self.rand_affine.resampler(d[key], grid, mode, padding_mode) @@ -1552,10 +1552,8 @@ def inverse(self, data: Mapping[Hashable, NdarrayOrTensor]) -> Dict[Hashable, Nd align_corners=False if align_corners == TraceKeys.NONE else align_corners, reverse_indexing=True, ) - img_t: torch.Tensor - img_t, *_ = convert_data_type(d[key], torch.Tensor, dtype=dtype) # type: ignore - transform_t: torch.Tensor - transform_t, *_ = convert_to_dst_type(inv_rot_mat, img_t) # type: ignore + img_t, *_ = convert_data_type(d[key], torch.Tensor, dtype=dtype) + transform_t, *_ = convert_to_dst_type(inv_rot_mat, img_t) out = xform(img_t.unsqueeze(0), transform_t, spatial_size=transform[TraceKeys.ORIG_SIZE]).squeeze(0) out, *_ = convert_to_dst_type(out, dst=d[key], dtype=out.dtype) @@ -1686,10 +1684,8 @@ def inverse(self, data: Mapping[Hashable, NdarrayOrTensor]) -> Dict[Hashable, Nd align_corners=False if align_corners == TraceKeys.NONE else align_corners, reverse_indexing=True, ) - img_t: torch.Tensor - img_t, *_ = convert_data_type(d[key], torch.Tensor, dtype=dtype) # type: ignore - transform_t: torch.Tensor - transform_t, *_ = convert_to_dst_type(inv_rot_mat, img_t) # type: ignore + img_t, *_ = convert_data_type(d[key], torch.Tensor, dtype=dtype) + transform_t, *_ = convert_to_dst_type(inv_rot_mat, img_t) output: torch.Tensor out = xform(img_t.unsqueeze(0), transform_t, spatial_size=transform[TraceKeys.ORIG_SIZE]).squeeze(0) out, *_ = convert_to_dst_type(out, dst=d[key], dtype=out.dtype) @@ -1785,7 +1781,7 @@ def inverse(self, data: Mapping[Hashable, NdarrayOrTensor]) -> Dict[Hashable, Nd align_corners=None if align_corners == TraceKeys.NONE else align_corners, ) # Size might be out by 1 voxel so pad - d[key] = SpatialPad(transform[TraceKeys.ORIG_SIZE], mode="edge")(d[key]) # type: ignore + d[key] = SpatialPad(transform[TraceKeys.ORIG_SIZE], mode="edge")(d[key]) # Remove the applied transform self.pop_transform(d, key) @@ -1909,7 +1905,7 @@ def inverse(self, data: Mapping[Hashable, NdarrayOrTensor]) -> Dict[Hashable, Nd align_corners=None if align_corners == TraceKeys.NONE else align_corners, ) # Size might be out by 1 voxel so pad - d[key] = SpatialPad(transform[TraceKeys.ORIG_SIZE], mode="edge")(d[key]) # type: ignore + d[key] = SpatialPad(transform[TraceKeys.ORIG_SIZE], mode="edge")(d[key]) # Remove the applied transform self.pop_transform(d, key) diff --git a/monai/transforms/transform.py b/monai/transforms/transform.py index 24203ff815..8537f7eb89 100644 --- a/monai/transforms/transform.py +++ b/monai/transforms/transform.py @@ -100,7 +100,7 @@ def apply_transform( def _log_stats(data, prefix: Optional[str] = "Data"): if isinstance(data, (np.ndarray, torch.Tensor)): # log data type, shape, range for array - datastats(img=data, data_shape=True, value_range=True, prefix=prefix) # type: ignore + datastats(img=data, data_shape=True, value_range=True, prefix=prefix) else: # log data type and value for other meta data datastats(img=data, data_value=True, prefix=prefix) diff --git a/monai/transforms/utility/array.py b/monai/transforms/utility/array.py index 664433270b..f1b20a942d 100644 --- a/monai/transforms/utility/array.py +++ b/monai/transforms/utility/array.py @@ -325,7 +325,7 @@ def __init__(self, dtype=np.float32) -> None: """ self.dtype = dtype - def __call__(self, img: NdarrayOrTensor, dtype: Optional[Union[DtypeLike, torch.dtype]] = None) -> NdarrayOrTensor: + def __call__(self, img: NdarrayOrTensor, dtype: Union[DtypeLike, torch.dtype] = None) -> NdarrayOrTensor: """ Apply the transform to `img`, assuming `img` is a numpy array or PyTorch Tensor. @@ -336,8 +336,7 @@ def __call__(self, img: NdarrayOrTensor, dtype: Optional[Union[DtypeLike, torch. TypeError: When ``img`` type is not in ``Union[numpy.ndarray, torch.Tensor]``. """ - img_out, *_ = convert_data_type(img, output_type=type(img), dtype=dtype or self.dtype) - return img_out + return convert_data_type(img, output_type=type(img), dtype=dtype or self.dtype)[0] # type: ignore class ToTensor(Transform): @@ -412,6 +411,7 @@ def __call__(self, data: NdarrayOrTensor): """ output_type = torch.Tensor if self.data_type == "tensor" else np.ndarray + out: NdarrayOrTensor out, *_ = convert_data_type( data=data, output_type=output_type, dtype=self.dtype, device=self.device, wrap_sequence=self.wrap_sequence ) @@ -1021,7 +1021,7 @@ def __call__(self, img: NdarrayOrTensor): img: PyTorch Tensor data for the TorchVision transform. """ - img_t, *_ = convert_data_type(img, torch.Tensor) # type: ignore + img_t, *_ = convert_data_type(img, torch.Tensor) out = self.trans(img_t) out, *_ = convert_to_dst_type(src=out, dst=img) return out @@ -1113,8 +1113,7 @@ def __call__( mask must have the same shape as input `img`. """ - img_np: np.ndarray - img_np, *_ = convert_data_type(img, np.ndarray) # type: ignore + img_np, *_ = convert_data_type(img, np.ndarray) if meta_data is None: meta_data = {} diff --git a/monai/transforms/utility/dictionary.py b/monai/transforms/utility/dictionary.py index 96e2ea6361..bbef4e22d7 100644 --- a/monai/transforms/utility/dictionary.py +++ b/monai/transforms/utility/dictionary.py @@ -520,7 +520,7 @@ def __init__( self, keys: KeysCollection, data_type: str = "tensor", - dtype: Optional[Union[DtypeLike, torch.dtype]] = None, + dtype: Union[DtypeLike, torch.dtype] = None, device: Optional[torch.device] = None, wrap_sequence: bool = True, allow_missing_keys: bool = False, diff --git a/monai/transforms/utils.py b/monai/transforms/utils.py index a58d80c6f1..9b7287df63 100644 --- a/monai/transforms/utils.py +++ b/monai/transforms/utils.py @@ -21,7 +21,7 @@ import monai from monai.config import DtypeLike, IndexSelection -from monai.config.type_definitions import NdarrayOrTensor +from monai.config.type_definitions import NdarrayOrTensor, NdarrayTensor from monai.networks.layers import GaussianFilter from monai.networks.utils import meshgrid_ij from monai.transforms.compose import Compose, OneOf @@ -156,7 +156,7 @@ def rescale_array( arr: NdarrayOrTensor, minv: Optional[float] = 0.0, maxv: Optional[float] = 1.0, - dtype: Optional[Union[DtypeLike, torch.dtype]] = np.float32, + dtype: Union[DtypeLike, torch.dtype] = np.float32, ) -> NdarrayOrTensor: """ Rescale the values of numpy array `arr` to be from `minv` to `maxv`. @@ -359,7 +359,7 @@ def map_classes_to_indices( label_flat = ravel(any_np_pt(label[c : c + 1] if channels > 1 else label == c, 0)) label_flat = img_flat & label_flat if img_flat is not None else label_flat # no need to save the indices in GPU, otherwise, still need to move to CPU at runtime when crop by indices - cls_indices, *_ = convert_data_type(nonzero(label_flat), device=torch.device("cpu")) + cls_indices: NdarrayOrTensor = convert_data_type(nonzero(label_flat), device=torch.device("cpu"))[0] indices.append(cls_indices) return indices @@ -403,7 +403,7 @@ def weighted_patch_samples( if not v[-1] or not isfinite(v[-1]) or v[-1] < 0: # uniform sampling idx = r_state.randint(0, len(v), size=n_samples) else: - r, *_ = convert_to_dst_type(r_state.random(n_samples), v) # type: ignore + r, *_ = convert_to_dst_type(r_state.random(n_samples), v) idx = searchsorted(v, r * v[-1], right=True) # type: ignore idx, *_ = convert_to_dst_type(idx, v, dtype=torch.int) # type: ignore # compensate 'valid' mode @@ -860,7 +860,7 @@ def create_translate( spatial_dims=spatial_dims, shift=shift, eye_func=lambda x: torch.eye(torch.as_tensor(x), device=device), # type: ignore - array_func=lambda x: torch.as_tensor(x, device=device), # type: ignore + array_func=lambda x: torch.as_tensor(x, device=device), ) raise ValueError(f"backend {backend} is not supported") @@ -930,7 +930,7 @@ def generate_spatial_bounding_box( return box_start, box_end -def get_largest_connected_component_mask(img: NdarrayOrTensor, connectivity: Optional[int] = None) -> NdarrayOrTensor: +def get_largest_connected_component_mask(img: NdarrayTensor, connectivity: Optional[int] = None) -> NdarrayTensor: """ Gets the largest connected component mask of an image. @@ -941,13 +941,12 @@ def get_largest_connected_component_mask(img: NdarrayOrTensor, connectivity: Opt connectivity of ``input.ndim`` is used. for more details: https://scikit-image.org/docs/dev/api/skimage.measure.html#skimage.measure.label. """ - img_arr: np.ndarray = convert_data_type(img, np.ndarray)[0] # type: ignore + img_arr = convert_data_type(img, np.ndarray)[0] largest_cc: np.ndarray = np.zeros(shape=img_arr.shape, dtype=img_arr.dtype) img_arr = measure.label(img_arr, connectivity=connectivity) if img_arr.max() != 0: largest_cc[...] = img_arr == (np.argmax(np.bincount(img_arr.flat)[1:]) + 1) - largest_cc = convert_to_dst_type(largest_cc, dst=img, dtype=largest_cc.dtype)[0] # type: ignore - return largest_cc + return convert_to_dst_type(largest_cc, dst=img, dtype=largest_cc.dtype)[0] def fill_holes( diff --git a/monai/transforms/utils_pytorch_numpy_unification.py b/monai/transforms/utils_pytorch_numpy_unification.py index 4f93f4a982..25cb1455dd 100644 --- a/monai/transforms/utils_pytorch_numpy_unification.py +++ b/monai/transforms/utils_pytorch_numpy_unification.py @@ -14,7 +14,7 @@ import numpy as np import torch -from monai.config.type_definitions import NdarrayOrTensor +from monai.config.type_definitions import NdarrayOrTensor, NdarrayTensor from monai.utils.misc import ensure_tuple, is_module_ver_at_least from monai.utils.type_conversion import convert_data_type, convert_to_dst_type @@ -44,7 +44,7 @@ ] -def allclose(a: NdarrayOrTensor, b: NdarrayOrTensor, rtol=1e-5, atol=1e-8, equal_nan=False) -> bool: +def allclose(a: NdarrayTensor, b: NdarrayOrTensor, rtol=1e-5, atol=1e-8, equal_nan=False) -> bool: """`np.allclose` with equivalent implementation for torch.""" b, *_ = convert_to_dst_type(b, a) if isinstance(a, np.ndarray): @@ -58,7 +58,7 @@ def moveaxis(x: NdarrayOrTensor, src: Union[int, Sequence[int]], dst: Union[int, if hasattr(torch, "movedim"): # `movedim` is new in torch 1.7.0 # torch.moveaxis is a recent alias since torch 1.8.0 return torch.movedim(x, src, dst) # type: ignore - return _moveaxis_with_permute(x, src, dst) # type: ignore + return _moveaxis_with_permute(x, src, dst) return np.moveaxis(x, src, dst) @@ -326,7 +326,7 @@ def isfinite(x: NdarrayOrTensor) -> NdarrayOrTensor: return torch.isfinite(x) -def searchsorted(a: NdarrayOrTensor, v: NdarrayOrTensor, right=False, sorter=None, **kwargs) -> NdarrayOrTensor: +def searchsorted(a: NdarrayTensor, v: NdarrayOrTensor, right=False, sorter=None, **kwargs) -> NdarrayTensor: """ `np.searchsorted` with equivalent implementation for torch. @@ -374,7 +374,7 @@ def isnan(x: NdarrayOrTensor) -> NdarrayOrTensor: return torch.isnan(x) -def ascontiguousarray(x: NdarrayOrTensor, **kwargs) -> NdarrayOrTensor: +def ascontiguousarray(x: NdarrayTensor, **kwargs) -> NdarrayOrTensor: """`np.ascontiguousarray` with equivalent implementation for torch (`contiguous`). Args: @@ -392,7 +392,7 @@ def ascontiguousarray(x: NdarrayOrTensor, **kwargs) -> NdarrayOrTensor: return x -def stack(x: Sequence[NdarrayOrTensor], dim: int) -> NdarrayOrTensor: +def stack(x: Sequence[NdarrayTensor], dim: int) -> NdarrayTensor: """`np.stack` with equivalent implementation for torch. Args: @@ -404,7 +404,7 @@ def stack(x: Sequence[NdarrayOrTensor], dim: int) -> NdarrayOrTensor: return torch.stack(x, dim) # type: ignore -def mode(x: NdarrayOrTensor, dim: int = -1, to_long: bool = True) -> NdarrayOrTensor: +def mode(x: NdarrayTensor, dim: int = -1, to_long: bool = True) -> NdarrayTensor: """`torch.mode` with equivalent implementation for numpy. Args: @@ -412,9 +412,8 @@ def mode(x: NdarrayOrTensor, dim: int = -1, to_long: bool = True) -> NdarrayOrTe dim: dimension along which to perform `mode` (referred to as `axis` by numpy) to_long: convert input to long before performing mode. """ - x_t: torch.Tensor dtype = torch.int64 if to_long else None - x_t, *_ = convert_data_type(x, torch.Tensor, dtype=dtype) # type: ignore + x_t, *_ = convert_data_type(x, torch.Tensor, dtype=dtype) o_t = torch.mode(x_t, dim).values o, *_ = convert_to_dst_type(o_t, x) return o diff --git a/monai/utils/type_conversion.py b/monai/utils/type_conversion.py index 8686557176..d5944e265b 100644 --- a/monai/utils/type_conversion.py +++ b/monai/utils/type_conversion.py @@ -10,12 +10,12 @@ # limitations under the License. import re -from typing import Any, Optional, Sequence, Tuple, Union +from typing import Any, Optional, Sequence, Tuple, Type, Union import numpy as np import torch -from monai.config.type_definitions import DtypeLike, NdarrayOrTensor +from monai.config.type_definitions import DtypeLike, NdarrayTensor from monai.utils import optional_import from monai.utils.module import look_up_option @@ -212,18 +212,18 @@ def convert_to_cupy(data, dtype: Optional[np.dtype] = None, wrap_sequence: bool def convert_data_type( data: Any, - output_type: Optional[type] = None, + output_type: Optional[Type[NdarrayTensor]] = None, device: Optional[torch.device] = None, - dtype: Optional[Union[DtypeLike, torch.dtype]] = None, + dtype: Union[DtypeLike, torch.dtype] = None, wrap_sequence: bool = False, -) -> Tuple[NdarrayOrTensor, type, Optional[torch.device]]: +) -> Tuple[NdarrayTensor, type, Optional[torch.device]]: """ Convert to `torch.Tensor`/`np.ndarray` from `torch.Tensor`/`np.ndarray`/`float`/`int` etc. Args: data: data to be converted - output_type: `torch.Tensor` or `np.ndarray` (if blank, unchanged) - device: if output is `torch.Tensor`, select device (if blank, unchanged) + output_type: `torch.Tensor` or `np.ndarray` (if `None`, unchanged) + device: if output is `torch.Tensor`, select device (if `None`, unchanged) dtype: dtype of output data. Converted to correct library type (e.g., `np.float32` is converted to `torch.float32` if output type is `torch.Tensor`). If left blank, it remains unchanged. @@ -241,7 +241,7 @@ def convert_data_type( (1.0, , None) """ - orig_type: Any + orig_type: type if isinstance(data, torch.Tensor): orig_type = torch.Tensor elif isinstance(data, np.ndarray): @@ -257,20 +257,22 @@ def convert_data_type( dtype_ = get_equivalent_dtype(dtype, output_type) - if output_type is torch.Tensor: - data = convert_to_tensor(data, dtype=dtype_, device=device, wrap_sequence=wrap_sequence) - elif output_type is np.ndarray: - data = convert_to_numpy(data, dtype=dtype_, wrap_sequence=wrap_sequence) - elif has_cp and output_type is cp.ndarray: - data = convert_to_cupy(data, dtype=dtype_, wrap_sequence=wrap_sequence) - else: - raise ValueError(f"Unsupported output type: {output_type}") - return data, orig_type, orig_device + data_: NdarrayTensor + if issubclass(output_type, torch.Tensor): + data_ = convert_to_tensor(data, dtype=dtype_, device=device, wrap_sequence=wrap_sequence) + return data_, orig_type, orig_device + if issubclass(output_type, np.ndarray): + data_ = convert_to_numpy(data, dtype=dtype_, wrap_sequence=wrap_sequence) + return data_, orig_type, orig_device + elif has_cp and issubclass(output_type, cp.ndarray): + data_ = convert_to_cupy(data, dtype=dtype_, wrap_sequence=wrap_sequence) + return data_, orig_type, orig_device + raise ValueError(f"Unsupported output type: {output_type}") def convert_to_dst_type( - src: Any, dst: NdarrayOrTensor, dtype: Optional[Union[DtypeLike, torch.dtype]] = None, wrap_sequence: bool = False -) -> Tuple[NdarrayOrTensor, type, Optional[torch.device]]: + src: Any, dst: NdarrayTensor, dtype: Union[DtypeLike, torch.dtype, None] = None, wrap_sequence: bool = False +) -> Tuple[NdarrayTensor, type, Optional[torch.device]]: """ Convert source data to the same data type and device as the destination data. If `dst` is an instance of `torch.Tensor` or its subclass, convert `src` to `torch.Tensor` with the same data type as `dst`, diff --git a/monai/visualize/class_activation_maps.py b/monai/visualize/class_activation_maps.py index b7e433d6fa..16fb64cb46 100644 --- a/monai/visualize/class_activation_maps.py +++ b/monai/visualize/class_activation_maps.py @@ -39,9 +39,9 @@ def _compute(data: np.ndarray) -> np.ndarray: return np.stack([scaler(i) for i in data], axis=0) if isinstance(x, torch.Tensor): - return torch.as_tensor(_compute(x.detach().cpu().numpy()), device=x.device) + return torch.as_tensor(_compute(x.detach().cpu().numpy()), device=x.device) # type: ignore - return _compute(x) + return _compute(x) # type: ignore class ModelWithHooks: diff --git a/monai/visualize/img2tensorboard.py b/monai/visualize/img2tensorboard.py index 4d4e91c6fd..0af05adf32 100644 --- a/monai/visualize/img2tensorboard.py +++ b/monai/visualize/img2tensorboard.py @@ -49,8 +49,7 @@ def _image3_animated_gif( if len(image.shape) != 3: raise AssertionError("3D image tensors expected to be in `HWD` format, len(image.shape) != 3") - image_np: np.ndarray - image_np, *_ = convert_data_type(image, output_type=np.ndarray) # type: ignore + image_np, *_ = convert_data_type(image, output_type=np.ndarray) ims = [(i * scale_factor).astype(np.uint8, copy=False) for i in np.moveaxis(image_np, frame_dim, 0)] ims = [GifImage.fromarray(im) for im in ims] img_str = b"" diff --git a/monai/visualize/occlusion_sensitivity.py b/monai/visualize/occlusion_sensitivity.py index 23c8ee857a..d87b93396a 100644 --- a/monai/visualize/occlusion_sensitivity.py +++ b/monai/visualize/occlusion_sensitivity.py @@ -276,9 +276,7 @@ def _compute_occlusion_sensitivity(self, x, b_box): return sensitivity_ims, output_im_shape - def __call__( # type: ignore - self, x: torch.Tensor, b_box: Optional[Sequence] = None - ) -> Tuple[torch.Tensor, torch.Tensor]: + def __call__(self, x: torch.Tensor, b_box: Optional[Sequence] = None) -> Tuple[torch.Tensor, torch.Tensor]: """ Args: x: Image to use for inference. Should be a tensor consisting of 1 batch. diff --git a/monai/visualize/utils.py b/monai/visualize/utils.py index 63cac7ea35..be4f3f60fc 100644 --- a/monai/visualize/utils.py +++ b/monai/visualize/utils.py @@ -93,7 +93,7 @@ def matshow3d( >>> plt.show() """ - vol: np.ndarray = convert_data_type(data=volume, output_type=np.ndarray)[0] # type: ignore + vol = convert_data_type(data=volume, output_type=np.ndarray)[0] if channel_dim is not None: if channel_dim not in [0, 1] or vol.shape[channel_dim] not in [1, 3, 4]: raise ValueError("channel_dim must be: None, 0 or 1, and channels of image must be 1, 3 or 4.") @@ -109,11 +109,11 @@ def matshow3d( while len(vol.shape) < 3: vol = np.expand_dims(vol, 0) # so that we display 2d as well - if channel_dim is not None: - vol = np.moveaxis(vol, frame_dim, -4) # move the expected dim to construct frames with `B` dim + if channel_dim is not None: # move the expected dim to construct frames with `B` dim + vol = np.moveaxis(vol, frame_dim, -4) # type: ignore vol = vol.reshape((-1, vol.shape[-3], vol.shape[-2], vol.shape[-1])) else: - vol = np.moveaxis(vol, frame_dim, -3) + vol = np.moveaxis(vol, frame_dim, -3) # type: ignore vol = vol.reshape((-1, vol.shape[-2], vol.shape[-1])) vmin = np.nanmin(vol) if vmin is None else vmin vmax = np.nanmax(vol) if vmax is None else vmax @@ -129,7 +129,7 @@ def matshow3d( if channel_dim is not None: width += [[0, 0]] # add pad width for the channel dim width += [[margin, margin]] * 2 - vol = np.pad(vol.astype(dtype, copy=False), width, mode="constant", constant_values=fill_value) + vol = np.pad(vol.astype(dtype, copy=False), width, mode="constant", constant_values=fill_value) # type: ignore im = np.block([[vol[i * cols + j] for j in range(cols)] for i in range(rows)]) if channel_dim is not None: # move channel dim to the end @@ -186,8 +186,7 @@ def blend_images( def get_label_rgb(cmap: str, label: NdarrayOrTensor): _cmap = cm.get_cmap(cmap) - label_np: np.ndarray - label_np, *_ = convert_data_type(label, np.ndarray) # type: ignore + label_np, *_ = convert_data_type(label, np.ndarray) label_rgb_np = _cmap(label_np[0]) label_rgb_np = np.moveaxis(label_rgb_np, -1, 0)[:3] label_rgb, *_ = convert_to_dst_type(label_rgb_np, label) diff --git a/setup.py b/setup.py index 83a60129e6..219f0eb957 100644 --- a/setup.py +++ b/setup.py @@ -38,7 +38,7 @@ BUILD_CUDA = (CUDA_HOME is not None) if torch.cuda.is_available() else FORCE_CUDA - _pt_version = pkg_resources.parse_version(torch.__version__).release # type: ignore[attr-defined] + _pt_version = pkg_resources.parse_version(torch.__version__).release if _pt_version is None or len(_pt_version) < 3: raise AssertionError("unknown torch version") TORCH_VERSION = int(_pt_version[0]) * 10000 + int(_pt_version[1]) * 100 + int(_pt_version[2]) diff --git a/tests/test_apply_filter.py b/tests/test_apply_filter.py index ff8480a02f..3174211f34 100644 --- a/tests/test_apply_filter.py +++ b/tests/test_apply_filter.py @@ -80,7 +80,7 @@ def test_wrong_args(self): with self.assertRaisesRegex(NotImplementedError, ""): apply_filter(torch.ones((1, 1, 1, 2, 3, 2)), torch.ones((2,))) with self.assertRaisesRegex(TypeError, ""): - apply_filter(((1, 1, 1, 2, 3, 2)), torch.ones((2,))) # type: ignore + apply_filter(((1, 1, 1, 2, 3, 2)), torch.ones((2,))) if __name__ == "__main__": diff --git a/tests/test_inverse.py b/tests/test_inverse.py index 8696d974ba..c04e9b0cd7 100644 --- a/tests/test_inverse.py +++ b/tests/test_inverse.py @@ -225,7 +225,7 @@ "Rotated 3d", "3D", 1e-1, - Rotated(KEYS, [random.uniform(np.pi / 6, np.pi) for _ in range(3)], True, dtype=np.float64), # type: ignore + Rotated(KEYS, [random.uniform(np.pi / 6, np.pi) for _ in range(3)], True, dtype=np.float64), ) ) diff --git a/tests/test_separable_filter.py b/tests/test_separable_filter.py index 167add9556..e152ad2c2b 100644 --- a/tests/test_separable_filter.py +++ b/tests/test_separable_filter.py @@ -78,7 +78,7 @@ def test_3d(self): def test_wrong_args(self): with self.assertRaisesRegex(TypeError, ""): - separable_filtering(((1, 1, 1, 2, 3, 2)), torch.ones((2,))) # type: ignore + separable_filtering(((1, 1, 1, 2, 3, 2)), torch.ones((2,))) if __name__ == "__main__": diff --git a/tests/test_spatial_resample.py b/tests/test_spatial_resample.py index 8bd23bdb2c..9ee84de85b 100644 --- a/tests/test_spatial_resample.py +++ b/tests/test_spatial_resample.py @@ -56,7 +56,7 @@ for p_src in TEST_NDARRAYS: for align in (True, False): if align and USE_COMPILED: - interp = ("nearest", "bilinear", 0, 1) # type: ignore + interp = ("nearest", "bilinear", 0, 1) else: interp = ("nearest", "bilinear") # type: ignore for interp_mode in interp: # type: ignore diff --git a/tests/test_spatial_resampled.py b/tests/test_spatial_resampled.py index 564635731c..73f83791d9 100644 --- a/tests/test_spatial_resampled.py +++ b/tests/test_spatial_resampled.py @@ -56,7 +56,7 @@ for p_src in TEST_NDARRAYS: for align in (True, False): if align and USE_COMPILED: - interp = ("nearest", "bilinear", 0, 1) # type: ignore + interp = ("nearest", "bilinear", 0, 1) else: interp = ("nearest", "bilinear") # type: ignore for interp_mode in interp: # type: ignore diff --git a/tests/test_tile_on_grid.py b/tests/test_tile_on_grid.py index d2d99654b7..09434de5e0 100644 --- a/tests/test_tile_on_grid.py +++ b/tests/test_tile_on_grid.py @@ -105,7 +105,7 @@ def make_image( for y in range(tile_count): tiles_list.append(image[:, x * step : x * step + tile_size, y * step : y * step + tile_size]) - tiles = np.stack(tiles_list, axis=0) # type: ignore + tiles = np.stack(tiles_list, axis=0) if (filter_mode == "min" or filter_mode == "max") and len(tiles) > tile_count**2: tiles = tiles[np.argsort(tiles.sum(axis=(1, 2, 3)))] diff --git a/tests/test_tile_on_grid_dict.py b/tests/test_tile_on_grid_dict.py index 7491582ce7..c6f35fe738 100644 --- a/tests/test_tile_on_grid_dict.py +++ b/tests/test_tile_on_grid_dict.py @@ -114,7 +114,7 @@ def make_image( for y in range(tile_count): tiles_list.append(image[:, x * step : x * step + tile_size, y * step : y * step + tile_size]) - tiles = np.stack(tiles_list, axis=0) # type: ignore + tiles = np.stack(tiles_list, axis=0) if (filter_mode == "min" or filter_mode == "max") and len(tiles) > tile_count**2: tiles = tiles[np.argsort(tiles.sum(axis=(1, 2, 3)))]