Skip to content

An example with double channel string marker#4

Open
abcsds wants to merge 7 commits into
xdf-modules:masterfrom
abcsds:master
Open

An example with double channel string marker#4
abcsds wants to merge 7 commits into
xdf-modules:masterfrom
abcsds:master

Conversation

@abcsds
Copy link
Copy Markdown

@abcsds abcsds commented Jan 25, 2025

Multiple channels with string markers seem to have been an issue in both liblxdf and xdf.jl. This file was uploaded by @tstenner in xdf-modules/libxdf#19
It presents a single data point at time [16.725987961266686] with markers ["Marker 0A" "Marker 0B"].
The header of the file is:

<?xml version=\"1.0\"?><info><name>SendMarker</name><type>Marker</type><channel_count>2</channel_count><nominal_srate>1000</nominal_srate><channel_format>string</channel_format><created_at>10</created_at></info>

The footer of the file is:

<?xml version=\"1.0\"?><info><first_timestamp>10</first_timestamp><last_timestamp>10.001</last_timestamp><sample_count>1</sample_count></info>

@cbrnr
Copy link
Copy Markdown
Contributor

cbrnr commented Jan 27, 2025

Same comment as in #5, can you add a description for the example file please? Either in a separate .md file, or (this would be my slight preference) add a section in README.md.

@cbrnr
Copy link
Copy Markdown
Contributor

cbrnr commented Jan 29, 2025

Also, I think multichannel_string_marker.xdf would be a slightly better name, can you rename it please? Or maybe twochannel_string_marker.xdf?

@abcsds
Copy link
Copy Markdown
Author

abcsds commented Jan 31, 2025

Used twochannel_string_marker.xdf.

@cbrnr
Copy link
Copy Markdown
Contributor

cbrnr commented Feb 3, 2025

@abcsds we have updated the README, can you please add a new section with a description of this dataset? Thanks!

Copy link
Copy Markdown
Contributor

@cbrnr cbrnr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @abcsds, I only have a few comments.

Comment thread README.md Outdated
Comment thread README.md
Comment thread README.md Outdated
Comment thread README.md Outdated
Comment thread README.md Outdated
@cbrnr
Copy link
Copy Markdown
Contributor

cbrnr commented Feb 19, 2025

Looks good! Now we should try to figure out the time stamp issue (i.e., why XDF.jl reports a different time stamp than pyxdf)!

abcsds added a commit to abcsds/XDF.jl that referenced this pull request May 22, 2026
The XDF binary spec stores each sample of a string stream as one
varlen-prefixed string per channel, but `read_xdf` read a single
varlen-prefixed string and broadcast it across every channel of the
sample. On twochannel_string_marker.xdf XDF.jl returned

    ["Marker 0A" "Marker 0A"]

where pyxdf returned

    [["Marker 0A", "Marker 0B"]].

Loop over channels and read one varlen-prefixed string each instead.

Add a regression test that vendors the 1.5 KB twochannel_string_marker.xdf
fixture from xdf-modules/example-files#4 under test/testdata/ and pins
its sha256, then asserts stream metadata and the per-channel marker
payload. test/Project.toml gains a dependency on stdlib SHA so the
fixture-integrity check can run.

Resolves cbrnr#10. Supersedes cbrnr#14.
abcsds added a commit to abcsds/XDF.jl that referenced this pull request May 22, 2026
With a single ClockOffset chunk, `sync_clock` built a 1x2 design matrix
and solved it with `x \ y`. That system is underdetermined, so Julia's
left divide returns the minimum-norm solution -- a valid answer to the
underdetermined system, but one that imposes a spurious non-zero slope
on the offset trajectory. On twochannel_string_marker.xdf (one offset
of -0.1 at clock time 6.1, one sample at raw t = 17.0) it produced

    t = 16.725987961266686

instead of the expected

    t = 17.0 + (-0.1) = 16.9.

pyxdf's `_clock_sync` (xdf-modules/pyxdf src/pyxdf/pyxdf.py) treats
single-offset segments as `(intercept = offset, slope = 0)`, i.e. a
constant correction. Special-case `size(offsets, 1) == 1` to do the
same; the regression path is unchanged for two or more offsets.

Add two sub-testsets pinning both raw and synced time stamps to the
values pyxdf returns on the same fixture; the synced assertion fails
without this change and passes with it.

Resolves the timestamp discrepancy flagged on
xdf-modules/example-files#4.
abcsds added a commit to abcsds/XDF.jl that referenced this pull request May 22, 2026
The XDF binary spec stores each sample of a string stream as one
varlen-prefixed string per channel, but `read_xdf` read a single
varlen-prefixed string and broadcast it across every channel of the
sample. On twochannel_string_marker.xdf XDF.jl returned

    ["Marker 0A" "Marker 0A"]

where pyxdf returned

    [["Marker 0A", "Marker 0B"]].

Loop over channels and read one varlen-prefixed string each instead.

Add a regression test that vendors the 1.5 KB twochannel_string_marker.xdf
fixture from xdf-modules/example-files#4 under test/testdata/ and pins
its sha256, then asserts stream metadata and the per-channel marker
payload. test/Project.toml gains a dependency on stdlib SHA so the
fixture-integrity check can run.

Resolves cbrnr#10. Supersedes cbrnr#14.
abcsds added a commit to abcsds/XDF.jl that referenced this pull request May 22, 2026
With a single ClockOffset chunk, `sync_clock` built a 1x2 design matrix
and solved it with `x \ y`. That system is underdetermined, so Julia's
left divide returns the minimum-norm solution -- a valid answer to the
underdetermined system, but one that imposes a spurious non-zero slope
on the offset trajectory. On twochannel_string_marker.xdf (one offset
of -0.1 at clock time 6.1, one sample at raw t = 17.0) it produced

    t = 16.725987961266686

instead of the expected

    t = 17.0 + (-0.1) = 16.9.

pyxdf's `_clock_sync` (xdf-modules/pyxdf src/pyxdf/pyxdf.py) treats
single-offset segments as `(intercept = offset, slope = 0)`, i.e. a
constant correction. Special-case `size(offsets, 1) == 1` to do the
same; the regression path is unchanged for two or more offsets.

Add two sub-testsets pinning both raw and synced time stamps to the
values pyxdf returns on the same fixture; the synced assertion fails
without this change and passes with it.

Resolves the timestamp discrepancy flagged on
xdf-modules/example-files#4.
abcsds added a commit to abcsds/XDF.jl that referenced this pull request May 22, 2026
The XDF binary spec stores each sample of a string stream as one
varlen-prefixed string per channel, but `read_xdf` read a single
varlen-prefixed string and broadcast it across every channel of the
sample. On twochannel_string_marker.xdf XDF.jl returned

    ["Marker 0A" "Marker 0A"]

where pyxdf returned

    [["Marker 0A", "Marker 0B"]].

Loop over channels and read one varlen-prefixed string each instead.

Add a regression test that vendors the 1.5 KB twochannel_string_marker.xdf
fixture from xdf-modules/example-files#4 under test/testdata/ and pins
its sha256, then asserts stream metadata and the per-channel marker
payload. test/Project.toml gains a dependency on stdlib SHA so the
fixture-integrity check can run.

Resolves cbrnr#10. Supersedes cbrnr#14.
abcsds added a commit to abcsds/XDF.jl that referenced this pull request May 22, 2026
With a single ClockOffset chunk, `sync_clock` built a 1x2 design matrix
and solved it with `x \ y`. That system is underdetermined, so Julia's
left divide returns the minimum-norm solution -- a valid answer to the
underdetermined system, but one that imposes a spurious non-zero slope
on the offset trajectory. On twochannel_string_marker.xdf (one offset
of -0.1 at clock time 6.1, one sample at raw t = 17.0) it produced

    t = 16.725987961266686

instead of the expected

    t = 17.0 + (-0.1) = 16.9.

pyxdf's `_clock_sync` (xdf-modules/pyxdf src/pyxdf/pyxdf.py) treats
single-offset segments as `(intercept = offset, slope = 0)`, i.e. a
constant correction. Special-case `size(offsets, 1) == 1` to do the
same; the regression path is unchanged for two or more offsets.

Add two sub-testsets pinning both raw and synced time stamps to the
values pyxdf returns on the same fixture; the synced assertion fails
without this change and passes with it.

Resolves the timestamp discrepancy flagged on
xdf-modules/example-files#4.
@abcsds abcsds mentioned this pull request May 22, 2026
3 tasks
Resolve README.md conflict by keeping both upstream's clock_resets
clock-offsets table (from xdf-modules#7) and the new twochannel_string_marker.xdf
section. Also normalize XML footer indentation in the second stream
(tabs → 4 spaces) for internal consistency within the new section, and
add a trailing newline at EOF.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants