Skip to content

fix(filter,clip): require query-grouped input (FILT3-02, CLIP3-05) - #517

Merged
nh13 merged 1 commit into
mainfrom
nh/fix-filter-clip-require-query-grouped
Jul 13, 2026
Merged

nh13 merged 1 commit into
mainfrom
nh/fix-filter-clip-require-query-grouped

Conversation

@nh13

@nh13 nh13 commented Jul 9, 2026 •

Copy link
Copy Markdown
Member

What & why

fgbio's FilterConsensusReads and ClipBam both call Bams.requireQueryGrouped before processing (FilterConsensusReads.scala:184, ClipBam.scala:115). fgumi did no such check. Both commands are template-based (they group a template's reads by adjacency), so on coordinate-sorted input a template's mates scatter, every read degrades to its own single-read "template", and the pair/template logic is silently wrong with a success exit:

  • filter drops all reads (each lone read fails the both-primaries-pass logic).
  • clip no-ops pair clipping / overlap / mate-info fix.

This is the filter/clip instance of the same missing-input-order-guard class fixed for the consensus callers in #508. Tracker IDs FILT3-02 (S3→S1) and CLIP3-05 (S3→S1).

The fix

Add a query-grouped guard matching fgbio's isQueryGrouped (SO:queryname || GO:query) — deliberately weaker than the consensus template-coordinate guard (check_consensus_sort_order), so a plain queryname sort is accepted:

  • fgumi-sam: new is_query_grouped() predicate; header_as_queryname() + a SamBuilder::set_queryname_sort_order() test helper (the three header_as_* stampers now share a rebuild_header_with_hd helper).
  • commands::common: require_query_grouped() with fgbio-style diagnostics that echo the found SO/GO.
  • Wired into filter::execute and both clip::execute paths (single-threaded + --threads), guarding the input header before clip rewrites SO for the output.

Test fixtures that fed bare-header BAMs were updated to stamp SO:queryname (bare headers are non-query-grouped, which fgbio also rejects — they were pinning invalid input).

Real-tool parity evidence

Adversarial fixture: coordinate-sorted BAM with scattered mates (a template's R1/R2 non-adjacent).

Input fgbio fgumi before fgumi after
coordinate-sorted errors (requireQueryGrouped) exit 0, silently wrong (filter "kept 0, rejected 4"; clip no-op) errors: not queryname sorted or query grouped, found: SO:coordinate GO:none
query-grouped accepts accepts accepts (clip 4→4 byte parity)

Stacking

Stacked on #508 (nh/fix-consensus-sort-order-guards) — filter/clip already edited there, and it introduces the sibling check_consensus_sort_order. Merge order: #505 → #508 → this PR. GitHub auto-retargets to main as the stack merges.

The third W2 finding, MERGE3-01, ships as its own main-based PR (different mechanism, non-overlapping merge.rs, no in-flight merge PR).

Tracker: reports/2026-07-09-fgumi-final-audit-burndown-tracker.md (W2a).

Summary by CodeRabbit

  • New Features

    • Added support for identifying and marking query-grouped SAM/BAM data.
    • Added validation for query-grouped input required by template-based processing.
  • Bug Fixes

    • clip and filter now reject coordinate-sorted or otherwise incompatible BAM files before processing.
    • Improved error messages identify the detected sort and grouping settings.
    • Added coverage for both single-threaded and multithreaded workflows.

@nh13
nh13 temporarily deployed to github-actions July 9, 2026 17:42 — with GitHub Actions Inactive
@coderabbitai

coderabbitai Bot commented Jul 9, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 273a1822-2c75-40e0-877b-c1d340cc039a

📥 Commits

Reviewing files that changed from the base of the PR and between 97b85c9 and c676f1b.

📒 Files selected for processing (7)
  • crates/fgumi-sam/src/builder.rs
  • crates/fgumi-sam/src/lib.rs
  • src/lib/commands/clip.rs
  • src/lib/commands/common.rs
  • src/lib/commands/filter.rs
  • tests/integration/test_clip_command.rs
  • tests/integration/test_filter_command.rs

Walkthrough

SAM header utilities now identify query-grouped inputs and rebuild headers while preserving metadata. Clip and filter reject non-query-grouped BAMs before processing, with builders and integration tests updated for accepted and rejected header orders.

Changes

Query-grouped input enforcement

Layer / File(s) Summary
SAM header query-grouping contract
crates/fgumi-sam/src/builder.rs, crates/fgumi-sam/src/lib.rs
Adds queryname sort-order construction, query-grouped detection, shared header rebuilding, and coverage for SO, GO, and SS behavior.
Shared query-grouped validation
src/lib/commands/common.rs
Adds require_query_grouped, accepting SO:queryname or GO:query and reporting detected header-order fields for rejected inputs.
Clip and filter preflight integration
src/lib/commands/clip.rs, src/lib/commands/filter.rs, crates/fgumi-sam/src/builder.rs
Validates headers before clipping or filtering in both clip execution modes and before filter pipeline setup; existing test inputs receive queryname grouping.
Rejected-input integration coverage
tests/integration/test_clip_command.rs, tests/integration/test_filter_command.rs
Refactors BAM helpers to accept explicit headers and verifies coordinate-sorted inputs fail for clip and filter commands.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant ClipOrFilter
  participant BAMReader
  participant require_query_grouped
  User->>ClipOrFilter: run command with BAM
  ClipOrFilter->>BAMReader: open input
  BAMReader-->>ClipOrFilter: header
  ClipOrFilter->>require_query_grouped: validate SO/GO/SS
  require_query_grouped-->>ClipOrFilter: accept or error
  ClipOrFilter-->>User: process input or reject command
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: requiring query-grouped input for filter and clip.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch nh/fix-filter-clip-require-query-grouped

Comment @coderabbitai help to get the list of available commands.

@codecov

codecov Bot commented Jul 9, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.11650% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 92.60%. Comparing base (97b85c9) to head (c676f1b).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
crates/fgumi-sam/src/lib.rs 94.44% 3 Missing ⚠️
src/lib/commands/common.rs 94.73% 1 Missing ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main     #517   +/-   ##
=======================================
  Coverage   92.60%   92.60%           
=======================================
  Files         165      165           
  Lines       99636    99709   +73     
=======================================
+ Hits        92265    92336   +71     
- Misses       7371     7373    +2     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@nh13
nh13 force-pushed the nh/fix-consensus-sort-order-guards branch from 98be98d to a24cb2a Compare July 9, 2026 20:21
@nh13
nh13 force-pushed the nh/fix-filter-clip-require-query-grouped branch from bd77b55 to 8d07a40 Compare July 9, 2026 20:37
@nh13
nh13 force-pushed the nh/fix-consensus-sort-order-guards branch from a24cb2a to e80c30b Compare July 9, 2026 20:39
@nh13
nh13 force-pushed the nh/fix-filter-clip-require-query-grouped branch from 8d07a40 to 33c1059 Compare July 9, 2026 21:33
@nh13
nh13 temporarily deployed to github-actions July 9, 2026 21:33 — with GitHub Actions Inactive
@nh13
nh13 force-pushed the nh/fix-consensus-sort-order-guards branch from e80c30b to 37e2e83 Compare July 11, 2026 01:06
@nh13
nh13 force-pushed the nh/fix-filter-clip-require-query-grouped branch from 33c1059 to 43fa76c Compare July 11, 2026 01:09
@nh13
nh13 temporarily deployed to github-actions July 11, 2026 01:09 — with GitHub Actions Inactive
@nh13
nh13 force-pushed the nh/fix-consensus-sort-order-guards branch from 37e2e83 to d52374b Compare July 11, 2026 01:11
@nh13
nh13 force-pushed the nh/fix-filter-clip-require-query-grouped branch from 43fa76c to 80744f5 Compare July 11, 2026 01:13
@nh13
nh13 temporarily deployed to github-actions July 11, 2026 01:13 — with GitHub Actions Inactive
@nh13
nh13 force-pushed the nh/fix-consensus-sort-order-guards branch 3 times, most recently from ae3dee2 to 4332216 Compare July 11, 2026 20:36
@nh13
nh13 force-pushed the nh/fix-filter-clip-require-query-grouped branch from 80744f5 to 72072c4 Compare July 11, 2026 22:17
@nh13
nh13 temporarily deployed to github-actions July 11, 2026 22:17 — with GitHub Actions Inactive
Base automatically changed from nh/fix-consensus-sort-order-guards to main July 12, 2026 15:14
fgbio's FilterConsensusReads and ClipBam both call Bams.requireQueryGrouped
before processing; fgumi did no such check. On coordinate-sorted input a
template's mates scatter, every read degrades to its own single-read
"template", and pair/template logic is silently wrong with a success exit
(filter drops all reads; clip no-ops pair clipping).

Add a query-grouped guard matching fgbio's isQueryGrouped
(SO:queryname || GO:query) — weaker than the consensus template-coordinate
guard, so a plain queryname sort is accepted:

- fgumi-sam: is_query_grouped() predicate, header_as_queryname(), and a
  SamBuilder::set_queryname_sort_order() test helper.
- commands::common: require_query_grouped() with fgbio-style diagnostics
  that echo the found SO/GO.
- Wire it into filter::execute and both clip::execute paths, guarding the
  input header before clip rewrites SO for the output.

Real-tool parity (adversarial coordinate-sorted fixture with scattered mates):
  before: fgbio errors; fgumi exits 0 (filter "kept 0, rejected 4"; clip no-op).
  after:  fgumi errors like fgbio ("not queryname sorted or query grouped,
          found: SO:coordinate GO:none"); both accept query-grouped input
          (clip 4->4 byte parity).

Test fixtures that fed bare-header BAMs updated to stamp SO:queryname.

Tracker: reports/2026-07-09-fgumi-final-audit-burndown-tracker.md (W2)
@nh13
nh13 force-pushed the nh/fix-filter-clip-require-query-grouped branch from 72072c4 to c676f1b Compare July 12, 2026 15:28
@nh13
nh13 temporarily deployed to github-actions July 12, 2026 15:28 — with GitHub Actions Inactive
@nh13

nh13 commented Jul 13, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 13, 2026 •

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@nh13

nh13 commented Jul 13, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 13, 2026 •

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@nh13
nh13 merged commit 309f1dc into main Jul 13, 2026
11 checks passed
@nh13
nh13 deleted the nh/fix-filter-clip-require-query-grouped branch July 13, 2026 03:15
@nh13 nh13 mentioned this pull request Jul 13, 2026

This branch was previously deployed

1 inactive deployment
github-actions — c676f1b0 Deployed Jul 12, 2026 by nh13 via coverage #2413
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.

1 participant