From bb3bab6a8c8c099b54eec1d707596b574e7da0d7 Mon Sep 17 00:00:00 2001 From: Anabella Trigila <18577080+atrigila@users.noreply.github.com> Date: Sun, 5 Apr 2026 17:53:56 -0300 Subject: [PATCH 1/6] add new quilt2 module --- modules/nf-core/quilt/quilt2/environment.yml | 8 + modules/nf-core/quilt/quilt2/main.nf | 108 ++++++ modules/nf-core/quilt/quilt2/meta.yml | 224 ++++++++++++ .../nf-core/quilt/quilt2/tests/main.nf.test | 296 ++++++++++++++++ .../quilt/quilt2/tests/main.nf.test.snap | 320 ++++++++++++++++++ .../quilt/quilt2/tests/nextflow.config | 16 + 6 files changed, 972 insertions(+) create mode 100644 modules/nf-core/quilt/quilt2/environment.yml create mode 100644 modules/nf-core/quilt/quilt2/main.nf create mode 100644 modules/nf-core/quilt/quilt2/meta.yml create mode 100644 modules/nf-core/quilt/quilt2/tests/main.nf.test create mode 100644 modules/nf-core/quilt/quilt2/tests/main.nf.test.snap create mode 100644 modules/nf-core/quilt/quilt2/tests/nextflow.config diff --git a/modules/nf-core/quilt/quilt2/environment.yml b/modules/nf-core/quilt/quilt2/environment.yml new file mode 100644 index 000000000000..9e10122a1a3a --- /dev/null +++ b/modules/nf-core/quilt/quilt2/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::r-quilt=2.0.4=r44h503566f_0 + - r-base=4.4.0 diff --git a/modules/nf-core/quilt/quilt2/main.nf b/modules/nf-core/quilt/quilt2/main.nf new file mode 100644 index 000000000000..cb15c113f45b --- /dev/null +++ b/modules/nf-core/quilt/quilt2/main.nf @@ -0,0 +1,108 @@ +process QUILT_QUILT2 { + tag "${meta.id}" + label 'process_single' + + conda "${moduleDir}/environment.yml" + container "${workflow.containerEngine == 'singularity' && !task.ext.singularity_pull_docker_container + ? 'https://depot.galaxyproject.org/singularity/r-quilt:2.0.4--r44h503566f_0' + : 'biocontainers/r-quilt:2.0.4--r44h503566f_0'}" + + input: + tuple val(meta), path(bams), path(bais), path(bamlist), path(samplename), path(reference_vcf_file), path(reference_vcf_index), path(posfile), path(phasefile), path(genfile), val(chr), val(regions_start), val(regions_end), val(ngen), val(buffer), path(genetic_map) + tuple val(meta2), path(fasta), path(fasta_fai) + + output: + tuple val(meta), path("*.vcf.gz") , emit: vcf + tuple val(meta), path("*.vcf.gz.tbi") , emit: tbi , optional: true + tuple val(meta), path("RData", type: "dir"), emit: rdata, optional: true + tuple val(meta), path("plots", type: "dir"), emit: plots, optional: true + tuple val("${task.process}"), val('r-quilt'), eval('Rscript -e "cat(as.character(packageVersion(\'QUILT\')))"'), topic: versions, emit: versions_r_quilt + tuple val("${task.process}"), val('r-base'), eval('R --version | sed "1!d; s/.*version //; s/ .*//"'), topic: versions, emit: versions_r_base + + when: + task.ext.when == null || task.ext.when + + script: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def suffix = task.ext.suffix ?: "vcf.gz" + + def extensions = bams.collect { path -> path.extension } + def extension = extensions.flatten().unique() + def list_command = extension == ["bam"] + ? "--bamlist=" + : extension == ["cram"] ? "--reference=${fasta} --cramlist=" : "" + + def genetic_map_command = genetic_map ? "--genetic_map_file=${genetic_map}" : "" + def posfile_command = posfile ? "--posfile=${posfile}" : "" + def phasefile_command = phasefile ? "--phasefile=${phasefile}" : "" + def genfile_command = genfile ? "--genfile=${genfile}" : "" + def samplename_command = samplename ? "--sampleNames_file=${samplename}" : "" + def start_command = regions_start ? "--regionStart=${regions_start}" : "" + def end_command = regions_end ? "--regionEnd=${regions_end}" : "" + def buffer_command = buffer ? "--buffer=${buffer}" : "" + + if (!(args ==~ /.*--seed.*/)) { + args += " --seed=1" + } + + """ + if [ -n "${bamlist}" ] ; + then + BAM_LIST="${bamlist}" + else + printf "%s\\n" ${bams} | tr -d '[],' > all_files.txt + BAM_LIST="all_files.txt" + fi + + QUILT2.R \\ + ${list_command}\$BAM_LIST \\ + ${genetic_map_command} \\ + ${posfile_command} \\ + ${phasefile_command} \\ + ${genfile_command} \\ + ${samplename_command} \\ + --chr=${chr} \\ + ${start_command} \\ + ${end_command} \\ + ${buffer_command} \\ + --nGen=${ngen} \\ + --nCores=${task.cpus} \\ + --outputdir="." \\ + --reference_vcf_file=${reference_vcf_file} \\ + --output_filename=${prefix}.${suffix} \\ + ${args} + """ + + stub: + def args = task.ext.args ?: '' + def prefix = task.ext.prefix ?: "${meta.id}" + def suffix = task.ext.suffix ?: "vcf.gz" + def create_cmd = suffix.endsWith(".gz") ? "echo '' | gzip >" : "touch" + def make_plots = args.contains("--make_plots=TRUE") + def save_ref = args.contains("--save_prepared_reference=TRUE") + def nGibbsSamples = args.contains("--nGibbsSamples=") ? args.split("--nGibbsSamples=")[1].split(" ")[0] : 7 + def n_seek_its = args.contains("--n_seek_its=") ? args.split("--n_seek_its=")[1].split(" ")[0] : 3 + + """ + ${create_cmd} ${prefix}.${suffix} + touch ${prefix}.${suffix}.tbi + if [ "${save_ref}" == true ] + then + mkdir -p RData + touch "RData/QUILT_prepared_reference.${chr}.${regions_start}.${regions_end}.RData" + fi + if [ "${make_plots}" == true ] + then + mkdir -p plots + for nGibbs in {0..${nGibbsSamples}} + do + touch "plots/haps.${prefix}.${chr}.${regions_start}.${regions_end}_igs.\$((nGibbs+1)).0.truth.png" + for its in {1..${n_seek_its}} + do + touch "plots/haps.${prefix}.${chr}.${regions_start}.${regions_end}_igs.\$((nGibbs+1)).it\$its.gibbs.png" + done + done + fi + """ +} diff --git a/modules/nf-core/quilt/quilt2/meta.yml b/modules/nf-core/quilt/quilt2/meta.yml new file mode 100644 index 000000000000..75f68be99e64 --- /dev/null +++ b/modules/nf-core/quilt/quilt2/meta.yml @@ -0,0 +1,224 @@ +name: "quilt_quilt2" +description: QUILT2 is an R and C++ program for fast genotype imputation from + low-coverage sequence using a large phased reference panel in VCF/BCF format. +keywords: + - imputation + - low-coverage + - genotype + - genomics + - vcf +tools: + - "quilt": + description: "Fast read-aware genotype imputation from low-coverage sequence + using a large phased reference panel" + homepage: "https://github.com/rwdavies/QUILT" + documentation: "https://github.com/rwdavies/QUILT" + tool_dev_url: "https://github.com/rwdavies/QUILT" + doi: "10.1038/s41467-025-67218-1" + licence: + - "GPL v3" + identifier: "" +input: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - bams: + type: file + description: (Mandatory) BAM/CRAM files + pattern: "*.{bam,cram}" + ontologies: [] + - bais: + type: file + description: (Mandatory) BAM/CRAM index files + pattern: "*.{bai,crai}" + ontologies: [] + - bamlist: + type: file + description: (Optional) File with list of BAM/CRAM files to impute. One + file per line. + pattern: "*.{txt}" + ontologies: [] + - samplename: + type: file + description: (Optional) File with list of samples names in the same order + as in bamlist to impute. One file per line. + pattern: "*.{txt}" + ontologies: [] + - reference_vcf_file: + type: file + description: (Mandatory) Phased reference panel VCF/BCF file for + imputation. + pattern: "*.{vcf,vcf.gz,bcf}" + ontologies: [] + - reference_vcf_index: + type: file + description: (Mandatory) Index for the reference panel VCF file. + pattern: "*.{tbi,csi}" + ontologies: [] + - posfile: + type: file + description: (Optional) File with positions of where to impute, lining up + one-to-one with genfile. File is tab separated with no header, one row + per SNP, with col 1 = chromosome, col 2 = physical position (sorted from + smallest to largest), col 3 = reference base, col 4 = alternate base. + Bases are capitalized. + pattern: "*.{txt}" + ontologies: [] + - phasefile: + type: file + description: (Optional) File with truth phasing results. Supersedes + genfile if both options given. File has a header row with a name for + each sample, matching what is found in the bam file. Each subject is + then a tab separated column, with 0 = ref and 1 = alt, separated by a + vertical bar |, e.g. 0|0 or 0|1. Note therefore this file has one more + row than posfile which has no header. + pattern: "*.{txt}" + ontologies: [] + - genfile: + type: file + description: (Optional) Path to gen file with high coverage results. Empty + for no genfile. If both genfile and phasefile are given, only phasefile + is used, as genfile (unphased genotypes) is derivative to phasefile + (phased genotypes). File has a header row with a name for each sample, + matching what is found in the bam file. Each subject is then a tab + seperated column, with 0 = hom ref, 1 = het, 2 = hom alt and NA + indicating missing genotype, with rows corresponding to rows of the + posfile. Note therefore this file has one more row than posfile which + has no header [default ""] + pattern: "*.{txt}" + ontologies: [] + - chr: + type: string + description: (Mandatory) What chromosome to run. Should match BAM headers. + - regions_start: + type: integer + description: (Mandatory) When running imputation, where to start from. The + 1-based position x is kept if regionStart <= x <= regionEnd. + - regions_end: + type: integer + description: (Mandatory) When running imputation, where to stop. + - ngen: + type: integer + description: Number of generations since founding or mixing. Note that the + algorithm is relatively robust to this. Use nGen = 4 * Ne / K if unsure. + - buffer: + type: integer + description: Buffer of region to perform imputation over. So imputation is + run form regionStart-buffer to regionEnd+buffer, and reported for + regionStart to regionEnd, including the bases of regionStart and + regionEnd. + - genetic_map: + type: file + description: (Optional) File with genetic map information, a file with 3 + white-space delimited entries giving position (1-based), genetic rate + map in cM/Mbp, and genetic map in cM. If no file included, rate is based + on physical distance and expected rate (expRate). + pattern: "*.{txt,map}{,gz}" + ontologies: [] + - - meta2: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - fasta: + type: file + description: (Optional) File with reference genome. + pattern: "*.{fa,fasta}" + ontologies: [] + - fasta_fai: + type: file + description: (Optional) File with reference genome index. + pattern: "*.{fai}" + ontologies: [] +output: + vcf: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.vcf.gz": + type: file + description: VCF file with both SNP annotation information and + per-sample genotype information. + pattern: "*.{vcf.gz}" + ontologies: [] + tbi: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - "*.vcf.gz.tbi": + type: file + description: TBI file of the VCF. + pattern: "*.{vcf.gz.tbi}" + ontologies: [] + rdata: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - RData: + type: directory + description: | + Folder of RData objects generated during the imputation process. + pattern: "RData" + plots: + - - meta: + type: map + description: | + Groovy Map containing sample information + e.g. [ id:'test', single_end:false ] + - plots: + type: directory + description: | + Folder of plots generated during the imputation process. + pattern: "plots" + versions_r_quilt: + - - ${task.process}: + type: string + description: The name of the process + - r-quilt: + type: string + description: The name of the tool + - Rscript -e "cat(as.character(packageVersion('QUILT')))": + type: eval + description: The expression to obtain the version of the tool + versions_r_base: + - - ${task.process}: + type: string + description: The name of the process + - r-base: + type: string + description: The name of the tool + - R --version | 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 + - r-quilt: + type: string + description: The name of the tool + - Rscript -e "cat(as.character(packageVersion('QUILT')))": + type: eval + description: The expression to obtain the version of the tool + - - ${task.process}: + type: string + description: The name of the process + - r-base: + type: string + description: The name of the tool + - R --version | sed "1!d; s/.*version //; s/ .*//": + type: eval + description: The expression to obtain the version of the tool +authors: + - "@atrigila" +maintainers: + - "@atrigila" diff --git a/modules/nf-core/quilt/quilt2/tests/main.nf.test b/modules/nf-core/quilt/quilt2/tests/main.nf.test new file mode 100644 index 000000000000..6a4b6fe4663a --- /dev/null +++ b/modules/nf-core/quilt/quilt2/tests/main.nf.test @@ -0,0 +1,296 @@ +nextflow_process { + + name "Test Process QUILT2" + script "../main.nf" + process "QUILT_QUILT2" + + tag "modules" + tag "modules_nfcore" + tag "quilt/quilt2" + tag "quilt" + + config "./nextflow.config" + + test("homo_sapiens - bam, reference vcf, map - fasta") { + when { + params{ + quilt_args = "--save_prepared_reference=TRUE --seed=1" + } + process { + """ + input[0] = [ + [ id:'NA12878', chr:'chr22' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/NA12878.chr21_22.1X.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/NA12878.chr21_22.1X.bam.bai', checkIfExists: true), + [], [], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/popgen/1000GP.chr22.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/popgen/1000GP.chr22.vcf.gz.csi', checkIfExists: true), + [], [], [], + "chr22", "16570000", "16610000", "100", "10000", + file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genetic_map/genome.GRCh38.chr22.stitch.map", checkIfExists:true) + ] + input[1] = [ + [id: 'GRCh38'], + 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.fai', checkIfExists: true) + ] + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot( + process.out.tbi, + process.out.rdata, + process.out.vcf.collect{ meta, vcf -> [ + meta, + path(vcf).vcf.header.getGenotypeSamples().sort(), + path(vcf).vcf.variantsMD5 + ]}, + process.out.findAll { key, val -> key.startsWith('versions') } + ).match() } + ) + } + } + + test("QUILT2 - stub") { + options '-stub' + when { + params{ + quilt_args = "--save_prepared_reference=TRUE --make_plots=TRUE" + } + process { + """ + input[0] = Channel.of([ + [ id:'NA12878', chr:'chr22' ], + [], [], [], [], [], [], [], [], + [], "chr22", "16570000", "16610000", "100", "10000", [] + ]) + input[1] = [ + [id: 'GRCh38'], + 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.fai', checkIfExists: true) + ] + """ + } + } + + then { + assert process.success + def dir = new File(process.out.plots[0][1]) + def list = [] + dir.eachFileRecurse { file -> list << file.getName() } + assertAll( + { assert snapshot( + process.out.vcf, + process.out.tbi, + list.sort(), + process.out.rdata, + process.out.findAll { key, val -> key.startsWith('versions') } + ).match() } + ) + } + } + + test("QUILT2 no optional files") { + when { + params{ + quilt_args = "--seed=1" + } + process { + """ + input[0] = [ + [ id:'test', chr:'chr22' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/NA12878.chr21_22.1X.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/NA12878.chr21_22.1X.bam.bai', checkIfExists: true), + [], [], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/popgen/1000GP.chr22.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/popgen/1000GP.chr22.vcf.gz.csi', checkIfExists: true), + [], [], [], + "chr22", "16570000", "16610000", "100", "10000", + [] + ] + input[1] = [[id: null], [], []] + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot( + process.out.tbi, + process.out.rdata, + process.out.vcf.collect{ meta, vcf -> [ + meta, + path(vcf).vcf.header.getGenotypeSamples().sort(), + path(vcf).vcf.variantsMD5 + ]}, + process.out.findAll { key, val -> key.startsWith('versions') } + ).match() } + ) + } + } + + test("QUILT2 with bamlist and renaming") { + when { + params{ + quilt_args = "--seed=1" + } + process { + """ + bamlist = Channel.of( + "NA12878.chr21_22.1X.bam", + ).collectFile(name : 'bamlist.txt', newLine : true) + + bamnames = Channel.of( + "Mysample1", + ).collectFile(name : 'bamnames.txt', newLine : true) + + ch_input = Channel.of([ + [ id:'test', chr:'chr20' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/NA12878.chr21_22.1X.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/NA12878.chr21_22.1X.bam.bai', checkIfExists: true) + ]) + .combine(bamlist) + .combine(bamnames) + .combine(Channel.of([ + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/popgen/1000GP.chr22.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/popgen/1000GP.chr22.vcf.gz.csi', checkIfExists: true), + [], [], [], + "chr22", "16570000", "16610000", "100", "10000", + [] + ])) + + input[0] = ch_input + input[1] = [[id: null], [], []] + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot( + process.out.tbi, + process.out.rdata, + process.out.vcf.collect{ meta, vcf -> [ + meta, + path(vcf).vcf.header.getGenotypeSamples().sort(), + path(vcf).vcf.variantsMD5 + ]}, + process.out.findAll { key, val -> key.startsWith('versions') } + ).match() } + ) + } + } + + test("QUILT2 quick start example") { + setup { + run("WGET", alias: "DOWNLOAD_QUICKSTART") { + script "../../../wget/main.nf" + process { + """ + input[0] = [ + [ id:'quilt2_quickstart' ], + "https://zenodo.org/records/12786681/files/QUILT2_example_2024.tar.xz", + "tar.xz" + ] + """ + } + } + + run("XZ_DECOMPRESS", alias: "XZ_DECOMPRESS_QUICKSTART") { + script "../../../xz/decompress/main.nf" + process { + """ + input[0] = DOWNLOAD_QUICKSTART.out.outfile + """ + } + } + + run("UNTAR", alias: "UNTAR_QUICKSTART") { + script "../../../untar/main.nf" + process { + """ + input[0] = XZ_DECOMPRESS_QUICKSTART.out.file.map { meta, archive -> [meta, archive] } + """ + } + } + } + + when { + params { + quilt_args = "--save_prepared_reference=TRUE --seed=1" + } + process { + """ + bamlist = Channel.of( + "NA12878.haplotagged.1.0.bam", + "NA12878.ont.1.0.bam", + "NA12878.illumina.1.0.bam", + ).collectFile(name: 'bamlist.txt', newLine: true) + + ch_quickstart = UNTAR_QUICKSTART.out.untar.map { meta, dir -> + [ + [ id:'quickstart', chr:'chr20' ], + [ + dir.resolve('NA12878.haplotagged.1.0.bam'), + dir.resolve('NA12878.ont.1.0.bam'), + dir.resolve('NA12878.illumina.1.0.bam'), + ], + [ + dir.resolve('NA12878.haplotagged.1.0.bam.bai'), + dir.resolve('NA12878.ont.1.0.bam.bai'), + dir.resolve('NA12878.illumina.1.0.bam.bai'), + ], + dir.resolve('ALL.chr20_GRCh38.genotypes.20170504.chr20.2000001.4000000.noNA12878.vcf.gz'), + dir.resolve('ALL.chr20_GRCh38.genotypes.20170504.chr20.2000001.4000000.noNA12878.vcf.gz.tbi'), + dir.resolve('CEU-chr20-final.b38.txt.gz') + ] + } + + input[0] = ch_quickstart.combine(bamlist).map { meta, bams, bais, reference_vcf, reference_vcf_index, genetic_map, bamlist_file -> + [ + meta, + bams, + bais, + bamlist_file, + [], + reference_vcf, + reference_vcf_index, + [], + [], + [], + "chr20", + "2000001", + "4000000", + "100", + "500000", + genetic_map + ] + } + input[1] = [[id: null], [], []] + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot( + process.out.tbi, + process.out.rdata, + process.out.vcf.collect{ meta, vcf -> [ + meta, + path(vcf).vcf.header.getGenotypeSamples().sort(), + path(vcf).vcf.variantsMD5 + ]}, + process.out.findAll { key, val -> key.startsWith('versions') } + ).match() } + ) + } + } +} diff --git a/modules/nf-core/quilt/quilt2/tests/main.nf.test.snap b/modules/nf-core/quilt/quilt2/tests/main.nf.test.snap new file mode 100644 index 000000000000..ad6753835af4 --- /dev/null +++ b/modules/nf-core/quilt/quilt2/tests/main.nf.test.snap @@ -0,0 +1,320 @@ +{ + "QUILT2 quick start example": { + "content": [ + [ + [ + { + "id": "quickstart", + "chr": "chr20" + }, + "quickstart.vcf.gz.tbi:md5,735a74d3b49cb9a8aa6ef77e5210a828" + ] + ], + [ + [ + { + "id": "quickstart", + "chr": "chr20" + }, + [ + "QUILT_prepared_reference.chr20.2000001.4000000.RData:md5,25868d83403201ea41f58cfea6f5e3ff" + ] + ] + ], + [ + [ + { + "id": "quickstart", + "chr": "chr20" + }, + [ + "NA12878", + "NA12878HT", + "NA12878ONT" + ], + "d20c7cfeb27ecd84f5fef33d66479e38" + ] + ], + { + "versions_r_base": [ + [ + "QUILT_QUILT2", + "r-base", + "4.4.3" + ] + ], + "versions_r_quilt": [ + [ + "QUILT_QUILT2", + "r-quilt", + "2.0.4" + ] + ] + } + ], + "timestamp": "2026-04-05T17:19:29.083876565", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + }, + "QUILT2 - stub": { + "content": [ + [ + [ + { + "id": "NA12878", + "chr": "chr22" + }, + "NA12878.vcf.gz:md5,68b329da9893e34099c7d8ad5cb9c940" + ] + ], + [ + [ + { + "id": "NA12878", + "chr": "chr22" + }, + "NA12878.vcf.gz.tbi:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ], + [ + "haps.NA12878.chr22.16570000.16610000_igs.1.0.truth.png", + "haps.NA12878.chr22.16570000.16610000_igs.1.it1.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.1.it2.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.1.it3.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.2.0.truth.png", + "haps.NA12878.chr22.16570000.16610000_igs.2.it1.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.2.it2.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.2.it3.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.3.0.truth.png", + "haps.NA12878.chr22.16570000.16610000_igs.3.it1.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.3.it2.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.3.it3.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.4.0.truth.png", + "haps.NA12878.chr22.16570000.16610000_igs.4.it1.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.4.it2.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.4.it3.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.5.0.truth.png", + "haps.NA12878.chr22.16570000.16610000_igs.5.it1.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.5.it2.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.5.it3.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.6.0.truth.png", + "haps.NA12878.chr22.16570000.16610000_igs.6.it1.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.6.it2.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.6.it3.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.7.0.truth.png", + "haps.NA12878.chr22.16570000.16610000_igs.7.it1.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.7.it2.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.7.it3.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.8.0.truth.png", + "haps.NA12878.chr22.16570000.16610000_igs.8.it1.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.8.it2.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.8.it3.gibbs.png" + ], + [ + [ + { + "id": "NA12878", + "chr": "chr22" + }, + [ + "QUILT_prepared_reference.chr22.16570000.16610000.RData:md5,d41d8cd98f00b204e9800998ecf8427e" + ] + ] + ], + { + "versions_r_base": [ + [ + "QUILT_QUILT2", + "r-base", + "4.4.3" + ] + ], + "versions_r_quilt": [ + [ + "QUILT_QUILT2", + "r-quilt", + "2.0.4" + ] + ] + } + ], + "timestamp": "2026-04-05T16:44:47.20694205", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + }, + "QUILT2 no optional files": { + "content": [ + [ + [ + { + "id": "test", + "chr": "chr22" + }, + "test.vcf.gz.tbi:md5,a4f8d419c7cdffd35743582d2f8cf62a" + ] + ], + [ + [ + { + "id": "test", + "chr": "chr22" + }, + [ + + ] + ] + ], + [ + [ + { + "id": "test", + "chr": "chr22" + }, + [ + "NA12878" + ], + "a560a607175034af92f6aab795cdfece" + ] + ], + { + "versions_r_base": [ + [ + "QUILT_QUILT2", + "r-base", + "4.4.3" + ] + ], + "versions_r_quilt": [ + [ + "QUILT_QUILT2", + "r-quilt", + "2.0.4" + ] + ] + } + ], + "timestamp": "2026-04-05T16:39:35.155242296", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + }, + "homo_sapiens - bam, reference vcf, map - fasta": { + "content": [ + [ + [ + { + "id": "NA12878", + "chr": "chr22" + }, + "NA12878.vcf.gz.tbi:md5,5a60a33c0a274815ff0a52ca16050b39" + ] + ], + [ + [ + { + "id": "NA12878", + "chr": "chr22" + }, + [ + "QUILT_prepared_reference.chr22.16570000.16610000.RData:md5,c981d3c2da392174bb17acdae0538eed" + ] + ] + ], + [ + [ + { + "id": "NA12878", + "chr": "chr22" + }, + [ + "NA12878" + ], + "7b6b8619f2a16a80dd4a5dcd1cfe4306" + ] + ], + { + "versions_r_base": [ + [ + "QUILT_QUILT2", + "r-base", + "4.4.3" + ] + ], + "versions_r_quilt": [ + [ + "QUILT_QUILT2", + "r-quilt", + "2.0.4" + ] + ] + } + ], + "timestamp": "2026-04-05T16:42:44.640836278", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + }, + "QUILT2 with bamlist and renaming": { + "content": [ + [ + [ + { + "id": "test", + "chr": "chr20" + }, + "test.vcf.gz.tbi:md5,8255cab2750a3d3d24f485438ef9ebe5" + ] + ], + [ + [ + { + "id": "test", + "chr": "chr20" + }, + [ + + ] + ] + ], + [ + [ + { + "id": "test", + "chr": "chr20" + }, + [ + "Mysample1" + ], + "a560a607175034af92f6aab795cdfece" + ] + ], + { + "versions_r_base": [ + [ + "QUILT_QUILT2", + "r-base", + "4.4.3" + ] + ], + "versions_r_quilt": [ + [ + "QUILT_QUILT2", + "r-quilt", + "2.0.4" + ] + ] + } + ], + "timestamp": "2026-04-05T16:39:45.620802389", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + } +} \ No newline at end of file diff --git a/modules/nf-core/quilt/quilt2/tests/nextflow.config b/modules/nf-core/quilt/quilt2/tests/nextflow.config new file mode 100644 index 000000000000..7eb173b3e42f --- /dev/null +++ b/modules/nf-core/quilt/quilt2/tests/nextflow.config @@ -0,0 +1,16 @@ +process { + // More than 1 cpu may lead to different md5sum + resourceLimits = [ + cpus: 1 + ] + withName: QUILT_QUILT2 { + ext.args = { "${params.quilt_args}" } + } + withName: BCFTOOLS_QUERY { + ext.args = { "${params.bcftools_query_args}" } + ext.suffix = { "${params.bcftools_query_suffix}" } + } + withName: GAWK_NAME { + ext.suffix = { "${params.gawk_name_suffix}" } + } +} From a661379bcacc92fa24769de655ba7e9048802b4b Mon Sep 17 00:00:00 2001 From: Anabella Trigila <18577080+atrigila@users.noreply.github.com> Date: Sun, 5 Apr 2026 18:04:45 -0300 Subject: [PATCH 2/6] fix conda tests --- modules/nf-core/quilt/quilt2/environment.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/nf-core/quilt/quilt2/environment.yml b/modules/nf-core/quilt/quilt2/environment.yml index 9e10122a1a3a..644ec1b21c3e 100644 --- a/modules/nf-core/quilt/quilt2/environment.yml +++ b/modules/nf-core/quilt/quilt2/environment.yml @@ -5,4 +5,4 @@ channels: - bioconda dependencies: - bioconda::r-quilt=2.0.4=r44h503566f_0 - - r-base=4.4.0 + - r-base=4.4.3 From 44e97e2654ec38ec76378fdeee16dd3a68210ce8 Mon Sep 17 00:00:00 2001 From: Anabella Trigila <18577080+atrigila@users.noreply.github.com> Date: Sun, 5 Apr 2026 18:19:14 -0300 Subject: [PATCH 3/6] fix linting --- modules/nf-core/quilt/quilt2/main.nf | 9 +++------ modules/nf-core/quilt/quilt2/tests/main.nf.test | 3 +++ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/nf-core/quilt/quilt2/main.nf b/modules/nf-core/quilt/quilt2/main.nf index cb15c113f45b..4a2ceff42d0d 100644 --- a/modules/nf-core/quilt/quilt2/main.nf +++ b/modules/nf-core/quilt/quilt2/main.nf @@ -25,7 +25,6 @@ process QUILT_QUILT2 { script: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - def suffix = task.ext.suffix ?: "vcf.gz" def extensions = bams.collect { path -> path.extension } def extension = extensions.flatten().unique() @@ -70,23 +69,21 @@ process QUILT_QUILT2 { --nCores=${task.cpus} \\ --outputdir="." \\ --reference_vcf_file=${reference_vcf_file} \\ - --output_filename=${prefix}.${suffix} \\ + --output_filename=${prefix}.vcf.gz \\ ${args} """ stub: def args = task.ext.args ?: '' def prefix = task.ext.prefix ?: "${meta.id}" - def suffix = task.ext.suffix ?: "vcf.gz" - def create_cmd = suffix.endsWith(".gz") ? "echo '' | gzip >" : "touch" def make_plots = args.contains("--make_plots=TRUE") def save_ref = args.contains("--save_prepared_reference=TRUE") def nGibbsSamples = args.contains("--nGibbsSamples=") ? args.split("--nGibbsSamples=")[1].split(" ")[0] : 7 def n_seek_its = args.contains("--n_seek_its=") ? args.split("--n_seek_its=")[1].split(" ")[0] : 3 """ - ${create_cmd} ${prefix}.${suffix} - touch ${prefix}.${suffix}.tbi + echo '' | gzip > ${prefix}.vcf.gz + touch ${prefix}.vcf.gz.tbi if [ "${save_ref}" == true ] then mkdir -p RData diff --git a/modules/nf-core/quilt/quilt2/tests/main.nf.test b/modules/nf-core/quilt/quilt2/tests/main.nf.test index 6a4b6fe4663a..d82f00406455 100644 --- a/modules/nf-core/quilt/quilt2/tests/main.nf.test +++ b/modules/nf-core/quilt/quilt2/tests/main.nf.test @@ -8,6 +8,9 @@ nextflow_process { tag "modules_nfcore" tag "quilt/quilt2" tag "quilt" + tag "wget" + tag "xz/decompress" + tag "untar" config "./nextflow.config" From 47e33aedf332e8416b35ef2bbae3f751a3eb6a27 Mon Sep 17 00:00:00 2001 From: Anabella Trigila <18577080+atrigila@users.noreply.github.com> Date: Mon, 6 Apr 2026 17:32:14 -0300 Subject: [PATCH 4/6] add cram test --- .../nf-core/quilt/quilt2/tests/main.nf.test | 73 +++++++++++++++++++ .../quilt/quilt2/tests/main.nf.test.snap | 57 +++++++++++++++ .../quilt/quilt2/tests/nextflow.config | 10 +-- 3 files changed, 133 insertions(+), 7 deletions(-) diff --git a/modules/nf-core/quilt/quilt2/tests/main.nf.test b/modules/nf-core/quilt/quilt2/tests/main.nf.test index d82f00406455..9e33b7a262ae 100644 --- a/modules/nf-core/quilt/quilt2/tests/main.nf.test +++ b/modules/nf-core/quilt/quilt2/tests/main.nf.test @@ -8,6 +8,7 @@ nextflow_process { tag "modules_nfcore" tag "quilt/quilt2" tag "quilt" + tag "samtools/view" tag "wget" tag "xz/decompress" tag "untar" @@ -58,6 +59,78 @@ nextflow_process { } } + test("homo_sapiens - cram, reference vcf, map - fasta") { + setup { + run("SAMTOOLS_VIEW", alias: "BAM_TO_CRAM") { + script "../../../samtools/view/main.nf" + process { + """ + input[0] = Channel.of([ + [id: 'NA12878'], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/NA12878.chr21_22.1X.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/NA12878.chr21_22.1X.bam.bai', checkIfExists: true) + ]) + input[1] = Channel.of([ + [id: 'GRCh38'], + 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.fai', checkIfExists: true) + ]) + input[2] = [[], []] + input[3] = [[], []] + input[4] = 'crai' + """ + } + } + } + + when { + params{ + quilt_args = "--save_prepared_reference=TRUE --seed=1" + samtools_args = "--output-fmt cram,no_ref --write-index" + } + process { + """ + input[0] = BAM_TO_CRAM.out.cram + .join(BAM_TO_CRAM.out.crai) + .map { meta, cram, crai -> + [ + meta + [chr:'chr22'], + cram, + crai, + [], [], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/popgen/1000GP.chr22.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/popgen/1000GP.chr22.vcf.gz.csi', checkIfExists: true), + [], [], [], + "chr22", "16570000", "16610000", "100", "10000", + file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genetic_map/genome.GRCh38.chr22.stitch.map", checkIfExists:true) + ] + } + input[1] = [ + [id: 'GRCh38'], + 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.fai', checkIfExists: true) + ] + """ + } + } + + then { + assert process.success + assertAll( + { assert snapshot( + process.out.tbi, + process.out.rdata, + process.out.vcf.collect{ meta, vcf -> [ + meta, + path(vcf).vcf.header.getGenotypeSamples().sort(), + path(vcf).vcf.variantsMD5 + ]}, + process.out.findAll { key, val -> key.startsWith('versions') } + ).match() } + ) + } + } + test("QUILT2 - stub") { options '-stub' when { diff --git a/modules/nf-core/quilt/quilt2/tests/main.nf.test.snap b/modules/nf-core/quilt/quilt2/tests/main.nf.test.snap index ad6753835af4..6bcfe4e39ecb 100644 --- a/modules/nf-core/quilt/quilt2/tests/main.nf.test.snap +++ b/modules/nf-core/quilt/quilt2/tests/main.nf.test.snap @@ -260,6 +260,63 @@ "nextflow": "25.10.4" } }, + "homo_sapiens - cram, reference vcf, map - fasta": { + "content": [ + [ + [ + { + "id": "NA12878", + "chr": "chr22" + }, + "NA12878.vcf.gz.tbi:md5,5a60a33c0a274815ff0a52ca16050b39" + ] + ], + [ + [ + { + "id": "NA12878", + "chr": "chr22" + }, + [ + "QUILT_prepared_reference.chr22.16570000.16610000.RData:md5,c981d3c2da392174bb17acdae0538eed" + ] + ] + ], + [ + [ + { + "id": "NA12878", + "chr": "chr22" + }, + [ + "NA12878" + ], + "7b6b8619f2a16a80dd4a5dcd1cfe4306" + ] + ], + { + "versions_r_base": [ + [ + "QUILT_QUILT2", + "r-base", + "4.4.3" + ] + ], + "versions_r_quilt": [ + [ + "QUILT_QUILT2", + "r-quilt", + "2.0.4" + ] + ] + } + ], + "timestamp": "2026-04-06T17:23:04.938845476", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + }, "QUILT2 with bamlist and renaming": { "content": [ [ diff --git a/modules/nf-core/quilt/quilt2/tests/nextflow.config b/modules/nf-core/quilt/quilt2/tests/nextflow.config index 7eb173b3e42f..75cc3ec13682 100644 --- a/modules/nf-core/quilt/quilt2/tests/nextflow.config +++ b/modules/nf-core/quilt/quilt2/tests/nextflow.config @@ -3,14 +3,10 @@ process { resourceLimits = [ cpus: 1 ] + withName: SAMTOOLS_VIEW { + ext.args = { "${params.samtools_args}" } + } withName: QUILT_QUILT2 { ext.args = { "${params.quilt_args}" } } - withName: BCFTOOLS_QUERY { - ext.args = { "${params.bcftools_query_args}" } - ext.suffix = { "${params.bcftools_query_suffix}" } - } - withName: GAWK_NAME { - ext.suffix = { "${params.gawk_name_suffix}" } - } } From 56829e43b725d64c284bd3449b3ef10726005d70 Mon Sep 17 00:00:00 2001 From: Anabella Trigila <18577080+atrigila@users.noreply.github.com> Date: Mon, 6 Apr 2026 20:32:22 -0300 Subject: [PATCH 5/6] remove old test --- .../nf-core/quilt/quilt2/tests/main.nf.test | 106 ------------------ .../quilt/quilt2/tests/main.nf.test.snap | 59 ---------- 2 files changed, 165 deletions(-) diff --git a/modules/nf-core/quilt/quilt2/tests/main.nf.test b/modules/nf-core/quilt/quilt2/tests/main.nf.test index 9e33b7a262ae..c5c311a3acf2 100644 --- a/modules/nf-core/quilt/quilt2/tests/main.nf.test +++ b/modules/nf-core/quilt/quilt2/tests/main.nf.test @@ -263,110 +263,4 @@ nextflow_process { } } - test("QUILT2 quick start example") { - setup { - run("WGET", alias: "DOWNLOAD_QUICKSTART") { - script "../../../wget/main.nf" - process { - """ - input[0] = [ - [ id:'quilt2_quickstart' ], - "https://zenodo.org/records/12786681/files/QUILT2_example_2024.tar.xz", - "tar.xz" - ] - """ - } - } - - run("XZ_DECOMPRESS", alias: "XZ_DECOMPRESS_QUICKSTART") { - script "../../../xz/decompress/main.nf" - process { - """ - input[0] = DOWNLOAD_QUICKSTART.out.outfile - """ - } - } - - run("UNTAR", alias: "UNTAR_QUICKSTART") { - script "../../../untar/main.nf" - process { - """ - input[0] = XZ_DECOMPRESS_QUICKSTART.out.file.map { meta, archive -> [meta, archive] } - """ - } - } - } - - when { - params { - quilt_args = "--save_prepared_reference=TRUE --seed=1" - } - process { - """ - bamlist = Channel.of( - "NA12878.haplotagged.1.0.bam", - "NA12878.ont.1.0.bam", - "NA12878.illumina.1.0.bam", - ).collectFile(name: 'bamlist.txt', newLine: true) - - ch_quickstart = UNTAR_QUICKSTART.out.untar.map { meta, dir -> - [ - [ id:'quickstart', chr:'chr20' ], - [ - dir.resolve('NA12878.haplotagged.1.0.bam'), - dir.resolve('NA12878.ont.1.0.bam'), - dir.resolve('NA12878.illumina.1.0.bam'), - ], - [ - dir.resolve('NA12878.haplotagged.1.0.bam.bai'), - dir.resolve('NA12878.ont.1.0.bam.bai'), - dir.resolve('NA12878.illumina.1.0.bam.bai'), - ], - dir.resolve('ALL.chr20_GRCh38.genotypes.20170504.chr20.2000001.4000000.noNA12878.vcf.gz'), - dir.resolve('ALL.chr20_GRCh38.genotypes.20170504.chr20.2000001.4000000.noNA12878.vcf.gz.tbi'), - dir.resolve('CEU-chr20-final.b38.txt.gz') - ] - } - - input[0] = ch_quickstart.combine(bamlist).map { meta, bams, bais, reference_vcf, reference_vcf_index, genetic_map, bamlist_file -> - [ - meta, - bams, - bais, - bamlist_file, - [], - reference_vcf, - reference_vcf_index, - [], - [], - [], - "chr20", - "2000001", - "4000000", - "100", - "500000", - genetic_map - ] - } - input[1] = [[id: null], [], []] - """ - } - } - - then { - assert process.success - assertAll( - { assert snapshot( - process.out.tbi, - process.out.rdata, - process.out.vcf.collect{ meta, vcf -> [ - meta, - path(vcf).vcf.header.getGenotypeSamples().sort(), - path(vcf).vcf.variantsMD5 - ]}, - process.out.findAll { key, val -> key.startsWith('versions') } - ).match() } - ) - } - } } diff --git a/modules/nf-core/quilt/quilt2/tests/main.nf.test.snap b/modules/nf-core/quilt/quilt2/tests/main.nf.test.snap index 6bcfe4e39ecb..6206dc9db486 100644 --- a/modules/nf-core/quilt/quilt2/tests/main.nf.test.snap +++ b/modules/nf-core/quilt/quilt2/tests/main.nf.test.snap @@ -1,63 +1,4 @@ { - "QUILT2 quick start example": { - "content": [ - [ - [ - { - "id": "quickstart", - "chr": "chr20" - }, - "quickstart.vcf.gz.tbi:md5,735a74d3b49cb9a8aa6ef77e5210a828" - ] - ], - [ - [ - { - "id": "quickstart", - "chr": "chr20" - }, - [ - "QUILT_prepared_reference.chr20.2000001.4000000.RData:md5,25868d83403201ea41f58cfea6f5e3ff" - ] - ] - ], - [ - [ - { - "id": "quickstart", - "chr": "chr20" - }, - [ - "NA12878", - "NA12878HT", - "NA12878ONT" - ], - "d20c7cfeb27ecd84f5fef33d66479e38" - ] - ], - { - "versions_r_base": [ - [ - "QUILT_QUILT2", - "r-base", - "4.4.3" - ] - ], - "versions_r_quilt": [ - [ - "QUILT_QUILT2", - "r-quilt", - "2.0.4" - ] - ] - } - ], - "timestamp": "2026-04-05T17:19:29.083876565", - "meta": { - "nf-test": "0.9.5", - "nextflow": "25.10.4" - } - }, "QUILT2 - stub": { "content": [ [ From 0a705a9fb8383a58019fbc347a28517fde2adc87 Mon Sep 17 00:00:00 2001 From: Anabella Trigila <18577080+atrigila@users.noreply.github.com> Date: Sun, 12 Apr 2026 18:02:14 -0300 Subject: [PATCH 6/6] add non stub test with optional outputs --- .../nf-core/quilt/quilt2/tests/main.nf.test | 89 +++++++++++++++++- .../quilt/quilt2/tests/main.nf.test.snap | 91 +++++++++++++++++++ .../quilt/quilt2/tests/nextflow.config | 7 ++ 3 files changed, 184 insertions(+), 3 deletions(-) diff --git a/modules/nf-core/quilt/quilt2/tests/main.nf.test b/modules/nf-core/quilt/quilt2/tests/main.nf.test index c5c311a3acf2..88e04fdd39e2 100644 --- a/modules/nf-core/quilt/quilt2/tests/main.nf.test +++ b/modules/nf-core/quilt/quilt2/tests/main.nf.test @@ -9,9 +9,8 @@ nextflow_process { tag "quilt/quilt2" tag "quilt" tag "samtools/view" - tag "wget" - tag "xz/decompress" - tag "untar" + tag "bcftools/query" + tag "gawk" config "./nextflow.config" @@ -131,6 +130,90 @@ nextflow_process { } } + test("homo_sapiens - bam, reference vcf, map, optional outputs - fasta") { + setup { + run("BCFTOOLS_QUERY") { + script "../../../bcftools/query/main.nf" + process { + """ + input[0] = [ + [id: 'NA12878'], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/vcf/NA12878.chr21_22.1X.glimpse2.vcf.gz.csi', checkIfExists: true) + ] + input[1] = [] + input[2] = [] + input[3] = [] + """ + } + } + + run("GAWK", alias: "GAWK_NAME") { + script "../../../gawk/main.nf" + process { + """ + program = Channel.of('BEGIN{print "NA12878"} {print}').collectFile(name: 'program.txt', newLine: true) + input[0] = BCFTOOLS_QUERY.out.output + input[1] = program + input[2] = false + """ + } + } + } + + when { + params{ + bcftools_query_args = "-f '[%GT]\\n' -r chr22" + bcftools_query_suffix = "phasefile.txt" + gawk_suffix = "phasefile.name.txt" + quilt_args = "--save_prepared_reference=TRUE --make_plots=TRUE --impute_rare_common=FALSE --seed=1" + } + process { + """ + input[0] = Channel.of([ + [ id:'NA12878', chr:'chr22' ], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/NA12878.chr21_22.1X.bam', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/illumina/bam/NA12878.chr21_22.1X.bam.bai', checkIfExists: true), + [], [], + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/popgen/1000GP.chr22.vcf.gz', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/popgen/1000GP.chr22.vcf.gz.csi', checkIfExists: true), + file(params.modules_testdata_base_path + 'genomics/homo_sapiens/popgen/1000GP.chr22.posfile', checkIfExists: true), + ]) + .combine(GAWK_NAME.out.output.map { it[1] }) + .combine(channel.of([ + [], "chr22", "16570000", "16610000", "100", "10000", + file(params.modules_testdata_base_path + "genomics/homo_sapiens/genome/genetic_map/genome.GRCh38.chr22.stitch.map", checkIfExists:true) + ])) + input[1] = [ + [id: 'GRCh38'], + 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.fai', checkIfExists: true) + ] + """ + } + } + + then { + assert process.success + def plots_dir = new File(process.out.plots[0][1]) + def plots = [] + plots_dir.eachFileRecurse { file -> plots << file.getName() } + assertAll( + { assert snapshot( + process.out.tbi, + plots.sort(), + process.out.rdata, + process.out.vcf.collect{ meta, vcf -> [ + meta, + path(vcf).vcf.header.getGenotypeSamples().sort(), + path(vcf).vcf.variantsMD5 + ]}, + process.out.findAll { key, val -> key.startsWith('versions') } + ).match() } + ) + } + } + test("QUILT2 - stub") { options '-stub' when { diff --git a/modules/nf-core/quilt/quilt2/tests/main.nf.test.snap b/modules/nf-core/quilt/quilt2/tests/main.nf.test.snap index 6206dc9db486..7538d3d240fb 100644 --- a/modules/nf-core/quilt/quilt2/tests/main.nf.test.snap +++ b/modules/nf-core/quilt/quilt2/tests/main.nf.test.snap @@ -144,6 +144,97 @@ "nextflow": "25.10.4" } }, + "homo_sapiens - bam, reference vcf, map, optional outputs - fasta": { + "content": [ + [ + [ + { + "id": "NA12878", + "chr": "chr22" + }, + "NA12878.vcf.gz.tbi:md5,d93e9cc42b928f040dd627d91d0c38cb" + ] + ], + [ + "haps.NA12878.chr22.16570000.16610000_igs.1.0.truth.png", + "haps.NA12878.chr22.16570000.16610000_igs.1.it1.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.1.it2.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.1.it3.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.2.0.truth.png", + "haps.NA12878.chr22.16570000.16610000_igs.2.it1.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.2.it2.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.2.it3.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.3.0.truth.png", + "haps.NA12878.chr22.16570000.16610000_igs.3.it1.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.3.it2.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.3.it3.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.4.0.truth.png", + "haps.NA12878.chr22.16570000.16610000_igs.4.it1.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.4.it2.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.4.it3.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.5.0.truth.png", + "haps.NA12878.chr22.16570000.16610000_igs.5.it1.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.5.it2.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.5.it3.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.6.0.truth.png", + "haps.NA12878.chr22.16570000.16610000_igs.6.it1.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.6.it2.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.6.it3.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.7.0.truth.png", + "haps.NA12878.chr22.16570000.16610000_igs.7.it1.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.7.it2.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.7.it3.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.8.0.truth.png", + "haps.NA12878.chr22.16570000.16610000_igs.8.it1.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.8.it2.gibbs.png", + "haps.NA12878.chr22.16570000.16610000_igs.8.it3.gibbs.png" + ], + [ + [ + { + "id": "NA12878", + "chr": "chr22" + }, + [ + "QUILT_prepared_reference.chr22.16570000.16610000.RData:md5,d7efdb9debc0ed36050d7d1e3cd526af" + ] + ] + ], + [ + [ + { + "id": "NA12878", + "chr": "chr22" + }, + [ + "NA12878" + ], + "e2195be0270b7fcecafd989acbc4718" + ] + ], + { + "versions_r_base": [ + [ + "QUILT_QUILT2", + "r-base", + "4.4.3" + ] + ], + "versions_r_quilt": [ + [ + "QUILT_QUILT2", + "r-quilt", + "2.0.4" + ] + ] + } + ], + "timestamp": "2026-04-12T18:00:07.039402568", + "meta": { + "nf-test": "0.9.5", + "nextflow": "25.10.4" + } + }, "homo_sapiens - bam, reference vcf, map - fasta": { "content": [ [ diff --git a/modules/nf-core/quilt/quilt2/tests/nextflow.config b/modules/nf-core/quilt/quilt2/tests/nextflow.config index 75cc3ec13682..cdebc062433e 100644 --- a/modules/nf-core/quilt/quilt2/tests/nextflow.config +++ b/modules/nf-core/quilt/quilt2/tests/nextflow.config @@ -3,6 +3,13 @@ process { resourceLimits = [ cpus: 1 ] + withName: BCFTOOLS_QUERY { + ext.args = { "${params.bcftools_query_args}" } + ext.suffix = { "${params.bcftools_query_suffix}" } + } + withName: GAWK { + ext.suffix = { "${params.gawk_suffix}" } + } withName: SAMTOOLS_VIEW { ext.args = { "${params.samtools_args}" } }