|
1
|
|
|
import copy |
|
2
|
|
|
import tempfile |
|
3
|
|
|
import torch |
|
4
|
|
|
import numpy as np |
|
5
|
|
|
import torchio as tio |
|
6
|
|
|
from ..utils import TorchioTestCase |
|
7
|
|
|
|
|
8
|
|
|
|
|
9
|
|
|
class TestSubject(TorchioTestCase): |
|
10
|
|
|
"""Tests for `Subject`.""" |
|
11
|
|
|
def test_positional_args(self): |
|
12
|
|
|
with self.assertRaises(ValueError): |
|
13
|
|
|
tio.Subject(0) |
|
14
|
|
|
|
|
15
|
|
|
def test_input_dict(self): |
|
16
|
|
|
with tempfile.NamedTemporaryFile(delete=False) as f: |
|
17
|
|
|
input_dict = {'image': tio.ScalarImage(f.name)} |
|
18
|
|
|
tio.Subject(input_dict) |
|
19
|
|
|
tio.Subject(**input_dict) |
|
20
|
|
|
|
|
21
|
|
|
def test_no_sample(self): |
|
22
|
|
|
with tempfile.NamedTemporaryFile(delete=False) as f: |
|
23
|
|
|
input_dict = {'image': tio.ScalarImage(f.name)} |
|
24
|
|
|
subject = tio.Subject(input_dict) |
|
25
|
|
|
with self.assertRaises(RuntimeError): |
|
26
|
|
|
with self.assertWarns(UserWarning): |
|
27
|
|
|
tio.RandomFlip()(subject) |
|
28
|
|
|
|
|
29
|
|
|
def test_history(self): |
|
30
|
|
|
transformed = tio.RandomGamma()(self.sample_subject) |
|
31
|
|
|
self.assertIs(len(transformed.history), 1) |
|
32
|
|
|
|
|
33
|
|
|
def test_inconsistent_shape(self): |
|
34
|
|
|
subject = tio.Subject( |
|
35
|
|
|
a=tio.ScalarImage(tensor=torch.rand(1, 2, 3, 4)), |
|
36
|
|
|
b=tio.ScalarImage(tensor=torch.rand(2, 2, 3, 4)), |
|
37
|
|
|
) |
|
38
|
|
|
subject.spatial_shape |
|
39
|
|
|
with self.assertRaises(RuntimeError): |
|
40
|
|
|
subject.shape |
|
41
|
|
|
|
|
42
|
|
|
def test_inconsistent_spatial_shape(self): |
|
43
|
|
|
subject = tio.Subject( |
|
44
|
|
|
a=tio.ScalarImage(tensor=torch.rand(1, 3, 3, 4)), |
|
45
|
|
|
b=tio.ScalarImage(tensor=torch.rand(2, 2, 3, 4)), |
|
46
|
|
|
) |
|
47
|
|
|
with self.assertRaises(RuntimeError): |
|
48
|
|
|
subject.spatial_shape |
|
49
|
|
|
|
|
50
|
|
|
def test_plot(self): |
|
51
|
|
|
self.sample_subject.plot( |
|
52
|
|
|
show=False, |
|
53
|
|
|
output_path=self.dir / 'figure.png', |
|
54
|
|
|
cmap_dict=dict( |
|
55
|
|
|
t2='viridis', |
|
56
|
|
|
label={0: 'yellow', 1: 'blue'}, |
|
57
|
|
|
), |
|
58
|
|
|
) |
|
59
|
|
|
|
|
60
|
|
|
def test_plot_one_image(self): |
|
61
|
|
|
subject = tio.Subject(t1=tio.ScalarImage(self.get_image_path('t1_plot'))) |
|
62
|
|
|
subject.plot(show=False) |
|
63
|
|
|
|
|
64
|
|
|
# flake8: noqa: E203, E241 |
|
65
|
|
|
def test_same_space(self): |
|
66
|
|
|
# https://github.com/fepegar/torchio/issues/381 |
|
67
|
|
|
affine1 = np.array([ |
|
68
|
|
|
[ 4.27109375e-14, -8.71264808e-03, 9.99876633e-01, -3.39850907e+01], |
|
69
|
|
|
[-5.54687500e-01, -2.71630469e-12, 8.75148028e-17, 1.62282930e+02], |
|
70
|
|
|
[ 2.71575000e-12, -5.54619070e-01, -1.57073092e-02, 2.28515784e+02], |
|
71
|
|
|
[ 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 1.00000000e+00], |
|
72
|
|
|
]) |
|
73
|
|
|
affine2 = np.array([ |
|
74
|
|
|
[ 3.67499773e-08, -8.71257665e-03, 9.99876635e-01, -3.39850922e+01], |
|
75
|
|
|
[-5.54687500e-01, 3.67499771e-08, 6.73024385e-08, 1.62282928e+02], |
|
76
|
|
|
[-3.73318194e-08, -5.54619071e-01, -1.57071802e-02, 2.28515778e+02], |
|
77
|
|
|
[ 0.00000000e+00, 0.00000000e+00, 0.00000000e+00, 1.00000000e+00], |
|
78
|
|
|
]) |
|
79
|
|
|
t = torch.rand(1, 2, 3, 4) |
|
80
|
|
|
subject = tio.Subject( |
|
81
|
|
|
im1=tio.ScalarImage(tensor=t, affine=affine1), |
|
82
|
|
|
im2=tio.ScalarImage(tensor=t, affine=affine2), |
|
83
|
|
|
) |
|
84
|
|
|
subject.check_consistent_space() |
|
85
|
|
|
|
|
86
|
|
|
def test_delete_image(self): |
|
87
|
|
|
subject = copy.deepcopy(self.sample_subject) |
|
88
|
|
|
subject.remove_image('t1') |
|
89
|
|
|
with self.assertRaises(KeyError): |
|
90
|
|
|
subject['t1'] |
|
91
|
|
|
with self.assertRaises(AttributeError): |
|
92
|
|
|
subject.t1 |
|
93
|
|
|
|
|
94
|
|
|
def test_2d(self): |
|
95
|
|
|
subject = self.make_2d(self.sample_subject) |
|
96
|
|
|
assert subject.is_2d() |
|
97
|
|
|
|
|
98
|
|
|
def test_different_non_numeric(self): |
|
99
|
|
|
with self.assertRaises(RuntimeError): |
|
100
|
|
|
self.sample_subject.check_consistent_attribute('path') |
|
101
|
|
|
|
|
102
|
|
|
def test_bad_arg(self): |
|
103
|
|
|
with self.assertRaises(ValueError): |
|
104
|
|
|
tio.Subject(0) |
|
105
|
|
|
|
|
106
|
|
|
def test_no_images(self): |
|
107
|
|
|
with self.assertRaises(ValueError): |
|
108
|
|
|
tio.Subject(a=0) |
|
109
|
|
|
|