forked from nipy/nibabel
-
Notifications
You must be signed in to change notification settings - Fork 0
/
images.py
130 lines (104 loc) · 3.43 KB
/
images.py
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
# emacs: -*- mode: python-mode; py-indent-offset: 4; indent-tabs-mode: nil -*-
# vi: set ft=python sts=4 ts=4 sw=4 et:
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##
#
# See COPYING file distributed along with the NiBabel package for the
# copyright and license terms.
#
### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##
''' Base class for images
A draft.
'''
import nibabel.ioimps as ioimps
class ImageError(Exception):
pass
class Image(object):
''' Base class for images
Attributes:
* data : array-like; image data
* affine : array; mapping from image voxels to output space
coordinates
* output_space : string; name for affine output space
* meta : dict-like; image metadata
* io : image io implementation object
Properties (sorry guys):
* filename : string : read only, filename or None if none
* mode : string; 'r'ead, 'w'rite, or 'rw'
Methods:
* save(filespec=None)
* get_filespec()
* set_filespec(filespec)
* same_as_filename()
Class attributes:
* default_io_class
'''
default_io_class = ioimps.default_io
def __init__(self, data,
affine=None,
output_space=None,
meta=None,
filespec=None,
io=None,
mode='rw'):
self.data = data
self.affine = affine
self.output_space = output_space
if meta is None:
meta = {}
self.meta = meta
if not filespec is None:
if io is None:
io = ioimps.guessed_imp(filespec)
else:
io.set_filespec(filespec)
if io is None:
io = self.default_io_class()
self.io = io
# lay down flag to show changes in IO
self._io_hash = io.get_hash()
self._mode = None
self.mode = mode
@property
def filename(self):
filespec = self.get_filespec()
return filespec.filename
def mode():
def fget(self):
return self._mode
def fset(self, mode):
if not set('rw').issuperset(set(mode)):
raise ImageError('Invalid mode "%s"' % mode)
self._mode = mode
doc = 'image read / write mode'
return locals()
mode = property(**mode())
def get_filespec(self):
return self.io.get_filespec()
def set_filespec(self, filespec):
self.io.set_filespec(filespec)
def save(self, filespec=None, io=None):
io.save_image(self, filespec, io)
@classmethod
def from_io(klass, io):
return io.as_image(klass)
def same_as_filename(self, filename=None):
''' True if image in memory is same as image on disk '''
fname = self.filename
if fname is None:
return False
if filename:
if filename != fname:
return False
# first, check if io has changed
if self._io_hash != self.io.get_hash():
return False
# Then get io to check image against itself
return self.io.same_as_image(self)
def load(filespec, maker=Image, io=None):
if io is None:
io = ioimps.guessed_implementation(filespec)
else:
io.set_filespec(filespec)
return maker.from_io(io)
def save(img, filespec=None, io=None):
img.save(filespec, io)