Repository: mne-tools/mne-python

Issue:
Reminder: fix ica test warnings
This reminds us / me to look into the ica test warnings issued when invoking different automatically  linked scored functions with the test data snippet.



Discussion:
can we close?

I think it's not yet addressed.

On 07.03.2013, at 22:02, Alexandre Gramfort notifications@github.com wrote:

> can we close?
> 
> —
> Reply to this email directly or view it on GitHub.


Resolving patch:
diff --git a/examples/preprocessing/plot_ica_from_epochs.py b/examples/preprocessing/plot_ica_from_epochs.py
--- a/examples/preprocessing/plot_ica_from_epochs.py
+++ b/examples/preprocessing/plot_ica_from_epochs.py
@@ -5,8 +5,10 @@
 
 ICA is used to decompose raw data in 49 to 50 sources.
 The source matching the ECG is found automatically
-and displayed. Finally, the cleaned epochs are compared
-to the uncleaned epochs.
+and displayed. Finally, after the cleaned epochs are
+compared to the uncleaned epochs, evoked ICA sources
+are investigated using sensor space ERF plotting
+techniques.
 
 """
 print __doc__
@@ -128,3 +130,15 @@
 pl.figure()
 epochs_ica.average().plot()
 pl.show()
+
+###############################################################################
+# Inspect evoked ICA sources
+
+# create ICA Epochs object.
+ica_epochs = ica.sources_as_epochs(epochs)
+
+# don't exclude bad sources by passing an empty list.
+ica_picks = mne.fiff.pick_types(ica_epochs.info, misc=True, exclude=[])
+ica_evoked = ica_epochs.average(ica_picks)
+pl.figure()
+ica_evoked.plot(titles=dict(misc='ICA sources'))
diff --git a/mne/preprocessing/ica.py b/mne/preprocessing/ica.py
--- a/mne/preprocessing/ica.py
+++ b/mne/preprocessing/ica.py
@@ -25,7 +25,7 @@
 
 from ..cov import compute_whitener
 from .. import Covariance
-from ..fiff import pick_types, pick_channels
+from ..fiff.pick import pick_types, pick_channels
 from ..fiff.write import write_double_matrix, write_string, \
                          write_name_list, write_int, start_block, \
                          end_block
@@ -470,7 +470,6 @@ def sources_as_raw(self, raw, picks=None, start=None, stop=None):
             raw._data, raw._times = data, times
 
         out.fids = []
-        out.info['filenames'] = []
         data_, times_ = raw[picks, start:stop]
 
         out._data = np.r_[sources, data_]
@@ -481,27 +480,64 @@ def sources_as_raw(self, raw, picks=None, start=None, stop=None):
         out.first_samp = raw.first_samp + (start if start else 0)
         out.last_samp = out.first_samp + stop if stop else raw.last_samp
 
+        self._ica_export_info(out.info, raw, picks)
+
+        return out
+
+    def _ica_export_info(self, info, container, picks):
+        """ Aux function
+        """
         # set channel names and info
-        ch_names = out.info['ch_names'] = []
-        ch_info = out.info['chs'] = []
-        for i in xrange(self.n_components_):
-            ch_names.append('ICA %03d' % (i + 1))
-            ch_info.append(dict(ch_name='ICA %03d' % (i + 1), cal=1,
-                logno=i + 1, coil_type=FIFF.FIFFV_COIL_NONE,
+        ch_names = info['ch_names'] = []
+        ch_info = info['chs'] = []
+        for ii in xrange(self.n_components_):
+            this_source = 'ICA %03d' % (ii + 1)
+            ch_names.append(this_source)
+            ch_info.append(dict(ch_name=this_source, cal=1,
+                logno=ii + 1, coil_type=FIFF.FIFFV_COIL_NONE,
                 kind=FIFF.FIFFV_MISC_CH, coord_Frame=FIFF.FIFFV_COORD_UNKNOWN,
-                loc=np.array([0., 0., 0., 1., 0., 0., 0., 1.,
-                              0., 0., 0., 1.], dtype=np.float32),
+                loc=np.array([0., 0., 0., 1.] * 3, dtype='f4'),
                 unit=FIFF.FIFF_UNIT_NONE, eeg_loc=None, range=1.0,
-                scanno=i + 1, unit_mul=0, coil_trans=None))
+                scanno=ii + 1, unit_mul=0, coil_trans=None))
 
         # re-append additionally picked ch_names
-        ch_names += [raw.ch_names[k] for k in picks]
+        ch_names += [container.ch_names[k] for k in picks]
         # re-append additionally picked ch_info
-        ch_info += [raw.info['chs'][k] for k in picks]
+        ch_info += [container.info['chs'][k] for k in picks]
 
         # update number of channels
-        out.info['nchan'] = len(picks) + self.n_components_
-        out.info['bads'] = [self.ch_names[k] for k in self.exclude]
+        info['nchan'] = len(picks) + self.n_components_
+
+        info['bads'] = [self.ch_names[k] for k in self.exclude]
+        container.info['filenames'] = []
+
+    def sources_as_epochs(self, epochs, picks=None):
+        """ Create epochs in ICA space from raw object
+
+        Parameters
+        ----------
+        epochs : instance of Epochs
+            Epochs object to draw sources from.
+        picks : array-like
+            Channels to be included in addition to the sources. If None,
+            artifact channels will be included.
+
+        Returns
+        -------
+        ica_epochs : instance of Epochs
+            The epochs in ICA space.
+        """
+
+        out = epochs.copy()
+        sources = self.get_sources_epochs(epochs)
+        if picks is None:
+            picks = pick_types(epochs.info, meg=False, eeg=False, misc=True,
+                               ecg=True, eog=True, stim=True, exclude='bads')
+
+        out._data = np.concatenate([sources, epochs.get_data()[:, picks]],
+                                    axis=1) if len(picks) > 0 else sources
+
+        self._ica_export_info(out.info, epochs, picks)
 
         return out
 


Test patch:
diff --git a/mne/preprocessing/tests/test_ica.py b/mne/preprocessing/tests/test_ica.py
--- a/mne/preprocessing/tests/test_ica.py
+++ b/mne/preprocessing/tests/test_ica.py
@@ -51,6 +51,8 @@
 epochs_eog = Epochs(raw, events[:4], event_id, tmin, tmax, picks=picks2,
                 baseline=(None, 0), preload=True)
 
+score_funcs_unsuited = ['pointbiserialr', 'ansari']
+
 
 @requires_sklearn
 def test_ica_core():
@@ -222,16 +224,13 @@ def test_ica_additional():
         assert_array_almost_equal(_raw1[:, :][0], _raw2[:, :][0])
 
     os.remove(test_ica_fname)
-    # score funcs raw, with catch since "ties preclude exact" warning
-    # XXX this should be fixed by a future PR...
-    with warnings.catch_warnings(True) as w:
-        sfunc_test = [ica.find_sources_raw(raw, target='EOG 061',
-                score_func=n, start=0, stop=10)
-                for n, f in score_funcs.items()]
-    # score funcs raw
-
-    # check lenght of scores
-    [assert_true(ica.n_components_ == len(scores)) for scores in sfunc_test]
+    # check scrore funcs
+    for name, func in score_funcs.items():
+        if name in score_funcs_unsuited:
+            continue
+        scores = ica.find_sources_raw(raw, target='EOG 061', score_func=func,
+                                      start=0, stop=10)
+        assert_true(ica.n_components_ == len(scores))
 
     # check univariate stats
     scores = ica.find_sources_raw(raw, score_func=stats.skew)
@@ -248,18 +247,15 @@ def test_ica_additional():
                              var_criterion=idx, kurt_criterion=idx)
     ## score funcs epochs ##
 
-    # check lenght of scores
-    # XXX this needs to be fixed, some of the score funcs don't seem to be
-    # suited for the testing data.
-    with warnings.catch_warnings(True) as w:
-        sfunc_test = [ica.find_sources_epochs(epochs_eog, target='EOG 061',
-                score_func=n)
-                for n, f in score_funcs.items()]
-
-    # check lenght of scores
-    [assert_true(ica.n_components_ == len(scores)) for scores in sfunc_test]
+    # check score funcs
+    for name, func in score_funcs.items():
+        if name in score_funcs_unsuited:
+            continue
+        scores = ica.find_sources_epochs(epochs_eog, target='EOG 061',
+                                         score_func=func)
+        assert_true(ica.n_components_ == len(scores))
 
-    # check univariat stats
+    # check univariate stats
     scores = ica.find_sources_epochs(epochs, score_func=stats.skew)
 
     # check exception handling
@@ -293,6 +289,14 @@ def test_ica_additional():
     ica_raw2.close()
     os.remove(test_ica_fname)
 
+    # Test ica epochs export
+    ica_epochs = ica.sources_as_epochs(epochs)
+    assert_true(ica_epochs.events.shape == epochs.events.shape)
+    sources_epochs = ica.get_sources_epochs(epochs)
+    assert_array_equal(ica_epochs.get_data(), sources_epochs)
+    ica_chans = [ch for ch in ica_epochs.ch_names if 'ICA' in ch]
+    assert_true(ica.n_components_ == len(ica_chans))
+
     # regression test for plot method
     assert_raises(ValueError, ica.plot_sources_raw, raw,
                   order=np.arange(50))