Skip to content

feat: add simplex-metrics command for simplex sequencing QC - #195

Merged
nh13 merged 1 commit into
mainfrom
nh/simplex-metrics
Mar 30, 2026
Merged

nh13 merged 1 commit into
mainfrom
nh/simplex-metrics

Conversation

@nh13

@nh13 nh13 commented Mar 27, 2026 •

Copy link
Copy Markdown
Member

Summary

Implements simplex-metrics (closes #192) — a new command for collecting QC metrics on simplex sequencing data, mirroring the existing duplex-metrics command but adapted for simplex-only experiments.

  • Family size distributions: CS (coordinate+strand) and SS (single-strand by UMI) family sizes with per-size fractions and cumulative fractions
  • Yield curves: metrics at 20 downsampling levels (5%–100%) showing SS families, mean family size, singleton fraction, and consensus-eligible families
  • UMI observation frequencies: raw/unique/error counts per UMI sequence
  • PDF plots: 7 ggplot2 visualizations (family sizes, cumulative distributions, yield curve, mean family size, singleton fraction, UMI representation, read distribution)
  • Shared refactoring: extracted ~800 lines of common infrastructure from duplex-metrics into shared_metrics.rs and shared.rs for reuse by both commands

Test plan

  • 1946 existing tests pass (no regressions in duplex-metrics)
  • 7 unit tests for simplex metric types and collectors
  • 7 unit tests for the simplex-metrics command logic
  • 5 integration tests (output files, family sizes, yield metrics, UMI metrics, min-reads parameter)
  • cargo ci-fmt and cargo ci-lint pass
  • Review output metrics and PDF plots for correctness
  • Verify yield curves and family sizes match expectations for known simplex datasets

@nh13
nh13 temporarily deployed to github-actions March 27, 2026 17:46 — with GitHub Actions Inactive
@codecov

codecov Bot commented Mar 27, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 90.58642% with 61 lines in your changes missing coverage. Please review.
✅ Project coverage is 87.90%. Comparing base (7442efd) to head (bbf7b06).
⚠️ Report is 4 commits behind head on main.

Files with missing lines Patch % Lines
src/commands/shared_metrics.rs 87.59% 32 Missing ⚠️
src/commands/simplex_metrics.rs 94.84% 18 Missing ⚠️
src/commands/duplex_metrics.rs 73.17% 11 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #195      +/-   ##
==========================================
+ Coverage   86.12%   87.90%   +1.77%     
==========================================
  Files         110      113       +3     
  Lines       51974    52593     +619     
==========================================
+ Hits        44765    46231    +1466     
+ Misses       7209     6362     -847     

☔ View full report in Codecov by Sentry.
📢 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 marked this pull request as ready for review March 27, 2026 17:59
@coderabbitai

coderabbitai Bot commented Mar 27, 2026 •

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: eb79ee7a-2c19-4db9-a9ef-cdb485c5ae6f

📥 Commits

Reviewing files that changed from the base of the PR and between 4adb79a and bbf7b06.

📒 Files selected for processing (15)
  • crates/fgumi-metrics/src/duplex.rs
  • crates/fgumi-metrics/src/lib.rs
  • crates/fgumi-metrics/src/shared.rs
  • crates/fgumi-metrics/src/simplex.rs
  • resources/CollectDuplexSeqMetrics.R
  • resources/CollectSimplexSeqMetrics.R
  • src/commands/duplex_metrics.rs
  • src/commands/mod.rs
  • src/commands/shared_metrics.rs
  • src/commands/simplex_metrics.rs
  • src/lib/metrics/mod.rs
  • src/main.rs
  • tests/integration/main.rs
  • tests/integration/test_duplex_metrics_command.rs
  • tests/integration/test_simplex_metrics_command.rs
✅ Files skipped from review due to trivial changes (3)
  • tests/integration/main.rs
  • src/commands/mod.rs
  • tests/integration/test_simplex_metrics_command.rs
🚧 Files skipped from review as they are similar to previous changes (4)
  • tests/integration/test_duplex_metrics_command.rs
  • crates/fgumi-metrics/src/lib.rs
  • src/lib/metrics/mod.rs
  • crates/fgumi-metrics/src/duplex.rs

📝 Walkthrough

Walkthrough

Adds a new simplex-metrics CLI command and associated simplex metrics module, plus a shared metrics module that centralizes UMI tracking (UmiMetric, UmiCountTracker) and metric generation. Introduces src/commands/shared_metrics.rs with BAM/interval processing, hashing/downsampling, and R execution helpers; refactors duplex-metrics to use those shared utilities. Adds R plotting scripts and unit/integration tests for simplex and updated duplex behavior.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the primary change—adding a new simplex-metrics command for simplex sequencing QC.
Description check ✅ Passed The description is well-structured, covers the feature scope (family sizes, yield curves, UMI metrics, PDF plots, shared refactoring), test plan, and issue reference.
Linked Issues check ✅ Passed The PR fully addresses issue #192: implements simplex-metrics command, family size distributions (CS/SS), yield-curve metrics across 20 downsampling fractions, UMI observation frequencies, PDF visualizations, and refactors shared infrastructure for code reuse.
Out of Scope Changes check ✅ Passed All changes align with the PR scope: simplex-metrics implementation, shared refactoring from duplex-metrics, duplex-metrics updates to use shared code, metric types (UmiMetric, SimplexFamilySizeMetric, SimplexYieldMetric), R script for visualization, and tests. No unrelated changes detected.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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/simplex-metrics

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@nh13

nh13 commented Mar 28, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Mar 28, 2026

Copy link
Copy Markdown
✅ Actions performed

Review triggered.

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 force-pushed the nh/simplex-metrics branch from 6772f11 to 4adb79a Compare March 29, 2026 07:16
@nh13
nh13 temporarily deployed to github-actions March 29, 2026 07:16 — with GitHub Actions Inactive
@nh13

nh13 commented Mar 29, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Mar 29, 2026

Copy link
Copy Markdown
✅ Actions performed

Review triggered.

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
tests/integration/test_simplex_metrics_command.rs (2)

199-204: Direct index access could panic if yield metrics count changes.

metrics[19] assumes exactly 20 entries. If DOWNSAMPLING_FRACTIONS changes, this panics without a helpful message.

🔧 Suggested improvement
-    let full = &metrics[19];
+    let full = metrics.last().expect("Should have at least one yield metric");
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/integration/test_simplex_metrics_command.rs` around lines 199 - 204,
The test uses a hard-coded index metrics[19] which will panic if the number of
entries or DOWNSAMPLING_FRACTIONS changes; update the assertion to locate the
100% entry robustly by searching metrics for an item with fraction approximately
1.0 (e.g., metrics.iter().find(|m| (m.fraction - 1.0).abs() < EPS)) or use
metrics.last() with a clear unwrap message, then assert on ss_families and
cs_families using that found entry (reference symbols: metrics, fraction,
ss_families, cs_families in test_simplex_metrics_command.rs).

283-290: Same direct index pattern here.

Use .last() or .find() for robustness, consistent with the suggested pattern above.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/integration/test_simplex_metrics_command.rs` around lines 283 - 290,
The test uses brittle direct indexing (&default_metrics[19],
&strict_metrics[19]) to get the "full" metric; replace these with calls that
pick the last element for robustness, e.g. use
default_metrics.last().expect("expected default_metrics non-empty") and
strict_metrics.last().expect("expected strict_metrics non-empty") (or
.last().unwrap()) and update default_full and strict_full to bind those results
instead of indexing so the assertions that follow remain valid.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@resources/CollectSimplexSeqMetrics.R`:
- Line 46: The assignment to sampleInfo uses paste(args[5:length(args)]) which
returns a vector when multiple args are present; change the call in the
sampleInfo assignment to paste(args[5:length(args)], collapse=" ") so all
elements from args[5] onward are concatenated into a single string for the title
(refer to the sampleInfo variable and the paste(...) call).

In `@src/commands/shared_metrics.rs`:
- Around line 141-150: compute_hash_fraction can panic when `hash as i32` equals
i32::MIN because calling `.abs()` on i32::MIN panics in debug; update
compute_hash_fraction to detect i32::MIN before calling .abs(): cast the hash to
i32 into `hash_i32`, if `hash_i32 == i32::MIN` compute the positive value as
2147483648 (e.g. (i32::MAX as i64 + 1) as f64) otherwise use `hash_i32.abs()`
safely (promoting to i64 before abs to avoid overflow), then divide that f64
numerator by `i32::MAX as f64` to preserve the original normalization behavior.

---

Nitpick comments:
In `@tests/integration/test_simplex_metrics_command.rs`:
- Around line 199-204: The test uses a hard-coded index metrics[19] which will
panic if the number of entries or DOWNSAMPLING_FRACTIONS changes; update the
assertion to locate the 100% entry robustly by searching metrics for an item
with fraction approximately 1.0 (e.g., metrics.iter().find(|m| (m.fraction -
1.0).abs() < EPS)) or use metrics.last() with a clear unwrap message, then
assert on ss_families and cs_families using that found entry (reference symbols:
metrics, fraction, ss_families, cs_families in test_simplex_metrics_command.rs).
- Around line 283-290: The test uses brittle direct indexing
(&default_metrics[19], &strict_metrics[19]) to get the "full" metric; replace
these with calls that pick the last element for robustness, e.g. use
default_metrics.last().expect("expected default_metrics non-empty") and
strict_metrics.last().expect("expected strict_metrics non-empty") (or
.last().unwrap()) and update default_full and strict_full to bind those results
instead of indexing so the assertions that follow remain valid.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 5880082b-e429-474d-9dc1-e15023b5df8b

📥 Commits

Reviewing files that changed from the base of the PR and between bed8549 and 4adb79a.

📒 Files selected for processing (14)
  • crates/fgumi-metrics/src/duplex.rs
  • crates/fgumi-metrics/src/lib.rs
  • crates/fgumi-metrics/src/shared.rs
  • crates/fgumi-metrics/src/simplex.rs
  • resources/CollectSimplexSeqMetrics.R
  • src/commands/duplex_metrics.rs
  • src/commands/mod.rs
  • src/commands/shared_metrics.rs
  • src/commands/simplex_metrics.rs
  • src/lib/metrics/mod.rs
  • src/main.rs
  • tests/integration/main.rs
  • tests/integration/test_duplex_metrics_command.rs
  • tests/integration/test_simplex_metrics_command.rs

Comment thread resources/CollectSimplexSeqMetrics.R Outdated
Comment thread src/commands/shared_metrics.rs
…cing QC

Add a new `simplex-metrics` command that collects comprehensive QC metrics
for simplex sequencing experiments, mirroring `duplex-metrics` but adapted
for simplex-only data (no DS/duplex columns).

Outputs:
- Family size distributions (CS and SS families)
- Yield curves at 20 downsampling levels (5%-100%)
- UMI observation frequencies
- Optional PDF plots via embedded R script (7 ggplot2 visualizations)

Also refactors ~800 lines of shared infrastructure out of `duplex-metrics`
into `shared_metrics.rs` and `shared.rs` for reuse by both commands.

Closes #192
@nh13
nh13 force-pushed the nh/simplex-metrics branch from 4adb79a to bbf7b06 Compare March 30, 2026 06:27
@nh13
nh13 temporarily deployed to github-actions March 30, 2026 06:27 — with GitHub Actions Inactive
@nh13

nh13 commented Mar 30, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Mar 30, 2026

Copy link
Copy Markdown
✅ Actions performed

Review triggered.

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 Mar 30, 2026

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Mar 30, 2026

Copy link
Copy Markdown
✅ Actions performed

Review triggered.

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 91e5af6 into main Mar 30, 2026
7 checks passed
@nh13
nh13 deleted the nh/simplex-metrics branch March 30, 2026 09:00
@nh13 nh13 mentioned this pull request Mar 30, 2026

This branch was previously deployed

1 inactive deployment
github-actions — bbf7b068 Deployed Mar 30, 2026 by nh13 via coverage #767
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.

simplex-metrics: collect QC metrics for simplex sequencing data

1 participant