diff --git a/modules/nf-core/vembrane/table/environment.yml b/modules/nf-core/vembrane/table/environment.yml new file mode 100644 index 00000000000..825a5fac4b7 --- /dev/null +++ b/modules/nf-core/vembrane/table/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::vembrane=2.4.0 diff --git a/modules/nf-core/vembrane/table/main.nf b/modules/nf-core/vembrane/table/main.nf new file mode 100644 index 00000000000..243ce472b36 --- /dev/null +++ b/modules/nf-core/vembrane/table/main.nf @@ -0,0 +1,47 @@ +process VEMBRANE_TABLE { + tag "${meta.id}" + label 'process_low' + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/vembrane:2.4.0--pyhdfd78af_0' + : 'biocontainers/vembrane:2.4.0--pyhdfd78af_0'}" + + input: + tuple val(meta), path(vcf) + val expression + + output: + tuple val(meta), path("*.tsv"), emit: table + path "versions.yml", emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + """ + vembrane table \\ + ${args} \\ + --output ${prefix}.tsv \\ + '${expression}' \\ + ${vcf} + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + vembrane: \$(vembrane --version | sed '1!d;s/.* //') + END_VERSIONS + """ + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}.tsv + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + vembrane: \$(vembrane --version | sed '1!d;s/.* //') + END_VERSIONS + """ +} diff --git a/modules/nf-core/vembrane/table/meta.yml b/modules/nf-core/vembrane/table/meta.yml new file mode 100644 index 00000000000..2743421d4d6 --- /dev/null +++ b/modules/nf-core/vembrane/table/meta.yml @@ -0,0 +1,63 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/meta-schema.json +name: "vembrane_table" +description: Creates tabular (TSV) files from VCF/BCF data with flexible Python expressions +keywords: + - vcf + - bcf + - table + - genomics + - variant + - annotation +tools: + - "vembrane": + description: "Filter VCF/BCF files with Python expressions" + homepage: "https://vembrane.github.io/" + documentation: "https://github.com/vembrane/vembrane/blob/main/docs/table.md" + tool_dev_url: "https://github.com/vembrane/vembrane" + doi: "10.1093/bioinformatics/btac810" + licence: ["MIT"] + identifier: biotools:vembrane + args_id: "$args" + +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1', single_end:false ]` + - vcf: + type: file + description: VCF/BCF file to extract tabular data from + pattern: "*.{vcf,vcf.gz,bcf,bcf.gz}" + ontologies: + - edam: http://edamontology.org/format_3016 # VCF + - expression: + type: string + description: A comma-separated tuple of expressions that define the table column contents + +output: + table: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. `[ id:'sample1', single_end:false ]` + - "*.tsv": + type: file + description: TSV file containing tabular data from VCF/BCF + pattern: "*.tsv" + ontologies: + - edam: http://edamontology.org/format_3475 # TSV + versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" + ontologies: + - edam: http://edamontology.org/format_3750 # YAML +authors: +- "@mkatsanto" +- "@trangdo-hsc" +maintainers: +- "@mkatsanto" +- "@trangdo-hsc" diff --git a/modules/nf-core/vembrane/table/tests/main.nf.test b/modules/nf-core/vembrane/table/tests/main.nf.test new file mode 100644 index 00000000000..bfc7595e77b --- /dev/null +++ b/modules/nf-core/vembrane/table/tests/main.nf.test @@ -0,0 +1,137 @@ +nextflow_process { + + name "Test Process VEMBRANE_TABLE" + script "../main.nf" + process "VEMBRANE_TABLE" + + tag "modules" + tag "modules_nfcore" + tag "vembrane" + tag "vembrane/table" + + test("homo_sapiens - [vcf] - tsv") { + + when { + process { + """ + input[0] = [ + [ id:'test' ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/test.rnaseq.vcf', checkIfExists: true) + ] + input[1] = 'CHROM, POS, REF, ALT, QUAL' + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("homo_sapiens - [bcf.gz] - tsv") { + + when { + process { + """ + input[0] = [ + [ id:'test' ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/popgen/plink_simulated.bcf.gz', checkIfExists: true) + ] + input[1] = 'CHROM, POS, REF, ALT, QUAL' + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("homo_sapiens - [vcf] - csv - custom_separator") { + + config "./nextflow.config" + + when { + params { + vembrane_args = '--separator ,' + } + process { + """ + input[0] = [ + [ id:'test' ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/test.rnaseq.vcf', checkIfExists: true) + ] + input[1] = 'CHROM, POS, REF, ALT' + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("homo_sapiens - [vcf] - tsv - custom_header") { + + config "./nextflow.config" + + when { + params { + vembrane_args = '--header "Chromosome,Position,Variant_ID,Quality"' + } + process { + """ + input[0] = [ + [ id:'test' ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/test.rnaseq.vcf', checkIfExists: true) + ] + input[1] = 'CHROM, POS, ID, QUAL' + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("homo_sapiens - [vcf] - tsv - stub") { + + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'test' ], // meta map + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/test.rnaseq.vcf', checkIfExists: true) + ] + input[1] = 'CHROM, POS, REF, ALT, QUAL' + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + process.out, + path(process.out.versions[0]).yaml + ).match() } + ) + } + } + +} diff --git a/modules/nf-core/vembrane/table/tests/main.nf.test.snap b/modules/nf-core/vembrane/table/tests/main.nf.test.snap new file mode 100644 index 00000000000..afc04910885 --- /dev/null +++ b/modules/nf-core/vembrane/table/tests/main.nf.test.snap @@ -0,0 +1,172 @@ +{ + "homo_sapiens - [vcf] - tsv - custom_header": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.tsv:md5,a000109bce654d2d6f8ce132c03d27b4" + ] + ], + "1": [ + "versions.yml:md5,24635137815ac702717f1edf14621d8c" + ], + "table": [ + [ + { + "id": "test" + }, + "test.tsv:md5,a000109bce654d2d6f8ce132c03d27b4" + ] + ], + "versions": [ + "versions.yml:md5,24635137815ac702717f1edf14621d8c" + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.0" + }, + "timestamp": "2025-10-29T16:45:22.931526" + }, + "homo_sapiens - [vcf] - tsv": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.tsv:md5,bc377c509db1bea19cb2d13b7e3b5480" + ] + ], + "1": [ + "versions.yml:md5,24635137815ac702717f1edf14621d8c" + ], + "table": [ + [ + { + "id": "test" + }, + "test.tsv:md5,bc377c509db1bea19cb2d13b7e3b5480" + ] + ], + "versions": [ + "versions.yml:md5,24635137815ac702717f1edf14621d8c" + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.0" + }, + "timestamp": "2025-10-29T16:44:33.392488" + }, + "homo_sapiens - [bcf.gz] - tsv": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.tsv:md5,f0d357c993b9c0463b4564681ffffa2e" + ] + ], + "1": [ + "versions.yml:md5,24635137815ac702717f1edf14621d8c" + ], + "table": [ + [ + { + "id": "test" + }, + "test.tsv:md5,f0d357c993b9c0463b4564681ffffa2e" + ] + ], + "versions": [ + "versions.yml:md5,24635137815ac702717f1edf14621d8c" + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.0" + }, + "timestamp": "2025-10-29T16:44:48.817287" + }, + "homo_sapiens - [vcf] - csv - custom_separator": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.tsv:md5,f8616b2040be43518e270c02aac600f6" + ] + ], + "1": [ + "versions.yml:md5,24635137815ac702717f1edf14621d8c" + ], + "table": [ + [ + { + "id": "test" + }, + "test.tsv:md5,f8616b2040be43518e270c02aac600f6" + ] + ], + "versions": [ + "versions.yml:md5,24635137815ac702717f1edf14621d8c" + ] + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.0" + }, + "timestamp": "2025-10-29T16:45:03.973682" + }, + "homo_sapiens - [vcf] - tsv - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test" + }, + "test.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "1": [ + "versions.yml:md5,24635137815ac702717f1edf14621d8c" + ], + "table": [ + [ + { + "id": "test" + }, + "test.tsv:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,24635137815ac702717f1edf14621d8c" + ] + }, + { + "VEMBRANE_TABLE": { + "vembrane": "2.4.0" + } + } + ], + "meta": { + "nf-test": "0.9.3", + "nextflow": "25.10.0" + }, + "timestamp": "2025-10-29T16:45:36.132566" + } +} \ No newline at end of file diff --git a/modules/nf-core/vembrane/table/tests/nextflow.config b/modules/nf-core/vembrane/table/tests/nextflow.config new file mode 100644 index 00000000000..77acb7b7741 --- /dev/null +++ b/modules/nf-core/vembrane/table/tests/nextflow.config @@ -0,0 +1,5 @@ +process { + withName: 'VEMBRANE_TABLE' { + ext.args = params.vembrane_args ?: '' + } +} \ No newline at end of file