Repository: mne-tools/mne-python

Issue:
Kind mismatch with Evoked
I think the wrong flag is being written for evokeds. It is saving evokeds with the`standard_error` for kind instead of `average`. Also there is a mismatch in the name, `evoked.kind` should be `average`, not `mean` according to `_aspect_rev`.

``` python
In [36]: evs = [rerf['word/prime/primed'], rerf['word/prime/unprimed']]

In [37]: evs[0]
Out[37]: <Evoked  |  comment : 'word/prime/primed', kind : mean, time : [-0.200000, 1.000000], n_epochs : 44, n_channels x n_times : 208 x 601>

In [38]: evs[0].kind
Out[38]: 'mean'

In [39]: mne.write_evokeds('/Users/teon/Desktop/test-ave.fif', evs)

In [40]: evs = mne.read_evokeds('/Users/teon/Desktop/test-ave.fif')
Reading /Users/teon/Desktop/test-ave.fif ...
    Read a total of 1 projection items:
        axial--0.100-0.030-PCA-01 (1 x 208) active
    Found the data of interest:
        t =    -200.00 ...    1000.00 ms (word/prime/primed)
        0 CTF compensation matrices available
        nave = 44 - aspect type = 101
Projections have already been applied. Setting proj attribute to True.
No baseline correction applied
    Read a total of 1 projection items:
        axial--0.100-0.030-PCA-01 (1 x 208) active
    Found the data of interest:
        t =    -200.00 ...    1000.00 ms (word/prime/unprimed)
        0 CTF compensation matrices available
        nave = 44 - aspect type = 101
Projections have already been applied. Setting proj attribute to True.
No baseline correction applied

In [41]: evs[0]
Out[41]: <Evoked  |  comment : 'word/prime/primed', kind : standard_error, time : [-0.200000, 1.000000], n_epochs : 44, n_channels x n_times : 208 x 601>

In [42]: evs[0].kind
Out[42]: 'standard_error'
```



Discussion:
I suspect the wrong flag is being _set_ by whatever function you used to construct the Evokeds -- it should probably be "average" not "mean". Evoked should be stricter about this and sanity check that it's either "average" or "standard_error", but the highest proirity should be fixing whatever created the Evoked instances in the first place. `git grep` suggests it's in `mne/stats/regression.py` -- I'll open a PR.


Resolving patch:
diff --git a/mne/epochs.py b/mne/epochs.py
--- a/mne/epochs.py
+++ b/mne/epochs.py
@@ -32,7 +32,7 @@
 from .io.proj import setup_proj, ProjMixin, _proj_equal
 from .io.base import _BaseRaw, ToDataFrameMixin
 from .bem import _check_origin
-from .evoked import EvokedArray, _aspect_rev
+from .evoked import EvokedArray
 from .baseline import rescale, _log_rescale
 from .channels.channels import (ContainsMixin, UpdateChannelsMixin,
                                 SetChannelsMixin, InterpolationMixin)
@@ -747,18 +747,16 @@ def _compute_mean_or_stderr(self, picks, mode='ave'):
                 data = np.sqrt(data / n_events)
 
         if not _do_std:
-            _aspect_kind = FIFF.FIFFV_ASPECT_AVERAGE
+            kind = 'average'
         else:
-            _aspect_kind = FIFF.FIFFV_ASPECT_STD_ERR
+            kind = 'standard_error'
             data /= np.sqrt(n_events)
         return self._evoked_from_epoch_data(data, self.info, picks, n_events,
-                                            _aspect_kind)
+                                            kind)
 
-    def _evoked_from_epoch_data(self, data, info, picks, n_events,
-                                aspect_kind):
+    def _evoked_from_epoch_data(self, data, info, picks, n_events, kind):
         """Helper to create an evoked object from epoch data"""
         info = deepcopy(info)
-        kind = _aspect_rev.get(str(aspect_kind), 'Unknown')
         evoked = EvokedArray(data, info, tmin=self.times[0],
                              comment=self.name, nave=n_events, kind=kind,
                              verbose=self.verbose)
@@ -3005,8 +3003,8 @@ def average_movements(epochs, head_pos=None, orig_sfreq=None, picks=None,
         # Apply mapping
         data[meg_picks] = np.dot(mapping, data[good_picks])
     info_to['dev_head_t'] = recon_trans  # set the reconstruction transform
-    evoked = epochs._evoked_from_epoch_data(
-        data, info_to, picks, count, 'average')
+    evoked = epochs._evoked_from_epoch_data(data, info_to, picks,
+                                            n_events=count, kind='average')
     _remove_meg_projs(evoked)  # remove MEG projectors, they won't apply now
     logger.info('Created Evoked dataset from %s epochs' % (count,))
     return (evoked, mapping) if return_mapping else evoked
diff --git a/mne/evoked.py b/mne/evoked.py
--- a/mne/evoked.py
+++ b/mne/evoked.py
@@ -942,10 +942,12 @@ def __init__(self, data, info, tmin, comment='', nave=1, kind='average',
         self.picks = None
         self.verbose = verbose
         self._projector = None
-        if self.kind == 'average':
-            self._aspect_kind = _aspect_dict['average']
-        else:
-            self._aspect_kind = _aspect_dict['standard_error']
+        if not isinstance(self.kind, string_types):
+            raise TypeError('kind must be a string, not "%s"' % (type(kind),))
+        if self.kind not in _aspect_dict:
+            raise ValueError('unknown kind "%s", should be "average" or '
+                             '"standard_error"' % (self.kind,))
+        self._aspect_kind = _aspect_dict[self.kind]
 
 
 def _get_entries(fid, evoked_node):
diff --git a/mne/stats/regression.py b/mne/stats/regression.py
--- a/mne/stats/regression.py
+++ b/mne/stats/regression.py
@@ -228,8 +228,8 @@ def linear_regression_raw(raw, events, event_id=None, tmin=-.1, tmax=1,
     solver : str | function
         Either a function which takes as its inputs the sparse predictor
         matrix X and the observation matrix Y, and returns the coefficient
-        matrix b; or a string. If str, must be `cholesky`, in which case the
-        solver used is ``linalg.solve(dot(X.T, X), dot(X.T, y))``.
+        matrix b; or a string. If str, must be ``'cholesky'``, in which case
+        the solver used is ``linalg.solve(dot(X.T, X), dot(X.T, y))``.
 
     Returns
     -------
@@ -383,13 +383,12 @@ def _make_evokeds(coefs, conds, cond_length, tmin_s, tmax_s, info):
     durations, primarily for `linear_regression_raw`. See there for an
     explanation of parameters and output."""
     evokeds = dict()
-    cum = 0
+    cumul = 0
     for cond in conds:
         tmin_, tmax_ = tmin_s[cond], tmax_s[cond]
-        evokeds[cond] = EvokedArray(coefs[:, cum:cum + tmax_ - tmin_],
-                                    info=info, comment=cond,
-                                    tmin=tmin_ / float(info["sfreq"]),
-                                    nave=cond_length[cond],
-                                    kind='mean')  # nave and kind are
-        cum += tmax_ - tmin_                      # technically not correct
+        evokeds[cond] = EvokedArray(
+            coefs[:, cumul:cumul + tmax_ - tmin_], info=info, comment=cond,
+            tmin=tmin_ / float(info["sfreq"]), nave=cond_length[cond],
+            kind='average')  # nave and kind are technically incorrect
+        cumul += tmax_ - tmin_
     return evokeds


Test patch:
diff --git a/mne/tests/test_epochs.py b/mne/tests/test_epochs.py
--- a/mne/tests/test_epochs.py
+++ b/mne/tests/test_epochs.py
@@ -1519,21 +1519,24 @@ def test_epochs_proj_mixin():
 
 
 def test_delayed_epochs():
-    """Test delayed projection
-    """
+    """Test delayed projection on Epochs"""
     raw, events, picks = _get_data()
     events = events[:10]
     picks = np.concatenate([pick_types(raw.info, meg=True, eeg=True)[::22],
                             pick_types(raw.info, meg=False, eeg=False,
                                        ecg=True, eog=True)])
     picks = np.sort(picks)
+    raw.load_data().pick_channels([raw.ch_names[pick] for pick in picks],
+                                  copy=False)
+    raw.info.normalize_proj()
+    del picks
     raw.info['lowpass'] = 40.  # fake the LP info so no warnings
     for preload in (True, False):
         for proj in (True, False, 'delayed'):
             for decim in (1, 3):
                 for ii in range(2):
                     epochs = Epochs(raw, events, event_id, tmin, tmax,
-                                    picks=picks, proj=proj, reject=reject,
+                                    proj=proj, reject=reject,
                                     preload=preload, decim=decim)
                     if ii == 1:
                         epochs.load_data()
diff --git a/mne/tests/test_evoked.py b/mne/tests/test_evoked.py
--- a/mne/tests/test_evoked.py
+++ b/mne/tests/test_evoked.py
@@ -449,6 +449,10 @@ def test_array_epochs():
     assert_equal(evoked1.kind, evoked3.kind)
     assert_equal(evoked1.nave, evoked3.nave)
 
+    # test kind check
+    assert_raises(TypeError, EvokedArray, data1, info, tmin=0, kind=1)
+    assert_raises(ValueError, EvokedArray, data1, info, tmin=0, kind='mean')
+
     # test match between channels info and data
     ch_names = ['EEG %03d' % (i + 1) for i in range(19)]
     types = ['eeg'] * 19