diff --git a/CHANGELOG.md b/CHANGELOG.md index d68b0072..d4726f68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - A new analysis option `mito` to call and annotate only mitochondrial variants [#608](https://github.com/nf-core/raredisease/pull/608) - An option to restrict analysis to specific contigs [#644](https://github.com/nf-core/raredisease/pull/644) - Fastp and ngsbits output files as input of MultiQC [#647](https://github.com/nf-core/raredisease/pull/647/). +- Replace DeepVariant process with a subworkflow [#651](https://github.com/nf-core/raredisease/pull/651) ### `Changed` diff --git a/conf/modules/call_snv_deepvariant.config b/conf/modules/call_snv_deepvariant.config index 348e95cc..72121ad6 100644 --- a/conf/modules/call_snv_deepvariant.config +++ b/conf/modules/call_snv_deepvariant.config @@ -21,11 +21,20 @@ process { ext.when = params.variant_caller.equals("deepvariant") } - withName: '.*CALL_SNV_DEEPVARIANT:DEEPVARIANT' { + withName: '.*CALL_SNV_DEEPVARIANT:DEEPVARIANT:DEEPVARIANT_MAKEEXAMPLES' { ext.args = { [ - "--model_type=${params.analysis_type.toUpperCase()}", + "--channels insert_size", meta.sex == "1" ? params.genome == 'GRCh37' ? '--haploid_contigs="X,Y"' : '--haploid_contigs="chrX,chrY"' : '' ].join(' ') } + } + + withName: '.*CALL_SNV_DEEPVARIANT:DEEPVARIANT:DEEPVARIANT_CALLVARIANTS' { + ext.args = { [ + "--checkpoint /opt/models/${params.analysis_type.toLowerCase()}", + ].join(' ') } + } + + withName: '.*CALL_SNV_DEEPVARIANT:DEEPVARIANT:DEEPVARIANT_POSTPROCESSVARIANTS' { ext.prefix = { "${meta.id}_deepvar" } } diff --git a/conf/test_full.config b/conf/test_full.config index 0fe2b4f2..c6df5f13 100644 --- a/conf/test_full.config +++ b/conf/test_full.config @@ -34,7 +34,7 @@ process { withName: 'MARKDUPLICATES' { memory = { check_max( 90.GB * task.attempt, 'memory' ) } } - withName: 'DEEPVARIANT' { + withName: '.*:DEEPVARIANT:DEEPVARIANT_CALLVARIANTS' { cpus = 24 memory = { check_max( 90.GB * task.attempt, 'memory' ) } } diff --git a/docs/usage.md b/docs/usage.md index 028a064d..cd91cf57 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -560,3 +560,22 @@ plugins { ``` This should go in your Nextflow configuration file, specified with `-c ` when running the pipeline. + +### Calling variants on the GPU with DeepVariant + +To use GPU for variant calling you have to override the container image. The GPU-enabled DeepVariant image is very large, so it's not used by default. You need to identify the DeepVariant version used by raredisease. Then replace the container image of the `DEEPVARIANT_CALLVARIANTS` process with one from Google's Docker Hub, `docker.io/google/deepvariant:X.Y.Z-gpu`, changing "X.Y.Z" to the version. + +For singularity / apptainer you can use containerOptions = '--nv' to enable GPU access. For Docker, use the `--gpus` option. + +If using a queue system like SLURM, or the Cloud, you usually have to enable certain options to get access to GPUs, e.g. the `queue` directive. If you run locally on a server with a single GPU, you can set `maxForks = 1` to prevent starting simultaneous GPU jobs for different samples. + +Configuration example: + +``` + withName:"DEEPVARIANT_CALLVARIANTS" { + cpus = 6 + containerOptions = '--nv' + container = 'docker.io/google/deepvariant:1.6.1-gpu' + maxForks = 1 + } +``` diff --git a/modules.json b/modules.json index ba502d28..c9cc2605 100644 --- a/modules.json +++ b/modules.json @@ -111,10 +111,20 @@ "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", "installed_by": ["modules"] }, - "deepvariant/rundeepvariant": { + "deepvariant/callvariants": { "branch": "master", "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", - "installed_by": ["modules"] + "installed_by": ["deepvariant"] + }, + "deepvariant/makeexamples": { + "branch": "master", + "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "installed_by": ["deepvariant"] + }, + "deepvariant/postprocessvariants": { + "branch": "master", + "git_sha": "666652151335353eef2fcd58880bcef5bc2928e1", + "installed_by": ["deepvariant"] }, "eklipse": { "branch": "master", @@ -517,6 +527,11 @@ }, "subworkflows": { "nf-core": { + "deepvariant": { + "branch": "master", + "git_sha": "f1236caa87bac87e75698af65281a795cded208c", + "installed_by": ["subworkflows"] + }, "utils_nextflow_pipeline": { "branch": "master", "git_sha": "3aa0aec1d52d492fe241919f0c6100ebf0074082", diff --git a/modules/nf-core/deepvariant/callvariants/main.nf b/modules/nf-core/deepvariant/callvariants/main.nf new file mode 100644 index 00000000..668b51ae --- /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 00000000..4507192c --- /dev/null +++ b/modules/nf-core/deepvariant/callvariants/meta.yml @@ -0,0 +1,48 @@ +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"] + identifier: biotools:deepvariant +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: + - meta: + type: list + description: | + Each output contains: unique ID string from input channel, meta, tfrecord file with variant calls. + - ${prefix}.call-*-of-*.tfrecord.gz: + type: list + description: | + Each output contains: unique ID string from input channel, meta, tfrecord file with variant calls. + - versions: + - versions.yml: + 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 00000000..72f04b51 --- /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 00000000..8f04ede7 --- /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 00000000..590aa060 --- /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 00000000..02e63f50 --- /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/makeexamples/main.nf b/modules/nf-core/deepvariant/makeexamples/main.nf new file mode 100644 index 00000000..022d0bf2 --- /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 00000000..6fb9f1b8 --- /dev/null +++ b/modules/nf-core/deepvariant/makeexamples/meta.yml @@ -0,0 +1,102 @@ +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"] + identifier: biotools:deepvariant +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: + - meta: + type: list + description: | + Tuple containing sample metadata and examples that can be used for calling + - ${prefix}.examples.tfrecord-*-of-*.gz{,.example_info.json}: + type: list + description: | + Tuple containing sample metadata and examples that can be used for calling + - gvcf: + - meta: + type: list + description: | + Tuple containing sample metadata and the GVCF data in tfrecord format + - ${prefix}.gvcf.tfrecord-*-of-*.gz: + type: list + description: | + Tuple containing sample metadata and the GVCF data in tfrecord format + - versions: + - versions.yml: + 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/rundeepvariant/tests/main.nf.test b/modules/nf-core/deepvariant/makeexamples/tests/main.nf.test similarity index 51% rename from modules/nf-core/deepvariant/rundeepvariant/tests/main.nf.test rename to modules/nf-core/deepvariant/makeexamples/tests/main.nf.test index 0790fb81..d46dbe6d 100644 --- a/modules/nf-core/deepvariant/rundeepvariant/tests/main.nf.test +++ b/modules/nf-core/deepvariant/makeexamples/tests/main.nf.test @@ -1,17 +1,17 @@ nextflow_process { - name "Test Process DEEPVARIANT_RUNDEEPVARIANT" + name "Test Process DEEPVARIANT_MAKEEXAMPLES" script "../main.nf" - process "DEEPVARIANT_RUNDEEPVARIANT" + config "./nextflow.config" + process "DEEPVARIANT_MAKEEXAMPLES" - tag "deepvariant/rundeepvariant" + tag "deepvariant/makeexamples" tag "deepvariant" tag "modules" tag "modules_nfcore" test("homo_sapiens - [bam, bai] - fasta - fai") { when { - config "./nextflow.config" process { """ @@ -42,13 +42,29 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(process.out).match() } + // 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") { - config "./nextflow-intervals.config" when { process { @@ -80,37 +96,52 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(process.out).match() } + { 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 - [cram, crai, genome_bed] - fasta - fai - par_bed") { - config "./nextflow-non-autosomal-calling.config" - tag "test" + 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/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) + 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) + 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.fai', checkIfExists: true) + 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] = [ - [ id:'genome'], - file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.blacklist_intervals.bed', checkIfExists: true) + [],[] ] """ } @@ -119,14 +150,33 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(process.out).match() } + + { 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("homo_sapiens - [bam, bai] - fasta_gz - fasta_gz_fai") { + test("stub") { + + options "-stub" + when { - config "./nextflow.config" process { """ @@ -138,15 +188,14 @@ nextflow_process { ] input[1] = [ [ id:'genome'], - file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.fasta.gz', checkIfExists: true) + 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.gz.fai', checkIfExists: true) + file(params.modules_testdata_base_path + '/genomics/homo_sapiens/genome/genome.fasta.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] = [ [],[] @@ -158,7 +207,20 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(process.out).match() } + { 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 00000000..24182c54 --- /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 00000000..5f071fcb --- /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 00000000..6a13da09 --- /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/postprocessvariants/main.nf b/modules/nf-core/deepvariant/postprocessvariants/main.nf new file mode 100644 index 00000000..90e8563d --- /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/rundeepvariant/meta.yml b/modules/nf-core/deepvariant/postprocessvariants/meta.yml similarity index 81% rename from modules/nf-core/deepvariant/rundeepvariant/meta.yml rename to modules/nf-core/deepvariant/postprocessvariants/meta.yml index 29b45ff9..132a5263 100644 --- a/modules/nf-core/deepvariant/rundeepvariant/meta.yml +++ b/modules/nf-core/deepvariant/postprocessvariants/meta.yml @@ -1,4 +1,4 @@ -name: deepvariant_rundeepvariant +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: @@ -21,17 +21,16 @@ input: description: | Groovy Map containing sample information e.g. [ id:'test', single_end:false ] - - input: + - variant_calls_tfrecord_files: type: file - description: BAM/CRAM file - pattern: "*.bam/cram" - - index: - type: file - description: Index of BAM/CRAM file - pattern: "*.bai/crai" - - intervals: + description: | + One or more data files containing variant calls from DEEPVARIANT_CALLVARIANTS + pattern: "*.tfrecord.gz" + - gvcf_tfrecords: type: file - description: file containing intervals + description: | + Sharded tfrecord file from DEEPVARIANT_MAKEEXAMPLES with the coverage information used for GVCF output + pattern: "*.gz" - - meta2: type: map description: | @@ -59,15 +58,6 @@ input: 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: - vcf: - meta: @@ -87,7 +77,7 @@ output: e.g. [ id:'test', single_end:false ] - ${prefix}.vcf.gz.tbi: type: file - description: Tabix index file of compressed VCF + description: Index for VCF pattern: "*.vcf.gz.tbi" - gvcf: - meta: @@ -107,16 +97,17 @@ output: e.g. [ id:'test', single_end:false ] - ${prefix}.g.vcf.gz.tbi: type: file - description: Tabix index file of compressed GVCF + description: Index for GVCF pattern: "*.g.vcf.gz.tbi" - versions: - versions.yml: type: file - description: File containing software versions + 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 00000000..e4e9b557 --- /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 00000000..5a29c624 --- /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 00000000..070b4892 --- /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 00000000..d26188cd --- /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 deleted file mode 100644 index 7f99c53f..00000000 --- a/modules/nf-core/deepvariant/rundeepvariant/main.nf +++ /dev/null @@ -1,78 +0,0 @@ -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/tests/nextflow-intervals.config b/modules/nf-core/deepvariant/rundeepvariant/tests/nextflow-intervals.config deleted file mode 100644 index 78d8d598..00000000 --- a/modules/nf-core/deepvariant/rundeepvariant/tests/nextflow-intervals.config +++ /dev/null @@ -1,8 +0,0 @@ -process { - - withName: DEEPVARIANT_RUNDEEPVARIANT { - ext.args = '--model_type=WGS ' - ext.prefix = { "${meta.id}_out" } - } - -} diff --git a/modules/nf-core/deepvariant/rundeepvariant/tests/nextflow-non-autosomal-calling.config b/modules/nf-core/deepvariant/rundeepvariant/tests/nextflow-non-autosomal-calling.config deleted file mode 100644 index 6d265292..00000000 --- a/modules/nf-core/deepvariant/rundeepvariant/tests/nextflow-non-autosomal-calling.config +++ /dev/null @@ -1,8 +0,0 @@ -process { - - withName: DEEPVARIANT_RUNDEEPVARIANT { - ext.args = '--model_type=WGS --haploid_contigs chr22' - ext.prefix = { "${meta.id}_out" } - } - -} diff --git a/modules/nf-core/deepvariant/rundeepvariant/tests/nextflow.config b/modules/nf-core/deepvariant/rundeepvariant/tests/nextflow.config deleted file mode 100644 index 77e355ca..00000000 --- a/modules/nf-core/deepvariant/rundeepvariant/tests/nextflow.config +++ /dev/null @@ -1,8 +0,0 @@ -process { - - 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 deleted file mode 100644 index 958b8e41..00000000 --- a/modules/nf-core/deepvariant/rundeepvariant/tests/tags.yml +++ /dev/null @@ -1,2 +0,0 @@ -deepvariant/rundeepvariant: - - modules/nf-core/deepvariant/rundeepvariant/** diff --git a/subworkflows/local/variant_calling/call_snv_deepvariant.nf b/subworkflows/local/variant_calling/call_snv_deepvariant.nf index 9cfb6389..59c0db19 100644 --- a/subworkflows/local/variant_calling/call_snv_deepvariant.nf +++ b/subworkflows/local/variant_calling/call_snv_deepvariant.nf @@ -5,7 +5,7 @@ include { BCFTOOLS_ANNOTATE } from '../../../modules/nf-core/bcftools/annotate/main' include { BCFTOOLS_NORM as SPLIT_MULTIALLELICS_GL } from '../../../modules/nf-core/bcftools/norm/main' include { BCFTOOLS_NORM as REMOVE_DUPLICATES_GL } from '../../../modules/nf-core/bcftools/norm/main' -include { DEEPVARIANT_RUNDEEPVARIANT as DEEPVARIANT } from '../../../modules/nf-core/deepvariant/rundeepvariant/main' +include { DEEPVARIANT } from '../../nf-core/deepvariant/main' include { GLNEXUS } from '../../../modules/nf-core/glnexus/main' include { TABIX_BGZIP } from '../../../modules/nf-core/tabix/bgzip/main' include { TABIX_TABIX as TABIX_GL } from '../../../modules/nf-core/tabix/tabix/main' diff --git a/subworkflows/nf-core/deepvariant/README.md b/subworkflows/nf-core/deepvariant/README.md new file mode 100644 index 00000000..6f816c22 --- /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 00000000..f3837708 --- /dev/null +++ b/subworkflows/nf-core/deepvariant/main.nf @@ -0,0 +1,44 @@ +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 00000000..6321fc24 --- /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 00000000..4195d473 --- /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/modules/nf-core/deepvariant/rundeepvariant/tests/main.nf.test.snap b/subworkflows/nf-core/deepvariant/tests/main.nf.test.snap similarity index 50% rename from modules/nf-core/deepvariant/rundeepvariant/tests/main.nf.test.snap rename to subworkflows/nf-core/deepvariant/tests/main.nf.test.snap index 1ec351ee..08105c1b 100644 --- a/modules/nf-core/deepvariant/rundeepvariant/tests/main.nf.test.snap +++ b/subworkflows/nf-core/deepvariant/tests/main.nf.test.snap @@ -1,5 +1,5 @@ { - "homo_sapiens - [bam, bai] - fasta_gz - fasta_gz_fai": { + "homo_sapiens - different samples and regions - cram - fasta - fai": { "content": [ { "0": [ @@ -8,176 +8,147 @@ "id": "test", "single_end": false }, - "test_out.vcf.gz:md5,8b8ab4a675f01e437aa72e1438a717d0" - ] - ], - "1": [ + "test.vcf.gz:md5,8b8ab4a675f01e437aa72e1438a717d0" + ], [ { - "id": "test", + "id": "test2", "single_end": false }, - "test_out.vcf.gz.tbi:md5,0000833138104e87b05eaa906821eb21" + "test2.vcf.gz:md5,5c36d104b2eb6e410788990928667b93" ] ], - "2": [ + "1": [ [ { "id": "test", "single_end": false }, - "test_out.g.vcf.gz:md5,0a629e1745926cfcedf4b169046a921a" - ] - ], - "3": [ + "test.vcf.gz.tbi:md5,0000833138104e87b05eaa906821eb21" + ], [ { - "id": "test", + "id": "test2", "single_end": false }, - "test_out.g.vcf.gz.tbi:md5,49503913c28ec70a6f4aa52f6b357b4d" + "test2.vcf.gz.tbi:md5,5451379c05fa59498b2b8aafcb18c9eb" ] ], - "4": [ - "versions.yml:md5,a251d8d9f5e8b737d8298eead96c0890" - ], - "gvcf": [ + "2": [ [ { "id": "test", "single_end": false }, - "test_out.g.vcf.gz:md5,0a629e1745926cfcedf4b169046a921a" - ] - ], - "gvcf_tbi": [ + "test.g.vcf.gz:md5,0a629e1745926cfcedf4b169046a921a" + ], [ { - "id": "test", + "id": "test2", "single_end": false }, - "test_out.g.vcf.gz.tbi:md5,49503913c28ec70a6f4aa52f6b357b4d" + "test2.g.vcf.gz:md5,2aefd9545ffefe9af0730dc4ffc5f638" ] ], - "vcf": [ + "3": [ [ { "id": "test", "single_end": false }, - "test_out.vcf.gz:md5,8b8ab4a675f01e437aa72e1438a717d0" - ] - ], - "vcf_tbi": [ + "test.g.vcf.gz.tbi:md5,49503913c28ec70a6f4aa52f6b357b4d" + ], [ { - "id": "test", + "id": "test2", "single_end": false }, - "test_out.vcf.gz.tbi:md5,0000833138104e87b05eaa906821eb21" + "test2.g.vcf.gz.tbi:md5,58d2e7fa7cf98d56fd734db6d59f8489" ] ], - "versions": [ - "versions.yml:md5,a251d8d9f5e8b737d8298eead96c0890" - ] - } - ], - "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-08-29T11:36:27.325363" - }, - "homo_sapiens - [bam, bai] - fasta - fai": { - "content": [ - { - "0": [ + "4": [ + "versions.yml:md5,5e6e7451f9819e2e0c33ad0d1b22d3b3", + "versions.yml:md5,c9c9c7000dc16bcb7e3107e7333481de", + "versions.yml:md5,cb2f0f2fe645633ed7d6528999bde458" + ], + "gvcf": [ [ { "id": "test", "single_end": false }, - "test_out.vcf.gz:md5,8b8ab4a675f01e437aa72e1438a717d0" - ] - ], - "1": [ + "test.g.vcf.gz:md5,0a629e1745926cfcedf4b169046a921a" + ], [ { - "id": "test", + "id": "test2", "single_end": false }, - "test_out.vcf.gz.tbi:md5,0000833138104e87b05eaa906821eb21" + "test2.g.vcf.gz:md5,2aefd9545ffefe9af0730dc4ffc5f638" ] ], - "2": [ + "gvcf_tbi": [ [ { "id": "test", "single_end": false }, - "test_out.g.vcf.gz:md5,0a629e1745926cfcedf4b169046a921a" - ] - ], - "3": [ + "test.g.vcf.gz.tbi:md5,49503913c28ec70a6f4aa52f6b357b4d" + ], [ { - "id": "test", + "id": "test2", "single_end": false }, - "test_out.g.vcf.gz.tbi:md5,49503913c28ec70a6f4aa52f6b357b4d" + "test2.g.vcf.gz.tbi:md5,58d2e7fa7cf98d56fd734db6d59f8489" ] ], - "4": [ - "versions.yml:md5,a251d8d9f5e8b737d8298eead96c0890" - ], - "gvcf": [ + "vcf": [ [ { "id": "test", "single_end": false }, - "test_out.g.vcf.gz:md5,0a629e1745926cfcedf4b169046a921a" - ] - ], - "gvcf_tbi": [ + "test.vcf.gz:md5,8b8ab4a675f01e437aa72e1438a717d0" + ], [ { - "id": "test", + "id": "test2", "single_end": false }, - "test_out.g.vcf.gz.tbi:md5,49503913c28ec70a6f4aa52f6b357b4d" + "test2.vcf.gz:md5,5c36d104b2eb6e410788990928667b93" ] ], - "vcf": [ + "vcf_tbi": [ [ { "id": "test", "single_end": false }, - "test_out.vcf.gz:md5,8b8ab4a675f01e437aa72e1438a717d0" - ] - ], - "vcf_tbi": [ + "test.vcf.gz.tbi:md5,0000833138104e87b05eaa906821eb21" + ], [ { - "id": "test", + "id": "test2", "single_end": false }, - "test_out.vcf.gz.tbi:md5,0000833138104e87b05eaa906821eb21" + "test2.vcf.gz.tbi:md5,5451379c05fa59498b2b8aafcb18c9eb" ] ], "versions": [ - "versions.yml:md5,a251d8d9f5e8b737d8298eead96c0890" + "versions.yml:md5,5e6e7451f9819e2e0c33ad0d1b22d3b3", + "versions.yml:md5,c9c9c7000dc16bcb7e3107e7333481de", + "versions.yml:md5,cb2f0f2fe645633ed7d6528999bde458" ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.8.4", + "nextflow": "24.04.3" }, - "timestamp": "2024-08-29T11:34:41.779153" + "timestamp": "2024-08-16T16:20:06.112232952" }, - "homo_sapiens - [cram, crai, genome_bed] - fasta - fai": { + "homo_sapiens - two inputs - bam - fasta - fai": { "content": [ { "0": [ @@ -186,173 +157,144 @@ "id": "test", "single_end": false }, - "test_out.vcf.gz:md5,8b8ab4a675f01e437aa72e1438a717d0" - ] - ], - "1": [ + "test.vcf.gz:md5,8b8ab4a675f01e437aa72e1438a717d0" + ], [ { - "id": "test", + "id": "test2", "single_end": false }, - "test_out.vcf.gz.tbi:md5,0000833138104e87b05eaa906821eb21" + "test2.vcf.gz:md5,8b8ab4a675f01e437aa72e1438a717d0" ] ], - "2": [ + "1": [ [ { "id": "test", "single_end": false }, - "test_out.g.vcf.gz:md5,0a629e1745926cfcedf4b169046a921a" - ] - ], - "3": [ + "test.vcf.gz.tbi:md5,0000833138104e87b05eaa906821eb21" + ], [ { - "id": "test", + "id": "test2", "single_end": false }, - "test_out.g.vcf.gz.tbi:md5,49503913c28ec70a6f4aa52f6b357b4d" + "test2.vcf.gz.tbi:md5,0000833138104e87b05eaa906821eb21" ] ], - "4": [ - "versions.yml:md5,a251d8d9f5e8b737d8298eead96c0890" - ], - "gvcf": [ + "2": [ [ { "id": "test", "single_end": false }, - "test_out.g.vcf.gz:md5,0a629e1745926cfcedf4b169046a921a" - ] - ], - "gvcf_tbi": [ + "test.g.vcf.gz:md5,0a629e1745926cfcedf4b169046a921a" + ], [ { - "id": "test", + "id": "test2", "single_end": false }, - "test_out.g.vcf.gz.tbi:md5,49503913c28ec70a6f4aa52f6b357b4d" + "test2.g.vcf.gz:md5,0a629e1745926cfcedf4b169046a921a" ] ], - "vcf": [ + "3": [ [ { "id": "test", "single_end": false }, - "test_out.vcf.gz:md5,8b8ab4a675f01e437aa72e1438a717d0" - ] - ], - "vcf_tbi": [ + "test.g.vcf.gz.tbi:md5,49503913c28ec70a6f4aa52f6b357b4d" + ], [ { - "id": "test", + "id": "test2", "single_end": false }, - "test_out.vcf.gz.tbi:md5,0000833138104e87b05eaa906821eb21" + "test2.g.vcf.gz.tbi:md5,49503913c28ec70a6f4aa52f6b357b4d" ] ], - "versions": [ - "versions.yml:md5,a251d8d9f5e8b737d8298eead96c0890" - ] - } - ], - "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" - }, - "timestamp": "2024-08-29T11:35:16.993129" - }, - "homo_sapiens - [cram, crai, genome_bed] - fasta - fai - par_bed": { - "content": [ - { - "0": [ + "4": [ + "versions.yml:md5,5e6e7451f9819e2e0c33ad0d1b22d3b3", + "versions.yml:md5,c9c9c7000dc16bcb7e3107e7333481de", + "versions.yml:md5,cb2f0f2fe645633ed7d6528999bde458" + ], + "gvcf": [ [ { "id": "test", "single_end": false }, - "test_out.vcf.gz:md5,d2e26d65dbbcea9b087ed191b5c9841c" - ] - ], - "1": [ + "test.g.vcf.gz:md5,0a629e1745926cfcedf4b169046a921a" + ], [ { - "id": "test", + "id": "test2", "single_end": false }, - "test_out.vcf.gz.tbi:md5,0801296d0356415bbf1ef8deb4ec84c3" + "test2.g.vcf.gz:md5,0a629e1745926cfcedf4b169046a921a" ] ], - "2": [ + "gvcf_tbi": [ [ { "id": "test", "single_end": false }, - "test_out.g.vcf.gz:md5,4fcaa9a8b55730d191382160c2b5bb0a" - ] - ], - "3": [ + "test.g.vcf.gz.tbi:md5,49503913c28ec70a6f4aa52f6b357b4d" + ], [ { - "id": "test", + "id": "test2", "single_end": false }, - "test_out.g.vcf.gz.tbi:md5,f468e846904733b3231ecf00ef7cd4a2" + "test2.g.vcf.gz.tbi:md5,49503913c28ec70a6f4aa52f6b357b4d" ] ], - "4": [ - "versions.yml:md5,a251d8d9f5e8b737d8298eead96c0890" - ], - "gvcf": [ + "vcf": [ [ { "id": "test", "single_end": false }, - "test_out.g.vcf.gz:md5,4fcaa9a8b55730d191382160c2b5bb0a" - ] - ], - "gvcf_tbi": [ + "test.vcf.gz:md5,8b8ab4a675f01e437aa72e1438a717d0" + ], [ { - "id": "test", + "id": "test2", "single_end": false }, - "test_out.g.vcf.gz.tbi:md5,f468e846904733b3231ecf00ef7cd4a2" + "test2.vcf.gz:md5,8b8ab4a675f01e437aa72e1438a717d0" ] ], - "vcf": [ + "vcf_tbi": [ [ { "id": "test", "single_end": false }, - "test_out.vcf.gz:md5,d2e26d65dbbcea9b087ed191b5c9841c" - ] - ], - "vcf_tbi": [ + "test.vcf.gz.tbi:md5,0000833138104e87b05eaa906821eb21" + ], [ { - "id": "test", + "id": "test2", "single_end": false }, - "test_out.vcf.gz.tbi:md5,0801296d0356415bbf1ef8deb4ec84c3" + "test2.vcf.gz.tbi:md5,0000833138104e87b05eaa906821eb21" ] ], "versions": [ - "versions.yml:md5,a251d8d9f5e8b737d8298eead96c0890" + "versions.yml:md5,5e6e7451f9819e2e0c33ad0d1b22d3b3", + "versions.yml:md5,c9c9c7000dc16bcb7e3107e7333481de", + "versions.yml:md5,cb2f0f2fe645633ed7d6528999bde458" ] } ], "meta": { - "nf-test": "0.9.0", - "nextflow": "24.04.4" + "nf-test": "0.8.4", + "nextflow": "24.04.3" }, - "timestamp": "2024-08-29T11:35:52.23093" + "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 00000000..be985479 --- /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 00000000..ae5640d2 --- /dev/null +++ b/subworkflows/nf-core/deepvariant/tests/tags.yml @@ -0,0 +1,2 @@ +subworkflows/deepvariant: + - subworkflows/nf-core/deepvariant/**