Repository: mne-tools/mne-python

Issue:
FIX: saving RawEDF
Trying to use the save method in a RawEDF object creates the following error ...
![screenshot from 2015-06-01 16 34 00](https://cloud.githubusercontent.com/assets/1099867/7941636/7f7d2b9e-090d-11e5-82b0-489967625512.png)



Discussion:
if you debug here, what's the value of stim_channel?

For me its 72

Can you upload a sample file somewhere for us to try it, and give a minimal script?

Sure. The files I'm analysing are about 1 GB each, but I'll find a smaller one to work with.

I've uploaded a sample .bdf with a short code that reproduces the error to the following repo

https://github.com/leggitta/SampleBDF

@leggitta it seems to work with you preload the data. with the stim_channel, by default, it automatically detects the channel, which is the Status so you don't need to specify it.

@Eric89GXL do you have any clue why save breaks with `preload=False`

No, I don't know why that would break it. I guess our tests aren't comprehensive enough.

:( :(


Resolving patch:
diff --git a/mne/io/base.py b/mne/io/base.py
--- a/mne/io/base.py
+++ b/mne/io/base.py
@@ -226,7 +226,7 @@ class _BaseRaw(ProjMixin, ContainsMixin, PickDropChannelsMixin,
     @verbose
     def __init__(self, info, preload=False,
                  first_samps=(0,), last_samps=None,
-                 filenames=(), raw_extras=(),
+                 filenames=(None,), raw_extras=(None,),
                  comp=None, orig_comp_grade=None,
                  orig_format='double', dtype=np.float64,
                  verbose=None):
@@ -1053,6 +1053,8 @@ def crop(self, tmin=0.0, tmax=None, copy=True):
         raw._last_samps[-1] -= cumul_lens[keepers[-1] + 1] - 1 - smax
         raw._raw_extras = [r for ri, r in enumerate(raw._raw_extras)
                            if ri in keepers]
+        raw._filenames = [r for ri, r in enumerate(raw._filenames)
+                          if ri in keepers]
         if raw.preload:
             # slice and copy to avoid the reference to large array
             raw._data = raw._data[:, smin:smax + 1].copy()
@@ -1610,6 +1612,10 @@ def append(self, raws, preload=None):
             self._filenames += r._filenames
         self._update_times()
 
+        if not (len(self._first_samps) == len(self._last_samps) ==
+                len(self._raw_extras) == len(self._filenames)):
+            raise RuntimeError('Append error')  # should never happen
+
     def close(self):
         """Clean up the object.
 
@@ -1624,8 +1630,9 @@ def copy(self):
         return deepcopy(self)
 
     def __repr__(self):
-        s = ', '.join(('%r' % op.basename(self._filenames[0]),
-                       "n_channels x n_times : %s x %s"
+        name = self._filenames[0]
+        name = 'None' if name is None else op.basename(name)
+        s = ', '.join(('%r' % name, "n_channels x n_times : %s x %s"
                        % (len(self.ch_names), self.n_times)))
         s = "n_channels x n_times : %s x %s" % (len(self.info['ch_names']),
                                                 self.n_times)
diff --git a/mne/io/edf/edf.py b/mne/io/edf/edf.py
--- a/mne/io/edf/edf.py
+++ b/mne/io/edf/edf.py
@@ -249,8 +249,10 @@ def _read_segment_file(self, data, idx, offset, fi, start, stop,
         data *= gains.T[sel]
         data += offsets[sel]
 
-        if stim_channel is not None:
-            stim_channel_idx = np.where(sel == stim_channel)[0][0]
+        # only try to read the stim channel if it's not None and it's
+        # actually one of the requested channels
+        if stim_channel is not None and (sel == stim_channel).sum() > 0:
+            stim_channel_idx = np.where(sel == stim_channel)[0]
             if annot and annotmap:
                 evts = _read_annot(annot, annotmap, sfreq,
                                    self._last_samps[fi])


Test patch:
diff --git a/mne/io/array/tests/test_array.py b/mne/io/array/tests/test_array.py
--- a/mne/io/array/tests/test_array.py
+++ b/mne/io/array/tests/test_array.py
@@ -60,6 +60,7 @@ def test_array_raw():
     # Make sure concatenation works
     raw_concat = concatenate_raws([raw2.copy(), raw2])
     assert_equal(raw_concat.n_times, 2 * raw2.n_times)
+    assert_true('RawArray' in repr(raw2))
 
     # saving
     temp_fname = op.join(tempdir, 'raw.fif')
diff --git a/mne/io/brainvision/tests/test_brainvision.py b/mne/io/brainvision/tests/test_brainvision.py
--- a/mne/io/brainvision/tests/test_brainvision.py
+++ b/mne/io/brainvision/tests/test_brainvision.py
@@ -8,7 +8,7 @@
 import os.path as op
 import inspect
 
-from nose.tools import assert_equal, assert_raises
+from nose.tools import assert_equal, assert_raises, assert_true
 import numpy as np
 from numpy.testing import assert_array_almost_equal, assert_array_equal
 
@@ -48,6 +48,7 @@ def test_brainvision_data():
                   preload=True, scale="0")
     raw_py = read_raw_brainvision(vhdr_path, montage, eog=eog, preload=True)
     raw_py.preload_data()  # currently does nothing
+    assert_true('RawBrainVision' in repr(raw_py))
 
     assert_equal(raw_py.info['highpass'], 0.)
     assert_equal(raw_py.info['lowpass'], 250.)
diff --git a/mne/io/bti/tests/test_bti.py b/mne/io/bti/tests/test_bti.py
--- a/mne/io/bti/tests/test_bti.py
+++ b/mne/io/bti/tests/test_bti.py
@@ -81,6 +81,7 @@ def test_raw():
             os.remove(tmp_raw_fname)
         with Raw(exported, preload=True) as ex:
             with read_raw_bti(pdf, config, hs) as ra:
+                assert_true('RawBTi' in repr(ra))
                 assert_equal(ex.ch_names[:NCH], ra.ch_names[:NCH])
                 assert_array_almost_equal(ex.info['dev_head_t']['trans'],
                                           ra.info['dev_head_t']['trans'], 7)
diff --git a/mne/io/edf/tests/test_edf.py b/mne/io/edf/tests/test_edf.py
--- a/mne/io/edf/tests/test_edf.py
+++ b/mne/io/edf/tests/test_edf.py
@@ -52,6 +52,7 @@ def test_bdf_data():
     """
     raw_py = read_raw_edf(bdf_path, montage=montage_path, eog=eog,
                           misc=misc, preload=True)
+    assert_true('RawEDF' in repr(raw_py))
     picks = pick_types(raw_py.info, meg=False, eeg=True, exclude='bads')
     data_py, _ = raw_py[picks]
 
diff --git a/mne/io/egi/tests/test_egi.py b/mne/io/egi/tests/test_egi.py
--- a/mne/io/egi/tests/test_egi.py
+++ b/mne/io/egi/tests/test_egi.py
@@ -27,6 +27,7 @@ def test_io_egi():
     with warnings.catch_warnings(record=True) as w:
         warnings.simplefilter('always', category=RuntimeWarning)
         raw = read_raw_egi(egi_fname, include=None)
+        assert_true('RawEGI' in repr(raw))
         raw.preload_data()  # currently does nothing
         assert_equal(len(w), 1)
         assert_true(w[0].category == RuntimeWarning)
diff --git a/mne/io/fiff/tests/test_raw.py b/mne/io/fiff/tests/test_raw.py
--- a/mne/io/fiff/tests/test_raw.py
+++ b/mne/io/fiff/tests/test_raw.py
@@ -379,6 +379,7 @@ def test_io_raw():
     # test unicode io
     for chars in [b'\xc3\xa4\xc3\xb6\xc3\xa9', b'a']:
         with Raw(fif_fname) as r:
+            assert_true('Raw' in repr(r))
             desc1 = r.info['description'] = chars.decode('utf-8')
             temp_file = op.join(tempdir, 'raw.fif')
             r.save(temp_file, overwrite=True)
diff --git a/mne/io/kit/tests/test_kit.py b/mne/io/kit/tests/test_kit.py
--- a/mne/io/kit/tests/test_kit.py
+++ b/mne/io/kit/tests/test_kit.py
@@ -9,7 +9,7 @@
 import inspect
 import numpy as np
 from numpy.testing import assert_array_almost_equal, assert_array_equal
-from nose.tools import assert_equal, assert_raises
+from nose.tools import assert_equal, assert_raises, assert_true
 import scipy.io
 
 from mne import pick_types, concatenate_raws, Epochs, read_events
@@ -54,7 +54,7 @@ def test_data():
     raw_py = read_raw_kit(sqd_path, mrk_path, elp_path, hsp_path,
                           stim=list(range(167, 159, -1)), slope='+',
                           stimthresh=1, preload=True)
-    print(repr(raw_py))
+    assert_true('RawKIT' in repr(raw_py))
 
     # Binary file only stores the sensor channels
     py_picks = pick_types(raw_py.info, exclude='bads')