TestRandomAffine.test_scale_too_large()   A
last analyzed

Complexity

Conditions 2

Size

Total Lines 3
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
import torch
2
import torchio as tio
3
from ...utils import TorchioTestCase
4
5
6
class TestRandomAffine(TorchioTestCase):
7
    """Tests for `RandomAffine`."""
8
    def setUp(self):
9
        # Set image origin far from center
10
        super().setUp()
11
        affine = self.sample_subject.t1.affine
12
        affine[:3, 3] = 1e5
13
14
    def test_rotation_image(self):
15
        # Rotation around image center
16
        transform = tio.RandomAffine(
17
            degrees=(90, 90),
18
            default_pad_value=0,
19
            center='image',
20
        )
21
        transformed = transform(self.sample_subject)
22
        total = transformed.t1.data.sum()
23
        self.assertNotEqual(total, 0)
24
25
    def test_rotation_origin(self):
26
        # Rotation around far away point, image should be empty
27
        transform = tio.RandomAffine(
28
            degrees=(90, 90),
29
            default_pad_value=0,
30
            center='origin',
31
        )
32
        transformed = transform(self.sample_subject)
33
        total = transformed.t1.data.sum()
34
        self.assertEqual(total, 0)
35
36
    def test_no_rotation(self):
37
        transform = tio.RandomAffine(
38
            scales=(1, 1),
39
            degrees=(0, 0),
40
            default_pad_value=0,
41
            center='image',
42
        )
43
        transformed = transform(self.sample_subject)
44
        self.assertTensorAlmostEqual(
45
            self.sample_subject.t1.data,
46
            transformed.t1.data,
47
        )
48
49
        transform = tio.RandomAffine(
50
            scales=(1, 1),
51
            degrees=(180, 180),
52
            default_pad_value=0,
53
            center='image',
54
        )
55
        transformed = transform(self.sample_subject)
56
        transformed = transform(transformed)
57
        self.assertTensorAlmostEqual(
58
            self.sample_subject.t1.data,
59
            transformed.t1.data,
60
        )
61
62
    def test_isotropic(self):
63
        tio.RandomAffine(isotropic=True)(self.sample_subject)
64
65
    def test_mean(self):
66
        tio.RandomAffine(default_pad_value='mean')(self.sample_subject)
67
68
    def test_otsu(self):
69
        tio.RandomAffine(default_pad_value='otsu')(self.sample_subject)
70
71
    def test_bad_center(self):
72
        with self.assertRaises(ValueError):
73
            tio.RandomAffine(center='bad')
74
75
    def test_negative_scales(self):
76
        with self.assertRaises(ValueError):
77
            tio.RandomAffine(scales=(-1, 1))
78
79
    def test_scale_too_large(self):
80
        with self.assertRaises(ValueError):
81
            tio.RandomAffine(scales=1.5)
82
83
    def test_scales_range_with_negative_min(self):
84
        with self.assertRaises(ValueError):
85
            tio.RandomAffine(scales=(-1, 4))
86
87
    def test_wrong_scales_type(self):
88
        with self.assertRaises(ValueError):
89
            tio.RandomAffine(scales='wrong')
90
91
    def test_wrong_degrees_type(self):
92
        with self.assertRaises(ValueError):
93
            tio.RandomAffine(degrees='wrong')
94
95
    def test_too_many_translation_values(self):
96
        with self.assertRaises(ValueError):
97
            tio.RandomAffine(translation=(-10, 4, 42))
98
99
    def test_wrong_translation_type(self):
100
        with self.assertRaises(ValueError):
101
            tio.RandomAffine(translation='wrong')
102
103
    def test_wrong_center(self):
104
        with self.assertRaises(ValueError):
105
            tio.RandomAffine(center=0)
106
107
    def test_wrong_default_pad_value(self):
108
        with self.assertRaises(ValueError):
109
            tio.RandomAffine(default_pad_value='wrong')
110
111
    def test_wrong_image_interpolation_type(self):
112
        with self.assertRaises(TypeError):
113
            tio.RandomAffine(image_interpolation=0)
114
115
    def test_wrong_image_interpolation_value(self):
116
        with self.assertRaises(ValueError):
117
            tio.RandomAffine(image_interpolation='wrong')
118
119
    def test_incompatible_args_isotropic(self):
120
        with self.assertRaises(ValueError):
121
            tio.RandomAffine(scales=(0.8, 0.5, 0.1), isotropic=True)
122
123
    def test_parse_scales(self):
124
        def do_assert(transform):
125
            self.assertEqual(transform.scales, 3 * (0.9, 1.1))
126
        do_assert(tio.RandomAffine(scales=0.1))
127
        do_assert(tio.RandomAffine(scales=(0.9, 1.1)))
128
        do_assert(tio.RandomAffine(scales=3 * (0.1,)))
129
        do_assert(tio.RandomAffine(scales=3 * [0.9, 1.1]))
130
131
    def test_parse_degrees(self):
132
        def do_assert(transform):
133
            self.assertEqual(transform.degrees, 3 * (-10, 10))
134
        do_assert(tio.RandomAffine(degrees=10))
135
        do_assert(tio.RandomAffine(degrees=(-10, 10)))
136
        do_assert(tio.RandomAffine(degrees=3 * (10,)))
137
        do_assert(tio.RandomAffine(degrees=3 * [-10, 10]))
138
139
    def test_parse_translation(self):
140
        def do_assert(transform):
141
            self.assertEqual(transform.translation, 3 * (-10, 10))
142
        do_assert(tio.RandomAffine(translation=10))
143
        do_assert(tio.RandomAffine(translation=(-10, 10)))
144
        do_assert(tio.RandomAffine(translation=3 * (10,)))
145
        do_assert(tio.RandomAffine(translation=3 * [-10, 10]))
146
147
    def test_default_value_label_map(self):
148
        # From https://github.com/fepegar/torchio/issues/626
149
        a = torch.tensor([[1, 0, 0], [0, 1, 0], [0, 0, 1]]).reshape(1, 3, 3, 1)
150
        image = tio.LabelMap(tensor=a)
151
        aff = tio.RandomAffine(translation=(0, 1, 1), default_pad_value='otsu')
152
        transformed = aff(image)
153
        assert all(n in (0, 1) for n in transformed.data.flatten())
154
155
    def test_no_inverse(self):
156
        tensor = torch.zeros((1, 2, 2, 2))
157
        tensor[0, 1, 1, 1] = 1  # most RAS voxel
158
        expected = torch.zeros((1, 2, 2, 2))
159
        expected[0, 0, 1, 1] = 1
160
        scales = 1, 1, 1
161
        degrees = 0, 0, 90  # anterior should go left
162
        translation = 0, 0, 0
163
        apply_affine = tio.Affine(
164
            scales,
165
            degrees,
166
            translation,
167
        )
168
        transformed = apply_affine(tensor)
169
        self.assertTensorAlmostEqual(transformed, expected)
170