Skip to content

Commit f0f986e

Browse files
authored
Merge branch 'dev' into bug/lps_orientation_transform
2 parents ed7d5af + cb200af commit f0f986e

File tree

74 files changed

+295
-591
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

74 files changed

+295
-591
lines changed

monai/apps/auto3dseg/auto_runner.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,15 @@ class AutoRunner:
194194
├── segresnet2d_0 # network scripts/configs/checkpoints and pickle object of the algo
195195
└── swinunetr_0 # network scripts/configs/checkpoints and pickle object of the algo
196196
197+
198+
The input config requires at least the following keys:
199+
- ``modality``: the modality of the data, e.g. "ct", "mri", etc.
200+
- ``datalist``: the path to the datalist file in JSON format.
201+
- ``dataroot``: the root directory of the data files.
202+
203+
For the datalist file format, see the description under :py:func:`monai.data.load_decathlon_datalist`.
204+
Note that the AutoRunner will use the "validation" key in the datalist file if it exists, otherwise
205+
it will do cross-validation, by default with five folds (this is hardcoded).
197206
"""
198207

199208
analyze_params: dict | None

monai/data/decathlon_datalist.py

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,42 @@ def load_decathlon_datalist(
9292
) -> list[dict]:
9393
"""Load image/label paths of decathlon challenge from JSON file
9494
95-
Json file is similar to what you get from http://medicaldecathlon.com/
96-
Those dataset.json files
95+
JSON file should follow the format of the Medical Segmentation Decathlon
96+
datalist.json files, see http://medicaldecathlon.com.
97+
The files are structured as follows:
98+
99+
.. code-block:: python
100+
101+
{
102+
"metadata_key_0": "metadata_value_0",
103+
"metadata_key_1": "metadata_value_1",
104+
...,
105+
"training": [
106+
{"image": "path/to/image_1.nii.gz", "label": "path/to/label_1.nii.gz"},
107+
{"image": "path/to/image_2.nii.gz", "label": "path/to/label_2.nii.gz"},
108+
...
109+
],
110+
"test": [
111+
"path/to/image_3.nii.gz",
112+
"path/to/image_4.nii.gz",
113+
...
114+
]
115+
}
116+
117+
118+
The metadata keys are optional for loading the datalist, but include:
119+
- some string items: ``name``, ``description``, ``reference``, ``licence``, ``release``, ``tensorImageSize``
120+
- two dict items: ``modality`` (keyed by channel index), and ``labels`` (keyed by label index)
121+
- and two integer items: ``numTraining`` and ``numTest``, with the number of items.
122+
123+
The ``training`` key contains a list of dictionaries, each of which has at least
124+
the ``image`` and ``label`` keys.
125+
The image and label are loaded by :py:func:`monai.transforms.LoadImaged`, so both can be either
126+
a single file path or a list of file paths, in which case they are loaded as multi-channel images.
127+
Each item can also include a ``fold`` key for cross-validation purposes.
128+
The "test" key contains a list of image paths, without labels, MONAI also supports a "validation" list
129+
with the same format as the "training" list.
130+
97131
98132
Args:
99133
data_list_file_path: the path to the json file of datalist.
@@ -107,11 +141,11 @@ def load_decathlon_datalist(
107141
108142
Returns a list of data items, each of which is a dict keyed by element names, for example:
109143
110-
.. code-block::
144+
.. code-block:: python
111145
112146
[
113-
{'image': '/workspace/data/chest_19.nii.gz', 'label': 0},
114-
{'image': '/workspace/data/chest_31.nii.gz', 'label': 1}
147+
{'image': '/workspace/data/chest_19.nii.gz', 'label': '/workspace/labels/chest_19.nii.gz'},
148+
{'image': '/workspace/data/chest_31.nii.gz', 'label': '/workspace/labels/chest_31.nii.gz'},
115149
]
116150
117151
"""
@@ -134,7 +168,8 @@ def load_decathlon_datalist(
134168

135169

136170
def load_decathlon_properties(data_property_file_path: PathLike, property_keys: Sequence[str] | str) -> dict:
137-
"""Load the properties from the JSON file contains data property with specified `property_keys`.
171+
"""Extract the properties with the specified keys from the Decathlon JSON file.
172+
See under `load_decathlon_datalist` for the expected keys in the Decathlon challenge.
138173
139174
Args:
140175
data_property_file_path: the path to the JSON file of data properties.

monai/transforms/intensity/dictionary.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1836,7 +1836,7 @@ class HistogramNormalized(MapTransform):
18361836
See also: :py:class:`monai.transforms.compose.MapTransform`
18371837
num_bins: number of the bins to use in histogram, default to `256`. for more details:
18381838
https://numpy.org/doc/stable/reference/generated/numpy.histogram.html.
1839-
min: the min value to normalize input image, default to `255`.
1839+
min: the min value to normalize input image, default to `0`.
18401840
max: the max value to normalize input image, default to `255`.
18411841
mask: if provided, must be ndarray of bools or 0s and 1s, and same shape as `image`.
18421842
only points at which `mask==True` are used for the equalization.

tests/__init__.py

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -8,32 +8,3 @@
88
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
99
# See the License for the specific language governing permissions and
1010
# limitations under the License.
11-
12-
from __future__ import annotations
13-
14-
import sys
15-
import unittest
16-
import warnings
17-
18-
19-
def _enter_pr_4800(self):
20-
"""
21-
code from https://github.com/python/cpython/pull/4800
22-
"""
23-
# The __warningregistry__'s need to be in a pristine state for tests
24-
# to work properly.
25-
for v in list(sys.modules.values()):
26-
if getattr(v, "__warningregistry__", None):
27-
v.__warningregistry__ = {}
28-
self.warnings_manager = warnings.catch_warnings(record=True)
29-
self.warnings = self.warnings_manager.__enter__()
30-
warnings.simplefilter("always", self.expected)
31-
return self
32-
33-
34-
# FIXME: workaround for https://bugs.python.org/issue29620
35-
try:
36-
# Suppression for issue #494: tests/__init__.py:34: error: Cannot assign to a method
37-
unittest.case._AssertWarnsContext.__enter__ = _enter_pr_4800 # type: ignore
38-
except AttributeError:
39-
pass

tests/apps/detection/networks/test_retinanet.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
from monai.networks import eval_mode
2121
from monai.networks.nets import resnet10, resnet18, resnet34, resnet50, resnet101, resnet152, resnet200
2222
from monai.utils import ensure_tuple, optional_import
23-
from tests.test_utils import SkipIfBeforePyTorchVersion, dict_product, skip_if_quick, test_onnx_save, test_script_save
23+
from tests.test_utils import dict_product, skip_if_quick, test_onnx_save, test_script_save
2424

2525
_, has_torchvision = optional_import("torchvision")
2626

@@ -94,7 +94,6 @@
9494
TEST_CASES_TS = [[params["model"], *params["case"]] for params in dict_product(model=MODEL_LIST, case=[TEST_CASE_1])]
9595

9696

97-
@SkipIfBeforePyTorchVersion((1, 12))
9897
@unittest.skipUnless(has_torchvision, "Requires torchvision")
9998
@skip_if_quick
10099
class TestRetinaNet(unittest.TestCase):

tests/apps/detection/networks/test_retinanet_detector.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from monai.apps.detection.utils.anchor_utils import AnchorGeneratorWithAnchorShape
2222
from monai.networks import eval_mode, train_mode
2323
from monai.utils import optional_import
24-
from tests.test_utils import SkipIfBeforePyTorchVersion, skip_if_quick, test_script_save
24+
from tests.test_utils import skip_if_quick, test_script_save
2525

2626
_, has_torchvision = optional_import("torchvision")
2727

@@ -110,7 +110,6 @@ def forward(self, images):
110110
return {self.cls_key: [torch.randn(out_cls_shape)], self.box_reg_key: [torch.randn(out_box_reg_shape)]}
111111

112112

113-
@SkipIfBeforePyTorchVersion((1, 11))
114113
@unittest.skipUnless(has_torchvision, "Requires torchvision")
115114
@skip_if_quick
116115
class TestRetinaNetDetector(unittest.TestCase):

tests/apps/detection/utils/test_anchor_box.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
from monai.apps.detection.utils.anchor_utils import AnchorGenerator, AnchorGeneratorWithAnchorShape
2020
from monai.utils import optional_import
21-
from tests.test_utils import SkipIfBeforePyTorchVersion, assert_allclose, test_script_save
21+
from tests.test_utils import assert_allclose, test_script_save
2222

2323
_, has_torchvision = optional_import("torchvision")
2424

@@ -39,7 +39,6 @@
3939
]
4040

4141

42-
@SkipIfBeforePyTorchVersion((1, 11))
4342
@unittest.skipUnless(has_torchvision, "Requires torchvision")
4443
class TestAnchorGenerator(unittest.TestCase):
4544
@parameterized.expand(TEST_CASES_2D)

tests/apps/maisi/networks/test_autoencoderkl_maisi.py

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
from monai.apps.generation.maisi.networks.autoencoderkl_maisi import AutoencoderKlMaisi
2020
from monai.networks import eval_mode
2121
from monai.utils import optional_import
22-
from tests.test_utils import SkipIfBeforePyTorchVersion
2322

2423
tqdm, has_tqdm = optional_import("tqdm", name="tqdm")
2524
_, has_einops = optional_import("einops")
@@ -87,7 +86,6 @@ def test_shape(self, input_param, input_shape, expected_shape, expected_latent_s
8786
self.assertEqual(result[2].shape, expected_latent_shape)
8887

8988
@parameterized.expand(CASES)
90-
@SkipIfBeforePyTorchVersion((1, 11))
9189
def test_shape_with_convtranspose_and_checkpointing(
9290
self, input_param, input_shape, expected_shape, expected_latent_shape
9391
):
@@ -152,7 +150,6 @@ def test_shape_reconstruction(self):
152150
result = net.reconstruct(torch.randn(input_shape).to(device))
153151
self.assertEqual(result.shape, expected_shape)
154152

155-
@SkipIfBeforePyTorchVersion((1, 11))
156153
def test_shape_reconstruction_with_convtranspose_and_checkpointing(self):
157154
input_param, input_shape, expected_shape, _ = CASES[0]
158155
input_param = input_param.copy()
@@ -170,7 +167,6 @@ def test_shape_encode(self):
170167
self.assertEqual(result[0].shape, expected_latent_shape)
171168
self.assertEqual(result[1].shape, expected_latent_shape)
172169

173-
@SkipIfBeforePyTorchVersion((1, 11))
174170
def test_shape_encode_with_convtranspose_and_checkpointing(self):
175171
input_param, input_shape, _, expected_latent_shape = CASES[0]
176172
input_param = input_param.copy()
@@ -190,7 +186,6 @@ def test_shape_sampling(self):
190186
)
191187
self.assertEqual(result.shape, expected_latent_shape)
192188

193-
@SkipIfBeforePyTorchVersion((1, 11))
194189
def test_shape_sampling_convtranspose_and_checkpointing(self):
195190
input_param, _, _, expected_latent_shape = CASES[0]
196191
input_param = input_param.copy()
@@ -209,7 +204,6 @@ def test_shape_decode(self):
209204
result = net.decode(torch.randn(latent_shape).to(device))
210205
self.assertEqual(result.shape, expected_input_shape)
211206

212-
@SkipIfBeforePyTorchVersion((1, 11))
213207
def test_shape_decode_convtranspose_and_checkpointing(self):
214208
input_param, expected_input_shape, _, latent_shape = CASES[0]
215209
input_param = input_param.copy()

tests/apps/maisi/networks/test_controlnet_maisi.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
from monai.apps.generation.maisi.networks.controlnet_maisi import ControlNetMaisi
2121
from monai.networks import eval_mode
2222
from monai.utils import optional_import
23-
from tests.test_utils import SkipIfBeforePyTorchVersion
2423

2524
_, has_einops = optional_import("einops")
2625

@@ -127,7 +126,6 @@
127126
]
128127

129128

130-
@SkipIfBeforePyTorchVersion((2, 0))
131129
class TestControlNet(unittest.TestCase):
132130
@parameterized.expand(TEST_CASES)
133131
@skipUnless(has_einops, "Requires einops")

0 commit comments

Comments
 (0)