Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions modules/nf-core/parsnp/environment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json
channels:
- conda-forge
- bioconda
dependencies:
- "bioconda::parsnp=2.1.5"
55 changes: 55 additions & 0 deletions modules/nf-core/parsnp/main.nf
Comment thread
emmcauley marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
process PARSNP {
tag "$meta.id"
label 'process_high'

conda "${moduleDir}/environment.yml"
container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ?
'oras://community.wave.seqera.io/library/parsnp:2.1.5--0605933fc69e7b20':
Comment thread
emmcauley marked this conversation as resolved.
Outdated
'community.wave.seqera.io/library/parsnp:2.1.5--2c7f64ad14a79523' }"

input:
tuple val(meta), path(genomes, stageAs: "genomes")
Comment thread
emmcauley marked this conversation as resolved.
Outdated
path reference

output:
tuple val(meta), path("*.xmfa") , emit: xmfa
tuple val(meta), path("*.ggr") , emit: ggr
tuple val(meta), path("*.snps.mblocks"), emit: snps_mblocks, optional: true
tuple val(meta), path("*.tree") , emit: tree
tuple val(meta), path("partition") , emit: partition, optional: true
tuple val("${task.process}"), val('parsnp'), eval("parsnp --version 2>/dev/null | tail -n 1 | sed 's/parsnp //'"), topic: versions, emit: versions_parsnp

when:
task.ext.when == null || task.ext.when

script:
def args = task.ext.args ?: ''
def prefix = task.ext.prefix ?: "${meta.id}"
"""
parsnp \\
-r "${reference}" \\
-d "${genomes}" \\
-o parsnp_out \\
-p ${task.cpus} \\
${args}

mv parsnp_out/parsnp.xmfa ${prefix}.xmfa
mv parsnp_out/parsnp.ggr ${prefix}.ggr
if [ -f parsnp_out/parsnp.snps.mblocks ]; then
mv parsnp_out/parsnp.snps.mblocks "${prefix}.snps.mblocks"
fi
mv parsnp_out/parsnp.tree ${prefix}.tree
if [ -d parsnp_out/partition ]; then
mv parsnp_out/partition .
fi
"""

stub:
Comment thread
famosab marked this conversation as resolved.
def prefix = task.ext.prefix ?: "${meta.id}"
Comment thread
emmcauley marked this conversation as resolved.
"""
touch ${prefix}.xmfa
touch ${prefix}.ggr
touch ${prefix}.snps.mblocks
touch ${prefix}.tree
"""
}
118 changes: 118 additions & 0 deletions modules/nf-core/parsnp/meta.yml
Comment thread
emmcauley marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/meta-schema.json
name: "parsnp"
description: "Parsnp is a command-line-tool for efficient microbial core genome alignment and SNP detection."
keywords:
- alignment
- bacteria
- phylogeny
- microbial genomics
- core genome
- SNP

tools:
- "parsnp":
description: "Parsnp is a command-line-tool for efficient microbial core genome alignment and SNP detection."
homepage: "https://harvest.readthedocs.io/en/latest/content/parsnp/tutorial.html"
documentation: "https://harvest.readthedocs.io/en/latest/content/parsnp/tutorial.html"
tool_dev_url: "https://github.com/marbl/parsnp"
doi: "10.1093/bioinformatics/btae311"
licence: ["custom; see https://raw.githubusercontent.com/marbl/parsnp/master/LICENSE"]
identifier: biotools:parsnp

input:
- - meta:
type: map
description: |
Groovy Map containing sample information
e.g. `[ id:'sample1' ]`
- genomes:
type: directory
description: Directory containing genome assemblies in FASTA format to be aligned
- reference:
type: file
description: Reference genome in FASTA format
pattern: "*.{fasta,fa,fna}"
ontologies:
- edam: "http://edamontology.org/format_1929" # FASTA

output:
xmfa:
- - meta:
type: map
description: |
Groovy Map containing sample information
e.g. `[ id:'sample1' ]`
- "*.xmfa":
type: file
description: Core-genome multiple sequence alignment in XMFA format
pattern: "*.xmfa"
Comment thread
emmcauley marked this conversation as resolved.
ggr:
- - meta:
type: map
description: |
Groovy Map containing sample information
e.g. `[ id:'sample1' ]`
- "*.ggr":
type: file
description: Compressed binary representation of the alignment generated by the Harvest toolkit, used for visualization with Gingr
pattern: "*.ggr"
Comment thread
emmcauley marked this conversation as resolved.
snps_mblocks:
- - meta:
type: map
description: |
Groovy Map containing sample information
e.g. `[ id:'sample1' ]`
- "*.snps.mblocks":
type: file
description: Core-SNP signature of each sequence in FASTA format, used to generate the phylogeny. Absent when no SNPs are detected.
pattern: "*.snps.mblocks"
ontologies:
- edam: "http://edamontology.org/format_1929" # FASTA
tree:
- - meta:
type: map
description: |
Groovy Map containing sample information
e.g. `[ id:'sample1' ]`
- "*.tree":
type: file
description: Resulting phylogeny in Newick format
pattern: "*.tree"
ontologies:
- edam: "http://edamontology.org/format_1910" # Newick
partition:
- - meta:
type: map
description: |
Groovy Map containing sample information
e.g. `[ id:'sample1' ]`
- "partition":
type: directory
description: Output directory from partition mode containing results of each partitioned run. Only present when --partition is specified.
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.

can we add a --partition test then to see if this works? :)

pattern: "partition"
versions_parsnp:
- - ${task.process}:
type: string
description: The name of the process
- parsnp:
type: string
description: The name of the tool
- "parsnp --version 2>/dev/null | tail -n 1 | sed 's/parsnp //'":
type: eval
description: The expression to obtain the version of the tool

topics:
versions:
- - ${task.process}:
type: string
description: The process
- parsnp:
type: string
description: The tool name
- parsnp --version 2>/dev/null | tail -n 1 | sed 's/parsnp //':
type: eval
description: The expression to obtain the version of the tool
authors:
- "@emmcauley"
maintainers:
- "@emmcauley"
62 changes: 62 additions & 0 deletions modules/nf-core/parsnp/tests/main.nf.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
nextflow_process {

name "Test Process PARSNP"
script "../main.nf"
process "PARSNP"

tag "modules"
tag "modules_nfcore"
tag "parsnp"

test("candidatus_portiera_aleyrodidarum - fasta") {
when {
process {
def dir = file("${outputDir}/genomes")
dir.mkdirs()
def genomeText = new URL('https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/genomics/prokaryotes/candidatus_portiera_aleyrodidarum/genome/genome.fasta').text
new File(dir, "portiera_1.fa").text = genomeText
Comment thread
emmcauley marked this conversation as resolved.
Outdated
Comment thread
emmcauley marked this conversation as resolved.
Outdated
new File(dir, "portiera_2.fa").text = genomeText
"""
input[0] = [[ id:'test' ], file("${outputDir}/genomes")]
input[1] = file(params.modules_testdata_base_path + 'genomics/prokaryotes/candidatus_portiera_aleyrodidarum/genome/genome.fasta', checkIfExists: true)
"""
}
}

then {
assertAll(
{ assert process.success },
{ assert snapshot(sanitizeOutput(process.out)).match() }
)
}

}

test("candidatus_portiera_aleyrodidarum - fasta - stub") {

options "-stub"

when {
process {
def dir = file("${outputDir}/genomes")
dir.mkdirs()
def genomeText = new URL('https://raw.githubusercontent.com/nf-core/test-datasets/modules/data/genomics/prokaryotes/candidatus_portiera_aleyrodidarum/genome/genome.fasta').text
new File(dir, "portiera_1.fa").text = genomeText
new File(dir, "portiera_2.fa").text = genomeText
"""
input[0] = [[ id:'test' ], file("${outputDir}/genomes")]
input[1] = file(params.modules_testdata_base_path + 'genomics/prokaryotes/candidatus_portiera_aleyrodidarum/genome/genome.fasta', checkIfExists: true)
"""
}
}

then {
assertAll(
{ assert process.success },
{ assert snapshot(sanitizeOutput(process.out)).match() }
)
}

}

}
108 changes: 108 additions & 0 deletions modules/nf-core/parsnp/tests/main.nf.test.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
{
"candidatus_portiera_aleyrodidarum - fasta - stub": {
"content": [
{
"ggr": [
[
{
"id": "test"
},
"test.ggr:md5,d41d8cd98f00b204e9800998ecf8427e"
]
],
"partition": [
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.

Is this supposed to be empty for this test?

Copy link
Copy Markdown
Contributor Author

@emmcauley emmcauley May 6, 2026

Choose a reason for hiding this comment

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

I've updated the tests to include a partition run and force output -- the deterministic md5s are included in the snapshot. I ran into errors using sanitizeOutput for this purpose so I use snapshot(...).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.

i see, but then we still need to assert the partititon output because whats the point of the test otherwise ;)


],
"snps_mblocks": [
[
{
"id": "test"
},
"test.snps.mblocks:md5,d41d8cd98f00b204e9800998ecf8427e"
]
],
"tree": [
[
{
"id": "test"
},
"test.tree:md5,d41d8cd98f00b204e9800998ecf8427e"
]
],
"versions_parsnp": [
[
"PARSNP",
"parsnp",
"2.1.5"
]
],
"xmfa": [
[
{
"id": "test"
},
"test.xmfa:md5,d41d8cd98f00b204e9800998ecf8427e"
]
]
}
],
"meta": {
"nf-test": "0.9.3",
"nextflow": "25.10.2"
},
"timestamp": "2026-04-15T10:59:34.624721"
},
"candidatus_portiera_aleyrodidarum - fasta": {
"content": [
{
"ggr": [
[
{
"id": "test"
},
"test.ggr:md5,98585d7f9ffae110bbcf37b139887d1b"
]
],
"partition": [

],
Comment thread
emmcauley marked this conversation as resolved.
Outdated
"snps_mblocks": [
[
{
"id": "test"
},
"test.snps.mblocks:md5,5cdabd01f303fc480d81a352661e802d"
]
],
"tree": [
[
{
"id": "test"
},
"test.tree:md5,e73585947555491eec4092429f3331bf"
]
],
"versions_parsnp": [
[
"PARSNP",
"parsnp",
"2.1.5"
]
],
"xmfa": [
[
{
"id": "test"
},
"test.xmfa:md5,5b07a37b1e4dfb96582cede2a2763f0c"
]
]
}
],
"meta": {
"nf-test": "0.9.3",
"nextflow": "25.10.2"
},
"timestamp": "2026-04-15T10:59:13.628388"
}
}
Loading