labstreaminglayer / App-LabRecorder

An application for streaming one or more LSL streams to disk in XDF file format.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

LabRecorder (LSL?) Record with different timestamps from different OS:es

Harimus opened this issue · comments

Hello, so I'm not sure if I should post this here or on the LSL issues.

So today I tried to record some EEG + trigger signals using LSL and LabRecorder. The EEG was a gTec device, and I used the gTec to lsl executable (available on LSL docs) on Windows PC, and the Trigger was sent from Ubuntu 20.04, and the LabRecorder run on the Ubuntu 20.04.

The Recording process went fine, but afterwards when I tried to open the resulting XDF file using pyxdf.load_xdf() it gave me an error. Upon closer look, it worked when i gave the argument synchronized_clocks=False, and upon checking the recorded Timestamp I had the following:

(Pdb) Trigger_ts = temp[2].last_timestamp
(Pdb) EEG_ts = temp[1].last_timestamp
(Pdb) Trigger_ts
1670998059.5400145
(Pdb) EEG_ts
2511123.0135805015
(Pdb) datetime.utcfromtimestamp(Trigger_ts) # correct timestamp of the recording
datetime.datetime(2022, 12, 14, 6, 7, 39, 540015) 
(Pdb) datetime.utcfromtimestamp(EEG_ts)
datetime.datetime(1970, 1, 30, 1, 32, 3, 13581)

I can see that the trigger is timestamped properly (Unix) but I don't know what the EEG timestamp is supposed to be (or how I should convert it), My guess is that it's some Windows format, but neither LabRecorder or the gTec to LSL executable had an option regarding time-synchronization or format.

I'm Using LabRecorder and liblsl 1.14.0 because current version (LabRecorder-1.16.2-focal_amd64.deb) expects Qt6 for Ubuntu 20.04 (Qt6 is only default from Ubuntu 22.04. On 20.04 it's still Qt5)

Am I just missing something here (Doing something wrong, when there's a right way)? My guess that this issue might be related to the problem I have sccn/labstreaminglayer#28

Thank you in advance!

when I tried to open the resulting XDF file using pyxdf.load_xdf() it gave me an error

What error?

when i gave the argument synchronized_clocks=False

Don't do that. It's helpful for debugging but it will make your analysis useless.

It's expected that the timestamps of different streams are on completely different clocks. LSL uses std::chrono::steady_clock and this isn't guaranteed to be Unix time or anything interpretable; just think of it as a monotonic clock that only makes sense on that specific computer. LabRecorder collects clock offsets in the background and the xdf importers use those to correct timestamps into a common clock.

There was a buggy version of liblsl that didn't have clock offsets so that could be the cause of your import problem, but I think that was 1.13.something, not 1.14.

Building liblsl and LabRecorder is not so difficult if you're familiar with cmake projects at all. It might be fastest for you to attempt building it yourself than waiting for me to get back to a machine that I can put a 20.04 image on.

Thank you for your swift reply!

The error is related to the time synchronization:

File "/home/dan/anaconda3/envs/mne/lib/python3.9/site-packages/pyxdf/pyxdf.py", line 364, in load_xdf
    temp = _clock_sync(
  File "/home/dan/anaconda3/envs/mne/lib/python3.9/site-packages/pyxdf/pyxdf.py", line 618, in _clock_sync
    coef.append(_robust_fit(X, y))
  File "/home/dan/anaconda3/envs/mne/lib/python3.9/site-packages/pyxdf/pyxdf.py", line 706, in _robust_fit
    L = np.linalg.cholesky(np.dot(A.T, A))
  File "<__array_function__ internals>", line 180, in cholesky
  File "/home/dan/anaconda3/envs/mne/lib/python3.9/site-packages/numpy/linalg/linalg.py", line 770, in cholesky
    r = gufunc(a, signature=signature, extobj=extobj)
  File "/home/dan/anaconda3/envs/mne/lib/python3.9/site-packages/numpy/linalg/linalg.py", line 92, in _raise_linalgerror_nonposdef
    raise LinAlgError("Matrix is not positive definite")
numpy.linalg.LinAlgError: Matrix is not positive definite

I did the syncronization=False to check if it was indeed for debugging to check where it where erroring out. The triggers need to be synchronized anyway to be able to extract epochs of data, so can't use it with that flag.

There was a buggy version of liblsl that didn't have clock offsets so that could be the cause of your import problem, but I think that was 1.13.something, not 1.14.

Ok so If I opt for building it myself with cmake (I must admit it was a long time ago I used cmake the last time....) on the Ubuntu computer, would you recommend to do it on the newest version (1.16, I think I saw an issue that solved building it with Qt5 rather than 6. I would rather not install Qt6 because I have about 3 other systems that is closely tied to Qt5 as their system dependencies)

Okay I might have found the problem. I tried recording it from the WindowsPC initially, and this still didnt work, but If I updated to liblsl 1.16 on the Ubuntu computer (originally 1.14) and recorded with LabRecorder from Windows PC instead, the synchronization ( positive definite matrix error on np.linalg.cholesky) seems to be working and the resulting timestamps seems to be in the equal ranges. So might have been liblsl 1.14 issue.

I guess If I'd like to use LabRecorder from Ubuntu I need to build it from cmake, but I can use the RCS and control the Labrecorder on Windows PC from Ubuntu using sockets so this shouldn't be an issue.

Thanks for pointing out that there might be bugs in liblsl depending on version 💯

I was having this problem from time to time when streaming from Windows to Raspberry Pi a while back. IIRC it was around v1.13/1.14. What I remember is that there is a numerical issue that can occur if the clock offsets are inordinately huge when the matrix gets inverted, resulting from a non positive definite during some stage in the Cholesky decomposition. I am glad to know that it is a (fixed) bug. I was afraid that the longer we get from the epoch, that this issue would become a show stopper.