[med-svn] [python-mne] 163/376: ENH : reject epochs based on threshold + parsing of .ave + .cov files
Yaroslav Halchenko
debian at onerussian.com
Fri Nov 27 17:22:26 UTC 2015
This is an automated email from the git hooks/post-receive script.
yoh pushed a commit to annotated tag v0.1
in repository python-mne.
commit ce3505f277aa5e0646cb8189acef4068ee4f4b53
Author: Alexandre Gramfort <alexandre.gramfort at inria.fr>
Date: Mon Mar 28 14:56:34 2011 -0400
ENH : reject epochs based on threshold + parsing of .ave + .cov files
---
examples/plot_read_epochs.py | 5 +--
mne/__init__.py | 1 +
mne/epochs.py | 82 ++++++++++++++++++++++++++++++++++++++------
mne/fiff/pick.py | 8 ++++-
mne/fiff/tests/data/test.ave | 2 +-
mne/misc.py | 64 ++++++++++++++++++++++++++++++++++
mne/tests/test_misc.py | 12 +++++++
7 files changed, 160 insertions(+), 14 deletions(-)
diff --git a/examples/plot_read_epochs.py b/examples/plot_read_epochs.py
index c2a94d0..d10cca6 100644
--- a/examples/plot_read_epochs.py
+++ b/examples/plot_read_epochs.py
@@ -27,18 +27,19 @@ raw_fname = data_path + '/MEG/sample/sample_audvis_filt-0-40_raw.fif'
event_fname = data_path + '/MEG/sample/sample_audvis_filt-0-40_raw-eve.fif'
event_id, tmin, tmax = 1, -0.2, 0.5
-# Setup for reading the raw data
+# Setup for reading the raw data
raw = fiff.Raw(raw_fname)
events = mne.read_events(event_fname)
# Set up pick list: EEG + MEG - bad channels (modify to your needs)
exclude = raw.info['bads'] + ['MEG 2443', 'EEG 053'] # bads + 2 more
-picks = fiff.pick_types(raw.info, meg=True, eeg=True, stim=False,
+picks = fiff.pick_types(raw.info, meg=True, eeg=False, stim=True,
exclude=exclude)
# Read epochs
epochs = mne.Epochs(raw, events, event_id, tmin, tmax,
picks=picks, baseline=(None, 0), preload=True)
+epochs.reject(grad=4000e-13, mag=4e-12, eog=150e-6)
evoked = epochs.average() # average epochs to get the evoked response
###############################################################################
diff --git a/mne/__init__.py b/mne/__init__.py
index c78f117..15b462f 100644
--- a/mne/__init__.py
+++ b/mne/__init__.py
@@ -9,4 +9,5 @@ from .source_space import read_source_spaces
from .inverse import read_inverse_operator, compute_inverse, minimum_norm
from .epochs import Epochs
from .label import label_time_courses, read_label
+from .misc import parse_config
import fiff
diff --git a/mne/epochs.py b/mne/epochs.py
index cd6d97a..2838039 100644
--- a/mne/epochs.py
+++ b/mne/epochs.py
@@ -7,6 +7,7 @@ import copy
import numpy as np
import fiff
from .fiff import Evoked
+from .fiff.pick import channel_type
class Epochs(object):
@@ -29,6 +30,9 @@ class Epochs(object):
tmax : float
End time after event
+ name : string
+ Comment that describes the Evoked data created.
+
keep_comp : boolean
Apply CTF gradient compensation
@@ -63,15 +67,15 @@ class Epochs(object):
"""
- def __init__(self, raw, events, event_id, tmin, tmax,
- picks=None, keep_comp=False,
- dest_comp=0, baseline=(None, 0),
+ def __init__(self, raw, events, event_id, tmin, tmax, baseline=(None, 0),
+ picks=None, name='Unknown', keep_comp=False, dest_comp=0,
preload=False):
self.raw = raw
self.event_id = event_id
self.tmin = tmin
self.tmax = tmax
self.picks = picks
+ self.name = name
self.keep_comp = keep_comp
self.dest_comp = dest_comp
self.baseline = baseline
@@ -217,6 +221,69 @@ class Epochs(object):
else:
return self._get_data_from_disk()
+ def reject(self, grad=None, mag=None, eeg=None, eog=None):
+ """Reject some epochs based on threshold values
+
+ Parameters
+ ----------
+ grad : float
+ Max value for gradiometers. (about 5000e-13).
+ If None do not reject based on gradiometers.
+ mag : float
+ Max value for magnetometers. (about 6e-12)
+ If None do not reject based on magnetometers.
+ eeg : float
+ Max value for EEG. (about 40e-6)
+ If None do not reject based on EEG.
+ eog : float
+ Max value for EEG. (about 250e-6)
+ If None do not reject based on EOG.
+
+ Returns
+ -------
+ data : array of shape [n_epochs, n_channels, n_times]
+ The epochs data
+ """
+ grad_idx = []
+ mag_idx = []
+ eeg_idx = []
+ eog_idx = []
+ for idx, ch in enumerate(self.ch_names):
+ if grad is not None and channel_type(self.info, idx) == 'grad':
+ grad_idx.append(idx)
+ if mag is not None and channel_type(self.info, idx) == 'mag':
+ mag_idx.append(idx)
+ if eeg is not None and channel_type(self.info, idx) == 'eeg':
+ eeg_idx.append(idx)
+ if eog is not None and channel_type(self.info, idx) == 'eog':
+ eog_idx.append(idx)
+
+ if len(eog_idx) == 0:
+ print "No EOG channel found. Do not rejecting based on EOG."
+
+ good_epochs = []
+ for k, e in enumerate(self):
+ if len(grad_idx) > 0 and np.max(e[grad_idx]) > grad:
+ print 'Rejecting epoch based on gradiometers.'
+ continue
+ if len(mag_idx) > 0 and np.max(e[mag_idx]) > mag:
+ print 'Rejecting epoch based on magnetometers.'
+ continue
+ if len(eeg_idx) > 0 and np.max(e[eeg_idx]) > eeg:
+ print 'Rejecting epoch based on EEG.'
+ continue
+ if len(eog_idx) > 0 and np.max(e[eog_idx]) > eog:
+ print 'Rejecting epoch based on EOG.'
+ continue
+ good_epochs.append(k)
+
+ n_good_epochs = len(good_epochs)
+ print "Keeping %d epochs (%d bad)" % (n_good_epochs,
+ len(self.events) - n_good_epochs)
+ self.events = self.events[good_epochs]
+ if self.preload:
+ self._data = self._data[good_epochs]
+
def __iter__(self):
"""To iteration over epochs easy.
"""
@@ -241,14 +308,9 @@ class Epochs(object):
s += ", baseline : %s" % str(self.baseline)
return "Epochs (%s)" % s
- def average(self, comment="Evoked data"):
+ def average(self):
"""Compute average of epochs
- Parameters
- ----------
- comment : string
- Comment that describes the Evoked data created.
-
Returns
-------
evoked : Evoked instance
@@ -268,7 +330,7 @@ class Epochs(object):
data /= n_events
evoked.data = data
evoked.times = self.times.copy()
- evoked.comment = comment
+ evoked.comment = self.name
evoked.aspect_kind = np.array([100]) # XXX
evoked.nave = n_events
evoked.first = - np.sum(self.times < 0)
diff --git a/mne/fiff/pick.py b/mne/fiff/pick.py
index 97edd61..b25c544 100644
--- a/mne/fiff/pick.py
+++ b/mne/fiff/pick.py
@@ -20,7 +20,7 @@ def channel_type(info, idx):
Returns
-------
- type : 'grad' | 'mag' | 'eeg' | 'stim'
+ type : 'grad' | 'mag' | 'eeg' | 'stim' | 'eog' | 'emg' | 'ecg'
Type of channel
"""
@@ -34,6 +34,12 @@ def channel_type(info, idx):
return 'eeg'
elif kind == FIFF.FIFFV_STIM_CH:
return 'stim'
+ elif kind == FIFF.FIFFV_EOG_CH:
+ return 'eog'
+ elif kind == FIFF.FIFFV_EMG_CH:
+ return 'emg'
+ elif kind == FIFF.FIFFV_ECG_CH:
+ return 'ecg'
def pick_channels(ch_names, include, exclude=[]):
diff --git a/mne/fiff/tests/data/test.ave b/mne/fiff/tests/data/test.ave
index be6ba6a..abc6533 100644
--- a/mne/fiff/tests/data/test.ave
+++ b/mne/fiff/tests/data/test.ave
@@ -13,7 +13,7 @@ average {
#
gradReject 4000e-13
magReject 4e-12
- eegReject 0e-6
+ eegReject 40e-6
eogReject 150e-6
#
# Category specifications
diff --git a/mne/misc.py b/mne/misc.py
new file mode 100644
index 0000000..9c25a5b
--- /dev/null
+++ b/mne/misc.py
@@ -0,0 +1,64 @@
+# Authors: Alexandre Gramfort <gramfort at nmr.mgh.harvard.edu>
+# Scott Burns <sburns at nmr.mgh.harvard.edu>
+#
+# License: BSD (3-clause)
+
+def parse_config(fname):
+ """Parse a config file (like .ave and .cov files)
+
+ Parameters
+ ----------
+ fname : string
+ config file name
+
+ Returns
+ -------
+ conditions : list of dict
+ Each condition is indexed by the event type.
+ A condition contains as keys:
+ tmin, tmax, name, grad_reject, mag_reject,
+ eeg_reject, eog_reject
+ """
+ try:
+ with open(fname, 'r') as f:
+ ave_lines = f.readlines()
+ except:
+ print("Error while reading %s" % fname)
+
+ reject_names = ['gradReject', 'magReject', 'eegReject', 'eogReject']
+ reject_pynames = ['grad_reject', 'mag_reject', 'eeg_reject', 'eog_reject']
+ reject_params = dict()
+ for line in ave_lines:
+ words = line.split()
+ if words[0] in reject_names:
+ reject_params[reject_pynames[reject_names.index(words[0])]] = \
+ float(words[1])
+
+ cat_ind = [i for i, x in enumerate(ave_lines) if "category {" in x]
+ event_dict = dict()
+ for ind in cat_ind:
+ for k in range(ind+1, ind+7):
+ words = ave_lines[k].split()
+ if len(words) >= 2:
+ key = words[0]
+ if key == 'event':
+ event = int(words[1])
+ break
+ else:
+ raise ValueError('Could not find event id.')
+ event_dict[event] = dict(**reject_params)
+ for k in range(ind+1, ind+7):
+ words = ave_lines[k].split()
+ if len(words) >= 2:
+ key = words[0]
+ if key == 'name':
+ name = ' '.join(words[1:])
+ if name[0] == '"':
+ name = name[1:]
+ if name[-1] == '"':
+ name = name[:-1]
+ event_dict[event]['name'] = name
+ if key in ['tmin', 'tmax', 'basemin', 'basemax']:
+ event_dict[event][key] = float(words[1])
+ return event_dict
+
diff --git a/mne/tests/test_misc.py b/mne/tests/test_misc.py
new file mode 100644
index 0000000..f7fbddc
--- /dev/null
+++ b/mne/tests/test_misc.py
@@ -0,0 +1,12 @@
+import os.path as op
+
+from ..misc import parse_config
+
+ave_fname = op.join(op.dirname(__file__), '..', 'fiff', 'tests', 'data',
+ 'test.ave')
+
+def test_parse_ave():
+ """Test parsing of .ave file
+ """
+ conditions = parse_config(ave_fname)
+ assert len(conditions) == 4
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/python-mne.git
More information about the debian-med-commit
mailing list