diff --git a/modules/nf-core/bcftools/pluginvcf2table/environment.yml b/modules/nf-core/bcftools/pluginvcf2table/environment.yml new file mode 100644 index 000000000000..c52fee5e2a2f --- /dev/null +++ b/modules/nf-core/bcftools/pluginvcf2table/environment.yml @@ -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::bcftools=1.23.1" diff --git a/modules/nf-core/bcftools/pluginvcf2table/main.nf b/modules/nf-core/bcftools/pluginvcf2table/main.nf new file mode 100644 index 000000000000..7bc852d822b9 --- /dev/null +++ b/modules/nf-core/bcftools/pluginvcf2table/main.nf @@ -0,0 +1,43 @@ +process BCFTOOLS_PLUGINVCF2TABLE { + tag "${meta.id}" + label 'process_low' + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/9e/9e674cbc269b944e50ad4f5846ee92a2196b59d9ed76e9146867c76fb32cb8aa/data' + : 'community.wave.seqera.io/library/bcftools:1.23.1--4d193a5f61d4aed7'}" + + input: + tuple val(meta), path(vcf), path(tbi) + tuple val(meta2), path(regions), path(targets), path(samples) + + output: + tuple val(meta), path("*.txt"), emit: txt + tuple val("${task.process}"), val('bcftools'), eval("bcftools --version | sed '1!d; s/^.*bcftools //'"), topic: versions, emit: versions_bcftools + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def regions_file = regions ? "--regions-file ${regions}" : '' + def targets_file = targets ? "--targets-file ${targets}" : '' + def samples_file = samples ? "--samples-file ${samples}" : '' + """ + bcftools \\ + +vcf2table \\ + ${args} \\ + ${regions_file} \\ + ${targets_file} \\ + ${samples_file} \\ + ${vcf} \\ + > ${prefix}.txt + """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}.txt + """ +} diff --git a/modules/nf-core/bcftools/pluginvcf2table/meta.yml b/modules/nf-core/bcftools/pluginvcf2table/meta.yml new file mode 100644 index 000000000000..8e68bf559bc0 --- /dev/null +++ b/modules/nf-core/bcftools/pluginvcf2table/meta.yml @@ -0,0 +1,106 @@ +name: bcftools_pluginvcf2table +description: | + Converts VCF/BCF files into a tab-delimited table using the bcftools +vcf2table plugin. + Each variant is output as one row, with INFO and FORMAT fields as columns. +keywords: + - bcftools + - vcf + - table + - variant calling +tools: + - bcftools: + description: | + BCFtools is a set of utilities for variant calling and manipulating VCF/BCF files. + The +vcf2table plugin converts VCF records into a tab-delimited table format. + homepage: http://samtools.github.io/bcftools/bcftools.html + documentation: http://www.htslib.org/doc/bcftools.html + doi: "10.1093/gigascience/giab008" + licence: + - "MIT" + identifier: biotools:bcftools +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + ontologies: [] + - vcf: + type: file + description: VCF/BCF file to be converted (optionally bgzipped). + pattern: "*.{vcf,vcf.gz,bcf,bcf.gz}" + ontologies: + - edam: "http://edamontology.org/format_3016" # VCF + - tbi: + type: file + description: Index of the VCF/BCF file (required when vcf is bgzipped). + pattern: "*.{tbi,csi}" + ontologies: [] + - - meta2: + type: map + description: | + Groovy Map containing filter file information + e.g. [ id:'test' ] + - regions: + type: file + description: | + Optional. Restrict the operation to regions listed in this BED or VCF file. + Relies on a tabix index. + pattern: "*.{bed,vcf,vcf.gz}" + ontologies: + - edam: "http://edamontology.org/format_3003" # BED + - edam: "http://edamontology.org/format_3016" # VCF + - targets: + type: file + description: | + Optional. Restrict the operation to regions listed in this file + (does not rely on index files). + pattern: "*.{bed,vcf,vcf.gz}" + ontologies: + - edam: "http://edamontology.org/format_3003" # BED + - edam: "http://edamontology.org/format_3016" # VCF + - samples: + type: file + description: | + Optional. File of sample names to include or exclude. + pattern: "*.txt" + ontologies: [] +output: + txt: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + ontologies: [] + - "*.txt": + type: file + description: Tab-delimited table output from bcftools +vcf2table. + pattern: "*.txt" + ontologies: + - edam: "http://edamontology.org/format_3475" # TSV + versions_bcftools: + - - ${task.process}: + type: string + description: The name of the process + - bcftools: + type: string + description: The name of the tool + - "bcftools --version | sed '1!d; s/^.*bcftools //'": + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - ${task.process}: + type: string + description: The name of the process + - bcftools: + type: string + description: The name of the tool + - "bcftools --version | sed '1!d; s/^.*bcftools //'": + type: eval + description: The expression to obtain the version of the tool +authors: + - "@emmcauley" +maintainers: + - "@emmcauley" diff --git a/modules/nf-core/bcftools/pluginvcf2table/tests/main.nf.test b/modules/nf-core/bcftools/pluginvcf2table/tests/main.nf.test new file mode 100644 index 000000000000..3047608405ab --- /dev/null +++ b/modules/nf-core/bcftools/pluginvcf2table/tests/main.nf.test @@ -0,0 +1,121 @@ +nextflow_process { + + name "Test Process BCFTOOLS_PLUGINVCF2TABLE" + script "../main.nf" + process "BCFTOOLS_PLUGINVCF2TABLE" + + tag "modules" + tag "modules_nfcore" + tag "bcftools" + tag "bcftools/pluginvcf2table" + + test("homo_sapiens - vcf_gz - tbi") { + + when { + process { + """ + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz.tbi', checkIfExists: true) + ] + input[1] = [ [], [], [], [] ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(sanitizeOutput(process.out)).match() }, + ) + } + + } + + test("homo_sapiens - vcf_gz - tbi - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz.tbi', checkIfExists: true) + ] + input[1] = [ [], [], [], [] ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(sanitizeOutput(process.out)).match() }, + ) + } + + + } + test("homo_sapiens - vcf_gz - tbi - regions") { + + when { + process { + """ + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz.tbi', checkIfExists: true) + ] + input[1] = [ + [ id:'test_regions' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bed/test.bed', checkIfExists: true), + [], + [] + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(sanitizeOutput(process.out)).match() }, + ) + } + + } + + test("homo_sapiens - vcf_gz - tbi - regions - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'test' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf.gz.tbi', checkIfExists: true) + ] + input[1] = [ + [ id:'test_regions' ], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/bed/test.bed', checkIfExists: true), + [], + [] + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(sanitizeOutput(process.out)).match() }, + ) + } + + } +} diff --git a/modules/nf-core/bcftools/pluginvcf2table/tests/main.nf.test.snap b/modules/nf-core/bcftools/pluginvcf2table/tests/main.nf.test.snap new file mode 100644 index 000000000000..8e6bc4e3628b --- /dev/null +++ b/modules/nf-core/bcftools/pluginvcf2table/tests/main.nf.test.snap @@ -0,0 +1,106 @@ +{ + "homo_sapiens - vcf_gz - tbi - regions - stub": { + "content": [ + { + "txt": [ + [ + { + "id": "test" + }, + "test.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_bcftools": [ + [ + "BCFTOOLS_PLUGINVCF2TABLE", + "bcftools", + "1.23.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-05-07T09:54:51.383032" + }, + "homo_sapiens - vcf_gz - tbi": { + "content": [ + { + "txt": [ + [ + { + "id": "test" + }, + "test.txt:md5,79defcea1d70a0213a72c106c989c5af" + ] + ], + "versions_bcftools": [ + [ + "BCFTOOLS_PLUGINVCF2TABLE", + "bcftools", + "1.23.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-05-07T09:53:54.113096" + }, + "homo_sapiens - vcf_gz - tbi - regions": { + "content": [ + { + "txt": [ + [ + { + "id": "test" + }, + "test.txt:md5,d3c61f3610c0be011539860ceeb48b15" + ] + ], + "versions_bcftools": [ + [ + "BCFTOOLS_PLUGINVCF2TABLE", + "bcftools", + "1.23.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-05-07T09:54:33.031911" + }, + "homo_sapiens - vcf_gz - tbi - stub": { + "content": [ + { + "txt": [ + [ + { + "id": "test" + }, + "test.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions_bcftools": [ + [ + "BCFTOOLS_PLUGINVCF2TABLE", + "bcftools", + "1.23.1" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.2" + }, + "timestamp": "2026-05-07T09:54:14.61752" + } +} \ No newline at end of file