From cdb8391a39beb8b0ca9c8e20f73a2f807f025b74 Mon Sep 17 00:00:00 2001 From: "Wei_Chuan, Chiang" Date: Mon, 23 Dec 2024 14:50:12 +0800 Subject: [PATCH 01/26] Fixes #6840 According to the issue, this PR addresses on the meta dictionary `data['pixdim']` of NIfTI images does not update after applying the `spacing` or `spacingd`. To align with `affine`, we update `data['pixdim']` and keep the original metainfo in `data['original_pixdim']`. Additionally, this PR also update the metainfo `key_{meta_key_postfix}['pixdim']` in NIfTI images, consistent with `spaced_data_dict['image_meta_dict']['pixdim']` in issue #6832. Signed-off-by: Wei_Chuan, Chiang Co-authored-by: einsyang723 Co-authored-by: IamTingTing <6121smile@gmail.com> --- monai/data/image_reader.py | 2 ++ monai/data/meta_tensor.py | 4 ++++ monai/transforms/spatial/array.py | 3 +++ monai/transforms/spatial/dictionary.py | 5 +++++ monai/utils/enums.py | 2 ++ 5 files changed, 16 insertions(+) diff --git a/monai/data/image_reader.py b/monai/data/image_reader.py index 5bc38f69ea..75ea009598 100644 --- a/monai/data/image_reader.py +++ b/monai/data/image_reader.py @@ -989,6 +989,8 @@ def get_data(self, img) -> tuple[np.ndarray, dict]: for i, filename in zip(ensure_tuple(img), self.filenames): header = self._get_meta_dict(i) + if MetaKeys.PIXDIM in header: + header[MetaKeys.ORIGINAL_PIXDIM] = np.array(header[MetaKeys.PIXDIM], copy=True) header[MetaKeys.AFFINE] = self._get_affine(i) header[MetaKeys.ORIGINAL_AFFINE] = self._get_affine(i) header["as_closest_canonical"] = self.as_closest_canonical diff --git a/monai/data/meta_tensor.py b/monai/data/meta_tensor.py index c4c491e1b9..b2ca6860ae 100644 --- a/monai/data/meta_tensor.py +++ b/monai/data/meta_tensor.py @@ -477,6 +477,10 @@ def pixdim(self): return [affine_to_spacing(a) for a in self.affine] return affine_to_spacing(self.affine) + def set_pixdim(self) -> None: + """Update pixdim based on current affine.""" + self.meta[MetaKeys.PIXDIM][1 : 1 + len(self.pixdim)] = affine_to_spacing(self.affine) + def peek_pending_shape(self): """ Get the currently expected spatial shape as if all the pending operations are executed. diff --git a/monai/transforms/spatial/array.py b/monai/transforms/spatial/array.py index e4ed196eff..1342953ff5 100644 --- a/monai/transforms/spatial/array.py +++ b/monai/transforms/spatial/array.py @@ -535,6 +535,9 @@ def __call__( dtype=dtype, lazy=lazy_, ) + if isinstance(data_array, MetaTensor) and "pixdim" in data_array.meta: + data_array = data_array.clone() + data_array.set_pixdim() if self.recompute_affine and isinstance(data_array, MetaTensor): if lazy_: raise NotImplementedError("recompute_affine is not supported with lazy evaluation.") diff --git a/monai/transforms/spatial/dictionary.py b/monai/transforms/spatial/dictionary.py index 2b80034a07..00322abf41 100644 --- a/monai/transforms/spatial/dictionary.py +++ b/monai/transforms/spatial/dictionary.py @@ -24,11 +24,13 @@ import numpy as np import torch +import monai.transforms as transforms from monai.config import DtypeLike, KeysCollection, SequenceStr from monai.config.type_definitions import NdarrayOrTensor from monai.data.box_utils import BoxMode, StandardMode from monai.data.meta_obj import get_track_meta from monai.data.meta_tensor import MetaTensor +from monai.data.utils import is_supported_format from monai.networks.layers.simplelayers import GaussianFilter from monai.transforms.croppad.array import CenterSpatialCrop from monai.transforms.inverse import InvertibleTransform @@ -520,6 +522,9 @@ def __call__(self, data: Mapping[Hashable, torch.Tensor], lazy: bool | None = No output_spatial_shape=output_shape_k if should_match else None, lazy=lazy_, ) + if isinstance(d[key], MetaTensor) and "filename_or_obj" in d[key].meta: + if 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 diff --git a/monai/utils/enums.py b/monai/utils/enums.py index 1fbf3ffa05..24f723c36a 100644 --- a/monai/utils/enums.py +++ b/monai/utils/enums.py @@ -528,6 +528,8 @@ class MetaKeys(StrEnum): Typical keys for MetaObj.meta """ + PIXDIM = "pixdim" # MetaTensor.pixdim + ORIGINAL_PIXDIM = "original_pixdim" # the pixdim after image loading before any data processing AFFINE = "affine" # MetaTensor.affine ORIGINAL_AFFINE = "original_affine" # the affine after image loading before any data processing SPATIAL_SHAPE = "spatial_shape" # optional key for the length in each spatial dimension From 8cc61754c807d62493651c61869d45641792e820 Mon Sep 17 00:00:00 2001 From: "Wei_Chuan, Chiang" Date: Mon, 23 Dec 2024 17:19:32 +0800 Subject: [PATCH 02/26] fix issue 6840 Signed-off-by: Wei_Chuan, Chiang --- monai/data/meta_tensor.py | 2 +- monai/transforms/spatial/array.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/monai/data/meta_tensor.py b/monai/data/meta_tensor.py index b2ca6860ae..e3d7d71e31 100644 --- a/monai/data/meta_tensor.py +++ b/monai/data/meta_tensor.py @@ -479,7 +479,7 @@ def pixdim(self): def set_pixdim(self) -> None: """Update pixdim based on current affine.""" - self.meta[MetaKeys.PIXDIM][1 : 1 + len(self.pixdim)] = affine_to_spacing(self.affine) + self.meta[MetaKeys.PIXDIM][1:1+len(self.pixdim)] = affine_to_spacing(self.affine) def peek_pending_shape(self): """ diff --git a/monai/transforms/spatial/array.py b/monai/transforms/spatial/array.py index 1342953ff5..ecd62e8162 100644 --- a/monai/transforms/spatial/array.py +++ b/monai/transforms/spatial/array.py @@ -536,7 +536,7 @@ def __call__( lazy=lazy_, ) if isinstance(data_array, MetaTensor) and "pixdim" in data_array.meta: - data_array = data_array.clone() + data_array = data_array.clone() # type: MetaTensor data_array.set_pixdim() if self.recompute_affine and isinstance(data_array, MetaTensor): if lazy_: From 501bc45fa3b75e5b453a117a8a1287bd275d628f Mon Sep 17 00:00:00 2001 From: "Wei_Chuan, Chiang" Date: Mon, 23 Dec 2024 17:27:41 +0800 Subject: [PATCH 03/26] fix issue 6840 format Signed-off-by: Wei_Chuan, Chiang --- monai/data/meta_tensor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monai/data/meta_tensor.py b/monai/data/meta_tensor.py index e3d7d71e31..b2ca6860ae 100644 --- a/monai/data/meta_tensor.py +++ b/monai/data/meta_tensor.py @@ -479,7 +479,7 @@ def pixdim(self): def set_pixdim(self) -> None: """Update pixdim based on current affine.""" - self.meta[MetaKeys.PIXDIM][1:1+len(self.pixdim)] = affine_to_spacing(self.affine) + self.meta[MetaKeys.PIXDIM][1 : 1 + len(self.pixdim)] = affine_to_spacing(self.affine) def peek_pending_shape(self): """ From c5ebb0d8333bc11fc0ba34dff14b919b8fc11406 Mon Sep 17 00:00:00 2001 From: "Wei_Chuan, Chiang" Date: Mon, 23 Dec 2024 17:41:02 +0800 Subject: [PATCH 04/26] fix casting Signed-off-by: Wei_Chuan, Chiang --- monai/transforms/spatial/array.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monai/transforms/spatial/array.py b/monai/transforms/spatial/array.py index ecd62e8162..f54f76f3bf 100644 --- a/monai/transforms/spatial/array.py +++ b/monai/transforms/spatial/array.py @@ -536,7 +536,7 @@ def __call__( lazy=lazy_, ) if isinstance(data_array, MetaTensor) and "pixdim" in data_array.meta: - data_array = data_array.clone() # type: MetaTensor + data_array = cast(MetaTensor, data_array.clone()) data_array.set_pixdim() if self.recompute_affine and isinstance(data_array, MetaTensor): if lazy_: From 1aabdaec468a04da440c3165a664466faacd9ac6 Mon Sep 17 00:00:00 2001 From: "Wei_Chuan, Chiang" Date: Mon, 23 Dec 2024 19:30:50 +0800 Subject: [PATCH 05/26] fix image_only flag issue Signed-off-by: Wei_Chuan, Chiang --- monai/transforms/spatial/dictionary.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/monai/transforms/spatial/dictionary.py b/monai/transforms/spatial/dictionary.py index 00322abf41..7e664a508d 100644 --- a/monai/transforms/spatial/dictionary.py +++ b/monai/transforms/spatial/dictionary.py @@ -522,8 +522,8 @@ def __call__(self, data: Mapping[Hashable, torch.Tensor], lazy: bool | None = No output_spatial_shape=output_shape_k if should_match else None, lazy=lazy_, ) - if isinstance(d[key], MetaTensor) and "filename_or_obj" in d[key].meta: - if is_supported_format(d[key].meta["filename_or_obj"], ["nii", "nii.gz"]): + 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:] From fe05f591ce9605db5f41adc1e5c2029f6be8ad18 Mon Sep 17 00:00:00 2001 From: "Wei_Chuan, Chiang" Date: Mon, 23 Dec 2024 19:38:38 +0800 Subject: [PATCH 06/26] fix format issue Signed-off-by: Wei_Chuan, Chiang --- monai/transforms/spatial/dictionary.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/monai/transforms/spatial/dictionary.py b/monai/transforms/spatial/dictionary.py index 7e664a508d..3cca368127 100644 --- a/monai/transforms/spatial/dictionary.py +++ b/monai/transforms/spatial/dictionary.py @@ -523,7 +523,9 @@ def __call__(self, data: Mapping[Hashable, torch.Tensor], lazy: bool | None = No 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"]): + 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:] From 464a99dd2bf69645e08842f516906353fe18896c Mon Sep 17 00:00:00 2001 From: "Wei_Chuan, Chiang" Date: Mon, 17 Feb 2025 17:44:33 +0800 Subject: [PATCH 07/26] Fix issue within TraceableTransform Previously, a method was defined in `meta_tensor`, and using `data_array.clone()` introduced additional costs. After reevaluating the code, modifying the `TraceableTransform.track_transform_meta()` method executed by `SpatialResample` makes it much cleaner and more maintainable. Signed-off-by: Wei_Chuan, Chiang Co-authored-by: einsyang723 Co-authored-by: IamTingTing <6121smile@gmail.com> --- monai/data/meta_tensor.py | 4 ---- monai/transforms/inverse.py | 4 +++- monai/transforms/spatial/array.py | 3 --- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/monai/data/meta_tensor.py b/monai/data/meta_tensor.py index 28801b0e3b..6425bc0a4f 100644 --- a/monai/data/meta_tensor.py +++ b/monai/data/meta_tensor.py @@ -477,10 +477,6 @@ def pixdim(self): return [affine_to_spacing(a) for a in self.affine] return affine_to_spacing(self.affine) - def set_pixdim(self) -> None: - """Update pixdim based on current affine.""" - self.meta[MetaKeys.PIXDIM][1 : 1 + len(self.pixdim)] = affine_to_spacing(self.affine) - def peek_pending_shape(self): """ Get the currently expected spatial shape as if all the pending operations are executed. diff --git a/monai/transforms/inverse.py b/monai/transforms/inverse.py index f94f11eca9..cf93dc5433 100644 --- a/monai/transforms/inverse.py +++ b/monai/transforms/inverse.py @@ -21,7 +21,7 @@ from monai import transforms from monai.data.meta_obj import MetaObj, get_track_meta from monai.data.meta_tensor import MetaTensor -from monai.data.utils import to_affine_nd +from monai.data.utils import to_affine_nd, affine_to_spacing from monai.transforms.traits import InvertibleTrait from monai.transforms.transform import Transform from monai.utils import ( @@ -197,6 +197,8 @@ def track_transform_meta( else: raise out_obj.meta[MetaKeys.AFFINE] = convert_to_tensor(affine, device=torch.device("cpu"), dtype=torch.float64) + out_obj.meta[MetaKeys.PIXDIM] = affine_to_spacing(out_obj.meta[MetaKeys.AFFINE]) + if not (get_track_meta() and transform_info and transform_info.get(TraceKeys.TRACING)): if isinstance(data, Mapping): diff --git a/monai/transforms/spatial/array.py b/monai/transforms/spatial/array.py index f54f76f3bf..e4ed196eff 100644 --- a/monai/transforms/spatial/array.py +++ b/monai/transforms/spatial/array.py @@ -535,9 +535,6 @@ def __call__( dtype=dtype, lazy=lazy_, ) - if isinstance(data_array, MetaTensor) and "pixdim" in data_array.meta: - data_array = cast(MetaTensor, data_array.clone()) - data_array.set_pixdim() if self.recompute_affine and isinstance(data_array, MetaTensor): if lazy_: raise NotImplementedError("recompute_affine is not supported with lazy evaluation.") From b73e733df604c6fd59dba6edefca04e0652a6e3f Mon Sep 17 00:00:00 2001 From: "Wei_Chuan, Chiang" Date: Mon, 17 Feb 2025 17:49:11 +0800 Subject: [PATCH 08/26] fix format issue Signed-off-by: Wei_Chuan, Chiang Co-authored-by: einsyang723 Co-authored-by: IamTingTing <6121smile@gmail.com> --- monai/transforms/inverse.py | 3 +-- monai/utils/jupyter_utils.py | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/monai/transforms/inverse.py b/monai/transforms/inverse.py index cf93dc5433..f0f0d6cc1c 100644 --- a/monai/transforms/inverse.py +++ b/monai/transforms/inverse.py @@ -21,7 +21,7 @@ from monai import transforms from monai.data.meta_obj import MetaObj, get_track_meta from monai.data.meta_tensor import MetaTensor -from monai.data.utils import to_affine_nd, affine_to_spacing +from monai.data.utils import affine_to_spacing, to_affine_nd from monai.transforms.traits import InvertibleTrait from monai.transforms.transform import Transform from monai.utils import ( @@ -199,7 +199,6 @@ def track_transform_meta( out_obj.meta[MetaKeys.AFFINE] = convert_to_tensor(affine, device=torch.device("cpu"), dtype=torch.float64) out_obj.meta[MetaKeys.PIXDIM] = affine_to_spacing(out_obj.meta[MetaKeys.AFFINE]) - if not (get_track_meta() and transform_info and transform_info.get(TraceKeys.TRACING)): if isinstance(data, Mapping): if not isinstance(data, dict): diff --git a/monai/utils/jupyter_utils.py b/monai/utils/jupyter_utils.py index c93e93dcb9..b1b43a6767 100644 --- a/monai/utils/jupyter_utils.py +++ b/monai/utils/jupyter_utils.py @@ -234,7 +234,7 @@ def plot_engine_status( def _get_loss_from_output( - output: list[torch.Tensor | dict[str, torch.Tensor]] | dict[str, torch.Tensor] | torch.Tensor, + output: list[torch.Tensor | dict[str, torch.Tensor]] | dict[str, torch.Tensor] | torch.Tensor ) -> torch.Tensor: """Returns a single value from the network output, which is a dict or tensor.""" From 89d71ac3ebb50b4195ddb2809b131cdce8b42b1f Mon Sep 17 00:00:00 2001 From: "Wei_Chuan, Chiang" Date: Mon, 17 Feb 2025 17:44:33 +0800 Subject: [PATCH 09/26] Fix issue within TraceableTransform Previously, a method was defined in `meta_tensor`, and using `data_array.clone()` introduced additional costs. After reevaluating the code, modifying the `TraceableTransform.track_transform_meta()` method executed by `SpatialResample` makes it much cleaner and more maintainable. Signed-off-by: Wei_Chuan, Chiang Co-authored-by: einsyang723 Co-authored-by: IamTingTing <6121smile@gmail.com> --- monai/data/meta_tensor.py | 4 ---- monai/transforms/inverse.py | 3 ++- monai/transforms/spatial/array.py | 3 --- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/monai/data/meta_tensor.py b/monai/data/meta_tensor.py index 28801b0e3b..6425bc0a4f 100644 --- a/monai/data/meta_tensor.py +++ b/monai/data/meta_tensor.py @@ -477,10 +477,6 @@ def pixdim(self): return [affine_to_spacing(a) for a in self.affine] return affine_to_spacing(self.affine) - def set_pixdim(self) -> None: - """Update pixdim based on current affine.""" - self.meta[MetaKeys.PIXDIM][1 : 1 + len(self.pixdim)] = affine_to_spacing(self.affine) - def peek_pending_shape(self): """ Get the currently expected spatial shape as if all the pending operations are executed. diff --git a/monai/transforms/inverse.py b/monai/transforms/inverse.py index f94f11eca9..f0f0d6cc1c 100644 --- a/monai/transforms/inverse.py +++ b/monai/transforms/inverse.py @@ -21,7 +21,7 @@ from monai import transforms from monai.data.meta_obj import MetaObj, get_track_meta from monai.data.meta_tensor import MetaTensor -from monai.data.utils import to_affine_nd +from monai.data.utils import affine_to_spacing, to_affine_nd from monai.transforms.traits import InvertibleTrait from monai.transforms.transform import Transform from monai.utils import ( @@ -197,6 +197,7 @@ def track_transform_meta( else: raise out_obj.meta[MetaKeys.AFFINE] = convert_to_tensor(affine, device=torch.device("cpu"), dtype=torch.float64) + out_obj.meta[MetaKeys.PIXDIM] = affine_to_spacing(out_obj.meta[MetaKeys.AFFINE]) if not (get_track_meta() and transform_info and transform_info.get(TraceKeys.TRACING)): if isinstance(data, Mapping): diff --git a/monai/transforms/spatial/array.py b/monai/transforms/spatial/array.py index f54f76f3bf..e4ed196eff 100644 --- a/monai/transforms/spatial/array.py +++ b/monai/transforms/spatial/array.py @@ -535,9 +535,6 @@ def __call__( dtype=dtype, lazy=lazy_, ) - if isinstance(data_array, MetaTensor) and "pixdim" in data_array.meta: - data_array = cast(MetaTensor, data_array.clone()) - data_array.set_pixdim() if self.recompute_affine and isinstance(data_array, MetaTensor): if lazy_: raise NotImplementedError("recompute_affine is not supported with lazy evaluation.") From 6f217d12150caca7a8a4cd82d9e16ca82bc23760 Mon Sep 17 00:00:00 2001 From: "Wei_Chuan, Chiang" Date: Mon, 17 Feb 2025 18:33:16 +0800 Subject: [PATCH 10/26] fix dependency issue Signed-off-by: Wei_Chuan, Chiang Co-authored-by: einsyang723 Co-authored-by: IamTingTing <6121smile@gmail.com> --- monai/utils/jupyter_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monai/utils/jupyter_utils.py b/monai/utils/jupyter_utils.py index b1b43a6767..c93e93dcb9 100644 --- a/monai/utils/jupyter_utils.py +++ b/monai/utils/jupyter_utils.py @@ -234,7 +234,7 @@ def plot_engine_status( def _get_loss_from_output( - output: list[torch.Tensor | dict[str, torch.Tensor]] | dict[str, torch.Tensor] | torch.Tensor + output: list[torch.Tensor | dict[str, torch.Tensor]] | dict[str, torch.Tensor] | torch.Tensor, ) -> torch.Tensor: """Returns a single value from the network output, which is a dict or tensor.""" From 2d703c4974cdf506a224d8261784d909bbe4adc0 Mon Sep 17 00:00:00 2001 From: "Wei_Chuan, Chiang" Date: Tue, 18 Feb 2025 01:09:51 +0800 Subject: [PATCH 11/26] Add constraint for pixdim Signed-off-by: Wei_Chuan, Chiang Co-authored-by: einsyang723 Co-authored-by: IamTingTing <6121smile@gmail.com> --- monai/transforms/inverse.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/monai/transforms/inverse.py b/monai/transforms/inverse.py index f0f0d6cc1c..445f627208 100644 --- a/monai/transforms/inverse.py +++ b/monai/transforms/inverse.py @@ -197,7 +197,8 @@ def track_transform_meta( else: raise out_obj.meta[MetaKeys.AFFINE] = convert_to_tensor(affine, device=torch.device("cpu"), dtype=torch.float64) - out_obj.meta[MetaKeys.PIXDIM] = affine_to_spacing(out_obj.meta[MetaKeys.AFFINE]) + spacing = affine_to_spacing(out_obj.meta[MetaKeys.AFFINE]) + out_obj.meta[MetaKeys.PIXDIM][1:1+len(spacing)] = spacing if not (get_track_meta() and transform_info and transform_info.get(TraceKeys.TRACING)): if isinstance(data, Mapping): From b6dd4607f8bd2c8331a1d9059c08ccb5d7ef92bc Mon Sep 17 00:00:00 2001 From: "Wei_Chuan, Chiang" Date: Tue, 18 Feb 2025 01:21:06 +0800 Subject: [PATCH 12/26] fix format Signed-off-by: Wei_Chuan, Chiang Co-authored-by: einsyang723 Co-authored-by: IamTingTing <6121smile@gmail.com> --- monai/transforms/inverse.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monai/transforms/inverse.py b/monai/transforms/inverse.py index 445f627208..e889b2bb97 100644 --- a/monai/transforms/inverse.py +++ b/monai/transforms/inverse.py @@ -198,7 +198,7 @@ def track_transform_meta( raise out_obj.meta[MetaKeys.AFFINE] = convert_to_tensor(affine, device=torch.device("cpu"), dtype=torch.float64) spacing = affine_to_spacing(out_obj.meta[MetaKeys.AFFINE]) - out_obj.meta[MetaKeys.PIXDIM][1:1+len(spacing)] = spacing + out_obj.meta[MetaKeys.PIXDIM][1 : 1 + len(spacing)] = spacing if not (get_track_meta() and transform_info and transform_info.get(TraceKeys.TRACING)): if isinstance(data, Mapping): From a34a656a7af318219ef7fdad48f4d600ef7e9d8a Mon Sep 17 00:00:00 2001 From: "Wei_Chuan, Chiang" Date: Wed, 19 Feb 2025 14:26:52 +0800 Subject: [PATCH 13/26] fix constraint for pixdim in track_transform_meta() function Signed-off-by: Wei_Chuan, Chiang Co-authored-by: einsyang723 Co-authored-by: IamTingTing <6121smile@gmail.com> --- monai/transforms/inverse.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/monai/transforms/inverse.py b/monai/transforms/inverse.py index e889b2bb97..780674ca4a 100644 --- a/monai/transforms/inverse.py +++ b/monai/transforms/inverse.py @@ -197,8 +197,9 @@ def track_transform_meta( else: raise out_obj.meta[MetaKeys.AFFINE] = convert_to_tensor(affine, device=torch.device("cpu"), dtype=torch.float64) - spacing = affine_to_spacing(out_obj.meta[MetaKeys.AFFINE]) - out_obj.meta[MetaKeys.PIXDIM][1 : 1 + len(spacing)] = spacing + if MetaKeys.PIXDIM in out_obj.meta: + spacing = affine_to_spacing(out_obj.meta[MetaKeys.AFFINE]) + out_obj.meta[MetaKeys.PIXDIM][1 : 1 + len(spacing)] = spacing if not (get_track_meta() and transform_info and transform_info.get(TraceKeys.TRACING)): if isinstance(data, Mapping): From 8503e3428324fc89a1889c67152a4aaea792249d Mon Sep 17 00:00:00 2001 From: "Wei_Chuan, Chiang" Date: Mon, 23 Dec 2024 14:50:12 +0800 Subject: [PATCH 14/26] Fixes #6840 According to the issue, this PR addresses on the meta dictionary `data['pixdim']` of NIfTI images does not update after applying the `spacing` or `spacingd`. To align with `affine`, we update `data['pixdim']` and keep the original metainfo in `data['original_pixdim']`. Additionally, this PR also update the metainfo `key_{meta_key_postfix}['pixdim']` in NIfTI images, consistent with `spaced_data_dict['image_meta_dict']['pixdim']` in issue #6832. Signed-off-by: Wei_Chuan, Chiang Co-authored-by: einsyang723 Co-authored-by: IamTingTing <6121smile@gmail.com> --- monai/data/image_reader.py | 2 ++ monai/data/meta_tensor.py | 4 ++++ monai/transforms/spatial/array.py | 3 +++ monai/transforms/spatial/dictionary.py | 5 +++++ monai/utils/enums.py | 2 ++ 5 files changed, 16 insertions(+) diff --git a/monai/data/image_reader.py b/monai/data/image_reader.py index 003ec2cf0b..0d07020cb9 100644 --- a/monai/data/image_reader.py +++ b/monai/data/image_reader.py @@ -1110,6 +1110,8 @@ def get_data(self, img) -> tuple[np.ndarray, dict]: for i, filename in zip(ensure_tuple(img), self.filenames): header = self._get_meta_dict(i) + if MetaKeys.PIXDIM in header: + header[MetaKeys.ORIGINAL_PIXDIM] = np.array(header[MetaKeys.PIXDIM], copy=True) header[MetaKeys.AFFINE] = self._get_affine(i) header[MetaKeys.ORIGINAL_AFFINE] = self._get_affine(i) header["as_closest_canonical"] = self.as_closest_canonical diff --git a/monai/data/meta_tensor.py b/monai/data/meta_tensor.py index 6425bc0a4f..28801b0e3b 100644 --- a/monai/data/meta_tensor.py +++ b/monai/data/meta_tensor.py @@ -477,6 +477,10 @@ def pixdim(self): return [affine_to_spacing(a) for a in self.affine] return affine_to_spacing(self.affine) + def set_pixdim(self) -> None: + """Update pixdim based on current affine.""" + self.meta[MetaKeys.PIXDIM][1 : 1 + len(self.pixdim)] = affine_to_spacing(self.affine) + def peek_pending_shape(self): """ Get the currently expected spatial shape as if all the pending operations are executed. diff --git a/monai/transforms/spatial/array.py b/monai/transforms/spatial/array.py index e4ed196eff..1342953ff5 100644 --- a/monai/transforms/spatial/array.py +++ b/monai/transforms/spatial/array.py @@ -535,6 +535,9 @@ def __call__( dtype=dtype, lazy=lazy_, ) + if isinstance(data_array, MetaTensor) and "pixdim" in data_array.meta: + data_array = data_array.clone() + data_array.set_pixdim() if self.recompute_affine and isinstance(data_array, MetaTensor): if lazy_: raise NotImplementedError("recompute_affine is not supported with lazy evaluation.") diff --git a/monai/transforms/spatial/dictionary.py b/monai/transforms/spatial/dictionary.py index 2b80034a07..00322abf41 100644 --- a/monai/transforms/spatial/dictionary.py +++ b/monai/transforms/spatial/dictionary.py @@ -24,11 +24,13 @@ import numpy as np import torch +import monai.transforms as transforms from monai.config import DtypeLike, KeysCollection, SequenceStr from monai.config.type_definitions import NdarrayOrTensor from monai.data.box_utils import BoxMode, StandardMode from monai.data.meta_obj import get_track_meta from monai.data.meta_tensor import MetaTensor +from monai.data.utils import is_supported_format from monai.networks.layers.simplelayers import GaussianFilter from monai.transforms.croppad.array import CenterSpatialCrop from monai.transforms.inverse import InvertibleTransform @@ -520,6 +522,9 @@ def __call__(self, data: Mapping[Hashable, torch.Tensor], lazy: bool | None = No output_spatial_shape=output_shape_k if should_match else None, lazy=lazy_, ) + if isinstance(d[key], MetaTensor) and "filename_or_obj" in d[key].meta: + if 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 diff --git a/monai/utils/enums.py b/monai/utils/enums.py index 3463a92e4b..3d8c18a6a3 100644 --- a/monai/utils/enums.py +++ b/monai/utils/enums.py @@ -529,6 +529,8 @@ class MetaKeys(StrEnum): Typical keys for MetaObj.meta """ + PIXDIM = "pixdim" # MetaTensor.pixdim + ORIGINAL_PIXDIM = "original_pixdim" # the pixdim after image loading before any data processing AFFINE = "affine" # MetaTensor.affine ORIGINAL_AFFINE = "original_affine" # the affine after image loading before any data processing SPATIAL_SHAPE = "spatial_shape" # optional key for the length in each spatial dimension From 173c6c1e63b1b2b52401d443bd8511e2133f3ccc Mon Sep 17 00:00:00 2001 From: "Wei_Chuan, Chiang" Date: Mon, 23 Dec 2024 17:19:32 +0800 Subject: [PATCH 15/26] fix issue 6840 Signed-off-by: Wei_Chuan, Chiang --- monai/data/meta_tensor.py | 2 +- monai/transforms/spatial/array.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/monai/data/meta_tensor.py b/monai/data/meta_tensor.py index 28801b0e3b..d2ee103f08 100644 --- a/monai/data/meta_tensor.py +++ b/monai/data/meta_tensor.py @@ -479,7 +479,7 @@ def pixdim(self): def set_pixdim(self) -> None: """Update pixdim based on current affine.""" - self.meta[MetaKeys.PIXDIM][1 : 1 + len(self.pixdim)] = affine_to_spacing(self.affine) + self.meta[MetaKeys.PIXDIM][1:1+len(self.pixdim)] = affine_to_spacing(self.affine) def peek_pending_shape(self): """ diff --git a/monai/transforms/spatial/array.py b/monai/transforms/spatial/array.py index 1342953ff5..ecd62e8162 100644 --- a/monai/transforms/spatial/array.py +++ b/monai/transforms/spatial/array.py @@ -536,7 +536,7 @@ def __call__( lazy=lazy_, ) if isinstance(data_array, MetaTensor) and "pixdim" in data_array.meta: - data_array = data_array.clone() + data_array = data_array.clone() # type: MetaTensor data_array.set_pixdim() if self.recompute_affine and isinstance(data_array, MetaTensor): if lazy_: From 5250d1531c0e4677c10c66a85e78980980361d0c Mon Sep 17 00:00:00 2001 From: "Wei_Chuan, Chiang" Date: Mon, 23 Dec 2024 17:27:41 +0800 Subject: [PATCH 16/26] fix issue 6840 format Signed-off-by: Wei_Chuan, Chiang --- monai/data/meta_tensor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monai/data/meta_tensor.py b/monai/data/meta_tensor.py index d2ee103f08..28801b0e3b 100644 --- a/monai/data/meta_tensor.py +++ b/monai/data/meta_tensor.py @@ -479,7 +479,7 @@ def pixdim(self): def set_pixdim(self) -> None: """Update pixdim based on current affine.""" - self.meta[MetaKeys.PIXDIM][1:1+len(self.pixdim)] = affine_to_spacing(self.affine) + self.meta[MetaKeys.PIXDIM][1 : 1 + len(self.pixdim)] = affine_to_spacing(self.affine) def peek_pending_shape(self): """ From f8fcae3a84071659844795a36a589e627d45ee48 Mon Sep 17 00:00:00 2001 From: "Wei_Chuan, Chiang" Date: Mon, 23 Dec 2024 17:41:02 +0800 Subject: [PATCH 17/26] fix casting Signed-off-by: Wei_Chuan, Chiang --- monai/transforms/spatial/array.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monai/transforms/spatial/array.py b/monai/transforms/spatial/array.py index ecd62e8162..f54f76f3bf 100644 --- a/monai/transforms/spatial/array.py +++ b/monai/transforms/spatial/array.py @@ -536,7 +536,7 @@ def __call__( lazy=lazy_, ) if isinstance(data_array, MetaTensor) and "pixdim" in data_array.meta: - data_array = data_array.clone() # type: MetaTensor + data_array = cast(MetaTensor, data_array.clone()) data_array.set_pixdim() if self.recompute_affine and isinstance(data_array, MetaTensor): if lazy_: From 56393135ab1f9d5e8402ce97b93df8ae25599147 Mon Sep 17 00:00:00 2001 From: "Wei_Chuan, Chiang" Date: Mon, 23 Dec 2024 19:30:50 +0800 Subject: [PATCH 18/26] fix image_only flag issue Signed-off-by: Wei_Chuan, Chiang --- monai/transforms/spatial/dictionary.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/monai/transforms/spatial/dictionary.py b/monai/transforms/spatial/dictionary.py index 00322abf41..7e664a508d 100644 --- a/monai/transforms/spatial/dictionary.py +++ b/monai/transforms/spatial/dictionary.py @@ -522,8 +522,8 @@ def __call__(self, data: Mapping[Hashable, torch.Tensor], lazy: bool | None = No output_spatial_shape=output_shape_k if should_match else None, lazy=lazy_, ) - if isinstance(d[key], MetaTensor) and "filename_or_obj" in d[key].meta: - if is_supported_format(d[key].meta["filename_or_obj"], ["nii", "nii.gz"]): + 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:] From 8c73c695c7071540a0385b3e28ea9d4a42d6969f Mon Sep 17 00:00:00 2001 From: "Wei_Chuan, Chiang" Date: Mon, 23 Dec 2024 19:38:38 +0800 Subject: [PATCH 19/26] fix format issue Signed-off-by: Wei_Chuan, Chiang --- monai/transforms/spatial/dictionary.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/monai/transforms/spatial/dictionary.py b/monai/transforms/spatial/dictionary.py index 7e664a508d..3cca368127 100644 --- a/monai/transforms/spatial/dictionary.py +++ b/monai/transforms/spatial/dictionary.py @@ -523,7 +523,9 @@ def __call__(self, data: Mapping[Hashable, torch.Tensor], lazy: bool | None = No 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"]): + 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:] From 0f18a3b052fdb95185632161183067f4809b5c5e Mon Sep 17 00:00:00 2001 From: "Wei_Chuan, Chiang" Date: Mon, 17 Feb 2025 17:44:33 +0800 Subject: [PATCH 20/26] Fix issue within TraceableTransform Previously, a method was defined in `meta_tensor`, and using `data_array.clone()` introduced additional costs. After reevaluating the code, modifying the `TraceableTransform.track_transform_meta()` method executed by `SpatialResample` makes it much cleaner and more maintainable. Signed-off-by: Wei_Chuan, Chiang Co-authored-by: einsyang723 Co-authored-by: IamTingTing <6121smile@gmail.com> --- monai/data/meta_tensor.py | 4 ---- monai/transforms/inverse.py | 4 +++- monai/transforms/spatial/array.py | 3 --- 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/monai/data/meta_tensor.py b/monai/data/meta_tensor.py index 28801b0e3b..6425bc0a4f 100644 --- a/monai/data/meta_tensor.py +++ b/monai/data/meta_tensor.py @@ -477,10 +477,6 @@ def pixdim(self): return [affine_to_spacing(a) for a in self.affine] return affine_to_spacing(self.affine) - def set_pixdim(self) -> None: - """Update pixdim based on current affine.""" - self.meta[MetaKeys.PIXDIM][1 : 1 + len(self.pixdim)] = affine_to_spacing(self.affine) - def peek_pending_shape(self): """ Get the currently expected spatial shape as if all the pending operations are executed. diff --git a/monai/transforms/inverse.py b/monai/transforms/inverse.py index f94f11eca9..cf93dc5433 100644 --- a/monai/transforms/inverse.py +++ b/monai/transforms/inverse.py @@ -21,7 +21,7 @@ from monai import transforms from monai.data.meta_obj import MetaObj, get_track_meta from monai.data.meta_tensor import MetaTensor -from monai.data.utils import to_affine_nd +from monai.data.utils import to_affine_nd, affine_to_spacing from monai.transforms.traits import InvertibleTrait from monai.transforms.transform import Transform from monai.utils import ( @@ -197,6 +197,8 @@ def track_transform_meta( else: raise out_obj.meta[MetaKeys.AFFINE] = convert_to_tensor(affine, device=torch.device("cpu"), dtype=torch.float64) + out_obj.meta[MetaKeys.PIXDIM] = affine_to_spacing(out_obj.meta[MetaKeys.AFFINE]) + if not (get_track_meta() and transform_info and transform_info.get(TraceKeys.TRACING)): if isinstance(data, Mapping): diff --git a/monai/transforms/spatial/array.py b/monai/transforms/spatial/array.py index f54f76f3bf..e4ed196eff 100644 --- a/monai/transforms/spatial/array.py +++ b/monai/transforms/spatial/array.py @@ -535,9 +535,6 @@ def __call__( dtype=dtype, lazy=lazy_, ) - if isinstance(data_array, MetaTensor) and "pixdim" in data_array.meta: - data_array = cast(MetaTensor, data_array.clone()) - data_array.set_pixdim() if self.recompute_affine and isinstance(data_array, MetaTensor): if lazy_: raise NotImplementedError("recompute_affine is not supported with lazy evaluation.") From 707e1024c29c6a2dfffcb0089984740901b053f6 Mon Sep 17 00:00:00 2001 From: "Wei_Chuan, Chiang" Date: Mon, 17 Feb 2025 17:49:11 +0800 Subject: [PATCH 21/26] fix format issue Signed-off-by: Wei_Chuan, Chiang Co-authored-by: einsyang723 Co-authored-by: IamTingTing <6121smile@gmail.com> --- monai/transforms/inverse.py | 3 +-- monai/utils/jupyter_utils.py | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/monai/transforms/inverse.py b/monai/transforms/inverse.py index cf93dc5433..f0f0d6cc1c 100644 --- a/monai/transforms/inverse.py +++ b/monai/transforms/inverse.py @@ -21,7 +21,7 @@ from monai import transforms from monai.data.meta_obj import MetaObj, get_track_meta from monai.data.meta_tensor import MetaTensor -from monai.data.utils import to_affine_nd, affine_to_spacing +from monai.data.utils import affine_to_spacing, to_affine_nd from monai.transforms.traits import InvertibleTrait from monai.transforms.transform import Transform from monai.utils import ( @@ -199,7 +199,6 @@ def track_transform_meta( out_obj.meta[MetaKeys.AFFINE] = convert_to_tensor(affine, device=torch.device("cpu"), dtype=torch.float64) out_obj.meta[MetaKeys.PIXDIM] = affine_to_spacing(out_obj.meta[MetaKeys.AFFINE]) - if not (get_track_meta() and transform_info and transform_info.get(TraceKeys.TRACING)): if isinstance(data, Mapping): if not isinstance(data, dict): diff --git a/monai/utils/jupyter_utils.py b/monai/utils/jupyter_utils.py index c93e93dcb9..b1b43a6767 100644 --- a/monai/utils/jupyter_utils.py +++ b/monai/utils/jupyter_utils.py @@ -234,7 +234,7 @@ def plot_engine_status( def _get_loss_from_output( - output: list[torch.Tensor | dict[str, torch.Tensor]] | dict[str, torch.Tensor] | torch.Tensor, + output: list[torch.Tensor | dict[str, torch.Tensor]] | dict[str, torch.Tensor] | torch.Tensor ) -> torch.Tensor: """Returns a single value from the network output, which is a dict or tensor.""" From 7bee28697db156b9f99f3fefd0048cb28df4895c Mon Sep 17 00:00:00 2001 From: "Wei_Chuan, Chiang" Date: Mon, 17 Feb 2025 18:33:16 +0800 Subject: [PATCH 22/26] fix dependency issue Signed-off-by: Wei_Chuan, Chiang Co-authored-by: einsyang723 Co-authored-by: IamTingTing <6121smile@gmail.com> --- monai/utils/jupyter_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monai/utils/jupyter_utils.py b/monai/utils/jupyter_utils.py index b1b43a6767..c93e93dcb9 100644 --- a/monai/utils/jupyter_utils.py +++ b/monai/utils/jupyter_utils.py @@ -234,7 +234,7 @@ def plot_engine_status( def _get_loss_from_output( - output: list[torch.Tensor | dict[str, torch.Tensor]] | dict[str, torch.Tensor] | torch.Tensor + output: list[torch.Tensor | dict[str, torch.Tensor]] | dict[str, torch.Tensor] | torch.Tensor, ) -> torch.Tensor: """Returns a single value from the network output, which is a dict or tensor.""" From 651eac59ff26fe619e8dd7f41426310d169ed6b4 Mon Sep 17 00:00:00 2001 From: "Wei_Chuan, Chiang" Date: Tue, 18 Feb 2025 01:09:51 +0800 Subject: [PATCH 23/26] Add constraint for pixdim Signed-off-by: Wei_Chuan, Chiang Co-authored-by: einsyang723 Co-authored-by: IamTingTing <6121smile@gmail.com> --- monai/transforms/inverse.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/monai/transforms/inverse.py b/monai/transforms/inverse.py index f0f0d6cc1c..445f627208 100644 --- a/monai/transforms/inverse.py +++ b/monai/transforms/inverse.py @@ -197,7 +197,8 @@ def track_transform_meta( else: raise out_obj.meta[MetaKeys.AFFINE] = convert_to_tensor(affine, device=torch.device("cpu"), dtype=torch.float64) - out_obj.meta[MetaKeys.PIXDIM] = affine_to_spacing(out_obj.meta[MetaKeys.AFFINE]) + spacing = affine_to_spacing(out_obj.meta[MetaKeys.AFFINE]) + out_obj.meta[MetaKeys.PIXDIM][1:1+len(spacing)] = spacing if not (get_track_meta() and transform_info and transform_info.get(TraceKeys.TRACING)): if isinstance(data, Mapping): From ae086d0c28fc0e177e94ce4e2ad7b466e86a32a3 Mon Sep 17 00:00:00 2001 From: "Wei_Chuan, Chiang" Date: Tue, 18 Feb 2025 01:21:06 +0800 Subject: [PATCH 24/26] fix format Signed-off-by: Wei_Chuan, Chiang Co-authored-by: einsyang723 Co-authored-by: IamTingTing <6121smile@gmail.com> --- monai/transforms/inverse.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monai/transforms/inverse.py b/monai/transforms/inverse.py index 445f627208..e889b2bb97 100644 --- a/monai/transforms/inverse.py +++ b/monai/transforms/inverse.py @@ -198,7 +198,7 @@ def track_transform_meta( raise out_obj.meta[MetaKeys.AFFINE] = convert_to_tensor(affine, device=torch.device("cpu"), dtype=torch.float64) spacing = affine_to_spacing(out_obj.meta[MetaKeys.AFFINE]) - out_obj.meta[MetaKeys.PIXDIM][1:1+len(spacing)] = spacing + out_obj.meta[MetaKeys.PIXDIM][1 : 1 + len(spacing)] = spacing if not (get_track_meta() and transform_info and transform_info.get(TraceKeys.TRACING)): if isinstance(data, Mapping): From 9e515763f360cebd85a9bec330a4c7ec09a53af9 Mon Sep 17 00:00:00 2001 From: "Wei_Chuan, Chiang" Date: Wed, 19 Feb 2025 14:26:52 +0800 Subject: [PATCH 25/26] fix constraint for pixdim in track_transform_meta() function Signed-off-by: Wei_Chuan, Chiang Co-authored-by: einsyang723 Co-authored-by: IamTingTing <6121smile@gmail.com> --- monai/transforms/inverse.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/monai/transforms/inverse.py b/monai/transforms/inverse.py index e889b2bb97..780674ca4a 100644 --- a/monai/transforms/inverse.py +++ b/monai/transforms/inverse.py @@ -197,8 +197,9 @@ def track_transform_meta( else: raise out_obj.meta[MetaKeys.AFFINE] = convert_to_tensor(affine, device=torch.device("cpu"), dtype=torch.float64) - spacing = affine_to_spacing(out_obj.meta[MetaKeys.AFFINE]) - out_obj.meta[MetaKeys.PIXDIM][1 : 1 + len(spacing)] = spacing + if MetaKeys.PIXDIM in out_obj.meta: + spacing = affine_to_spacing(out_obj.meta[MetaKeys.AFFINE]) + out_obj.meta[MetaKeys.PIXDIM][1 : 1 + len(spacing)] = spacing if not (get_track_meta() and transform_info and transform_info.get(TraceKeys.TRACING)): if isinstance(data, Mapping): From fc1156afb23eae23e0b96dfdfdae710b4ad12008 Mon Sep 17 00:00:00 2001 From: "Wei_Chuan, Chiang" Date: Thu, 6 Mar 2025 17:42:05 +0800 Subject: [PATCH 26/26] fix the issue of the naming rule of key_meta_dict Checking all dictionary keys that start with `{key}_` to support custom settings of `meta_keys` and `meta_key_postfix`. This ensures that no matter how users configure the naming conventions in `LoadImaged`, we can correctly synchronize metadata from the MetaTensor to the corresponding meta dictionary. Signed-off-by: Wei_Chuan, Chiang Co-authored-by: einsyang723 Co-authored-by: IamTingTing <6121smile@gmail.com> --- monai/transforms/spatial/dictionary.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/monai/transforms/spatial/dictionary.py b/monai/transforms/spatial/dictionary.py index 3cca368127..b4171f2003 100644 --- a/monai/transforms/spatial/dictionary.py +++ b/monai/transforms/spatial/dictionary.py @@ -24,7 +24,6 @@ import numpy as np import torch -import monai.transforms as transforms from monai.config import DtypeLike, KeysCollection, SequenceStr from monai.config.type_definitions import NdarrayOrTensor from monai.data.box_utils import BoxMode, StandardMode @@ -522,11 +521,13 @@ def __call__(self, data: Mapping[Hashable, torch.Tensor], lazy: bool | None = No 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 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