[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