Skip to content

feat(dada): add --failed-uniques diagnostic (issue #60)#62

Merged
cjfields merged 1 commit into
mainfrom
feat/failed-uniques-issue60
Jun 22, 2026
Merged

feat(dada): add --failed-uniques diagnostic (issue #60)#62
cjfields merged 1 commit into
mainfrom
feat/failed-uniques-issue60

Conversation

@cjfields

Copy link
Copy Markdown
Member

Closes #60.

What

Adds --failed-uniques <FILE> to dada, dada-pseudo, and dada-pooled. It emits the unique sequences that failed to denoise (final p-value < omega_c, map == null — R's $map == NA) as a tidy long-format TSV:

sequence	sample	reads
TACGAAGG…AACA	soil_A	7
TACGGAGG…AATC	soil_A	3

One row per failed unique per sample it appears in, with the reads it cost. This answers "what failed to denoise and how many reads did it cost?" without hand-joining the dada map to the derep uniques. Motivated by benjjneb/dada2#1899.

Semantics follow the subcommand

Subcommand "Failed" decided reads is
dada, dada-pseudo per sample (map == null; for pseudo, in the round-2 pass) the unique's in-sample abundance
dada-pooled globally (result.map == null on the merged unique table) the failed merged unique's read count in that sample (one row per sample it appears in)

Rows are sorted by sample / descending reads / sequence, so output is deterministic regardless of concurrent denoising order.

Note on the issue's caveat

The issue flagged that a pooled per-sample map null could mean either a denoising failure or a cluster with zero reads in that sample. That second case is unreachable: a unique present in a sample always carries ≥1 read into its cluster, so a per-sample map == null always means a genuine denoising failure. The TSV reports only real failures.

Changes

  • new module src/failed_uniques.rs (Row + write_tsv, deterministic sort)
  • denoise_and_serialize returns (json, Vec<Row>) gated by a collect_failed bool
  • collectors wired into single/multi dada, both dada-pseudo round-2 closures, and the dada-pooled output loop
  • integration test dada_failed_uniques_matches_map_nulls (TSV row count ≡ JSON map null count)
  • docs/diagnostics.md: new --failed-uniques section, cross-linked to kdist-calibrate --from-dada

Testing

  • full suite (60 unit + 13 integration) and clippy pass
  • verified end-to-end on all four modes; single-sample row count (60) matches the JSON map null count exactly

🤖 Generated with Claude Code

Emit the unique sequences that failed to denoise (final p-value < omega_c,
`map == null`) as a tidy long-format TSV (`sequence<TAB>sample<TAB>reads`,
one row per failed unique per sample), so users can answer "what failed to
denoise and how many reads did it cost?" without hand-joining the dada `map`
to the derep uniques. Motivated by benjjneb/dada2#1899.

Available on `dada`, `dada-pseudo`, and `dada-pooled`, with semantics that
follow the subcommand: `dada`/`dada-pseudo` report per-sample failures
(`map == null`, decided in pseudo's round-2 pass); `dada-pooled` reports
global failures (`result.map == null` on the merged unique table), expanded
to one row per sample the failed merged unique appears in.

The pooled per-sample-`map`-null ambiguity noted in the issue is unreachable:
a unique present in a sample always carries >=1 read into its cluster, so a
per-sample `map == null` always means a genuine denoising failure.

- new module src/failed_uniques.rs (Row + write_tsv, deterministic sort)
- denoise_and_serialize returns (json, Vec<Row>) gated by collect_failed
- integration test: dada_failed_uniques_matches_map_nulls
- docs/diagnostics.md: new --failed-uniques section

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@cjfields cjfields merged commit 18e7f16 into main Jun 22, 2026
7 checks passed
cjfields added a commit that referenced this pull request Jul 6, 2026
…tal WFA backend (issue #63)

Brings in the WFA feature-gating (a70de7a) and its documentation (25a1723).
The issue #60 diagnostic (3ac37f3) was already merged via PR #62.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.

Diagnostic: identify unique sequences that fail to denoise (map == null)

1 participant