Event markers that have been sent via LSL to the eego recording software (as opposed to an analog TTL trigger sent to the amplifier) may not be exported to the .EVT file created by eego. If you’re experiencing this, there’s an easy fix: delete the .EVT file! The markers are correctly encoded in the .CNT file. Without the .EVT, the libeep library (for which mne.io.read_raw_ant() is a wrapper) looks in the .CNT.
Could you share on GitHub - mscheltienne/antio: Python package to handle I/O with the CNT format from ANT Neuro. a set of files with/without .evt and a minimum loading script with mne.io.read_raw_ant (uses antio under the hood) which demonstrates this? It kind of sounds like a bug that could be fixed by having antio (and the underlying libeep) load both source of events and merge them.
Mathieu
Of course! Would you like me to create a new “issue” for this?
Thanks a lot. For x-ref: Reading ANT Neuro .CNT files that contain LSL derived markers: antio vs. MNE, with and without an EVT file · Issue #92 · mscheltienne/antio · GitHub
You bet. I tentatively agree with the merging idea, but everything should be present in the .CNT. ANT is considering getting rid of the EVT file entirely.
While we’re here, it’d be wonderful if mne.io.read_raw_ant() could extract impedance values. The antio version can do it, and I’ve been using this kludgy approach:
# Get the impedances using the older version of antio
cnt = read_cnt(file_path)
onsets,_,descriptions,impedances,_ = read_triggers(cnt)
# Place them in the mne.Info object as a DataFrame
raw.info['description'] = pd.DataFrame(
impedances, # 2xN array where N is the number of channels. Impedances collected at the beginning and end of a recording
index=pd.Index( # Timestamps for the impedance measures
[onset/raw.info['sfreq'] for i,onset in enumerate(onsets) if descriptions[i]=='impedance'], # divide the sample number by the sample frequency to get the time in seconds
name='time',
),
columns=pd.Index( # Channel names
raw.ch_names,
name='channel',
),
).stack().rename('impedance').reset_index().to_json(orient='index') # Rearrange and convert to json string
# These can be extracted with:
# df = pd.read_json(StringIO(raw.info['description']), orient='index').set_index(['time','channel'])