GithubHelp home page GithubHelp logo

Comments (8)

agricolab avatar agricolab commented on September 6, 2024

This xdf-file contains three streams. The stream with the name visual_oddball_Mrkrs seems to have been recorded twice. Once with this info:

 'channel_format': ['int32'],
 'nominal_srate': [0.0],
 'name': ['visual_oddball_Mrkrs'],
 'type': ['Markers'],
 'version': ['1.100000000000000'],
 'source_id': ['marker'],
 'created_at': ['27802.84568966000'],
 'uid': ['787beb22-a0e1-4366-aa5b-7ce63bd989af'],
 'session_id': ['default'],
 'hostname': ['admins-MacBook-Pro.local'],
 'v4address': [None],
 'v4data_port': ['16573'],
 'v4service_port': ['16573'],
 'v6address': [None],
 'v6data_port': ['0'],
 'v6service_port': ['0'],
 'desc': [None],
 'stream_id': 3,
 'effective_srate': 0}

and a second time with this info:

{'channel_count': [1],
 'channel_format': ['int32'],
 'nominal_srate': [0.0],
 'name': ['visual_oddball_Mrkrs'],
 'type': ['Markers'],
 'version': ['1.100000000000000'],
 'source_id': ['marker'],
 'created_at': ['30382.51934329500'],
 'uid': ['0675eb42-5900-4c37-a8fa-aeca281bc141'],
 'session_id': ['default'],
 'hostname': ['admins-MacBook-Pro.local'],
 'v4address': [None],
 'v4data_port': ['16574'],
 'v4service_port': ['16575'],
 'v6address': [None],
 'v6data_port': ['0'],
 'v6service_port': ['0'],
 'desc': [None],
 'stream_id': 1,
 'effective_srate': 0}

Logging this, as one hypothesis is that the issue you reported might have been caused by this. The second stream only contains a single sample: [[0]].

from pyxdf.

agricolab avatar agricolab commented on September 6, 2024

More in depth analysis of your marker streams showed that the markers all appear to have been sent at very similar timepoints. When loading with xdf, hdr = load_xdf("test.xdf", synchronize_clocks=False, dejitter_timestamps=False), we still have a very narrow range. Additionally, the stream footer reports 'first_timestamp': ['1612158259.371227'],'last_timestamp': ['1612158296.006913'].

Yet, the stream was: 'created_at': ['30382.51934329500'], and the timestamps when the clock offset were logged, e.g.

                            {'offset': [defaultdict(list,
                                          {'time': ['30411.5097852825'],
                                           'value': ['-1.388249984302092e-05']}),
                              defaultdict(list,
                                          {'time': ['30416.510396237'],
                                           'value': ['-2.737599970714655e-05']})

These are all good, i.e. in range of the timestamps of the third stream, i.e. 'obci_eeg1'. This makes we wonder whether the outlet you used did actually use the labstreaminglayer clock for timestamps or whether it was supporting its own timestamps. Can you tell us more about this visual_oddball_Mrkrs?

from pyxdf.

sari-saba-sadiya avatar sari-saba-sadiya commented on September 6, 2024

This is probably it! The code that streams visual_oddball_Mrkrs can be found here in lines 175, 178 and 186. Is there any tutorial or examples online I can follow?

Am I simply always supposed to use outlet.push_sample([id],pylsl.local_clock()) when sending timestamps? I am using LabRecorder, I assumed that it syncs the streams automatically.

from pyxdf.

cboulay avatar cboulay commented on September 6, 2024

LabRecorder saves the "clock offsets", but the clock offsets use the lsl clock, which isn't the same as the time.time() clock. User-provided timestamps to the push_ functions must also use the lsl clock for synchronization to work.

One of the only reasons you would want to provide your own timestamps is if the hardware has some delay built in (like wifi transmission) and you wanted to let LSL know, you could use pylsl.local_clock() - delay_in_seconds.

Another reason is if the hardware provides accurate timestamps and you wanted to use those, but you'd still have to convert those timestamps to the lsl clock, which usually means keeping track of some offsets between the hardware timestamps and the lsl clock. This isn't always feasible.

If neither of these situations apply to you, then don't supply timestamps at all and let LSL automatically insert the timestamps.

from pyxdf.

sari-saba-sadiya avatar sari-saba-sadiya commented on September 6, 2024

Hi

@cboulay you have been a great help these lasts few days with multiple issues, I appreciate your patience.

The output looks much better. One last question, how would I be able to calculate the best upper bound of jitters or offset between the streams? I have seen different numbers mentioned in the lsl forums, but in my special case would looking at two streams and taking the biggest offset for each and adding them be around the upper bound?

I will document my code and share it as an example so the next guy would hopefully be able to set things up easier.

from pyxdf.

cboulay avatar cboulay commented on September 6, 2024

I've never had to play with those settings. Sorry I don't have any advice beyond "use the defaults until they don't work".

from pyxdf.

agricolab avatar agricolab commented on September 6, 2024

calculate the best upper bound of jitters or offset between the streams

What exactly do you mean by that? The arguments re jitter and clock_offset threshold you can pass into load_xdf or something else?

from pyxdf.

sari-saba-sadiya avatar sari-saba-sadiya commented on September 6, 2024

Hi,

I am just interested to see if there is a simple way to calculate an upper bound of the error in the syncing between the two streams.

from pyxdf.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.