Handle CRAM references, empty thresholds, and zero-target extract inputs - #713
Open
SuhasSrinivasan wants to merge 10 commits into
Open
Conversation
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.
Review status: Author-reviewed and ready for ONT review.
Fixes #690.
Fixes #691.
Fixes #692.
Summary
--no-filteringtruly bypass sampling.Severity
Severity: High — format-dependent scientific completeness and automatic-threshold correctness
Rationale: #690 can make equivalent CRAM input exit successfully with zero extract rows while BAM emits complete output. #691 can silently turn an undefined automatic threshold into threshold zero, making automatic mode scientifically equivalent to no filtering. #692 is Medium in isolation because it fails explicitly, but it makes valid all-unmapped records unusable solely because an index is present.
Root cause
Reference paths were present at command boundaries but dropped when internal serial/indexed readers, sampling schedules, and unmapped fallbacks created new CRAM readers. Legacy threshold APIs had no reference-aware entry point.
The legacy threshold helper accepted an empty probability map, while modern
QualHistpaths inferred estimability from parsed-record count rather than actual canonical or modified probability observations.Finally, generic mapped-coordinate feeders required at least one reference target. Extract invoked those strict constructors before its existing unmapped pass, so an indexed file with zero
@SQtargets failed instead of representing an already-finished mapped phase.Implementation
The ten commits are grouped for review:
2ad0883,ac08413,456d543,b836f1b,87645350d828f1,ed9a6a2,06cf545,b63f53a0703550Public/internal compatibility wrappers preserve existing callers that have no reference. CRAM detection uses the opened file format rather than filename extension. Reference-independent all-unmapped CRAM remains supported without forcing a FASTA.
Preserved behavior
--no-filteringmodes remain valid and do not require an automatic population.Non-goals
Behavior before and after
extract fullextract calls --filter-threshold 0--no-filteringshould be at least 1 contigTesting
Test environment
87645355bdf76111381bb0bbee9f3c89b7864996af6960103ccf263651384e5c231e9758a1138583; clean after testing5cecc3fb3a9336068d9e3c68d5c08d678153dd2cCargo.lockSHA-2569ddcdd1f09bad24c0ecbdb730abcb31bcf5861c6f38e3289d36eae47d50bc1f5, usingrust-htslib0.46.0 andhts-sys2.2.0; no lockfile or dependency pin enters this patch336479a1351d5594dd46295d65e6e5894620acdeb7208ca9d5973b2a16fe2b0a); Summary reports successful zero-read resultshould be at least 1 contigcargo test -p modkit --test test_cram_reference_consumers --test test_extract_cram_reference --test test_empty_qual_hist_thresholds --test test_empty_threshold_sampling --test test_extract_zero_reference_targets -- --nocapture --test-threads=1cargo test -p modkit --test test_entropy -- --test-threads=1cargo test -p mod_kit empty --lib -- --test-threads=1plus focused duplex compatibility testcall_and_adjust_mods_match_bam_and_cramrepeated 20 times with per-test emptyREF_PATH/REF_CACHE0.5compares all 10 normalized BAM/CRAM MM/ML records; separate automatic CRAM run asserts 10 records plussampling 100%andestimated pass thresholdlog evidence[0.0, 0.5292969, 0.0, 0.0]; restored setter fails on the deliberately nonexistent supplied reference as expectedTMPDIR=/private/tmp/modkit-full-cram-8764535 cargo test --offline --locked --workspace --all-targets --no-fail-fast -- --test-threads=1rustfmt --check;git diff --check upstream/master...HEAD; ancestry/name-status auditTests not performed
Scientific validation
Output and compatibility
call-modsandadjust-modsgain/accept--reference/--reffor CRAM; existing internal no-reference wrappers and legacy duplex API remain available; no output schema changes.Reviewer guide
util.rs,reads_sampler, andthresholds.rsfor reference-aware compatibility wrappers and propagation.sample_probs::QualHistfor the probability-observation predicate and indexed-unmapped reference setter.extractreader construction andZeroReferenceTargetMode/feeder constructors for strict versus opt-in behavior.sample_probs/reads_sampler, while Prevent interval endpoint overflow and remove stray adjust-mods stderr output #706 touches the same interval feeder arithmetic.Checklist