Skip to content

Add taxonomy summary table with per-ASV barrnap/decontam/filter annotations - #1063

Merged
erikrikarddaniel merged 14 commits into
nf-core:devfrom
erikrikarddaniel:summary-table-taxonomy
Sep 24, 2026
Merged

erikrikarddaniel merged 14 commits into
nf-core:devfrom
erikrikarddaniel:summary-table-taxonomy

Conversation

@erikrikarddaniel

Copy link
Copy Markdown
Member

PR checklist

  • This comment contains a description of changes (with reason).
  • If you've fixed a bug or added code that should be tested, add tests!
  • If you've added a new tool - have you followed the pipeline conventions in the contribution docs
  • If necessary, also make a PR on the nf-core/ampliseq branch on the nf-core/test-datasets repository.
  • Make sure your code lints (nf-core pipelines lint).
  • Ensure the test suite passes (nextflow run . -profile test,docker --outdir <OUTDIR>).
  • Check for unexpected warnings in debug mode (nextflow run . -profile debug,test,docker --outdir <OUTDIR>).
  • Usage Documentation in docs/usage.md is updated.
  • Output Documentation in docs/output.md is updated.
  • CHANGELOG.md is updated.
  • README.md is updated (including new tool citations and authors/contributors).

Description

Closes the last piece of issue #1033: a per-classifier taxonomy summary table, joined with per-ASV
annotations from barrnap, decontam, and the optional post-processing filters.

summary_tables/ampliseq.taxonomy.<classifier>.<database>.tsv.gz (+ Parquet)

One file per classifier/database already carried in ch_tax_tsv (Kraken2 excluded -- its rank
vocabulary and output shape are too different to normalize). A slim, consistent-schema reformat of
that classifier's own native taxonomy table: asv_id, kingdom..species, confidence.
QIIME2's k__/p__-prefixed Taxon string and phylogenetic placement's unranked, semicolon-joined
string are both parsed into the same seven rank columns (best-effort for the latter). sequence is
dropped (recoverable via asv_id) and, for DADA2, the per-rank *_confidence columns are dropped
too (DADA2-specific detail, not comparable across classifiers) -- both remain available in full in
the native per-classifier files elsewhere in the output directory.

Joined onto every one of these files, whenever the corresponding step ran:

  • barrnap_domain: the rRNA domain barrnap called with the lowest e-value for this ASV, blank if
    none was significant.
  • decontam_contaminant / decontam_not_contaminant: decontam's own contaminant call.
  • passed_ssu_filter, passed_length_filter_asv, passed_codon_filter,
    passed_length_filter_itsx: whether this ASV survived each individual optional filter.
  • ampliseq_accept: whether this ASV survived the whole standard filtering chain (decontam through
    the ITSx-region length filter) end to end -- a convenience alongside the individual columns above,
    not instead of them, so the pipeline's own filtering choices can be recombined differently.

New module BUILD_ASV_ANNOTATIONS builds these by diffing each filter's ASV table immediately
before/after it runs (none of FILTER_SSU/FILTER_LEN/FILTER_CODONS emit a per-ASV pass/fail
column natively) -- purely additive plumbing, no change to the filter chain's own logic, order, or
gating. Tidyverse throughout (per-type long-format stacking + pivot_wider, split by value type
before stacking so Parquet gets real BOOLEAN/UTF8 columns rather than everything coerced through
one generically-typed column).

Also fixes a gap in the existing ampliseq.counts.tsv.gz/.parquet Parquet conversion (#1052):
DUCKDB_TABLE2PARQUET used to run immediately after SUMMARY_TABLE_COUNTS, before this PR's
taxonomy tables existed yet, so it silently never converted them. Moved to run once after every
summary table has been mixed into the shared channel.

Two real bugs found by review + testing, both fixed

  • DADA2_ADDSPECIES always renames its own species call to Species_exact, only re-adding a native
    Species column when assignTaxonomy's own taxlevels included one -- databases that rely on
    addSpecies alone for species-level calls (e.g. RDP) would have silently had no species column at
    all. Fixed by coalescing species/species_exact (prefer the native assignTaxonomy call, fall
    back to addSpecies), verified against real RDP output.
  • SUMMARY_TABLE_TAXONOMY needed .combine() against the annotations table -- without it, Nextflow
    silently dropped every ch_tax_tsv entry past the first, since a queue channel that only ever
    emits once isn't auto-broadcast against a multi-item channel the way a true value channel is.

Testing

  • tests/default.nf.test, tests/multidb.nf.test, tests/pplace.nf.test, tests/sintax.nf.test,
    tests/vsearch_lca.nf.test all run for real (docker), with manual content spot-checks beyond the
    automated assertions -- e.g. confirming QIIME2's k__/p__ string and PPLACE's unranked string
    both parse into the right rank columns, and that the RDP species fix actually populates real data.
  • The remaining profiles that run a non-Kraken2 classifier (fasta, glosed, multi, savont,
    savont_independent, single, pacbio_its, pplace_sheet, qiimecustom, reftaxcustom,
    failed, iontorrent) have their .nf.test.snap snapshots updated by hand rather than a full
    local run, based on tracing the exact classifier/database name each profile produces through the
    channel-building code (including the user database key used by every *_ref_tax_custom path).
    Flagging this explicitly in case CI surfaces a misprediction there.
  • nf-core pipelines lint and prek run -a both clean, at the same baseline as dev (the
    pre-existing nextflow config -o json/SAVONT_ASV issue and a couple of unrelated files_unchanged
    checks aren't introduced by this PR).

erikrikarddaniel and others added 5 commits September 17, 2026 20:17
…ations

Adds summary_tables/ampliseq.taxonomy.<classifier>.<database>.tsv.gz (+ Parquet),
a slim, consistent-schema reformat of every classifier/database in ch_tax_tsv
(Kraken2 excluded), joined with per-ASV annotations: barrnap's winning rRNA
domain, decontam's contaminant call, individual filter pass/fail booleans, and
ampliseq_accept (whether an ASV survived the whole standard filtering chain
end to end). Individual filter columns are kept alongside ampliseq_accept so
the pipeline's own filtering choices can be recombined differently if wanted.

Fixes an existing gap where DUCKDB_TABLE2PARQUET only converted the counts
table to Parquet, since it ran before any other summary table existed.

Generated by Claude
sintax.nf.test/vsearch_lca.nf.test snapshots regenerated via real nf-test
runs (verified real content: correct fungal ITS taxonomy, sh column
preserved, barrnap_domain=euk, and this run exercised passed_length_filter_itsx
for the first time).

The other 11 affected profiles (every profile that runs a non-Kraken2
classifier, except default/multidb/pplace already covered in the previous
commit) are hand-edited rather than run locally: for each, traced the exact
classifier/database name(s) through the actual channel-building code
(including the "user" database key used for every *_ref_tax_custom path,
and PPLACE's two distinct database tags for --pplace_tree vs --pplace_sheet)
and added the same two new snapshot entries (BUILD_ASV_ANNOTATIONS/
SUMMARY_TABLE_TAXONOMY versions, new summary_tables/ file paths) already
confirmed correct by the real runs. Safe because nf-test's snapshot().match()
is structural JSON equality, not byte-for-byte text comparison. Not locally
re-verified -- CI will confirm or correct any misprediction.

Also fixes a real YAML bug in summary_table_taxonomy/meta.yml: an unquoted
"[classifier: ...]" in a description string was parsed by the YAML/prettier
tooling as an attempted flow-sequence, caught by prek only after this change
(meta.yml isn't read by Nextflow at runtime, so no test run had exercised it).

Generated by Claude
Same lessons applied from review feedback on nf-core#1062: fill in the CHANGELOG
entry's real PR number (was #NNNN), and trim the summary-tables section of
docs/output.md, which had the same wall-of-text verbosity. Also fixes a real
doc gap caught while trimming: the taxonomy table's .parquet sibling was
never actually documented, only the counts table's was.

Generated by Claude
…y CI

The prior push's CI run (7 failed shards) surfaced a genuine bug, not just
snapshot mispredictions: BUILD_ASV_ANNOTATIONS crashed whenever barrnap's
summary.tsv had zero data rows -- a real, common case for ITS-only amplicon
runs (barrnap targets rRNA, so zero hits across every ASV is expected, not
a freak edge case), caused by a dplyr rowwise()/mutate()/c_across() corner
case on empty input. Fixed by guarding nrow(evals) > 0 before that block.

Also corrected 6 snapshots the earlier hand-edit pass missed, all verified
by real local nf-test runs rather than hand-edited again:
- doubleprimers/multiregion/novaseq: missing BUILD_ASV_ANNOTATIONS' versions
  entry -- it runs unconditionally regardless of classifiers, so these
  weren't actually "unaffected" as assumed.
- fasta/savont/savont_independent: missing the bare "summary_tables"
  directory entry (never existed before in these -- PR A scoped
  SUMMARY_TABLE_COUNTS to asv_calling == "dada2" only, and fasta uses
  --input_fasta with no count table), plus a DUCKDB_TABLE2PARQUET versions
  entry that only running for real (not hand-editing again) caught.

Generated by Claude
BUILD_ASV_ANNOTATIONS and SUMMARY_TABLE_TAXONOMY version entries were
missing from default.nf.test and glosed.nf.test's snapshots -- stale
from before this branch was rebased onto current dev. No functional
change; verified all 21 test files pass locally.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
ampliseq lists Added entries by ascending PR number, so nf-core#1063 belongs
above nf-core#1065. The rebase onto dev resolved the conflict the other way
round.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PYuhWC4HE6BP63fnsVQZHN

@d4straub d4straub left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Didnt check the R script details, just in-person-code-browsing. Looks good so far I think. Just a few comments

Comment thread workflows/ampliseq.nf
Comment thread conf/modules.config Outdated
Comment thread docs/output.md Outdated
Comment thread docs/output.md Outdated
erikrikarddaniel and others added 7 commits September 23, 2026 13:30
# Conflicts:
#	CHANGELOG.md
#	tests/default.nf.test.snap
#	tests/multidb.nf.test.snap
#	tests/savont.nf.test.snap
#	tests/sintax.nf.test.snap
#	tests/vsearch_lca.nf.test.snap
The consolidated DADA2 table (--consolidate_taxonomies, added in nf-core#1062) reaches
SUMMARY_TABLE_TAXONOMY through ch_tax_tsv like any other classifier/database
entry, so it needs no wiring of its own. Its "database" column names the
database that won each ASV, which reads as the table's own database once the
file name already carries that, so it is renamed on the way into the summary
table.

tests/multidb_mostspecific.nf.test asserts the consolidated summary table
exists and carries the column. The three multidb snapshots pick up the summary
tables the test profiles now produce.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PYuhWC4HE6BP63fnsVQZHN
- conf/modules.config: null-safe saveAs filter, as suggested in review.
- docs/output.md: the Parquet note moves out of the collapsed "Output files"
  block, where it was easy to miss.
- docs/output.md: state that the barrnap/decontam/filter annotations are joined
  onto the taxonomy tables only, and how to combine them with the counts table.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PYuhWC4HE6BP63fnsVQZHN
Both R scripts carried multi-paragraph comments that traced the mechanism the
code already shows, then justified the justification. Each is cut to the one
fact a reader needs at that line: why booleans stack in their own table, why
filter membership is diffed rather than read, why the whole chain is diffed
again for ampliseq_accept, why Species and Species_exact are folded into one
column.

These sit in script: blocks, so they are copied verbatim into the .command.sh
a user inspects at runtime.

The meta.yml descriptions lose the channel-wiring rationale, which belongs in
workflows/ampliseq.nf rather than in a module's interface documentation.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PYuhWC4HE6BP63fnsVQZHN
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PYuhWC4HE6BP63fnsVQZHN
The entry named the schema, the Parquet copies and the parameter that turns
them off, all of which docs/output.md covers. It now says what the files are
and links there.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PYuhWC4HE6BP63fnsVQZHN
@github-actions

github-actions Bot commented Sep 23, 2026 •

Copy link
Copy Markdown

nf-core pipelines lint overall result: Passed ✅ ⚠️

Posted for pipeline commit ecd0115

+| ✅ 319 tests passed       |+
#| ❔   8 tests were ignored |#
!| ❗ 114 tests had warnings |!
Details

❗ Test warnings:

❔ Tests ignored:

✅ Tests passed:

  • files_exist - File found: .gitattributes
  • files_exist - File found: .gitignore
  • files_exist - File found: .nf-core.yml
  • files_exist - File found: .prettierignore
  • files_exist - File found: .prettierrc.yml
  • files_exist - File found: CHANGELOG.md
  • files_exist - File found: CITATIONS.md
  • files_exist - File found: CODE_OF_CONDUCT.md
  • files_exist - File found: LICENSE or LICENSE.md or LICENCE or LICENCE.md
  • files_exist - File found: nextflow_schema.json
  • files_exist - File found: nextflow.config
  • files_exist - File found: README.md
  • files_exist - File found: .github/.dockstore.yml
  • files_exist - File found: .github/ISSUE_TEMPLATE/bug_report.yml
  • files_exist - File found: .github/ISSUE_TEMPLATE/config.yml
  • files_exist - File found: .github/ISSUE_TEMPLATE/feature_request.yml
  • files_exist - File found: .github/PULL_REQUEST_TEMPLATE.md
  • files_exist - File found: .github/workflows/branch.yml
  • files_exist - File found: .github/workflows/nf-test.yml
  • files_exist - File found: .github/actions/get-shards/action.yml
  • files_exist - File found: .github/actions/nf-test/action.yml
  • files_exist - File found: .github/workflows/pr-comment.yml
  • files_exist - File found: .github/workflows/linting.yml
  • files_exist - File found: assets/email_template.html
  • files_exist - File found: assets/email_template.txt
  • files_exist - File found: assets/sendmail_template.txt
  • files_exist - File found: assets/nf-core-ampliseq_logo_light.png
  • files_exist - File found: conf/modules.config
  • files_exist - File found: conf/test.config
  • files_exist - File found: conf/test_full.config
  • files_exist - File found: docs/CONTRIBUTING.md
  • files_exist - File found: docs/images/nf-core-ampliseq_logo_light.png
  • files_exist - File found: docs/images/nf-core-ampliseq_logo_dark.png
  • files_exist - File found: docs/output.md
  • files_exist - File found: docs/README.md
  • files_exist - File found: docs/README.md
  • files_exist - File found: docs/usage.md
  • files_exist - File found: nf-test.config
  • files_exist - File found: tests/default.nf.test
  • files_exist - File found: main.nf
  • files_exist - File found: assets/multiqc_config.yml
  • files_exist - File found: conf/base.config
  • files_exist - File found: conf/igenomes_ignored.config
  • files_exist - File found: .github/workflows/awstest.yml
  • files_exist - File found: .github/workflows/awsfulltest.yml
  • files_exist - File found: modules.json
  • files_exist - File found: ro-crate-metadata.json
  • files_exist - File not found check: .github/ISSUE_TEMPLATE/bug_report.md
  • files_exist - File not found check: .github/ISSUE_TEMPLATE/feature_request.md
  • files_exist - File not found check: .github/workflows/push_dockerhub.yml
  • files_exist - File not found check: .markdownlint.yml
  • files_exist - File not found check: .nf-core.yaml
  • files_exist - File not found check: .yamllint.yml
  • files_exist - File not found check: bin/markdown_to_html.r
  • files_exist - File not found check: conf/aws.config
  • files_exist - File not found check: docs/images/nf-core-ampliseq_logo.png
  • files_exist - File not found check: lib/Checks.groovy
  • files_exist - File not found check: lib/Completion.groovy
  • files_exist - File not found check: lib/NfcoreTemplate.groovy
  • files_exist - File not found check: lib/Utils.groovy
  • files_exist - File not found check: lib/Workflow.groovy
  • files_exist - File not found check: lib/WorkflowMain.groovy
  • files_exist - File not found check: lib/WorkflowAmpliseq.groovy
  • files_exist - File not found check: parameters.settings.json
  • files_exist - File not found check: pipeline_template.yml
  • files_exist - File not found check: Singularity
  • files_exist - File not found check: lib/nfcore_external_java_deps.jar
  • files_exist - File not found check: .travis.yml
  • nf_test_content - 'tests/glosed.nf.test' contains outdir parameter
  • nf_test_content - 'tests/glosed.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/glosed.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/taxonomy_hash.nf.test' contains outdir parameter
  • nf_test_content - 'tests/taxonomy_hash.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/multiregion.nf.test' contains outdir parameter
  • nf_test_content - 'tests/multiregion.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/multiregion.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/failed.nf.test' contains outdir parameter
  • nf_test_content - 'tests/failed.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/failed.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/multi.nf.test' contains outdir parameter
  • nf_test_content - 'tests/multi.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/multi.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/reftaxcustom.nf.test' contains outdir parameter
  • nf_test_content - 'tests/reftaxcustom.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/reftaxcustom.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/multidb_mixedranks.nf.test' contains outdir parameter
  • nf_test_content - 'tests/multidb_mixedranks.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/multidb_mixedranks.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/doubleprimers.nf.test' contains outdir parameter
  • nf_test_content - 'tests/doubleprimers.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/doubleprimers.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/single.nf.test' contains outdir parameter
  • nf_test_content - 'tests/single.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/single.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/novaseq.nf.test' contains outdir parameter
  • nf_test_content - 'tests/novaseq.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/novaseq.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/multidb_mostspecific.nf.test' contains outdir parameter
  • nf_test_content - 'tests/multidb_mostspecific.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/multidb_mostspecific.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/vsearch_lca.nf.test' contains outdir parameter
  • nf_test_content - 'tests/vsearch_lca.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/sintax.nf.test' contains outdir parameter
  • nf_test_content - 'tests/sintax.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/sintax.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/fasta.nf.test' contains outdir parameter
  • nf_test_content - 'tests/fasta.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/fasta.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/qiimecustom.nf.test' contains outdir parameter
  • nf_test_content - 'tests/qiimecustom.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/qiimecustom.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/pplace_sheet.nf.test' contains outdir parameter
  • nf_test_content - 'tests/pplace_sheet.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/pplace_sheet.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/savont_independent.nf.test' contains outdir parameter
  • nf_test_content - 'tests/savont_independent.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/savont_independent.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/pacbio_its.nf.test' contains outdir parameter
  • nf_test_content - 'tests/pacbio_its.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/pacbio_its.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/pplace.nf.test' contains outdir parameter
  • nf_test_content - 'tests/pplace.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/pplace.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/multidb.nf.test' contains outdir parameter
  • nf_test_content - 'tests/multidb.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/multidb.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/default.nf.test' contains outdir parameter
  • nf_test_content - 'tests/default.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/default.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/multidb_score.nf.test' contains outdir parameter
  • nf_test_content - 'tests/multidb_score.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/multidb_score.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/savont.nf.test' contains outdir parameter
  • nf_test_content - 'tests/savont.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/savont.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/iontorrent.nf.test' contains outdir parameter
  • nf_test_content - 'tests/iontorrent.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/iontorrent.nf.test' snapshots a 'versions.yml' file
  • nf_test_content - 'tests/nextflow.config' contains modules_testdata_base_path
  • nf_test_content - 'tests/nextflow.config' contains pipelines_testdata_base_path
  • nf_test_content - 'nf-test.config' sets a testsDir
  • nf_test_content - 'nf-test.config' sets a workDir
  • nf_test_content - 'nf-test.config' sets a configFile
  • files_unchanged - .prettierrc.yml matches the template
  • files_unchanged - CODE_OF_CONDUCT.md matches the template
  • files_unchanged - LICENSE matches the template
  • files_unchanged - .github/.dockstore.yml matches the template
  • files_unchanged - .github/ISSUE_TEMPLATE/bug_report.yml matches the template
  • files_unchanged - .github/ISSUE_TEMPLATE/config.yml matches the template
  • files_unchanged - .github/ISSUE_TEMPLATE/feature_request.yml matches the template
  • files_unchanged - .github/PULL_REQUEST_TEMPLATE.md matches the template
  • files_unchanged - .github/workflows/branch.yml matches the template
  • files_unchanged - .github/workflows/pr-comment.yml matches the template
  • files_unchanged - .github/workflows/linting.yml matches the template
  • files_unchanged - assets/email_template.html matches the template
  • files_unchanged - assets/email_template.txt matches the template
  • files_unchanged - assets/sendmail_template.txt matches the template
  • files_unchanged - docs/README.md matches the template
  • actions_nf_test - '.github/workflows/nf-test.yml' is triggered on expected events
  • actions_nf_test - '.github/workflows/nf-test.yml' checks minimum NF version
  • actions_awstest - '.github/workflows/awstest.yml' is triggered correctly
  • actions_awsfulltest - .github/workflows/awsfulltest.yml is triggered correctly
  • actions_awsfulltest - .github/workflows/awsfulltest.yml does not use -profile test
  • readme - README Nextflow minimum version badge matched config. Badge: 26.04.0, Config: 26.04.0
  • readme - README nf-core template version badge found.
  • readme - README Zenodo placeholder was replaced with DOI.
  • pipeline_todos - No TODO strings found
  • pipeline_if_empty_null - No ifEmpty(null) strings found
  • plugin_includes - No wrong validation plugin imports have been found
  • pipeline_name_conventions - Name adheres to nf-core convention
  • template_strings - Did not find any Jinja template strings (0 files)
  • schema_lint - Schema lint passed
  • schema_lint - Schema title + description lint passed
  • schema_lint - Input mimetype lint passed: 'text/tsv'
  • system_exit - No System.exit calls found
  • actions_schema_validation - Workflow validation passed: pr-comment.yml
  • actions_schema_validation - Workflow validation passed: branch.yml
  • actions_schema_validation - Workflow validation passed: nf-test.yml
  • actions_schema_validation - Workflow validation passed: awsfulltest.yml
  • actions_schema_validation - Workflow validation passed: download_pipeline.yml
  • actions_schema_validation - Workflow validation passed: awstest.yml
  • actions_schema_validation - Workflow validation passed: clean-up.yml
  • actions_schema_validation - Workflow validation passed: template-version-comment.yml
  • actions_schema_validation - Workflow validation passed: fix_linting.yml
  • actions_schema_validation - Workflow validation passed: linting.yml
  • actions_schema_validation - Workflow validation passed: release-announcements.yml
  • merge_markers - No merge markers found in pipeline files
  • modules_json - Only installed modules found in modules.json
  • multiqc_config - assets/multiqc_config.yml found and not ignored.
  • multiqc_config - assets/multiqc_config.yml contains report_section_order
  • multiqc_config - assets/multiqc_config.yml contains export_plots
  • multiqc_config - assets/multiqc_config.yml contains report_comment
  • multiqc_config - assets/multiqc_config.yml follows the ordering scheme of the minimally required plugins.
  • multiqc_config - assets/multiqc_config.yml contains a matching 'report_comment'.
  • multiqc_config - assets/multiqc_config.yml contains 'export_plots: true'.
  • modules_structure - modules directory structure is correct 'modules/nf-core/TOOL/SUBTOOL'
  • base_config - conf/base.config found and not ignored.
  • modules_config - conf/modules.config found and not ignored.
  • modules_config - DOWNLOAD_REFERENCE found in conf/modules.config and Nextflow scripts.
  • modules_config - RENAME_RAW_DATA_FILES found in conf/modules.config and Nextflow scripts.
  • modules_config - FASTQC found in conf/modules.config and Nextflow scripts.
  • modules_config - PORECHOP_ABI found in conf/modules.config and Nextflow scripts.
  • modules_config - CHOPPER found in conf/modules.config and Nextflow scripts.
  • modules_config - CUTADAPT_BASIC found in conf/modules.config and Nextflow scripts.
  • modules_config - CUTADAPT_READTHROUGH found in conf/modules.config and Nextflow scripts.
  • modules_config - CUTADAPT_DOUBLEPRIMER found in conf/modules.config and Nextflow scripts.
  • modules_config - SAVONT_ASV found in conf/modules.config and Nextflow scripts.
  • modules_config - SAVONT_EXPORT found in conf/modules.config and Nextflow scripts.
  • modules_config - CUTADAPT_TAXONOMY found in conf/modules.config and Nextflow scripts.
  • modules_config - CUTADAPT_SUMMARY_MERGE found in conf/modules.config and Nextflow scripts.
  • modules_config - DADA2_QUALITY1 found in conf/modules.config and Nextflow scripts.
  • modules_config - TRUNCLEN found in conf/modules.config and Nextflow scripts.
  • modules_config - DADA2_FILTNTRIM found in conf/modules.config and Nextflow scripts.
  • modules_config - DADA2_QUALITY2 found in conf/modules.config and Nextflow scripts.
  • modules_config - DADA2_ERR found in conf/modules.config and Nextflow scripts.
  • modules_config - DADA2_DENOISING found in conf/modules.config and Nextflow scripts.
  • modules_config - DADA2_RMCHIMERA found in conf/modules.config and Nextflow scripts.
  • modules_config - DADA2_STATS found in conf/modules.config and Nextflow scripts.
  • modules_config - DADA2_MERGE found in conf/modules.config and Nextflow scripts.
  • modules_config - SUMMARY_TABLE_COUNTS found in conf/modules.config and Nextflow scripts.
  • modules_config - SUMMARY_TABLE_TAXONOMY found in conf/modules.config and Nextflow scripts.
  • modules_config - DUCKDB_TABLE2PARQUET found in conf/modules.config and Nextflow scripts.
  • modules_config - DADA2_SPLITREGIONS found in conf/modules.config and Nextflow scripts.
  • modules_config - SIDLE_DBFILT found in conf/modules.config and Nextflow scripts.
  • modules_config - SIDLE_DBEXTRACT found in conf/modules.config and Nextflow scripts.
  • modules_config - SIDLE_TRIM found in conf/modules.config and Nextflow scripts.
  • modules_config - SIDLE_ALIGN found in conf/modules.config and Nextflow scripts.
  • modules_config - SIDLE_DBRECON found in conf/modules.config and Nextflow scripts.
  • modules_config - SIDLE_TABLERECON found in conf/modules.config and Nextflow scripts.
  • modules_config - SIDLE_TAXRECON found in conf/modules.config and Nextflow scripts.
  • modules_config - SIDLE_FILTTAX found in conf/modules.config and Nextflow scripts.
  • modules_config - SIDLE_SEQRECON found in conf/modules.config and Nextflow scripts.
  • modules_config - SIDLE_TREERECON found in conf/modules.config and Nextflow scripts.
  • modules_config - DECONTAM found in conf/modules.config and Nextflow scripts.
  • modules_config - BARRNAP found in conf/modules.config and Nextflow scripts.
  • modules_config - BARRNAPSUMMARY found in conf/modules.config and Nextflow scripts.
  • modules_config - FILTER_SSU found in conf/modules.config and Nextflow scripts.
  • modules_config - FILTER_LEN_ASV found in conf/modules.config and Nextflow scripts.
  • modules_config - FILTER_CODONS found in conf/modules.config and Nextflow scripts.
  • modules_config - MERGE_STATS_CUTADAPT found in conf/modules.config and Nextflow scripts.
  • modules_config - ITSX_CUTASV found in conf/modules.config and Nextflow scripts.
  • modules_config - ITSXRUST_CUTASV found in conf/modules.config and Nextflow scripts.
  • modules_config - FILTER_LEN_ITSX found in conf/modules.config and Nextflow scripts.
  • modules_config - FORMAT_TAXONOMY found in conf/modules.config and Nextflow scripts.
  • modules_config - DADA2_TAXONOMY found in conf/modules.config and Nextflow scripts.
  • modules_config - CONSOLIDATE_DADA2_TAXONOMY found in conf/modules.config and Nextflow scripts.
  • modules_config - DADA2_ADDSPECIES found in conf/modules.config and Nextflow scripts.
  • modules_config - FORMAT_TAXONOMY_SINTAX found in conf/modules.config and Nextflow scripts.
  • modules_config - VSEARCH_SINTAX found in conf/modules.config and Nextflow scripts.
  • modules_config - FORMAT_TAXRESULTS_SINTAX found in conf/modules.config and Nextflow scripts.
  • modules_config - KRAKEN2_KRAKEN2 found in conf/modules.config and Nextflow scripts.
  • modules_config - FORMAT_TAXRESULTS_KRAKEN2 found in conf/modules.config and Nextflow scripts.
  • modules_config - VSEARCH_USEARCHGLOBAL found in conf/modules.config and Nextflow scripts.
  • modules_config - VSEARCH_USEARCHGLOBAL_LCA found in conf/modules.config and Nextflow scripts.
  • modules_config - FORMAT_TAXONOMY_VSEARCH_LCA found in conf/modules.config and Nextflow scripts.
  • modules_config - FORMAT_TAXRESULTS_VSEARCH_LCA found in conf/modules.config and Nextflow scripts.
  • modules_config - VSEARCH_CLUSTER found in conf/modules.config and Nextflow scripts.
  • modules_config - FILTER_CLUSTERS found in conf/modules.config and Nextflow scripts.
  • modules_config - ASSIGNSH found in conf/modules.config and Nextflow scripts.
  • modules_config - FORMAT_TAXONOMY_QIIME found in conf/modules.config and Nextflow scripts.
  • modules_config - QIIME2_EXTRACT found in conf/modules.config and Nextflow scripts.
  • modules_config - HMMER_HMMRANK found in conf/modules.config and Nextflow scripts.
  • modules_config - HMMER_HMMBUILD found in conf/modules.config and Nextflow scripts.
  • modules_config - HMMER_UNALIGNREF found in conf/modules.config and Nextflow scripts.
  • modules_config - HMMER_HMMALIGNREF found in conf/modules.config and Nextflow scripts.
  • modules_config - HMMER_HMMALIGNQUERY found in conf/modules.config and Nextflow scripts.
  • modules_config - HMMER_MASK found in conf/modules.config and Nextflow scripts.
  • modules_config - HMMER_MASKQUERY found in conf/modules.config and Nextflow scripts.
  • modules_config - HMMER_MASKREF found in conf/modules.config and Nextflow scripts.
  • modules_config - HMMER_AFAFORMATQUERY found in conf/modules.config and Nextflow scripts.
  • modules_config - HMMER_AFAFORMATREF found in conf/modules.config and Nextflow scripts.
  • modules_config - MAFFT found in conf/modules.config and Nextflow scripts.
  • modules_config - CLUSTALO_ALIGN found in conf/modules.config and Nextflow scripts.
  • modules_config - EPANG_PLACE found in conf/modules.config and Nextflow scripts.
  • modules_config - GAPPA_GRAFT found in conf/modules.config and Nextflow scripts.
  • modules_config - GAPPA_ASSIGN found in conf/modules.config and Nextflow scripts.
  • modules_config - GAPPA_HEATTREE found in conf/modules.config and Nextflow scripts.
  • modules_config - QIIME2_INASV found in conf/modules.config and Nextflow scripts.
  • modules_config - PPLACEFORMATTAX found in conf/modules.config and Nextflow scripts.
  • modules_config - QIIME2_INASV_BPAVG found in conf/modules.config and Nextflow scripts.
  • modules_config - QIIME2_TABLEFILTERTAXA found in conf/modules.config and Nextflow scripts.
  • modules_config - FILTER_STATS found in conf/modules.config and Nextflow scripts.
  • modules_config - QIIME2_BARPLOT found in conf/modules.config and Nextflow scripts.
  • modules_config - QIIME2_BPAVG found in conf/modules.config and Nextflow scripts.
  • modules_config - QIIME2_EXPORT_ABSOLUTE found in conf/modules.config and Nextflow scripts.
  • modules_config - QIIME2_EXPORT_RELASV found in conf/modules.config and Nextflow scripts.
  • modules_config - QIIME2_TREE found in conf/modules.config and Nextflow scripts.
  • modules_config - QIIME2_FILTERSAMPLES_ANCOM found in conf/modules.config and Nextflow scripts.
  • modules_config - QIIME2_ALPHARAREFACTION found in conf/modules.config and Nextflow scripts.
  • modules_config - QIIME2_DIVERSITY_CORE found in conf/modules.config and Nextflow scripts.
  • modules_config - QIIME2_DIVERSITY_ALPHA found in conf/modules.config and Nextflow scripts.
  • modules_config - QIIME2_DIVERSITY_ADONIS found in conf/modules.config and Nextflow scripts.
  • modules_config - QIIME2_ANCOM_TAX found in conf/modules.config and Nextflow scripts.
  • modules_config - QIIME2_ANCOMBC_TAX found in conf/modules.config and Nextflow scripts.
  • modules_config - ANCOMBC_FORMULA_TAX found in conf/modules.config and Nextflow scripts.
  • modules_config - QIIME2_ANCOMBC2_TAX found in conf/modules.config and Nextflow scripts.
  • modules_config - ANCOMBC2_FORMULA_TAX found in conf/modules.config and Nextflow scripts.
  • modules_config - PICRUST found in conf/modules.config and Nextflow scripts.
  • modules_config - SBDIEXPORT found in conf/modules.config and Nextflow scripts.
  • modules_config - SBDIEXPORTREANNOTATE found in conf/modules.config and Nextflow scripts.
  • modules_config - PHYLOSEQ found in conf/modules.config and Nextflow scripts.
  • modules_config - TREESUMMARIZEDEXPERIMENT found in conf/modules.config and Nextflow scripts.
  • modules_config - VSEARCH_USEARCHGLOBAL_BM found in conf/modules.config and Nextflow scripts.
  • modules_config - COMPARE_SEQUENCES found in conf/modules.config and Nextflow scripts.
  • modules_config - COMPARE_PERFORMANCE found in conf/modules.config and Nextflow scripts.
  • modules_config - COMPARE_PROFILE found in conf/modules.config and Nextflow scripts.
  • modules_config - MULTIQC found in conf/modules.config and Nextflow scripts.
  • modules_config - SUMMARY_REPORT found in conf/modules.config and Nextflow scripts.
  • nfcore_yml - Repository type in .nf-core.yml is valid: pipeline
  • nfcore_yml - nf-core version in .nf-core.yml is set to the latest version: 4.1.0
  • rocrate_readme_sync - RO-Crate descriptions are in sync with README.md.
  • container_configs - conf/containers_conda_lock_files_amd64.config is up to date
  • container_configs - conf/containers_conda_lock_files_arm64.config is up to date
  • container_configs - conf/containers_docker_amd64.config is up to date
  • container_configs - conf/containers_docker_arm64.config is up to date
  • container_configs - conf/containers_singularity_https_amd64.config is up to date
  • container_configs - conf/containers_singularity_https_arm64.config is up to date
  • container_configs - conf/containers_singularity_oras_amd64.config is up to date
  • container_configs - conf/containers_singularity_oras_arm64.config is up to date

Run details

  • nf-core/tools version 4.1.0
  • Run at 2026-09-24 14:12:40

@github-actions

github-actions Bot commented Sep 23, 2026 •

Copy link
Copy Markdown

❌ nf-test failed with latest Nextflow version

Note

Tests with Nextflow's latest version failed but it will not cause a CI workflow failure.
Please check if the failure is expected with newer (edge-)releases of Nextflow or if it needs fixing.

  • ❌ docker | latest-everything | Shard 2/20

See the full run for details.

@erikrikarddaniel
erikrikarddaniel marked this pull request as ready for review September 24, 2026 06:29

@d4straub d4straub left a comment •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Looks almost good to me. Two nitpicks:

  • the fruitless execution of BUILD_ASV_ANNOTATIONS (details below)
  • now that we have those summery_tables folder, maybe we should also store "overall_summary.tsv" there (and rename it to maybe something like read_counts_passed.tsv)?

Comment thread workflows/ampliseq.nf
// MODULE: Per-ASV annotations (barrnap domain call, decontam contaminant call, per-filter
// pass/fail, and the whole-chain "ampliseq_accept") for the taxonomy summary tables below
//
BUILD_ASV_ANNOTATIONS (

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I saw in the .snap files that three tests execute BUILD_ASV_ANNOTATIONS but not SUMMARY_TABLE_TAXONOMY and produce no additional output. Additional module execution without benefit seems pointless. Maybe that could be avoided?

The three tests in question (with the settings that I suspect causing that):

  • doubleprimers (skip_dada_taxonomy = true & kraken2_ref_taxonomy = "greengenes")
  • multiregion (skip_dada_taxonomy = true & sidle_ref_taxonomy = "greengenes88")
  • novaseq (skip_taxonomy = true)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Good catch, and you identified the right three.
BUILD_ASV_ANNOTATIONS is called unconditionally, but the only thing that reads its output is SUMMARY_TABLE_TAXONOMY, which consumes ch_tax_tsv with Kraken2 filtered out.
In all three of those profiles that filtered channel is empty -- Kraken2 only in doubleprimers, SIDLE never enters ch_tax_tsv in multiregion, and novaseq skips taxonomy altogether -- so the annotations get built and then dropped.

I would rather not gate it on the parameters, since ch_tax_tsv is filled from six separate places under six different conditions and a parameter expression would have to restate all of them, which is the maintenance trap you pointed at in the other thread.
Gating on the channel itself keeps the two in step:

ch_summary_tax = ch_tax_tsv.filter { meta, _tsv -> meta.classifier != "KRAKEN2" }

ch_annot_barrnap = ch_summary_tax
    .map { _meta, _tsv -> true }
    .first()
    .combine( ch_barrnapsummary.ifEmpty( [] ) )
    .map { _gate, summary -> summary }

The gated channel replaces the module's first input and the other twelve stay as they are, so the module itself does not change.
I checked the operator behaviour on its own before wiring it in: an empty taxonomy channel leaves the process unexecuted, and several taxonomy tables still run it exactly once.

I will push this and confirm the three snapshots lose the process without anything else moving.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Done in ecd0115.

BUILD_ASV_ANNOTATIONS now takes its first input through a gate derived from the channel SUMMARY_TABLE_TAXONOMY consumes, so it runs only when there is a taxonomy table to join the annotations onto.
The module itself is unchanged, and SUMMARY_TABLE_TAXONOMY reuses the same filtered channel rather than filtering a second time.

All three profiles you named now lose the module's entry from the versions file and nothing else moves in their snapshots:

  • doubleprimers passed
  • multiregion passed
  • novaseq passed

fasta was run as a control, since it does write a summary table, and its snapshot is byte-identical.

SUMMARY_TABLE_TAXONOMY is the only consumer of BUILD_ASV_ANNOTATIONS, and it
takes ch_tax_tsv with Kraken2 filtered out. Where that filtered channel is
empty the combine yields nothing, so no summary table is written and the
annotations table is built for nobody. Three profiles are in that position:
doubleprimers classifies with Kraken2 alone, multiregion goes through SIDLE,
which never enters ch_tax_tsv, and novaseq skips taxonomy altogether.

The gate is the filtered channel itself rather than a parameter expression.
ch_tax_tsv is filled from six places under six different conditions, and a
parameter expression would have to restate all of them and then stay in step
with them. Taking the first emission of the channel the module's output is
joined onto cannot drift the same way.

The three snapshots lose the module's entry from the versions file and nothing
else. Profiles that do write summary tables are unchanged.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PYuhWC4HE6BP63fnsVQZHN

@d4straub d4straub left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM!

@erikrikarddaniel
erikrikarddaniel merged commit 8d4f0a1 into nf-core:dev Sep 24, 2026
87 of 90 checks passed
@erikrikarddaniel
erikrikarddaniel deleted the summary-table-taxonomy branch September 24, 2026 17:15
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.

2 participants