Skip to content
Draft
Show file tree
Hide file tree
Changes from all 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
64 changes: 64 additions & 0 deletions modules/nf-core/parabricks/deepsomatic/main.nf
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
process PARABRICKS_DEEPSOMATIC {
tag "${meta.id}"
label 'process_high'
label 'process_gpu'
// needed by the module to work properly can be removed when fixed upstream - see: https://github.com/nf-core/modules/issues/7226
stageInMode 'copy'

container "nvcr.io/nvidia/clara/clara-parabricks:4.7.1-1"

input:
tuple val(meta), path(input_tumor), path(index_tumor), path(input_normal), path(index_normal), path(intervals)
tuple val(ref_meta), path(fasta)

output:
tuple val(meta), path("*.vcf.gz"), emit: vcf, optional: true
tuple val(meta), path("*.g.vcf.gz"), emit: gvcf, optional: true
tuple val(meta), path("*.vcf.gz.tbi"), emit: index, optional: true
path "compatible_versions.yml", emit: compatible_versions, optional: true
tuple val("${task.process}"), val('parabricks'), eval("pbrun version | grep -m1 '^pbrun:' | sed 's/^pbrun:[[:space:]]*//'"), topic: versions, emit: versions_parabricks

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

script:
// Exit if running this module with -profile conda / -profile mamba
if (workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1) {
exit(1, "Parabricks module does not support Conda. Please use Docker / Singularity / Podman instead.")
}
def args = task.ext.args ?: ''
def prefix = task.ext.prefix ?: "${meta.id}"
def output_file = args.contains("--gvcf") ? "${prefix}.g.vcf.gz" : "${prefix}.vcf.gz"
def interval_command = intervals ? intervals.collect { interval -> "--interval-file ${interval}" }.join(' ') : ""
def num_gpus = task.accelerator ? "--num-gpus ${task.accelerator.request}" : ''
"""
pbrun \\
deepsomatic \\
--ref ${fasta} \\
--in-tumor-bam ${input_tumor} \\
--in-normal-bam ${input_normal} \\
--out-variants ${output_file} \\
${interval_command} \\
${num_gpus} \\
${args}
"""

stub:
def args = task.ext.args ?: ''
def prefix = task.ext.prefix ?: "${meta.id}"
def output_cmd = args.contains("--gvcf") ? "echo '' | gzip > ${prefix}.g.vcf.gz" : "echo '' | gzip > ${prefix}.vcf.gz"
"""
${output_cmd}

# Capture the full version output once and store it in a variable
pbrun_version_output=\$(pbrun deepsomatic --version 2>&1)

# Generate compatible_versions.yml
cat <<EOF > compatible_versions.yml
"${task.process}":
pbrun_version: \$(echo "\$pbrun_version_output" | grep "pbrun:" | awk '{print \$2}')
compatible_with:
\$(echo "\$pbrun_version_output" | awk '/Compatible With:/,/^---/{ if (\$1 ~ /^[A-Z]/ && \$1 != "Compatible" && \$1 != "---") { printf " %s: %s\\n", \$1, \$2 } }')
EOF
"""
}
119 changes: 119 additions & 0 deletions modules/nf-core/parabricks/deepsomatic/meta.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/meta-schema.json
name: "parabricks_deepsomatic"
description: NVIDIA Clara Parabricks GPU-accelerated somatic variant calling, replicating
deepsomatic.
keywords:
- variant
- somatic
- vcf
- deepsomatic
- tumor
- normal
tools:
- "parabricks":
description: "NVIDIA Clara Parabricks GPU-accelerated genomics tools"
homepage: https://www.nvidia.com/en-us/clara/genomics/
documentation: https://docs.nvidia.com/clara/parabricks/latest/index.html
licence: ["custom"]
identifier: ""

input:
- - meta:
type: map
description: |
Groovy Map containing sample information.
[ id:'tumor_vs_normal']
- input_tumor:
type: file
description: BAM/CRAM file for tumor sample.
pattern: "*.{bam,cram}"
ontologies: []
- index_tumor:
type: file
description: BAI/CRAI index corresponding to tumor BAM/CRAM file.
pattern: "*.{bai,crai}"
ontologies: []
- input_normal:
type: file
description: BAM/CRAM file for normal sample.
pattern: "*.{bam,cram}"
ontologies: []
- index_normal:
type: file
description: BAI/CRAI index corresponding to normal BAM/CRAM file.
pattern: "*.{bai,crai}"
ontologies: []
- intervals:
type: file
description: File or files containing genomic intervals for variant calling.
pattern: "*.{bed,interval_list,picard,list,intervals}"
ontologies: []
- - ref_meta:
type: map
description: |
Groovy Map containing reference information.
[ id:'genome']
- fasta:
type: file
description: Reference fasta - must be unzipped.
pattern: "*.fasta"
ontologies: []

output:
vcf:
- - meta:
type: map
description: |
Groovy Map containing sample information.
e.g. [ id:'tumor_vs_normal' ]
- "*.vcf.gz":
type: file
description: VCF file created with deepsomatic, optional
pattern: "*.vcf.gz"
ontologies: []
gvcf:
- - meta:
type: map
description: |
Groovy Map containing sample information.
e.g. [ id:'tumor_vs_normal' ]
- "*.g.vcf.gz":
type: file
description: bgzipped gVCF created with deepsomatic, optional
pattern: "*.g.vcf.gz"
ontologies:
- edam: http://edamontology.org/format_3989 # GZIP format
compatible_versions:
- compatible_versions.yml:
type: file
description: File containing info on compatible CPU-based software versions.
pattern: "compatible_versions.yml"
ontologies:
- edam: http://edamontology.org/format_3750 # YAML
versions_parabricks:
- - ${task.process}:
type: string
description: The process the versions were collected from
- parabricks:
type: string
description: The tool name
- "pbrun version | grep -m1 '^pbrun:' | sed 's/^pbrun:[[:space:]]*//'":
type: string
description: The command used to generate the version of the tool

topics:
versions:
- - ${task.process}:
type: string
description: The process the versions were collected from
- parabricks:
type: string
description: The tool name
- "pbrun version | grep -m1 '^pbrun:' | sed 's/^pbrun:[[:space:]]*//'":
type: string
description: The command used to generate the version of the tool

authors:
- "@sppearce"
maintainers:
- "@sppearce"
184 changes: 184 additions & 0 deletions modules/nf-core/parabricks/deepsomatic/tests/main.nf.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
nextflow_process {

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

tag "modules"
tag "modules_nfcore"
tag "parabricks"
tag "parabricks/deepsomatic"
tag "gpu"
config './nextflow.config'

test("human - tumor_normal_pair") {

params {
module_args = ''
}

when {
process {
"""
input[0] = [
[ id:'tumor_vs_normal' ],
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test2.paired_end.recalibrated.sorted.bam', checkIfExists: true),
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test2.paired_end.recalibrated.sorted.bam.bai', checkIfExists: true),
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.recalibrated.sorted.bam', checkIfExists: true),
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.recalibrated.sorted.bam.bai', checkIfExists: true),
[]
]
input[1] = [
[ id:'genome' ],
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.fasta', checkIfExists: true)
]
"""
}
}

then {
assert process.success
assertAll(
{ assert snapshot(sanitizeOutput(process.out, variantsMD5Keys:["vcf"])).match() }
)
}

}

test("human - tumor_normal_pair - intervals") {

when {
params {
module_args = ''
}
process {
"""
input[0] = [
[ id:'tumor_vs_normal' ],
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test2.paired_end.recalibrated.sorted.bam', checkIfExists: true),
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test2.paired_end.recalibrated.sorted.bam.bai', checkIfExists: true),
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.recalibrated.sorted.bam', checkIfExists: true),
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.recalibrated.sorted.bam.bai', checkIfExists: true),
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/multi_intervals.bed', checkIfExists: true)
]
input[1] = [
[ id:'genome' ],
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.fasta', checkIfExists: true)
]
"""
}
}

then {
assert process.success
assertAll(
{ assert snapshot(sanitizeOutput(process.out, variantsMD5Keys:["vcf"])).match() }
)
}

}

test("human - tumor_normal_pair - gvcf") {

when {
params {
module_args = '--gvcf'
}
process {
"""
input[0] = [
[ id:'tumor_vs_normal' ],
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test2.paired_end.recalibrated.sorted.bam', checkIfExists: true),
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test2.paired_end.recalibrated.sorted.bam.bai', checkIfExists: true),
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.recalibrated.sorted.bam', checkIfExists: true),
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.recalibrated.sorted.bam.bai', checkIfExists: true),
[]
]
input[1] = [
[ id:'genome' ],
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.fasta', checkIfExists: true)
]
"""
}
}

then {
assert process.success
assertAll(
{ assert snapshot(sanitizeOutput(process.out, variantsMD5Keys:["gvcf"])).match() }
)
}

}

test("human - tumor_normal_pair - stub") {

options "-stub"

when {
params {
module_args = ''
}
process {
"""
input[0] = [
[ id:'tumor_vs_normal' ],
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test2.paired_end.recalibrated.sorted.bam', checkIfExists: true),
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test2.paired_end.recalibrated.sorted.bam.bai', checkIfExists: true),
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.recalibrated.sorted.bam', checkIfExists: true),
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.recalibrated.sorted.bam.bai', checkIfExists: true),
[]
]
input[1] = [
[ id:'genome' ],
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.fasta', checkIfExists: true)
]
"""
}
}

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

}

test("human - tumor_normal_pair - gvcf - stub") {

options "-stub"

when {
params {
module_args = '--gvcf'
}
process {
"""
input[0] = [
[ id:'tumor_vs_normal' ],
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test2.paired_end.recalibrated.sorted.bam', checkIfExists: true),
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test2.paired_end.recalibrated.sorted.bam.bai', checkIfExists: true),
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.recalibrated.sorted.bam', checkIfExists: true),
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.recalibrated.sorted.bam.bai', checkIfExists: true),
[]
]
input[1] = [
[ id:'genome' ],
file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.fasta', checkIfExists: true)
]
"""
}
}

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

}

}
7 changes: 7 additions & 0 deletions modules/nf-core/parabricks/deepsomatic/tests/nextflow.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
process {

withName: 'PARABRICKS_DEEPSOMATIC' {
ext.args = params.module_args
}

}
Loading