diff --git a/modules/nf-core/gridss/call/environment.yml b/modules/nf-core/gridss/call/environment.yml new file mode 100644 index 000000000000..db37d675e605 --- /dev/null +++ b/modules/nf-core/gridss/call/environment.yml @@ -0,0 +1,5 @@ +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::gridss=2.13.2 diff --git a/modules/nf-core/gridss/call/main.nf b/modules/nf-core/gridss/call/main.nf new file mode 100644 index 000000000000..729913c1526b --- /dev/null +++ b/modules/nf-core/gridss/call/main.nf @@ -0,0 +1,52 @@ +process GRIDSS_CALL { + tag "$meta.id" + label 'process_medium' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine in ['singularity', 'apptainer'] && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/gridss:2.13.2--h50ea8bc_3': + 'quay.io/biocontainers/gridss:2.13.2--h50ea8bc_3' }" + + input: + tuple val(meta), path(bam), path(bai), path(preprocess_dir), path(assemble_dir), path(assemble_bam) + tuple val(meta2), path(fasta), path(fasta_fai), path(bwa_index) + tuple val(meta3), path(gridss_config) + + output: + tuple val(meta), path("*.sv.gridss.vcf.gz"), emit: vcf + tuple val("${task.process}"), val('gridss'), eval("CallVariants --version 2>&1 | sed 's/-gridss\$//'") , topic: versions, emit: versions_gridss + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def arg_config = gridss_config ? "-c ${gridss_config}" : "" + def bam_list = bam instanceof List ? bam : [bam] + + def index_files = bwa_index instanceof List ? bwa_index : [bwa_index] + // GRIDSS requires all BWA index files to have the exact same basename as the reference fasta + def link_cmds = index_files.collect { idx -> "ln -sf ${idx} ./${fasta}.${idx.extension}" }.join('\n') + """ + ${link_cmds} + + gridss ${args} \\ + --jvmheap ${Math.round(task.memory.bytes * 0.95)} \\ + --steps call \\ + --reference ${fasta} \\ + --workingdir "." \\ + --assembly ${assemble_bam} \\ + --output ${prefix}.sv.gridss.vcf.gz \\ + --threads ${task.cpus} ${arg_config} ${bam_list.join(' ')} + + """ + + stub: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + + """ + echo "" | gzip > ${prefix}.sv.gridss.vcf.gz + """ +} diff --git a/modules/nf-core/gridss/call/meta.yml b/modules/nf-core/gridss/call/meta.yml new file mode 100644 index 000000000000..2448915d9408 --- /dev/null +++ b/modules/nf-core/gridss/call/meta.yml @@ -0,0 +1,118 @@ +name: "gridss_call" +description: Run the GRIDSS variant calling step to identify structural variants + from pre-processed and assembled alignments. +keywords: + - gridss + - structural variants + - variant calling + - bam + - vcf +tools: + - "gridss": + description: "GRIDSS: the Genomic Rearrangement IDentification Software Suite" + homepage: "https://github.com/PapenfussLab/gridss/wiki/GRIDSS-Documentation" + documentation: "https://github.com/PapenfussLab/gridss/wiki/GRIDSS-Documentation" + tool_dev_url: "https://github.com/PapenfussLab/gridss" + doi: "10.1186/s13059-021-02423-x" + licence: + - "GPL v3" + identifier: biotools:gridss +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'test' ]` + - bam: + type: file + description: Input BAM file(s) + pattern: "*.bam" + ontologies: + - edam: http://edamontology.org/format_2572 + - bai: + type: file + description: BAM index file(s) + pattern: "*.bam.bai" + ontologies: [] + - preprocess_dir: + type: directory + description: Working directory containing the output of the GRIDSS preprocess step + preprocess step + - assemble_dir: + type: directory + description: Working directory containing the output of the GRIDSS assemble step + assemble step + - assemble_bam: + type: file + description: The assembly BAM file created by the GRIDSS assemble step + pattern: "*.{bam}" + ontologies: + - edam: http://edamontology.org/data_1383 + - edam: http://edamontology.org/format_2572 + - - meta2: + type: map + description: | + Groovy Map containing reference information + e.g. `[ id:'genome' ]` + - fasta: + type: file + description: The reference fasta + pattern: "*.{fa,fna,fasta}" + ontologies: [] + - fasta_fai: + type: file + description: The index of the reference fasta + pattern: "*.fai" + ontologies: [] + - bwa_index: + type: directory + description: The BWA index created from the reference fasta + - - meta3: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'test' ]` + - gridss_config: + type: file + description: OPTIONAL - A GRIDSS configuration file (Java .properties format). + See the default config for available settings, + https://github.com/PapenfussLab/gridss/blob/825bc8e1bb092e9bb2ccb0c1c51dc6e7e1a922dd/src/main/resources/gridss.properties + ontologies: [] +output: + vcf: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'test' ]` + - "*.sv.gridss.vcf.gz": + type: file + description: The called VCF file created by the GRIDSS call step + pattern: "*.sv.gridss.vcf.gz" + ontologies: + - edam: http://edamontology.org/format_3989 + versions_gridss: + - - ${task.process}: + type: string + description: The name of the process + - gridss: + type: string + description: The name of the tool + - CallVariants --version 2>&1 | sed 's/-gridss\$//': + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - gridss: + type: string + description: The name of the tool + - CallVariants --version 2>&1 | sed 's/-gridss\$//': + type: eval + description: The expression to obtain the version of the tool +authors: + - "@imsarath" +maintainers: + - "@imsarath" diff --git a/modules/nf-core/gridss/call/tests/main.nf.test b/modules/nf-core/gridss/call/tests/main.nf.test new file mode 100644 index 000000000000..abfe2689dbbc --- /dev/null +++ b/modules/nf-core/gridss/call/tests/main.nf.test @@ -0,0 +1,136 @@ +nextflow_process { + + name "Test Process GRIDSS_CALL" + script "../main.nf" + process "GRIDSS_CALL" + + tag "modules" + tag "modules_nfcore" + tag "bwa/index" + tag "gridss" + tag "gridss/preprocess" + tag "gridss/assemble" + tag "gridss/call" + + setup { + run("BWA_INDEX") { + script "../../../bwa/index/main.nf" + process { + """ + input[0] = [ + [ id: 'fasta' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + ] + """ + } + } + + run("GRIDSS_PREPROCESS") { + script "../../preprocess/main.nf" + process { + """ + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) + ] + input[1] = channel.of([ + [id:'fasta'], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) + ]).join(BWA_INDEX.out.index) + """ + } + } + + run("GRIDSS_ASSEMBLE") { + script "../../assemble/main.nf" + process { + """ + input[0] = channel.of([ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) + ]).join(GRIDSS_PREPROCESS.out.preprocess_dir) + input[1] = channel.of([ + [id:'fasta'], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) + ]).join(BWA_INDEX.out.index) + input[2] = channel.of([ + [ id: 'gridss_config' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gridss/gridss.properties', checkIfExists: true) + ]) + """ + } + } + } + + test("human - bam") { + + when { + process { + """ + input[0] = channel.of([ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) + ]).join(GRIDSS_PREPROCESS.out.preprocess_dir).join(GRIDSS_ASSEMBLE.out.assemble_dir) + input[1] = channel.of([ + [id:'fasta'], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) + ]).join(BWA_INDEX.out.index) + input[2] = channel.of([ + [ id: 'gridss_config' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gridss/gridss.properties', checkIfExists: true) + ]) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + path(process.out.vcf[0][1]).vcf.summary, + process.out.findAll { key, val -> key.startsWith("versions") } + ).match() } + ) + } + } + + test("human - bam - stub") { + + options "-stub" + + when { + process { + """ + input[0] = channel.of([ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/test.paired_end.sorted.bam.bai', checkIfExists: true) + ]).join(GRIDSS_PREPROCESS.out.preprocess_dir).join(GRIDSS_ASSEMBLE.out.assemble_dir) + input[1] = channel.of([ + [id:'fasta'], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) + ]).join(BWA_INDEX.out.index) + input[2] = channel.of([ + [ id: 'gridss_config' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/gridss/gridss.properties', checkIfExists: true) + ]) + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(sanitizeOutput(process.out)).match() } + ) + } + } + +} diff --git a/modules/nf-core/gridss/call/tests/main.nf.test.snap b/modules/nf-core/gridss/call/tests/main.nf.test.snap new file mode 100644 index 000000000000..9d8fddc3407d --- /dev/null +++ b/modules/nf-core/gridss/call/tests/main.nf.test.snap @@ -0,0 +1,47 @@ +{ + "human - bam - stub": { + "content": [ + { + "vcf": [ + [ + { + "id": "test" + }, + "test.sv.gridss.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "versions_gridss": [ + [ + "GRIDSS_CALL", + "gridss", + "2.13.2" + ] + ] + } + ], + "timestamp": "2026-07-27T11:40:58.652323404", + "meta": { + "nf-test": "0.9.4", + "nextflow": "26.04.3" + } + }, + "human - bam": { + "content": [ + "VcfFile [chromosomes=[], sampleCount=1, variantCount=0, phased=true, phasedAutodetect=true]", + { + "versions_gridss": [ + [ + "GRIDSS_CALL", + "gridss", + "2.13.2" + ] + ] + } + ], + "timestamp": "2026-07-27T11:40:40.343197386", + "meta": { + "nf-test": "0.9.4", + "nextflow": "26.04.3" + } + } +} \ No newline at end of file