Skip to content

Commit 2d55074

Browse files
committed
Recovers deleted file
1 parent 3508211 commit 2d55074

File tree

1 file changed

+196
-0
lines changed

1 file changed

+196
-0
lines changed
Lines changed: 196 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
# Copyright (c) MONAI Consortium
2+
# Licensed under the Apache License, Version 2.0 (the "License");
3+
# you may not use this file except in compliance with the License.
4+
# You may obtain a copy of the License at
5+
# http://www.apache.org/licenses/LICENSE-2.0
6+
# Unless required by applicable law or agreed to in writing, software
7+
# distributed under the License is distributed on an "AS IS" BASIS,
8+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9+
# See the License for the specific language governing permissions and
10+
# limitations under the License.
11+
12+
from __future__ import annotations
13+
14+
import unittest
15+
16+
from parameterized import parameterized
17+
18+
from monai.transforms import ClipIntensityPercentilesd
19+
from monai.transforms.utils_pytorch_numpy_unification import clip, percentile
20+
from monai.utils.type_conversion import convert_to_tensor
21+
from tests.utils import TEST_NDARRAYS, NumpyImageTestCase2D, NumpyImageTestCase3D, assert_allclose
22+
23+
from .test_clip_intensity_percentiles import test_hard_clip_func, test_soft_clip_func
24+
25+
26+
class TestClipIntensityPercentilesd2D(NumpyImageTestCase2D):
27+
28+
@parameterized.expand([[p] for p in TEST_NDARRAYS])
29+
def test_hard_clipping_two_sided(self, p):
30+
key = "img"
31+
hard_clipper = ClipIntensityPercentilesd(keys=[key], upper=95, lower=5)
32+
im = p(self.imt)
33+
result = hard_clipper({key: im})
34+
expected = test_hard_clip_func(im, 5, 95)
35+
assert_allclose(result[key], p(expected), type_test="tensor", rtol=1e-4, atol=0)
36+
37+
@parameterized.expand([[p] for p in TEST_NDARRAYS])
38+
def test_hard_clipping_one_sided_high(self, p):
39+
key = "img"
40+
hard_clipper = ClipIntensityPercentilesd(keys=[key], upper=95, lower=None)
41+
im = p(self.imt)
42+
result = hard_clipper({key: im})
43+
expected = test_hard_clip_func(im, 0, 95)
44+
assert_allclose(result[key], p(expected), type_test="tensor", rtol=1e-4, atol=0)
45+
46+
@parameterized.expand([[p] for p in TEST_NDARRAYS])
47+
def test_hard_clipping_one_sided_low(self, p):
48+
key = "img"
49+
hard_clipper = ClipIntensityPercentilesd(keys=[key], upper=None, lower=5)
50+
im = p(self.imt)
51+
result = hard_clipper({key: im})
52+
expected = test_hard_clip_func(im, 5, 100)
53+
assert_allclose(result[key], p(expected), type_test="tensor", rtol=1e-4, atol=0)
54+
55+
@parameterized.expand([[p] for p in TEST_NDARRAYS])
56+
def test_soft_clipping_two_sided(self, p):
57+
key = "img"
58+
soft_clipper = ClipIntensityPercentilesd(keys=[key], upper=95, lower=5, sharpness_factor=1.0)
59+
im = p(self.imt)
60+
result = soft_clipper({key: im})
61+
expected = test_soft_clip_func(im, 5, 95)
62+
# the rtol is set to 1e-4 because the logaddexp function used in softplus is not stable accross torch and numpy
63+
assert_allclose(result[key], p(expected), type_test="tensor", rtol=1e-4, atol=0)
64+
65+
@parameterized.expand([[p] for p in TEST_NDARRAYS])
66+
def test_soft_clipping_one_sided_high(self, p):
67+
key = "img"
68+
soft_clipper = ClipIntensityPercentilesd(keys=[key], upper=95, lower=None, sharpness_factor=1.0)
69+
im = p(self.imt)
70+
result = soft_clipper({key: im})
71+
expected = test_soft_clip_func(im, None, 95)
72+
# the rtol is set to 1e-4 because the logaddexp function used in softplus is not stable accross torch and numpy
73+
assert_allclose(result[key], p(expected), type_test="tensor", rtol=1e-4, atol=0)
74+
75+
@parameterized.expand([[p] for p in TEST_NDARRAYS])
76+
def test_soft_clipping_one_sided_low(self, p):
77+
key = "img"
78+
soft_clipper = ClipIntensityPercentilesd(keys=[key], upper=None, lower=5, sharpness_factor=1.0)
79+
im = p(self.imt)
80+
result = soft_clipper({key: im})
81+
expected = test_soft_clip_func(im, 5, None)
82+
# the rtol is set to 1e-4 because the logaddexp function used in softplus is not stable accross torch and numpy
83+
assert_allclose(result[key], p(expected), type_test="tensor", rtol=1e-4, atol=0)
84+
85+
@parameterized.expand([[p] for p in TEST_NDARRAYS])
86+
def test_channel_wise(self, p):
87+
key = "img"
88+
clipper = ClipIntensityPercentilesd(keys=[key], upper=95, lower=5, channel_wise=True)
89+
im = p(self.imt)
90+
result = clipper({key: im})
91+
im_t = convert_to_tensor(self.imt)
92+
for i, c in enumerate(im_t):
93+
lower, upper = percentile(c, (5, 95))
94+
expected = clip(c, lower, upper)
95+
assert_allclose(result[key][i], p(expected), type_test="tensor", rtol=1e-3, atol=0)
96+
97+
def test_ill_sharpness_factor(self):
98+
key = "img"
99+
with self.assertRaises(ValueError):
100+
ClipIntensityPercentilesd(keys=[key], upper=95, lower=5, sharpness_factor=0.0)
101+
102+
def test_ill_lower_percentile(self):
103+
key = "img"
104+
with self.assertRaises(ValueError):
105+
ClipIntensityPercentilesd(keys=[key], upper=None, lower=-1)
106+
107+
def test_ill_upper_percentile(self):
108+
key = "img"
109+
with self.assertRaises(ValueError):
110+
ClipIntensityPercentilesd(keys=[key], upper=101, lower=None)
111+
112+
def test_ill_percentiles(self):
113+
key = "img"
114+
with self.assertRaises(ValueError):
115+
ClipIntensityPercentilesd(keys=[key], upper=95, lower=96)
116+
117+
def test_ill_both_none(self):
118+
key = "img"
119+
with self.assertRaises(ValueError):
120+
ClipIntensityPercentilesd(keys=[key], upper=None, lower=None)
121+
122+
123+
class TestClipIntensityPercentilesd3D(NumpyImageTestCase3D):
124+
125+
@parameterized.expand([[p] for p in TEST_NDARRAYS])
126+
def test_hard_clipping_two_sided(self, p):
127+
key = "img"
128+
hard_clipper = ClipIntensityPercentilesd(keys=[key], upper=95, lower=5)
129+
im = p(self.imt)
130+
result = hard_clipper({key: im})
131+
expected = test_hard_clip_func(im, 5, 95)
132+
assert_allclose(result[key], p(expected), type_test="tensor", rtol=1e-4, atol=0)
133+
134+
@parameterized.expand([[p] for p in TEST_NDARRAYS])
135+
def test_hard_clipping_one_sided_high(self, p):
136+
key = "img"
137+
hard_clipper = ClipIntensityPercentilesd(keys=[key], upper=95, lower=None)
138+
im = p(self.imt)
139+
result = hard_clipper({key: im})
140+
expected = test_hard_clip_func(im, 0, 95)
141+
assert_allclose(result[key], p(expected), type_test="tensor", rtol=1e-4, atol=0)
142+
143+
@parameterized.expand([[p] for p in TEST_NDARRAYS])
144+
def test_hard_clipping_one_sided_low(self, p):
145+
key = "img"
146+
hard_clipper = ClipIntensityPercentilesd(keys=[key], upper=None, lower=5)
147+
im = p(self.imt)
148+
result = hard_clipper({key: im})
149+
expected = test_hard_clip_func(im, 5, 100)
150+
assert_allclose(result[key], p(expected), type_test="tensor", rtol=1e-4, atol=0)
151+
152+
@parameterized.expand([[p] for p in TEST_NDARRAYS])
153+
def test_soft_clipping_two_sided(self, p):
154+
key = "img"
155+
soft_clipper = ClipIntensityPercentilesd(keys=[key], upper=95, lower=5, sharpness_factor=1.0)
156+
im = p(self.imt)
157+
result = soft_clipper({key: im})
158+
expected = test_soft_clip_func(im, 5, 95)
159+
# the rtol is set to 1e-4 because the logaddexp function used in softplus is not stable accross torch and numpy
160+
assert_allclose(result[key], p(expected), type_test="tensor", rtol=1e-4, atol=0)
161+
162+
@parameterized.expand([[p] for p in TEST_NDARRAYS])
163+
def test_soft_clipping_one_sided_high(self, p):
164+
key = "img"
165+
soft_clipper = ClipIntensityPercentilesd(keys=[key], upper=95, lower=None, sharpness_factor=1.0)
166+
im = p(self.imt)
167+
result = soft_clipper({key: im})
168+
expected = test_soft_clip_func(im, None, 95)
169+
# the rtol is set to 1e-4 because the logaddexp function used in softplus is not stable accross torch and numpy
170+
assert_allclose(result[key], p(expected), type_test="tensor", rtol=1e-4, atol=0)
171+
172+
@parameterized.expand([[p] for p in TEST_NDARRAYS])
173+
def test_soft_clipping_one_sided_low(self, p):
174+
key = "img"
175+
soft_clipper = ClipIntensityPercentilesd(keys=[key], upper=None, lower=5, sharpness_factor=1.0)
176+
im = p(self.imt)
177+
result = soft_clipper({key: im})
178+
expected = test_soft_clip_func(im, 5, None)
179+
# the rtol is set to 1e-6 because the logaddexp function used in softplus is not stable accross torch and numpy
180+
assert_allclose(result[key], p(expected), type_test="tensor", rtol=1e-4, atol=0)
181+
182+
@parameterized.expand([[p] for p in TEST_NDARRAYS])
183+
def test_channel_wise(self, p):
184+
key = "img"
185+
clipper = ClipIntensityPercentilesd(keys=[key], upper=95, lower=5, channel_wise=True)
186+
im = p(self.imt)
187+
result = clipper({key: im})
188+
im_t = convert_to_tensor(im)
189+
for i, c in enumerate(im_t):
190+
lower, upper = percentile(c, (5, 95))
191+
expected = clip(c, lower, upper)
192+
assert_allclose(result[key][i], p(expected), type_test="tensor", rtol=1e-4, atol=0)
193+
194+
195+
if __name__ == "__main__":
196+
unittest.main()

0 commit comments

Comments
 (0)