Skip to content

Add DIAMOND blastp subworkflow for protein homology search against NCBI RefSeq - #50

Open
tracelail wants to merge 67 commits into
nf-core:devfrom
tracelail:unfinished-diamond-blastp
Open

Add DIAMOND blastp subworkflow for protein homology search against NCBI RefSeq#50
tracelail wants to merge 67 commits into
nf-core:devfrom
tracelail:unfinished-diamond-blastp

Conversation

@tracelail

@tracelail tracelail commented Jun 2, 2025

Copy link
Copy Markdown

Protein functional annotation at scale demands efficient sequence alignment against large reference databases. BLAST, the traditional tool for this task, is computationally expensive for large datasets. [DIAMOND](https://github.com/bbuchfink/diamond) (Buchfink et al., [Nature Methods 2021](https://doi.org/10.1038/s41592-021-01101-x)) provides BLAST-compatible sensitivity with significantly higher throughput, up to 10,000× faster than BLAST on large protein databases by using a double-indexed alignment algorithm optimized for modern hardware. Adding DIAMOND blastp to proteinannotator enables users to run protein homology searches against the full NCBI RefSeq protein database as part of their functional annotation workflow, which would be impractical with BLAST at scale.

This PR adds [DIAMOND blastp](https://github.com/bbuchfink/diamond) ([Buchfink et al., Nature Methods 2021](https://doi.org/10.1038/s41592-021-01101-x)) to the pipeline, using the existing nf-core diamond/blastp and [diamond/makedb](https://nf-co.re/modules/diamond_makedb/) modules, plus two new local modules:

New local modules:

  • ncbirefseqdownload : Downloads and concatenates NCBI RefSeq protein FASTAs for a specified release category (e.g. complete, other) into a single compressed reference FASTA for use by diamond/makedb
  • diamondpreparetaxa : Downloads and extracts NCBI taxonomy files (nodes.dmp, names.dmp) required for taxonomic classification in diamond/makedb

New subworkflows:

  • subworkflows/local/diamond : Orchestrates the full DIAMOND pipeline: RefSeq download → taxonomy preparation → DIAMOND_MAKEDBDIAMOND_BLASTP. Supports all seven DIAMOND output formats (blast, xml, txt, daa, sam, tsv, paf) via params.diamond_outfmt and params.diamond_blast_columns
  • subworkflows/local/functional_annotation — Integrates the DIAMOND subworkflow alongside the existing InterProScan and KOfamScan logic. All three tools are independently gated by their own skip flag (params.skip_diamond, params.skip_interproscan, params.skip_kofamscan); FUNCTIONAL_ANNOTATION passes through all seven of DIAMOND's real output channels (diamond_blast, diamond_xml, diamond_txt, diamond_daa, diamond_sam, diamond_tsv, diamond_paf) rather than hardcoding a single outfmt-specific emit

New parameters (added to nextflow_schema.json and nextflow.config):

  • -skip_diamond — Skip the DIAMOND BLASTP taxonomic classification step entirely (default: false)
  • -refseq_release — NCBI RefSeq release category (default: complete)
  • -taxondmp_zip — URL to NCBI taxonomy dump archive
  • -taxonmap — URL to compressed protein accession-to-taxid map
  • -diamond_outfmt — Output format code (default: 6, tabular)
  • -diamond_blast_columns — Optional column list for tabular output

Testing:

All new local modules have nf-test test suites with both live and stub tests:

The diamond subworkflow is tested end-to-end using a miniature mini_prot.accession2taxid.gz taxon map and a small test_refseq.fasta. Tests cover five scenarios:

  • Live run with tabular output (outfmt 6, no columns)
  • Stub: outfmt 6, no columns
  • Stub: outfmt 6, with custom columns
  • Stub: outfmt 0 (pairwise BLAST format)
  • Stub: two-sample input, regression-testing a fixed channel cardinality bug (DIAMOND_MAKEDB's output now correctly broadcasts to every sample via .first(), rather than pairing positionally and silently dropping any sample beyond the first)

The functional_annotation subworkflow is tested with skip_interproscan = true and skip_diamond = false for DIAMOND-focused tests (live and stub), confirming the DIAMOND path runs correctly independently. Pre-existing InterProScan- and KOfamScan-focused tests now set skip_diamond = true, since they were previously running the full DIAMOND pipeline unconditionally despite being unrelated to what they test.

All stub tests are tagged CI for fast pipeline CI runs. Live module tests require -profile docker and are tagged accordingly.

subworkflows/local/functional_annotation — Integrates the DIAMOND subworkflow alongside the existing InterProScan and KOfamScan logic. All three tools are independently gated by their own skip flag. FUNCTIONAL_ANNOTATION passes through all seven of DIAMOND's real output channels; consuming these outputs downstream in proteinannotator.nf (e.g. a comparison/reporting step) is left to a follow-up PR.

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](https://github.com/nf-core/proteinannotator/tree/master/.github/CONTRIBUTING.md)
  • If necessary, also make a PR on the nf-core/proteinannotator branch on the [nf-core/test-datasets](https://github.com/nf-core/test-datasets) repository.
  • Make sure your code lints (nf-core pipelines lint).
  • Ensure the test suite passes (e.g. nf-test test */local --profile=~test,docker for all new local tests).
  • Check for unexpected warnings in debug mode (nf-test test */local --profile=~test,docker,debug).
  • 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).

@nf-core-bot

nf-core-bot commented Jun 2, 2025

Copy link
Copy Markdown
Member

Warning

Newer version of the nf-core template is available.

Your pipeline is using an old version of the nf-core template: 3.3.1.
Please update your pipeline to the latest version.

For more documentation on how to update your pipeline, please see the nf-core documentation and Synchronisation documentation.

@olgabot olgabot mentioned this pull request Jun 24, 2025
11 tasks

@olgabot olgabot 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.

Turns out I had started this review a while ago... But here are a bunch of suggestions that will hopefully deal with the container issues.

Comment thread .vscode/settings.json
Comment thread .nf-test.log Outdated
Comment thread CITATIONS.md Outdated
Comment thread docs/output.md Outdated
Comment thread docs/output.md
Comment thread modules/local/diamondpreparetaxa/environment.yml Outdated
Comment thread modules/local/diamondpreparetaxa/main.nf Outdated
Comment thread modules/local/diamondpreparetaxa/main.nf Outdated
Comment thread modules/local/diamondpreparetaxa/main.nf Outdated
Comment thread modules/local/ncbirefseqdownload/main.nf Outdated
tracelail and others added 5 commits July 28, 2025 12:21
… modules and subworkflows. Added some tests and confirmed updated snapshots.
… merged back in if needed or fixed if requested.

updated docs.md with some breaks in markdown and output examples of PAF.

Fixed some dev merging issues in functional_annotation/meta.yml.
…ond test had a typo of tsv output when it should have been txt. Updated snapshots are also included.
…hannels from diamond subworkflow main and nf-test assertions.
@tracelail
tracelail marked this pull request as ready for review April 9, 2026 14:55
@tracelail tracelail changed the title wrote draft integration of BLAST_MAKEBLASTDB and NCBIREFSEQDOWNLOAD into functional_annotation subworkflow. Integration of BLAST_MAKEBLASTDB and NCBIREFSEQDOWNLOAD into functional_annotation subworkflow. Apr 9, 2026
@tracelail tracelail changed the title Integration of BLAST_MAKEBLASTDB and NCBIREFSEQDOWNLOAD into functional_annotation subworkflow. Add DIAMOND blastp subworkflow for protein homology search against NCBI RefSeq Apr 9, 2026
@tracelail
tracelail requested a review from olgabot April 9, 2026 15:17

@erikrikarddaniel erikrikarddaniel left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Quite some work left.

DIAMOND(
ch_fasta
)
ch_diamond_tsv = DIAMOND.out.tsv

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

diamond_tsv is wired to DIAMOND.out.tsv, which only gets populated for outfmt==102 -- not the pipeline's default outfmt=6 (txt) -- and this emit has no downstream consumer in this PR at all

Failure scenario: Run with the default --diamond_outfmt 6: DIAMOND_BLASTP writes a .txt file, but FUNCTIONAL_ANNOTATION.out.diamond_tsv stays empty -- proven directly by the PR's own committed snapshot (subworkflows/local/functional_annotation/tests/main.nf.test.snap, test 'Diamond execution subworkflow success', diamond_outfmt=6): "diamond_tsv": [] while workflow.success is true.

Checked workflows/proteinannotator.nf: FUNCTIONAL_ANNOTATION.out.diamond_tsv isn't referenced anywhere downstream either, matching this PR's own description ("not consumed downstream... deferred to follow-up PR"). Given that, I'd recommend removing ch_diamond_tsv/the diamond_tsv emit entirely for now rather than fixing its wiring -- it's currently dead code on both ends (never correctly populated under default settings, and never read), so there's nothing to keep. When the follow-up PR actually wires in a comparison module, it can pick the emit that matches whatever --diamond_outfmt it's designed around, deliberately, instead of inheriting this mismatch.


Posted by an automated code review (recall-biased, high effort). Please verify before acting.

{ assert snapshot(
path(workflow.out.interproscan_tsv[0][1]).readLines()[0]
.contains("GI|225038609|EFDID|719595|FULL 079fff43a0270e432d339ea71b6f0acf 350 SFLD SFLDS00057 Glutaminase/Asparaginase 17 347 0.0 T"),
.contains("GI|225038609|EFDID|719595|FULL 079fff43a0270e432d339ea71b6f0acf 350 SFLD SFLDS00057 Glutaminase/Asparaginase 17 347 0.0 T"),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The two pre-existing InterProScan tests lost their snapshot baselines, and the one retained assertion string was silently corrupted from tab-delimited to space-delimited

Confirmed via cat -A against origin/dev: the retained assertion expects space-separated output where the pre-existing baseline (and the tool's actual output format) uses tabs. As written, this assertion no longer checks what it's meant to check.


Posted by an automated code review (recall-biased, high effort). Please verify before acting.

ch_fasta
)
ch_diamond_tsv = DIAMOND.out.tsv
ch_versions = ch_versions.mix(DIAMOND.out.versions.first())

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

.first() on DIAMOND.out.versions (a channel that legitimately carries two version entries -- rsync + wget) silently discards one, non-deterministically

Failure scenario: The standalone DIAMOND subworkflow's own test snapshot shows two versions.yml entries for this exact scenario, but the same run through FUNCTIONAL_ANNOTATION collapses to one -- confirmed by diffing the two committed snapshots. The aggregated versions.yml/MultiQC table will be missing either the rsync or wget version line whenever DIAMOND runs through FUNCTIONAL_ANNOTATION.

Worth being precise about blast radius: this channel only ever feeds the software-versions report, never any data/process-invocation logic, so this doesn't affect actual DIAMOND results -- it's a reproducibility/traceability bug, not a correctness one.

Both NCBIREFSEQDOWNLOAD and DIAMONDPREPARETAXA already have the topic-channel version of their own versions emit commented out in place (// updated versioning method to be implemented, followed by the real tuple(...), emit: versions, topic: versions line). Switching those two on would sidestep this whole .mix()/.first() bookkeeping for these two new modules specifically, without needing the rest of the pipeline to migrate first -- topic channels coexist fine alongside the existing versions.yml-file pattern used elsewhere. Given the PR description notes topic-channel migration is deferred pending an nf-core-wide mandate timeline, this bug is a concrete example of the exact risk that pattern avoids -- worth reconsidering for at least these two new modules, even if the full pipeline migration stays deferred.


Posted by an automated code review (recall-biased, high effort). Please verify before acting.

"versions.yml:md5,f1d8a406d3dcb97a7c15e9c810926de1"
"versions.yml:md5,a74a0c8fcb741e59bc14424f612b8d09"
],
"funfam_domains": [

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Unrelated subworkflow (domain_annotation, not touched by this PR's own stated scope) has a regressed snapshot -- empty arrays plus a duplicate JSON key

Corroborated by a stray committed .nf-test.log in this PR's diff -- looks like an accidental local --update-snapshot run swept this in alongside the intended changes.


Posted by an automated code review (recall-biased, high effort). Please verify before acting.

"""
mkdir -p taxa/
wget -q ${taxondmp_zip}
tar -xzf taxdump.tar.gz -C taxa/

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

tar -xzf taxdump.tar.gz extracts a hardcoded filename, but the actual downloaded file's name depends on whatever --taxondmp_zip URL was given

Failure scenario: Any schema-valid --taxondmp_zip URL with a different basename than taxdump.tar.gz -- the file wget saves will have that different name, and the hardcoded tar -xzf taxdump.tar.gz will fail to find it.


Posted by an automated code review (recall-biased, high effort). Please verify before acting.

@@ -0,0 +1,51 @@
process DIAMONDPREPARETAXA {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

DIAMONDPREPARETAXA hand-rolls wget+tar as a new bespoke local module, duplicating a fetch-and-unpack pattern this same PR's sibling functional_annotation/main.nf:37-41 already solves generically via the vendored ARIA2+UNTAR modules

Failure scenario: Two different, inconsistent 'download a reference URL and unpack it' implementations now coexist one function-call apart in the same subworkflow tree: nf-core-standard ARIA2 (retry-capable) + UNTAR on one side, a bespoke wget -q (no retry) + tar on the other. A future robustness fix (retries, checksum validation) applied to ARIA2 won't benefit this path, and a new contributor has two inconsistent patterns to learn instead of one.

Worth distinguishing from the sibling NCBIREFSEQDOWNLOAD module: that one uses rsync, and there's currently no rsync module in nf-core/modules to install instead, so a local module is more defensible there. This one has no such excuse -- ARIA2+UNTAR are already proven working in this exact PR.


Posted by an automated code review (recall-biased, high effort). Please verify before acting.

@@ -0,0 +1,122 @@
process DIAMOND_BLASTP {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

DIAMOND_BLASTP has no publishDir configured anywhere -- not in the module, not in conf/modules.config, no pipeline-wide fallback either

Checked conf/modules.config, conf/base.config, nextflow.config, and this vendored module itself: none of them publish any of DIAMOND_BLASTP's outputs. Combined with the diamond_tsv issue above, this means running the pipeline today produces no visible DIAMOND result file in the results directory at all, under any --diamond_outfmt setting -- the actual homology-search hits only ever exist transiently in work/. Given this PR's stated purpose is enabling DIAMOND-based homology search "as part of their functional annotation workflow," I'd expect at least the raw hits file to be published even before the comparison-module integration lands in the follow-up PR.


Posted by an automated code review (recall-biased, high effort). Please verify before acting.

}
workflow {
"""
input[0] = [ [id:'test'], file("${moduleTestDir}/test_refseq.fasta", checkIfExists: true)]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

No test anywhere in this PR passes more than one sample through ch_fasta

Checked all six test cases touching the new Diamond code (this file's 4 tests, plus subworkflows/local/functional_annotation/tests/main.nf.test's 2 Diamond-focused tests): every single one uses input[0] = [ [id:'test'], file(...)] -- a single tuple, never a multi-item channel. This isn't "coverage happens to miss the multi-sample case" -- structurally, none of these tests could have caught the ch_diamond_db cardinality issue flagged in subworkflows/local/diamond/main.nf:39, since that failure mode only manifests when ch_fasta has more than one item. Worth adding at least one test case with channel.of([...], [...]) carrying two samples before merge -- that would immediately confirm or rule out the cardinality concern empirically, and closes a real coverage gap either way.


Posted by an automated code review (recall-biased, high effort). Please verify before acting.

when {
process {
"""
input[0] = 'ftp://ftp.ncbi.nih.gov/pub/taxonomy/taxdump.tar.gz'

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Every "live" (non-stub) test that touches DIAMONDPREPARETAXA downloads the full, real NCBI taxonomy dump -- repeated identically across three separate test files

This exact taxondmp_zip = 'ftp://ftp.ncbi.nih.gov/pub/taxonomy/taxdump.tar.gz' (full-size, unminified) appears in this file, subworkflows/local/diamond/tests/main.nf.test, and subworkflows/local/functional_annotation/tests/main.nf.test. Contrast with taxonmap and the FASTA input in the same tests, which were both thoughtfully shrunk to small fixtures (mini_prot.accession2taxid.gz, test_refseq.fasta) -- the same care wasn't applied here. Three separate live CI runs each pulling the full NCBI taxdump is real CI cost and a source of network-flakiness risk that didn't need to exist; a small hand-built nodes.dmp/names.dmp fixture (matching what mini_prot.accession2taxid.gz already required for the taxonmap side) would let these tests run fast and deterministically.


Posted by an automated code review (recall-biased, high effort). Please verify before acting.

Comment thread CHANGELOG.md
- [[PR #13](https://github.com/nf-core/proteinannotator/pull/13)] Add nf-core seqkit/stats module
- [[PR #9](https://github.com/nf-core/proteinannotator/pull/9)] Add [InterProScan](https://interproscan-docs.readthedocs.io/) module
- [#90](https://github.com/nf-core/proteinannotator/pull/90) - Added the option to download and use the latest `metagRoot` HMM library (or use path to an existing one) for domain annotation. (by @angelphanth)
- [#90](https://github.com/nf-core/proteinannotator/pull/90) - Added the option to download and use the latest `metagRoot` HMM library (or use path to an existing one) for domain annotation. (by @angelphanth)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Inconsistent format (sometimes PR sometimes not) and not ordered.

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.

  • duplication

@heuermh

heuermh commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Would you need help resolving conflicts here? It is somewhat difficult to review if conflicts remain.

Then

--skip_diamond parameter deferred to follow-up PR

Does this mean the DIAMOND blastp subworkflow will run by default now?

If so, that could be surprising to existing users. I might think it better to include --skip_diamond in this pull request and set it to true by default.

@tracelail

tracelail commented Aug 14, 2026

Copy link
Copy Markdown
Author

@heuermh

Would you need help resolving conflicts here? It is somewhat difficult to review if conflicts remain.

Then

--skip_diamond parameter deferred to follow-up PR

Does this mean the DIAMOND blastp subworkflow will run by default now?

If so, that could be surprising to existing users. I might think it better to include --skip_diamond in this pull request and set it to true by default.

I can address the conflicts. I should have checked again for conflicts before requesting review. On the the --skip_diamond you're absolutely right and an oversight on my part. I got lost in executing diamond and forgot that it should be implemented in this PR.

@vagkaratzas vagkaratzas 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.

quite a few non nf-core stuff around that need to be fixed..the latest dev should be merged in this branch and conflicts should be resolved.

I was wondring if this should stay under the functional_annotation subworkflow, or become its own derive_taxonomy subworkflow (or something like that) that is currently missing from the pipeline and this seems to fill that gap.

when finalized and before merging, the metro map should be updated accordingly (I can do that)

Comment thread .vscode/settings.json
@@ -1,3 +1,6 @@
{

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.

please gitignore non-standard nf-core template files such as this one

Comment thread docs/output.md

</details>

#### Diamond

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'd argue this is too long for usage.md. I would trim down extensively, or have DIAMOND.md file, and/or link to the external software? What do you think @erikrikarddaniel ? Since you also recently linked some non nf-core md files for extra info

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.

again, non-standard file...this information should be reflected in the updated metro-map instead

Comment thread tests/nextflow.config Outdated
@@ -10,4 +10,34 @@ params {
pipelines_testdata_base_path = 'https://raw.githubusercontent.com/nf-core/test-datasets/refs/heads/proteinannotator'

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.

remove the extra bloat from this file --only keep the few lines that are in the template.

Comment thread .nf-test.log Outdated

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.

.log files should be gitignored

Comment thread CHANGELOG.md
- [[PR #13](https://github.com/nf-core/proteinannotator/pull/13)] Add nf-core seqkit/stats module
- [[PR #9](https://github.com/nf-core/proteinannotator/pull/9)] Add [InterProScan](https://interproscan-docs.readthedocs.io/) module
- [#90](https://github.com/nf-core/proteinannotator/pull/90) - Added the option to download and use the latest `metagRoot` HMM library (or use path to an existing one) for domain annotation. (by @angelphanth)
- [#90](https://github.com/nf-core/proteinannotator/pull/90) - Added the option to download and use the latest `metagRoot` HMM library (or use path to an existing one) for domain annotation. (by @angelphanth)

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.

  • duplication

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.

7 participants