BrainVision files

Dear colleagues,

I'm just starting to use MNE-python, and I face a problem opening
BrainVisionAnalyer files. When calling the
"mne.io.read_raw_brainvision", I get the following error (full traceback
at the end):

--> 462 params, settings = settings.split('[Comment]')
     463 cfg = configparser.ConfigParser()
     464 if hasattr(cfg, 'read_file'): # newer API

ValueError: need more than 1 value to unpack

It appears that 'read_raw_brainvision' is searching for a "section"
untitled "Comment" in the header (vhdr) file. I have been using
BrainVision files quite a lot (actually, I would like to get rid of it
by using mne-python...), and I never encountered such a "Comment" field
in my vhdr files. However, I always worked with data **exported** from
BrainVision, not acquired with it. So I guess the "Comment" field the
parser is searching might come from the files created by
BrainVisionRecorder. But since I do not have any such file, I cannot check.

I do have python code that, I believe, open all variants of files
**exported** from BrainVisionAnalyser (be they ASCII or binary, 16, 32
... bits etc...). The code outputs a dictionary for the header (vhdr)
file, a numpy.array for the data, and a list of events for the
markers/events/triggers. Although I guess it should also open files
created by BrainVisionRecorder, I cannot be sure.

So, if someone could provide me with a small file that is currently
openable by "mne.io.read_raw_brainvision", I would be happy to check
whether my code also open it. And, if you find it useful, I would be
more than happy to share the code and adapt it to mne-python (with a bit
of help from you, probably ...)

   All the best,
     B.

full traceback:
In [4]: mne.io.read_raw_brainvision('COUBA_EMG_PC_CompLeft.vhdr')
Extracting eeg Parameters from COUBA_EMG_PC_CompLeft.vhdr...

hi Boris,

our test data are in:

https://github.com/mne-tools/mne-python/tree/master/mne/io/brainvision/tests/data

don't hesitate to share a file so we can patch the reader to fix the issue.

Best,
Alex

Hi again,

Trying to find the issue, I realized that my installed version of mne
was pretty old (0.8.6), and that this issue has already been fixed (at
least it is in the dev version...). I apologize for that...

But I found another issue:

If I read correctly, it looks like line 201 of _read_vmrk_events assumes
that response triggers name must contain an integer, probably
considering that the names are "Rxxx", with "xxx" being integers.
However, this is not a requirement of the file format and, especially
after some preprocessing, the triggers names may have been changed to
pure text (for example 'LeftResp'). In this case, the code does not seem
to work, since 'trigger' is None, and line 206 issues an error:

     trigger += response_trig_shift
TypeError: unsupported operand type(s) for +=: 'NoneType' and 'int'

Am I reading the code correctly?
  
  Thanks in advance,
    B.

Jona and Teon. Any thought on this?

thanks
Alex

Teon has recently added extended BV support:
https://github.com/mne-tools/mne-python/pull/2634/files

Now with the most up-to-date version,
  event_id : dict | None
        The id of the event to consider. If None (default),
        only stimulus events are added to the stimulus channel. If dict,
        the keys will be mapped to trigger values on the stimulus channel
        in addition to the stimulus events. Keys are case-sensitive.
        Example: {'SyncStatus': 1; 'Pulse Artifact': 3}.

Does that help?

Hi Jona,

Thanks for looking at it.

Teon has recently added extended BV support:
[MRG] ENH Add support for Brainvision V2.0 by teonbrooks · Pull Request #2634 · mne-tools/mne-python · GitHub

Now with the most up-to-date version,

   event_id :dict | None
         Theid of the event to consider. If None (default),
         only stimulus events are added to the stimulus channel. Ifdict,
         the keys will be mapped to trigger values on the stimulus channel
         in addition to the stimulus events. Keys are case-sensitive.
         Example: {'SyncStatus':1;'Pulse Artifact':3}.

Does that help?

Not really, since this still assumes that the trigger values are
integers, and we translate those integers into strings (or whatever).
But if the triggers are already strings, then the code fails.

A workaround could be to check whether "trigger" is an int, and if not,
return keep the description (mdesc) of the event. Code around line 206
would read:

         if mtype.lower().startswith('response'):
             if response_trig_shift is not None:
                 if isinstance(trigger, int):
                     trigger += response_trig_shift
             else:
                 trigger = mdesc

This small modification helps reading files with marker descriptions
such as "Resp_Left" for example. But I'm not sure whether that would
introduce other issues elsewhere...

  hope this helps...
    B.

Hi Boris,

If I understand this correctly, you're saying that you want to preserve the
string information?

In MNE, the default is to have events represented as int and these are
later referred to by strings in a dict. The event_id that is mentioned in
the raw reader would be the same one you could use in your epochs
constructor. This will allow you refer to the events as strings again.
Since the underlying data representation are numpy.array of floats, this is
the best approach to maintain max cross-talk to other packages.

If I missed the mark, could you share an example file with me, and try
expressing again what you want the reader to do.

HTH,