1
2
3
4
5
6
7
8
9 """Tiny snippets to interface with FSL easily."""
10
11 __docformat__ = 'restructuredtext'
12
13 import numpy as N
14
15 from mvpa.misc.io import ColumnData
16 from mvpa.misc.support import Event
17
18 if __debug__:
19 from mvpa.base import debug
20
21
23 """IO helper to read FSL's EV3 files.
24
25 This is a three-column textfile format that is used to specify stimulation
26 protocols for fMRI data analysis in FSL's FEAT module.
27
28 Data is always read as `float`.
29 """
31 """Read and write FSL EV3 files.
32
33 :Parameter:
34 source: filename of an EV3 file
35 """
36
37 ColumnData.__init__(self, source,
38 header=['onsets', 'durations', 'intensities'],
39 sep=None, dtype=float)
40
41
43 """Returns the number of EVs in the file.
44 """
45 return self.getNRows()
46
47
49 """Returns a tuple of (onset time, simulus duration, intensity) for a
50 certain EV.
51 """
52 return (self['onsets'][evid],
53 self['durations'][evid],
54 self['intensities'][evid])
55
56
58 """Write data to a FSL EV3 file.
59 """
60 ColumnData.tofile(self, filename,
61 header=False,
62 header_order=['onsets', 'durations', 'intensities'],
63 sep=' ')
64
65
67 """Convert into a list of `Event` instances.
68
69 :Parameters:
70 kwargs
71 Any keyword arugment provided would be replicated, through all
72 the entries. Useful to specify label or even a chunk
73 """
74 return \
75 [Event(onset=self['onsets'][i],
76 duration=self['durations'][i],
77 features=[self['intensities'][i]],
78 **kwargs)
79 for i in xrange(self.nevs)]
80
81
82 onsets = property(fget=lambda self: self['onsets'])
83 durations = property(fget=lambda self: self['durations'])
84 intensities = property(fget=lambda self: self['intensities'])
85 nevs = property(fget=getNEVs)
86
87
88
90 """Read and write McFlirt's motion estimation parameters from and to text
91 files.
92 """
93 header_def = ['rot1', 'rot2', 'rot3', 'x', 'y', 'z']
94
105
106
114
115
117 """Produce a simple plot of the estimated translation and rotation
118 parameters using.
119
120 You still need to can pylab.show() or pylab.savefig() if you want to
121 see/get anything.
122 """
123
124
125 import pylab as P
126
127
128 P.subplot(211)
129 P.plot(self.x)
130 P.plot(self.y)
131 P.plot(self.z)
132 P.ylabel('Translations in mm')
133 P.legend(('x', 'y', 'z'), loc=0)
134
135
136 P.subplot(212)
137 P.plot(self.rot1)
138 P.plot(self.rot2)
139 P.plot(self.rot3)
140 P.ylabel('Rotations in rad')
141 P.legend(('rot1', 'rot2', 'rot3'), loc=0)
142
143
145 """Returns the data as an array with six columns (same order as in file).
146 """
147 import numpy as N
148
149
150 return N.array([self[i] for i in McFlirtParams.header_def],
151 dtype='float').T
152
153
155 """Load FSL GLM design matrices from file.
156
157 Be aware that such a desig matrix has its regressors in columns and the
158 samples in its rows.
159 """
161 """
162 :Parameter:
163 source: filename
164 Compressed files will be read as well, if their filename ends with
165 '.gz'.
166 """
167
168 self._loadFile(source)
169
170
172 """Helper function to load GLM definition from a file.
173 """
174
175 nwaves = 0
176 ntimepoints = 0
177 matrix_offset = 0
178
179
180 if fname.endswith('.gz'):
181 fh = gzip.open(fname, 'r')
182 else:
183 fh = open(fname, 'r')
184
185
186 for i, line in enumerate(fh):
187 if line.startswith('/NumWaves'):
188 nwaves = int(line.split()[1])
189 if line.startswith('/NumPoints'):
190 ntimepoints = int(line.split()[1])
191 if line.startswith('/PPheights'):
192 self.ppheights = [float(i) for i in line.split()[1:]]
193 if line.startswith('/Matrix'):
194 matrix_offset = i + 1
195
196
197 fh.close()
198 self.mat = N.loadtxt(fname, skiprows=matrix_offset)
199
200
201 if not self.mat.shape == (ntimepoints, nwaves):
202 raise IOError, "Design matrix file '%s' did not contain expected " \
203 "matrix size (expected %s, got %s)" \
204 % (fname, str((ntimepoints, nwaves)), self.mat.shape)
205
206
207 - def plot(self, style='lines', **kwargs):
208 """Visualize the design matrix.
209
210 :Parameters:
211 style: 'lines', 'matrix'
212 **kwargs:
213 Additional arguments will be passed to the corresponding matplotlib
214 plotting functions 'plot()' and 'pcolor()' for 'lines' and 'matrix'
215 plots respectively.
216 """
217
218
219 import pylab as P
220
221 if style == 'lines':
222
223 yax = N.arange(0, self.mat.shape[0])
224 axcenters = []
225 col_offset = max(self.ppheights)
226
227
228 for i in xrange(self.mat.shape[1]):
229 axcenter = i * col_offset
230 P.plot(self.mat[:, i] + axcenter, yax, **kwargs)
231 axcenters.append(axcenter)
232
233 P.xticks(N.array(axcenters), range(self.mat.shape[1]))
234 elif style == 'matrix':
235 P.pcolor(self.mat, **kwargs)
236 ticks = N.arange(1, self.mat.shape[1]+1)
237 P.xticks(ticks - 0.5, ticks)
238 else:
239 raise ValueError, "Unknown plotting style '%s'" % style
240
241
242 P.ylabel('Samples (top to bottom)')
243 P.xlabel('Regressors')
244 P.ylim(self.mat.shape[0],0)
245