New version with XDF file support

Hello,

I see XDF file import is on the features roadmap.
How far away is it ?
Is it weeks or rather months ?
Will it read all the streams or eeg only like eeglab ?

Kind regards
Peter

I could work on this in the next few weeks.
The only thing I needed to get started was a user to test it!
Could you share one or a few example files, in order to illustrate everything that you need to be read from these files? (upload the files somewhere and post the download links here)
Thanks

I have some files with 8 channel eeg streamed from OpenBCI and 1 channel streamed from Wiimote (GitHub - labstreaminglayer/App-Wiimote) to to LabRecorder (GitHub - labstreaminglayer/App-LabRecorder: An application for streaming one or more LSL streams to disk in XDF file format.)
I will be happy to test it when the beta is available.
I can do more twisted files if you need (openbci stream + Muse stream + wiimote stream) but this would need to wait until tomorrow.
Where shall I upload the files ?

Regards
Peter

Anything you might think is interesting.
I won't be working on it before the end of next week.

Where shall I upload the files ?

Wherever you'd like. Google drive?

I will prepare a set tomorrow then.

I just uploaded my old file
https://drive.google.com/file/d/1_Ze0yji6pNLMTjTcyZcwwhczlMm0zpow/view?usp=sharing

it contains Muse and Wiimote streams.
When browsing using python's pyxdf module, it shows 1 muse stream, 2 wiimote button streams and 2 wiimote sensors streams

I will later create. file with 2 EEG streams + Wiimote stream + pylsl generated stream as if it was generated by stimulus onset by psychopy

This is latest multi stream file but no Open?BCI yet (will create one today)

https://drive.google.com/file/d/1DPgWfp06SUOshVDIA07eRGMZgNyVSklp/view?usp=sharing

The view by pyxdf:

strong text

The use case of multiple streams (in my case at least) would be seeing selected channels (including non=EEG channels - wiimote and pylsl) so the users can focus their analysis for example on fragment between 2 wiimote markers or after a particular pylsl marker.
I do not see a use for the wiimote sensor data channel yet and am not sure how they could be presented in =Brainstorm GUI so at this stage I am ok for them to be ignored.

Please let me know when/how I can help any further here.

Regards
Peter

I added a basic support for XDF files in Brainstorm, but it probably requires additional work to get the events right. Update Brainstorm to get this commit:
https://github.com/brainstorm-tools/brainstorm3/commit/97b9386567aec56fc4fe12eabc46c0ebdd907ae4

The problem I have with your file "sub-P001_ses-S001_task-Default_run-002_eeg.xdf" is that the time stamps do not match in the different streams.

Stream 'WiimoteMarkers1':
    first_timestamp: '937859.846525154'
     last_timestamp: '937885.990850207'

Stream 'Muse':
    first_timestamp: '1642606156.35645'
     last_timestamp: '1642606209.1935'

How are we supposed to add the Wiimote markers as events available in the EEG recordings in Brainstorm?

Thank you Francois,

Let me dig here a bit.
I will be back

Regards
Peter

Yes, this obviously does not make any sense.
It seems to be derived from the "created_at" time which is a time since device reboot according to:
https://github.com/sccn/labstreaminglayer/issues/28

I will flag this to the developer and will be back.

Regards
Peter

Just created:
GIT HUB /labstreaminglayer/App-Wiimote/issues/1

Regards
Peter

My previous post was hidden as it contained a link to github:

Yes, this obviously does not make any sense.
It seems to be derived from the "created_at" time which is a time since device reboot according to:
"git hub issue 28"

I will flag this to the developer and will be back.

Regards
Peter

I just did a bit of digging.
May I ask how were the timestamps implemented ?
Were they just taken from the timestamps list (in python - the time_stamps list) ?

data, header = pyxdf.load_xdf(filename='/Users/windy/wiimote_pylsl_muse_test.xdf',verbose=False)
data[0]["time_stamps"]

It seems that to get the time synched between different streams implementation needs to consider the
time offset (i.e in python - >

data, header = pyxdf.load_xdf(filename='/Users/windy/wiimote_pylsl_muse_test.xdf',verbose=False)

data[0]['footer']["info"]["clock_offsets"][0]["offset"][0]["time"][0]
data[0]['footer']["info"]["clock_offsets"][0]["offset"][0]["value"][0]

Peter

May I ask how were the timestamps implemented ?
Were they just taken from the timestamps list (in python - the time_stamps list) ?

These are simply the time stamps read by the library.

It seems that to get the time synched between different streams implementation needs to consider the
time offset

Unfortunately I have no idea what to do with these clock_offsets...

[streams, fileheader] = load_xdf('wiimote_pylsl_muse_test.xdf');

% Stream 2: EEG
streams{2}.info.name        % 'Muse'
streams{2}.time_stamps(1)   % '1662538492.337204'
streams{2}.time_stamps(end) % '1662539106.378531'

streams{2}.info.clock_offsets.offset{1} 
     time: '689177.036504109'
    value: '935403.2126102761'

streams{2}.info.clock_offsets.offset{111} 
     time: '689787.5735895969'
    value: '935403.212608692'


% Stream 3: Wiimote
streams{3}.info.name        % 'WiimoteMarkers1'
streams{3}.time_stamps(1)   % '1624585.380932'
streams{3}.time_stamps(end) % '1625125.514074'

streams{3}.info.clock_offsets.offset{1} 
     time: '1624580.249122672'
    value: '-1.401640474796295e-05'

streams{3}.info.clock_offsets.offset{111}
     time: '1625190.782890341'
    value: '2.137967385351658e-06'

I am just doing further experiments with 8 channels OpenBCI + Wiimote + Pylsl (will upload the file soon if still needed)
I read the XDF into EEBLab and am getting all channels, Pylsl and wiimote markers synched in one graph.
I found the matlab examples in labstreaminglayer that use the offset synchronisation

There is github /labstreaminglayer/liblsl-Matlab repo
and the load_xdf.m matlab script:
github /xdf-modules/xdf-Matlab

I guess this script can be just included in the Brainstorm distro.

Regards
Peter

I'm sorry, I don't know where to start from or what to look for in these code bases.
Please describe what you are doing with more details: full code and step by step screen captures, including for what it means to "read the XDF into EEBLab" (I am not familiar with EEGLAB).

The function load_xdf.m from xdf-modules/xdf-Matlab is the one I've been using:

Please feel free to open PR to fix the XDF reader directly on the Brainstorm github repo:

It seems that my Muse+Wiimote xdf file was somehow corrupted.
The 3 stream xdf with OpenBCI + Wiimote + PyLSL does show all 3 streams in Brainstorm.
Thank you for your work.

So everything is working as expected?
No need to make any change to the current implementation?