Passed
Pull Request — master (#353)
by Fernando
01:09
created

tests.transforms.augmentation.test_random_labels_to_image   A

Complexity

Total Complexity 41

Size/Duplication

Total Lines 245
Duplicated Lines 14.29 %

Importance

Changes 0
Metric Value
eloc 150
dl 35
loc 245
rs 9.1199
c 0
b 0
f 0
wmc 41

25 Methods

Rating   Name   Duplication   Size   Complexity  
A TestRandomLabelsToImage.test_filling_without_any_hole() 0 11 1
A TestRandomLabelsToImage.test_filling_with_discretized_label_map() 0 15 1
A TestRandomLabelsToImage.test_filling_with_discretized_pv_label_map() 0 16 1
A TestRandomLabelsToImage.test_deterministic_simulation_with_pv_map() 0 17 1
A TestRandomLabelsToImage.test_filling() 0 14 1
A TestRandomLabelsToImage.test_random_simulation() 0 6 1
A TestRandomLabelsToImage.test_deterministic_simulation_with_discretized_label_map() 18 18 1
A TestRandomLabelsToImage.test_deterministic_simulation_with_discretized_pv_map() 0 15 1
A TestRandomLabelsToImage.test_deterministic_simulation() 17 17 1
A TestRandomLabelsToImage.test_with_bad_default_mean_type() 0 4 2
A TestRandomLabelsToImage.test_with_wrong_label_key_type() 0 5 2
A TestRandomLabelsToImage.test_with_wrong_used_labels_elements_type() 0 5 2
A TestRandomLabelsToImage.test_with_wrong_used_labels_type() 0 5 2
A TestRandomLabelsToImage.test_mean_and_std_len_not_matching() 0 4 2
A TestRandomLabelsToImage.test_mean_and_used_labels_len_not_matching() 0 5 2
A TestRandomLabelsToImage.test_with_bad_default_std_type() 0 4 2
A TestRandomLabelsToImage.test_with_bad_default_mean_range() 0 5 2
A TestRandomLabelsToImage.test_with_wrong_mean_type() 0 4 2
A TestRandomLabelsToImage.test_with_wrong_std_type() 0 4 2
A TestRandomLabelsToImage.test_mean_not_matching_number_of_labels() 0 6 2
A TestRandomLabelsToImage.test_std_and_used_labels_len_not_matching() 0 5 2
A TestRandomLabelsToImage.test_with_wrong_std_elements_type() 0 5 2
A TestRandomLabelsToImage.test_std_not_matching_number_of_labels() 0 6 2
A TestRandomLabelsToImage.test_with_wrong_mean_elements_type() 0 5 2
A TestRandomLabelsToImage.test_with_bad_default_std_range() 0 5 2

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complexity

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like tests.transforms.augmentation.test_random_labels_to_image often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
from torchio.transforms import RandomLabelsToImage
2
from torchio import DATA
3
from ...utils import TorchioTestCase
4
5
6
class TestRandomLabelsToImage(TorchioTestCase):
7
    """Tests for `RandomLabelsToImage`."""
8
    def test_random_simulation(self):
9
        """The transform runs without error and an 'image_from_labels' key is
10
        present in the transformed subject."""
11
        transform = RandomLabelsToImage(label_key='label')
12
        transformed = transform(self.sample_subject)
13
        self.assertIn('image_from_labels', transformed)
14
15 View Code Duplication
    def test_deterministic_simulation(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
16
        """The transform creates an image where values are equal to given
17
        mean if standard deviation is zero.
18
        Using a label map."""
19
        transform = RandomLabelsToImage(
20
            label_key='label',
21
            mean=[0.5, 2],
22
            std=[0, 0]
23
        )
24
        transformed = transform(self.sample_subject)
25
        self.assertTensorEqual(
26
            transformed['image_from_labels'][DATA] == 0.5,
27
            self.sample_subject['label'][DATA] == 0
28
        )
29
        self.assertTensorEqual(
30
            transformed['image_from_labels'][DATA] == 2,
31
            self.sample_subject['label'][DATA] == 1
32
        )
33
34 View Code Duplication
    def test_deterministic_simulation_with_discretized_label_map(self):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
35
        """The transform creates an image where values are equal to given mean
36
        if standard deviation is zero.
37
        Using a discretized label map."""
38
        transform = RandomLabelsToImage(
39
            label_key='label',
40
            mean=[0.5, 2],
41
            std=[0, 0],
42
            discretize=True
43
        )
44
        transformed = transform(self.sample_subject)
45
        self.assertTensorEqual(
46
            transformed['image_from_labels'][DATA] == 0.5,
47
            self.sample_subject['label'][DATA] == 0
48
        )
49
        self.assertTensorEqual(
50
            transformed['image_from_labels'][DATA] == 2,
51
            self.sample_subject['label'][DATA] == 1
52
        )
53
54
    def test_deterministic_simulation_with_pv_map(self):
55
        """The transform creates an image where values are equal to given
56
        mean weighted by partial-volume if standard deviation is zero."""
57
        subject = self.get_subject_with_partial_volume_label_map(components=2)
58
        transform = RandomLabelsToImage(
59
            label_key='label',
60
            mean=[0.5, 1],
61
            std=[0, 0]
62
        )
63
        transformed = transform(subject)
64
        self.assertTensorAlmostEqual(
65
            transformed['image_from_labels'][DATA][0],
66
            subject['label'][DATA][0] * 0.5 + subject['label'][DATA][1] * 1
67
        )
68
        self.assertEqual(
69
            transformed['image_from_labels'][DATA].shape,
70
            (1, 10, 20, 30)
71
        )
72
73
    def test_deterministic_simulation_with_discretized_pv_map(self):
74
        """The transform creates an image where values are equal to given mean
75
        if standard deviation is zero.
76
        Using a discretized partial-volume label map."""
77
        subject = self.get_subject_with_partial_volume_label_map()
78
        transform = RandomLabelsToImage(
79
            label_key='label',
80
            mean=[0.5],
81
            std=[0],
82
            discretize=True
83
        )
84
        transformed = transform(subject)
85
        self.assertTensorAlmostEqual(
86
            transformed['image_from_labels'][DATA],
87
            (subject['label'][DATA] > 0) * 0.5
88
        )
89
90
    def test_filling(self):
91
        """The transform can fill in the generated image with an already
92
        existing image.
93
        Using a label map."""
94
        transform = RandomLabelsToImage(
95
            label_key='label',
96
            image_key='t1',
97
            used_labels=[1]
98
        )
99
        t1_indices = self.sample_subject['label'][DATA] == 0
100
        transformed = transform(self.sample_subject)
101
        self.assertTensorAlmostEqual(
102
            transformed['t1'][DATA][t1_indices],
103
            self.sample_subject['t1'][DATA][t1_indices]
104
        )
105
106
    def test_filling_with_discretized_label_map(self):
107
        """The transform can fill in the generated image with an already
108
        existing image.
109
        Using a discretized label map."""
110
        transform = RandomLabelsToImage(
111
            label_key='label',
112
            image_key='t1',
113
            discretize=True,
114
            used_labels=[1]
115
        )
116
        t1_indices = self.sample_subject['label'][DATA] < 0.5
117
        transformed = transform(self.sample_subject)
118
        self.assertTensorAlmostEqual(
119
            transformed['t1'][DATA][t1_indices],
120
            self.sample_subject['t1'][DATA][t1_indices]
121
        )
122
123
    def test_filling_with_discretized_pv_label_map(self):
124
        """The transform can fill in the generated image with an already
125
        existing image.
126
        Using a discretized partial-volume label map."""
127
        subject = self.get_subject_with_partial_volume_label_map(components=2)
128
        transform = RandomLabelsToImage(
129
            label_key='label',
130
            image_key='t1',
131
            discretize=True,
132
            used_labels=[1]
133
        )
134
        t1_indices = subject['label'][DATA].argmax(dim=0) == 0
135
        transformed = transform(subject)
136
        self.assertTensorAlmostEqual(
137
            transformed['t1'][DATA][0][t1_indices],
138
            subject['t1'][DATA][0][t1_indices]
139
        )
140
141
    def test_filling_without_any_hole(self):
142
        """The transform does not fill anything if there is no hole."""
143
        transform = RandomLabelsToImage(
144
            label_key='label',
145
            image_key='t1',
146
            default_std=0.,
147
            default_mean=-1.
148
        )
149
        original_t1 = self.sample_subject.t1.data.clone()
150
        transformed = transform(self.sample_subject)
151
        self.assertTensorNotEqual(original_t1, transformed.t1.data)
152
153
    def test_with_bad_default_mean_range(self):
154
        """The transform raises an error if default_mean is not a
155
        single value nor a tuple of two values."""
156
        with self.assertRaises(ValueError):
157
            RandomLabelsToImage(label_key='label', default_mean=(0, 1, 2))
158
159
    def test_with_bad_default_mean_type(self):
160
        """The transform raises an error if default_mean has the wrong type."""
161
        with self.assertRaises(ValueError):
162
            RandomLabelsToImage(label_key='label', default_mean='wrong')
163
164
    def test_with_bad_default_std_range(self):
165
        """The transform raises an error if default_std is not a
166
        single value nor a tuple of two values."""
167
        with self.assertRaises(ValueError):
168
            RandomLabelsToImage(label_key='label', default_std=(0, 1, 2))
169
170
    def test_with_bad_default_std_type(self):
171
        """The transform raises an error if default_std has the wrong type."""
172
        with self.assertRaises(ValueError):
173
            RandomLabelsToImage(label_key='label', default_std='wrong')
174
175
    def test_with_wrong_label_key_type(self):
176
        """The transform raises an error if a wrong type is given for
177
        label_key."""
178
        with self.assertRaises(TypeError):
179
            RandomLabelsToImage(label_key=42)
180
181
    def test_with_wrong_used_labels_type(self):
182
        """The transform raises an error if a wrong type is given for
183
        used_labels."""
184
        with self.assertRaises(TypeError):
185
            RandomLabelsToImage(label_key='label', used_labels=42)
186
187
    def test_with_wrong_used_labels_elements_type(self):
188
        """The transform raises an error if wrong type are given for
189
        used_labels elements."""
190
        with self.assertRaises(ValueError):
191
            RandomLabelsToImage(label_key='label', used_labels=['wrong'])
192
193
    def test_with_wrong_mean_type(self):
194
        """The transform raises an error if wrong type is given for mean."""
195
        with self.assertRaises(TypeError):
196
            RandomLabelsToImage(label_key='label', mean=42)
197
198
    def test_with_wrong_mean_elements_type(self):
199
        """The transform raises an error if wrong type are given for
200
        mean elements."""
201
        with self.assertRaises(ValueError):
202
            RandomLabelsToImage(label_key='label', mean=['wrong'])
203
204
    def test_with_wrong_std_type(self):
205
        """The transform raises an error if wrong type is given for std."""
206
        with self.assertRaises(TypeError):
207
            RandomLabelsToImage(label_key='label', std=42)
208
209
    def test_with_wrong_std_elements_type(self):
210
        """The transform raises an error if wrong type are given for
211
        std elements."""
212
        with self.assertRaises(ValueError):
213
            RandomLabelsToImage(label_key='label', std=['wrong'])
214
215
    def test_mean_and_std_len_not_matching(self):
216
        """The transform raises an error if mean and std length don't match."""
217
        with self.assertRaises(AssertionError):
218
            RandomLabelsToImage(label_key='label', mean=[0], std=[0, 1])
219
220
    def test_mean_and_used_labels_len_not_matching(self):
221
        """The transform raises an error if mean and used_labels
222
         length don't match."""
223
        with self.assertRaises(AssertionError):
224
            RandomLabelsToImage(label_key='label', mean=[0], used_labels=[0, 1])
225
226
    def test_std_and_used_labels_len_not_matching(self):
227
        """The transform raises an error if std and used_labels
228
         length don't match."""
229
        with self.assertRaises(AssertionError):
230
            RandomLabelsToImage(label_key='label', std=[0], used_labels=[0, 1])
231
232
    def test_mean_not_matching_number_of_labels(self):
233
        """The transform raises an error at runtime if mean length
234
        does not match label numbers."""
235
        transform = RandomLabelsToImage(label_key='label', mean=[0])
236
        with self.assertRaises(RuntimeError):
237
            transform(self.sample_subject)
238
239
    def test_std_not_matching_number_of_labels(self):
240
        """The transform raises an error at runtime if std length
241
        does not match label numbers."""
242
        transform = RandomLabelsToImage(label_key='label', std=[1, 2, 3])
243
        with self.assertRaises(RuntimeError):
244
            transform(self.sample_subject)
245