diff --git a/.github/skip_nf_test.json b/.github/skip_nf_test.json index 50d489477088..e28fd60e22de 100644 --- a/.github/skip_nf_test.json +++ b/.github/skip_nf_test.json @@ -124,6 +124,7 @@ "subworkflows/nf-core/fastq_align_bwa" ], "docker": [ + "modules/nf-core/canvas/germline", "modules/nf-core/parabricks", "modules/nf-core/sparsesignatures", "subworkflows/nf-core/deepvariant/tests/equality" @@ -131,6 +132,7 @@ "singularity": [ "modules/nf-core/numorph/3dunet", "modules/nf-core/bases2fastq", + "modules/nf-core/canvas/germline", "modules/nf-core/deepsomatic", "modules/nf-core/deepvariant/rundeepvariant", "modules/nf-core/deepvariant/vcfstatsreport", diff --git a/modules/nf-core/canvas/germline/environment.yml b/modules/nf-core/canvas/germline/environment.yml new file mode 100644 index 000000000000..9485e71ace53 --- /dev/null +++ b/modules/nf-core/canvas/germline/environment.yml @@ -0,0 +1,7 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::canvas=1.40.0.1613 diff --git a/modules/nf-core/canvas/germline/main.nf b/modules/nf-core/canvas/germline/main.nf index 714c197e124a..0d9400ea5409 100644 --- a/modules/nf-core/canvas/germline/main.nf +++ b/modules/nf-core/canvas/germline/main.nf @@ -5,56 +5,59 @@ process CANVAS_GERMLINE { container "quay.io/nf-core/canvas:1.40.0" input: - tuple val(meta), path(bam), path(bai) - path germline_snv_vcf - tuple val(sex), path(male_ploidy_vcf), path(female_ploidy_vcf) - path genomedir - path reference - path filter13 + tuple val(meta) , path(bam), path(bai) + tuple val(meta2), path(kmer_fasta, stageAs: 'Sequence/WholeGenomeFasta/genome.fa') + tuple val(meta3), path(genomesize, stageAs: 'Sequence/WholeGenomeFasta/GenomeSize.xml') + tuple val(meta4), path(filter_bed) + tuple val(meta5), path(sample_snv_vcf) + tuple val(meta6), path(population_snv_vcf) + tuple val(meta7), path(ploidy_vcf) + tuple val(meta8), path(common_cnvs_bed) output: - tuple val(meta), path("${prefix}.vcf.gz"), emit: vcf - tuple val(meta), path("${prefix}.CoverageAndVariantFrequency.txt"), emit: covandvarfreq - tuple val("${task.process}"), val('canvas'), val('1.40.0'), topic: versions, emit: versions_canvas - // --version not supported by CLI, please update this manually when updating the tool + tuple val(meta), path("${prefix}.vcf.gz") , emit: vcf + tuple val(meta), path("${prefix}.CoverageAndVariantFrequency.txt") , emit: covandvarfreq + tuple val("${task.process}"), val('canvas'), eval('Canvas --version'), topic: versions, emit: versions_canvas when: task.ext.when == null || task.ext.when script: - prefix = task.ext.prefix ?: "${meta.id}" - def ploidy_vcf = (sex == 'male') ? male_ploidy_vcf : female_ploidy_vcf - """ - PLOIDYVCF=\$(mod_sex_vcf.py ${ploidy_vcf} ${prefix} ./) - SNV_VCF=${germline_snv_vcf} - if [[ ${germline_snv_vcf} == *.gz ]]; then - gunzip -c ${germline_snv_vcf} > snv_input.vcf - SNV_VCF=snv_input.vcf - fi + if (!(sample_snv_vcf || population_snv_vcf)) { + error("Either sample_snv_vcf or population_snv_vcf must be supplied") + } - mkdir -p Sequence - ln -s \$(realpath ${genomedir}) Sequence/WholeGenomeFasta + prefix = task.ext.prefix ?: "${meta.id}" + def args = task.ext.args ?: "" + def sample_vcf_arg = sample_snv_vcf ? "--sample-b-allele-vcf ${sample_snv_vcf}" : "" + def population_vcf_arg = population_snv_vcf ? "--population-b-allele-vcf ${population_snv_vcf}" : "" + def ploidy_arg = ploidy_vcf ? "--ploidy-vcf $ploidy_vcf" : "" + def common_cnvs_arg = common_cnvs_bed ? "--common-cnvs-bed ${common_cnvs_bed}" : "" + """ Canvas SmallPedigree-WGS \\ - --bam=${bam} \\ - --sample-b-allele-vcf=\$SNV_VCF \\ - --ploidy-vcf=\$PLOIDYVCF \\ - -g ./Sequence/WholeGenomeFasta \\ - -r ${reference} \\ - -f ${filter13} \\ - -o ./ + --bam ${bam} \\ + --genome-folder ./Sequence/WholeGenomeFasta \\ + --reference ${kmer_fasta} \\ + --filter-bed ${filter_bed} \\ + --output ./ \\ + ${sample_vcf_arg} \\ + ${population_vcf_arg} \\ + ${ploidy_arg} \\ + ${common_cnvs_arg} \\ + ${args} - if [ -f CNV.vcf.gz ]; then - gunzip CNV.vcf.gz - fi - - grep -v 'Canvas:REF' CNV.vcf | bgzip > ${prefix}.vcf.gz - - find . -name "CNV.CoverageAndVariantFrequency.txt" | head -1 | xargs -I{} cp {} ./${prefix}.CoverageAndVariantFrequency.txt + mv CNV.vcf.gz ${prefix}.vcf.gz + mv TempCNV_*/CNV.CoverageAndVariantFrequency.txt ${prefix}.CoverageAndVariantFrequency.txt """ stub: + + if (!(sample_snv_vcf || population_snv_vcf)) { + error("Either sample_snv_vcf or population_snv_vcf must be supplied") + } + prefix = task.ext.prefix ?: "${meta.id}" """ echo "" | gzip > ${prefix}.vcf.gz diff --git a/modules/nf-core/canvas/germline/meta.yml b/modules/nf-core/canvas/germline/meta.yml index 49926f10c7c4..07440558fdeb 100644 --- a/modules/nf-core/canvas/germline/meta.yml +++ b/modules/nf-core/canvas/germline/meta.yml @@ -25,111 +25,91 @@ tools: input: - - meta: type: map - description: | - Groovy Map containing sample information. - e.g. `[ id:'sample1' ]` - ontologies: [] + description: Groovy map containing sample information - bam: type: file - description: Sorted BAM file of aligned WGS reads. + description: BAM file for the sample pattern: "*.bam" ontologies: - edam: "http://edamontology.org/format_2572" - bai: type: file - description: BAM index file. + description: BAM index file for the sample pattern: "*.bai" ontologies: - edam: "http://edamontology.org/format_3327" - - germline_snv_vcf: - type: file - description: | - VCF (or gzipped VCF) containing germline SNV b-allele sites (PASS filter only). - Typically produced by a variant caller such as DNAscope or DeepVariant. - pattern: "*.{vcf,vcf.gz}" - ontologies: - - edam: "http://edamontology.org/format_3016" - - - sex: - type: string - description: | - Sample sex. Must be either "male" or "female". Used to select the - appropriate ploidy VCF for sex chromosomes. - - male_ploidy_vcf: + - - meta2: + type: map + description: Groovy map containing reference information + - kmer_fasta: type: file - description: | - VCF defining expected ploidy for sex chromosomes in male samples. - Both ploidy VCFs (male and female) must always be provided. The module - automatically selects the correct one based on the sex value. - The sample name in the VCF header is automatically updated to match the SM tag in the BAM header. - Expected format (hg38 example): - - ``` - ##fileformat=VCFv4.1 - ##INFO= - ##FORMAT= - #CHROM POS ID REF ALT QUAL FILTER INFO FORMAT SAMPLE - chrX 0 . N . PASS END=10001 CN 1 - chrX 2781479 . N . PASS END=155701383 CN 1 - chrX 156030895 . N . PASS END=156040895 CN 1 - chrY 0 . N . PASS END=57227415 CN 1 - ``` - pattern: "*.vcf" + description: Canvas-ready reference FASTA file with softmasked non-unique 35-mers + pattern: "*.{fa,fna,fasta}" + ontologies: + - edam: "http://edamontology.org/format_1929" + - - meta3: + type: map + description: Groovy map containing reference information + - genomesize: + type: file + description: Illumina-style Genome size XML file (GenomeSize.xml) + pattern: "*.xml" + ontologies: + - edam: "http://edamontology.org/format_2332" + - - meta4: + type: map + description: Groovy map containing reference information + - filter_bed: + type: file + description: BED file of regions to skip + pattern: "*.bed" + ontologies: + - edam: "http://edamontology.org/format_3003" + - - meta5: + type: map + description: Groovy map containing sample information + - sample_snv_vcf: + type: file + description: Multisample VCF file containing SNV b-allele sites (sample-specific). Either this or `population_snv_vcf` must be provided. + pattern: "*.vcf(.gz)?" ontologies: - edam: "http://edamontology.org/format_3016" - - female_ploidy_vcf: + - - meta6: + type: map + description: Groovy map containing meta information for population SNV VCF + - population_snv_vcf: type: file - description: | - VCF defining expected ploidy for sex chromosomes in female samples. - Both ploidy VCFs (male and female) must always be provided. The module - automatically selects the correct one based on the sex value. - The sample name in the VCF header is automatically updated to match the SM tag in the BAM header. - Expected format (hg38 example): - - ``` - ##fileformat=VCFv4.1 - ##INFO= - ##FORMAT= - #CHROM POS ID REF ALT QUAL FILTER INFO FORMAT SAMPLE - chrY 0 . N . PASS END=57227415 CN 0 - ``` - pattern: "*.vcf" + description: VCF file containing SNV b-allele sites in the population. Either this or `sample_snv_vcf` must be provided. + pattern: "*.vcf(.gz)?" ontologies: - edam: "http://edamontology.org/format_3016" - - genomedir: - type: directory - description: | - Canvas genome reference directory containing genome.fa and GenomeSize.xml. - Available for GRCh37/hg19/GRCh38 from s3://canvas-cnv-public. - - reference: - type: file - description: | - Canvas-ready kmer reference file (kmer.fa). - Available from s3://canvas-cnv-public. - pattern: "*.fa" - ontologies: - - edam: "http://edamontology.org/format_1929" - - filter13: - type: file - description: | - BED file of regions to exclude from CNV calling (e.g. centromeres, telomeres). - Named filter13 following Canvas reference package conventions. - Available from s3://canvas-cnv-public. - pattern: "*.bed" - ontologies: - - edam: "http://edamontology.org/format_3003" + - - meta7: + type: map + description: Groovy map containing for ploidy VCF + - ploidy_vcf: + type: file + description: Multisample VCF file containing regions with expected ploidy different from 2. (See https://github.com/Illumina/canvas/wiki for an example) + pattern: "*.vcf(.gz)?" + ontologies: + - edam: "http://edamontology.org/format_3016" + - - meta8: + type: map + description: Groovy map containing reference information + - common_cnvs_bed: + type: file + description: BED file containing regions of known common CNVs + pattern: "*.bed" + ontologies: + - edam: "http://edamontology.org/format_3003" output: vcf: - - meta: type: map description: | Groovy Map containing sample information. - e.g. `[ id:'sample1' ]` - ontologies: [] - ${prefix}.vcf.gz: type: file - description: | - Bgzipped VCF file containing germline CNV calls. Canvas:REF entries (non-variant regions) - are excluded. Requires further annotation for standard SV ALT notation. + description: Bgzipped VCF file containing germline CNV calls. pattern: "*.vcf.gz" ontologies: - edam: "http://edamontology.org/format_3016" @@ -138,13 +118,10 @@ output: type: map description: | Groovy Map containing sample information. - e.g. `[ id:'sample1' ]` - ontologies: [] - ${prefix}.CoverageAndVariantFrequency.txt: type: file description: | Tab-separated file with per-bin coverage and variant allele frequency values. - Used as input for CANVAS_CREATESEG to generate segmentation files. pattern: "*.CoverageAndVariantFrequency.txt" ontologies: - edam: "http://edamontology.org/format_3475" @@ -155,10 +132,10 @@ output: - canvas: type: string description: The name of the tool - - 1.40.0: + - Canvas --version: type: string - description: The version of the tool (hardcoded as Canvas is an archived - tool) + description: The version of the tool + topics: versions: - - ${task.process}: @@ -167,11 +144,13 @@ topics: - canvas: type: string description: The name of the tool - - 1.40.0: + - Canvas --version: type: string description: The version of the tool (hardcoded as Canvas is an archived tool) authors: - "@ktruve" + - "@Schmytzi" maintainers: - "@ktruve" + - "@Schmytzi" diff --git a/modules/nf-core/canvas/germline/tests/main.nf.test b/modules/nf-core/canvas/germline/tests/main.nf.test index f21adc41ba5b..c717095ac119 100644 --- a/modules/nf-core/canvas/germline/tests/main.nf.test +++ b/modules/nf-core/canvas/germline/tests/main.nf.test @@ -3,33 +3,142 @@ nextflow_process { name "Test Process CANVAS_GERMLINE" script "../main.nf" process "CANVAS_GERMLINE" + config "./nextflow.config" tag "modules" tag "modules_nfcore" tag "canvas/germline" tag "canvas" + tag "bcftools" + tag "bcftools/reheader" - test("homo_sapiens - bam - female - stub") { + test("homo_sapiens - [ [bam,bai], fasta, xml, bed, [], population vcf, [], [] ]") { + when { + process { + """ + input[0] = [ + [ id:'NA12878' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/NA12878.chr22.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/NA12878.chr22.bam.bai', checkIfExists: true) + ] + input[1] = [ + [ id: 'GRCh38' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr22/sequence/hg38.chr22.fasta', checkIfExists: true) + ] + input[2] = [ + [ id: 'GRCh38' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr22/sequence/GenomeSize.xml', checkIfExists: true) + ] + // exclude regions not covered by test data + input[3] = channel.of("chr22\t0\t16569800", "chr22\t16610000\t50818468").collectFile(name: 'test_filter.bed', newLine:true) + .map { file -> [[id:'GRCh38'], file]} + input[4] = [ [], [] ] + input[5] = [ + [ id: 'GRCh38'], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr22.vcf.gz', checkIfExists: true) + ] + input[6] = [ [], [] ] + input[7] = [ [], [] ] + """ + } + } - options "-stub" + then { + assertAll( + { assert process.success }, + { assert snapshot( + path(process.out.vcf.get(0).get(1)).vcf.variantsMD5, + process.out.covandvarfreq, + process.out.versions_canvas + ).match() } + ) + } + } + test("homo_sapiens - [ [bam,bai], fasta, xml, bed, sample vcf, [], [], [] ]") { when { process { """ input[0] = [ - [ id:'test' ], - 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:'NA12878' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/NA12878.chr22.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/NA12878.chr22.bam.bai', checkIfExists: true) + ] + input[1] = [ + [ id: 'GRCh38' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr22/sequence/hg38.chr22.fasta', checkIfExists: true) ] - input[1] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz', checkIfExists: true) input[2] = [ - "female", - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr22.vcf.gz', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz', checkIfExists: true) + [ id: 'GRCh38' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr22/sequence/GenomeSize.xml', checkIfExists: true) ] - input[3] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.dict', checkIfExists: true) - input[4] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.fasta', checkIfExists: true) - input[5] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/multi_intervals.bed', checkIfExists: true) + input[3] = channel.of("chr22\t0\t16569800", "chr22\t16610000\t50818468").collectFile(name: 'test_filter.bed', newLine:true) + .map { file -> [[id:'GRCh38'], file]} + input[4] = [ + [ id: 'GRCh38'], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr22.vcf.gz', checkIfExists: true) + ] + input[5] = [ [], [] ] + input[6] = [ [], [] ] + input[7] = [ [], [] ] + """ + } + } + then { + assertAll( + { assert process.success }, + { assert snapshot( + path(process.out.vcf.get(0).get(1)).vcf.variantsMD5, + process.out.covandvarfreq, + process.out.versions_canvas + ).match() } + ) + } + } + + test("homo_sapiens - [ [bam,bai], fasta, xml, bed, sample vcf, [], ploidy vcf, known cnv bed ]") { + setup { + run("BCFTOOLS_REHEADER") { + script "../../../bcftools/reheader/main.nf" + process { + """ + input[0] = [ + [ id: 'NA12878' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/empty.vcf.gz', checkIfExists: true), + [], + [] + ] + input[1] = [[], []] + """ + } + } + } + when { + process { + """ + input[0] = [ + [ id:'NA12878' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/NA12878.chr22.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/NA12878.chr22.bam.bai', checkIfExists: true) + ] + input[1] = [ + [ id: 'GRCh38' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr22/sequence/hg38.chr22.fasta', checkIfExists: true) + ] + input[2] = [ + [ id: 'GRCh38' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr22/sequence/GenomeSize.xml', checkIfExists: true) + ] + input[3] = channel.of("chr22\t0\t16569800", "chr22\t16610000\t50818468").collectFile(name: 'test_filter.bed', newLine:true) + .map { file -> [[id:'GRCh38'], file]} + input[4] = [ + [ id: 'GRCh38'], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr22.vcf.gz', checkIfExists: true) + ] + input[5] = [ [], [] ] + input[6] = BCFTOOLS_REHEADER.out.vcf + input[7] = channel.of("chr22\t16570000\t16572000").collectFile(name: 'test_cnv.bed', newLine:true) + .map { file -> [[id:'GRCh38'], file]} """ } } @@ -37,32 +146,172 @@ nextflow_process { then { assertAll( { assert process.success }, - { assert snapshot(process.out).match() } + { assert snapshot( + path(process.out.vcf.get(0).get(1)).vcf.variantsMD5, + process.out.covandvarfreq, + process.out.versions_canvas + ).match() } ) } } - test("homo_sapiens - bam - male - stub") { + test("homo_sapiens - [ [bam,bai], fasta, xml, bed, [], [], [], [] ] - should fail") { + when { + process { + """ + input[0] = [ + [ id:'NA12878' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/NA12878.chr22.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/NA12878.chr22.bam.bai', checkIfExists: true) + ] + input[1] = [ + [ id: 'GRCh38' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr22/sequence/hg38.chr22.fasta', checkIfExists: true) + ] + input[2] = [ + [ id: 'GRCh38' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr22/sequence/GenomeSize.xml', checkIfExists: true) + ] + // exclude regions not covered by test data + input[3] = channel.of("chr22\t0\t16569800", "chr22\t16610000\t50818468").collectFile(name: 'test_filter.bed', newLine:true) + .map { file -> [[id:'GRCh38'], file]} + input[4] = [ [], [] ] + input[5] = [ [], [] ] + input[6] = [ [], [] ] + input[7] = [ [], [] ] + """ + } + } + + then { + assertAll( + { assert !process.success } + ) + } + } + + test("homo_sapiens - [ [bam,bai], fasta, xml, bed, [], population vcf, [], [] ] - stub") { + options "-stub" + when { + process { + """ + input[0] = [ + [ id:'NA12878' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/NA12878.chr22.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/NA12878.chr22.bam.bai', checkIfExists: true) + ] + input[1] = [ + [ id: 'GRCh38' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr22/sequence/hg38.chr22.fasta', checkIfExists: true) + ] + input[2] = [ + [ id: 'GRCh38' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr22/sequence/GenomeSize.xml', checkIfExists: true) + ] + // exclude regions not covered by test data + input[3] = channel.of("chr22\t0\t16569800", "chr22\t16610000\t50818468").collectFile(name: 'test_filter.bed', newLine:true) + .map { file -> [[id:'GRCh38'], file]} + input[4] = [ [], [] ] + input[5] = [ + [ id: 'GRCh38'], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr22.vcf.gz', checkIfExists: true) + ] + input[6] = [ [], [] ] + input[7] = [ [], [] ] + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + test("homo_sapiens - [ [bam,bai], fasta, xml, bed, sample vcf, [], [], [] ] - stub") { options "-stub" + when { + process { + """ + input[0] = [ + [ id:'NA12878' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/NA12878.chr22.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/NA12878.chr22.bam.bai', checkIfExists: true) + ] + input[1] = [ + [ id: 'GRCh38' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr22/sequence/hg38.chr22.fasta', checkIfExists: true) + ] + input[2] = [ + [ id: 'GRCh38' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr22/sequence/GenomeSize.xml', checkIfExists: true) + ] + input[3] = channel.of("chr22\t0\t16569800", "chr22\t16610000\t50818468").collectFile(name: 'test_filter.bed', newLine:true) + .map { file -> [[id:'GRCh38'], file]} + input[4] = [ + [ id: 'GRCh38'], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr22.vcf.gz', checkIfExists: true) + ] + input[5] = [ [], [] ] + input[6] = [ [], [] ] + input[7] = [ [], [] ] + """ + } + } + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + test("homo_sapiens - [ [bam,bai], fasta, xml, bed, sample vcf, [], ploidy vcf, known cnv bed ] - stub") { + options "-stub" + setup { + run("BCFTOOLS_REHEADER") { + script "../../../bcftools/reheader/main.nf" + process { + """ + input[0] = [ + [ id: 'NA12878' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/empty.vcf.gz', checkIfExists: true), + [], + [] + ] + input[1] = [[], []] + """ + } + } + } when { process { """ input[0] = [ - [ id:'test' ], - 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:'NA12878' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/NA12878.chr22.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/NA12878.chr22.bam.bai', checkIfExists: true) + ] + input[1] = [ + [ id: 'GRCh38' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr22/sequence/hg38.chr22.fasta', checkIfExists: true) ] - input[1] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr21_22.vcf.gz', checkIfExists: true) input[2] = [ - "male", - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr22.vcf.gz', checkIfExists: true), - file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr22.1X.vcf.gz', checkIfExists: true) + [ id: 'GRCh38' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr22/sequence/GenomeSize.xml', checkIfExists: true) ] - input[3] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.dict', checkIfExists: true) - input[4] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/genome.fasta', checkIfExists: true) - input[5] = file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr21/sequence/multi_intervals.bed', checkIfExists: true) + input[3] = channel.of("chr22\t0\t16569800", "chr22\t16610000\t50818468").collectFile(name: 'test_filter.bed', newLine:true) + .map { file -> [[id:'GRCh38'], file]} + input[4] = [ + [ id: 'GRCh38'], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878_GIAB.chr22.vcf.gz', checkIfExists: true) + ] + input[5] = [ [], [] ] + input[6] = BCFTOOLS_REHEADER.out.vcf + input[7] = channel.of("chr22\t16570000\t16572000").collectFile(name: 'test_cnv.bed', newLine:true) + .map { file -> [[id:'GRCh38'], file]} """ } } @@ -74,4 +323,41 @@ nextflow_process { ) } } + + test("homo_sapiens - [ [bam,bai], fasta, xml, bed, [], [], [], [] ] - should fail - stub") { + options "-stub" + when { + process { + """ + input[0] = [ + [ id:'NA12878' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/NA12878.chr22.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/NA12878.chr22.bam.bai', checkIfExists: true) + ] + input[1] = [ + [ id: 'GRCh38' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr22/sequence/hg38.chr22.fasta', checkIfExists: true) + ] + input[2] = [ + [ id: 'GRCh38' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr22/sequence/GenomeSize.xml', checkIfExists: true) + ] + // exclude regions not covered by test data + input[3] = channel.of("chr22\t0\t16569800", "chr22\t16610000\t50818468").collectFile(name: 'test_filter.bed', newLine:true) + .map { file -> [[id:'GRCh38'], file]} + input[4] = [ [], [] ] + input[5] = [ [], [] ] + input[6] = [ [], [] ] + input[7] = [ [], [] ] + """ + } + } + + then { + assertAll( + { assert !process.success } + ) + } + } + } diff --git a/modules/nf-core/canvas/germline/tests/main.nf.test.snap b/modules/nf-core/canvas/germline/tests/main.nf.test.snap index 14f3c3b0d70b..fba99d0c1cc4 100644 --- a/modules/nf-core/canvas/germline/tests/main.nf.test.snap +++ b/modules/nf-core/canvas/germline/tests/main.nf.test.snap @@ -1,116 +1,248 @@ { - "homo_sapiens - bam - female - stub": { + "homo_sapiens - [ [bam,bai], fasta, xml, bed, [], population vcf, [], [] ]": { + "content": [ + "657528fc60c61adfa9d1a757ce835d70", + [ + [ + { + "id": "NA12878" + }, + "NA12878.CoverageAndVariantFrequency.txt:md5,7a0bf126ad613632eabcc2d5b20034c5" + ] + ], + [ + [ + "CANVAS_GERMLINE", + "canvas", + "1.40.0.1613+master" + ] + ] + ], + "timestamp": "2026-07-29T11:06:19.438085217", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.4" + } + }, + "homo_sapiens - [ [bam,bai], fasta, xml, bed, sample vcf, [], [], [] ]": { + "content": [ + "657528fc60c61adfa9d1a757ce835d70", + [ + [ + { + "id": "NA12878" + }, + "NA12878.CoverageAndVariantFrequency.txt:md5,7a0bf126ad613632eabcc2d5b20034c5" + ] + ], + [ + [ + "CANVAS_GERMLINE", + "canvas", + "1.40.0.1613+master" + ] + ] + ], + "timestamp": "2026-07-29T11:06:40.874163808", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.4" + } + }, + "homo_sapiens - [ [bam,bai], fasta, xml, bed, sample vcf, [], ploidy vcf, known cnv bed ]": { + "content": [ + "657528fc60c61adfa9d1a757ce835d70", + [ + [ + { + "id": "NA12878" + }, + "NA12878.CoverageAndVariantFrequency.txt:md5,7a0bf126ad613632eabcc2d5b20034c5" + ] + ], + [ + [ + "CANVAS_GERMLINE", + "canvas", + "1.40.0.1613+master" + ] + ] + ], + "timestamp": "2026-07-29T11:07:04.150257341", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.4" + } + }, + "homo_sapiens - [ [bam,bai], fasta, xml, bed, sample vcf, [], [], [] ] - stub": { + "content": [ + { + "0": [ + [ + { + "id": "NA12878" + }, + "NA12878.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + [ + { + "id": "NA12878" + }, + "NA12878.CoverageAndVariantFrequency.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "2": [ + [ + "CANVAS_GERMLINE", + "canvas", + "1.40.0.1613+master" + ] + ], + "covandvarfreq": [ + [ + { + "id": "NA12878" + }, + "NA12878.CoverageAndVariantFrequency.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + "vcf": [ + [ + { + "id": "NA12878" + }, + "NA12878.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "versions_canvas": [ + [ + "CANVAS_GERMLINE", + "canvas", + "1.40.0.1613+master" + ] + ] + } + ], + "timestamp": "2026-07-29T11:21:37.031208528", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.4" + } + }, + "homo_sapiens - [ [bam,bai], fasta, xml, bed, sample vcf, [], ploidy vcf, known cnv bed ] - stub": { "content": [ { "0": [ [ { - "id": "test" + "id": "NA12878" }, - "test.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + "NA12878.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], "1": [ [ { - "id": "test" + "id": "NA12878" }, - "test.CoverageAndVariantFrequency.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + "NA12878.CoverageAndVariantFrequency.txt:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "2": [ [ "CANVAS_GERMLINE", "canvas", - "1.40.0" + "1.40.0.1613+master" ] ], "covandvarfreq": [ [ { - "id": "test" + "id": "NA12878" }, - "test.CoverageAndVariantFrequency.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + "NA12878.CoverageAndVariantFrequency.txt:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "vcf": [ [ { - "id": "test" + "id": "NA12878" }, - "test.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + "NA12878.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], "versions_canvas": [ [ "CANVAS_GERMLINE", "canvas", - "1.40.0" + "1.40.0.1613+master" ] ] } ], - "timestamp": "2026-04-15T15:14:01.021403508", + "timestamp": "2026-07-29T11:21:49.256913378", "meta": { "nf-test": "0.9.5", - "nextflow": "25.04.5" + "nextflow": "26.04.4" } }, - "homo_sapiens - bam - male - stub": { + "homo_sapiens - [ [bam,bai], fasta, xml, bed, [], population vcf, [], [] ] - stub": { "content": [ { "0": [ [ { - "id": "test" + "id": "NA12878" }, - "test.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + "NA12878.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], "1": [ [ { - "id": "test" + "id": "NA12878" }, - "test.CoverageAndVariantFrequency.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + "NA12878.CoverageAndVariantFrequency.txt:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "2": [ [ "CANVAS_GERMLINE", "canvas", - "1.40.0" + "1.40.0.1613+master" ] ], "covandvarfreq": [ [ { - "id": "test" + "id": "NA12878" }, - "test.CoverageAndVariantFrequency.txt:md5,d41d8cd98f00b204e9800998ecf8427e" + "NA12878.CoverageAndVariantFrequency.txt:md5,d41d8cd98f00b204e9800998ecf8427e" ] ], "vcf": [ [ { - "id": "test" + "id": "NA12878" }, - "test.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + "NA12878.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" ] ], "versions_canvas": [ [ "CANVAS_GERMLINE", "canvas", - "1.40.0" + "1.40.0.1613+master" ] ] } ], - "timestamp": "2026-04-15T15:14:08.862453059", + "timestamp": "2026-07-29T11:21:26.171186177", "meta": { "nf-test": "0.9.5", - "nextflow": "25.04.5" + "nextflow": "26.04.4" } } } \ No newline at end of file diff --git a/modules/nf-core/canvas/germline/tests/nextflow.config b/modules/nf-core/canvas/germline/tests/nextflow.config new file mode 100644 index 000000000000..30d8e0021f4e --- /dev/null +++ b/modules/nf-core/canvas/germline/tests/nextflow.config @@ -0,0 +1,8 @@ +process { + + withName: 'BCFTOOLS_REHEADER' { + ext.args = "--samples-list NA12878" + } + + +}