diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4b6f1b63..07826b80 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,7 +47,8 @@ jobs: - "bam_variant_calling_qdnaseq" - "bam_variant_calling_smoove" - "bam_variant_calling_wisecondorx" - - "vcf_annotate_vep_annotsv_vcfanno" + - "vcf_annotate_vep_annotsv" + - "vcf_annotate_vcfanno" - "vcf_concat_bcftools" - "vcf_merge_callers_jasmine" - "vcf_merge_family_jasmine" diff --git a/CHANGELOG.md b/CHANGELOG.md index ed108722..7ee8a6aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 5. Fixed language server errors 6. Removed the old output publishing code and used the new workflow output definitions instead 7. Bumped the minimal nextflow version to 24.10.0 +8. VCFanno will now run when `--vcfanno_toml` has been given and `--annotate` has not been given. You still need to supply `--annotate` to get the full annotation, but this can be used check for common variants without having to perform full annotation. ### `Fixed` diff --git a/conf/modules.config b/conf/modules.config index 1c27d93e..21b006b8 100644 --- a/conf/modules.config +++ b/conf/modules.config @@ -197,12 +197,12 @@ process { ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ - withName: "^.*VCF_ANNOTATE_VEP_ANNOTSV_VCFANNO:BCFTOOLS_FILTER\$" { + withName: "^.*VCF_ANNOTATE_VEP_ANNOTSV:BCFTOOLS_FILTER\$" { ext.prefix = {"${meta.id}.filter"} ext.args = "-e 'GT=\"ref\"' --output-type z" } - withName: "^.*VCF_ANNOTATE_VEP_ANNOTSV_VCFANNO:ANNOTSV_ANNOTSV\$" { + withName: "^.*VCF_ANNOTATE_VEP_ANNOTSV:ANNOTSV_ANNOTSV\$" { ext.args = {[ "-SVminSize 20", "-vcf 1", @@ -211,12 +211,12 @@ process { ext.prefix = {"${meta.id}.annot"} } - withName: "^.*VCF_ANNOTATE_VEP_ANNOTSV_VCFANNO:BCFTOOLS_CONCAT\$" { + withName: "^.*VCF_ANNOTATE_VEP_ANNOTSV:BCFTOOLS_CONCAT\$" { ext.prefix = "annotsv_annotated" ext.args = "--output-type z --naive-force" } - withName: "^.*VCF_ANNOTATE_VEP_ANNOTSV_VCFANNO:ENSEMBLVEP_VEP\$" { + withName: "^.*VCF_ANNOTATE_VEP_ANNOTSV:ENSEMBLVEP_VEP\$" { ext.prefix = {"${meta.id}.vep"} ext.args = {[ // specify we use VCF files @@ -240,17 +240,14 @@ process { ].join(' ').trim()} } - withName: "^.*VCF_ANNOTATE_VEP_ANNOTSV_VCFANNO:VCFANNO\$" { + withName: "^.*VCF_ANNOTATE_VCFANNO:VCFANNO\$" { + ext.prefix = {"${meta.id}.${meta.variant_type}.vcfanno"} ext.args = "-permissive-overlap -ends" } - withName: "^.*VCF_ANNOTATE_VEP_ANNOTSV_VCFANNO:TABIX_ANNOTATED\$" { - ext.prefix = { "${meta.id}.${meta.variant_type}.annotated" } - } - - withName: "^.*VCF_ANNOTATE_VEP_ANNOTSV_VCFANNO:BCFTOOLS_FILTER_COMMON\$" { - ext.prefix = {"${meta.id}.${meta.variant_type}.annotated"} - ext.args = "${params.annotations_filter} --output-type z" + withName: "^.*VCF_ANNOTATE_VCFANNO:BCFTOOLS_FILTER\$" { + ext.prefix = {"${meta.id}.${meta.variant_type}.filtered"} + ext.args = "${params.annotations_filter} --output-type z --write-index=tbi" } /* diff --git a/modules.json b/modules.json index f4ed7109..734bcbc2 100644 --- a/modules.json +++ b/modules.json @@ -28,9 +28,8 @@ }, "bcftools/filter": { "branch": "master", - "git_sha": "a3893076a76e91b3ff152faddf872f00778fb224", - "installed_by": ["modules"], - "patch": "modules/nf-core/bcftools/filter/bcftools-filter.diff" + "git_sha": "81880787133db07d9b4c1febd152c090eb8325dc", + "installed_by": ["modules"] }, "bcftools/sort": { "branch": "master", @@ -152,8 +151,9 @@ }, "vcfanno": { "branch": "master", - "git_sha": "b558cd24f8751dcda51f957391f5f9cb83e28586", - "installed_by": ["modules"] + "git_sha": "81880787133db07d9b4c1febd152c090eb8325dc", + "installed_by": ["modules"], + "patch": "modules/nf-core/vcfanno/vcfanno.diff" }, "wisecondorx/convert": { "branch": "master", diff --git a/modules/nf-core/bcftools/filter/environment.yml b/modules/nf-core/bcftools/filter/environment.yml index b2698757..b276efd9 100644 --- a/modules/nf-core/bcftools/filter/environment.yml +++ b/modules/nf-core/bcftools/filter/environment.yml @@ -1,7 +1,7 @@ -name: bcftools_filter +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda - - defaults dependencies: - - bioconda::bcftools=1.18 + - bioconda::bcftools=1.20 diff --git a/modules/nf-core/bcftools/filter/main.nf b/modules/nf-core/bcftools/filter/main.nf index cc9a2361..36cbf8c2 100644 --- a/modules/nf-core/bcftools/filter/main.nf +++ b/modules/nf-core/bcftools/filter/main.nf @@ -4,14 +4,16 @@ process BCFTOOLS_FILTER { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/bcftools:1.18--h8b25389_0': - 'biocontainers/bcftools:1.18--h8b25389_0' }" + 'https://depot.galaxyproject.org/singularity/bcftools:1.20--h8b25389_0': + 'biocontainers/bcftools:1.20--h8b25389_0' }" input: - tuple val(meta), path(vcf) + tuple val(meta), path(vcf), path(tbi) output: tuple val(meta), path("*.${extension}"), emit: vcf + tuple val(meta), path("*.tbi") , emit: tbi, optional: true + tuple val(meta), path("*.csi") , emit: csi, optional: true path "versions.yml" , emit: versions when: @@ -45,19 +47,23 @@ process BCFTOOLS_FILTER { stub: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - extension = args.contains("--output-type b") || args.contains("-Ob") ? "bcf.gz" : args.contains("--output-type u") || args.contains("-Ou") ? "bcf" : args.contains("--output-type z") || args.contains("-Oz") ? "vcf.gz" : args.contains("--output-type v") || args.contains("-Ov") ? "vcf" : "vcf" + def index = args.contains("--write-index=tbi") || args.contains("-W=tbi") ? "tbi" : + args.contains("--write-index=csi") || args.contains("-W=csi") ? "csi" : + args.contains("--write-index") || args.contains("-W") ? "csi" : + "" + def create_cmd = extension.endsWith(".gz") ? "echo '' | gzip >" : "touch" + def create_index = extension.endsWith(".gz") && index.matches("csi|tbi") ? "touch ${prefix}.${extension}.${index}" : "" if ("$vcf" == "${prefix}.${extension}") error "Input and output names are the same, set prefix in module configuration to disambiguate!" - def create_file = extension.endsWith(".gz") ? "echo '' | gzip > ${prefix}.${extension}" : "touch ${prefix}.${extension}" - """ - ${create_file} + ${create_cmd} ${prefix}.${extension} + ${create_index} cat <<-END_VERSIONS > versions.yml "${task.process}": diff --git a/modules/nf-core/bcftools/filter/meta.yml b/modules/nf-core/bcftools/filter/meta.yml index deb93b13..d72f2755 100644 --- a/modules/nf-core/bcftools/filter/meta.yml +++ b/modules/nf-core/bcftools/filter/meta.yml @@ -12,30 +12,57 @@ tools: documentation: http://www.htslib.org/doc/bcftools.html doi: 10.1093/bioinformatics/btp352 licence: ["MIT"] + identifier: biotools:bcftools input: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - vcf: - type: file - description: VCF input file - pattern: "*.{vcf,bcf,vcf.gz,bcf.gz}" + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - vcf: + type: file + description: VCF input file + pattern: "*.{vcf,bcf,vcf.gz,bcf.gz}" + - tbi: + type: file + description: VCF index file + pattern: "*.tbi" output: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - vcf: - type: file - description: VCF filtered output file - pattern: "*.{vcf,bcf,vcf.gz,bcf.gz}" + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.${extension}": + type: file + description: VCF filtered output file + pattern: "*.{vcf,bcf,vcf.gz,bcf.gz}" + - tbi: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.tbi": + type: file + description: Alternative VCF file index + pattern: "*.tbi" + - csi: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.csi": + type: file + description: Default VCF file index + pattern: "*.csi" - versions: - type: file - description: File containing software versions - pattern: "versions.yml" + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" authors: - "@joseespinosa" - "@drpatelh" diff --git a/modules/nf-core/bcftools/filter/tests/main.nf.test b/modules/nf-core/bcftools/filter/tests/main.nf.test index eaf100e8..fadff0e3 100644 --- a/modules/nf-core/bcftools/filter/tests/main.nf.test +++ b/modules/nf-core/bcftools/filter/tests/main.nf.test @@ -9,16 +9,17 @@ nextflow_process { tag "bcftools" tag "bcftools/filter" - config "./nextflow.config" - test("sarscov2 - vcf") { + config "./nextflow.config" + when { process { """ input[0] = [ [id:"vcf_test"], - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf', checkIfExists: true), + [] ] """ } @@ -33,14 +34,110 @@ nextflow_process { } + test("sarscov2 - vcf_gz_index") { + + config "./vcf_gz_index.config" + + when { + process { + """ + input[0] = [ + [id:"vcf_test"], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf', checkIfExists: true), + [] + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + process.out.vcf, + process.out.csi.collect { it.collect { it instanceof Map ? it : file(it).name } }, + process.out.tbi.collect { it.collect { it instanceof Map ? it : file(it).name } }, + process.out.versions + ).match() }, + { assert process.out.csi[0][1].endsWith(".csi") } + ) + } + + } + + test("sarscov2 - vcf_gz_index_csi") { + + config "./vcf_gz_index_csi.config" + + when { + process { + """ + input[0] = [ + [id:"vcf_test"], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf', checkIfExists: true), + [] + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + process.out.vcf, + process.out.csi.collect { it.collect { it instanceof Map ? it : file(it).name } }, + process.out.tbi.collect { it.collect { it instanceof Map ? it : file(it).name } }, + process.out.versions + ).match() }, + { assert process.out.csi[0][1].endsWith(".csi") } + ) + } + + } + + test("sarscov2 - vcf_gz_index_tbi") { + + config "./vcf_gz_index_tbi.config" + + when { + process { + """ + input[0] = [ + [id:"vcf_test"], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf', checkIfExists: true), + [] + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot( + process.out.vcf, + process.out.csi.collect { it.collect { it instanceof Map ? it : file(it).name } }, + process.out.tbi.collect { it.collect { it instanceof Map ? it : file(it).name } }, + process.out.versions + ).match() }, + { assert process.out.tbi[0][1].endsWith(".tbi") } + ) + } + + } + test("sarscov2 - vcf - bcf output") { + config "./nextflow.config" + when { process { """ input[0] = [ [id:"bcf_test"], - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf', checkIfExists: true), + [] ] """ } @@ -55,8 +152,34 @@ nextflow_process { } + test("sarscov2 - vcf.gz, tbi - region filter") { + + config "./region_filter.config" + + when { + process { + """ + input[0] = [ + [id:"bcf_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) + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match("region filter") } + ) + } + + } + test("sarscov2 - vcf - stub") { + config "./nextflow.config" options "-stub" when { @@ -64,7 +187,8 @@ nextflow_process { """ input[0] = [ [id:"vcf_test"], - file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf', checkIfExists: true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf', checkIfExists: true), + [] ] """ } @@ -79,4 +203,85 @@ nextflow_process { } -} + test("sarscov2 - vcf_gz_index - stub") { + + config "./vcf_gz_index.config" + options "-stub" + + when { + process { + """ + input[0] = [ + [id:"vcf_test"], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf', checkIfExists: true), + [] + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() }, + { assert process.out.csi[0][1].endsWith(".csi") } + ) + } + + } + + test("sarscov2 - vcf_gz_index_csi - stub") { + + config "./vcf_gz_index_csi.config" + options "-stub" + + when { + process { + """ + input[0] = [ + [id:"vcf_test"], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf', checkIfExists: true), + [] + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() }, + { assert process.out.csi[0][1].endsWith(".csi") } + ) + } + + } + + test("sarscov2 - vcf_gz_index_tbi - stub") { + + config "./vcf_gz_index_tbi.config" + options "-stub" + + when { + process { + """ + input[0] = [ + [id:"vcf_test"], + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf', checkIfExists: true), + [] + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() }, + { assert process.out.tbi[0][1].endsWith(".tbi") } + ) + } + + } + +} \ No newline at end of file diff --git a/modules/nf-core/bcftools/filter/tests/main.nf.test.snap b/modules/nf-core/bcftools/filter/tests/main.nf.test.snap index f8e17aa0..640907e4 100644 --- a/modules/nf-core/bcftools/filter/tests/main.nf.test.snap +++ b/modules/nf-core/bcftools/filter/tests/main.nf.test.snap @@ -1,4 +1,104 @@ { + "region filter": { + "content": [ + { + "0": [ + [ + { + "id": "bcf_test" + }, + "bcf_test_vcf.vcf.gz:md5,8e722884ffb75155212a3fc053918766" + ] + ], + "1": [ + + ], + "2": [ + + ], + "3": [ + "versions.yml:md5,9a336d1ee26b527d7a2bdbeead155f64" + ], + "csi": [ + + ], + "tbi": [ + + ], + "vcf": [ + [ + { + "id": "bcf_test" + }, + "bcf_test_vcf.vcf.gz:md5,8e722884ffb75155212a3fc053918766" + ] + ], + "versions": [ + "versions.yml:md5,9a336d1ee26b527d7a2bdbeead155f64" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-10-08T09:14:47.394005264" + }, + "sarscov2 - vcf_gz_index_tbi - stub": { + "content": [ + { + "0": [ + [ + { + "id": "vcf_test" + }, + "vcf_test_vcf.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + [ + { + "id": "vcf_test" + }, + "vcf_test_vcf.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + + ], + "3": [ + "versions.yml:md5,9a336d1ee26b527d7a2bdbeead155f64" + ], + "csi": [ + + ], + "tbi": [ + [ + { + "id": "vcf_test" + }, + "vcf_test_vcf.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "vcf": [ + [ + { + "id": "vcf_test" + }, + "vcf_test_vcf.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "versions": [ + "versions.yml:md5,9a336d1ee26b527d7a2bdbeead155f64" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-06-05T13:59:08.235854993" + }, "vcf": { "content": [ { @@ -11,7 +111,19 @@ ] ], "1": [ - "versions.yml:md5,7dc77043f9afb848d942d47a7bc19f67" + + ], + "2": [ + + ], + "3": [ + "versions.yml:md5,9a336d1ee26b527d7a2bdbeead155f64" + ], + "csi": [ + + ], + "tbi": [ + ], "vcf": [ [ @@ -22,15 +134,15 @@ ] ], "versions": [ - "versions.yml:md5,7dc77043f9afb848d942d47a7bc19f67" + "versions.yml:md5,9a336d1ee26b527d7a2bdbeead155f64" ] } ], "meta": { "nf-test": "0.8.4", - "nextflow": "24.02.0" + "nextflow": "24.04.2" }, - "timestamp": "2024-03-27T16:57:32.940161987" + "timestamp": "2024-06-04T15:20:28.427974818" }, "bcf output": { "content": [ @@ -44,7 +156,19 @@ ] ], "1": [ - "versions.yml:md5,7dc77043f9afb848d942d47a7bc19f67" + + ], + "2": [ + + ], + "3": [ + "versions.yml:md5,9a336d1ee26b527d7a2bdbeead155f64" + ], + "csi": [ + + ], + "tbi": [ + ], "vcf": [ [ @@ -55,15 +179,77 @@ ] ], "versions": [ - "versions.yml:md5,7dc77043f9afb848d942d47a7bc19f67" + "versions.yml:md5,9a336d1ee26b527d7a2bdbeead155f64" ] } ], "meta": { "nf-test": "0.8.4", - "nextflow": "24.02.0" + "nextflow": "24.04.2" + }, + "timestamp": "2024-06-04T15:20:34.049236749" + }, + "sarscov2 - vcf_gz_index": { + "content": [ + [ + [ + { + "id": "vcf_test" + }, + "vcf_test_vcf.vcf.gz:md5,8e722884ffb75155212a3fc053918766" + ] + ], + [ + [ + { + "id": "vcf_test" + }, + "vcf_test_vcf.vcf.gz.csi" + ] + ], + [ + + ], + [ + "versions.yml:md5,9a336d1ee26b527d7a2bdbeead155f64" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-06-05T08:09:49.837854646" + }, + "sarscov2 - vcf_gz_index_csi": { + "content": [ + [ + [ + { + "id": "vcf_test" + }, + "vcf_test_vcf.vcf.gz:md5,8e722884ffb75155212a3fc053918766" + ] + ], + [ + [ + { + "id": "vcf_test" + }, + "vcf_test_vcf.vcf.gz.csi" + ] + ], + [ + + ], + [ + "versions.yml:md5,9a336d1ee26b527d7a2bdbeead155f64" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" }, - "timestamp": "2024-03-27T16:45:14.586866398" + "timestamp": "2024-06-05T13:57:19.513365022" }, "vcf - stub": { "content": [ @@ -77,7 +263,19 @@ ] ], "1": [ - "versions.yml:md5,7dc77043f9afb848d942d47a7bc19f67" + + ], + "2": [ + + ], + "3": [ + "versions.yml:md5,9a336d1ee26b527d7a2bdbeead155f64" + ], + "csi": [ + + ], + "tbi": [ + ], "vcf": [ [ @@ -88,14 +286,155 @@ ] ], "versions": [ - "versions.yml:md5,7dc77043f9afb848d942d47a7bc19f67" + "versions.yml:md5,9a336d1ee26b527d7a2bdbeead155f64" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-06-04T15:29:55.846566153" + }, + "sarscov2 - vcf_gz_index - stub": { + "content": [ + { + "0": [ + [ + { + "id": "vcf_test" + }, + "vcf_test_vcf.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + + ], + "2": [ + [ + { + "id": "vcf_test" + }, + "vcf_test_vcf.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + "versions.yml:md5,9a336d1ee26b527d7a2bdbeead155f64" + ], + "csi": [ + [ + { + "id": "vcf_test" + }, + "vcf_test_vcf.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "tbi": [ + + ], + "vcf": [ + [ + { + "id": "vcf_test" + }, + "vcf_test_vcf.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "versions": [ + "versions.yml:md5,9a336d1ee26b527d7a2bdbeead155f64" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" + }, + "timestamp": "2024-06-04T15:59:37.636874258" + }, + "sarscov2 - vcf_gz_index_csi - stub": { + "content": [ + { + "0": [ + [ + { + "id": "vcf_test" + }, + "vcf_test_vcf.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + + ], + "2": [ + [ + { + "id": "vcf_test" + }, + "vcf_test_vcf.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "3": [ + "versions.yml:md5,9a336d1ee26b527d7a2bdbeead155f64" + ], + "csi": [ + [ + { + "id": "vcf_test" + }, + "vcf_test_vcf.vcf.gz.csi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "tbi": [ + + ], + "vcf": [ + [ + { + "id": "vcf_test" + }, + "vcf_test_vcf.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "versions": [ + "versions.yml:md5,9a336d1ee26b527d7a2bdbeead155f64" ] } ], "meta": { "nf-test": "0.8.4", - "nextflow": "24.02.0" + "nextflow": "24.04.2" + }, + "timestamp": "2024-06-05T13:58:46.36278584" + }, + "sarscov2 - vcf_gz_index_tbi": { + "content": [ + [ + [ + { + "id": "vcf_test" + }, + "vcf_test_vcf.vcf.gz:md5,8e722884ffb75155212a3fc053918766" + ] + ], + [ + + ], + [ + [ + { + "id": "vcf_test" + }, + "vcf_test_vcf.vcf.gz.tbi" + ] + ], + [ + "versions.yml:md5,9a336d1ee26b527d7a2bdbeead155f64" + ] + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.2" }, - "timestamp": "2024-03-27T17:05:52.80837892" + "timestamp": "2024-06-05T13:57:34.748836577" } } \ No newline at end of file diff --git a/modules/nf-core/bcftools/filter/tests/region_filter.config b/modules/nf-core/bcftools/filter/tests/region_filter.config new file mode 100644 index 00000000..b18fb4bf --- /dev/null +++ b/modules/nf-core/bcftools/filter/tests/region_filter.config @@ -0,0 +1,4 @@ +process { + ext.prefix = { "${meta.id}_vcf" } + ext.args = "--output-type z -r MT192765.1 --no-version" +} diff --git a/modules/nf-core/bcftools/filter/tests/vcf_gz_index.config b/modules/nf-core/bcftools/filter/tests/vcf_gz_index.config new file mode 100644 index 00000000..7dd696ee --- /dev/null +++ b/modules/nf-core/bcftools/filter/tests/vcf_gz_index.config @@ -0,0 +1,4 @@ +process { + ext.prefix = { "${meta.id}_vcf" } + ext.args = "--output-type z --write-index --no-version" +} diff --git a/modules/nf-core/bcftools/filter/tests/vcf_gz_index_csi.config b/modules/nf-core/bcftools/filter/tests/vcf_gz_index_csi.config new file mode 100644 index 00000000..aebffb6f --- /dev/null +++ b/modules/nf-core/bcftools/filter/tests/vcf_gz_index_csi.config @@ -0,0 +1,4 @@ +process { + ext.prefix = { "${meta.id}_vcf" } + ext.args = "--output-type z --write-index=csi --no-version" +} diff --git a/modules/nf-core/bcftools/filter/tests/vcf_gz_index_tbi.config b/modules/nf-core/bcftools/filter/tests/vcf_gz_index_tbi.config new file mode 100644 index 00000000..b192ae7d --- /dev/null +++ b/modules/nf-core/bcftools/filter/tests/vcf_gz_index_tbi.config @@ -0,0 +1,4 @@ +process { + ext.prefix = { "${meta.id}_vcf" } + ext.args = "--output-type z --write-index=tbi --no-version" +} diff --git a/modules/nf-core/vcfanno/environment.yml b/modules/nf-core/vcfanno/environment.yml index f336cc6b..f780d24d 100644 --- a/modules/nf-core/vcfanno/environment.yml +++ b/modules/nf-core/vcfanno/environment.yml @@ -1,7 +1,9 @@ -name: vcfanno +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json channels: - conda-forge - bioconda - - defaults + dependencies: + - bioconda::htslib=1.21 - bioconda::vcfanno=0.3.5 diff --git a/modules/nf-core/vcfanno/main.nf b/modules/nf-core/vcfanno/main.nf index 25c131b1..ecd57a6d 100644 --- a/modules/nf-core/vcfanno/main.nf +++ b/modules/nf-core/vcfanno/main.nf @@ -4,8 +4,8 @@ process VCFANNO { conda "${moduleDir}/environment.yml" container "${ workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container ? - 'https://depot.galaxyproject.org/singularity/vcfanno:0.3.5--h9ee0642_0': - 'biocontainers/vcfanno:0.3.5--h9ee0642_0' }" + 'https://community-cr-prod.seqera.io/docker/registry/v2/blobs/sha256/d6/d6a1af15acc0fbec648812e07ccb4c1c39a926f3a98031a50f51c5b859e543e1/data': + 'community.wave.seqera.io/library/htslib_vcfanno:398cde9953538855' }" input: tuple val(meta), path(vcf), path(tbi), path(specific_resources) @@ -14,15 +14,18 @@ process VCFANNO { path resources output: - tuple val(meta), path("*.vcf") , emit: vcf - path "versions.yml" , emit: versions + tuple val(meta), path("*.vcf.gz") , emit: vcf + tuple val(meta), path("*.vcf.gz.tbi") , emit: tbi + 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}" + def args = task.ext.args ?: '' + def args2 = task.ext.args2 ?: '' + def args3 = task.ext.args3 ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" def lua_cmd = lua ? "--lua ${lua}" : "" """ vcfanno \\ @@ -31,7 +34,9 @@ process VCFANNO { ${lua_cmd} \\ ${toml} \\ ${vcf} \\ - > ${prefix}.vcf + | bgzip ${args2} --threads ${task.cpus} \\ + > ${prefix}.vcf.gz \\ + && tabix ${args3} ${prefix}.vcf.gz cat <<-END_VERSIONS > versions.yml "${task.process}": @@ -42,7 +47,8 @@ process VCFANNO { stub: def prefix = task.ext.prefix ?: "${meta.id}" """ - touch ${prefix}.vcf + echo "" | bgzip > ${prefix}.vcf.gz + touch ${prefix}.vcf.gz.tbi cat <<-END_VERSIONS > versions.yml "${task.process}": diff --git a/modules/nf-core/vcfanno/meta.yml b/modules/nf-core/vcfanno/meta.yml index 89c781ad..2f5b3add 100644 --- a/modules/nf-core/vcfanno/meta.yml +++ b/modules/nf-core/vcfanno/meta.yml @@ -1,5 +1,6 @@ name: vcfanno -description: quickly annotate your VCF with any number of INFO fields from any number of VCFs or BED files +description: quickly annotate your VCF with any number of INFO fields from any number + of VCFs or BED files keywords: - vcf - bed @@ -14,51 +15,74 @@ tools: tool_dev_url: https://github.com/brentp/vcfanno doi: "10.1186/s13059-016-0973-5" license: ["MIT"] + identifier: biotools:vcfanno input: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - vcf: - type: file - description: query VCF file - pattern: "*.{vcf, vcf.gz}" - - vcf_tabix: - type: file - description: tabix index of query VCF - only needed if vcf is compressed - pattern: "*.vcf.gz.tbi" - - specific_resources: - type: map - description: A list of sample specific reference files defined in toml config, must also include indices if bgzipped. - - toml: - type: file - description: configuration file with reference file basenames - pattern: "*.toml" - - lua: - type: file - description: Lua file for custom annotations - pattern: "*.lua" - - resources: - type: map - description: List of reference files defined in toml config, must also include indices if bgzipped. + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - vcf: + type: file + description: query VCF file + pattern: "*.{vcf, vcf.gz}" + - tbi: + type: file + description: tabix index file for the query VCF + pattern: "*.tbi" + - specific_resources: + type: map + description: A list of sample specific reference files defined in toml config, + must also include indices if bgzipped. + - - toml: + type: file + description: configuration file with reference file basenames + pattern: "*.toml" + - - lua: + type: file + description: Lua file for custom annotations + pattern: "*.lua" + - - resources: + type: map + description: List of reference files defined in toml config, must also include + indices if bgzipped. output: - - meta: - type: map - description: | - Groovy Map containing sample information - e.g. [ id:'test', single_end:false ] - - versions: - type: file - description: File containing software versions - pattern: "versions.yml" - vcf: - type: file - description: Annotated VCF file - pattern: "*.vcf" + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + pattern: "*.vcf.gz" + - "*.vcf.gz": + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + pattern: "*.vcf.gz" + - tbi: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + pattern: "*.vcf.gz.tbi" + - "*.vcf.gz.tbi": + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + pattern: "*.vcf.gz.tbi" + - versions: + - versions.yml: + type: file + description: File containing software versions + pattern: "versions.yml" authors: - "@projectoriented" - "@matthdsm" + - "@nvnieuwk" maintainers: - "@projectoriented" - "@matthdsm" + - "@nvnieuwk" diff --git a/modules/nf-core/vcfanno/tests/main.nf.test b/modules/nf-core/vcfanno/tests/main.nf.test index b28431b2..8bbcfd89 100644 --- a/modules/nf-core/vcfanno/tests/main.nf.test +++ b/modules/nf-core/vcfanno/tests/main.nf.test @@ -15,11 +15,11 @@ nextflow_process { """ input[0] = [ [ id:'test_compressed', single_end:false ], // meta map - file(params.test_data['sarscov2']['illumina']['test_vcf_gz'], checkIfExists: true), - file(params.test_data['sarscov2']['illumina']['test_vcf_gz_tbi'], checkIfExists: true), - file(params.test_data['sarscov2']['illumina']['test2_vcf'], checkIfExists:true) + 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), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf', checkIfExists: true) ] - input[1] = file(params.test_data['homo_sapiens']['genome']['vcfanno_toml'], checkIfExists: true) + input[1] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/vcf/vcfanno/vcfanno.toml', checkIfExists: true) input[2] = [] input[3] = [ file("https://github.com/brentp/vcfanno/raw/master/example/exac.vcf.gz", checkIfExists: true), @@ -45,11 +45,11 @@ nextflow_process { """ input[0] = [ [ id:'test_uncompressed', single_end:false ], // meta map - file(params.test_data['sarscov2']['illumina']['test_vcf'], checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test.vcf', checkIfExists: true), [], - file(params.test_data['sarscov2']['illumina']['test2_vcf'], checkIfExists:true) + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf', checkIfExists: true) ] - input[1] = file(params.test_data['homo_sapiens']['genome']['vcfanno_toml'], checkIfExists: true) + input[1] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/vcf/vcfanno/vcfanno.toml', checkIfExists: true) input[2] = [] input[3] = [ file("https://github.com/brentp/vcfanno/raw/master/example/exac.vcf.gz", checkIfExists: true), @@ -77,11 +77,11 @@ nextflow_process { """ input[0] = [ [ id:'test_compressed', single_end:false ], // meta map - file(params.test_data['sarscov2']['illumina']['test_vcf_gz'], checkIfExists: true), - file(params.test_data['sarscov2']['illumina']['test_vcf_gz_tbi'], checkIfExists: true), - file(params.test_data['sarscov2']['illumina']['test2_vcf'], checkIfExists:true) + 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), + file(params.modules_testdata_base_path + 'genomics/sarscov2/illumina/vcf/test2.vcf', checkIfExists: true) ] - input[1] = file(params.test_data['homo_sapiens']['genome']['vcfanno_toml'], checkIfExists: true) + input[1] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/vcf/vcfanno/vcfanno.toml', checkIfExists: true) input[2] = [] input[3] = [ file("https://github.com/brentp/vcfanno/raw/master/example/exac.vcf.gz", checkIfExists: true), diff --git a/modules/nf-core/vcfanno/tests/main.nf.test.snap b/modules/nf-core/vcfanno/tests/main.nf.test.snap index 7e5f737c..ca4d76d2 100644 --- a/modules/nf-core/vcfanno/tests/main.nf.test.snap +++ b/modules/nf-core/vcfanno/tests/main.nf.test.snap @@ -1,12 +1,16 @@ { "sarscov2 - [vcf(gz), tbi, vcf], [], toml, [vcf, tbi] - stub": { "content": [ - "test_compressed.vcf", + "test_compressed.vcf.gz", [ "versions.yml:md5,5ff0991b612706ce15d82eb1564513b0" ] ], - "timestamp": "2023-12-06T12:18:25.69588598" + "meta": { + "nf-test": "0.9.1", + "nextflow": "24.10.3" + }, + "timestamp": "2025-01-23T14:03:21.974046858" }, "sarscov2 - [vcf(gz), tbi, vcf], [], toml, [vcf, tbi]": { "content": [ @@ -17,19 +21,37 @@ "id": "test_compressed", "single_end": false }, - "test_compressed.vcf:md5,d3cf5a6eaf6cca5b957833a313c5fbf4" + "test_compressed.vcf.gz:md5,d3cf5a6eaf6cca5b957833a313c5fbf4" ] ], "1": [ + [ + { + "id": "test_compressed", + "single_end": false + }, + "test_compressed.vcf.gz.tbi:md5,67a4272d5897fea5cc395dc87afc3629" + ] + ], + "2": [ "versions.yml:md5,5ff0991b612706ce15d82eb1564513b0" ], + "tbi": [ + [ + { + "id": "test_compressed", + "single_end": false + }, + "test_compressed.vcf.gz.tbi:md5,67a4272d5897fea5cc395dc87afc3629" + ] + ], "vcf": [ [ { "id": "test_compressed", "single_end": false }, - "test_compressed.vcf:md5,d3cf5a6eaf6cca5b957833a313c5fbf4" + "test_compressed.vcf.gz:md5,d3cf5a6eaf6cca5b957833a313c5fbf4" ] ], "versions": [ @@ -37,7 +59,11 @@ ] } ], - "timestamp": "2023-12-06T12:21:13.209704154" + "meta": { + "nf-test": "0.9.1", + "nextflow": "24.10.3" + }, + "timestamp": "2025-01-23T14:04:38.599392384" }, "sarscov2 - [vcf, [], vcf], [], toml, [vcf, tbi]": { "content": [ @@ -48,19 +74,37 @@ "id": "test_uncompressed", "single_end": false }, - "test_uncompressed.vcf:md5,d3cf5a6eaf6cca5b957833a313c5fbf4" + "test_uncompressed.vcf.gz:md5,d3cf5a6eaf6cca5b957833a313c5fbf4" ] ], "1": [ + [ + { + "id": "test_uncompressed", + "single_end": false + }, + "test_uncompressed.vcf.gz.tbi:md5,67a4272d5897fea5cc395dc87afc3629" + ] + ], + "2": [ "versions.yml:md5,5ff0991b612706ce15d82eb1564513b0" ], + "tbi": [ + [ + { + "id": "test_uncompressed", + "single_end": false + }, + "test_uncompressed.vcf.gz.tbi:md5,67a4272d5897fea5cc395dc87afc3629" + ] + ], "vcf": [ [ { "id": "test_uncompressed", "single_end": false }, - "test_uncompressed.vcf:md5,d3cf5a6eaf6cca5b957833a313c5fbf4" + "test_uncompressed.vcf.gz:md5,d3cf5a6eaf6cca5b957833a313c5fbf4" ] ], "versions": [ @@ -68,6 +112,10 @@ ] } ], - "timestamp": "2023-12-06T12:21:19.255212216" + "meta": { + "nf-test": "0.9.1", + "nextflow": "24.10.3" + }, + "timestamp": "2025-01-23T14:04:48.104846161" } } \ No newline at end of file diff --git a/modules/nf-core/vcfanno/vcfanno.diff b/modules/nf-core/vcfanno/vcfanno.diff new file mode 100644 index 00000000..bc9f90e9 --- /dev/null +++ b/modules/nf-core/vcfanno/vcfanno.diff @@ -0,0 +1,21 @@ +Changes in component 'nf-core/vcfanno' +Changes in 'vcfanno/main.nf': +--- modules/nf-core/vcfanno/main.nf ++++ modules/nf-core/vcfanno/main.nf +@@ -47,7 +47,7 @@ + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ +- touch ${prefix}.vcf.gz ++ echo "" > ${prefix}.vcf.gz + touch ${prefix}.vcf.gz.tbi + + cat <<-END_VERSIONS > versions.yml + +'modules/nf-core/vcfanno/environment.yml' is unchanged +'modules/nf-core/vcfanno/meta.yml' is unchanged +'modules/nf-core/vcfanno/tests/tags.yml' is unchanged +'modules/nf-core/vcfanno/tests/main.nf.test' is unchanged +'modules/nf-core/vcfanno/tests/main.nf.test.snap' is unchanged +'modules/nf-core/vcfanno/tests/nextflow.config' is unchanged +************************************************************ diff --git a/subworkflows/local/vcf_annotate_vcfanno/main.nf b/subworkflows/local/vcf_annotate_vcfanno/main.nf new file mode 100644 index 00000000..e3e40306 --- /dev/null +++ b/subworkflows/local/vcf_annotate_vcfanno/main.nf @@ -0,0 +1,130 @@ +// +// Annotate the VCFs +// + +include { VCFANNO } from '../../../modules/nf-core/vcfanno/main' +include { BCFTOOLS_FILTER } from '../../../modules/nf-core/bcftools/filter/main' + +workflow VCF_ANNOTATE_VCFANNO { + take: + ch_vcfs // channel: [mandatory] [ val(meta), path(vcf), path(tbi) ] VCFs containing the called structural variants + ch_sample_specific_resources // channel: [optional] [ val(meta), path(vcf), path(tbi) ] Files containing resources that are sample-specific + ch_vcfanno_lua // channel: [optional] [ path(lua) ] => The lua script to influence VCFanno + val_vcfanno_resources // list: [optional] [ path(file1, file2, file3...) ] => The extra VCFanno files + filter // string: [optional] => A filter pattern to use after annotating + vcfanno_toml // file: [optional] => A vcfanno TOML config + default_vcfanno_tomls // list: [mandatory] => A list of default vcfanno configs to be concatenated with the input TOML + annotate // boolean: [mandatory] => Whether or not to run the full annotation or only the specified annotations + + main: + + def ch_versions = Channel.empty() + + def ch_vcfanno_toml = Channel.empty() + def ch_vcfanno_input = Channel.empty() + if(annotate) { + ch_vcfanno_toml = Channel.fromList(create_vcfanno_toml(val_vcfanno_resources, vcfanno_toml, default_vcfanno_tomls)) + .collectFile(name:"vcfanno.toml", newLine:true) + .collect() + def ch_collected_specific_resources = ch_sample_specific_resources.map { entry -> + [ entry[0], entry[1..-1].findAll { res_file -> res_file != [] } ] + } + ch_vcfanno_input = ch_vcfs.join(ch_collected_specific_resources, failOnMismatch:true, failOnDuplicate:true) + } else { + ch_vcfanno_toml = Channel.fromPath(vcfanno_toml) + ch_vcfanno_input = ch_vcfs.map { meta, vcf, tbi -> + [ meta, vcf, tbi, [] ] + } + } + + VCFANNO( + ch_vcfanno_input, + ch_vcfanno_toml, + ch_vcfanno_lua, + val_vcfanno_resources ? Channel.fromList(val_vcfanno_resources).collect() : [] + ) + ch_versions = ch_versions.mix(VCFANNO.out.versions) + + def ch_vcfanno_output = VCFANNO.out.vcf.join(VCFANNO.out.tbi, failOnDuplicate:true, failOnMismatch:true) + + def ch_annotated_vcfs = Channel.empty() + if(filter) { + BCFTOOLS_FILTER( + ch_vcfanno_output + ) + ch_versions = ch_versions.mix(BCFTOOLS_FILTER.out.versions.first()) + + ch_annotated_vcfs = BCFTOOLS_FILTER.out.vcf.join(BCFTOOLS_FILTER.out.tbi, failOnDuplicate:true, failOnMismatch:true) + } else { + ch_annotated_vcfs = ch_vcfanno_output + } + + emit: + vcfs = ch_annotated_vcfs // channel: [ val(meta), path(vcf), path(tbi) ] + + versions = ch_versions +} + +def create_vcfanno_toml(vcfanno_resources, input_vcfanno_toml, List vcfanno_defaults) { + def vcfanno_toml = input_vcfanno_toml ? parse_toml(input_vcfanno_toml) : [:] + def default_tomls = parse_toml(vcfanno_defaults) + def resources = vcfanno_resources.collect { Path resource -> resource.fileName.toString() } + resources.add("annotsv_annotated.vcf.gz" as String) + def output = [] + resources.each { file_name -> + if (vcfanno_toml.containsKey(file_name)){ + output.add(vcfanno_toml[file_name]) + } + else if (default_tomls.containsKey(file_name)){ + output.add(default_tomls[file_name]) + } + } + def postannotation = vcfanno_toml.postannotation != [] ? vcfanno_toml.postannotation : default_tomls.postannotation + if (postannotation != []){ + output.add(postannotation) + } + return output.flatten() +} + +def parse_toml(tomls) { + def output = [:] + output.postannotation = [] + def toml_list = tomls instanceof List ? tomls : [tomls] + toml_list.each { toml -> + def info = "" + def file = "" + def fields = [] + toml.readLines().each { line -> + if (line.startsWith("#")) { return } + if (line == "[[annotation]]" || line == "[[postannotation]]") { + if (info.startsWith("[[postannotation]]")) { + output.postannotation.add(create_toml_config(fields)) + } + else if(info != "") { + output[file] = create_toml_config(fields) + } + if (info != "") { + info = "" + file = "" + fields = [] + } + info = line + } + else if (line.startsWith("file")) { + file = line.split("\"")[-1] + } + fields.add(line) + } + if (info.startsWith("[[postannotation]]")) { + output.postannotation.add(create_toml_config(fields)) + } else { + output[file] = create_toml_config(fields) + } + } + return output +} + +def create_toml_config(fields_list) { + def config = fields_list.findAll { field -> field != "" }.join("\n") + return "${config}\n" +} diff --git a/subworkflows/local/vcf_annotate_vep_annotsv_vcfanno/main.nf b/subworkflows/local/vcf_annotate_vep_annotsv/main.nf similarity index 54% rename from subworkflows/local/vcf_annotate_vep_annotsv_vcfanno/main.nf rename to subworkflows/local/vcf_annotate_vep_annotsv/main.nf index 9e06a973..cc24bd79 100644 --- a/subworkflows/local/vcf_annotate_vep_annotsv_vcfanno/main.nf +++ b/subworkflows/local/vcf_annotate_vep_annotsv/main.nf @@ -7,16 +7,12 @@ include { BCFTOOLS_CONSENSUS_REHEADER } from '../../../modules/loc include { ANNOTSV_ANNOTSV } from '../../../modules/nf-core/annotsv/annotsv/main' include { ENSEMBLVEP_VEP } from '../../../modules/nf-core/ensemblvep/vep/main' -include { VCFANNO } from '../../../modules/nf-core/vcfanno/main' -include { TABIX_BGZIPTABIX as TABIX_ANNOTATED } from '../../../modules/nf-core/tabix/bgziptabix/main' include { TABIX_TABIX as TABIX_ANNOTSV } from '../../../modules/nf-core/tabix/tabix/main' include { TABIX_TABIX as TABIX_VEP } from '../../../modules/nf-core/tabix/tabix/main' include { BCFTOOLS_FILTER } from '../../../modules/nf-core/bcftools/filter/main' -include { BCFTOOLS_FILTER as BCFTOOLS_FILTER_COMMON } from '../../../modules/nf-core/bcftools/filter/main' include { BCFTOOLS_CONCAT } from '../../../modules/nf-core/bcftools/concat/main' -include { TABIX_TABIX as TABIX_FILTER } from '../../../modules/nf-core/tabix/tabix/main' -workflow VCF_ANNOTATE_VEP_ANNOTSV_VCFANNO { +workflow VCF_ANNOTATE_VEP_ANNOTSV { take: ch_vcfs // channel: [mandatory] [ val(meta), path(vcf), path(tbi) ] VCFs containing the called structural variants ch_small_variants // channel: [mandatory] [ val(meta), path(vcf) ] VCFs containing small variants used in AnnotSV @@ -26,15 +22,10 @@ workflow VCF_ANNOTATE_VEP_ANNOTSV_VCFANNO { ch_annotsv_gene_transcripts // channel: [optional] [ val(meta), path(gene_transcripts) ] ch_vep_cache // channel: [optional] [ path(cache) ] => The path to the local VEP cache ch_vep_extra_files // channel: [optional] [ path(file1, file2, file3...) ] => The VEP extra files - ch_vcfanno_lua // channel: [optional] [ path(lua) ] => The lua script to influence VCFanno - val_vcfanno_resources // list: [optional] [ path(file1, file2, file3...) ] => The extra VCFanno files val_variant_types // list: [mandatory] => The variant types genome // string: [mandatory] => The genome used by the variant callers species // string: [mandatory] => The species used by VEP vep_cache_version // integer: [mandatory] => The VEP cache version to use - filter // string: [optional] => A filter pattern to use after annotating - vcfanno_toml // file: [optional] => A vcfanno TOML config - default_vcfanno_tomls // list: [mandatory] => A list of default vcfanno configs to be concatenated with the input TOML main: @@ -44,7 +35,7 @@ workflow VCF_ANNOTATE_VEP_ANNOTSV_VCFANNO { // Run AnnotSV and VEP in parallel and merge TSV from AnnotSV with VCF from VEP during VCFanno BCFTOOLS_FILTER( - ch_vcfs.map { meta, vcf, _tbi -> [ meta, vcf ]} + ch_vcfs ) ch_versions = ch_versions.mix(BCFTOOLS_FILTER.out.versions.first()) @@ -120,9 +111,6 @@ workflow VCF_ANNOTATE_VEP_ANNOTSV_VCFANNO { def ch_annotsv_output = BCFTOOLS_CONCAT.out.vcf .join(TABIX_ANNOTSV.out.tbi, failOnDuplicate:true, failOnMismatch:true) - .map { meta, vcf, tbi -> - [ meta, [vcf, tbi] ] - } ENSEMBLVEP_VEP( ch_vcfs, @@ -144,113 +132,10 @@ workflow VCF_ANNOTATE_VEP_ANNOTSV_VCFANNO { def ch_vep_output = ENSEMBLVEP_VEP.out.vcf .join(TABIX_VEP.out.tbi, failOnDuplicate:true, failOnMismatch:true) - def ch_vcfanno_input = CustomChannelOperators.joinOnKeys( - ch_vep_output, - ch_annotsv_output, - ['id', 'sample', 'sex', 'family', 'family_count', 'variant_type'] - ) - - def ch_vcfanno_toml = Channel.fromList(create_vcfanno_toml(val_vcfanno_resources, vcfanno_toml, default_vcfanno_tomls)) - .collectFile(name:"vcfanno.toml", newLine:true) - .collect() - - VCFANNO( - ch_vcfanno_input, - ch_vcfanno_toml, - ch_vcfanno_lua, - val_vcfanno_resources ? Channel.fromList(val_vcfanno_resources).collect() : [] - ) - ch_versions = ch_versions.mix(VCFANNO.out.versions) - - def ch_annotated_vcfs = Channel.empty() - if(filter) { - BCFTOOLS_FILTER_COMMON( - VCFANNO.out.vcf - ) - ch_versions = ch_versions.mix(BCFTOOLS_FILTER_COMMON.out.versions.first()) - - TABIX_FILTER( - BCFTOOLS_FILTER_COMMON.out.vcf - ) - ch_versions = ch_versions.mix(TABIX_FILTER.out.versions.first()) - - ch_annotated_vcfs = BCFTOOLS_FILTER_COMMON.out.vcf.join(TABIX_FILTER.out.tbi, failOnDuplicate:true, failOnMismatch:true) - } else { - TABIX_ANNOTATED( - VCFANNO.out.vcf - ) - ch_versions = ch_versions.mix(TABIX_ANNOTATED.out.versions) - - ch_annotated_vcfs = TABIX_ANNOTATED.out.gz_tbi - } - emit: - vcfs = ch_annotated_vcfs // channel: [ val(meta), path(vcf), path(tbi) ] + vep_vcfs = ch_vep_output // channel: [ val(meta), path(vcf), path(tbi) ] + annotsv_vcfs = ch_annotsv_output // channel: [ val(meta), path(vcf), path(tbi) ] reports = ch_reports versions = ch_versions } - -def create_vcfanno_toml(vcfanno_resources, input_vcfanno_toml, List vcfanno_defaults) { - def vcfanno_toml = input_vcfanno_toml ? parse_toml(input_vcfanno_toml) : [:] - def default_tomls = parse_toml(vcfanno_defaults) - def resources = vcfanno_resources.collect { Path resource -> resource.fileName.toString() } - resources.add("annotsv_annotated.vcf.gz" as String) - def output = [] - resources.each { file_name -> - if (vcfanno_toml.containsKey(file_name)){ - output.add(vcfanno_toml[file_name]) - } - else if (default_tomls.containsKey(file_name)){ - output.add(default_tomls[file_name]) - } - } - def postannotation = vcfanno_toml.postannotation != [] ? vcfanno_toml.postannotation : default_tomls.postannotation - if (postannotation != []){ - output.add(postannotation) - } - return output.flatten() -} - -def parse_toml(tomls) { - def output = [:] - output.postannotation = [] - def toml_list = tomls instanceof List ? tomls : [tomls] - toml_list.each { toml -> - def info = "" - def file = "" - def fields = [] - toml.readLines().each { line -> - if (line.startsWith("#")) { return } - if (line == "[[annotation]]" || line == "[[postannotation]]") { - if (info.startsWith("[[postannotation]]")) { - output.postannotation.add(create_toml_config(fields)) - } - else if(info != "") { - output[file] = create_toml_config(fields) - } - if (info != "") { - info = "" - file = "" - fields = [] - } - info = line - } - else if (line.startsWith("file")) { - file = line.split("\"")[-1] - } - fields.add(line) - } - if (info.startsWith("[[postannotation]]")) { - output.postannotation.add(create_toml_config(fields)) - } else { - output[file] = create_toml_config(fields) - } - } - return output -} - -def create_toml_config(fields_list) { - def config = fields_list.findAll { field -> field != "" }.join("\n") - return "${config}\n" -} diff --git a/tests/subworkflows/local/vcf_annotate_vcfanno/main.nf.test b/tests/subworkflows/local/vcf_annotate_vcfanno/main.nf.test new file mode 100644 index 00000000..744385f5 --- /dev/null +++ b/tests/subworkflows/local/vcf_annotate_vcfanno/main.nf.test @@ -0,0 +1,147 @@ +nextflow_workflow { + + name "Test Workflow VCF_ANNOTATE_VCFANNO" + script "subworkflows/local/vcf_annotate_vcfanno/main.nf" + workflow "VCF_ANNOTATE_VCFANNO" + + tag "subworkflows" + tag "subworkflows_local" + tag "vcf_annotate_vcfanno" + + options "-stub" + + test("homo_sapiens - no_filter, annotate") { + + when { + params { + annotations_filter = null + } + workflow { + """ + def meta = [id:"test", sample:"test", sex:"male", family: "test1", family_count:1, hpo:[], variant_type:'sv'] + input[0] = Channel.of([ + meta, + file(params.sv_vcf1, checkIfExists:true), + file(params.sv_tbi1, checkIfExists:true) + ]) + input[1] = Channel.of([ + meta, + [], + [] + ]) + input[2] = [] + input[3] = [] + input[4] = params.annotations_filter + input[5] = [] + input[6] = files("\${params.vcfanno_tomls}/*.toml", checkIfExists:true) + input[7] = true + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.collectEntries { key, value -> + if(key.matches("^\\d+\$") || key.matches('versions')) { + return null + } + return [ key, value ] + }.findAll { it != null } + ).match() } + ) + } + + } + + test("homo_sapiens - filter, no_annotate") { + + when { + params { + annotations_filter = "-i FILTER='PASS'" + } + workflow { + """ + def meta = [id:"test", sample:"test", sex:"male", family: "test1", family_count:1, hpo:[], variant_type:'sv'] + input[0] = Channel.of([ + meta, + file(params.sv_vcf1, checkIfExists:true), + file(params.sv_tbi1, checkIfExists:true) + ]) + input[1] = Channel.of([ + meta, + [], + [] + ]) + input[2] = [] + input[3] = [] + input[4] = params.annotations_filter + input[5] = files("\${params.vcfanno_tomls}/*.toml", checkIfExists:true)[0] + input[6] = files("\${params.vcfanno_tomls}/*.toml", checkIfExists:true) + input[7] = false + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.collectEntries { key, value -> + if(key.matches("^\\d+\$") || key.matches('versions')) { + return null + } + return [ key, value ] + }.findAll { it != null } + ).match() } + ) + } + + } + + test("homo_sapiens - filter, annotate") { + + when { + params { + annotations_filter = null + } + workflow { + """ + def meta = [id:"test", sample:"test", sex:"male", family: "test1", family_count:1, hpo:[], variant_type:'sv'] + input[0] = Channel.of([ + meta, + file(params.sv_vcf1, checkIfExists:true), + file(params.sv_tbi1, checkIfExists:true) + ]) + input[1] = Channel.of([ + meta, + [], + [] + ]) + input[2] = [] + input[3] = [] + input[4] = params.annotations_filter + input[5] = [] + input[6] = files("\${params.vcfanno_tomls}/*.toml", checkIfExists:true) + input[7] = true + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot( + workflow.out.collectEntries { key, value -> + if(key.matches("^\\d+\$") || key.matches('versions')) { + return null + } + return [ key, value ] + }.findAll { it != null } + ).match() } + ) + } + + } +} diff --git a/tests/subworkflows/local/vcf_annotate_vcfanno/main.nf.test.snap b/tests/subworkflows/local/vcf_annotate_vcfanno/main.nf.test.snap new file mode 100644 index 00000000..240fe12a --- /dev/null +++ b/tests/subworkflows/local/vcf_annotate_vcfanno/main.nf.test.snap @@ -0,0 +1,86 @@ +{ + "homo_sapiens - filter, no_annotate": { + "content": [ + { + "vcfs": [ + [ + { + "id": "test", + "sample": "test", + "sex": "male", + "family": "test1", + "family_count": 1, + "hpo": [ + + ], + "variant_type": "sv" + }, + "test.sv.filtered.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test.sv.filtered.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.1", + "nextflow": "24.10.4" + }, + "timestamp": "2025-02-10T16:55:00.763124808" + }, + "homo_sapiens - filter, annotate": { + "content": [ + { + "vcfs": [ + [ + { + "id": "test", + "sample": "test", + "sex": "male", + "family": "test1", + "family_count": 1, + "hpo": [ + + ], + "variant_type": "sv" + }, + "test.sv.vcfanno.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test.sv.vcfanno.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.1", + "nextflow": "24.10.4" + }, + "timestamp": "2025-02-10T16:55:09.970621986" + }, + "homo_sapiens - no_filter, annotate": { + "content": [ + { + "vcfs": [ + [ + { + "id": "test", + "sample": "test", + "sex": "male", + "family": "test1", + "family_count": 1, + "hpo": [ + + ], + "variant_type": "sv" + }, + "test.sv.vcfanno.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test.sv.vcfanno.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.1", + "nextflow": "24.10.4" + }, + "timestamp": "2025-02-10T16:54:50.521405941" + } +} \ No newline at end of file diff --git a/tests/subworkflows/local/vcf_annotate_vep_annotsv_vcfanno/main.nf.test b/tests/subworkflows/local/vcf_annotate_vep_annotsv/main.nf.test similarity index 63% rename from tests/subworkflows/local/vcf_annotate_vep_annotsv_vcfanno/main.nf.test rename to tests/subworkflows/local/vcf_annotate_vep_annotsv/main.nf.test index e4dd44f5..46cf5c93 100644 --- a/tests/subworkflows/local/vcf_annotate_vep_annotsv_vcfanno/main.nf.test +++ b/tests/subworkflows/local/vcf_annotate_vep_annotsv/main.nf.test @@ -1,20 +1,19 @@ nextflow_workflow { - name "Test Workflow VCF_ANNOTATE_VEP_ANNOTSV_VCFANNO" - script "subworkflows/local/vcf_annotate_vep_annotsv_vcfanno/main.nf" - workflow "VCF_ANNOTATE_VEP_ANNOTSV_VCFANNO" + name "Test Workflow VCF_ANNOTATE_VEP_ANNOTSV" + script "subworkflows/local/vcf_annotate_vep_annotsv/main.nf" + workflow "VCF_ANNOTATE_VEP_ANNOTSV" tag "subworkflows" tag "subworkflows_local" - tag "vcf_annotate_vep_annotsv_vcfanno" + tag "vcf_annotate_vep_annotsv" options "-stub" - test("homo_sapiens - sv, no_filter") { + test("homo_sapiens - sv") { when { params { - annotations_filter = null genome = "GRCh38" species = "homo_sapiens" vep_cache_version = 110 @@ -41,15 +40,10 @@ nextflow_workflow { input[5] = [[],[]] input[6] = [] input[7] = [] - input[8] = [] - input[9] = [] - input[10] = ["sv"] - input[11] = params.genome - input[12] = params.species - input[13] = params.vep_cache_version - input[14] = null - input[15] = [] - input[16] = files("\${params.vcfanno_tomls}/*.toml", checkIfExists:true) + input[8] = ["sv"] + input[9] = params.genome + input[10] = params.species + input[11] = params.vep_cache_version """ } } @@ -58,21 +52,22 @@ nextflow_workflow { assertAll( { assert workflow.success }, { assert snapshot( - workflow.out.vcfs.collect { it.collect { it instanceof Map ? it : file(it).name } }, - workflow.out.reports, - workflow.trace.succeeded().size(), - workflow.trace.failed().size() + workflow.out.collectEntries { key, value -> + if(key.matches("^\\d+\$") || key.matches('versions')) { + return null + } + return [ key, value ] + }.findAll { it != null } ).match() } ) } } - test("homo_sapiens - cnv, filter") { + test("homo_sapiens - cnv") { when { params { - annotations_filter = "-i FILTER='PASS'" genome = "GRCh38" species = "homo_sapiens" vep_cache_version = 110 @@ -99,15 +94,10 @@ nextflow_workflow { input[5] = [[],[]] input[6] = [] input[7] = [] - input[8] = [] - input[9] = [] - input[10] = ["cnv"] - input[11] = params.genome - input[12] = params.species - input[13] = params.vep_cache_version - input[14] = params.annotations_filter - input[15] = [] - input[16] = files("\${params.vcfanno_tomls}/*.toml", checkIfExists:true) + input[8] = ["cnv"] + input[9] = params.genome + input[10] = params.species + input[11] = params.vep_cache_version """ } } @@ -116,10 +106,12 @@ nextflow_workflow { assertAll( { assert workflow.success }, { assert snapshot( - workflow.out.vcfs.collect { it.collect { it instanceof Map ? it : file(it).name } }, - workflow.out.reports, - workflow.trace.succeeded().size(), - workflow.trace.failed().size() + workflow.out.collectEntries { key, value -> + if(key.matches("^\\d+\$") || key.matches('versions')) { + return null + } + return [ key, value ] + }.findAll { it != null } ).match() } ) } @@ -130,7 +122,6 @@ nextflow_workflow { when { params { - annotations_filter = null genome = "GRCh38" species = "homo_sapiens" vep_cache_version = 110 @@ -161,15 +152,10 @@ nextflow_workflow { input[5] = [[],[]] input[6] = [] input[7] = [] - input[8] = [] - input[9] = [] - input[10] = ["sv", "cnv"] - input[11] = params.genome - input[12] = params.species - input[13] = params.vep_cache_version - input[14] = null - input[15] = [] - input[16] = files("\${params.vcfanno_tomls}/*.toml", checkIfExists:true) + input[8] = ["sv", "cnv"] + input[9] = params.genome + input[10] = params.species + input[11] = params.vep_cache_version """ } } @@ -178,10 +164,12 @@ nextflow_workflow { assertAll( { assert workflow.success }, { assert snapshot( - workflow.out.vcfs.collect { it.collect { it instanceof Map ? it : file(it).name } }, - workflow.out.reports, - workflow.trace.succeeded().size(), - workflow.trace.failed().size() + workflow.out.collectEntries { key, value -> + if(key.matches("^\\d+\$") || key.matches('versions')) { + return null + } + return [ key, value ] + }.findAll { it != null } ).match() } ) } diff --git a/tests/subworkflows/local/vcf_annotate_vep_annotsv/main.nf.test.snap b/tests/subworkflows/local/vcf_annotate_vep_annotsv/main.nf.test.snap new file mode 100644 index 00000000..0e4dd468 --- /dev/null +++ b/tests/subworkflows/local/vcf_annotate_vep_annotsv/main.nf.test.snap @@ -0,0 +1,189 @@ +{ + "homo_sapiens - sv": { + "content": [ + { + "annotsv_vcfs": [ + [ + { + "groupSize": 7, + "groupTarget": { + "id": "test", + "sample": "test", + "sex": "male", + "family": "test1", + "family_count": 1, + "hpo": [ + + ], + "variant_type": "sv" + } + }, + "annotsv_annotated.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "annotsv_annotated.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "reports": [ + "test.vep.summary.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + "vep_vcfs": [ + [ + { + "id": "test", + "sample": "test", + "sex": "male", + "family": "test1", + "family_count": 1, + "hpo": [ + + ], + "variant_type": "sv" + }, + "test.vep.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test.vep.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.1", + "nextflow": "24.10.4" + }, + "timestamp": "2025-02-10T16:07:52.627675525" + }, + "homo_sapiens - sv & cnv": { + "content": [ + { + "annotsv_vcfs": [ + [ + { + "groupSize": 7, + "groupTarget": { + "id": "test", + "sample": "test", + "sex": "male", + "family": "test1", + "family_count": 1, + "hpo": [ + + ], + "variant_type": "cnv" + } + }, + "annotsv_annotated.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "annotsv_annotated.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "groupSize": 7, + "groupTarget": { + "id": "test", + "sample": "test", + "sex": "male", + "family": "test1", + "family_count": 1, + "hpo": [ + + ], + "variant_type": "sv" + } + }, + "annotsv_annotated.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "annotsv_annotated.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "reports": [ + "test.vep.summary.html:md5,d41d8cd98f00b204e9800998ecf8427e", + "test.vep.summary.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + "vep_vcfs": [ + [ + { + "id": "test", + "sample": "test", + "sex": "male", + "family": "test1", + "family_count": 1, + "hpo": [ + + ], + "variant_type": "cnv" + }, + "test.vep.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test.vep.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + [ + { + "id": "test", + "sample": "test", + "sex": "male", + "family": "test1", + "family_count": 1, + "hpo": [ + + ], + "variant_type": "sv" + }, + "test.vep.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test.vep.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.1", + "nextflow": "24.10.4" + }, + "timestamp": "2025-02-10T16:08:38.671891243" + }, + "homo_sapiens - cnv": { + "content": [ + { + "annotsv_vcfs": [ + [ + { + "groupSize": 7, + "groupTarget": { + "id": "test", + "sample": "test", + "sex": "male", + "family": "test1", + "family_count": 1, + "hpo": [ + + ], + "variant_type": "cnv" + } + }, + "annotsv_annotated.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "annotsv_annotated.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "reports": [ + "test.vep.summary.html:md5,d41d8cd98f00b204e9800998ecf8427e" + ], + "vep_vcfs": [ + [ + { + "id": "test", + "sample": "test", + "sex": "male", + "family": "test1", + "family_count": 1, + "hpo": [ + + ], + "variant_type": "cnv" + }, + "test.vep.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "test.vep.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + } + ], + "meta": { + "nf-test": "0.9.1", + "nextflow": "24.10.4" + }, + "timestamp": "2025-02-10T16:08:11.442901471" + } +} \ No newline at end of file diff --git a/tests/subworkflows/local/vcf_annotate_vep_annotsv_vcfanno/main.nf.test.snap b/tests/subworkflows/local/vcf_annotate_vep_annotsv_vcfanno/main.nf.test.snap deleted file mode 100644 index 69f24fa6..00000000 --- a/tests/subworkflows/local/vcf_annotate_vep_annotsv_vcfanno/main.nf.test.snap +++ /dev/null @@ -1,111 +0,0 @@ -{ - "homo_sapiens - sv, no_filter": { - "content": [ - [ - [ - { - "id": "test", - "sample": "test", - "sex": "male", - "family": "test1", - "family_count": 1, - "hpo": [ - - ], - "variant_type": "sv" - }, - "test.sv.annotated.vcf.gz", - "test.sv.annotated.vcf.gz.tbi" - ] - ], - [ - "test.vep.summary.html:md5,d41d8cd98f00b204e9800998ecf8427e" - ], - 22, - 0 - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" - }, - "timestamp": "2024-06-05T16:01:35.19225934" - }, - "homo_sapiens - sv & cnv": { - "content": [ - [ - [ - { - "id": "test", - "sample": "test", - "sex": "male", - "family": "test1", - "family_count": 1, - "hpo": [ - - ], - "variant_type": "cnv" - }, - "test.cnv.annotated.vcf.gz", - "test.cnv.annotated.vcf.gz.tbi" - ], - [ - { - "id": "test", - "sample": "test", - "sex": "male", - "family": "test1", - "family_count": 1, - "hpo": [ - - ], - "variant_type": "sv" - }, - "test.sv.annotated.vcf.gz", - "test.sv.annotated.vcf.gz.tbi" - ] - ], - [ - "test.vep.summary.html:md5,d41d8cd98f00b204e9800998ecf8427e", - "test.vep.summary.html:md5,d41d8cd98f00b204e9800998ecf8427e" - ], - 44, - 0 - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" - }, - "timestamp": "2024-06-05T16:04:50.892603799" - }, - "homo_sapiens - cnv, filter": { - "content": [ - [ - [ - { - "id": "test", - "sample": "test", - "sex": "male", - "family": "test1", - "family_count": 1, - "hpo": [ - - ], - "variant_type": "cnv" - }, - "test.cnv.annotated.vcf.gz", - "test.cnv.annotated.vcf.gz.tbi" - ] - ], - [ - "test.vep.summary.html:md5,d41d8cd98f00b204e9800998ecf8427e" - ], - 23, - 0 - ], - "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" - }, - "timestamp": "2024-06-05T16:02:48.492322238" - } -} \ No newline at end of file diff --git a/workflows/structural.nf b/workflows/structural.nf index 1f9f4fac..4ac459d7 100644 --- a/workflows/structural.nf +++ b/workflows/structural.nf @@ -21,7 +21,8 @@ include { methodsDescriptionText } from '../subworkflows/local/utils_nfcore_stru include { BAM_PREPARE_SAMTOOLS } from '../subworkflows/local/bam_prepare_samtools/main' include { BAM_SV_CALLING } from '../subworkflows/local/bam_sv_calling/main' include { BAM_CNV_CALLING } from '../subworkflows/local/bam_cnv_calling/main' -include { VCF_ANNOTATE_VEP_ANNOTSV_VCFANNO } from '../subworkflows/local/vcf_annotate_vep_annotsv_vcfanno/main' +include { VCF_ANNOTATE_VEP_ANNOTSV } from '../subworkflows/local/vcf_annotate_vep_annotsv/main' +include { VCF_ANNOTATE_VCFANNO } from '../subworkflows/local/vcf_annotate_vcfanno/main' include { BAM_REPEAT_ESTIMATION_EXPANSIONHUNTER } from '../subworkflows/local/bam_repeat_estimation_expansionhunter/main' include { VCF_CONCAT_BCFTOOLS } from '../subworkflows/local/vcf_concat_bcftools/main' include { VCF_MERGE_FAMILY_JASMINE } from '../subworkflows/local/vcf_merge_family_jasmine/main' @@ -375,9 +376,10 @@ workflow STRUCTURAL { // Annotate the variants // - def ch_outputs = Channel.empty() + def ch_annotation_output = Channel.empty() + def ch_annotsv_vcfs = Channel.empty() if(annotate) { - VCF_ANNOTATE_VEP_ANNOTSV_VCFANNO( + VCF_ANNOTATE_VEP_ANNOTSV( ch_annotation_input, ch_inputs.small_variants, ch_fasta, @@ -386,20 +388,34 @@ workflow STRUCTURAL { ch_annotsv_gene_transcripts, ch_vep_cache, ch_vep_extra_files, - ch_vcfanno_lua, - val_vcfanno_resources, variant_types, genome, species, - vep_cache_version, + vep_cache_version + ) + + ch_reports = ch_reports.mix(VCF_ANNOTATE_VEP_ANNOTSV.out.reports) + ch_versions = ch_versions.mix(VCF_ANNOTATE_VEP_ANNOTSV.out.versions) + ch_annotation_output = VCF_ANNOTATE_VEP_ANNOTSV.out.vep_vcfs + ch_annotsv_vcfs = VCF_ANNOTATE_VEP_ANNOTSV.out.annotsv_vcfs + } else { + ch_annotation_output = ch_annotation_input + } + + def ch_outputs = Channel.empty() + if(annotate || vcfanno_toml) { + VCF_ANNOTATE_VCFANNO( + ch_annotation_output, + ch_annotsv_vcfs, + ch_vcfanno_lua, + val_vcfanno_resources, annotations_filter, val_vcfanno_toml, - val_default_vcfanno_tomls + val_default_vcfanno_tomls, + annotate ) - - ch_reports = ch_reports.mix(VCF_ANNOTATE_VEP_ANNOTSV_VCFANNO.out.reports) - ch_versions = ch_versions.mix(VCF_ANNOTATE_VEP_ANNOTSV_VCFANNO.out.versions) - ch_outputs = ch_outputs.mix(VCF_ANNOTATE_VEP_ANNOTSV_VCFANNO.out.vcfs) + ch_versions = ch_versions.mix(VCF_ANNOTATE_VCFANNO.out.versions) + ch_outputs = ch_outputs.mix(VCF_ANNOTATE_VCFANNO.out.vcfs) } else { ch_outputs = ch_outputs.mix(ch_annotation_input) }