1
2
3
4
5
6
7
8
9 """FSL atlases interfaces
10
11 """
12
13 import os, re
14 import numpy as N
15
16 from mvpa.base import warning, externals
17 from mvpa.misc.support import reuseAbsolutePath
18
19 externals.exists('nifti', raiseException=True)
20 from nifti import NiftiImage
21
22 from mvpa.atlases.base import XMLBasedAtlas, LabelsLevel
23
24 if __debug__:
25 from mvpa.base import debug
26
27
28
29
30
31 -class FSLAtlas(XMLBasedAtlas):
32 """Base class for FSL atlases
33
34 """
35 source = 'FSL'
36
38 """
39
40 :Parameters:
41 filename : string
42 Filename for the xml definition of the atlas
43 resolution : None or float
44 Some atlases link to multiple images at different
45 resolutions. if None -- best resolution is selected
46 using 0th dimension resolution
47 """
48 XMLBasedAtlas.__init__(self, *args, **kwargs)
49 self.space = 'MNI'
50
51
53 resolution = self._resolution
54 header = self.header
55 images = header.images
56
57
58
59 ni_image = None
60 resolutions = []
61 for image in images:
62 imagefile = image.imagefile
63 imagefilename = reuseAbsolutePath(
64 self._filename, imagefile.text, force=True)
65
66 try:
67 ni_image_ = NiftiImage(imagefilename, load=False)
68 except RuntimeError, e:
69 raise RuntimeError, " Cannot open file " + imagefilename
70
71 resolution_ = ni_image_.pixdim[0]
72 if resolution is None:
73
74 if ni_image is None or \
75 resolution_ < ni_image.pixdim[0]:
76 ni_image = ni_image_
77 self._imagefile = imagefilename
78 else:
79 if resolution_ == resolution:
80 ni_image = ni_image_
81 self._imagefile = imagefilename
82 break
83 else:
84 resolutions += [resolution_]
85
86
87 if ni_image is None:
88 msg = "Could not find an appropriate atlas among %d atlases."
89 if resolution is not None:
90 msg += " Atlases had resolutions %s" % \
91 (resolutions,)
92 raise RuntimeError, msg
93 if __debug__:
94 debug('ATL__', "Loading atlas data from %s" % self._imagefile)
95 self._image = ni_image
96 self._resolution = ni_image.pixdim[0]
97 self._origin = N.abs(ni_image.header['qoffset']) * 1.0
98 self._data = self._image.data
99
100
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125 @staticmethod
127 return re.search('^[0-9]+\.[0-9]', version) is not None
128
131
132 - def __init__(self, thr=0.0, strategy='all', sort=True, *args, **kwargs):
133 """
134
135 :Parameters:
136 thr : float
137 Value to threshold at
138 strategy : basestring
139 Possible values
140 all - all entries above thr
141 max - entry with maximal value
142 sort : bool
143 Either to sort entries for 'all' strategy according to
144 probability
145 """
146
147 FSLAtlas.__init__(self, *args, **kwargs)
148 self.thr = thr
149 self.strategy = strategy
150 self.sort = sort
151
153 if levels is not None and not (levels in [0, [0], (0,)]):
154 raise ValueError, \
155 "I guess we don't support levels other than 0 in FSL atlas"
156
157
158 c = self._checkRange(c)
159
160
161
162 level = 0
163 resultLabels = []
164 for index, area in enumerate(self._levels_dict[level]):
165 prob = int(self._data[index, c[2], c[1], c[0]])
166 if prob > self.thr:
167 resultLabels += [dict(index=index,
168
169 label=area.text,
170 prob=prob)]
171
172 if self.sort or self.strategy == 'max':
173 resultLabels.sort(cmp=lambda x,y: cmp(x['prob'], y['prob']),
174 reverse=True)
175
176 if self.strategy == 'max':
177 resultLabels = resultLabels[:1]
178 elif self.strategy == 'all':
179 pass
180 else:
181 raise ValueError, 'Unknown strategy %s' % self.strategy
182
183 result = {'voxel_queried' : c,
184
185
186 'labels': [resultLabels]}
187
188 return result
189
195