From 04ca47738714dfef98616c26d6395eb56f30169f Mon Sep 17 00:00:00 2001 From: KumoLiu Date: Wed, 13 Sep 2023 14:35:43 +0800 Subject: [PATCH 1/6] fix #6974 Signed-off-by: KumoLiu --- monai/transforms/transform.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monai/transforms/transform.py b/monai/transforms/transform.py index e35335ba0e..8af3c9ade0 100644 --- a/monai/transforms/transform.py +++ b/monai/transforms/transform.py @@ -104,7 +104,7 @@ def apply_transform( map_items: bool = True, unpack_items: bool = False, log_stats: bool | str = False, - lazy: bool | None = False, + lazy: bool | None = None, overrides: dict | None = None, ) -> list[ReturnType] | ReturnType: """ From 9157e77987aa1646c7ddb6e085842139622aab90 Mon Sep 17 00:00:00 2001 From: KumoLiu Date: Wed, 13 Sep 2023 14:43:33 +0800 Subject: [PATCH 2/6] fix #6974 Signed-off-by: KumoLiu --- monai/data/dataset.py | 2 +- monai/transforms/transform.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/monai/data/dataset.py b/monai/data/dataset.py index 4f2061426e..43b8a890b7 100644 --- a/monai/data/dataset.py +++ b/monai/data/dataset.py @@ -95,7 +95,7 @@ def _transform(self, index: int): Fetch single data item from `self.data`. """ data_i = self.data[index] - return apply_transform(self.transform, data_i) if self.transform is not None else data_i + return apply_transform(self.transform, data_i, lazy=self.transform.lazy) if self.transform is not None else data_i def __getitem__(self, index: int | slice | Sequence[int]): """ diff --git a/monai/transforms/transform.py b/monai/transforms/transform.py index 8af3c9ade0..e4e90a53a2 100644 --- a/monai/transforms/transform.py +++ b/monai/transforms/transform.py @@ -104,7 +104,7 @@ def apply_transform( map_items: bool = True, unpack_items: bool = False, log_stats: bool | str = False, - lazy: bool | None = None, + lazy: bool | None = False, overrides: dict | None = None, ) -> list[ReturnType] | ReturnType: """ @@ -124,7 +124,7 @@ def apply_transform( disables the logger for processing pipeline errors. Setting it to None or True will enable logging to the default logger name. Setting it to a string specifies the logger to which errors should be logged. lazy: whether to execute in lazy mode or not. See the :ref:`Lazy Resampling topic for more - information about lazy resampling. + information about lazy resampling. overrides: optional overrides to apply to transform parameters. This parameter is ignored unless transforms are being executed lazily. See the :ref:`Lazy Resampling topic for more details and examples of its usage. From 4aa85fc5e60953263ed9763cad4463fe0ec20026 Mon Sep 17 00:00:00 2001 From: KumoLiu Date: Wed, 13 Sep 2023 14:53:21 +0800 Subject: [PATCH 3/6] Revert "fix #6974" This reverts commit 9157e77987aa1646c7ddb6e085842139622aab90. --- monai/data/dataset.py | 2 +- monai/transforms/transform.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/monai/data/dataset.py b/monai/data/dataset.py index 43b8a890b7..4f2061426e 100644 --- a/monai/data/dataset.py +++ b/monai/data/dataset.py @@ -95,7 +95,7 @@ def _transform(self, index: int): Fetch single data item from `self.data`. """ data_i = self.data[index] - return apply_transform(self.transform, data_i, lazy=self.transform.lazy) if self.transform is not None else data_i + return apply_transform(self.transform, data_i) if self.transform is not None else data_i def __getitem__(self, index: int | slice | Sequence[int]): """ diff --git a/monai/transforms/transform.py b/monai/transforms/transform.py index e4e90a53a2..8af3c9ade0 100644 --- a/monai/transforms/transform.py +++ b/monai/transforms/transform.py @@ -104,7 +104,7 @@ def apply_transform( map_items: bool = True, unpack_items: bool = False, log_stats: bool | str = False, - lazy: bool | None = False, + lazy: bool | None = None, overrides: dict | None = None, ) -> list[ReturnType] | ReturnType: """ @@ -124,7 +124,7 @@ def apply_transform( disables the logger for processing pipeline errors. Setting it to None or True will enable logging to the default logger name. Setting it to a string specifies the logger to which errors should be logged. lazy: whether to execute in lazy mode or not. See the :ref:`Lazy Resampling topic for more - information about lazy resampling. + information about lazy resampling. overrides: optional overrides to apply to transform parameters. This parameter is ignored unless transforms are being executed lazily. See the :ref:`Lazy Resampling topic for more details and examples of its usage. From 8d0573730ea4026e537bf84fc54ef1a38b94846e Mon Sep 17 00:00:00 2001 From: KumoLiu Date: Wed, 13 Sep 2023 15:29:19 +0800 Subject: [PATCH 4/6] add unittests Signed-off-by: KumoLiu --- tests/test_compose.py | 6 ++++++ tests/test_dataset.py | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/tests/test_compose.py b/tests/test_compose.py index 453ae3868d..a1952b102f 100644 --- a/tests/test_compose.py +++ b/tests/test_compose.py @@ -607,6 +607,12 @@ def test_compose_with_logger(self, keys, pipeline): "INFO - Pending transforms applied: applied_operations: 1\n" ), ], + [ + mt.OneOf, + (mt.Flip(0),), + False, + ("INFO - Apply pending transforms - lazy: False, pending: 0, " "upcoming 'Flip', transform.lazy: False\n"), + ], ] diff --git a/tests/test_dataset.py b/tests/test_dataset.py index 667595caa4..14445569f4 100644 --- a/tests/test_dataset.py +++ b/tests/test_dataset.py @@ -11,9 +11,12 @@ from __future__ import annotations +import logging import os import tempfile import unittest +from copy import deepcopy +from io import StringIO import nibabel as nib import numpy as np @@ -21,6 +24,7 @@ from monai.data import Dataset from monai.transforms import Compose, LoadImaged, SimulateDelayd +from tests.test_compose import TEST_COMPOSE_LAZY_ON_CALL_LOGGING_TEST_CASES, data_from_keys TEST_CASE_1 = [(128, 128, 128)] @@ -89,6 +93,39 @@ def test_shape(self, expected_shape): for d in data4_list: self.assertTupleEqual(d["image"].shape, expected_shape) + def test_dataset_lazy_on_call(self): + data = np.zeros((1, 5, 5)) + data[0, 0:2, 0:2] = 1 + + +class TestDatsesetWithLazy(unittest.TestCase): + LOGGER_NAME = "a_logger_name" + + def init_logger(self, name=LOGGER_NAME): + stream = StringIO() + handler = logging.StreamHandler(stream) + formatter = logging.Formatter("%(levelname)s - %(message)s") + handler.setFormatter(formatter) + logger = logging.getLogger(name) + logger.setLevel(logging.INFO) + while len(logger.handlers) > 0: + logger.removeHandler(logger.handlers[-1]) + logger.addHandler(handler) + return handler, stream + + @parameterized.expand(TEST_COMPOSE_LAZY_ON_CALL_LOGGING_TEST_CASES) + def test_dataset_lazy_with_logging(self, compose_type, pipeline, lazy, expected): + handler, stream = self.init_logger(name=self.LOGGER_NAME) + + data = data_from_keys(None, 12, 16) + c = compose_type(deepcopy(pipeline), log_stats=self.LOGGER_NAME, lazy=lazy) + x = Dataset([data], transform=c) + x[0] + + handler.flush() + actual = stream.getvalue() + self.assertEqual(actual, expected) + if __name__ == "__main__": unittest.main() From 413323605694c182d5cf1051a9e5c91251ab8527 Mon Sep 17 00:00:00 2001 From: KumoLiu Date: Wed, 13 Sep 2023 15:31:06 +0800 Subject: [PATCH 5/6] update docstring Signed-off-by: KumoLiu --- monai/transforms/transform.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/monai/transforms/transform.py b/monai/transforms/transform.py index 8af3c9ade0..3d09cea545 100644 --- a/monai/transforms/transform.py +++ b/monai/transforms/transform.py @@ -124,7 +124,7 @@ def apply_transform( disables the logger for processing pipeline errors. Setting it to None or True will enable logging to the default logger name. Setting it to a string specifies the logger to which errors should be logged. lazy: whether to execute in lazy mode or not. See the :ref:`Lazy Resampling topic for more - information about lazy resampling. + information about lazy resampling. Defaults to None. overrides: optional overrides to apply to transform parameters. This parameter is ignored unless transforms are being executed lazily. See the :ref:`Lazy Resampling topic for more details and examples of its usage. From 889b4ae9874fcd1e35fdc4af89ced770c673e0c5 Mon Sep 17 00:00:00 2001 From: KumoLiu Date: Wed, 13 Sep 2023 15:33:31 +0800 Subject: [PATCH 6/6] DCO Remediation Commit for KumoLiu I, KumoLiu , hereby add my Signed-off-by to this commit: 4aa85fc5e60953263ed9763cad4463fe0ec20026 Signed-off-by: KumoLiu --- tests/test_dataset.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_dataset.py b/tests/test_dataset.py index 14445569f4..c7c2b77697 100644 --- a/tests/test_dataset.py +++ b/tests/test_dataset.py @@ -119,8 +119,8 @@ def test_dataset_lazy_with_logging(self, compose_type, pipeline, lazy, expected) data = data_from_keys(None, 12, 16) c = compose_type(deepcopy(pipeline), log_stats=self.LOGGER_NAME, lazy=lazy) - x = Dataset([data], transform=c) - x[0] + ds = Dataset([data], transform=c) + ds[0] handler.flush() actual = stream.getvalue()