Package mvpa :: Package misc :: Package fsl :: Module base
[hide private]
[frames] | no frames]

Source Code for Module mvpa.misc.fsl.base

  1  # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*- 
  2  # vi: set ft=python sts=4 ts=4 sw=4 et: 
  3  ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ## 
  4  # 
  5  #   See COPYING file distributed along with the PyMVPA package for the 
  6  #   copyright and license terms. 
  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   
22 -class FslEV3(ColumnData):
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 """
30 - def __init__(self, source):
31 """Read and write FSL EV3 files. 32 33 :Parameter: 34 source: filename of an EV3 file 35 """ 36 # init data from known format 37 ColumnData.__init__(self, source, 38 header=['onsets', 'durations', 'intensities'], 39 sep=None, dtype=float)
40 41
42 - def getNEVs(self):
43 """Returns the number of EVs in the file. 44 """ 45 return self.getNRows()
46 47
48 - def getEV(self, evid):
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
57 - def tofile(self, filename):
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
66 - def toEvents(self, **kwargs):
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
89 -class McFlirtParams(ColumnData):
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
95 - def __init__(self, source):
96 """Initialize McFlirtParams 97 98 :Parameter: 99 source: str 100 Filename of a parameter file. 101 """ 102 ColumnData.__init__(self, source, 103 header=McFlirtParams.header_def, 104 sep=None, dtype=float)
105 106
107 - def tofile(self, filename):
108 """Write motion parameters to file. 109 """ 110 ColumnData.tofile(self, filename, 111 header=False, 112 header_order=McFlirtParams.header_def, 113 sep=' ')
114 115
116 - def plot(self):
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 # import internally as it takes some time and might not be needed most 124 # of the time 125 import pylab as P 126 127 # translations subplot 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 # rotations subplot 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
144 - def toarray(self):
145 """Returns the data as an array with six columns (same order as in file). 146 """ 147 import numpy as N 148 149 # return as array with time axis first 150 return N.array([self[i] for i in McFlirtParams.header_def], 151 dtype='float').T
152 153
154 -class FslGLMDesign(object):
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 """
160 - def __init__(self, source):
161 """ 162 :Parameter: 163 source: filename 164 Compressed files will be read as well, if their filename ends with 165 '.gz'. 166 """ 167 # XXX maybe load from array as well 168 self._loadFile(source)
169 170
171 - def _loadFile(self, fname):
172 """Helper function to load GLM definition from a file. 173 """ 174 # header info 175 nwaves = 0 176 ntimepoints = 0 177 matrix_offset = 0 178 179 # open the file compressed or not 180 if fname.endswith('.gz'): 181 fh = gzip.open(fname, 'r') 182 else: 183 fh = open(fname, 'r') 184 185 # read header 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 # done with the header, now revert to NumPy's loadtxt for convenience 197 fh.close() 198 self.mat = N.loadtxt(fname, skiprows=matrix_offset) 199 200 # checks 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 # import internally as it takes some time and might not be needed most 218 # of the time 219 import pylab as P 220 221 if style == 'lines': 222 # common y-axis 223 yax = N.arange(0, self.mat.shape[0]) 224 axcenters = [] 225 col_offset = max(self.ppheights) 226 227 # for all columns 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 # labels and turn y-axis upside down 242 P.ylabel('Samples (top to bottom)') 243 P.xlabel('Regressors') 244 P.ylim(self.mat.shape[0],0)
245