[030aeb]: / tests / scan_sequences / test_scan_io.py

Download this file

143 lines (113 with data), 5.0 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
import os
import numpy as np
import pydicom
from pydicom.data import get_testdata_file
from dosma.scan_sequences.scan_io import ScanIOMixin
from .. import util as ututils
class MockScanIOMixin(ScanIOMixin):
"""Mock class for the :cls:`ScanIOMixin`.
This mixin will be used to load an MR slice hosted on pydicom: ``MR_small.dcm``.
"""
NAME = "mock-scan-io"
__DEFAULT_SPLIT_BY__ = None
def __init__(self, volumes, foo="foo", bar="bar") -> None:
self.volumes = volumes
self._from_file_args = {}
self.foo = foo
self._bar = bar
# Attributes that should not be serialized
self._temp_path = "some/path"
self.__some_attr__ = 1234
self.__pydicom_header__ = pydicom.Dataset()
@property
def some_property(self):
return "new/path"
class TestScanIOMixin(ututils.TempPathMixin):
def test_from_dicom(self):
mr_dcm = get_testdata_file("MR_small.dcm")
fs = pydicom.read_file(mr_dcm)
arr = fs.pixel_array
scan = MockScanIOMixin.from_dicom(mr_dcm, foo="foofoo", bar="barbar")
assert len(scan.volumes) == 1
assert np.all(scan.volumes[0] == arr[..., np.newaxis])
assert scan.foo == "foofoo"
assert scan._bar == "barbar"
assert scan._from_file_args == {
"dir_or_files": mr_dcm,
"ignore_ext": False,
"group_by": None,
"_type": "dicom",
}
scan = MockScanIOMixin.from_dicom([mr_dcm], foo="foofoo", bar="barbar")
assert len(scan.volumes) == 1
assert np.all(scan.volumes[0] == arr[..., np.newaxis])
assert scan.foo == "foofoo"
assert scan._bar == "barbar"
assert scan._from_file_args == {
"dir_or_files": [mr_dcm],
"ignore_ext": False,
"group_by": None,
"_type": "dicom",
}
def test_from_dict(self):
mr_dcm = get_testdata_file("MR_small.dcm")
scan1 = MockScanIOMixin.from_dicom(mr_dcm)
scan2 = MockScanIOMixin.from_dict(scan1.__dict__)
assert scan1.__dict__.keys() == scan2.__dict__.keys()
for k in scan1.__dict__.keys():
assert scan1.__dict__[k] == scan2.__dict__[k]
new_dict = dict(scan1.__dict__)
new_dict["extra_bool_field"] = True
with self.assertWarns(UserWarning):
scan2 = MockScanIOMixin.from_dict(new_dict)
assert not hasattr(scan2, "extra_bool_field")
scan2 = MockScanIOMixin.from_dict(new_dict, force=True)
assert hasattr(scan2, "extra_bool_field")
def test_save_load(self):
mr_dcm = get_testdata_file("MR_small.dcm")
scan = MockScanIOMixin.from_dicom(mr_dcm)
scan.foo = "foofoo"
scan._bar = "barbar"
vars = scan.__serializable_variables__()
serializable = ("foo", "_bar", "volumes", "_from_file_args")
not_serializable = ("_temp_path", "__some_attr__", "__pydicom_header__", "some_property")
assert all(x in vars for x in serializable)
assert all(x not in vars for x in not_serializable)
save_dir = os.path.join(self.data_dirpath, "test_save_load")
save_path = scan.save(save_dir, save_custom=True)
assert os.path.isfile(save_path)
scan_loaded = MockScanIOMixin.load(save_path)
assert scan_loaded.volumes[0].is_identical(scan.volumes[0])
assert scan_loaded.foo == "foofoo"
assert scan._bar == "barbar"
scan_loaded = MockScanIOMixin.load(save_dir)
assert scan_loaded.volumes[0].is_identical(scan.volumes[0])
assert scan_loaded.foo == "foofoo"
assert scan._bar == "barbar"
with self.assertRaises(FileNotFoundError):
_ = MockScanIOMixin.load(os.path.join(save_dir, "some-path.pik"))
new_dict = dict(scan.__dict__)
new_dict.pop("volumes")
with self.assertWarns(UserWarning):
scan_loaded = MockScanIOMixin.load(new_dict)
assert scan_loaded.volumes[0].is_identical(scan.volumes[0])
assert scan_loaded.foo == "foofoo"
assert scan._bar == "barbar"
# Backwards compatibility with how DOSMA wrote files versions<0.0.12
new_dict = dict(scan.__dict__)
new_dict.pop("volumes")
new_dict.pop("_from_file_args")
new_dict.update({"dicom_path": mr_dcm, "ignore_ext": False, "series_number": 7})
with self.assertWarns(UserWarning):
scan_loaded = MockScanIOMixin.load(new_dict)
assert scan_loaded.volumes[0].is_identical(scan.volumes[0])
assert scan_loaded.foo == "foofoo"
assert scan._bar == "barbar"
new_dict = dict(scan.__dict__)
new_dict.pop("volumes")
new_dict.pop("_from_file_args")
with self.assertRaises(ValueError):
_ = MockScanIOMixin.load(new_dict)
save_dir = os.path.join(self.data_dirpath, "test_save_data")
with self.assertWarns(DeprecationWarning):
scan.save_data(save_dir)