Skip to content

Add virusrecom module for viral recombination detection#11658

Open
haggaikelisha-ai wants to merge 12 commits into
nf-core:masterfrom
haggaikelisha-ai:add-virusrecom-module
Open

Add virusrecom module for viral recombination detection#11658
haggaikelisha-ai wants to merge 12 commits into
nf-core:masterfrom
haggaikelisha-ai:add-virusrecom-module

Conversation

@haggaikelisha-ai
Copy link
Copy Markdown

New module: virusrecom

Adding virusrecom — an information-theory-based method for
recombination detection of viral lineages using weighted
information content (WIC).

PR checklist

  • This comment contains a description of changes (with reason)
  • If you've added a new tool - have you followed the module conventions
  • Add a resource label
  • Use BioConda and BioContainers if possible to fulfil software requirements

@haggaikelisha-ai
Copy link
Copy Markdown
Author

@nf-core-bot fix linting

Copy link
Copy Markdown
Contributor

@Joon-Klaps Joon-Klaps left a comment

Choose a reason for hiding this comment

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

Very Nice contribution.

I believe this module is going to be a bit more difficult (still totally feasible) to add, especially for a first module.

Let me know what you think, open to discussion.

If you do decide to continue, make sure all possible input combinations are tested & that we update the meta.yml file

tag "modules_nfcore"
tag "virusrecom"

test("virusrecom - fasta - stub") {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Don't forget to make an actuall test once the testdata is merged in.

Would also be better if the stub used these files as well instead of fasta & fasta.fai

Suggested change
test("virusrecom - fasta - stub") {
test("sarscov2 - alignment [fasta] mapping [tsv] - stub") {

then {
assert process.success
assertAll(
{ assert snapshot(process.out).match() }
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
{ assert snapshot(process.out).match() }
{ assert snapshot(sanitizeOutput(process.out)).match() }

sanitizeOutput() makes the snapshot easier to read.

Comment thread modules/nf-core/virusrecom/main.nf Outdated
@@ -0,0 +1,38 @@
process VIRUSRECOM {
tag "$meta.id"
label 'process_single'
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
label 'process_single'
label 'process_low'

We can specify the number of threads to use but we would restrict it to only a single thread? From their docs the default is 4. I'm not familar with the tool, but if it takes a long time, we might want to update to even process_medium

Comment thread modules/nf-core/virusrecom/main.nf Outdated

output:
tuple val(meta), path("${meta.id}/"), emit: results
tuple val("${task.process}"), val('virusrecom'), eval("virusrecom -h 2>&1 | grep 'Version:' | sed 's/.*Version: //' | sed 's/ (.*//'" ), topic: versions, emit: versions_virusrecom
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
tuple val("${task.process}"), val('virusrecom'), eval("virusrecom -h 2>&1 | grep 'Version:' | sed 's/.*Version: //' | sed 's/ (.*//'" ), topic: versions, emit: versions_virusrecom
tuple val("${task.process}"), val('virusrecom'), eval("virusrecom -h 2>&1 | sed -n 's/.*Version: \([^ ]*\).*/\1/p'"), topic: versions, emit: versions_virusrecom

It's shorter

Comment thread modules/nf-core/virusrecom/main.nf Outdated
def prefix = task.ext.prefix ?: "${meta.id}"
"""
virusrecom \\
-a ${alignment} \\
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looking at the docs, we can also pass an unaligned file and have it aligned with mafft or another tool as well as passa a iwic input.

If we were to follow the nf-core rules, we should also support this.

I believe the best approach to be is,

input:
tuple val(meta), path(fasta), path(mapping), path(iwic)
val(is_aligned)
val(alignment_tool)

script:
def args          = task.ext.args ?: ''
def prefix        = task.ext.prefix ?: "${meta.id}"
def use_iwic      = iwic as boolean  // path(iwic) will be [] when absent

def input_command = use_iwic    ? "-iwic ${iwic}"
                  : is_aligned  ? "-a ${fasta}"
                  :               "-ua ${fasta}"

def map_command   = use_iwic ? "" : "-map ${mapping}"
def at_command    = (!use_iwic && !is_aligned && alignment_tool) ? "-at ${alignment_tool}" : ""

if (!use_iwic && !is_aligned && !alignment_tool) {
    error "alignment_tool must be specified when input is unaligned (no iwic provided)"
}

"""
virusrecom \\
    ${input_command} \\
    ${map_command} \\
    ${at_command} \\
    -o ${prefix} \\
    -t ${task.cpus} \\
    ${args}
"""

Comment thread modules/nf-core/virusrecom/main.nf
Comment thread modules/nf-core/virusrecom/meta.yml
@haggaikelisha-ai
Copy link
Copy Markdown
Author

haggaikelisha-ai commented May 18, 2026 via email

@haggaikelisha-ai
Copy link
Copy Markdown
Author

haggaikelisha-ai commented May 18, 2026 via email

@Joon-Klaps
Copy link
Copy Markdown
Contributor

Joon-Klaps commented May 19, 2026

There are still quite a few questions unaswered:

  • Include more tests (non-stub tests)
    • input is aligned
    • input is unaligned
    • input is iwic
  • query name, is it a mandatory input variable? If so, we should also add it as an input
  • The label process_single is used but the tool can be multithreaded, so this should become process_low I believe.

@haggaikelisha-ai
Copy link
Copy Markdown
Author

haggaikelisha-ai commented May 19, 2026 via email

@Joon-Klaps
Copy link
Copy Markdown
Contributor

Yes, that's my fault I thoughquay.io was no longer needed, but it is. Apologies for the confusion.

Copy link
Copy Markdown
Contributor

@Joon-Klaps Joon-Klaps left a comment

Choose a reason for hiding this comment

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

Sorry for the confusion and the long reviews.

Comment thread modules/nf-core/virusrecom/meta.yml Outdated
Comment on lines +53 to +54
description: Alignment tool to use for unaligned sequences (e.g. mafft,
muscle, clustalo)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Suggested change
description: Alignment tool to use for unaligned sequences (e.g. mafft,
muscle, clustalo)
description: Alignment tool to use for unaligned sequences (e.g. mafft,
muscle, clustalo)
enum: [mafft, muscle, clustalo]

tag "virusrecom"

test("sarscov2 - alignment [fasta] mapping [tsv] - stub") {
options "-stub"
Copy link
Copy Markdown
Contributor

@Joon-Klaps Joon-Klaps May 19, 2026

Choose a reason for hiding this comment

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

With this option "-stub" we don't actually run the tool virusrecom but we run the stub section of our module.
Which are these lines.

 stub:
    def prefix = task.ext.prefix ?: "${meta.id}"
    """
    mkdir -p ${meta.id}
    touch ${meta.id}/stub_output.txt
    """

Typically within our tests we want to test both the script block & the stub block.

To make a test for the script block, don't include the options "-stub" in the test.

Within this test script I believe we need:

  • normal test for input alignment
  • normal test for unaligned input (specify one of the three tools to align)
  • normal test with iwic input
  • stub test with input alignment

@haggaikelisha-ai
Copy link
Copy Markdown
Author

haggaikelisha-ai commented May 19, 2026 via email

@Joon-Klaps
Copy link
Copy Markdown
Contributor

Yes please extend the current testing framework, see my individual comments.

@haggaikelisha-ai
Copy link
Copy Markdown
Author

haggaikelisha-ai commented May 19, 2026 via email

@Joon-Klaps
Copy link
Copy Markdown
Contributor

We could patch the container, but let us instead just drop the funcitonality then for unaligned inputs and only allow aligned inputs or iwic files. So yeah, no need to test it.

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