From a004c86eea62d4eed15768c0edb3adcc3f2c1424 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marius=20Bj=C3=B8rnstad?= Date: Thu, 12 Sep 2024 14:03:33 +0200 Subject: [PATCH] Split deepvariant 3 (#6172) * Move DeepVariant into a subcommand module rundeepvariant, preparing for split modules The test snapshot is updated because the process name in the version file changed. * Add a split DeepVariant workflow with individual processes for each step * Remove hash unique ID and fix input structure issue * Fixes for call_variants outputing sharded file * Fix test * Remove --channels insert_size, which is only applicable for short read data The channels should be specified in the pipeline config * Replace the model type value input with ext.args config * Fix tests: should run twice for two samples in input channel * Fix linting issues and input channel description * Fix formatting of md files Co-authored-by: Felix Lenner <52530259+fellen31@users.noreply.github.com> * Corrections / imrpovements from @fellen31 review * Check tfrecord file names * Updating conda skipping options, because the paths have changed * Add deprecation warning for top-level process and test for the deprecated process * also skip conda for the new deprecated module --------- Co-authored-by: Felix Lenner <52530259+fellen31@users.noreply.github.com> Co-authored-by: Maxime U Garcia --- .github/workflows/test.yml | 10 + modules/nf-core/deepvariant/README.md | 50 +++ .../nf-core/deepvariant/callvariants/main.nf | 58 ++++ .../nf-core/deepvariant/callvariants/meta.yml | 40 +++ .../callvariants/tests/main.nf.test | 85 +++++ .../callvariants/tests/main.nf.test.snap | 59 ++++ .../callvariants/tests/nextflow.config | 11 + .../deepvariant/callvariants/tests/tags.yml | 2 + modules/nf-core/deepvariant/main.nf | 67 +--- .../nf-core/deepvariant/makeexamples/main.nf | 66 ++++ .../nf-core/deepvariant/makeexamples/meta.yml | 88 +++++ .../makeexamples/tests/main.nf.test | 228 +++++++++++++ .../makeexamples/tests/main.nf.test.snap | 134 ++++++++ .../makeexamples/tests/nextflow.config | 6 + .../deepvariant/makeexamples/tests/tags.yml | 2 + modules/nf-core/deepvariant/meta.yml | 2 +- .../deepvariant/postprocessvariants/main.nf | 77 +++++ .../deepvariant/postprocessvariants/meta.yml | 90 ++++++ .../postprocessvariants/tests/main.nf.test | 118 +++++++ .../tests/main.nf.test.snap | 180 +++++++++++ .../postprocessvariants/tests/nextflow.config | 10 + .../postprocessvariants/tests/tags.yml | 2 + .../deepvariant/rundeepvariant/main.nf | 78 +++++ .../deepvariant/rundeepvariant/meta.yml | 92 ++++++ .../rundeepvariant/tests/main.nf.test | 166 ++++++++++ .../tests/main.nf.test.snap | 40 +-- .../tests/nextflow-intervals.config | 2 +- .../nextflow-non-autosomal-calling.config | 2 +- .../tests/nextflow.config | 2 +- .../deepvariant/rundeepvariant/tests/tags.yml | 2 + .../nf-core/deepvariant/tests/main.nf.test | 128 +------- subworkflows/nf-core/deepvariant/README.md | 8 + subworkflows/nf-core/deepvariant/main.nf | 45 +++ subworkflows/nf-core/deepvariant/meta.yml | 76 +++++ .../nf-core/deepvariant/tests/main.nf.test | 105 ++++++ .../deepvariant/tests/main.nf.test.snap | 300 ++++++++++++++++++ .../nf-core/deepvariant/tests/nextflow.config | 8 + .../nf-core/deepvariant/tests/tags.yml | 2 + 38 files changed, 2241 insertions(+), 200 deletions(-) create mode 100644 modules/nf-core/deepvariant/callvariants/main.nf create mode 100644 modules/nf-core/deepvariant/callvariants/meta.yml create mode 100644 modules/nf-core/deepvariant/callvariants/tests/main.nf.test create mode 100644 modules/nf-core/deepvariant/callvariants/tests/main.nf.test.snap create mode 100644 modules/nf-core/deepvariant/callvariants/tests/nextflow.config create mode 100644 modules/nf-core/deepvariant/callvariants/tests/tags.yml create mode 100644 modules/nf-core/deepvariant/makeexamples/main.nf create mode 100644 modules/nf-core/deepvariant/makeexamples/meta.yml create mode 100644 modules/nf-core/deepvariant/makeexamples/tests/main.nf.test create mode 100644 modules/nf-core/deepvariant/makeexamples/tests/main.nf.test.snap create mode 100644 modules/nf-core/deepvariant/makeexamples/tests/nextflow.config create mode 100644 modules/nf-core/deepvariant/makeexamples/tests/tags.yml create mode 100644 modules/nf-core/deepvariant/postprocessvariants/main.nf create mode 100644 modules/nf-core/deepvariant/postprocessvariants/meta.yml create mode 100644 modules/nf-core/deepvariant/postprocessvariants/tests/main.nf.test create mode 100644 modules/nf-core/deepvariant/postprocessvariants/tests/main.nf.test.snap create mode 100644 modules/nf-core/deepvariant/postprocessvariants/tests/nextflow.config create mode 100644 modules/nf-core/deepvariant/postprocessvariants/tests/tags.yml create mode 100644 modules/nf-core/deepvariant/rundeepvariant/main.nf create mode 100644 modules/nf-core/deepvariant/rundeepvariant/meta.yml create mode 100644 modules/nf-core/deepvariant/rundeepvariant/tests/main.nf.test rename modules/nf-core/deepvariant/{ => rundeepvariant}/tests/main.nf.test.snap (91%) rename modules/nf-core/deepvariant/{ => rundeepvariant}/tests/nextflow-intervals.config (70%) rename modules/nf-core/deepvariant/{ => rundeepvariant}/tests/nextflow-non-autosomal-calling.config (74%) rename modules/nf-core/deepvariant/{ => rundeepvariant}/tests/nextflow.config (75%) create mode 100644 modules/nf-core/deepvariant/rundeepvariant/tests/tags.yml create mode 100644 subworkflows/nf-core/deepvariant/README.md create mode 100644 subworkflows/nf-core/deepvariant/main.nf create mode 100644 subworkflows/nf-core/deepvariant/meta.yml create mode 100644 subworkflows/nf-core/deepvariant/tests/main.nf.test create mode 100644 subworkflows/nf-core/deepvariant/tests/main.nf.test.snap create mode 100644 subworkflows/nf-core/deepvariant/tests/nextflow.config create mode 100644 subworkflows/nf-core/deepvariant/tests/tags.yml diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 413f31a8b1b..4a44189f3e8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -540,6 +540,14 @@ jobs: path: modules/nf-core/deepcell/mesmer - profile: conda path: modules/nf-core/deepvariant + - profile: conda + path: modules/nf-core/deepvariant/callvariants + - profile: conda + path: modules/nf-core/deepvariant/makeexamples + - profile: conda + path: modules/nf-core/deepvariant/postprocessvariants + - profile: conda + path: modules/nf-core/deepvariant/rundeepvariant - profile: conda path: modules/nf-core/ensemblvep/vep - profile: conda @@ -630,6 +638,8 @@ jobs: path: subworkflows/nf-core/vcf_annotate_ensemblvep - profile: conda path: subworkflows/nf-core/bcl_demultiplex + - profile: conda + path: subworkflows/nf-core/deepvariant - profile: conda path: subworkflows/nf-core/fastq_align_bamcmp_bwa - profile: conda diff --git a/modules/nf-core/deepvariant/README.md b/modules/nf-core/deepvariant/README.md index 9d1ceb344ba..4b3ed086899 100644 --- a/modules/nf-core/deepvariant/README.md +++ b/modules/nf-core/deepvariant/README.md @@ -1,3 +1,7 @@ +# DeepVariant module / subworkflow options + +The DeepVariant tool can be run using the `deepvariant/rundeepvariant` subcommand, or the subworkflow `deepvariant`, which calls the subcommands `makeexamples`, `callvariants` and `postprocessvariants`. The subcommand `rundeepvariant` is simpler, but the subworkflow may be useful if you want to run `callvariants` on GPU. + # Conda is not supported at the moment The [bioconda](https://bioconda.github.io/recipes/deepvariant/README.html) recipe is not fully working as expected. @@ -9,3 +13,49 @@ Hence, we are using the docker container provided by the authors of the tool: - [google/deepvariant](https://hub.docker.com/r/google/deepvariant) This image is mirrored on the [nf-core quay.io](https://quay.io/repository/nf-core/deepvariant) for convenience. + +# DeepVariant subworkflow + +You can use the subworkflow `nf-core/deepvariant`, which integrates the three +processes to perform variant calling with common file formats. + +These module subcommands incorporate the individual steps of the DeepVariant pipeline: + + * makeexamples: Converts the input alignment file to a tfrecord format suitable for the deep learning model + * callvariants: Call variants based on input tfrecords. The output is also in + tfrecord format, and needs postprocessing to convert it to vcf. + * postprocessvariants: Convert variant calls from callvariants to VCF, and + also create GVCF files based on genomic information from makeexamples. + +# Recommended parameters + +## makeexamples + +This process imports the data used for calling, and thus decides what information is available to the +deep neural network. It's important to import the correct channels for the model you want to use. + +The script `run_deepvariant` (not used in the subworkflow) does this automatically. You can refer to +the implementation in the DeepVariant repo: + +https://github.com/google/deepvariant/blob/bf9ed7e6de97cf6c8381694cb996317a740625ad/scripts/run_deepvariant.py#L367 + +For WGS and WES models you need to enable the `insert_size` channel. Specify the following in the config: + +``` +withName: "DEEPVARIANT_MAKEEXAMPLES" { + ext.args = '--channels "insert_size"' +} +``` + +## callvariants + +It is mandatory to specify a model type. The models are available on the container filesystem in +`/opt/models` - specify the one you want with the `--checkpoint` argument. + +``` +withName: "DEEPVARIANT_CALLVARIANTS" { + ext.args = '--checkpoint "/opt/models/wgs' +} +``` + +The channels specified in the `makeexamples` process must match the model used for calling. diff --git a/modules/nf-core/deepvariant/callvariants/main.nf b/modules/nf-core/deepvariant/callvariants/main.nf new file mode 100644 index 00000000000..668b51ae4cc --- /dev/null +++ b/modules/nf-core/deepvariant/callvariants/main.nf @@ -0,0 +1,58 @@ + +process DEEPVARIANT_CALLVARIANTS { + tag "$meta.id" + label 'process_high' + + //Conda is not supported at the moment + container "nf-core/deepvariant:1.6.1" + + input: + tuple val(meta), path(make_examples_tfrecords) + + output: + tuple val(meta), path("${prefix}.call-*-of-*.tfrecord.gz"), emit: call_variants_tfrecords + path "versions.yml", emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + // Exit if running this module with -profile conda / -profile mamba + if (workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1) { + error "DEEPVARIANT module does not support Conda. Please use Docker / Singularity / Podman instead." + } + def args = task.ext.args ?: '' + prefix = task.ext.prefix ?: "${meta.id}" + + def matcher = make_examples_tfrecords[0].baseName =~ /^(.+)-\d{5}-of-(\d{5})$/ + if (!matcher.matches()) { + throw new IllegalArgumentException("tfrecord baseName '" + make_examples_tfrecords[0].baseName + "' doesn't match the expected pattern") + } + def examples_tfrecord_name = matcher[0][1] + def shardCount = matcher[0][2] + // Reconstruct the logical name - ${tfrecord_name}.examples.tfrecord@${task.cpus}.gz + def examples_tfrecords_logical_name = "${examples_tfrecord_name}@${shardCount}.gz" + + """ + /opt/deepvariant/bin/call_variants \\ + ${args} \\ + --outfile "${prefix}.call.tfrecord.gz" \\ + --examples "${examples_tfrecords_logical_name}" + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + deepvariant_callvariants: \$(echo \$(/opt/deepvariant/bin/run_deepvariant --version) | sed 's/^.*version //; s/ .*\$//' ) + END_VERSIONS + """ + + stub: + prefix = task.ext.prefix ?: "${meta.id}" + """ + echo "" | gzip > ${prefix}.call-00000-of-00001.tfrecord.gz + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + deepvariant_callvariants: \$(echo \$(/opt/deepvariant/bin/run_deepvariant --version) | sed 's/^.*version //; s/ .*\$//' ) + END_VERSIONS + """ +} diff --git a/modules/nf-core/deepvariant/callvariants/meta.yml b/modules/nf-core/deepvariant/callvariants/meta.yml new file mode 100644 index 00000000000..db779c62ba0 --- /dev/null +++ b/modules/nf-core/deepvariant/callvariants/meta.yml @@ -0,0 +1,40 @@ +name: deepvariant_callvariants +description: Call variants from the examples produced by make_examples +keywords: + - variant calling + - machine learning + - neural network +tools: + - deepvariant: + description: DeepVariant is an analysis pipeline that uses a deep neural network to call genetic variants from next-generation DNA sequencing data + homepage: https://github.com/google/deepvariant + documentation: https://github.com/google/deepvariant + tool_dev_url: https://github.com/google/deepvariant + doi: "10.1038/nbt.4235" + licence: ["BSD-3-clause"] +input: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - make_examples_tfrecords: + type: file + description: The actual sharded input files, from DEEPVARIANT_MAKEEXAMPLES process + pattern: "*.gz" +output: + - call_variants_tfrecords: + type: list + description: | + Each output contains: unique ID string from input channel, meta, tfrecord file with variant calls. + - versions: + type: file + description: File containing software version + pattern: "versions.yml" +authors: + - "@abhi18av" + - "@ramprasadn" + - "@fa2k" +maintainers: + - "@abhi18av" + - "@ramprasadn" diff --git a/modules/nf-core/deepvariant/callvariants/tests/main.nf.test b/modules/nf-core/deepvariant/callvariants/tests/main.nf.test new file mode 100644 index 00000000000..72f04b51f3b --- /dev/null +++ b/modules/nf-core/deepvariant/callvariants/tests/main.nf.test @@ -0,0 +1,85 @@ +nextflow_process { + + name "Test Process DEEPVARIANT_CALLVARIANTS" + script "../main.nf" + config "./nextflow.config" + process "DEEPVARIANT_CALLVARIANTS" + + tag "deepvariant/makeexamples" + tag "deepvariant/callvariants" + tag "deepvariant" + tag "modules" + tag "modules_nfcore" + + test("homo_sapiens - wgs") { + setup { + run("DEEPVARIANT_MAKEEXAMPLES") { + script "../../makeexamples/main.nf" + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + 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] = [ + [ id:'genome'], + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + ] + input[2] = [ + [ id:'genome'], + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) + ] + input[3] = [ + [],[] + ] + input[4] = [ + [],[] + ] + """ + } + } + } + when { + process { + """ + input[0] = DEEPVARIANT_MAKEEXAMPLES.out.examples + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert process.out.call_variants_tfrecords.get(0).get(0) == [ id:'test', single_end:false ] }, + // The tfrecord binary representation is not stable, but we check the name of the output. + { assert snapshot(file(process.out.call_variants_tfrecords.get(0).get(1)).name).match("homo_sapiens-wgs-call_variants_tfrecords-filenames")}, + { assert snapshot(process.out.versions).match("versions") }, + ) + } + } + + test("homo_sapiens - wgs - stub") { + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta + [] // No input paths are needed in stub mode + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + +} diff --git a/modules/nf-core/deepvariant/callvariants/tests/main.nf.test.snap b/modules/nf-core/deepvariant/callvariants/tests/main.nf.test.snap new file mode 100644 index 00000000000..8f04ede70eb --- /dev/null +++ b/modules/nf-core/deepvariant/callvariants/tests/main.nf.test.snap @@ -0,0 +1,59 @@ +{ + "versions": { + "content": [ + [ + "versions.yml:md5,5ff99ffba1e56e4e919d3dfc2d0f3cbb" + ] + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-08-09T16:38:47.927241" + }, + "homo_sapiens-wgs-call_variants_tfrecords-filenames": { + "content": [ + "test.call-00000-of-00001.tfrecord.gz" + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-09-04T17:04:33.276938" + }, + "homo_sapiens - wgs - stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.call-00000-of-00001.tfrecord.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + "versions.yml:md5,5ff99ffba1e56e4e919d3dfc2d0f3cbb" + ], + "call_variants_tfrecords": [ + [ + { + "id": "test", + "single_end": false + }, + "test.call-00000-of-00001.tfrecord.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "versions": [ + "versions.yml:md5,5ff99ffba1e56e4e919d3dfc2d0f3cbb" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-08-13T21:07:17.335788301" + } +} \ No newline at end of file diff --git a/modules/nf-core/deepvariant/callvariants/tests/nextflow.config b/modules/nf-core/deepvariant/callvariants/tests/nextflow.config new file mode 100644 index 00000000000..590aa060237 --- /dev/null +++ b/modules/nf-core/deepvariant/callvariants/tests/nextflow.config @@ -0,0 +1,11 @@ +process { + withName: "DEEPVARIANT_CALLVARIANTS" { + ext.args = '--checkpoint "/opt/models/wgs"' + cpus = 2 // Keep CPUs fixed so the number of output files is reproducible + } +} +process { + withName: "DEEPVARIANT_MAKEEXAMPLES" { + ext.args = '--channels "insert_size"' + } +} diff --git a/modules/nf-core/deepvariant/callvariants/tests/tags.yml b/modules/nf-core/deepvariant/callvariants/tests/tags.yml new file mode 100644 index 00000000000..02e63f50891 --- /dev/null +++ b/modules/nf-core/deepvariant/callvariants/tests/tags.yml @@ -0,0 +1,2 @@ +deepvariant/callvariants: + - modules/nf-core/deepvariant/callvariants/** diff --git a/modules/nf-core/deepvariant/main.nf b/modules/nf-core/deepvariant/main.nf index 8d3d091119d..12c9366bb7b 100644 --- a/modules/nf-core/deepvariant/main.nf +++ b/modules/nf-core/deepvariant/main.nf @@ -1,10 +1,21 @@ +def deprecation_message = """ +WARNING: The deepvariant process has been moved into deepvariant/rundeepvariant. + +Reason: +A subworkflow "deepvariant" was added, to split DeepVariant into three processes, to help optimise +the usage of GPU resources (https://github.com/nf-core/modules/pull/6172). The subworkflow can be +used instead of this module. Alternatively, it is possible to use the subcommand "rundeepvariant" in +this module. "rundeepvariant" (the process DEEPVARIANT_RUNDEEPVARIANT) is the exact same as this +top-level process (DEEPVARIANT) used to be. + +The processing stages used by the subworkflow are implemented as module subcommands, e.g. makeexamples. +""" + + process DEEPVARIANT { tag "$meta.id" label 'process_high' - // FIXME Conda is not supported at the moment - // BUG https://github.com/nf-core/modules/issues/1754 - // BUG https://github.com/bioconda/bioconda-recipes/issues/30310 container "nf-core/deepvariant:1.6.1" input: @@ -25,54 +36,6 @@ process DEEPVARIANT { task.ext.when == null || task.ext.when script: - // Exit if running this module with -profile conda / -profile mamba - if (workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1) { - error "DEEPVARIANT module does not support Conda. Please use Docker / Singularity / Podman instead." - } - def args = task.ext.args ?: '' - prefix = task.ext.prefix ?: "${meta.id}" - def regions = intervals ? "--regions=${intervals}" : "" - def par_regions = par_bed ? "--par_regions_bed=${par_bed}" : "" - // WARN https://github.com/nf-core/modules/pull/5801#issuecomment-2194293755 - // FIXME Revert this on next version bump - def VERSION = '1.6.1' - - """ - /opt/deepvariant/bin/run_deepvariant \\ - --ref=${fasta} \\ - --reads=${input} \\ - --output_vcf=${prefix}.vcf.gz \\ - --output_gvcf=${prefix}.g.vcf.gz \\ - ${args} \\ - ${regions} \\ - ${par_regions} \\ - --intermediate_results_dir=tmp \\ - --num_shards=${task.cpus} - - cat <<-END_VERSIONS > versions.yml - "${task.process}": - deepvariant: $VERSION - END_VERSIONS - """ - - stub: - // Exit if running this module with -profile conda / -profile mamba - if (workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1) { - error "DEEPVARIANT module does not support Conda. Please use Docker / Singularity / Podman instead." - } - prefix = task.ext.prefix ?: "${meta.id}" - // WARN https://github.com/nf-core/modules/pull/5801#issuecomment-2194293755 - // FIXME Revert this on next version bump - def VERSION = '1.6.1' - """ - touch ${prefix}.vcf.gz - touch ${prefix}.vcf.gz.tbi - touch ${prefix}.g.vcf.gz - touch ${prefix}.g.vcf.gz.tbi + assert false: deprecation_message - cat <<-END_VERSIONS > versions.yml - "${task.process}": - deepvariant: $VERSION - END_VERSIONS - """ } diff --git a/modules/nf-core/deepvariant/makeexamples/main.nf b/modules/nf-core/deepvariant/makeexamples/main.nf new file mode 100644 index 00000000000..022d0bf2808 --- /dev/null +++ b/modules/nf-core/deepvariant/makeexamples/main.nf @@ -0,0 +1,66 @@ +process DEEPVARIANT_MAKEEXAMPLES { + tag "$meta.id" + label 'process_high' + + //Conda is not supported at the moment + container "nf-core/deepvariant:1.6.1" + + input: + tuple val(meta), path(input), path(index), path(intervals) + tuple val(meta2), path(fasta) + tuple val(meta3), path(fai) + tuple val(meta4), path(gzi) + tuple val(meta5), path(par_bed) + + output: + tuple val(meta), path("${prefix}.examples.tfrecord-*-of-*.gz{,.example_info.json}"), emit: examples + tuple val(meta), path("${prefix}.gvcf.tfrecord-*-of-*.gz"), emit: gvcf + path "versions.yml", emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + // Exit if running this module with -profile conda / -profile mamba + if (workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1) { + error "DEEPVARIANT module does not support Conda. Please use Docker / Singularity / Podman instead." + } + def args = task.ext.args ?: '' + prefix = task.ext.prefix ?: "${meta.id}" + def regions = intervals ? "--regions ${intervals}" : "" + def par_regions = par_bed ? "--par_regions_bed=${par_bed}" : "" + + """ + seq 0 ${task.cpus - 1} | parallel -q --halt 2 --line-buffer /opt/deepvariant/bin/make_examples \\ + --mode calling \\ + --ref "${fasta}" \\ + --reads "${input}" \\ + --examples "./${prefix}.examples.tfrecord@${task.cpus}.gz" \\ + --gvcf "./${prefix}.gvcf.tfrecord@${task.cpus}.gz" \\ + ${regions} \\ + ${par_regions} \\ + ${args} \\ + --task {} + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + deepvariant_makeexamples: \$(echo \$(/opt/deepvariant/bin/run_deepvariant --version) | sed 's/^.*version //; s/ .*\$//' ) + END_VERSIONS + """ + + stub: + prefix = task.ext.prefix ?: "${meta.id}" + """ + printf -v SHARD_COUNT "%04d" ${task.cpus} + for i in \$( seq -f "%04g" 0 ${task.cpus-1} ) + do + touch ${prefix}.examples.tfrecord-\$i-of-\$SHARD_COUNT.tfrecord.gz{,.example_info.json} + touch ${prefix}.gvcf.tfrecord-\$i-of-\$SHARD_COUNT.tfrecord.gz + done + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + deepvariant_makeexamples: \$(echo \$(/opt/deepvariant/bin/run_deepvariant --version) | sed 's/^.*version //; s/ .*\$//' ) + END_VERSIONS + """ +} diff --git a/modules/nf-core/deepvariant/makeexamples/meta.yml b/modules/nf-core/deepvariant/makeexamples/meta.yml new file mode 100644 index 00000000000..ab1d2e589a1 --- /dev/null +++ b/modules/nf-core/deepvariant/makeexamples/meta.yml @@ -0,0 +1,88 @@ +name: deepvariant_makeexamples +description: Transforms the input alignments to a format suitable for the deep neural network variant caller +keywords: + - variant calling + - machine learning + - neural network +tools: + - deepvariant: + description: DeepVariant is an analysis pipeline that uses a deep neural network to call genetic variants from next-generation DNA sequencing data + homepage: https://github.com/google/deepvariant + documentation: https://github.com/google/deepvariant + tool_dev_url: https://github.com/google/deepvariant + doi: "10.1038/nbt.4235" + licence: ["BSD-3-clause"] +input: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - input: + type: file + description: BAM/CRAM file + pattern: "*.bam/cram" + - index: + type: file + description: Index of BAM/CRAM file + pattern: "*.bai/crai" + - intervals: + type: file + description: Interval file for targeted regions + pattern: "*.bed" + - meta2: + type: map + description: | + Groovy Map containing reference information + e.g. [ id:'genome' ] + - fasta: + type: file + description: The reference fasta file + pattern: "*.fasta" + - meta3: + type: map + description: | + Groovy Map containing reference information + e.g. [ id:'genome' ] + - fai: + type: file + description: Index of reference fasta file + pattern: "*.fai" + - meta4: + type: map + description: | + Groovy Map containing reference information + e.g. [ id:'genome' ] + - gzi: + type: file + description: GZI index of reference fasta file + - meta5: + type: map + description: | + Groovy Map containing reference information + e.g. [ id:'genome' ] + pattern: "*.gzi" + - par_bed: + type: file + description: BED file containing PAR regions + pattern: "*.bed" +output: + - examples: + type: list + description: | + Tuple containing sample metadata and examples that can be used for calling + - gvcf: + type: list + description: | + Tuple containing sample metadata and the GVCF data in tfrecord format + - versions: + type: file + description: File containing the DeepVariant software version + pattern: "versions.yml" +authors: + - "@abhi18av" + - "@ramprasadn" + - "@fa2k" +maintainers: + - "@abhi18av" + - "@ramprasadn" diff --git a/modules/nf-core/deepvariant/makeexamples/tests/main.nf.test b/modules/nf-core/deepvariant/makeexamples/tests/main.nf.test new file mode 100644 index 00000000000..d46dbe6d57c --- /dev/null +++ b/modules/nf-core/deepvariant/makeexamples/tests/main.nf.test @@ -0,0 +1,228 @@ +nextflow_process { + + name "Test Process DEEPVARIANT_MAKEEXAMPLES" + script "../main.nf" + config "./nextflow.config" + process "DEEPVARIANT_MAKEEXAMPLES" + + tag "deepvariant/makeexamples" + tag "deepvariant" + tag "modules" + tag "modules_nfcore" + + test("homo_sapiens - [bam, bai] - fasta - fai") { + when { + + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + 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] = [ + [ id:'genome'], + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + ] + input[2] = [ + [ id:'genome'], + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) + ] + input[3] = [ + [],[] + ] + input[4] = [ + [],[] + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + // Test string values and versions. The tfrecords contents are not stable, but we check the names. + { assert process.out.examples.get(0).get(0) == [ id:'test', single_end:false ] }, + { assert process.out.gvcf.get(0).get(0) == [ id:'test', single_end:false ] }, + { assert process.out.examples.get(0).get(1).size() == 4 }, + { assert snapshot( // Check examples (tfrecord / json) file name list + file(process.out.examples.get(0).get(1).get(0)).name, + file(process.out.examples.get(0).get(1).get(1)).name, + file(process.out.examples.get(0).get(1).get(2)).name, + file(process.out.examples.get(0).get(1).get(3)).name, + ).match("test1-exaamples-filenames")}, + + { assert process.out.gvcf.get(0).get(0) == [ id:'test', single_end:false ] }, + { assert process.out.gvcf.get(0).get(1).size() == 2 }, + { assert snapshot( // Check gvcf file name list + file(process.out.gvcf.get(0).get(1).get(0)).name, + file(process.out.gvcf.get(0).get(1).get(1)).name, + ).match("test1-gvcf-filenames")}, + { assert snapshot(process.out.versions).match("test1-versions") }, + ) + } + } + + test("homo_sapiens - [cram, crai, genome_bed] - fasta - fai") { + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram', checkIfExists: true), + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram.crai', checkIfExists: true), + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.bed', checkIfExists: true) + ] + input[1] = [ + [ id:'genome'], + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + ] + input[2] = [ + [ id:'genome'], + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) + ] + input[3] = [ + [],[] + ] + input[4] = [ + [],[] + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert process.out.examples.get(0).get(0) == [ id:'test', single_end:false ] }, + // The test is always run with 2 cpus + { assert process.out.examples.get(0).get(1).size() == 4 }, + { assert snapshot( // Check examples (tfrecord / json) file names + file(process.out.examples.get(0).get(1).get(0)).name, + file(process.out.examples.get(0).get(1).get(1)).name, + file(process.out.examples.get(0).get(1).get(2)).name, + file(process.out.examples.get(0).get(1).get(3)).name, + ).match("test2-examples-filenames")}, + + { assert process.out.gvcf.get(0).get(0) == [ id:'test', single_end:false ] }, + { assert process.out.gvcf.get(0).get(1).size() == 2 }, + { assert snapshot( // Check gvcf tfrecord file names + file(process.out.gvcf.get(0).get(1).get(0)).name, + file(process.out.gvcf.get(0).get(1).get(1)).name, + ).match("test2-gvcf-filenames")}, + { assert snapshot(process.out.versions).match("test2-versions") }, + ) + } + } + + test("homo_sapiens - [bam, bai] - fasta_gz - fasta_gz_fai") { + when { + + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + 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] = [ + [ id:'genome'], + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.fasta.gz', checkIfExists: true) + ] + input[2] = [ + [ id:'genome'], + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.fasta.gz.fai', checkIfExists: true) + ] + input[3] = [ + [ id:'genome'], + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.fasta.gz.gzi', checkIfExists: true) + ] + input[4] = [ + [],[] + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + + { assert process.out.examples.get(0).get(0) == [ id:'test', single_end:false ] }, + // The test is always run with 2 cpus + { assert process.out.examples.get(0).get(1).size() == 4 }, + { assert snapshot( // Check examples (tfrecord / json) file name list + file(process.out.examples.get(0).get(1).get(0)).name, + file(process.out.examples.get(0).get(1).get(1)).name, + file(process.out.examples.get(0).get(1).get(2)).name, + file(process.out.examples.get(0).get(1).get(3)).name, + ).match("test3-examples-filenames")}, + + { assert process.out.gvcf.get(0).get(0) == [ id:'test', single_end:false ] }, + { assert process.out.gvcf.get(0).get(1).size() == 2 }, + { assert snapshot( // Check gvcf file name list + file(process.out.gvcf.get(0).get(1).get(0)).name, + file(process.out.gvcf.get(0).get(1).get(1)).name, + ).match("test3-gvcf-filenames")}, + { assert snapshot(process.out.versions).match("test3-versions") }, + ) + } + } + + test("stub") { + + options "-stub" + + when { + + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + 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] = [ + [ id:'genome'], + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + ] + input[2] = [ + [ id:'genome'], + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) + ] + input[3] = [ + [],[] + ] + input[4] = [ + [],[] + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert process.out.examples.get(0).get(1).size() == 4 }, + { assert snapshot( // Check examples (tfrecord / json) file name list + file(process.out.examples.get(0).get(1).get(0)).name, + file(process.out.examples.get(0).get(1).get(1)).name, + file(process.out.examples.get(0).get(1).get(2)).name, + file(process.out.examples.get(0).get(1).get(3)).name, + ).match("test4-examples-filenames")}, + + { assert process.out.gvcf.get(0).get(0) == [ id:'test', single_end:false ] }, + { assert process.out.gvcf.get(0).get(1).size() == 2 }, + { assert snapshot( // Check gvcf file name list + file(process.out.gvcf.get(0).get(1).get(0)).name, + file(process.out.gvcf.get(0).get(1).get(1)).name, + ).match("test4-gvcf-filenames")}, + ) + } + } + +} diff --git a/modules/nf-core/deepvariant/makeexamples/tests/main.nf.test.snap b/modules/nf-core/deepvariant/makeexamples/tests/main.nf.test.snap new file mode 100644 index 00000000000..24182c54a0b --- /dev/null +++ b/modules/nf-core/deepvariant/makeexamples/tests/main.nf.test.snap @@ -0,0 +1,134 @@ +{ + "test1-gvcf-filenames": { + "content": [ + "test.gvcf.tfrecord-00000-of-00002.gz", + "test.gvcf.tfrecord-00001-of-00002.gz" + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-09-04T16:09:47.885995" + }, + "test2-examples-filenames": { + "content": [ + "test.examples.tfrecord-00000-of-00002.gz", + "test.examples.tfrecord-00000-of-00002.gz.example_info.json", + "test.examples.tfrecord-00001-of-00002.gz", + "test.examples.tfrecord-00001-of-00002.gz.example_info.json" + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-09-04T16:10:02.757227" + }, + "test2-versions": { + "content": [ + [ + "versions.yml:md5,842dca9323f25aa3cfd67789d18e7e33" + ] + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-08-09T16:39:28.960959" + }, + "test4-examples-filenames": { + "content": [ + "test.examples.tfrecord-0000-of-0002.tfrecord.gz", + "test.examples.tfrecord-0000-of-0002.tfrecord.gz.example_info.json", + "test.examples.tfrecord-0001-of-0002.tfrecord.gz", + "test.examples.tfrecord-0001-of-0002.tfrecord.gz.example_info.json" + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-09-04T16:10:27.41698" + }, + "test1-versions": { + "content": [ + [ + "versions.yml:md5,842dca9323f25aa3cfd67789d18e7e33" + ] + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-08-09T16:39:13.57526" + }, + "test3-examples-filenames": { + "content": [ + "test.examples.tfrecord-00000-of-00002.gz", + "test.examples.tfrecord-00000-of-00002.gz.example_info.json", + "test.examples.tfrecord-00001-of-00002.gz", + "test.examples.tfrecord-00001-of-00002.gz.example_info.json" + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-09-04T16:10:17.705948" + }, + "test2-gvcf-filenames": { + "content": [ + "test.gvcf.tfrecord-00000-of-00002.gz", + "test.gvcf.tfrecord-00001-of-00002.gz" + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-09-04T16:10:02.765863" + }, + "test4-gvcf-filenames": { + "content": [ + "test.gvcf.tfrecord-0000-of-0002.tfrecord.gz", + "test.gvcf.tfrecord-0001-of-0002.tfrecord.gz" + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-09-04T16:10:27.423442" + }, + "test3-versions": { + "content": [ + [ + "versions.yml:md5,842dca9323f25aa3cfd67789d18e7e33" + ] + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-08-09T16:39:44.83616" + }, + "test1-exaamples-filenames": { + "content": [ + "test.examples.tfrecord-00000-of-00002.gz", + "test.examples.tfrecord-00000-of-00002.gz.example_info.json", + "test.examples.tfrecord-00001-of-00002.gz", + "test.examples.tfrecord-00001-of-00002.gz.example_info.json" + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-09-04T16:09:47.874585" + }, + "test3-gvcf-filenames": { + "content": [ + "test.gvcf.tfrecord-00000-of-00002.gz", + "test.gvcf.tfrecord-00001-of-00002.gz" + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-09-04T16:10:17.714443" + } +} \ No newline at end of file diff --git a/modules/nf-core/deepvariant/makeexamples/tests/nextflow.config b/modules/nf-core/deepvariant/makeexamples/tests/nextflow.config new file mode 100644 index 00000000000..5f071fcb34b --- /dev/null +++ b/modules/nf-core/deepvariant/makeexamples/tests/nextflow.config @@ -0,0 +1,6 @@ +process { + withName: "DEEPVARIANT_MAKEEXAMPLES" { + ext.args = '--channels "insert_size"' + cpus = 2 // The number of output files is determined by cpus - keep it the same for tests + } +} diff --git a/modules/nf-core/deepvariant/makeexamples/tests/tags.yml b/modules/nf-core/deepvariant/makeexamples/tests/tags.yml new file mode 100644 index 00000000000..6a13da09590 --- /dev/null +++ b/modules/nf-core/deepvariant/makeexamples/tests/tags.yml @@ -0,0 +1,2 @@ +deepvariant/makeexamples: + - modules/nf-core/deepvariant/makeexamples/** diff --git a/modules/nf-core/deepvariant/meta.yml b/modules/nf-core/deepvariant/meta.yml index 2327dd5f406..30c0285ae3e 100644 --- a/modules/nf-core/deepvariant/meta.yml +++ b/modules/nf-core/deepvariant/meta.yml @@ -1,5 +1,5 @@ name: deepvariant -description: DeepVariant is an analysis pipeline that uses a deep neural network to call genetic variants from next-generation DNA sequencing data +description: (DEPRECATED - see main.nf) DeepVariant is an analysis pipeline that uses a deep neural network to call genetic variants from next-generation DNA sequencing data keywords: - variant calling - machine learning diff --git a/modules/nf-core/deepvariant/postprocessvariants/main.nf b/modules/nf-core/deepvariant/postprocessvariants/main.nf new file mode 100644 index 00000000000..90e8563deb6 --- /dev/null +++ b/modules/nf-core/deepvariant/postprocessvariants/main.nf @@ -0,0 +1,77 @@ +process DEEPVARIANT_POSTPROCESSVARIANTS { + tag "$meta.id" + label 'process_medium' + + //Conda is not supported at the moment + container "nf-core/deepvariant:1.6.1" + + input: + tuple val(meta), path(variant_calls_tfrecord_files), path(gvcf_tfrecords) + tuple val(meta2), path(fasta) + tuple val(meta3), path(fai) + tuple val(meta4), path(gzi) + + output: + tuple val(meta), path("${prefix}.vcf.gz") , emit: vcf + tuple val(meta), path("${prefix}.vcf.gz.tbi") , emit: vcf_tbi + tuple val(meta), path("${prefix}.g.vcf.gz") , emit: gvcf + tuple val(meta), path("${prefix}.g.vcf.gz.tbi"), emit: gvcf_tbi + + path "versions.yml", emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + // Exit if running this module with -profile conda / -profile mamba + if (workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1) { + error "DEEPVARIANT module does not support Conda. Please use Docker / Singularity / Podman instead." + } + def args = task.ext.args ?: '' + prefix = task.ext.prefix ?: "${meta.id}" + + def variant_calls_tfrecord_name = variant_calls_tfrecord_files[0].name.replaceFirst(/-\d{5}-of-\d{5}/, "") + + def gvcf_matcher = gvcf_tfrecords[0].baseName =~ /^(.+)-\d{5}-of-(\d{5})$/ + if (!gvcf_matcher.matches()) { + throw new IllegalArgumentException("tfrecord baseName '" + gvcf_tfrecords[0].baseName + "' doesn't match the expected pattern") + } + def gvcf_tfrecord_name = gvcf_matcher[0][1] + def gvcf_shardCount = gvcf_matcher[0][2] + // Reconstruct the logical name - ${tfrecord_name}.examples.tfrecord@${task.cpus}.gz + def gvcf_tfrecords_logical_name = "${gvcf_tfrecord_name}@${gvcf_shardCount}.gz" + + """ + /opt/deepvariant/bin/postprocess_variants \\ + ${args} \\ + --ref "${fasta}" \\ + --infile "${variant_calls_tfrecord_name}" \\ + --outfile "${prefix}.vcf.gz" \\ + --nonvariant_site_tfrecord_path "${gvcf_tfrecords_logical_name}" \\ + --gvcf_outfile "${prefix}.g.vcf.gz" \\ + --cpus $task.cpus + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + deepvariant_postprocessvariants: \$(echo \$(/opt/deepvariant/bin/run_deepvariant --version) | sed 's/^.*version //; s/ .*\$//' ) + END_VERSIONS + """ + + stub: + // Exit if running this module with -profile conda / -profile mamba + if (workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1) { + error "DEEPVARIANT module does not support Conda. Please use Docker / Singularity / Podman instead." + } + prefix = task.ext.prefix ?: "${meta.id}" + """ + echo "" | gzip > ${prefix}.vcf.gz + touch ${prefix}.vcf.gz.tbi + echo "" | gzip > ${prefix}.g.vcf.gz + touch ${prefix}.g.vcf.gz.tbi + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + deepvariant_callvariants: \$(echo \$(/opt/deepvariant/bin/run_deepvariant --version) | sed 's/^.*version //; s/ .*\$//' ) + END_VERSIONS + """ +} diff --git a/modules/nf-core/deepvariant/postprocessvariants/meta.yml b/modules/nf-core/deepvariant/postprocessvariants/meta.yml new file mode 100644 index 00000000000..03a0a6b8235 --- /dev/null +++ b/modules/nf-core/deepvariant/postprocessvariants/meta.yml @@ -0,0 +1,90 @@ +name: deepvariant_postprocessvariants +description: DeepVariant is an analysis pipeline that uses a deep neural network to call genetic variants from next-generation DNA sequencing data +keywords: + - variant calling + - machine learning + - neural network +tools: + - deepvariant: + description: DeepVariant is an analysis pipeline that uses a deep neural network to call genetic variants from next-generation DNA sequencing data + homepage: https://github.com/google/deepvariant + documentation: https://github.com/google/deepvariant + tool_dev_url: https://github.com/google/deepvariant + doi: "10.1038/nbt.4235" + licence: ["BSD-3-clause"] +input: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - variant_calls_tfrecord_files: + type: file + description: | + One or more data files containing variant calls from DEEPVARIANT_CALLVARIANTS + pattern: "*.tfrecord.gz" + - gvcf_tfrecords: + type: file + description: | + Sharded tfrecord file from DEEPVARIANT_MAKEEXAMPLES with the coverage information used for GVCF output + pattern: "*.gz" + - meta2: + type: map + description: | + Groovy Map containing reference information + e.g. [ id:'genome' ] + - fasta: + type: file + description: The reference fasta file + pattern: "*.fasta" + - meta3: + type: map + description: | + Groovy Map containing reference information + e.g. [ id:'genome' ] + - fai: + type: file + description: Index of reference fasta file + pattern: "*.fai" + - meta4: + type: map + description: | + Groovy Map containing reference information + e.g. [ id:'genome' ] + - gzi: + type: file + description: GZI index of reference fasta file + pattern: "*.gzi" +output: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - vcf: + type: file + description: Compressed VCF file + pattern: "*.vcf.gz" + - vcf_tbi: + type: file + description: Index for VCF + pattern: "*.vcf.gz.tbi" + - gvcf: + type: file + description: Compressed GVCF file + pattern: "*.g.vcf.gz" + - gvcf_tbi: + type: file + description: Index for GVCF + pattern: "*.g.vcf.gz.tbi" + - versions: + type: file + description: File containing software version + pattern: "versions.yml" +authors: + - "@abhi18av" + - "@ramprasadn" + - "@fa2k" +maintainers: + - "@abhi18av" + - "@ramprasadn" diff --git a/modules/nf-core/deepvariant/postprocessvariants/tests/main.nf.test b/modules/nf-core/deepvariant/postprocessvariants/tests/main.nf.test new file mode 100644 index 00000000000..e4e9b5570c2 --- /dev/null +++ b/modules/nf-core/deepvariant/postprocessvariants/tests/main.nf.test @@ -0,0 +1,118 @@ +nextflow_process { + + name "Test Process DEEPVARIANT_POSTPROCESSVARIANTS" + script "../main.nf" + process "DEEPVARIANT_POSTPROCESSVARIANTS" + config "./nextflow.config" + + tag "deepvariant/makeexamples" + tag "deepvariant/callvariants" + tag "deepvariant/postprocessvariants" + tag "deepvariant" + tag "modules" + tag "modules_nfcore" + + test("homo_sapiens - wgs") { + setup { + run("DEEPVARIANT_MAKEEXAMPLES") { + script "../../makeexamples/main.nf" + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + 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] = [ + [ id:'genome'], + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + ] + input[2] = [ + [ id:'genome'], + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) + ] + input[3] = [ + [],[] + ] + input[4] = [ + [],[] + ] + """ + } + } + run("DEEPVARIANT_CALLVARIANTS") { + script "../../callvariants/main.nf" + process { + """ + input[0] = DEEPVARIANT_MAKEEXAMPLES.out.examples + """ + } + } + } + when { + process { + """ + input[0] = DEEPVARIANT_CALLVARIANTS.out.call_variants_tfrecords.join( + DEEPVARIANT_MAKEEXAMPLES.out.gvcf, + failOnMismatch: true + ) + input[1] = [ + [ id:'genome'], + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + ] + input[2] = [ + [ id:'genome'], + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) + ] + input[3] = [ + [],[] + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("homo_sapiens - wgs - stub") { + options "-stub" + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], + [], + [], + [], + ] + input[1] = [ + [ id:'genome'], + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + ] + input[2] = [ + [ id:'genome'], + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) + ] + input[3] = [ + [],[] + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match("stub") } + ) + } + } + +} diff --git a/modules/nf-core/deepvariant/postprocessvariants/tests/main.nf.test.snap b/modules/nf-core/deepvariant/postprocessvariants/tests/main.nf.test.snap new file mode 100644 index 00000000000..5a29c624e50 --- /dev/null +++ b/modules/nf-core/deepvariant/postprocessvariants/tests/main.nf.test.snap @@ -0,0 +1,180 @@ +{ + "stub": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "test.g.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "3": [ + [ + { + "id": "test", + "single_end": false + }, + "test.g.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "4": [ + "versions.yml:md5,37f0e454a6983de82f7a93eb39849985" + ], + "gvcf": [ + [ + { + "id": "test", + "single_end": false + }, + "test.g.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "gvcf_tbi": [ + [ + { + "id": "test", + "single_end": false + }, + "test.g.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "vcf": [ + [ + { + "id": "test", + "single_end": false + }, + "test.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "vcf_tbi": [ + [ + { + "id": "test", + "single_end": false + }, + "test.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "versions": [ + "versions.yml:md5,37f0e454a6983de82f7a93eb39849985" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-08-09T16:40:38.231189" + }, + "homo_sapiens - wgs": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.vcf.gz:md5,8b8ab4a675f01e437aa72e1438a717d0" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.vcf.gz.tbi:md5,0000833138104e87b05eaa906821eb21" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "test.g.vcf.gz:md5,0a629e1745926cfcedf4b169046a921a" + ] + ], + "3": [ + [ + { + "id": "test", + "single_end": false + }, + "test.g.vcf.gz.tbi:md5,49503913c28ec70a6f4aa52f6b357b4d" + ] + ], + "4": [ + "versions.yml:md5,b1d5ddb90c4a59a1a3fdace9dcc8445c" + ], + "gvcf": [ + [ + { + "id": "test", + "single_end": false + }, + "test.g.vcf.gz:md5,0a629e1745926cfcedf4b169046a921a" + ] + ], + "gvcf_tbi": [ + [ + { + "id": "test", + "single_end": false + }, + "test.g.vcf.gz.tbi:md5,49503913c28ec70a6f4aa52f6b357b4d" + ] + ], + "vcf": [ + [ + { + "id": "test", + "single_end": false + }, + "test.vcf.gz:md5,8b8ab4a675f01e437aa72e1438a717d0" + ] + ], + "vcf_tbi": [ + [ + { + "id": "test", + "single_end": false + }, + "test.vcf.gz.tbi:md5,0000833138104e87b05eaa906821eb21" + ] + ], + "versions": [ + "versions.yml:md5,b1d5ddb90c4a59a1a3fdace9dcc8445c" + ] + } + ], + "meta": { + "nf-test": "0.9.0", + "nextflow": "24.04.4" + }, + "timestamp": "2024-08-09T16:46:15.793662" + } +} \ No newline at end of file diff --git a/modules/nf-core/deepvariant/postprocessvariants/tests/nextflow.config b/modules/nf-core/deepvariant/postprocessvariants/tests/nextflow.config new file mode 100644 index 00000000000..070b4892f86 --- /dev/null +++ b/modules/nf-core/deepvariant/postprocessvariants/tests/nextflow.config @@ -0,0 +1,10 @@ +process { + withName: "DEEPVARIANT_CALLVARIANTS" { + ext.args = '--checkpoint "/opt/models/wgs"' + } +} +process { + withName: "DEEPVARIANT_MAKEEXAMPLES" { + ext.args = '--channels "insert_size"' + } +} diff --git a/modules/nf-core/deepvariant/postprocessvariants/tests/tags.yml b/modules/nf-core/deepvariant/postprocessvariants/tests/tags.yml new file mode 100644 index 00000000000..d26188cd7a2 --- /dev/null +++ b/modules/nf-core/deepvariant/postprocessvariants/tests/tags.yml @@ -0,0 +1,2 @@ +deepvariant/postprocessvariants: + - modules/nf-core/deepvariant/postprocessvariants/** diff --git a/modules/nf-core/deepvariant/rundeepvariant/main.nf b/modules/nf-core/deepvariant/rundeepvariant/main.nf new file mode 100644 index 00000000000..7f99c53f6d2 --- /dev/null +++ b/modules/nf-core/deepvariant/rundeepvariant/main.nf @@ -0,0 +1,78 @@ +process DEEPVARIANT_RUNDEEPVARIANT { + tag "$meta.id" + label 'process_high' + + // FIXME Conda is not supported at the moment + // BUG https://github.com/nf-core/modules/issues/1754 + // BUG https://github.com/bioconda/bioconda-recipes/issues/30310 + container "nf-core/deepvariant:1.6.1" + + input: + tuple val(meta), path(input), path(index), path(intervals) + tuple val(meta2), path(fasta) + tuple val(meta3), path(fai) + tuple val(meta4), path(gzi) + tuple val(meta5), path(par_bed) + + output: + tuple val(meta), path("${prefix}.vcf.gz") , emit: vcf + tuple val(meta), path("${prefix}.vcf.gz.tbi") , emit: vcf_tbi + tuple val(meta), path("${prefix}.g.vcf.gz") , emit: gvcf + tuple val(meta), path("${prefix}.g.vcf.gz.tbi"), emit: gvcf_tbi + path "versions.yml" , emit: versions + + when: + task.ext.when == null || task.ext.when + + script: + // Exit if running this module with -profile conda / -profile mamba + if (workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1) { + error "DEEPVARIANT module does not support Conda. Please use Docker / Singularity / Podman instead." + } + def args = task.ext.args ?: '' + prefix = task.ext.prefix ?: "${meta.id}" + def regions = intervals ? "--regions=${intervals}" : "" + def par_regions = par_bed ? "--par_regions_bed=${par_bed}" : "" + // WARN https://github.com/nf-core/modules/pull/5801#issuecomment-2194293755 + // FIXME Revert this on next version bump + def VERSION = '1.6.1' + + """ + /opt/deepvariant/bin/run_deepvariant \\ + --ref=${fasta} \\ + --reads=${input} \\ + --output_vcf=${prefix}.vcf.gz \\ + --output_gvcf=${prefix}.g.vcf.gz \\ + ${args} \\ + ${regions} \\ + ${par_regions} \\ + --intermediate_results_dir=tmp \\ + --num_shards=${task.cpus} + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + deepvariant: $VERSION + END_VERSIONS + """ + + stub: + // Exit if running this module with -profile conda / -profile mamba + if (workflow.profile.tokenize(',').intersect(['conda', 'mamba']).size() >= 1) { + error "DEEPVARIANT module does not support Conda. Please use Docker / Singularity / Podman instead." + } + prefix = task.ext.prefix ?: "${meta.id}" + // WARN https://github.com/nf-core/modules/pull/5801#issuecomment-2194293755 + // FIXME Revert this on next version bump + def VERSION = '1.6.1' + """ + touch ${prefix}.vcf.gz + touch ${prefix}.vcf.gz.tbi + touch ${prefix}.g.vcf.gz + touch ${prefix}.g.vcf.gz.tbi + + cat <<-END_VERSIONS > versions.yml + "${task.process}": + deepvariant: $VERSION + END_VERSIONS + """ +} diff --git a/modules/nf-core/deepvariant/rundeepvariant/meta.yml b/modules/nf-core/deepvariant/rundeepvariant/meta.yml new file mode 100644 index 00000000000..a6ee5499285 --- /dev/null +++ b/modules/nf-core/deepvariant/rundeepvariant/meta.yml @@ -0,0 +1,92 @@ +name: deepvariant_rundeepvariant +description: DeepVariant is an analysis pipeline that uses a deep neural network to call genetic variants from next-generation DNA sequencing data +keywords: + - variant calling + - machine learning + - neural network +tools: + - deepvariant: + description: DeepVariant is an analysis pipeline that uses a deep neural network to call genetic variants from next-generation DNA sequencing data + homepage: https://github.com/google/deepvariant + documentation: https://github.com/google/deepvariant + tool_dev_url: https://github.com/google/deepvariant + doi: "10.1038/nbt.4235" + licence: ["BSD-3-clause"] +input: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - input: + type: file + description: BAM/CRAM file + pattern: "*.bam/cram" + - index: + type: file + description: Index of BAM/CRAM file + pattern: "*.bai/crai" + - interval: + type: file + description: Interval file for targeted regions + pattern: "*.bed" + - meta2: + type: map + description: | + Groovy Map containing reference information + e.g. [ id:'genome' ] + - fasta: + type: file + description: The reference fasta file + pattern: "*.fasta" + - meta3: + type: map + description: | + Groovy Map containing reference information + e.g. [ id:'genome' ] + - fai: + type: file + description: Index of reference fasta file + pattern: "*.fai" + - meta4: + type: map + description: | + Groovy Map containing reference information + e.g. [ id:'genome' ] + - gzi: + type: file + description: GZI index of reference fasta file + pattern: "*.gzi" + - meta5: + type: map + description: | + Groovy Map containing reference information + e.g. [ id:'genome' ] + - par_bed: + type: file + description: BED file containing PAR regions + pattern: "*.bed" +output: + - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - vcf: + type: file + description: Compressed VCF file + pattern: "*.vcf.gz" + - gvcf: + type: file + description: Compressed GVCF file + pattern: "*.g.vcf.gz" + - version: + type: file + description: File containing software version + pattern: "*.{version.txt}" +authors: + - "@abhi18av" + - "@ramprasadn" +maintainers: + - "@abhi18av" + - "@ramprasadn" diff --git a/modules/nf-core/deepvariant/rundeepvariant/tests/main.nf.test b/modules/nf-core/deepvariant/rundeepvariant/tests/main.nf.test new file mode 100644 index 00000000000..0790fb81362 --- /dev/null +++ b/modules/nf-core/deepvariant/rundeepvariant/tests/main.nf.test @@ -0,0 +1,166 @@ +nextflow_process { + + name "Test Process DEEPVARIANT_RUNDEEPVARIANT" + script "../main.nf" + process "DEEPVARIANT_RUNDEEPVARIANT" + + tag "deepvariant/rundeepvariant" + tag "deepvariant" + tag "modules" + tag "modules_nfcore" + + test("homo_sapiens - [bam, bai] - fasta - fai") { + when { + config "./nextflow.config" + + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + 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] = [ + [ id:'genome'], + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + ] + input[2] = [ + [ id:'genome'], + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) + ] + input[3] = [ + [],[] + ] + input[4] = [ + [],[] + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("homo_sapiens - [cram, crai, genome_bed] - fasta - fai") { + config "./nextflow-intervals.config" + + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram', checkIfExists: true), + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram.crai', checkIfExists: true), + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.bed', checkIfExists: true) + ] + input[1] = [ + [ id:'genome'], + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + ] + input[2] = [ + [ id:'genome'], + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) + ] + input[3] = [ + [],[] + ] + input[4] = [ + [],[] + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("homo_sapiens - [cram, crai, genome_bed] - fasta - fai - par_bed") { + config "./nextflow-non-autosomal-calling.config" + tag "test" + when { + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram', checkIfExists: true), + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram.crai', checkIfExists: true), + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.bed', checkIfExists: true) + ] + input[1] = [ + [ id:'genome'], + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + ] + input[2] = [ + [ id:'genome'], + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) + ] + input[3] = [ + [],[] + ] + input[4] = [ + [ id:'genome'], + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.blacklist_intervals.bed', checkIfExists: true) + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + + test("homo_sapiens - [bam, bai] - fasta_gz - fasta_gz_fai") { + when { + config "./nextflow.config" + + process { + """ + input[0] = [ + [ id:'test', single_end:false ], // meta map + 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] = [ + [ id:'genome'], + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.fasta.gz', checkIfExists: true) + ] + input[2] = [ + [ id:'genome'], + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.fasta.gz.fai', checkIfExists: true) + ] + input[3] = [ + [ id:'genome'], + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.fasta.gz.gzi', checkIfExists: true) + ] + input[4] = [ + [],[] + ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + +} diff --git a/modules/nf-core/deepvariant/tests/main.nf.test.snap b/modules/nf-core/deepvariant/rundeepvariant/tests/main.nf.test.snap similarity index 91% rename from modules/nf-core/deepvariant/tests/main.nf.test.snap rename to modules/nf-core/deepvariant/rundeepvariant/tests/main.nf.test.snap index 04f87774241..1ec351eecc9 100644 --- a/modules/nf-core/deepvariant/tests/main.nf.test.snap +++ b/modules/nf-core/deepvariant/rundeepvariant/tests/main.nf.test.snap @@ -39,7 +39,7 @@ ] ], "4": [ - "versions.yml:md5,efbdcb1ad96e0209b31bcafedd0017a8" + "versions.yml:md5,a251d8d9f5e8b737d8298eead96c0890" ], "gvcf": [ [ @@ -78,15 +78,15 @@ ] ], "versions": [ - "versions.yml:md5,efbdcb1ad96e0209b31bcafedd0017a8" + "versions.yml:md5,a251d8d9f5e8b737d8298eead96c0890" ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.0", + "nextflow": "24.04.4" }, - "timestamp": "2024-07-01T12:09:40.987117305" + "timestamp": "2024-08-29T11:36:27.325363" }, "homo_sapiens - [bam, bai] - fasta - fai": { "content": [ @@ -128,7 +128,7 @@ ] ], "4": [ - "versions.yml:md5,efbdcb1ad96e0209b31bcafedd0017a8" + "versions.yml:md5,a251d8d9f5e8b737d8298eead96c0890" ], "gvcf": [ [ @@ -167,15 +167,15 @@ ] ], "versions": [ - "versions.yml:md5,efbdcb1ad96e0209b31bcafedd0017a8" + "versions.yml:md5,a251d8d9f5e8b737d8298eead96c0890" ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.0", + "nextflow": "24.04.4" }, - "timestamp": "2024-07-01T12:08:47.058887374" + "timestamp": "2024-08-29T11:34:41.779153" }, "homo_sapiens - [cram, crai, genome_bed] - fasta - fai": { "content": [ @@ -217,7 +217,7 @@ ] ], "4": [ - "versions.yml:md5,efbdcb1ad96e0209b31bcafedd0017a8" + "versions.yml:md5,a251d8d9f5e8b737d8298eead96c0890" ], "gvcf": [ [ @@ -256,15 +256,15 @@ ] ], "versions": [ - "versions.yml:md5,efbdcb1ad96e0209b31bcafedd0017a8" + "versions.yml:md5,a251d8d9f5e8b737d8298eead96c0890" ] } ], "meta": { - "nf-test": "0.8.4", - "nextflow": "24.04.2" + "nf-test": "0.9.0", + "nextflow": "24.04.4" }, - "timestamp": "2024-07-01T12:09:13.952808655" + "timestamp": "2024-08-29T11:35:16.993129" }, "homo_sapiens - [cram, crai, genome_bed] - fasta - fai - par_bed": { "content": [ @@ -306,7 +306,7 @@ ] ], "4": [ - "versions.yml:md5,efbdcb1ad96e0209b31bcafedd0017a8" + "versions.yml:md5,a251d8d9f5e8b737d8298eead96c0890" ], "gvcf": [ [ @@ -345,14 +345,14 @@ ] ], "versions": [ - "versions.yml:md5,efbdcb1ad96e0209b31bcafedd0017a8" + "versions.yml:md5,a251d8d9f5e8b737d8298eead96c0890" ] } ], "meta": { "nf-test": "0.9.0", - "nextflow": "24.04.3" + "nextflow": "24.04.4" }, - "timestamp": "2024-07-23T14:29:24.939680679" + "timestamp": "2024-08-29T11:35:52.23093" } -} +} \ No newline at end of file diff --git a/modules/nf-core/deepvariant/tests/nextflow-intervals.config b/modules/nf-core/deepvariant/rundeepvariant/tests/nextflow-intervals.config similarity index 70% rename from modules/nf-core/deepvariant/tests/nextflow-intervals.config rename to modules/nf-core/deepvariant/rundeepvariant/tests/nextflow-intervals.config index 6d135f9f109..78d8d5982ae 100644 --- a/modules/nf-core/deepvariant/tests/nextflow-intervals.config +++ b/modules/nf-core/deepvariant/rundeepvariant/tests/nextflow-intervals.config @@ -1,6 +1,6 @@ process { - withName: DEEPVARIANT { + withName: DEEPVARIANT_RUNDEEPVARIANT { ext.args = '--model_type=WGS ' ext.prefix = { "${meta.id}_out" } } diff --git a/modules/nf-core/deepvariant/tests/nextflow-non-autosomal-calling.config b/modules/nf-core/deepvariant/rundeepvariant/tests/nextflow-non-autosomal-calling.config similarity index 74% rename from modules/nf-core/deepvariant/tests/nextflow-non-autosomal-calling.config rename to modules/nf-core/deepvariant/rundeepvariant/tests/nextflow-non-autosomal-calling.config index 4be8986bd6e..6d265292ab6 100644 --- a/modules/nf-core/deepvariant/tests/nextflow-non-autosomal-calling.config +++ b/modules/nf-core/deepvariant/rundeepvariant/tests/nextflow-non-autosomal-calling.config @@ -1,6 +1,6 @@ process { - withName: DEEPVARIANT { + withName: DEEPVARIANT_RUNDEEPVARIANT { ext.args = '--model_type=WGS --haploid_contigs chr22' ext.prefix = { "${meta.id}_out" } } diff --git a/modules/nf-core/deepvariant/tests/nextflow.config b/modules/nf-core/deepvariant/rundeepvariant/tests/nextflow.config similarity index 75% rename from modules/nf-core/deepvariant/tests/nextflow.config rename to modules/nf-core/deepvariant/rundeepvariant/tests/nextflow.config index d335d30b54f..77e355cae82 100644 --- a/modules/nf-core/deepvariant/tests/nextflow.config +++ b/modules/nf-core/deepvariant/rundeepvariant/tests/nextflow.config @@ -1,6 +1,6 @@ process { - withName: DEEPVARIANT { + withName: DEEPVARIANT_RUNDEEPVARIANT { ext.args = ' --regions=\"chr22:0-40001\" --model_type=WGS ' ext.prefix = { "${meta.id}_out" } } diff --git a/modules/nf-core/deepvariant/rundeepvariant/tests/tags.yml b/modules/nf-core/deepvariant/rundeepvariant/tests/tags.yml new file mode 100644 index 00000000000..958b8e4149b --- /dev/null +++ b/modules/nf-core/deepvariant/rundeepvariant/tests/tags.yml @@ -0,0 +1,2 @@ +deepvariant/rundeepvariant: + - modules/nf-core/deepvariant/rundeepvariant/** diff --git a/modules/nf-core/deepvariant/tests/main.nf.test b/modules/nf-core/deepvariant/tests/main.nf.test index 1776523326a..cf62430fa5a 100644 --- a/modules/nf-core/deepvariant/tests/main.nf.test +++ b/modules/nf-core/deepvariant/tests/main.nf.test @@ -1,6 +1,6 @@ nextflow_process { - name "Test Process DEEPVARIANT" + name "Deprecated module DEEPVARIANT Test" script "../main.nf" process "DEEPVARIANT" @@ -8,10 +8,8 @@ nextflow_process { tag "modules" tag "modules_nfcore" - test("homo_sapiens - [bam, bai] - fasta - fai") { + test("DEEPVARIANT top-level process is deprecated and should fail") { when { - config "./nextflow.config" - process { """ input[0] = [ @@ -40,126 +38,8 @@ nextflow_process { then { assertAll( - { assert process.success }, - { assert snapshot(process.out).match() } - ) - } - } - - test("homo_sapiens - [cram, crai, genome_bed] - fasta - fai") { - config "./nextflow-intervals.config" - - when { - process { - """ - input[0] = [ - [ id:'test', single_end:false ], // meta map - file(params.modules_testdata_base_path + '/genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram', checkIfExists: true), - file(params.modules_testdata_base_path + '/genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram.crai', checkIfExists: true), - file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.bed', checkIfExists: true) - ] - input[1] = [ - [ id:'genome'], - file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) - ] - input[2] = [ - [ id:'genome'], - file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) - ] - input[3] = [ - [],[] - ] - input[4] = [ - [],[] - ] - """ - } - } - - then { - assertAll( - { assert process.success }, - { assert snapshot(process.out).match() } + { assert !process.success } ) } } - - test("homo_sapiens - [cram, crai, genome_bed] - fasta - fai - par_bed") { - config "./nextflow-non-autosomal-calling.config" - tag "test" - when { - process { - """ - input[0] = [ - [ id:'test', single_end:false ], // meta map - file(params.modules_testdata_base_path + '/genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram', checkIfExists: true), - file(params.modules_testdata_base_path + '/genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram.crai', checkIfExists: true), - file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.bed', checkIfExists: true) - ] - input[1] = [ - [ id:'genome'], - file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) - ] - input[2] = [ - [ id:'genome'], - file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) - ] - input[3] = [ - [],[] - ] - input[4] = [ - [ id:'genome'], - file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.blacklist_intervals.bed', checkIfExists: true) - ] - """ - } - } - - then { - assertAll( - { assert process.success }, - { assert snapshot(process.out).match() } - ) - } - } - - test("homo_sapiens - [bam, bai] - fasta_gz - fasta_gz_fai") { - when { - config "./nextflow.config" - - process { - """ - input[0] = [ - [ id:'test', single_end:false ], // meta map - 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] = [ - [ id:'genome'], - file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.fasta.gz', checkIfExists: true) - ] - input[2] = [ - [ id:'genome'], - file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.fasta.gz.fai', checkIfExists: true) - ] - input[3] = [ - [ id:'genome'], - file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.fasta.gz.gzi', checkIfExists: true) - ] - input[4] = [ - [],[] - ] - """ - } - } - - then { - assertAll( - { assert process.success }, - { assert snapshot(process.out).match() } - ) - } - } - -} \ No newline at end of file +} diff --git a/subworkflows/nf-core/deepvariant/README.md b/subworkflows/nf-core/deepvariant/README.md new file mode 100644 index 00000000000..6f816c22ed5 --- /dev/null +++ b/subworkflows/nf-core/deepvariant/README.md @@ -0,0 +1,8 @@ +# DeepVariant subworkflow + +Usage: the input channel should contain tuples of three elements: `meta`, an alignment file in bam or +cram format, and a corresponding index. + +It is very important that the input channel's `meta` is unique for all the input elements, because the subworkflow does a join on `meta`. + +Please note the important configuration items listed in the `deepvariant` module's README file. It is required to use the configuration to specify the input "channels" (data types to extract from bam file) for `DEEPVARIANT_MAKEEXAMPLES`, and the model to run for `DEEPVARIANT_CALLVARIANTS`. The correct arguments for a specific model (data type) can be determined by manually using the `run_deepvariant` command from the Docker / Singularity image with the `--dry_run` option. diff --git a/subworkflows/nf-core/deepvariant/main.nf b/subworkflows/nf-core/deepvariant/main.nf new file mode 100644 index 00000000000..02a5114c30b --- /dev/null +++ b/subworkflows/nf-core/deepvariant/main.nf @@ -0,0 +1,45 @@ + +include { DEEPVARIANT_MAKEEXAMPLES } from '../../../modules/nf-core/deepvariant/makeexamples/main' +include { DEEPVARIANT_CALLVARIANTS } from '../../../modules/nf-core/deepvariant/callvariants/main' +include { DEEPVARIANT_POSTPROCESSVARIANTS } from '../../../modules/nf-core/deepvariant/postprocessvariants/main' + +workflow DEEPVARIANT { + take: + ch_input // channel: [ val(meta), path(input), path(index), path(intervals)] + ch_fasta // channel: [ val(meta2), path(fasta) ] + ch_fai // channel: [ val(meta3), path(fail) ] + ch_gzi // channel: [ val(meta4), path(gzi) ] + ch_par_bed // channel: [ val(meta5), path(par_bed) ] + + main: + + ch_versions = Channel.empty() + + DEEPVARIANT_MAKEEXAMPLES(ch_input, ch_fasta, ch_fai, ch_gzi, ch_par_bed) + ch_versions = ch_versions.mix(DEEPVARIANT_MAKEEXAMPLES.out.versions.first()) + + DEEPVARIANT_CALLVARIANTS(DEEPVARIANT_MAKEEXAMPLES.out.examples) + ch_versions = ch_versions.mix(DEEPVARIANT_CALLVARIANTS.out.versions.first()) + + // Input to postprocessing step needs both the gvcfs from MAKEEXAMPLES and the variant + // calls from CALLVARIANTS. Joining on meta, which is assumed to be unique. + ch_postproc_input = DEEPVARIANT_CALLVARIANTS.out.call_variants_tfrecords.join( + DEEPVARIANT_MAKEEXAMPLES.out.gvcf, + failOnMismatch: true + ) + DEEPVARIANT_POSTPROCESSVARIANTS( + ch_postproc_input, + ch_fasta, + ch_fai, + ch_gzi + ) + + ch_versions = ch_versions.mix(DEEPVARIANT_POSTPROCESSVARIANTS.out.versions.first()) + + emit: + vcf = DEEPVARIANT_POSTPROCESSVARIANTS.out.vcf + vcf_tbi = DEEPVARIANT_POSTPROCESSVARIANTS.out.vcf_tbi + gvcf = DEEPVARIANT_POSTPROCESSVARIANTS.out.gvcf + gvcf_tbi = DEEPVARIANT_POSTPROCESSVARIANTS.out.gvcf_tbi + versions = ch_versions +} diff --git a/subworkflows/nf-core/deepvariant/meta.yml b/subworkflows/nf-core/deepvariant/meta.yml new file mode 100644 index 00000000000..6321fc24c66 --- /dev/null +++ b/subworkflows/nf-core/deepvariant/meta.yml @@ -0,0 +1,76 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/subworkflows/yaml-schema.json +name: deepvariant +description: DeepVariant is an analysis pipeline that uses a deep neural network to call genetic variants from next-generation DNA sequencing data +keywords: + - variant calling + - machine learning + - neural network +components: + - deepvariant/makeexamples + - deepvariant/callvariants + - deepvariant/postprocessvariants +input: + - ch_input: + type: list + description: | + Input aligned reads in bam or cram format, with index, and optional intervals BED file + Structure: [ val(meta), path(bam_or_cram), path(bai_or_crai), path(intervals_bed) ] + - ch_fasta: + type: file + description: | + Reference genome + Structure: [ val(meta2), path(fasta) ] + - ch_fai: + type: string + description: | + Reference genome index in fai format + Structure: [ val(meta3), path(fai) ] + - ch_gzi: + type: string + description: | + Reference genome index in gzi format (either gzi or fai should be used) + Structure: [ val(meta4), val(gzi) ] + - ch_par_bed: + type: string + description: | + bed file of pseudoautosomal regions (optional) + Structure: [ val(meta5), val(par_bed) ] + pattern: "*.bed" +output: + - vcf: + type: file + description: | + Variant calls + Structure: [ val(meta), path(vcf) ] + pattern: "*.vcf.gz" + - vcf_tbi: + type: file + description: | + Index for variant call file + Structure: [ val(meta), path(vcf_tbi) ] + pattern: "*.tbi" + - gvcf: + type: file + description: | + Variant call file with genomic coverage information + Structure: [ val(meta), path(gvcf) ] + pattern: "*.g.vcf.gz" + - gvcf_tbi: + type: file + description: | + Index for the GVCF. + Structure: [ val(meta), path(gvcf_tbi) ] + pattern: "*.tbi" + - versions: + type: file + description: | + File containing software versions + Structure: path(versions.yml) + pattern: "versions.yml" +authors: + - "@abhi18av" + - "@ramprasadn" + - "@fa2k" +maintainers: + - "@abhi18av" + - "@ramprasadn" diff --git a/subworkflows/nf-core/deepvariant/tests/main.nf.test b/subworkflows/nf-core/deepvariant/tests/main.nf.test new file mode 100644 index 00000000000..4195d4730e7 --- /dev/null +++ b/subworkflows/nf-core/deepvariant/tests/main.nf.test @@ -0,0 +1,105 @@ +nextflow_workflow { + + name "Test Subworkflow DEEPVARIANT" + script "../main.nf" + config "./nextflow.config" + workflow "DEEPVARIANT" + + tag "subworkflows" + tag "subworkflows_nfcore" + tag "subworkflows/deepvariant" + + tag "deepvariant" + tag "deepvariant/makeexamples" + tag "deepvariant/callvariants" + tag "deepvariant/postprocessvariants" + + test("homo_sapiens - two inputs - bam - fasta - fai") { + when { + workflow { + """ + input[0] = Channel.of( + [ + [ id:'test', single_end:false ], // meta map + 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), + [] + ], + [ + [ id:'test2', single_end:false ], // meta map + 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] = [ + [ id:'genome'], + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + ] + input[2] = [ + [ id:'genome'], + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) + ] + input[3] = [ + [],[] + ] + input[4] = [ + [],[] + ] + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot(workflow.out).match() } + ) + } + } + + test("homo_sapiens - different samples and regions - cram - fasta - fai") { + + when { + workflow { + """ + input[0] = Channel.of( + [ + [ id:'test', single_end:false ], // meta map + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram', checkIfExists: true), + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/illumina/cram/test.paired_end.sorted.cram.crai', checkIfExists: true), + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.bed', checkIfExists: true) + ], + [ + [ id:'test2', single_end:false ], // meta map + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/illumina/bam/test2.paired_end.sorted.bam', checkIfExists: true), + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/illumina/bam/test2.paired_end.sorted.bam.bai', checkIfExists: true), + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.bed', checkIfExists: true) + ] + ) + input[1] = [ + [ id:'genome'], + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.fasta', checkIfExists: true) + ] + input[2] = [ + [ id:'genome'], + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.fasta.fai', checkIfExists: true) + ] + input[3] = [ + [],[] + ] + input[4] = [ + [],[] + ] + """ + } + } + + then { + assertAll( + { assert workflow.success }, + { assert snapshot(workflow.out).match() } + ) + } + } + +} diff --git a/subworkflows/nf-core/deepvariant/tests/main.nf.test.snap b/subworkflows/nf-core/deepvariant/tests/main.nf.test.snap new file mode 100644 index 00000000000..08105c1b0f0 --- /dev/null +++ b/subworkflows/nf-core/deepvariant/tests/main.nf.test.snap @@ -0,0 +1,300 @@ +{ + "homo_sapiens - different samples and regions - cram - fasta - fai": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.vcf.gz:md5,8b8ab4a675f01e437aa72e1438a717d0" + ], + [ + { + "id": "test2", + "single_end": false + }, + "test2.vcf.gz:md5,5c36d104b2eb6e410788990928667b93" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.vcf.gz.tbi:md5,0000833138104e87b05eaa906821eb21" + ], + [ + { + "id": "test2", + "single_end": false + }, + "test2.vcf.gz.tbi:md5,5451379c05fa59498b2b8aafcb18c9eb" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "test.g.vcf.gz:md5,0a629e1745926cfcedf4b169046a921a" + ], + [ + { + "id": "test2", + "single_end": false + }, + "test2.g.vcf.gz:md5,2aefd9545ffefe9af0730dc4ffc5f638" + ] + ], + "3": [ + [ + { + "id": "test", + "single_end": false + }, + "test.g.vcf.gz.tbi:md5,49503913c28ec70a6f4aa52f6b357b4d" + ], + [ + { + "id": "test2", + "single_end": false + }, + "test2.g.vcf.gz.tbi:md5,58d2e7fa7cf98d56fd734db6d59f8489" + ] + ], + "4": [ + "versions.yml:md5,5e6e7451f9819e2e0c33ad0d1b22d3b3", + "versions.yml:md5,c9c9c7000dc16bcb7e3107e7333481de", + "versions.yml:md5,cb2f0f2fe645633ed7d6528999bde458" + ], + "gvcf": [ + [ + { + "id": "test", + "single_end": false + }, + "test.g.vcf.gz:md5,0a629e1745926cfcedf4b169046a921a" + ], + [ + { + "id": "test2", + "single_end": false + }, + "test2.g.vcf.gz:md5,2aefd9545ffefe9af0730dc4ffc5f638" + ] + ], + "gvcf_tbi": [ + [ + { + "id": "test", + "single_end": false + }, + "test.g.vcf.gz.tbi:md5,49503913c28ec70a6f4aa52f6b357b4d" + ], + [ + { + "id": "test2", + "single_end": false + }, + "test2.g.vcf.gz.tbi:md5,58d2e7fa7cf98d56fd734db6d59f8489" + ] + ], + "vcf": [ + [ + { + "id": "test", + "single_end": false + }, + "test.vcf.gz:md5,8b8ab4a675f01e437aa72e1438a717d0" + ], + [ + { + "id": "test2", + "single_end": false + }, + "test2.vcf.gz:md5,5c36d104b2eb6e410788990928667b93" + ] + ], + "vcf_tbi": [ + [ + { + "id": "test", + "single_end": false + }, + "test.vcf.gz.tbi:md5,0000833138104e87b05eaa906821eb21" + ], + [ + { + "id": "test2", + "single_end": false + }, + "test2.vcf.gz.tbi:md5,5451379c05fa59498b2b8aafcb18c9eb" + ] + ], + "versions": [ + "versions.yml:md5,5e6e7451f9819e2e0c33ad0d1b22d3b3", + "versions.yml:md5,c9c9c7000dc16bcb7e3107e7333481de", + "versions.yml:md5,cb2f0f2fe645633ed7d6528999bde458" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.3" + }, + "timestamp": "2024-08-16T16:20:06.112232952" + }, + "homo_sapiens - two inputs - bam - fasta - fai": { + "content": [ + { + "0": [ + [ + { + "id": "test", + "single_end": false + }, + "test.vcf.gz:md5,8b8ab4a675f01e437aa72e1438a717d0" + ], + [ + { + "id": "test2", + "single_end": false + }, + "test2.vcf.gz:md5,8b8ab4a675f01e437aa72e1438a717d0" + ] + ], + "1": [ + [ + { + "id": "test", + "single_end": false + }, + "test.vcf.gz.tbi:md5,0000833138104e87b05eaa906821eb21" + ], + [ + { + "id": "test2", + "single_end": false + }, + "test2.vcf.gz.tbi:md5,0000833138104e87b05eaa906821eb21" + ] + ], + "2": [ + [ + { + "id": "test", + "single_end": false + }, + "test.g.vcf.gz:md5,0a629e1745926cfcedf4b169046a921a" + ], + [ + { + "id": "test2", + "single_end": false + }, + "test2.g.vcf.gz:md5,0a629e1745926cfcedf4b169046a921a" + ] + ], + "3": [ + [ + { + "id": "test", + "single_end": false + }, + "test.g.vcf.gz.tbi:md5,49503913c28ec70a6f4aa52f6b357b4d" + ], + [ + { + "id": "test2", + "single_end": false + }, + "test2.g.vcf.gz.tbi:md5,49503913c28ec70a6f4aa52f6b357b4d" + ] + ], + "4": [ + "versions.yml:md5,5e6e7451f9819e2e0c33ad0d1b22d3b3", + "versions.yml:md5,c9c9c7000dc16bcb7e3107e7333481de", + "versions.yml:md5,cb2f0f2fe645633ed7d6528999bde458" + ], + "gvcf": [ + [ + { + "id": "test", + "single_end": false + }, + "test.g.vcf.gz:md5,0a629e1745926cfcedf4b169046a921a" + ], + [ + { + "id": "test2", + "single_end": false + }, + "test2.g.vcf.gz:md5,0a629e1745926cfcedf4b169046a921a" + ] + ], + "gvcf_tbi": [ + [ + { + "id": "test", + "single_end": false + }, + "test.g.vcf.gz.tbi:md5,49503913c28ec70a6f4aa52f6b357b4d" + ], + [ + { + "id": "test2", + "single_end": false + }, + "test2.g.vcf.gz.tbi:md5,49503913c28ec70a6f4aa52f6b357b4d" + ] + ], + "vcf": [ + [ + { + "id": "test", + "single_end": false + }, + "test.vcf.gz:md5,8b8ab4a675f01e437aa72e1438a717d0" + ], + [ + { + "id": "test2", + "single_end": false + }, + "test2.vcf.gz:md5,8b8ab4a675f01e437aa72e1438a717d0" + ] + ], + "vcf_tbi": [ + [ + { + "id": "test", + "single_end": false + }, + "test.vcf.gz.tbi:md5,0000833138104e87b05eaa906821eb21" + ], + [ + { + "id": "test2", + "single_end": false + }, + "test2.vcf.gz.tbi:md5,0000833138104e87b05eaa906821eb21" + ] + ], + "versions": [ + "versions.yml:md5,5e6e7451f9819e2e0c33ad0d1b22d3b3", + "versions.yml:md5,c9c9c7000dc16bcb7e3107e7333481de", + "versions.yml:md5,cb2f0f2fe645633ed7d6528999bde458" + ] + } + ], + "meta": { + "nf-test": "0.8.4", + "nextflow": "24.04.3" + }, + "timestamp": "2024-08-16T16:18:03.021031138" + } +} \ No newline at end of file diff --git a/subworkflows/nf-core/deepvariant/tests/nextflow.config b/subworkflows/nf-core/deepvariant/tests/nextflow.config new file mode 100644 index 00000000000..be9854791fb --- /dev/null +++ b/subworkflows/nf-core/deepvariant/tests/nextflow.config @@ -0,0 +1,8 @@ +process { + withName: "DEEPVARIANT_MAKEEXAMPLES" { + ext.args = '--channels "insert_size"' + } + withName: "DEEPVARIANT_CALLVARIANTS" { + ext.args = '--checkpoint "/opt/models/wgs"' + } +} diff --git a/subworkflows/nf-core/deepvariant/tests/tags.yml b/subworkflows/nf-core/deepvariant/tests/tags.yml new file mode 100644 index 00000000000..ae5640d2330 --- /dev/null +++ b/subworkflows/nf-core/deepvariant/tests/tags.yml @@ -0,0 +1,2 @@ +subworkflows/deepvariant: + - subworkflows/nf-core/deepvariant/**