diff --git a/modules/nf-core/angsd/dosaf/environment.yml b/modules/nf-core/angsd/dosaf/environment.yml new file mode 100644 index 000000000000..2e83f3f2ca8f --- /dev/null +++ b/modules/nf-core/angsd/dosaf/environment.yml @@ -0,0 +1,8 @@ +--- +# yaml-language-server: $schema=https://raw.githubusercontent.com/nf-core/modules/master/modules/environment-schema.json +channels: + - conda-forge + - bioconda +dependencies: + - bioconda::angsd=0.940 + - bioconda::htslib=1.23 diff --git a/modules/nf-core/angsd/dosaf/main.nf b/modules/nf-core/angsd/dosaf/main.nf new file mode 100644 index 000000000000..14ceb77fbd2d --- /dev/null +++ b/modules/nf-core/angsd/dosaf/main.nf @@ -0,0 +1,137 @@ +process ANGSD_DOSAF { + tag "$meta.id" + label 'process_medium' + + conda "${moduleDir}/environment.yml" + container "${ workflow.containerEngine in ['singularity', 'apptainer'] && !task.ext.singularity_pull_docker_container ? + 'https://depot.galaxyproject.org/singularity/angsd:0.940--h13024bc_4': + 'quay.io/biocontainers/angsd:0.940--h13024bc_4' }" + + input: + tuple val(meta), path(bams), path(bam_indices) + tuple path(reference_fasta), path(reference_fai) + tuple path(ancestral_fasta), path(ancestral_fai) // Optional. Provides ancestral state for unfolded SFS. + path(error_file) // Optional. Required for SYK model (-GL 4) only. + path(inbreeding_coefficients) // Optional. Required for -doSAF 2 (inbreeding-aware mode). + val(gl_model) + val(dosaf_mode) + + output: + tuple val(meta), path("*.saf.idx"), path("*.saf.pos.gz"), path("*.saf.gz"), emit: saf + tuple val("${task.process}"), val('angsd'), eval("angsd 2>&1 | sed '1!d;s/.*version: //;s/ .*//'"), emit: versions_angsd, topic: versions + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + + // Validate GL model + if (!(gl_model in [1, 2, 3, 4])) { + error( + "ANGSD_DOSAF: Invalid GL model '${gl_model}'. Please pass one of 1, 2, 3, or 4 as the gl_model input." + ) + } + + // Validate doSAF mode + if (!(dosaf_mode in [1, 2])) { + error( + "ANGSD_DOSAF: Invalid doSAF mode '${dosaf_mode}'. Please pass 1 or 2 as the dosaf_mode input." + ) + } + + // Validate doSAF 2 has inbreeding coefficients + if (dosaf_mode == 2 && !inbreeding_coefficients) { + error( + "ANGSD_DOSAF: -doSAF 2 requires inbreeding coefficients (indF). Please supply an inbreeding_coefficients file." + ) + } + + // Validate doSAF 2 called alongside -doMajoMinor and -doMaf + if (dosaf_mode == 2 && !(args.contains("-doMajorMinor"))) { + error( + "ANGSD_DOSAF: -doSAF 2 requires -doMajorMinor to be specified. Please include in ext.args." + ) + } + if (dosaf_mode == 2 && !(args.contains("-doMaf"))) { + error( + "ANGSD_DOSAF: -doSAF 2 requires -doMaf to be specified. Please include in ext.args." + ) + } + + // Validate GL 4 has error file + if (gl_model == 4 && !error_file) { + error( + "ANGSD_DOSAF: -GL 4 (SYK model) requires an error file. Please supply an error_file." + ) + } + + // Compute -minInd dynamically as a fraction of the population's BAM list size + // Default set to 0 as this mimics angsd default for minInd + def frac = (task.ext.args2 ?: '0') as Double + def n_samples = bams instanceof List ? bams.size() : 1 + def min_ind_arg = frac > 0 ? "-minInd ${Math.ceil(n_samples * frac).toInteger()}" : '' + + // Touch fai indices to ensure they are newer than their fasta (ANGSD requirement) + def touch_ref = reference_fai ? "sleep 1 && touch ${reference_fai}" : '' + def touch_anc = ancestral_fai ? "sleep 1 && touch ${ancestral_fai}" : '' + + // Reference / ancestral args. + // If ancestral_fasta supplied: use as -anc and pass reference as -ref. + // If not supplied: use reference as -anc and -ref (suitable for folded SFS via realSFS -fold 1). + def ref_anc_arg = ancestral_fasta ? "-anc ${ancestral_fasta} -ref ${reference_fasta}" : "-anc ${reference_fasta} -ref ${reference_fasta}" + + // Optional args + def indF_arg = inbreeding_coefficients ? "-indF ${inbreeding_coefficients}" : "" + def errors_arg = error_file ? "-errors ${error_file}" : "" + + // Shared preamble + def preamble = """ + ${touch_ref} + ${touch_anc} + printf '%s\\n' ${bams} > bamlist.txt + """ + +// SOAPsnp (-GL 3) needs a calibration pass first to generate the matrix +// angsd reads back in during the doSAF step. +def calibration = '' +if (gl_model == 3) { + calibration = """ + angsd \\ + -nThreads ${task.cpus} \\ + -bam bamlist.txt \\ + -minQ 0 \\ + -GL ${gl_model} \\ + -ref ${reference_fasta} \\ + -out ${prefix} + """ +} + +// SYK model (-GL 4) needs an error file and -doCounts 1 +def gl4_args = gl_model == 4 ? "${errors_arg} -doCounts 1" : '' + +""" +${preamble} +${calibration} +angsd \\ + -nThreads ${task.cpus} \\ + -bam bamlist.txt \\ + -GL ${gl_model} \\ + -doSAF ${dosaf_mode} \\ + ${ref_anc_arg} \\ + ${indF_arg} \\ + ${gl4_args} \\ + ${args} \\ + ${min_ind_arg} \\ + -out ${prefix} +""" + + stub: + def prefix = task.ext.prefix ?: "${meta.id}" + """ + touch ${prefix}.saf.idx + echo "" | gzip > ${prefix}.saf.pos.gz + echo "" | gzip > ${prefix}.saf.gz + """ +} diff --git a/modules/nf-core/angsd/dosaf/meta.yml b/modules/nf-core/angsd/dosaf/meta.yml new file mode 100644 index 000000000000..d62fe6724dae --- /dev/null +++ b/modules/nf-core/angsd/dosaf/meta.yml @@ -0,0 +1,131 @@ +name: "angsd_dosaf" +description: Estimate site allele frequencies from BAM files. +keywords: + - angsd + - genotype likelihood + - genomics +tools: + - "angsd": + description: "ANGSD: Analysis of next generation Sequencing Data" + homepage: "http://www.popgen.dk/angsd/" + documentation: "http://www.popgen.dk/angsd/" + tool_dev_url: "https://github.com/ANGSD/angsd" + doi: "10.1186/s12859-014-0356-4" + licence: + - "GPL v3" + - "MIT" + identifier: biotools:angsd +input: + - - meta: + type: map + description: | + Groovy Map containing population information + e.g. [ id:'test', population:'population id', samples:'sample IDs' ] + - bams: + type: file + description: A list of BAM or CRAM files. + pattern: "*.{bam,cram}" + ontologies: + - edam: "http://edamontology.org/format_2572" + - edam: "http://edamontology.org/format_3462" + - bam_indices: + type: file + description: A list of BAM or CRAM indices. + pattern: "*.{bam.bai,cram.crai}" + ontologies: + - edam: "http://edamontology.org/format_3327" + - edam: "http://edamontology.org/format_3462" + - - reference_fasta: + type: file + description: A reference genome in FASTA format. + pattern: "*.{fasta,fa,fasta.gz,fa.gz}" + ontologies: + - edam: "http://edamontology.org/format_1929" + - reference_fai: + type: file + description: Index of the reference genome FASTA file. + pattern: "*.{fasta,fa,fasta.gz,fa.gz}.fai" + ontologies: + - edam: "http://edamontology.org/format_1929" + - - ancestral_fasta: + type: file + description: An ancestral state genome in FASTA format. + pattern: "*.{fasta,fa,fasta.gz,fa.gz}" + ontologies: + - edam: "http://edamontology.org/format_1929" + - ancestral_fai: + type: file + description: Index of the ancestral state genome FASTA file. + pattern: "*.{fasta,fa,fasta.gz,fa.gz}.fai" + ontologies: + - edam: "http://edamontology.org/format_1929" + - error_file: + type: file + description: A file containing per-base substitution error rates for use + with the Sykes genotype likelihood model (-GL 4). + pattern: "*.errors" + ontologies: [] + - inbreeding_coefficients: + type: file + description: A file containing estimates of individual inbreeding + coefficients. + pattern: "*.indF" + ontologies: [] + - gl_model: + type: integer + description: | + Genotype likelihood model to use (angsd -GL). 1=SAMtools, 2=GATK, 3=SOAPsnp, 4=SYK. + - dosaf_mode: + type: integer + description: | + Site allele frequency likelihood estimation mode (angsd -doSAF). 1=standard, 2=inbreeding-aware (requires indF). +output: + saf: + - - meta: + type: map + description: Groovy Map containing population information. e.g. `[ + id:'test', population:'population id', samples:'sample IDs' ]` + - "*.saf.idx": + type: file + description: ANGSD site allele frequency index file + pattern: "*.saf.idx" + ontologies: [] + - "*.saf.pos.gz": + type: file + description: Gzipped file containing genomic positions of sites in the + SAF + pattern: "*.saf.pos.gz" + ontologies: + - edam: http://edamontology.org/format_3989 + - "*.saf.gz": + type: file + description: Gzipped binary file containing per-site sample allele + frequency likelihoods + pattern: "*.saf.gz" + ontologies: + - edam: http://edamontology.org/format_3989 + versions_angsd: + - - "${task.process}": + type: string + description: The name of the process + - angsd: + type: string + description: The name of the tool + - "angsd 2>&1 | sed '1!d;s/.*version: //;s/ .*//'": + type: eval + description: The expression to obtain the version of the tool +topics: + versions: + - - "${task.process}": + type: string + description: The name of the process + - angsd: + type: string + description: The name of the tool + - "angsd 2>&1 | sed '1!d;s/.*version: //;s/ .*//'": + type: eval + description: The expression to obtain the version of the tool +authors: + - "@ASendellPrice" +maintainers: + - "@ASendellPrice" diff --git a/modules/nf-core/angsd/dosaf/tests/main.nf.test b/modules/nf-core/angsd/dosaf/tests/main.nf.test new file mode 100644 index 000000000000..e8bf55d1a314 --- /dev/null +++ b/modules/nf-core/angsd/dosaf/tests/main.nf.test @@ -0,0 +1,843 @@ +nextflow_process { + + name "Test Process ANGSD_DOSAF" + script "../main.nf" + process "ANGSD_DOSAF" + + tag "modules" + tag "modules_nfcore" + tag "angsd" + tag "angsd/dosaf" + + + // ------------------------------------------------------------------------- + // SUCCESS CASE 1: GL 1; doSAF 1; no ancestral + // ------------------------------------------------------------------------- + + test("angsd - GL 1 - doSAF 1") { + config "./nextflow.config" + + when { + params { + angsd_args = '-r chr20:1400000-1500000 -checkBamHeaders 0' + min_ind_frac = 0 + } + process { + """ + input[0] = [ + [ + id: "FIN", + population: "FIN", + samples: ["HG00349", "HG00358", "HG00350", "HG00351"] + ], + [ + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00349.chr20_1400000-1500000.bam"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00350.chr20_1400000-1500000.bam"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00351.chr20_1400000-1500000.bam"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00358.chr20_1400000-1500000.bam") + ], + [ + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00349.chr20_1400000-1500000.bam.bai"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00350.chr20_1400000-1500000.bam.bai"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00351.chr20_1400000-1500000.bam.bai"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00358.chr20_1400000-1500000.bam.bai") + ] + ] + input[1] = [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr20/sequence/GRCh38_chr20_1_2000000.fasta.gz'), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr20/sequence/GRCh38_chr20_1_2000000.fasta.gz.fai') + ] + input[2] = [ [], [] ] + input[3] = [] + input[4] = [] + input[5] = 1 + input[6] = 1 + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert process.out.saf }, + { assert snapshot(sanitizeOutput(process.out)).match() } + ) + } + } + + + // ------------------------------------------------------------------------- + // SUCCESS CASE 2: GL 1; doSAF 2; no ancestral + // ------------------------------------------------------------------------- + + test("angsd - GL 1 - doSAF 2") { + config "./nextflow.config" + + setup{ + new File("${launchDir}/angsd_FIN.indF").text = "0.0\n0.0\n0.01\n0.017\n" + } + + when { + params { + angsd_args = '-doMajorMinor 1 -doMaf 1 -r chr20:1400000-1500000 -checkBamHeaders 0' + min_ind_frac = 0 + } + process { + """ + input[0] = [ + [ + id: "FIN", + population: "FIN", + samples: ["HG00349", "HG00358", "HG00350", "HG00351"] + ], + [ + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00349.chr20_1400000-1500000.bam"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00350.chr20_1400000-1500000.bam"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00351.chr20_1400000-1500000.bam"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00358.chr20_1400000-1500000.bam") + ], + [ + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00349.chr20_1400000-1500000.bam.bai"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00350.chr20_1400000-1500000.bam.bai"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00351.chr20_1400000-1500000.bam.bai"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00358.chr20_1400000-1500000.bam.bai") + ] + ] + input[1] = [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr20/sequence/GRCh38_chr20_1_2000000.fasta.gz'), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr20/sequence/GRCh38_chr20_1_2000000.fasta.gz.fai') + ] + input[2] = [ [], [] ] + input[3] = [] + input[4] = file("${launchDir}/angsd_FIN.indF", checkIfExists: true) + input[5] = 1 + input[6] = 2 + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert process.out.saf }, + { assert snapshot(sanitizeOutput(process.out)).match() } + ) + } + } + + + // ------------------------------------------------------------------------- + // SUCCESS CASE 3: GL 3; doSAF 1; no ancestral + // ------------------------------------------------------------------------- + + test("angsd - GL3 - two steps") { + config "./nextflow.config" + + when { + params { + angsd_args = '-r chr20:1400000-1500000 -checkBamHeaders 0' + min_ind_frac = 0 + } + + process { + """ + input[0] = [ + [ + id: "FIN", + population: "FIN", + samples: ["HG00349", "HG00358", "HG00350", "HG00351"] + ], + [ + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00349.chr20_1400000-1500000.bam"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00350.chr20_1400000-1500000.bam"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00351.chr20_1400000-1500000.bam"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00358.chr20_1400000-1500000.bam") + ], + [ + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00349.chr20_1400000-1500000.bam.bai"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00350.chr20_1400000-1500000.bam.bai"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00351.chr20_1400000-1500000.bam.bai"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00358.chr20_1400000-1500000.bam.bai") + ] + ] + input[1] = [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr20/sequence/GRCh38_chr20_1_2000000.fasta.gz'), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr20/sequence/GRCh38_chr20_1_2000000.fasta.gz.fai') + ] + input[2] = [ [], [] ] + input[3] = [] + input[4] = [] + input[5] = 3 + input[6] = 1 + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert process.out.saf }, + { assert snapshot(sanitizeOutput(process.out)).match() } + ) + } + } + + + // ------------------------------------------------------------------------- + // SUCCESS CASE 4: GL 4 (requires error file) + // ------------------------------------------------------------------------- + + test("angsd - GL4") { + config "./nextflow.config" + + setup { + new File("${launchDir}/angsd_syk.errors").text = "0.000000\t0.005488\t0.003847\t0.003137\t0.006807\t0.000000\t0.001972\t0.002396\t0.002190\t0.001855\t0.000000\t0.008068\t0.002491\t0.004268\t0.005812\t0.000000\n" + } + + when { + params { + angsd_args = '-r chr20:1400000-1500000 -checkBamHeaders 0' + min_ind_frac = 0 + } + + process { + """ + input[0] = [ + [ + id: "FIN", + population: "FIN", + samples: ["HG00349", "HG00358", "HG00350", "HG00351"] + ], + [ + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00349.chr20_1400000-1500000.bam"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00350.chr20_1400000-1500000.bam"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00351.chr20_1400000-1500000.bam"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00358.chr20_1400000-1500000.bam") + ], + [ + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00349.chr20_1400000-1500000.bam.bai"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00350.chr20_1400000-1500000.bam.bai"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00351.chr20_1400000-1500000.bam.bai"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00358.chr20_1400000-1500000.bam.bai") + ] + ] + input[1] = [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr20/sequence/GRCh38_chr20_1_2000000.fasta.gz'), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr20/sequence/GRCh38_chr20_1_2000000.fasta.gz.fai') + ] + input[2] = [ [], [] ] + input[3] = file("${launchDir}/angsd_syk.errors", checkIfExists: true) + input[4] = [] + input[5] = 4 + input[6] = 1 + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert process.out.saf }, + { assert snapshot(sanitizeOutput(process.out)).match() } + ) + } + } + + + // ------------------------------------------------------------------------- + // SUCCESS CASE 5: GL 1; doSAF 1; with ancestral FASTA + // ------------------------------------------------------------------------- + + test("angsd - GL 1 - doSAF 1 - with ancestral fasta") { + config "./nextflow.config" + + when { + params { + angsd_args = '-r chr20:1400000-1500000 -checkBamHeaders 0' + min_ind_frac = 0 + } + process { + """ + input[0] = [ + [ + id: "FIN", + population: "FIN", + samples: ["HG00349", "HG00358", "HG00350", "HG00351"] + ], + [ + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00349.chr20_1400000-1500000.bam"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00350.chr20_1400000-1500000.bam"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00351.chr20_1400000-1500000.bam"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00358.chr20_1400000-1500000.bam") + ], + [ + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00349.chr20_1400000-1500000.bam.bai"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00350.chr20_1400000-1500000.bam.bai"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00351.chr20_1400000-1500000.bam.bai"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00358.chr20_1400000-1500000.bam.bai") + ] + ] + input[1] = [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr20/sequence/GRCh38_chr20_1_2000000.fasta.gz'), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr20/sequence/GRCh38_chr20_1_2000000.fasta.gz.fai') + ] + input[2] = [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr20/resources/homo_sapiens_ancestor_chr20_1_2000000.fasta.gz'), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr20/resources/homo_sapiens_ancestor_chr20_1_2000000.fasta.gz.fai') + ] + input[3] = [] + input[4] = [] + input[5] = 1 + input[6] = 1 + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert process.out.saf }, + { assert snapshot(sanitizeOutput(process.out)).match() } + ) + } + } + + + // ------------------------------------------------------------------------- + // SUCCESS CASE 6: GL 1; doSAF 1; min_ind_frac > 0 + // ------------------------------------------------------------------------- + + test("angsd - GL 1 - doSAF 1 - min_ind_frac") { + config "./nextflow.config" + + when { + params { + angsd_args = '-r chr20:1400000-1500000 -checkBamHeaders 0' + min_ind_frac = 0.5 + } + process { + """ + input[0] = [ + [ + id: "FIN", + population: "FIN", + samples: ["HG00349", "HG00358", "HG00350", "HG00351"] + ], + [ + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00349.chr20_1400000-1500000.bam"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00350.chr20_1400000-1500000.bam"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00351.chr20_1400000-1500000.bam"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00358.chr20_1400000-1500000.bam") + ], + [ + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00349.chr20_1400000-1500000.bam.bai"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00350.chr20_1400000-1500000.bam.bai"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00351.chr20_1400000-1500000.bam.bai"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00358.chr20_1400000-1500000.bam.bai") + ] + ] + input[1] = [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr20/sequence/GRCh38_chr20_1_2000000.fasta.gz'), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr20/sequence/GRCh38_chr20_1_2000000.fasta.gz.fai') + ] + input[2] = [ [], [] ] + input[3] = [] + input[4] = [] + input[5] = 1 + input[6] = 1 + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert process.out.saf }, + { assert snapshot(sanitizeOutput(process.out)).match() } + ) + } + } + + + // ------------------------------------------------------------------------- + // FAILURE CASE 1: Missing inbreeding coefficients file (needed for doSAF 2) + // ------------------------------------------------------------------------- + + test("angsd - GL1 - doSAF2 - missing inbreeding coefficients") { + config "./nextflow.config" + + when { + params { + angsd_args = '-r chr20:1400000-1500000 -checkBamHeaders 0' + min_ind_frac = 0 + } + process { + """ + input[0] = [ + [ + id: "FIN", + population: "FIN", + samples: ["HG00349", "HG00358", "HG00350", "HG00351"] + ], + [ + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00349.chr20_1400000-1500000.bam"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00350.chr20_1400000-1500000.bam"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00351.chr20_1400000-1500000.bam"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00358.chr20_1400000-1500000.bam") + ], + [ + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00349.chr20_1400000-1500000.bam.bai"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00350.chr20_1400000-1500000.bam.bai"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00351.chr20_1400000-1500000.bam.bai"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00358.chr20_1400000-1500000.bam.bai") + ] + ] + input[1] = [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr20/sequence/GRCh38_chr20_1_2000000.fasta.gz'), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr20/sequence/GRCh38_chr20_1_2000000.fasta.gz.fai') + ] + input[2] = [ [], [] ] + input[3] = [] + input[4] = [] + input[5] = 1 + input[6] = 2 + """ + } + } + + then { + def caused = process.errorReport + .split("Source block:")[0] + .split("Caused by:")[1] + .trim() + + assertAll( + { assert process.failed }, + { assert caused.contains("-doSAF 2 requires inbreeding coefficients") } + ) + } + } + + + // ------------------------------------------------------------------------- + // FAILURE CASE 2: Missing doSAF mode (not supplied) + // ------------------------------------------------------------------------- + + test("angsd - missing doSAF mode") { + config "./nextflow.config" + + when { + params { + angsd_args = '-r chr20:1400000-1500000 -checkBamHeaders 0' + min_ind_frac = 0 + } + process { + """ + input[0] = [ + [ + id: "FIN", + population: "FIN", + samples: ["HG00349", "HG00358", "HG00350", "HG00351"] + ], + [ + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00349.chr20_1400000-1500000.bam"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00350.chr20_1400000-1500000.bam"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00351.chr20_1400000-1500000.bam"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00358.chr20_1400000-1500000.bam") + ], + [ + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00349.chr20_1400000-1500000.bam.bai"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00350.chr20_1400000-1500000.bam.bai"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00351.chr20_1400000-1500000.bam.bai"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00358.chr20_1400000-1500000.bam.bai") + ] + ] + input[1] = [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr20/sequence/GRCh38_chr20_1_2000000.fasta.gz'), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr20/sequence/GRCh38_chr20_1_2000000.fasta.gz.fai') + ] + input[2] = [ [], [] ] + input[3] = [] + input[4] = [] + input[5] = 1 + input[6] = [] + """ + } + } + + then { + def caused = process.errorReport + .split("Source block:")[0] + .split("Caused by:")[1] + .trim() + + assertAll( + { assert process.failed }, + { assert caused.contains("Invalid doSAF mode") } + ) + } + } + + + // ------------------------------------------------------------------------- + // FAILURE CASE 3: Missing GL model (not supplied) + // ------------------------------------------------------------------------- + + test("angsd - missing GL model") { + config "./nextflow.config" + + when { + params { + angsd_args = '-r chr20:1400000-1500000 -checkBamHeaders 0' + min_ind_frac = 0 + } + process { + """ + input[0] = [ + [ + id: "FIN", + population: "FIN", + samples: ["HG00349", "HG00358", "HG00350", "HG00351"] + ], + [ + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00349.chr20_1400000-1500000.bam"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00350.chr20_1400000-1500000.bam"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00351.chr20_1400000-1500000.bam"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00358.chr20_1400000-1500000.bam") + ], + [ + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00349.chr20_1400000-1500000.bam.bai"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00350.chr20_1400000-1500000.bam.bai"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00351.chr20_1400000-1500000.bam.bai"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00358.chr20_1400000-1500000.bam.bai") + ] + ] + input[1] = [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr20/sequence/GRCh38_chr20_1_2000000.fasta.gz'), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr20/sequence/GRCh38_chr20_1_2000000.fasta.gz.fai') + ] + input[2] = [ [], [] ] + input[3] = [] + input[4] = [] + input[5] = [] + input[6] = 1 + """ + } + } + + then { + def caused = process.errorReport + .split("Source block:")[0] + .split("Caused by:")[1] + .trim() + + assertAll( + { assert process.failed }, + { assert caused.contains("Invalid GL model") } + ) + } + } + + + // ------------------------------------------------------------------------- + // FAILURE CASE 4: Invalid GL value + // ------------------------------------------------------------------------- + + test("angsd - invalid -GL value") { + config "./nextflow.config" + + when { + params { + angsd_args = '-r chr20:1400000-1500000 -checkBamHeaders 0' + min_ind_frac = 0 + } + process { + """ + input[0] = [ + [ + id: "FIN", + population: "FIN", + samples: ["HG00349", "HG00358", "HG00350", "HG00351"] + ], + [ + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00349.chr20_1400000-1500000.bam"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00350.chr20_1400000-1500000.bam"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00351.chr20_1400000-1500000.bam"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00358.chr20_1400000-1500000.bam") + ], + [ + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00349.chr20_1400000-1500000.bam.bai"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00350.chr20_1400000-1500000.bam.bai"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00351.chr20_1400000-1500000.bam.bai"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00358.chr20_1400000-1500000.bam.bai") + ] + ] + input[1] = [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr20/sequence/GRCh38_chr20_1_2000000.fasta.gz'), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr20/sequence/GRCh38_chr20_1_2000000.fasta.gz.fai') + ] + input[2] = [ [], [] ] + input[3] = [] + input[4] = [] + input[5] = 5 + input[6] = 1 + """ + } + } + + then { + def caused = process.errorReport + .split("Source block:")[0] + .split("Caused by:")[1] + .trim() + + assertAll( + { assert process.failed }, + { assert caused.contains("Invalid GL model") } + ) + } + } + + + // ------------------------------------------------------------------------- + // FAILURE CASE 5: Missing error file (required by -GL 4) + // ------------------------------------------------------------------------- + + test("angsd - GL4 - missing error file") { + config "./nextflow.config" + + when { + params { + angsd_args = '-r chr20:1400000-1500000 -checkBamHeaders 0' + min_ind_frac = 0 + } + process {""" + input[0] = [ + [ + id: "FIN", + population: "FIN", + samples: ["HG00349", "HG00358", "HG00350", "HG00351"] + ], + [ + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00349.chr20_1400000-1500000.bam"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00350.chr20_1400000-1500000.bam"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00351.chr20_1400000-1500000.bam"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00358.chr20_1400000-1500000.bam") + ], + [ + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00349.chr20_1400000-1500000.bam.bai"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00350.chr20_1400000-1500000.bam.bai"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00351.chr20_1400000-1500000.bam.bai"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00358.chr20_1400000-1500000.bam.bai") + ] + ] + input[1] = [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr20/sequence/GRCh38_chr20_1_2000000.fasta.gz'), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr20/sequence/GRCh38_chr20_1_2000000.fasta.gz.fai') + ] + input[2] = [ [], [] ] + input[3] = [] + input[4] = [] + input[5] = 4 + input[6] = 1 + """} + } + + then { + def caused = process.errorReport + .split("Source block:")[0] + .split("Caused by:")[1] + .trim() + + assertAll( + { assert process.failed }, + { assert caused.contains("-GL 4 (SYK model) requires an error file") } + ) + } + } + + + // ------------------------------------------------------------------------- + // FAILURE CASE 6: doSAF 2 called without -doMajorMinor + // ------------------------------------------------------------------------- + + test("angsd - GL 1 - doSAF 2 - missing -doMajorMinor") { + config "./nextflow.config" + + setup{ + new File("${launchDir}/angsd_FIN.indF").text = "0.0\n0.0\n0.01\n0.017\n" + } + + when { + params { + angsd_args = '-doMaf 1 -r chr20:1400000-1500000 -checkBamHeaders 0' + min_ind_frac = 0 + } + process { + """ + input[0] = [ + [ + id: "FIN", + population: "FIN", + samples: ["HG00349", "HG00358", "HG00350", "HG00351"] + ], + [ + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00349.chr20_1400000-1500000.bam"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00350.chr20_1400000-1500000.bam"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00351.chr20_1400000-1500000.bam"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00358.chr20_1400000-1500000.bam") + ], + [ + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00349.chr20_1400000-1500000.bam.bai"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00350.chr20_1400000-1500000.bam.bai"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00351.chr20_1400000-1500000.bam.bai"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00358.chr20_1400000-1500000.bam.bai") + ] + ] + input[1] = [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr20/sequence/GRCh38_chr20_1_2000000.fasta.gz'), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr20/sequence/GRCh38_chr20_1_2000000.fasta.gz.fai') + ] + input[2] = [ [], [] ] + input[3] = [] + input[4] = file("${launchDir}/angsd_FIN.indF", checkIfExists: true) + input[5] = 1 + input[6] = 2 + """ + } + } + + then { + def caused = process.errorReport + .split("Source block:")[0] + .split("Caused by:")[1] + .trim() + + assertAll( + { assert process.failed }, + { assert caused.contains("-doSAF 2 requires -doMajorMinor to be specified. Please include in ext.args.") } + ) + } + } + + + // ------------------------------------------------------------------------- + // FAILURE CASE 7: doSAF 2 called without -doMaf + // ------------------------------------------------------------------------- + + test("angsd - GL 1 - doSAF 2 - missing -doMaf") { + config "./nextflow.config" + + setup{ + new File("${launchDir}/angsd_FIN.indF").text = "0.0\n0.0\n0.01\n0.017\n" + } + + when { + params { + angsd_args = '-doMajorMinor 1 -r chr20:1400000-1500000 -checkBamHeaders 0' + min_ind_frac = 0 + } + process { + """ + input[0] = [ + [ + id: "FIN", + population: "FIN", + samples: ["HG00349", "HG00358", "HG00350", "HG00351"] + ], + [ + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00349.chr20_1400000-1500000.bam"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00350.chr20_1400000-1500000.bam"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00351.chr20_1400000-1500000.bam"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00358.chr20_1400000-1500000.bam") + ], + [ + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00349.chr20_1400000-1500000.bam.bai"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00350.chr20_1400000-1500000.bam.bai"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00351.chr20_1400000-1500000.bam.bai"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00358.chr20_1400000-1500000.bam.bai") + ] + ] + input[1] = [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr20/sequence/GRCh38_chr20_1_2000000.fasta.gz'), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr20/sequence/GRCh38_chr20_1_2000000.fasta.gz.fai') + ] + input[2] = [ [], [] ] + input[3] = [] + input[4] = file("${launchDir}/angsd_FIN.indF", checkIfExists: true) + input[5] = 1 + input[6] = 2 + """ + } + } + + then { + def caused = process.errorReport + .split("Source block:")[0] + .split("Caused by:")[1] + .trim() + + assertAll( + { assert process.failed }, + { assert caused.contains("-doSAF 2 requires -doMaf to be specified. Please include in ext.args.") } + ) + } + } + + + // ------------------------------------------------------------------------- + // STUB + // ------------------------------------------------------------------------- + + test("angsd - GL 1 - doSAF 1 - stub") { + options "-stub" + config "./nextflow.config" + + when { + params { + angsd_args = '-r chr20:1400000-1500000 -checkBamHeaders 0' + min_ind_frac = 0 + } + process { + """ + input[0] = [ + [ + id: "FIN", + population: "FIN", + samples: ["HG00349", "HG00358", "HG00350", "HG00351"] + ], + [ + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00349.chr20_1400000-1500000.bam"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00350.chr20_1400000-1500000.bam"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00351.chr20_1400000-1500000.bam"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00358.chr20_1400000-1500000.bam") + ], + [ + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00349.chr20_1400000-1500000.bam.bai"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00350.chr20_1400000-1500000.bam.bai"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00351.chr20_1400000-1500000.bam.bai"), + file(params.modules_testdata_base_path + "genomics/homo_sapiens/illumina/bam/HG00358.chr20_1400000-1500000.bam.bai") + ] + ] + input[1] = [ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr20/sequence/GRCh38_chr20_1_2000000.fasta.gz'), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/genome/chr20/sequence/GRCh38_chr20_1_2000000.fasta.gz.fai') + ] + input[2] = [ [], [] ] + input[3] = [] + input[4] = [] + input[5] = 1 + input[6] = 1 + """ + } + } + + then { + assertAll( + { assert process.success }, + { assert snapshot(process.out).match() } + ) + } + } + +} diff --git a/modules/nf-core/angsd/dosaf/tests/main.nf.test.snap b/modules/nf-core/angsd/dosaf/tests/main.nf.test.snap new file mode 100644 index 000000000000..8394d92a34db --- /dev/null +++ b/modules/nf-core/angsd/dosaf/tests/main.nf.test.snap @@ -0,0 +1,271 @@ +{ + "angsd - GL 1 - doSAF 2": { + "content": [ + { + "saf": [ + [ + { + "id": "FIN", + "population": "FIN", + "samples": [ + "HG00349", + "HG00358", + "HG00350", + "HG00351" + ] + }, + "FIN.saf.idx:md5,f825a57ec037dd03127fced8c11c1f84", + "FIN.saf.pos.gz:md5,bbdf128514097d6faa7c71031af7b97b", + "FIN.saf.gz:md5,5b8d21df08479f96405d430758937977" + ] + ], + "versions_angsd": [ + [ + "ANGSD_DOSAF", + "angsd", + "0.940-dirty" + ] + ] + } + ], + "timestamp": "2026-07-16T12:41:01.480791", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.1" + } + }, + "angsd - GL 1 - doSAF 1": { + "content": [ + { + "saf": [ + [ + { + "id": "FIN", + "population": "FIN", + "samples": [ + "HG00349", + "HG00358", + "HG00350", + "HG00351" + ] + }, + "FIN.saf.idx:md5,c2a21e30aacb59091931c3651ea69ccd", + "FIN.saf.pos.gz:md5,bbdf128514097d6faa7c71031af7b97b", + "FIN.saf.gz:md5,8ca7bbf4f93b7aa09cb6da8f7c87c132" + ] + ], + "versions_angsd": [ + [ + "ANGSD_DOSAF", + "angsd", + "0.940-dirty" + ] + ] + } + ], + "timestamp": "2026-07-16T12:40:55.726472", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.1" + } + }, + "angsd - GL 1 - doSAF 1 - with ancestral fasta": { + "content": [ + { + "saf": [ + [ + { + "id": "FIN", + "population": "FIN", + "samples": [ + "HG00349", + "HG00358", + "HG00350", + "HG00351" + ] + }, + "FIN.saf.idx:md5,c2a21e30aacb59091931c3651ea69ccd", + "FIN.saf.pos.gz:md5,bbdf128514097d6faa7c71031af7b97b", + "FIN.saf.gz:md5,29eb0ee312740e0aa6de230e6405e44e" + ] + ], + "versions_angsd": [ + [ + "ANGSD_DOSAF", + "angsd", + "0.940-dirty" + ] + ] + } + ], + "timestamp": "2026-07-16T12:41:27.922853", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.1" + } + }, + "angsd - GL3 - two steps": { + "content": [ + { + "saf": [ + [ + { + "id": "FIN", + "population": "FIN", + "samples": [ + "HG00349", + "HG00358", + "HG00350", + "HG00351" + ] + }, + "FIN.saf.idx:md5,ed87cdf671b5b11137b5082f05e3ce6a", + "FIN.saf.pos.gz:md5,bbdf128514097d6faa7c71031af7b97b", + "FIN.saf.gz:md5,095fc8b1763ae7be00218e0d52e1a1b4" + ] + ], + "versions_angsd": [ + [ + "ANGSD_DOSAF", + "angsd", + "0.940-dirty" + ] + ] + } + ], + "timestamp": "2026-07-16T12:41:15.856922", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.1" + } + }, + "angsd - GL 1 - doSAF 1 - stub": { + "content": [ + { + "0": [ + [ + { + "id": "FIN", + "population": "FIN", + "samples": [ + "HG00349", + "HG00358", + "HG00350", + "HG00351" + ] + }, + "FIN.saf.idx:md5,d41d8cd98f00b204e9800998ecf8427e", + "FIN.saf.pos.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "FIN.saf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "1": [ + [ + "ANGSD_DOSAF", + "angsd", + "0.940-dirty" + ] + ], + "saf": [ + [ + { + "id": "FIN", + "population": "FIN", + "samples": [ + "HG00349", + "HG00358", + "HG00350", + "HG00351" + ] + }, + "FIN.saf.idx:md5,d41d8cd98f00b204e9800998ecf8427e", + "FIN.saf.pos.gz:md5,68b329da9893e34099c7d8ad5cb9c940", + "FIN.saf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + "versions_angsd": [ + [ + "ANGSD_DOSAF", + "angsd", + "0.940-dirty" + ] + ] + } + ], + "timestamp": "2026-07-16T12:41:57.125426", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.1" + } + }, + "angsd - GL4": { + "content": [ + { + "saf": [ + [ + { + "id": "FIN", + "population": "FIN", + "samples": [ + "HG00349", + "HG00358", + "HG00350", + "HG00351" + ] + }, + "FIN.saf.idx:md5,821d582655745d035cd963012e04684e", + "FIN.saf.pos.gz:md5,bbdf128514097d6faa7c71031af7b97b", + "FIN.saf.gz:md5,e21b7f5dfdcdeec7bd59a3c203a95c7c" + ] + ], + "versions_angsd": [ + [ + "ANGSD_DOSAF", + "angsd", + "0.940-dirty" + ] + ] + } + ], + "timestamp": "2026-07-16T12:41:21.255121", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.1" + } + }, + "angsd - GL 1 - doSAF 1 - min_ind_frac": { + "content": [ + { + "saf": [ + [ + { + "id": "FIN", + "population": "FIN", + "samples": [ + "HG00349", + "HG00358", + "HG00350", + "HG00351" + ] + }, + "FIN.saf.idx:md5,4fc612eb149887c6238af1d4239ffc7e", + "FIN.saf.pos.gz:md5,12f398f2c01708e40b32da38931ffd68", + "FIN.saf.gz:md5,5692b34cf0807dcbb92eca36f970b975" + ] + ], + "versions_angsd": [ + [ + "ANGSD_DOSAF", + "angsd", + "0.940-dirty" + ] + ] + } + ], + "timestamp": "2026-07-16T12:41:34.159609", + "meta": { + "nf-test": "0.9.5", + "nextflow": "26.04.1" + } + } +} \ No newline at end of file diff --git a/modules/nf-core/angsd/dosaf/tests/nextflow.config b/modules/nf-core/angsd/dosaf/tests/nextflow.config new file mode 100644 index 000000000000..10a06e4c1b6a --- /dev/null +++ b/modules/nf-core/angsd/dosaf/tests/nextflow.config @@ -0,0 +1,6 @@ +process { + withName: ANGSD_DOSAF { + ext.args = { params.angsd_args } + ext.args2 = { params.min_ind_frac } + } +}