python-neo icon indicating copy to clipboard operation
python-neo copied to clipboard

Blackrock nsx files to edf/mne

Open Falach opened this issue 3 years ago • 3 comments

Hi, I'm trying to convert my blackrock recordings into edf to mne files using python. I tried to run some examples I found using BlackrockIO: https://mne.tools/stable/auto_examples/io/read_neo_format.html https://tinmard.github.io/file-conversion.html https://github.com/tinmarD/utils_python/blob/master/utils_eeg_io.py But I got different errors and I still can't figure it out. It seems like they were some API updates, and also not all channels are represented in the output (only 2). Does anyone have an example of this kind of conversion? Or just documentation to help me figure out the format and how to handle the situation?

Thanks

Falach avatar Feb 09 '22 16:02 Falach

Hi @Falach, the last two example codes you are linking are assuming AnalogSignal objects to contain only a single recording trace. This default behavior was changed with the neo 0.9.0 release. You can force the old behaviour using the signal_group_mode flag. See notes here: `https://neo.readthedocs.io/en/stable/releases/0.9.0.html.

Neo does not support writing to EDF itself, you would need to use pyedflib or another library to create files of that format. For reading data using neo there's also documentation on readthedocs (https://neo.readthedocs.io/en/stable/io.html) and tutorial material available here (https://gin.g-node.org/NeuralEnsemble/neo_elephant_teaching, see tutorial notebooks).

I suspect your AnalogSignals contain multiple traces and not just 2, could you check the .shape attribute? The first dimension gives you the number of samples and the second the number of recording traces.

JuliaSprenger avatar Feb 10 '22 09:02 JuliaSprenger

Thanks for the quick answer @JuliaSprenger :) I already wrote code that converts from MNE raw/ NumPy array to edf so if I could initialize one of those it can be great. I am supposed to have 94 channels and I also can see their names in one of the AnalogSignal objects. I think I managed to covert properly with this code:

nsx_reader = neo.io.BlackrockIO(filename=nsx_filepath)
bl = nsx_reader.read(lazy=False)[0]
signal = bl.segments[1].analogsignals[1]
data = signal.transpose().magnitude
ch_names = signal.name
sfreq = int(signal.sampling_rate.magnitude)
info = mne.create_info(ch_names=ch_names.replace('Channel bundle(', '').split(','), sfreq=sfreq)
mne_raw = mne.io.RawArray(data, info)

Falach avatar Feb 13 '22 14:02 Falach

Hi @Falach, this looks like it should work. As a note: You are only converting a single AnalogSignal object of a single Segment. Just be aware there might be more data in other Segments / AnalogSignals. Also be aware that by using .magnitude you are stripping all physical unit information of a value. You might want to ensure a specific unit by first running .rescale('Hz'), e.g. to rescale to hertz. The channel names should also be attached as an array annotation (see .array_annotations), so you probably don't need to to the splitting of the ch_names.

JuliaSprenger avatar Mar 03 '22 13:03 JuliaSprenger

@Falach Closing this for now. Feel free to reopen if there's news.

JuliaSprenger avatar Apr 02 '23 14:04 JuliaSprenger