Repository: mne-tools/mne-python

Issue:
Bug: Reading Evoked data from saved -ave.fif files
There seems to be problem(a bug) with reading the saved evoked data (-ave.fif files) using  mne.read_evokeds. 

The evoked data is present before we save it into a file but there seems to be a problem when we read it. (more specifically-> there are no data present for some trails when we read it)

As a result the average of subject over trials or the grand average could not be obtained. 
I use mne version '0.9.dev'. 



Discussion:
can you share the file that creates the problem as well as a script to
produce the error?

Yes I can send them to you by mail as I'm not able to send in the file on github.  

please share a tiny script that reproduces the error not your full script

also please share the broken -ave.fif file via dropbox or google drive. I
am not at Neurospin nor at work.

ok. I got the problem.

can you read the original raw file?

problem occurs at line 90 in proc_history.py is due to the fact that
this a non ascii character in user name (é)

cc @Eric89GXL 

also don't hesitate to share the files with @Eric89GXL and please add a raw file to drive so we can debug as I suspect we don't write back correctly after reading the raw file.

Tomorrow I can try to reproduce it by putting some non-ascii chars in an evoked `info` and writing/reading it

great idea. Thanks for taking a look


Resolving patch:
diff --git a/mne/io/meas_info.py b/mne/io/meas_info.py
--- a/mne/io/meas_info.py
+++ b/mne/io/meas_info.py
@@ -27,7 +27,7 @@
 from ..utils import logger, verbose
 from ..fixes import Counter
 from .. import __version__
-from ..externals.six import b, BytesIO, string_types
+from ..externals.six import b, BytesIO, string_types, text_type
 
 
 _kind_dict = dict(
@@ -595,7 +595,7 @@ def read_meas_info(fid, tree, verbose=None):
             kind = hpi_meas['directory'][k].kind
             pos = hpi_meas['directory'][k].pos
             if kind == FIFF.FIFF_CREATOR:
-                hm['creator'] = str(read_tag(fid, pos).data)
+                hm['creator'] = text_type(read_tag(fid, pos).data)
             elif kind == FIFF.FIFF_SFREQ:
                 hm['sfreq'] = float(read_tag(fid, pos).data)
             elif kind == FIFF.FIFF_NCHAN:
@@ -643,16 +643,16 @@ def read_meas_info(fid, tree, verbose=None):
                 si['id'] = int(tag.data)
             elif kind == FIFF.FIFF_SUBJ_HIS_ID:
                 tag = read_tag(fid, pos)
-                si['his_id'] = str(tag.data)
+                si['his_id'] = text_type(tag.data)
             elif kind == FIFF.FIFF_SUBJ_LAST_NAME:
                 tag = read_tag(fid, pos)
-                si['last_name'] = str(tag.data)
+                si['last_name'] = text_type(tag.data)
             elif kind == FIFF.FIFF_SUBJ_FIRST_NAME:
                 tag = read_tag(fid, pos)
-                si['first_name'] = str(tag.data)
+                si['first_name'] = text_type(tag.data)
             elif kind == FIFF.FIFF_SUBJ_MIDDLE_NAME:
                 tag = read_tag(fid, pos)
-                si['middle_name'] = str(tag.data)
+                si['middle_name'] = text_type(tag.data)
             elif kind == FIFF.FIFF_SUBJ_BIRTH_DAY:
                 tag = read_tag(fid, pos)
                 si['birthday'] = tag.data
@@ -677,7 +677,7 @@ def read_meas_info(fid, tree, verbose=None):
                 hs['ncoil'] = int(tag.data)
             elif kind == FIFF.FIFF_EVENT_CHANNEL:
                 tag = read_tag(fid, pos)
-                hs['event_channel'] = str(tag.data)
+                hs['event_channel'] = text_type(tag.data)
             hpi_coils = dir_tree_find(hpi_subsystem, FIFF.FIFFB_HPI_COIL)
             hc = []
             for coil in hpi_coils:
diff --git a/mne/io/proc_history.py b/mne/io/proc_history.py
--- a/mne/io/proc_history.py
+++ b/mne/io/proc_history.py
@@ -1,3 +1,4 @@
+# -*- coding: utf-8 -*-
 # Authors: Denis A. Engemann <denis.engemann@gmail.com>
 #          Eric Larson <larson.eric.d@gmail.com>
 # License: Simplified BSD
@@ -12,6 +13,7 @@
                     write_string, write_float_matrix, write_int_matrix,
                     write_float_sparse_rcs, write_id)
 from .constants import FIFF
+from ..externals.six import text_type
 
 
 _proc_keys = ['parent_file_id', 'block_id', 'parent_block_id',
@@ -25,7 +27,7 @@
 _proc_writers = [write_id, write_id, write_id,
                  write_int, write_string, write_string]
 _proc_casters = [dict, dict, dict,
-                 np.array, str, str]
+                 np.array, text_type, text_type]
 
 
 def _read_proc_history(fid, tree, info):
@@ -162,7 +164,7 @@ def _write_proc_history(fid, info):
 _sss_ctc_writers = (write_id, write_id, write_id,
                     write_int, write_string, write_float_sparse_rcs)
 _sss_ctc_casters = (dict, dict, dict,
-                    np.array, str, csc_matrix)
+                    np.array, text_type, csc_matrix)
 
 _sss_cal_keys = ('cal_chans', 'cal_corrs')
 _sss_cal_ids = (FIFF.FIFF_SSS_CAL_CHANS, FIFF.FIFF_SSS_CAL_CORRS)


Test patch:
diff --git a/mne/io/tests/test_meas_info.py b/mne/io/tests/test_meas_info.py
--- a/mne/io/tests/test_meas_info.py
+++ b/mne/io/tests/test_meas_info.py
@@ -1,3 +1,5 @@
+# -*- coding: utf-8 -*-
+
 import os.path as op
 
 from nose.tools import assert_false, assert_equal, assert_raises, assert_true
@@ -15,6 +17,7 @@
 base_dir = op.join(op.dirname(__file__), 'data')
 fiducials_fname = op.join(base_dir, 'fsaverage-fiducials.fif')
 raw_fname = op.join(base_dir, 'test_raw.fif')
+chpi_fname = op.join(base_dir, 'test_chpi_raw_sss.fif')
 event_name = op.join(base_dir, 'test-eve.fif')
 evoked_nf_name = op.join(base_dir, 'test-nf-ave.fif')
 hsp_fname = op.join(data_dir, 'test_hsp.txt')
@@ -85,6 +88,17 @@ def test_read_write_info():
     t2 = info2['dev_head_t']['trans']
     assert_true(len(info['chs']) == len(info2['chs']))
     assert_array_equal(t1, t2)
+    # proc_history (e.g., GH#1875)
+    creator = u'é'
+    info = io.read_info(chpi_fname)
+    info['proc_history'][0]['creator'] = creator
+    info['hpi_meas'][0]['creator'] = creator
+    info['subject_info']['his_id'] = creator
+    io.write_info(temp_file, info)
+    info = io.read_info(temp_file)
+    assert_equal(info['proc_history'][0]['creator'], creator)
+    assert_equal(info['hpi_meas'][0]['creator'], creator)
+    assert_equal(info['subject_info']['his_id'], creator)
 
 
 def test_io_dig_points():