Repository: Project-MONAI/MONAI
File: monai/transforms/spatial/dictionary.py (Python)

Code before:

        for key, mode, padding_mode, align_corners, dtype, scale_extent in self.key_iterator(
            d, self.mode, self.padding_mode, self.align_corners, self.dtype, self.scale_extent
        ):
            if self.ensure_same_shape and isinstance(d[key], MetaTensor):
                if _init_shape is None and _pixdim is None:
                    _init_shape, _pixdim = d[key].peek_pending_shape(), d[key].pixdim
                else:
                    should_match = np.allclose(_init_shape, d[key].peek_pending_shape()) and np.allclose(
                        _pixdim, d[key].pixdim, atol=1e-3
                    )
            d[key] = self.spacing_transform(
                data_array=d[key],
                mode=mode,
                padding_mode=padding_mode,
                align_corners=align_corners,
                dtype=dtype,
                scale_extent=scale_extent,
                output_spatial_shape=output_shape_k if should_match else None,
                lazy=lazy_,
            )
            if isinstance(d[key], MetaTensor) and f"{key}_meta_dict" in d:
                if "filename_or_obj" in d[key].meta and is_supported_format(
                    d[key].meta["filename_or_obj"], ["nii", "nii.gz"]
                ):
                    d = transforms.sync_meta_info(key, d)
            if output_shape_k is None:
                output_shape_k = d[key].peek_pending_shape() if isinstance(d[key], MetaTensor) else d[key].shape[1:]
        return d

    def inverse(self, data: Mapping[Hashable, NdarrayOrTensor]) -> dict[Hashable, NdarrayOrTensor]:
        d = dict(data)
        for key in self.key_iterator(d):
            d[key] = self.spacing_transform.inverse(cast(torch.Tensor, d[key]))
        return d


class Orientationd(MapTransform, InvertibleTransform, LazyTransform):
    """
    Dictionary-based wrapper of :py:class:`monai.transforms.Orientation`.

    This transform assumes the channel-first input format.
    In the case of using this transform for normalizing the orientations of images,
    it should be used before any anisotropic spatial transforms.

    This transform is capable of lazy execution. See the :ref:`Lazy Resampling topic<lazy_resampling>`
    for more information.
    """

    backend = Orientation.backend


Review comment (suggestion):
May I ask why we need this sync here seems it already been done in the `MapTransform`?
https://github.com/Project-MONAI/MONAI/blob/996e876e7542f683508aa04e74b97e284bbde72b/monai/transforms/transform.py#L426

Code after:

        for key, mode, padding_mode, align_corners, dtype, scale_extent in self.key_iterator(
            d, self.mode, self.padding_mode, self.align_corners, self.dtype, self.scale_extent
        ):
            if self.ensure_same_shape and isinstance(d[key], MetaTensor):
                if _init_shape is None and _pixdim is None:
                    _init_shape, _pixdim = d[key].peek_pending_shape(), d[key].pixdim
                else:
                    should_match = np.allclose(_init_shape, d[key].peek_pending_shape()) and np.allclose(
                        _pixdim, d[key].pixdim, atol=1e-3
                    )
            d[key] = self.spacing_transform(
                data_array=d[key],
                mode=mode,
                padding_mode=padding_mode,
                align_corners=align_corners,
                dtype=dtype,
                scale_extent=scale_extent,
                output_spatial_shape=output_shape_k if should_match else None,
                lazy=lazy_,
            )
            if isinstance(d[key], MetaTensor):
                meta_keys = [k for k in d.keys() if k is not None and k.startswith(f"{key}_")]
                for meta_key in meta_keys:
                    if "filename_or_obj" in d[key].meta and is_supported_format(
                        d[key].meta["filename_or_obj"], ["nii", "nii.gz"]
                    ):
                        d[meta_key].update(d[key].meta)
            if output_shape_k is None:
                output_shape_k = d[key].peek_pending_shape() if isinstance(d[key], MetaTensor) else d[key].shape[1:]
        return d

    def inverse(self, data: Mapping[Hashable, NdarrayOrTensor]) -> dict[Hashable, NdarrayOrTensor]:
        d = dict(data)
        for key in self.key_iterator(d):
            d[key] = self.spacing_transform.inverse(cast(torch.Tensor, d[key]))
        return d


class Orientationd(MapTransform, InvertibleTransform, LazyTransform):
    """
    Dictionary-based wrapper of :py:class:`monai.transforms.Orientation`.

    This transform assumes the channel-first input format.
    In the case of using this transform for normalizing the orientations of images,
    it should be used before any anisotropic spatial transforms.

    This transform is capable of lazy execution. See the :ref:`Lazy Resampling topic<lazy_resampling>`
    for more information.
    """