Skip to content

compress_ephys: pass the data format (unsigned, 8/32/64-bit, float) - #4

Merged
stevevanhooser merged 9 commits into
mainfrom
claude/ephys-data-format
Oct 31, 2026
Merged

stevevanhooser merged 9 commits into
mainfrom
claude/ephys-data-format

Conversation

@stevevanhooser

@stevevanhooser stevevanhooser commented Oct 28, 2026 •

Copy link
Copy Markdown
Contributor

Why

NDI-python's ingest needs to store data the way NDI-matlab does. For example, Intan amplifier and aux samples are stored as unsigned 16-bit integers. The encoder learned this in Waltham-Data-Science/NDI-compress#14 (merged). This PR brings the matching wrapper change, the rebuilt binaries, and a way to keep the bundled binaries in step with NDI-compress.

What

  • compress_ephys(data, fullfilename, *, output_size_bits=None, data_is_unsigned=None, data_format=None), mirroring MATLAB's ndi.compress.compress_ephys:
    • integer arrays keep their dtype (signedness and size);
    • data_format='float' stores 64-bit floats;
    • non-integer input with no data_format is still converted to int16, as before.
  • Stale-binary guard: after compressing, the wrapper checks the written header and raises if it doesn't match the request. An ndi_compress_ephys built before NDI-compress#14 ignores the format keys and silently stores signed int16. Legacy int16 calls still work with old binaries.
  • Binaries for all three platforms rebuilt from NDI-compress 650b308 (main with #14) by the new workflow, in commit 8693827.
  • build-binaries workflow: builds the tools from NDI-compress on Linux (ubuntu-22.04), macOS (universal) and Windows. It runs this package's tests with them on each platform, then commits them into src/ndicompress/bin/ on the branch it ran on.
    • Which NDI-compress commit to build is recorded in ndi-compress-ref.txt.
    • Changing that file, or the workflow itself, triggers a build. Once this PR is on main, it can also be run from the Actions tab.
    • NDI-compress is private, so the workflow reads it with a read-only deploy key (NDI_COMPRESS_DEPLOY_KEY). The key doesn't expire, isn't tied to anyone's account, and can read only NDI-compress.
    • Only the commit job can write to the repo. Every action is pinned to a commit. The NDI-compress checkout doesn't keep its key in the runner's git config.
    • On Windows the tests run in PowerShell, so they use Windows' own tar, as users' setups do.
  • test.yml can also be run by hand (workflow_dispatch). A commit made by build-binaries starts no other workflow, so after a rebuild, run "Test NDI Compress" on the branch.
  • The README explains how the bundled executables are kept up to date.

Testing

  • build-binaries run 3 passed:
    • NDI-compress built on Linux, macOS and Windows;
    • its C tests and this package's tests passed on each platform with the new binaries;
    • the binaries were then committed.
  • "Test NDI Compress" on the head commit (d428259): ubuntu, macOS and Windows all pass.
  • New tests:
    • exact round trips for int8, uint8, int16, uint16 and int32;
    • the uint16 header fields;
    • float round trip;
    • the legacy int16 conversion.
  • With the old Linux binary, the guard raised on a uint16 request and the legacy int16 call still worked.

Generated by Claude Code

compress_ephys(data, fullfilename, output_size_bits=, data_is_unsigned=,
data_format=) writes the format keys that ndi_compress_ephys reads since
Waltham-Data-Science/NDI-compress#14, matching MATLAB's
ndi.compress.compress_ephys. Integer arrays keep their dtype (signedness
and size); data_format='float' stores 64-bit floats. Non-integer input
with no data_format is still converted to int16.

The written header is checked: a binary that predates the format keys
stores signed int16 regardless, and compress_ephys now raises rather
than leaving wrong data.

The Linux ndi_compress_ephys is rebuilt from NDI-compress#14. The macOS
and Windows binaries still need copying from that PR's build artifacts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011v7R5rnKYwncJkrNZRXhtw

Copy link
Copy Markdown
Contributor Author

test (macos-latest) fails because bin/macos/ndi_compress_ephys is still the old binary. Windows will fail the same way. The code here is fine.

The old binary:

  • reads only int16, so the uint8/int8/int32 round trips fail with Error reading input data;
  • crashes on the 3-sample inputs (the short-input bug fixed in Waltham-Data-Science/NDI-compress#14);
  • ignores data_format. The new header guard catches this one: it reports (1, 0, 16) instead of the requested (2, 0, 64).

Fix: replace src/ndicompress/bin/macos/ndi_compress_ephys and src/ndicompress/bin/windows/ndi_compress_ephys.exe with the builds from NDI-compress#14's artifacts (ndi-tools-macos-latest, ndi-tools-windows-latest, run 40742285671). I can't download artifacts from my environment, so this needs a manual copy. Linux passes because its binary is already rebuilt in this PR.


Generated by Claude Code

The executables in src/ndicompress/bin were copied in by hand, so they
go stale whenever NDI-compress changes (as with NDI-compress#14).
The new build-binaries workflow builds them on Linux (ubuntu-22.04),
macOS (universal) and Windows from the NDI-compress commit named in
ndi-compress-ref.txt (or given when it is run by hand), runs this
package's tests with them on each platform, and commits them to the
branch it ran on. Changing ndi-compress-ref.txt triggers it.

ndi-compress-ref.txt starts at 650b308, NDI-compress main with #14,
so this push builds the macOS and Windows binaries this PR needs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011v7R5rnKYwncJkrNZRXhtw
…KEN secret

The workflow's own GITHUB_TOKEN can read only this repository, so the
checkout of NDI-compress failed with 'Repository not found'. The
NDI-compress checkout and ls-remote now use the repository secret
NDI_COMPRESS_TOKEN, and the run stops with an explanation when it is
not set.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011v7R5rnKYwncJkrNZRXhtw
Only the commit job gets contents: write; the build jobs, which run
third-party code and the NDI-compress build, are read-only. Every
action is pinned to a commit, since what runs here ends up in the
executables every NDI-python install runs. The NDI-compress checkout
does not keep its token in git config.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011v7R5rnKYwncJkrNZRXhtw

Copy link
Copy Markdown
Contributor Author

test (macos-latest) still fails for the same reason as before: bin/macos holds the old binary.

The fix is now in this PR as the build-binaries workflow. It builds the binaries from NDI-compress, tests them on all three platforms, and commits them. Its first run stopped at the NDI-compress checkout with "Repository not found", because NDI-compress is private and a workflow's own token can't read it.

Blocker: the repository secret NDI_COMPRESS_TOKEN, a fine-grained token with read-only Contents access to Waltham-Data-Science/NDI-compress. Once it's set, I'll trigger the build by changing ndi-compress-ref.txt. The workflow's commit doesn't start test.yml itself, so that check should then be re-run on the new head.


Generated by Claude Code

claude and others added 5 commits October 31, 2026 13:04
A deploy key does not expire, belongs to no person, and can read only
NDI-compress, where a personal access token is tied to someone's
account and (fine-grained) expires. The private key is the secret
NDI_COMPRESS_DEPLOY_KEY. The resolve job now checks NDI-compress out at
the requested ref and takes its HEAD, which works for a branch, tag or
commit and needs no token in a URL.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011v7R5rnKYwncJkrNZRXhtw
Changing ndi-compress-ref.txt starts build-binaries, which now has the
NDI_COMPRESS_DEPLOY_KEY secret. The workflow resolves main to its commit
and writes that back to the file with the binaries.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011v7R5rnKYwncJkrNZRXhtw
… workflow changes

The NDI tools unpack with tar. The build job's bash shell on Windows
is Git Bash, whose GNU tar reads 'C:\...' as a remote host, so every
expand test failed although the binaries were fine. Users (and
test.yml) run them where Windows' own tar is found, so the Windows
test step now uses pwsh. A change to this workflow now also triggers
a rebuild.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011v7R5rnKYwncJkrNZRXhtw
Built and tested on Linux, macOS and Windows by the build-binaries workflow (run 41204651693).
A commit pushed by build-binaries starts no other workflow, so the
tests could not be run on it without another push. Test NDI Compress
can now be run on any branch from the Actions tab; the README says
when.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011v7R5rnKYwncJkrNZRXhtw
@stevevanhooser
stevevanhooser merged commit 4a3e8f1 into main Oct 31, 2026
3 checks passed
@stevevanhooser
stevevanhooser deleted the claude/ephys-data-format branch October 31, 2026 17:20
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