From c0eacd7c68133d5b5f79e8aef4243500ca1c0ced Mon Sep 17 00:00:00 2001 From: Jaakko Leppakangas Date: Wed, 15 Jul 2015 16:40:06 +0300 Subject: [PATCH 1/3] EOG and ECG channels added to the bottom of ICA plot. --- mne/viz/epochs.py | 8 +++++--- mne/viz/ica.py | 49 ++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 49 insertions(+), 8 deletions(-) diff --git a/mne/viz/epochs.py b/mne/viz/epochs.py index cc5fd74f353..1028d474a07 100644 --- a/mne/viz/epochs.py +++ b/mne/viz/epochs.py @@ -620,7 +620,7 @@ def plot_epochs_psd(epochs, fmin=0, fmax=np.inf, proj=False, n_fft=256, def _prepare_mne_browse_epochs(params, projs, n_channels, n_epochs, scalings, - title, picks): + title, picks, order=None): """Helper for setting up the mne_browse_epochs window.""" import matplotlib.pyplot as plt import matplotlib as mpl @@ -645,8 +645,10 @@ def _prepare_mne_browse_epochs(params, projs, n_channels, n_epochs, scalings, inds.append(idxs[mask]) types += [t] * len(inds[-1]) pick_kwargs = dict(meg=False, ref_meg=False, exclude=[]) - for ch_type in ['eeg', 'eog', 'ecg', 'emg', 'ref_meg', 'stim', 'resp', - 'misc', 'chpi', 'syst', 'ias', 'exci']: + if order is None: + order = ['eeg', 'eog', 'ecg', 'emg', 'ref_meg', 'stim', 'resp', 'misc', + 'chpi', 'syst', 'ias', 'exci'] + for ch_type in order: pick_kwargs[ch_type] = True idxs = pick_types(params['info'], **pick_kwargs) if len(idxs) < 1: diff --git a/mne/viz/ica.py b/mne/viz/ica.py index 7b748f7919c..d7ed84047c8 100644 --- a/mne/viz/ica.py +++ b/mne/viz/ica.py @@ -537,8 +537,28 @@ def _plot_sources_raw(ica, raw, picks, exclude, start, stop, show, title, picks = range(len(orig_data)) types = ['misc' for _ in picks] picks = list(sorted(picks)) + eog_chs = pick_types(raw.info, meg=False, eog=True) + ecg_chs = pick_types(raw.info, meg=False, ecg=True) data = [orig_data[pick] for pick in picks] c_names = ['ICA %03d' % x for x in range(len(orig_data))] + for eog_idx in eog_chs: + c_names.append(raw.ch_names[eog_idx]) + types.append('eog') + for ecg_idx in ecg_chs: + c_names.append(raw.ch_names[ecg_idx]) + types.append('ecg') + extra_picks = np.append(eog_chs, ecg_chs).astype(int) + if len(extra_picks) > 0: + eog_ecg_data, _ = raw[extra_picks, :] + for idx in range(len(eog_ecg_data)): + if idx < len(eog_chs): + eog_ecg_data[idx] /= 150e-6 # scaling for eog + else: + eog_ecg_data[idx] /= 5e-4 # scaling for ecg + data = np.append(data, eog_ecg_data, axis=0) + + for idx in range(len(extra_picks)): + picks = np.append(picks, ica.n_components_ + idx) if title is None: title = 'ICA components' info = create_info([c_names[x] for x in picks], raw.info['sfreq']) @@ -616,7 +636,7 @@ def _close_event(events, params): """Function for excluding the selected components on close.""" info = params['info'] c_names = ['ICA %03d' % x for x in range(params['ica'].n_components_)] - exclude = [c_names.index(x) for x in info['bads']] + exclude = [c_names.index(x) for x in info['bads'] if x.startswith('ICA')] params['ica'].exclude = exclude @@ -626,9 +646,24 @@ def _plot_sources_epochs(ica, epochs, picks, exclude, start, stop, show, import matplotlib.pyplot as plt plt.ion() # Turn interactive mode on to avoid warnings. data = ica._transform_epochs(epochs, concatenate=True) + eog_chs = pick_types(epochs.info, meg=False, eog=True) + ecg_chs = pick_types(epochs.info, meg=False, ecg=True) c_names = ['ICA %03d' % x for x in range(ica.n_components_)] - scalings = {'misc': 5.0} - info = create_info(ch_names=c_names, sfreq=epochs.info['sfreq']) + ch_types = np.repeat('misc', ica.n_components_) + for eog_idx in eog_chs: + c_names.append(epochs.ch_names[eog_idx]) + ch_types = np.append(ch_types, 'eog') + for ecg_idx in ecg_chs: + c_names.append(epochs.ch_names[ecg_idx]) + ch_types = np.append(ch_types, 'ecg') + extra_picks = np.append(eog_chs, ecg_chs).astype(int) + if len(extra_picks) > 0: + eog_ecg_data = np.concatenate(epochs.get_data()[:, extra_picks], + axis=1) + data = np.append(data, eog_ecg_data, axis=0) + scalings = {'misc': 5.0, 'eog': 150e-6, 'ecg': 5e-4} + info = create_info(ch_names=c_names, sfreq=epochs.info['sfreq'], + ch_types=ch_types) info['projs'] = list() info['bads'] = [c_names[x] for x in exclude] if title is None: @@ -640,6 +675,8 @@ def _plot_sources_epochs(ica, epochs, picks, exclude, start, stop, show, if stop is None: stop = start + 20 stop = min(stop, len(epochs.events)) + for idx in range(len(extra_picks)): + picks = np.append(picks, ica.n_components_ + idx) n_epochs = stop - start if n_epochs <= 0: raise RuntimeError('Stop must be larger than start.') @@ -653,7 +690,8 @@ def _plot_sources_epochs(ica, epochs, picks, exclude, start, stop, show, params['label_click_fun'] = partial(_label_clicked, params=params) _prepare_mne_browse_epochs(params, projs=list(), n_channels=20, n_epochs=n_epochs, scalings=scalings, - title=title, picks=picks) + title=title, picks=picks, + order=['misc', 'eog', 'ecg']) params['hsel_patch'].set_x(params['t_start']) callback_close = partial(_close_epochs_event, params=params) params['fig'].canvas.mpl_connect('close_event', callback_close) @@ -669,7 +707,8 @@ def _plot_sources_epochs(ica, epochs, picks, exclude, start, stop, show, def _close_epochs_event(events, params): """Function for excluding the selected components on close.""" info = params['info'] - exclude = [info['ch_names'].index(x) for x in info['bads']] + exclude = [info['ch_names'].index(x) for x in info['bads'] + if x.startswith('ICA')] params['ica'].exclude = exclude From e93a5e4a46e9b6e1868373dae34efbf2e9f647c8 Mon Sep 17 00:00:00 2001 From: Jaakko Leppakangas Date: Thu, 16 Jul 2015 11:33:40 +0300 Subject: [PATCH 2/3] Handle_default. --- mne/viz/ica.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mne/viz/ica.py b/mne/viz/ica.py index d7ed84047c8..a032217a765 100644 --- a/mne/viz/ica.py +++ b/mne/viz/ica.py @@ -661,7 +661,8 @@ def _plot_sources_epochs(ica, epochs, picks, exclude, start, stop, show, eog_ecg_data = np.concatenate(epochs.get_data()[:, extra_picks], axis=1) data = np.append(data, eog_ecg_data, axis=0) - scalings = {'misc': 5.0, 'eog': 150e-6, 'ecg': 5e-4} + scalings = _handle_default('scalings_plot_raw') + scalings['misc'] = 5.0 info = create_info(ch_names=c_names, sfreq=epochs.info['sfreq'], ch_types=ch_types) info['projs'] = list() From 308b0203dc4e82234ac8ae06e3b5229ec92cc6df Mon Sep 17 00:00:00 2001 From: Jaakko Leppakangas Date: Thu, 16 Jul 2015 13:22:40 +0300 Subject: [PATCH 3/3] Fix to picks. --- mne/viz/ica.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mne/viz/ica.py b/mne/viz/ica.py index a032217a765..d22a98885b8 100644 --- a/mne/viz/ica.py +++ b/mne/viz/ica.py @@ -670,7 +670,7 @@ def _plot_sources_epochs(ica, epochs, picks, exclude, start, stop, show, if title is None: title = 'ICA components' if picks is None: - picks = list(range(len(c_names))) + picks = list(range(ica.n_components_)) if start is None: start = 0 if stop is None: