Skip to content

Correct entropy regional medians and singleton summaries - #710

Closed
SuhasSrinivasan wants to merge 3 commits into
nanoporetech:masterfrom
SuhasSrinivasan:codex/publish-entropy-regional-statistics
Closed

Correct entropy regional medians and singleton summaries#710
SuhasSrinivasan wants to merge 3 commits into
nanoporetech:masterfrom
SuhasSrinivasan:codex/publish-entropy-regional-statistics

Conversation

@SuhasSrinivasan

Copy link
Copy Markdown
Contributor

Fixes #682.

Summary

  • Emits a valid regional entropy summary when exactly one window succeeds.
  • Sorts a private copy of multi-window entropy values before median interpolation.
  • Adds exact singleton CLI and exhaustive odd/even permutation regressions while preserving encounter order in the caller.

Severity

Severity: High — scientific and statistical accuracy

Rationale: entropy --regions can exit successfully while omitting a valid singleton region or reporting a plausible but incorrect median for ordinary unsorted genomic-order values. The output itself does not reveal the statistical error.

Root cause

Entropy-local DescriptiveStats::new passed every nonempty measurement slice directly to the shared percentile helper. That helper intentionally requires at least two observations and assumes its input is already sorted. Regional entropy values arrive in genomic encounter order, not numeric order.

Implementation

  • For one measurement, use that value directly as the median.
  • For two or more measurements, copy and sort the values with f32::total_cmp, then call the unchanged linear-interpolation helper.
  • Continue calculating mean, minimum, maximum, read counts, and success/failure counts from the original inputs.

The production change is seven entropy-local lines. Tests-first, production, and expanded CLI/permutation coverage remain separate commits.

Preserved behavior

  • The shared percentile helper and automatic-threshold behavior are unchanged.
  • Mean/min/max, read-count statistics, and successful/failed window counts are unchanged.
  • The caller's genomic-order measurement slice is not mutated.
  • The existing interpolation convention for even sample sizes is retained.

Non-goals

Behavior before and after

Case Before After Expected oracle
One successful window Shared helper rejects one datapoint; region row is omitted Emits one regional row mean/median/min/max equal the lone value; exact read and success/failure counts
Values [0.75, 0.25, 0.50] in genomic order Median 0.25 Median 0.50 Median of value-sorted [0.25, 0.50, 0.75]
Values [0.75, 0.00, 0.25, 0.50] Median 0.125 Median 0.375 Existing interpolation over sorted middle values 0.25 and 0.50
Permutations of the same multiset Can report different medians Report the same median All 6 odd and 24 even permutations agree; caller input remains unmodified

Testing

Test environment

  • Revision tested: 7e5050c13ac13a3c6614f532485c45145f253228
  • Tree tested and worktree state: 556d905849c1a3544440a1f70bd11e04f973a3cb; clean after testing
  • Toolchain: rustc/cargo 1.90.0
  • Platform: macOS 26.6, arm64 Apple Silicon
  • Reference binary: installed modkit 0.6.4 and exact upstream parent 5cecc3fb3a9336068d9e3c68d5c08d678153dd2c
  • External tools: samtools 1.23.1 for the public CLI fixture
  • Dependency resolution identity: ignored Cargo.lock SHA-256 f9d3389f8fc63c9ad653dad3fbf43a1c26cc54008f0a39e06e71ff6455a1e9b5; rust-htslib 0.46.0, hts-sys 2.2.0
Test layer Exact command, fixture, or matrix Result and evidence
Core: parent-red regression Exact parent and installed 0.6.4; replay singleton and odd/even median oracles Singleton unit returns PercentileNotEnoughDatapoints(1) and installed CLI leaves the region file empty; unsorted odd/even inputs report 0.25/0.125 instead of 0.50/0.375
Core: focused regression cargo test -p mod_kit entropy::entropy_mod_tests --lib -- --test-threads=1 6 passed, 0 failed; singleton exact fields plus all 6 odd and 24 even permutations pass without input mutation
Core: affected CLI integration cargo test -p modkit --test test_entropy_region_statistics -- --test-threads=1 1 passed, 0 failed; exact singleton regional row SHA-256 a58b12803513e46fe62df518c33db75fd7471dcb9fc7482ec3a69cf1aaabc9c3
Existing entropy integration cargo test -p modkit --test test_entropy -- --test-threads=1 2 passed, 0 failed
Core: applicable full workspace gate TMPDIR=/private/tmp/modkit-tmp-entropy-regional-statistics cargo test --workspace --all-targets -- --test-threads=1 185 passed, 14 ignored, 0 failed on the exact final head
Core: formatting/diff checks Targeted stable rustfmt --check; git diff --check upstream/master...HEAD Changed patch passes. Whole-workspace stable formatting is not a clean upstream gate because .rustfmt.toml requests nightly-only options and untouched files also differ

Tests not performed

  • No large-data performance, memory, or I/O benchmark was run. The production work is one singleton branch and one short private sort per regional summary, with no performance claim.
  • No change or test of the separate final-bit entropy reduction reproducibility question was made.

Scientific validation

  • Population/eligibility invariant: every region with at least one successful measurement remains eligible; no window population is added or removed.
  • Count/category conservation invariant: singleton and multi-window read counts plus success/failure fields are exact and unchanged.
  • Coordinate/strand/interval invariant: genomic window order and region coordinates are not mutated; only a private value copy is sorted.
  • Determinism invariant: median is invariant across every tested permutation of the same odd/even values.
  • Independent oracle or specialist review: singleton statistics and the two median order statistics are directly enumerable; Bioinformatics and supervisor source reviews approved the frozen branch.

Output and compatibility

  • User-visible change: singleton region rows are emitted, and previously incorrect unsorted medians are corrected.
  • Expected output differences: only omitted singleton summaries and incorrect median fields change.
  • Byte-identical controls: existing entropy integration remains green; non-median statistics are asserted unchanged.
  • CLI/API/schema compatibility: no option, Rust API, column, or schema change.
  • Partial-output or failure semantics: a valid singleton is no longer downgraded to a failed regional statistic.

Reviewer guide

  1. Review the two parent assumptions documented in issue entropy --regions omits singleton summaries and computes medians from genomic rather than value order #682 and the seven-line DescriptiveStats::new change.
  2. Confirm sorting occurs on a private copy and uses f32::total_cmp.
  3. Review the singleton CLI row and exhaustive odd/even permutation test.
  4. Rerun cargo test -p mod_kit entropy::entropy_mod_tests --lib and cargo test -p modkit --test test_entropy_region_statistics.
  5. Confirm the shared percentile helper and all non-median statistics remain unchanged.

Checklist

  • The issue contains reproducible observed and expected behavior.
  • The change is limited to the linked issue's approved scope.
  • The regressions are demonstrably red on the exact parent/released binary.
  • All tests actually performed are listed above with their results.
  • Unrun or inapplicable tests are disclosed.
  • Scientific counts/statistics and output compatibility are explicitly checked.
  • Formatting and diff-hygiene checks pass, or unrelated findings are documented.
  • No generated data, private sample identifiers, or unrelated changes are included.

@SuhasSrinivasan

Copy link
Copy Markdown
Contributor Author

This completed regional-statistics fix is now consolidated into #712 with the related entropy state and motif/window ownership corrections. The exact combined head was independently reviewed, formatted, and passed the full serial workspace gate (212 passed, 14 ignored, 0 failed). Closing this duplicate review surface so entropy can be reviewed in one PR.

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.

entropy --regions omits singleton summaries and computes medians from genomic rather than value order

1 participant