Skip to content

fix(merge): track chunk provenance instead of re-deriving group membership from labels - #327

Merged
jayhesselberth merged 1 commit into
mainfrom
fix/323-merge-relabel-provenance
Sep 15, 2026
Merged

jayhesselberth merged 1 commit into
mainfrom
fix/323-merge-relabel-provenance

Conversation

@jayhesselberth

Copy link
Copy Markdown
Member

Summary

  • leech data merge -i A=file1.npz -i B=file2.npz re-derived each group's label set from the original labels values stored in each input file, then matched chunks back into group 1/2 by that value. Two files sharing an internal label (e.g. both prepared with label "Thr" but representing different classes of the actual comparison, like attached ligand) collapsed to the same label_int — silently, with no error, and a log line that still looked correct.
  • _parse_and_validate_inputs (src/leech/commands/merge_split.py) now builds relabel_by_file: dict[Path, tuple[int, str]], keyed by which -i argument supplied each file, instead of re-deriving membership from stored labels values (meta_to_chunk_labels is gone, along with the per-file np.load peek it required).
  • merge_and_split_chunks / merge_and_kfold_split_chunks (src/leech/splitting/splitter.py) gained a relabel_by_file parameter (mutually exclusive with the existing relabel_pairwise) that's applied directly as the label override, bypassing value-matching entirely — including in the legacy in-memory (output_dir=None) path.
  • The value-based relabel_pairwise path is unchanged for process_comparison_spec's TSV workflow, where group membership genuinely is defined by label values drawn from an arbitrary set of files — but it now raises ValueError if the caller's group1/group2 label sets overlap, instead of silently collapsing to one class.

Closes #323

Test plan

  • uv run pytest tests/test_splitter_merge.py -v — 30 passed, including new regression tests reproducing the exact bug (TestMergeSplitCLIProvenance) and the guard-rail coverage (test_relabel_pairwise_overlapping_groups_raises, test_relabel_pairwise_and_relabel_by_file_are_mutually_exclusive)
  • uv run pytest tests/test_comparison_spec.py -v — 7 passed (confirms the untouched value-based TSV path still works)
  • uv run pytest tests/test_mask_seq_side.py -v — 24 passed (exercises other merge_split.py code paths)
  • uv run ruff format --check . / uv run ruff check . on touched files — clean
  • uv run ty check src/leech/ — clean

🤖 Generated with Claude Code

…rship from original labels

`leech data merge -i A=file1.npz -i B=file2.npz` re-derived each group's
label set from the *original* `labels` values stored in each file, then
matched chunks back into group 1/2 by that value. Two files sharing an
internal label (e.g. both prepared with label "Thr" but representing
different classes of the actual comparison) collapsed to the same
label_int with no error.

_parse_and_validate_inputs now builds relabel_by_file, a {path: (label_int,
label_str)} map keyed by which -i argument supplied each file, and
merge_and_split_chunks/merge_and_kfold_split_chunks apply it directly instead
of re-deriving group membership from stored label values. The value-based
relabel_pairwise path (used by the TSV comparison-spec workflow, where group
membership *is* defined by label values) is unchanged, but now raises if the
caller's group1/group2 label sets overlap instead of silently collapsing.

Fixes #323
@jayhesselberth
jayhesselberth merged commit cff6b69 into main Sep 15, 2026
3 checks passed
@jayhesselberth
jayhesselberth deleted the fix/323-merge-relabel-provenance branch September 15, 2026 13:41
@jayhesselberth jayhesselberth mentioned this pull request Sep 15, 2026
5 tasks
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.

bug: data merge pairwise relabeling matches by original labels value, silently collapsing same-body contrasts to one class

1 participant