1
2
3
4
5
6
7
8
9 """IO helper for MEG datasets."""
10
11 __docformat__ = 'restructuredtext'
12
13
14 import numpy as N
15
16
18 """Reader for MEG data from line-based textfile format.
19
20 This class reads segmented MEG data from a textfile, which is created by
21 converting the proprietary binary output files of a MEG device in
22 Tuebingen (Germany) with an unkown tool.
23
24 The file format is line-based, i.e. all timepoints for all samples/trials
25 are written in a single line. Each line is prefixed with an identifier
26 (using a colon as the delimiter between identifier and data). Two lines
27 have a special purpose. The first 'Sample Number' is a list of timepoint
28 ids, similar to `range(ntimepoints)` for each sample/trial (all
29 concatenated into one line. The second 'Time' contains the timing
30 information for each timepoint (relative to stimulus onset), again for all
31 trials concatenated into a single line.
32
33 All other lines contain various information (channels) recorded during
34 the experiment. The meaning of some channels is unknown. Known ones are:
35
36 M*: MEG channels
37 EEG*: EEG channels
38 ADC*: Analog to digital converter output
39
40 Dataset properties are available from various class attributes. The `data`
41 member provides all data from all channels (except for 'Sample Number' and
42 'Time') in a NumPy array (nsamples x nchannels x ntimepoints).
43
44 The reader supports uncompressed as well as gzipped input files (or other
45 file-like objects).
46 """
47
49 """Reader MEG data from texfiles or file-like objects.
50
51 :Parameters:
52 source: str | file-like
53 Strings are assumed to be filenames (with `.gz` suffix
54 compressed), while all other object types are treated as file-like
55 objects.
56 """
57 self.ntimepoints = None
58 self.timepoints = None
59 self.nsamples = None
60 self.channelids = []
61 self.data = []
62 self.samplingrate = None
63
64
65 if isinstance(source, str):
66 if source.endswith('.gz'):
67 import gzip
68 source = gzip.open(source, 'r')
69 else:
70 source = open(source, 'r')
71
72
73 for line in source:
74
75 colon = line.find(':')
76
77
78 if colon == -1:
79 continue
80
81 id = line[:colon]
82 data = line[colon+1:].strip()
83 if id == 'Sample Number':
84 timepoints = N.fromstring(data, dtype=int, sep='\t')
85
86 self.ntimepoints = int(timepoints.max()) + 1
87 self.nsamples = int(len(timepoints) / self.ntimepoints)
88 elif id == 'Time':
89 self.timepoints = N.fromstring(data,
90 dtype=float,
91 count=self.ntimepoints,
92 sep='\t')
93 self.samplingrate = self.ntimepoints \
94 / (self.timepoints[-1] - self.timepoints[0])
95 else:
96
97 self.data.append(
98 N.fromstring(data, dtype=float, sep='\t').reshape(
99 self.nsamples, self.ntimepoints))
100
101 self.channelids.append(id)
102
103
104
105 self.data = N.swapaxes(N.array(self.data), 0, 1)
106
107
109 """Give a short summary.
110 """
111 return '<TuebingenMEG: %i samples, %i timepoints, %i channels>' \
112 % (self.nsamples, self.ntimepoints, len(self.channelids))
113