Repository navigation
Always bind an epoch's binary, empty or not - #292
Merged
Merged
Conversation
ndi_element_timeseries.addepoch skipped writing and attaching
epoch_binary_data.vhsb when timepoints or datapoints was None, and fell
through to the base class, which added an element_epoch document with
nothing bound to that name.
MATLAB has no such branch. In ndi.element.timeseries/addepoch the
vhsb_write and the add_file sit AFTER the argument handling rather than
inside it, and timepoints/datapoints are required positional arguments,
so the class cannot produce a fileless epoch document at all:
vlt.file.custom_file_formats.vhsb_write(fname,timepoints,datapoints,...);
epochdoc = epochdoc.add_file('epoch_binary_data.vhsb',fname);
An epoch with NO SAMPLES is a supported case -- ndi/+mock/+fun/
subject_stimulator_neuron.m calls addepoch with [] for both, for a
stimulator element that marks a time range and carries no samples -- but
its binary is still written, just empty. An epoch may have no data; it
may not have no file. That is exactly what element_epoch's schema says
with mustbenotempty on epoch_binary_data.vhsb.
DID was not checking. VH-Lab/DID-python#86 closed check_files' step-3
fail-open, which looped over the actual file_info entries and fell
through to valid when a required name had none. So these documents were
accepted at add time and only failed at read time; now they are refused
where they are created, which is where the defect is.
The two tests under TestEpochWithoutData asserted the divergence rather
than the contract -- one of them was named
test_addepoch_without_samples_stores_no_binary. They now hold the
MATLAB behaviour: the binary is bound, it is declared on the document
(bound, not merely written -- what DID rejects is a name in file_list
with no matching file_info entry), and reading an epoch with no samples
gives nothing rather than an error, which is what the old test was
really about.
Measured against main in the same working tree, with did and
vhlab-toolbox-python both installed from main as CI installs them:
29 errors and 5 failures fixed, nothing newly broken.
- tests/test_fun_ensemble_db.py 26 errors -> 0
- tests/test_gui_app_ensemble_maker.py 3 errors -> 0
- tests/test_element_timeseries_vhsb.py 5 failed -> 0
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YHxsZ56GZsZ3hJ98TJ81t9
Contributor
Author
|
CI result on Every one of the 21 survivors is the fixture family named under What this does NOT fix — documents that declare a required file and bind nothing:
So this PR cannot reach green by itself, and that is by design rather than an oversight — the remaining work is test-side and touches ~20 sites across a dozen files, which does not belong bundled with a fix to shipping code. Tracked separately; this PR is complete as scoped. Generated by Claude Code |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
mainwent red at 12:02:34Z, when VH-Lab/DID-python#86 closed the fail-open incheck_files' step 3 — four minutes aftermain's last green run (11:45:34Z → 11:58:54Z). The failures are all one shape:What DID started rejecting is real, and it is ours.
The divergence
ndi_element_timeseries.addepochskipped writing and attaching the binary whentimepointsordatapointswasNone, and fell through to the base class — which added anelement_epochdocument with nothing bound to that name:MATLAB has no such branch. In
ndi.element.timeseries/addepochthe write and the attach sit after the argument handling rather than inside it, andtimepoints/datapointsare required positional arguments, so the class cannot produce a fileless epoch document at all:An epoch may have no data; it may not have no file
An epoch with no samples is a supported case, not an error —
ndi/+mock/+fun/subject_stimulator_neuron.m:76does exactly that for a stimulator element that marks a time range and carries no samples:That still writes a vhsb and still attaches it. The file is there and empty.
vhsb_writehandles empty input fine — 1,836 bytes of header that reads back as zero samples.So the distinction
element_epoch's schema draws withmustbenotemptyonepoch_binary_data.vhsbis exactly right, and it stays. My first reading of this was that the schema was over-claiming and should be relaxed tomustbenotempty: 0; that was wrong, and checking NDI-matlab is what showed it. Relaxing the schema would have papered over a Python bug and, worse, desynchronisedndi_commonfrom NDI-matlab to do it.The tests asserted the divergence
One of them was named
test_addepoch_without_samples_stores_no_binary— it asserted a document MATLAB cannot produce.TestEpochWithoutDatanow holds the contract instead:file_listwith no matchingfile_infoentry;Measured
Against
mainin the same working tree, withdidandvhlab-toolbox-pythonboth installed frommainas CI installs them (my container's copies of both were stale, which initially hid this behind unrelatedvhsb_writeerrors on short arrays):tests/test_fun_ensemble_db.pytests/test_gui_app_ensemble_maker.pytests/test_element_timeseries_vhsb.pyNothing newly broken — the before/after failure lists differ only by removals.
What this does NOT fix
A second family survives, and it is a different kind of problem: test fixtures that construct documents declaring a required file and never bind one.
tests/test_session_database_rm.py:39adds adata/generic_filewith nogeneric_file.ext; severalmatlab_testscases add ademoNDIwith nofilename1.ext(theconftest.pyhelper attaches one correctly — the individual tests do not).test_did_integration's allowlist also records error codes that have changed.That is roughly twenty sites across a dozen files, and none of it is a product bug: those documents were only ever built by tests. It belongs in its own change rather than bundled with a fix to shipping code, and I did not want to hold this one behind it. Happy to follow up with it.
Related
makeSourceFilemoved offgeneric_filebecause a described-only file cannot supply thegeneric_file.extthat class requires.🤖 Generated with Claude Code
https://claude.ai/code/session_01YHxsZ56GZsZ3hJ98TJ81t9
Generated by Claude Code